From 233a7aabdd96f1ae25f6a28115f5d7bd1c364fa0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Mar 2018 03:55:26 +0000 Subject: [PATCH 0001/1848] Removed usage of dropped timestamp field in import. --- WEB-INF/lib/ttImportHelper.class.php | 1 - WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 2b1b5af36..55fd15407 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -245,7 +245,6 @@ function endElement($parser, $name) { if ($name == 'LOG_ITEM' && $this->canImport) { $this->logMap[$this->currentElement['ID']] = ttTimeHelper::insert(array( - 'timestamp' => $this->currentElement['TIMESTAMP'], 'user_id' => $this->userMap[$this->currentElement['USER_ID']], 'date' => $this->currentElement['DATE'], 'start' => $this->currentElement['START'], diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9f114559a..1d95f5ecb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.64.4122 | Copyright © Anuko | +  Anuko Time Tracker 1.17.64.4123 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From dc00748e76b054fb1163f7a3835b686a752fbf8a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Mar 2018 15:20:07 +0000 Subject: [PATCH 0002/1848] Improved a comment for translators in translation files. --- WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/cs.lang.php | 2 +- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/en.lang.php | 4 ++-- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 +- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 +- WEB-INF/resources/sv.lang.php | 2 +- WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- WEB-INF/resources/zh-tw.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 32 insertions(+), 32 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 64fa6a277..0a4684d28 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -514,7 +514,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Factura enviada.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 549e8ed52..3300c7a3a 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -527,7 +527,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Faktura odeslána.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index abf049cd2..23cbc20ce 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -468,7 +468,7 @@ 'form.mail.report_sent' => 'Rapport sendt.', 'form.mail.invoice_sent' => 'Faktura sendt.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'År', 'form.quota.month' => 'Måned', 'form.quota.quota' => 'Kvota', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index a588ad493..f98216203 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -466,7 +466,7 @@ 'form.mail.report_sent' => 'Der Bericht wurde gesendet.', 'form.mail.invoice_sent' => 'Die Rechnung wurde gesendet.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 011f458ae..ce65dc622 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -452,14 +452,14 @@ 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Invoice sent.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Year', 'form.quota.month' => 'Month', 'form.quota.quota' => 'Quota', 'form.quota.workday_hours' => 'Hours in work day', 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 23b391a7f..0d7f7ab24 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -529,7 +529,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Factura enviada.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index b6a5895ca..aa8a63af8 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -524,7 +524,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Arve saadetud.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 5ad0871a5..2fa168ef1 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -497,7 +497,7 @@ 'form.mail.report_sent' => 'گزارش ارسال شد.', 'form.mail.invoice_sent' => 'فاکتور ارسال شد.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 5557499d3..a02c9d9cd 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -476,7 +476,7 @@ 'form.mail.report_sent' => 'Raportti lähetetty.', 'form.mail.invoice_sent' => 'Lasku lähetetty.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 1c8708a4c..1de9b91c9 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -465,7 +465,7 @@ 'form.mail.report_sent' => 'Le rapport a été envoyé.', 'form.mail.invoice_sent' => 'La facture a été envoyée.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Année', 'form.quota.month' => 'Mois', 'form.quota.quota' => 'Quota', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 934051983..e3477ccc3 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -451,7 +451,7 @@ 'form.mail.report_sent' => 'Η αναφορά στάλθηκε.', 'form.mail.invoice_sent' => 'Το τιμολόγιο στάλθηκε.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Χρόνος', 'form.quota.month' => 'Μήνας', 'form.quota.quota' => 'Ποσοστό', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2306e7c7e..bae295f90 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -502,7 +502,7 @@ 'form.mail.report_sent' => 'הדוח נשלח.', 'form.mail.invoice_sent' => 'החשבונית נשלחה.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index fae8f6d5b..70cfb40ca 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -519,7 +519,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'A számla elküldve.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 2954043a7..a1c1f47fc 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -467,7 +467,7 @@ 'form.mail.report_sent' => 'Rapporto inviato.', 'form.mail.invoice_sent' => 'Fattura inviata.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Anno', 'form.quota.month' => 'Mese', 'form.quota.quota' => 'Quota', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 0df3c610b..65d77779a 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -519,7 +519,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '送信した送り状。', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 717761c35..c3a47603f 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -517,7 +517,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '송신한 송장.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index e8153aa76..630c64d19 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -459,7 +459,7 @@ 'form.mail.report_sent' => 'Rapport is verzonden.', 'form.mail.invoice_sent' => 'Factuur is verzonden.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Jaar', 'form.quota.month' => 'Maand', 'form.quota.quota' => 'Quota', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index dceff3d7e..7aae59085 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -515,7 +515,7 @@ // 'form.mail.report_sent' => 'Report sent.', // 'form.mail.invoice_sent' => 'Invoice sent.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 7b9f37869..2c1427e3d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -478,7 +478,7 @@ 'form.mail.report_sent' => 'Wysłano raport', 'form.mail.invoice_sent' => 'Wysłano fakturę', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 5c9bd7f35..ecf7a70fa 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -473,7 +473,7 @@ 'form.mail.report_sent' => 'Relatório enviado.', 'form.mail.invoice_sent' => 'Fatura enviada.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 733d22f8b..c2909f43f 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -503,7 +503,7 @@ // 'form.mail.report_sent' => 'Report sent.', // 'form.mail.invoice_sent' => 'Invoice sent.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 6e0898f32..05522ac30 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -523,7 +523,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Factura trimisa.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index d3d8b25df..c03b6f12a 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -449,7 +449,7 @@ 'form.mail.report_sent' => 'Отчёт отправлен.', 'form.mail.invoice_sent' => 'Счёт отправлен.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Год', 'form.quota.month' => 'Месяц', 'form.quota.quota' => 'Квота', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 91f4d96f6..ac508d491 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -493,7 +493,7 @@ 'form.mail.report_sent' => 'Zostava odoslaná.', 'form.mail.invoice_sent' => 'Faktúra odoslaná.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 7a63b97dd..bd51ff4e4 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -501,7 +501,7 @@ // 'form.mail.report_sent' => 'Report sent.', // 'form.mail.invoice_sent' => 'Invoice sent.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index d96c4aa2a..0612d4e83 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -477,7 +477,7 @@ 'form.mail.report_sent' => 'Izveštaj poslat.', 'form.mail.invoice_sent' => 'Račun poslat.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 9a58e5703..24ad4551e 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -474,7 +474,7 @@ 'form.mail.report_sent' => 'Rapporten skickades.', 'form.mail.invoice_sent' => 'Fakturan skickades.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'År', 'form.quota.month' => 'Månad', 'form.quota.quota' => 'Kvot', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index b5b54939e..ad0565f9c 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -535,7 +535,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Fatura yollandı.', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 1581a9967..c174185f5 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -502,7 +502,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '发票已送出。', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 8c9ace018..a2c28331c 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -512,7 +512,7 @@ // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '發票已送出。', -// Quotas configuration form. +// Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1d95f5ecb..6c21ea63a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.64.4123 | Copyright © Anuko | +  Anuko Time Tracker 1.17.64.4124 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9eee35c738a83c870e8d6dfda19d859bd063b233 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Mar 2018 15:27:02 +0000 Subject: [PATCH 0003/1848] Improved a comment for translators. --- WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/cs.lang.php | 2 +- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 +- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 +- WEB-INF/resources/sv.lang.php | 2 +- WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- WEB-INF/resources/zh-tw.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 0a4684d28..078eaf5cd 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -522,7 +522,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 3300c7a3a..91ead1a9b 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -535,7 +535,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 23cbc20ce..397dc7f57 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -475,7 +475,7 @@ 'form.quota.workday_hours' => 'Timer på en arbejdsdag', 'form.quota.hint' => 'Hvis værdierne er tomme, beregnes kvoter automatisk baseret på arbejdsdage og helligdage.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index f98216203..279feee7a 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -474,7 +474,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 0d7f7ab24..b760badc6 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -537,7 +537,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index aa8a63af8..21fbcc0c2 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -532,7 +532,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 2fa168ef1..f9c7a3b9d 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -505,7 +505,7 @@ // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index a02c9d9cd..d722106d4 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -484,7 +484,7 @@ // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 1de9b91c9..c999d6380 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -472,7 +472,7 @@ 'form.quota.workday_hours' => 'Heures journée de travail', 'form.quota.hint' => 'Si les valeurs sont vides, les quotas sont calculés automatiquement selon les heures des journées de travail et des congés.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index e3477ccc3..1a7bfa1a3 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -458,7 +458,7 @@ 'form.quota.workday_hours' => 'Ώρες ανά ημέρα εργασίας', 'form.quota.hint' => 'Εάν οι τιμές είναι κενές, οι ποσοστώσεις υπολογίζονται αυτόματα με βάση τις ώρες της εργάσιμης ημέρας και τις αργίες.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index bae295f90..fc54004ed 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -510,7 +510,7 @@ // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 70cfb40ca..0ef9f2888 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -527,7 +527,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index a1c1f47fc..6df19a3b6 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -474,7 +474,7 @@ 'form.quota.workday_hours' => 'Ore lavorative in un giorno', 'form.quota.hint' => 'Se i valori sono vuoti, le quote vengono calcolate automaticamente basandosi su ore giornaliere e vacanze.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 65d77779a..c1845d73e 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -527,7 +527,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index c3a47603f..101cfd713 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -525,7 +525,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 630c64d19..fa65b754c 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -466,7 +466,7 @@ 'form.quota.workday_hours' => 'Werkuren per dag', 'form.quota.hint' => 'Als de velden leeg worden gelaten, dan zullen de doelen worden berekend op bassis van het aantal werkuren per dag en vakantiedagen.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 7aae59085..c467d9798 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -523,7 +523,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 2c1427e3d..f7b380672 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -486,7 +486,7 @@ // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index ecf7a70fa..aa7bb7620 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -481,7 +481,7 @@ // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index c2909f43f..feaff31cc 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -511,7 +511,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 05522ac30..96cf3a102 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -531,7 +531,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index c03b6f12a..07e1c619b 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -456,7 +456,7 @@ 'form.quota.workday_hours' => 'Количество часов в рабочем дне', 'form.quota.hint' => 'При пустых значениях квоты автоматически определяются из длительности рабочего дня и праздников.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. 'form.swap.swap_with' => 'Обменять роль с', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index ac508d491..2b6f43eb0 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -501,7 +501,7 @@ // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index bd51ff4e4..91e11c6f6 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -509,7 +509,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 0612d4e83..e5e04f935 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -485,7 +485,7 @@ // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 24ad4551e..d2ec27626 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -481,7 +481,7 @@ 'form.quota.workday_hours' => 'Arbetstimmar per dag', 'form.quota.hint' => 'Om fälten lämnas tomma räknas kvoterna automatiskt ut baserat på arbetstimmar per dag och helgdagar.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index ad0565f9c..6df4b32f1 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -543,7 +543,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index c174185f5..3d9c34d19 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -510,7 +510,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index a2c28331c..66b885cfd 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -520,7 +520,7 @@ // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', -// Swap roles form. +// Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. // 'form.swap.swap_with' => 'Swap roles with', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6c21ea63a..aaaf8db2b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.64.4124 | Copyright © Anuko | +  Anuko Time Tracker 1.17.64.4125 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 2ccee198591bc2ad5d80b5e1076246449d9232c1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Mar 2018 17:18:39 +0000 Subject: [PATCH 0004/1848] Started to work on ttRegistrator class to encapsulate restration related tasks. --- WEB-INF/lib/ttExportHelper.class.php | 12 ++-- WEB-INF/lib/ttRegistrator.class.php | 83 ++++++++++++++++++++++++++++ register.php | 25 +++++---- 3 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 WEB-INF/lib/ttRegistrator.class.php diff --git a/WEB-INF/lib/ttExportHelper.class.php b/WEB-INF/lib/ttExportHelper.class.php index 77b2db1fd..375de2f37 100644 --- a/WEB-INF/lib/ttExportHelper.class.php +++ b/WEB-INF/lib/ttExportHelper.class.php @@ -360,16 +360,14 @@ function compress($in, $out) { /* * Note about the utility functions below. - * We have roughly 3 groups of operations: + * We have roughly 4 groups of operations: * 1) Regular system usage for tracking time, etc. - * 2) Admin usage - used infrequently. - * 3) Export - used infrequently. - * - * TODO: we also have user registration process without initialized user. - * Perhaps we need a separate helper class for this. Think about it. + * 2) Registration process - used infrequently. + * 3) Admin usage - used infrequently. + * 4) Export - used infrequently. * * It is tempting to have a generic function to get things done for - * all situations. However, as export and admin access are one-off + * all situations. However, as registration, export and admin access are one-off * operations, while regular system usage is daily and must be efficient, * the current approach is to have SEPARATE functions for each mode. * diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php new file mode 100644 index 000000000..9a650c9c2 --- /dev/null +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -0,0 +1,83 @@ +user_name = $fields['user_name']; + $this->login = $fields['login']; + $this->password1 = $fields['password1']; + $this->password2 = $fields['password2']; + $this->email = $fields['email']; + $this->group_name = $fields['group_name']; + $this->currency = $fields['currency']; + $this->lang = $fields['lang']; + if (!$thins->lang) $this->lang = 'en'; + $this->err = $err; + + // Validate passed in parameters. + $this->validate(); + } + + function validate() { + global $i18n; + + if (!ttValidString($this->group_name, true)) + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.team_name')); + if (!ttValidString($this->currency, true)) + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.currency')); + if (!ttValidString($this->user_name)) + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_name')); + if (!ttValidString($this->login)) + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_login')); + if (!ttValidString($this->password1)) + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); + if (!ttValidString($this->password2)) + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + if ($this->password1 !== $this->password2) + $this->err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + if (!ttValidEmail($this->email, true)) + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + } + + // The register function registers a user in Time Tracker. + function register() { + // TODO: work in progress. Not implemented. + } +} diff --git a/register.php b/register.php index 92e97be68..a34a78fbc 100644 --- a/register.php +++ b/register.php @@ -85,16 +85,21 @@ $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_team_name, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.team_name')); - if (!ttValidString($cl_currency, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.currency')); - if (!ttValidString($cl_manager_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_name')); - if (!ttValidString($cl_manager_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_login')); - if (!ttValidString($cl_password1)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); - if (!ttValidEmail($cl_manager_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + // Create fields array for ttRegistrator instance. + $fields = array( + 'user_name' => $cl_manager_name, + 'login' => $cl_manager_login, + 'password1' => $cl_password1, + 'password2' => $cl_password2, + 'email' => $cl_manager_email, + 'group_name' => $cl_team_name, + 'currency' => $cl_currency, + 'lang' => $cl_lang); + + // Create an instance of ttRegistrator class. + import('ttRegistrator'); + $registrator = new ttRegistrator($fields, $err); + // Validation of user input occurs in ttRegistrator constructor above. if ($err->no()) { if (!ttUserHelper::getUserByLogin($cl_manager_login)) { From d40763fdef73f3118da81b497baafff29a73c5ba Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Mar 2018 19:12:59 +0000 Subject: [PATCH 0005/1848] Refactored register.php by encapsulating stuff in ttRegistrator class. --- WEB-INF/lib/ttRegistrator.class.php | 77 ++++++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- register.php | 42 ++++------------ 3 files changed, 85 insertions(+), 36 deletions(-) diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 9a650c9c2..0e51ce39c 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -35,6 +35,9 @@ class ttRegistrator { var $group_name = null; // Group name. var $currency = null; // Currency. var $lang = null; // Language. + var $group_id = null; // Group id, set after we create a group. + var $role_id = null; // Role id for top managers. + var $user_id = null; // User id after registration. var $err = null; // Error object, passed to us as reference. // We use it to communicate errors to caller. @@ -48,7 +51,7 @@ function __construct($fields, &$err) { $this->group_name = $fields['group_name']; $this->currency = $fields['currency']; $this->lang = $fields['lang']; - if (!$thins->lang) $this->lang = 'en'; + if (!$this->lang) $this->lang = 'en'; $this->err = $err; // Validate passed in parameters. @@ -78,6 +81,76 @@ function validate() { // The register function registers a user in Time Tracker. function register() { - // TODO: work in progress. Not implemented. + global $i18n; + + if ($this->err->yes()) + return; // There are errors, do not proceed. + + import('ttUserHelper'); + if (ttUserHelper::getUserByLogin($this->login)) { + // User login already exists. + $this->err->add($i18n->getKey('error.user_exists')); + return; + } + + // Create a new group. + $this->group_id = $this->createGroup(); + if (!$this->group_id) { + $this->err->add($i18n->getKey('error.db')); + return; + } + + import('ttRoleHelper'); + if (!ttRoleHelper::createPredefinedRoles($this->group_id, $this->lang)) { + $err->add($i18n->getKey('error.db')); + return; + } + $this->role_id = ttRoleHelper::getTopManagerRoleID(); + $this->user_id = $this->createUser(); + + if (!$this->user_id) { + $err->add($i18n->getKey('error.db')); + return; + } + } + + // The createGroup function creates a group in Time Tracker as part + // of user registration process. This is a top group for user as top manager. + function createGroup() { + $mdb2 = getConnection(); + + $name = $mdb2->quote($this->group_name); + $currency = $mdb2->quote($this->currency); + $lang = $mdb2->quote($this->lang); + + $sql = "insert into tt_teams (name, currency, lang) values($name, $currency, $lang)"; + $affected = $mdb2->exec($sql); + + if (!is_a($affected, 'PEAR_Error')) { + $group_id = $mdb2->lastInsertID('tt_teams', 'id'); + return $group_id; + } + return false; + } + + // The createUser creates a user in database as part of registration process. + function createUser() { + $mdb2 = getConnection(); + + $login = $mdb2->quote($this->login); + $password = 'md5('.$mdb2->quote($this->password1).')'; + $name = $mdb2->quote($this->user_name); + $email = $mdb2->quote($this->email); + $created = 'now()'; + $created_ip = $mdb2->quote($_SERVER['REMOTE_ADDR']); + $values = "values($login, $password, $name, $this->group_id, $this->role_id, $email, $created, $created_ip)"; + + $sql = 'insert into tt_users (login, password, name, team_id, role_id, email, created, created_ip) '.$values; + $affected = $mdb2->exec($sql); + if (!is_a($affected, 'PEAR_Error')) { + $user_id = $mdb2->lastInsertID('tt_users', 'id'); + return $user_id; + } + return false; } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index aaaf8db2b..0f5a4f2de 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.64.4125 | Copyright © Anuko | +  Anuko Time Tracker 1.17.64.4126 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/register.php b/register.php index a34a78fbc..3ddcb9902 100644 --- a/register.php +++ b/register.php @@ -28,8 +28,6 @@ require_once('initialize.php'); import('form.Form'); -import('ttUserHelper'); -import('ttRoleHelper'); if (!isTrue(MULTITEAM_MODE) || $auth->isPasswordExternal()) { header('Location: login.php'); @@ -99,39 +97,17 @@ // Create an instance of ttRegistrator class. import('ttRegistrator'); $registrator = new ttRegistrator($fields, $err); - // Validation of user input occurs in ttRegistrator constructor above. + $registrator->register(); if ($err->no()) { - if (!ttUserHelper::getUserByLogin($cl_manager_login)) { - // Create a new team. - $team_id = ttTeamHelper::insert(array('name'=>$cl_team_name,'currency'=>$cl_currency,'lang'=>$cl_lang)); - if ($team_id) { - if (!ttRoleHelper::createPredefinedRoles($team_id, $cl_lang)) - $err->add($i18n->getKey('error.db')); - - $role_id = ttRoleHelper::getTopManagerRoleID(); - - // Team created, now create a team manager. - $user_id = ttUserHelper::insert(array( - 'team_id' => $team_id, - 'role_id' => $role_id, - 'name' => $cl_manager_name, - 'login' => $cl_manager_login, - 'password' => $cl_password1, - 'email' => $cl_manager_email)); - } - if ($team_id && $user_id) { - if ($auth->doLogin($cl_manager_login, $cl_password1)) { - setcookie('tt_login', $cl_manager_login, time() + COOKIE_EXPIRE, '/'); - header('Location: time.php'); - } else { - header('Location: login.php'); - } - exit(); - } else - $err->add($i18n->getKey('error.db')); - } else - $err->add($i18n->getKey('error.user_exists')); + // Registration successful. + if ($auth->doLogin($cl_manager_login, $cl_password1)) { + setcookie('tt_login', $cl_manager_login, time() + COOKIE_EXPIRE, '/'); + header('Location: time.php'); + } else { + header('Location: login.php'); + } + exit(); } } // isPost From 7482d40143c40f58935fc37ecda54f2a60b2611e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Mar 2018 19:50:58 +0000 Subject: [PATCH 0006/1848] Introduced audit fields in tt_teams table. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 15 +++++++++++---- mysql.sql | 6 ++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0f5a4f2de..972eaf232 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.64.4126 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4127 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index ff0820b63..7fb35e831 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11764"]) { + if ($_POST["convert11744to11765"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -844,6 +844,13 @@ function setChange($sql) { setChange("update `tt_log` l inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.61') set l.created = l.timestamp where l.created is null"); setChange("ALTER TABLE `tt_log` drop `timestamp`"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.64', modified = now() where param_name = 'version_db' and param_value = '1.17.61'"); + setChange("ALTER TABLE `tt_teams` ADD `created` datetime default NULL AFTER `config`"); + setChange("ALTER TABLE `tt_teams` ADD `created_ip` varchar(45) default NULL AFTER `created`"); + setChange("ALTER TABLE `tt_teams` ADD `created_by` int(11) default NULL AFTER `created_ip`"); + setChange("ALTER TABLE `tt_teams` ADD `modified` datetime default NULL AFTER `created_by`"); + setChange("ALTER TABLE `tt_teams` ADD `modified_ip` varchar(45) default NULL AFTER `modified`"); + setChange("ALTER TABLE `tt_teams` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.65', modified = now() where param_name = 'version_db' and param_value = '1.17.64'"); } if ($_POST["cleanup"]) { @@ -889,7 +896,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.64) + Create database structure (v1.17.65)
(applies only to new installations, do not execute when updating)
@@ -929,8 +936,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.64)Update database structure (v1.17.44 to v1.17.65)
diff --git a/mysql.sql b/mysql.sql index 61b39098c..931f9bdc1 100644 --- a/mysql.sql +++ b/mysql.sql @@ -33,6 +33,12 @@ CREATE TABLE `tt_teams` ( `workday_minutes` smallint(4) default 480, # number of work minutes in a regular working day `custom_logo` tinyint(4) default 0, # whether to use a custom logo or not `config` text default NULL, # miscellaneous team configuration settings + `created` datetime default NULL, # creation timestamp + `created_ip` varchar(45) default NULL, # creator ip + `created_by` int(11) default NULL, # creator user_id + `modified` datetime default NULL, # modification timestamp + `modified_ip` varchar(45) default NULL, # modifier ip + `modified_by` int(11) default NULL, # modifier user_id `status` tinyint(4) default 1, # team status PRIMARY KEY (`id`) ); From 496cfee4721ea6f3dca65ec57a2845ef059c5b1d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Mar 2018 19:52:10 +0000 Subject: [PATCH 0007/1848] Updated db version. --- WEB-INF/templates/footer.tpl | 2 +- mysql.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 972eaf232..1a731bba4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4127 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4128 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mysql.sql b/mysql.sql index 931f9bdc1..cc4ffb0df 100644 --- a/mysql.sql +++ b/mysql.sql @@ -452,4 +452,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.64', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.65', now()); # TODO: change when structure changes. From 15684e556a6829fbea1511e99ee5bf8053d69295 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Mar 2018 21:11:48 +0000 Subject: [PATCH 0008/1848] Added handling of audit info to user registration. --- WEB-INF/lib/ttRegistrator.class.php | 13 ++++++++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 0e51ce39c..ea76f3a2f 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -122,8 +122,10 @@ function createGroup() { $name = $mdb2->quote($this->group_name); $currency = $mdb2->quote($this->currency); $lang = $mdb2->quote($this->lang); + $created = 'now()'; + $created_ip = $mdb2->quote($_SERVER['REMOTE_ADDR']); - $sql = "insert into tt_teams (name, currency, lang) values($name, $currency, $lang)"; + $sql = "insert into tt_teams (name, currency, lang, created, created_ip) values($name, $currency, $lang, $created, $created_ip)"; $affected = $mdb2->exec($sql); if (!is_a($affected, 'PEAR_Error')) { @@ -149,6 +151,15 @@ function createUser() { $affected = $mdb2->exec($sql); if (!is_a($affected, 'PEAR_Error')) { $user_id = $mdb2->lastInsertID('tt_users', 'id'); + + // Update created_by field for the team with user id, now that we have it. + $sql = "update tt_teams set created_by = $user_id where id = $this->group_id and created_by is null"; + $affected = $mdb2->exec($sql); + + // Update created_by field for user by setting to self. + $sql = "update tt_users set created_by = $user_id where id = $user_id and team_id = $this->group_id and created_by is null"; + $affected = $mdb2->exec($sql); + return $user_id; } return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1a731bba4..54e00f39f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4128 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4129 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From f340e538c5e269b9035905e808220a5683b079c4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Mar 2018 22:00:26 +0000 Subject: [PATCH 0009/1848] Added modification info to team updates. --- WEB-INF/lib/ttTeamHelper.class.php | 4 +++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 74ef55452..6dede8b23 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -867,6 +867,7 @@ static function insert($fields) { // The update function updates team information. static function update($team_id, $fields) { + global $user; $mdb2 = getConnection(); $name_part = 'name = '.$mdb2->quote($fields['name']); $currency_part = ''; @@ -897,10 +898,11 @@ static function update($team_id, $fields) if (isset($fields['config'])) $config_part = ', config = '.$mdb2->quote($fields['config']); if (isset($fields['lock_spec'])) $lock_spec_part = ', lock_spec = '.$mdb2->quote($fields['lock_spec']); if (isset($fields['workday_minutes'])) $workday_minutes_part = ', workday_minutes = '.$mdb2->quote($fields['workday_minutes']); + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); $sql = "update tt_teams set $name_part $currency_part $lang_part $decimal_mark_part $date_format_part $time_format_part $week_start_part $tracking_mode_part $task_required_part $record_type_part - $bcc_email_part $plugins_part $config_part $lock_spec_part $workday_minutes_part where id = $team_id"; + $bcc_email_part $plugins_part $config_part $lock_spec_part $workday_minutes_part $modified_part where id = $team_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 54e00f39f..d45f4d94f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4129 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4130 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 73bd55c5aaa9459806ef9fa899cc5a24513727bc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Mar 2018 00:06:41 +0000 Subject: [PATCH 0010/1848] Introduced ttAdmin class for admin tasks. --- WEB-INF/lib/ttAdmin.class.php | 179 ++++++++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- admin_team_delete.php | 5 +- 3 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/lib/ttAdmin.class.php diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php new file mode 100644 index 000000000..b6b081e97 --- /dev/null +++ b/WEB-INF/lib/ttAdmin.class.php @@ -0,0 +1,179 @@ +query($sql); + $users = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $users[] = $val; + } + } + return $users; + } + + // markUserDeleted marks a user and all things associated with user as deleted. + function markUserDeleted($user_id) { + $mdb2 = getConnection(); + + // Mark user binds as deleted. + $sql = "update tt_user_project_binds set status = NULL where user_id = $user_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Mark favorite reports as deleted. + $sql = "update tt_fav_reports set status = NULL where user_id = $user_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Mark user as deleted. + global $user; + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); + $sql = "update tt_users set status = NULL $modified_part where id = $user_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + return true; + } + + // The markTasksDeleted deletes task binds and marks the tasks as deleted for a group. + function markTasksDeleted($group_id) { + $mdb2 = getConnection(); + $sql = "select id from tt_tasks where team_id = $group_id"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return false; + + while ($val = $res->fetchRow()) { + // Delete task binds. + $task_id = $val['id']; + $sql = "delete from tt_project_task_binds where task_id = $task_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // Mark task as deleted. + $sql = "update tt_tasks set status = NULL where id = $task_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + } + return true; + } + + // markGroupDeleted marks the group and everything in it as deleted. + function markGroupDeleted($group_id) { + + // Keep the logic simple by returning false on first error. + + // Obtain subgroups and call self recursively on them. + $subgroups = $this->getSubgroups(); + foreach($subgroups as $subgroup) { + if (!$this->markGroupDeleted($subgroup['id'])) + return false; + } + + // Now that we are done with subgroups, handle this group. + $users = $this->getUsers($group_id); + + // Iterate through team users and mark them as deleted. + foreach ($users as $one_user) { + if (!$this->markUserDeleted($one_user['id'])) + return false; + } + + // Mark tasks deleted. + if (!$this->markTasksDeleted($group_id)) return false; + + $mdb2 = getConnection(); + + // Mark roles deleted. + $sql = "update tt_roles set status = NULL where team_id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // Mark projects deleted. + $sql = "update tt_projects set status = NULL where team_id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // Mark clients deleted. + $sql = "update tt_clients set status = NULL where team_id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // Mark invoices deleted. + $sql = "update tt_invoices set status = NULL where team_id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // Mark custom fields deleted. + $sql = "update tt_custom_fields set status = NULL where team_id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // Mark notifications deleted. + $sql = "update tt_cron set status = NULL where team_id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // Note: we don't mark tt_log or tt_expense_items deleted here. + // Reasoning is: + // + // 1) Users may mark some of them deleted during their work. + // If we mark all of them deleted here, we can't recover nicely + // as we'll lose track of what was deleted by user. + // + // 2) DB maintenance script (Clean up DB from inactive teams) should + // get rid of these items permanently eventually. + + // Mark group deleted. + global $user; + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); + $sql = "update tt_teams set status = NULL $modified_part where id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + return true; + } +} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d45f4d94f..e0a4919d8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4130 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4131 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_team_delete.php b/admin_team_delete.php index 6958ca0e8..b2b462ce6 100644 --- a/admin_team_delete.php +++ b/admin_team_delete.php @@ -47,7 +47,10 @@ if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if (ttTeamHelper::markDeleted($team_id)) { + import('ttAdmin'); + $admin = new ttAdmin(); + $result = $admin->markGroupDeleted($team_id); + if ($result) { header('Location: admin_teams.php'); exit(); } else From 62dc3d09ec2703764869f5e76e5bc82b351938a2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Mar 2018 14:45:15 +0000 Subject: [PATCH 0011/1848] Refactored admin_team_edit.php to use ttAdmin class. --- WEB-INF/lib/ttAdmin.class.php | 87 ++++++++++++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- admin_team_edit.php | 47 +++++++------------ 3 files changed, 104 insertions(+), 32 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index b6b081e97..e054547d1 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -26,11 +26,17 @@ // | https://www.anuko.com/time_tracker/credits.htm // +----------------------------------------------------------------------+ +import('ttUser'); + // ttAdmin class is used to perform admin tasks. class ttAdmin { + var $err = null; // Error object, passed to us as reference. + // We use it to communicate errors to caller. + // Constructor. - function __construct() { + function __construct(&$err = null) { + $this->err = $err; } // getSubgroups rerurns an array of subgroups for a group. @@ -176,4 +182,83 @@ function markGroupDeleted($group_id) { return true; } + + // validateTeamInfo validates team information entered by user. + function validateTeamInfo($fields) { + global $i18n; + global $auth; + + $result = true; + + if (!ttValidString($fields['group_name'], true)) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.team_name')); + $result = false; + } + if (!ttValidString($fields['user_name'])) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_name')); + $result = false; + } + if (!ttValidString($fields['new_login'])) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_login')); + $result = false; + } + + // If we change login, it must be unique. + if ($fields['new_login'] != $fields['old_login']) { + if (ttUserHelper::getUserByLogin($fields['new_login'])) { + $this->err->add($i18n->getKey('error.user_exists')); + $result = false; + } + } + + if (!$auth->isPasswordExternal() && ($fields['password1'] || $fields['password2'])) { + if (!ttValidString($fields['password1'])) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); + $result = false; + } + if (!ttValidString($fields['password2'])) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + $result = false; + } + if ($fields['password1'] !== $fields['password2']) { + $this->err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $result = false; + } + } + if (!ttValidEmail($fields['email'], true)) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + $result = false; + } + + return $result; + } + + // updateTeam validates user input and updates the team with new information. + function updateTeam($team_id, $fields) { + if (!$this->validateTeamInfo($fields)) return false; // Can't continue as user input is invalid. + + $mdb2 = getConnection(); + + // Update group name if it changed. + if ($fields['old_group_name'] != $fields['new_group_name']) { + $name = $mdb2->quote($fields['new_group_name']); + $sql = "update tt_teams set name = $name where id = $team_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + } + + // Update group manager. + $user_id = $fields['user_id']; + $login_part = 'login = '.$mdb2->quote($fields['new_login']); + if ($fields['password1']) + $password_part = ', password = md5('.$mdb2->quote($fields['password1']).')'; + $name_part = ', name = '.$mdb2->quote($fields['user_name']); + $email_part = ', email = '.$mdb2->quote($fields['email']); + + $sql = 'update tt_users set '.$login_part.$password_part.$name_part.$email_part.'where id = '.$user_id; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + return true; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e0a4919d8..0bbfc0348 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4131 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4132 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_team_edit.php b/admin_team_edit.php index 61828e166..428845855 100644 --- a/admin_team_edit.php +++ b/admin_team_edit.php @@ -74,37 +74,24 @@ if ($request->isPost()) { if ($request->getParameter('btn_save')) { - // Validate user input. - if (!ttValidString($cl_team_name, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.team_name')); - if (!ttValidString($cl_manager_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_name')); - if (!ttValidString($cl_manager_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_login')); - if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { - if (!ttValidString($cl_password1)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); - } - if (!ttValidEmail($cl_manager_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); - - // New login must be unique. - if ($cl_manager_login != $team_details['manager_login']) - if (ttUserHelper::getUserByLogin($cl_manager_login)) $err->add($i18n->getKey('error.user_exists')); + // Create fields array for ttAdmin instance. + $fields = array( + 'old_group_name' => $team_details['team_name'], + 'new_group_name' => $cl_team_name, + 'user_id' => $team_details['manager_id'], + 'user_name' => $cl_manager_name, + 'old_login' => $team_details['manager_login'], + 'new_login' => $cl_manager_login, + 'password1' => $cl_password1, + 'password2' => $cl_password2, + 'email' => $cl_manager_email); - if ($err->no()) { - $update_result = ttTeamHelper::update($team_id, array('name'=>$cl_team_name)); - if ($update_result) { - $update_result = ttUserHelper::update($team_details['manager_id'], array( - 'name' => $cl_manager_name, - 'login' => $cl_manager_login, - 'password' => $cl_password1, - 'email' => $cl_manager_email, - 'status' => ACTIVE)); - } - if ($update_result) { - header('Location: admin_teams.php'); - exit(); - } else - $err->add($i18n->getKey('error.db')); + import('ttAdmin'); + $admin = new ttAdmin($err); + $result = $admin->updateTeam($team_id, $fields); + if ($result) { + header('Location: admin_teams.php'); + exit(); } } From afb1ca7aaa68c5b34da82ed58b7e06df1c1525ab Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Mar 2018 18:21:35 +0000 Subject: [PATCH 0012/1848] A bit more refactoring for admin. --- WEB-INF/lib/ttAdmin.class.php | 34 ++++++++++++++-- WEB-INF/lib/ttRegistrator.class.php | 40 +++++++++++++------ WEB-INF/templates/footer.tpl | 2 +- admin_team_add.php | 61 ++++++++++++----------------- 4 files changed, 85 insertions(+), 52 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index e054547d1..d6b9696a1 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -237,12 +237,14 @@ function validateTeamInfo($fields) { function updateTeam($team_id, $fields) { if (!$this->validateTeamInfo($fields)) return false; // Can't continue as user input is invalid. + global $user; $mdb2 = getConnection(); // Update group name if it changed. if ($fields['old_group_name'] != $fields['new_group_name']) { - $name = $mdb2->quote($fields['new_group_name']); - $sql = "update tt_teams set name = $name where id = $team_id"; + $name_part = 'name = '.$mdb2->quote($fields['new_group_name']); + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); + $sql = 'update tt_teams set '.$name_part.$modified_part.' where id = '.$team_id; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; } @@ -254,11 +256,35 @@ function updateTeam($team_id, $fields) { $password_part = ', password = md5('.$mdb2->quote($fields['password1']).')'; $name_part = ', name = '.$mdb2->quote($fields['user_name']); $email_part = ', email = '.$mdb2->quote($fields['email']); - - $sql = 'update tt_users set '.$login_part.$password_part.$name_part.$email_part.'where id = '.$user_id; + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); + $sql = 'update tt_users set '.$login_part.$password_part.$name_part.$email_part.$modified_part.'where id = '.$user_id; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; return true; } + + // setCreatedByAdmin sets created_by field for both group and its top manager to admin account. + function setCreatedByAdmin($team_id, $user_id) { + global $user; + $mdb2 = getConnection(); + + // Update created_by for group. + $sql = "update tt_teams set created_by = $user->id where id = $team_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) { + $this->err->add($i18n->getKey('error.db')); + return false; + } + + // Update created_by for top manager. + $sql = "update tt_users set created_by = $user->id where id = $user_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) { + $this->err->add($i18n->getKey('error.db')); + return false; + } + + return true; + } } diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index ea76f3a2f..3ac6166d3 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -81,10 +81,9 @@ function validate() { // The register function registers a user in Time Tracker. function register() { - global $i18n; + if ($this->err->yes()) return; // There are errors, do not proceed. - if ($this->err->yes()) - return; // There are errors, do not proceed. + global $i18n; import('ttUserHelper'); if (ttUserHelper::getUserByLogin($this->login)) { @@ -112,6 +111,8 @@ function register() { $err->add($i18n->getKey('error.db')); return; } + + $this->setCreatedBy($this->user_id); } // The createGroup function creates a group in Time Tracker as part @@ -151,17 +152,34 @@ function createUser() { $affected = $mdb2->exec($sql); if (!is_a($affected, 'PEAR_Error')) { $user_id = $mdb2->lastInsertID('tt_users', 'id'); + return $user_id; + } + return false; + } - // Update created_by field for the team with user id, now that we have it. - $sql = "update tt_teams set created_by = $user_id where id = $this->group_id and created_by is null"; - $affected = $mdb2->exec($sql); + // The setCreatedBy sets created_by field for both group and user to passed in user_id. + function setCreatedBy($user_id) { + if ($this->err->yes()) return false; // There are errors, do not proceed. + + global $i18n; + $mdb2 = getConnection(); - // Update created_by field for user by setting to self. - $sql = "update tt_users set created_by = $user_id where id = $user_id and team_id = $this->group_id and created_by is null"; - $affected = $mdb2->exec($sql); + // Update group. + $sql = "update tt_teams set created_by = $user_id where id = $this->group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) { + $this->err->add($i18n->getKey('error.db')); + return false; + } - return $user_id; + // Update top manager. + $sql = "update tt_users set created_by = $user_id where id = $user_id and team_id = $this->group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) { + $this->err->add($i18n->getKey('error.db')); + return false; } - return false; + + return true; } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0bbfc0348..f9d1e927d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4132 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4133 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_team_add.php b/admin_team_add.php index 08a193117..b270de172 100644 --- a/admin_team_add.php +++ b/admin_team_add.php @@ -81,44 +81,33 @@ $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_team_name, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.team_name')); - if (!ttValidString($cl_manager_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_name')); - if (!ttValidString($cl_manager_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_login')); - if (!$auth->isPasswordExternal()) { - if (!ttValidString($cl_password1)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); - } - if (!ttValidEmail($cl_manager_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + /* + * Note: creating a group by admin is pretty much the same as self-registration, + * except that created_by gields for group and user must be set to admin account. + * Therefore, we'll reuse ttRegistrator instance to create a group here + * and override created_by fields using ttRegistrator::setCreatedBy() function. + */ - if ($err->no()) { - if (!ttUserHelper::getUserByLogin($cl_manager_login)) { - // Create a new team. - if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); - $team_id = ttTeamHelper::insert(array('name'=>$cl_team_name,'currency'=>CURRENCY_DEFAULT,'lang'=>$cl_lang)); - if ($team_id) { - if (!ttRoleHelper::createPredefinedRoles($team_id, $cl_lang)) - $err->add($i18n->getKey('error.db')); + // Create fields array for ttRegistrator instance. + if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); + $fields = array( + 'user_name' => $cl_manager_name, + 'login' => $cl_manager_login, + 'password1' => $cl_password1, + 'password2' => $cl_password2, + 'email' => $cl_manager_email, + 'group_name' => $cl_team_name, + 'currency' => CURRENCY_DEFAULT, + 'lang' => $cl_lang); - $role_id = ttRoleHelper::getTopManagerRoleID(); - - // Team created, now create a team manager. - $user_id = ttUserHelper::insert(array( - 'team_id' => $team_id, - 'role_id' => $role_id, - 'name' => $cl_manager_name, - 'login' => $cl_manager_login, - 'password' => $cl_password1, - 'email' => $cl_manager_email)); - } - if ($team_id && $user_id) { - header('Location: admin_teams.php'); - } else - $err->add($i18n->getKey('error.db')); - } else - $err->add($i18n->getKey('error.user_exists')); + // Create an instance of ttRegistrator class. + import('ttRegistrator'); + $registrator = new ttRegistrator($fields, $err); + $registrator->register(); + $registrator->setCreatedBy($user->id); // Override created_by to admin account. + if ($err->no()) { + header('Location: admin_teams.php'); + exit(); } } // isPost From bcff87ad905e60d848029cf5643c8c02191ca346 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Mar 2018 18:23:59 +0000 Subject: [PATCH 0013/1848] Removed unused function. --- WEB-INF/lib/ttAdmin.class.php | 24 ------------------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index d6b9696a1..9e29eeebf 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -263,28 +263,4 @@ function updateTeam($team_id, $fields) { return true; } - - // setCreatedByAdmin sets created_by field for both group and its top manager to admin account. - function setCreatedByAdmin($team_id, $user_id) { - global $user; - $mdb2 = getConnection(); - - // Update created_by for group. - $sql = "update tt_teams set created_by = $user->id where id = $team_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) { - $this->err->add($i18n->getKey('error.db')); - return false; - } - - // Update created_by for top manager. - $sql = "update tt_users set created_by = $user->id where id = $user_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) { - $this->err->add($i18n->getKey('error.db')); - return false; - } - - return true; - } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f9d1e927d..9427fe9d8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4133 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4134 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e80e19c6b609af8e06403a337a5cd46200ab4fc6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Mar 2018 19:52:28 +0000 Subject: [PATCH 0014/1848] Switched from timestamp to created column in a query. --- WEB-INF/lib/ttTeamHelper.class.php | 8 ++++---- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 6dede8b23..27f31bb32 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -693,12 +693,12 @@ static function getTeams() { $result = array(); $mdb2 = getConnection(); - $sql = "select id, name, lang, timestamp from tt_teams where status = 1 order by id desc"; + $sql = "select id, name, created, lang from tt_teams where status = 1 order by id desc"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { - $val['date'] = substr($val['timestamp'], 0, 10); // Strip the time. + $val['date'] = substr($val['created'], 0, 10); // Strip the time. $result[] = $val; } return $result; @@ -914,9 +914,9 @@ static function getInactiveTeams() { $inactive_teams = array(); $mdb2 = getConnection(); - // Get all team ids for teams created or modified more than 6 months ago. + // Get all team ids for teams created or modified more than 8 months ago. // $ts = date('Y-m-d', strtotime('-1 year')); - $ts = date('Y-m-d', strtotime('-6 month')); + $ts = date('Y-m-d', strtotime('-8 month')); $sql = "select id from tt_teams where timestamp < '$ts' order by id"; $res = $mdb2->query($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9427fe9d8..27a3ad38c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4134 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4135 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 7fb35e831..9f6972c93 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -851,6 +851,7 @@ function setChange($sql) { setChange("ALTER TABLE `tt_teams` ADD `modified_ip` varchar(45) default NULL AFTER `modified`"); setChange("ALTER TABLE `tt_teams` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.65', modified = now() where param_name = 'version_db' and param_value = '1.17.64'"); + setChange("update `tt_teams` t inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.65') set t.created = t.timestamp where t.created is null"); } if ($_POST["cleanup"]) { From 6753e281196a94e8a50d9c98d5195093e61fcefb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Mar 2018 20:27:44 +0000 Subject: [PATCH 0015/1848] Introduced ttGroupHelper class as part of refactoring. --- WEB-INF/lib/ttGroupHelper.class.php | 51 +++++++++++++++++++++++++++++ WEB-INF/lib/ttTeamHelper.class.php | 18 ---------- WEB-INF/templates/footer.tpl | 2 +- admin_teams.php | 5 ++- login.php | 4 +-- mobile/login.php | 4 +-- 6 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 WEB-INF/lib/ttGroupHelper.class.php diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php new file mode 100644 index 000000000..9fcb8443e --- /dev/null +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -0,0 +1,51 @@ +query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $val['date'] = substr($val['created'], 0, 10); // Strip the time. + $result[] = $val; + } + return $result; + } + return false; + } +} diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 27f31bb32..1c9e30fd1 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -688,24 +688,6 @@ static function getMonthlyQuotas($team_id) { return false; } - // The getTeams function returns an array of all active teams on the server. - static function getTeams() { - $result = array(); - $mdb2 = getConnection(); - - $sql = "select id, name, created, lang from tt_teams where status = 1 order by id desc"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $val['date'] = substr($val['created'], 0, 10); // Strip the time. - $result[] = $val; - } - return $result; - } - return false; - } - // The markDeleted function marks the team and everything in it as deleted. static function markDeleted($team_id) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 27a3ad38c..1ddc76d92 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4135 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4136 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_teams.php b/admin_teams.php index 9c3d2092c..55df54fc5 100644 --- a/admin_teams.php +++ b/admin_teams.php @@ -27,8 +27,7 @@ // +----------------------------------------------------------------------+ require_once('initialize.php'); -import('form.Form'); -import('ttTeamHelper'); +import('ttGroupHelper'); // Access check. if (!ttAccessAllowed('administer_site')) { @@ -36,7 +35,7 @@ exit(); } -$smarty->assign('teams', ttTeamHelper::getTeams()); +$smarty->assign('teams', ttGroupHelper::getTopGroups()); $smarty->assign('title', $i18n->getKey('title.teams')); $smarty->assign('content_page_name', 'admin_teams.tpl'); $smarty->display('index.tpl'); diff --git a/login.php b/login.php index d398794c4..538147b02 100644 --- a/login.php +++ b/login.php @@ -28,7 +28,7 @@ require_once('initialize.php'); import('form.Form'); -import('ttTeamHelper'); +import('ttGroupHelper'); import('ttUser'); $cl_login = $request->getParameter('login'); @@ -75,7 +75,7 @@ } } // isPost -if(!isTrue(MULTITEAM_MODE) && !ttTeamHelper::getTeams()) +if(!isTrue(MULTITEAM_MODE) && !ttGroupHelper::getTopGroups()) $err->add($i18n->getKey('error.no_teams')); // Determine whether to show login hint. It is currently used only for Windows LDAP authentication. diff --git a/mobile/login.php b/mobile/login.php index 538a0b544..384cf8c7f 100644 --- a/mobile/login.php +++ b/mobile/login.php @@ -28,7 +28,7 @@ require_once('../initialize.php'); import('form.Form'); -import('ttTeamHelper'); +import('ttGroupHelper'); import('ttUser'); if ($request->isPost()) { @@ -80,7 +80,7 @@ } } // isPost -if(!isTrue(MULTITEAM_MODE) && !ttTeamHelper::getTeams()) +if(!isTrue(MULTITEAM_MODE) && !ttGroupHelper::getTopGroups()) $err->add($i18n->getKey('error.no_teams')); // Determine whether to show login hint. It is currently used only for Windows LDAP authentication. From e616d14ff2173bd13155592c0bdba23636376ffe Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Mar 2018 23:49:20 +0000 Subject: [PATCH 0016/1848] Moving away from using the timestamp field. --- WEB-INF/lib/ttAdmin.class.php | 15 ++++++++++----- WEB-INF/lib/ttTeamHelper.class.php | 8 ++++---- WEB-INF/templates/footer.tpl | 2 +- admin_options.php | 20 ++++++++++++++++++++ admin_team_edit.php | 2 +- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index 9e29eeebf..87fe00bca 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -183,8 +183,8 @@ function markGroupDeleted($group_id) { return true; } - // validateTeamInfo validates team information entered by user. - function validateTeamInfo($fields) { + // validateGroupInfo validates group information entered by user. + function validateGroupInfo($fields) { global $i18n; global $auth; @@ -233,9 +233,9 @@ function validateTeamInfo($fields) { return $result; } - // updateTeam validates user input and updates the team with new information. - function updateTeam($team_id, $fields) { - if (!$this->validateTeamInfo($fields)) return false; // Can't continue as user input is invalid. + // updateGroup validates user input and updates the group with new information. + function updateGroup($team_id, $fields) { + if (!$this->validateGroupInfo($fields)) return false; // Can't continue as user input is invalid. global $user; $mdb2 = getConnection(); @@ -263,4 +263,9 @@ function updateTeam($team_id, $fields) { return true; } + + // updateSelf validates user input and updates admin account with new information. + function updateSelf($fields) { + return false; // Not yet implemeneted. + } } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 1c9e30fd1..9f3e0a902 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -898,8 +898,8 @@ static function getInactiveTeams() { // Get all team ids for teams created or modified more than 8 months ago. // $ts = date('Y-m-d', strtotime('-1 year')); - $ts = date('Y-m-d', strtotime('-8 month')); - $sql = "select id from tt_teams where timestamp < '$ts' order by id"; + $ts = $mdb2->quote(date('Y-m-d', strtotime('-8 month'))); + $sql = "select id from tt_teams where created < $ts and (modified is null or modified < $ts) order by id"; $res = $mdb2->query($sql); $count = 0; @@ -935,7 +935,7 @@ static function isTeamActive($team_id) { $count = 0; $ts = date('Y-m-d', strtotime('-2 years')); - $sql = "select count(*) as cnt from tt_log where user_id in ($user_list) and timestamp > '$ts'"; + $sql = "select count(*) as cnt from tt_log where user_id in ($user_list) and created > '$ts'"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) { @@ -950,7 +950,7 @@ static function isTeamActive($team_id) { // We will consider a team inactive if it has 5 or less time entries made more than 1 year ago. $count_last_year = 0; $ts = date('Y-m-d', strtotime('-1 year')); - $sql = "select count(*) as cnt from tt_log where user_id in ($user_list) and timestamp > '$ts'"; + $sql = "select count(*) as cnt from tt_log where user_id in ($user_list) and created > '$ts'"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1ddc76d92..0427ace0d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4136 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4137 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_options.php b/admin_options.php index 6f8125589..e728c830f 100644 --- a/admin_options.php +++ b/admin_options.php @@ -61,6 +61,26 @@ $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); if ($request->isPost()) { +/* + * This is work in progress... refactoring to replace the block below. + + // Create fields array for ttAdmin instance. + $fields = array( + 'name' => $cl_name, + 'login' => $cl_login, + 'password1' => $cl_password1, + 'password2' => $cl_password2, + 'email' => $cl_email); + + import('ttAdmin'); + $admin = new ttAdmin($err); + $result = $admin->updateSelf($fields); + if ($result) { + header('Location: admin_teams.php'); + exit(); + } + */ + // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.person_name')); if (!ttValidString($cl_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); diff --git a/admin_team_edit.php b/admin_team_edit.php index 428845855..63f8fe7ad 100644 --- a/admin_team_edit.php +++ b/admin_team_edit.php @@ -88,7 +88,7 @@ import('ttAdmin'); $admin = new ttAdmin($err); - $result = $admin->updateTeam($team_id, $fields); + $result = $admin->updateGroup($team_id, $fields); if ($result) { header('Location: admin_teams.php'); exit(); From c360da4bcfd113a87bc156e0f009e968d8a8bf07 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 00:59:41 +0000 Subject: [PATCH 0017/1848] Update for tt_users created field. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0427ace0d..3fa67d5ad 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.65.4137 | Copyright © Anuko | +  Anuko Time Tracker 1.17.65.4138 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 9f6972c93..b04a1f69e 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -852,6 +852,7 @@ function setChange($sql) { setChange("ALTER TABLE `tt_teams` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.65', modified = now() where param_name = 'version_db' and param_value = '1.17.64'"); setChange("update `tt_teams` t inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.65') set t.created = t.timestamp where t.created is null"); + setChange("update `tt_users` u inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.65') set u.created = u.timestamp where u.created is null"); } if ($_POST["cleanup"]) { From 7243c8da5a23936555f2a7adc1abf6f297a4e746 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 01:17:18 +0000 Subject: [PATCH 0018/1848] Dropping timestamp columns from tt_teams and tt_users. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 4 +--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3fa67d5ad..4dc0027ed 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.65.4138 | Copyright © Anuko | +  Anuko Time Tracker 1.17.66.4139 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index b04a1f69e..9c2d041b6 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11765"]) { + if ($_POST["convert11744to11766"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -853,6 +853,9 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.17.65', modified = now() where param_name = 'version_db' and param_value = '1.17.64'"); setChange("update `tt_teams` t inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.65') set t.created = t.timestamp where t.created is null"); setChange("update `tt_users` u inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.65') set u.created = u.timestamp where u.created is null"); + setChange("ALTER TABLE `tt_teams` drop `timestamp`"); + setChange("ALTER TABLE `tt_users` drop `timestamp`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.66', modified = now() where param_name = 'version_db' and param_value = '1.17.65'"); } if ($_POST["cleanup"]) { @@ -898,7 +901,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.65) + Create database structure (v1.17.66)
(applies only to new installations, do not execute when updating)
@@ -938,8 +941,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.65)Update database structure (v1.17.44 to v1.17.66)
diff --git a/mysql.sql b/mysql.sql index cc4ffb0df..48ec08331 100644 --- a/mysql.sql +++ b/mysql.sql @@ -14,7 +14,6 @@ # CREATE TABLE `tt_teams` ( `id` int(11) NOT NULL auto_increment, # team id - `timestamp` timestamp default CURRENT_TIMESTAMP, # Modification timestamp. TODO: redo all timestamps to survive beyond 2038. `name` varchar(80) default NULL, # team name `currency` varchar(7) default NULL, # team currency symbol `decimal_mark` char(1) NOT NULL default '.', # separator in decimals @@ -80,7 +79,6 @@ INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top man # CREATE TABLE `tt_users` ( `id` int(11) NOT NULL auto_increment, # user id - `timestamp` timestamp default CURRENT_TIMESTAMP, # modification timestamp `login` varchar(50) COLLATE utf8_bin NOT NULL, # user login `password` varchar(50) default NULL, # password hash `name` varchar(100) default NULL, # user name @@ -452,4 +450,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.65', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.66', now()); # TODO: change when structure changes. From 7ca15b5853146dd809f2ad3f5b2e1d9dab4f8dd4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 11:56:01 +0000 Subject: [PATCH 0019/1848] Refactored admin_options.php to use ttAdmin instance. --- WEB-INF/lib/ttAdmin.class.php | 82 +++++++++++++++++++++++++---- WEB-INF/lib/ttRegistrator.class.php | 15 +++--- WEB-INF/templates/footer.tpl | 2 +- admin_options.php | 45 +++------------- 4 files changed, 89 insertions(+), 55 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index 87fe00bca..6008dcab3 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -31,8 +31,8 @@ // ttAdmin class is used to perform admin tasks. class ttAdmin { - var $err = null; // Error object, passed to us as reference. - // We use it to communicate errors to caller. + var $err = null; // Error object, passed to us as reference. + // We use it to communicate errors to caller. // Constructor. function __construct(&$err = null) { @@ -65,22 +65,19 @@ function markUserDeleted($user_id) { // Mark user binds as deleted. $sql = "update tt_user_project_binds set status = NULL where user_id = $user_id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; + if (is_a($affected, 'PEAR_Error')) return false; // Mark favorite reports as deleted. $sql = "update tt_fav_reports set status = NULL where user_id = $user_id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; + if (is_a($affected, 'PEAR_Error')) return false; // Mark user as deleted. global $user; $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); $sql = "update tt_users set status = NULL $modified_part where id = $user_id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; + if (is_a($affected, 'PEAR_Error')) return false; return true; } @@ -104,6 +101,7 @@ function markTasksDeleted($group_id) { $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; } + return true; } @@ -264,8 +262,74 @@ function updateGroup($team_id, $fields) { return true; } + // validateUserInfo validates account information entered by user. + function validateUserInfo($fields) { + global $i18n; + global $user; + global $auth; + + $result = true; + + if (!ttValidString($fields['name'])) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.person_name')); + $result = false; + } + if (!ttValidString($fields['login'])) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); + $result = false; + } + // If we change login, it must be unique. + if ($fields['login'] != $user->login) { + if (ttUserHelper::getUserByLogin($fields['login'])) { + $this->err->add($i18n->getKey('error.user_exists')); + $result = false; + } + } + if (!$auth->isPasswordExternal() && ($fields['password1'] || $fields['password2'])) { + if (!ttValidString($fields['password1'])) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); + $result = false; + } + if (!ttValidString($fields['password2'])) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + $result = false; + } + if ($fields['password1'] !== $fields['password2']) { + $this->err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $result = false; + } + } + if (!ttValidEmail($fields['email'], true)) { + $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + $result = false; + } + + return $result; + } + // updateSelf validates user input and updates admin account with new information. function updateSelf($fields) { - return false; // Not yet implemeneted. + if (!$this->validateUserInfo($fields)) return false; // Can't continue as user input is invalid. + + global $user; + global $i18n; + $mdb2 = getConnection(); + + // Update self. + $user_id = $user->id; + $login_part = 'login = '.$mdb2->quote($fields['login']); + if ($fields['password1']) + $password_part = ', password = md5('.$mdb2->quote($fields['password1']).')'; + $name_part = ', name = '.$mdb2->quote($fields['name']); + $email_part = ', email = '.$mdb2->quote($fields['email']); + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); + $sql = 'update tt_users set '.$login_part.$password_part.$name_part.$email_part.$modified_part.'where id = '.$user_id; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) { + $this->err->add($i18n->getKey('error.db')); + return false; + } + + return true; } } diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 3ac6166d3..71f49e690 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -81,7 +81,7 @@ function validate() { // The register function registers a user in Time Tracker. function register() { - if ($this->err->yes()) return; // There are errors, do not proceed. + if ($this->err->yes()) return false; // There are errors, do not proceed. global $i18n; @@ -89,30 +89,33 @@ function register() { if (ttUserHelper::getUserByLogin($this->login)) { // User login already exists. $this->err->add($i18n->getKey('error.user_exists')); - return; + return false; } // Create a new group. $this->group_id = $this->createGroup(); if (!$this->group_id) { $this->err->add($i18n->getKey('error.db')); - return; + return false; } import('ttRoleHelper'); if (!ttRoleHelper::createPredefinedRoles($this->group_id, $this->lang)) { $err->add($i18n->getKey('error.db')); - return; + return false; } $this->role_id = ttRoleHelper::getTopManagerRoleID(); $this->user_id = $this->createUser(); if (!$this->user_id) { $err->add($i18n->getKey('error.db')); - return; + return false; } - $this->setCreatedBy($this->user_id); + if (!$this->setCreatedBy($this->user_id)) + return false; + + return true; } // The createGroup function creates a group in Time Tracker as part diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4dc0027ed..efe88efdd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.66.4139 | Copyright © Anuko | +  Anuko Time Tracker 1.17.66.4140 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_options.php b/admin_options.php index e728c830f..14cb3f54c 100644 --- a/admin_options.php +++ b/admin_options.php @@ -61,9 +61,6 @@ $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); if ($request->isPost()) { -/* - * This is work in progress... refactoring to replace the block below. - // Create fields array for ttAdmin instance. $fields = array( 'name' => $cl_name, @@ -72,42 +69,12 @@ 'password2' => $cl_password2, 'email' => $cl_email); - import('ttAdmin'); - $admin = new ttAdmin($err); - $result = $admin->updateSelf($fields); - if ($result) { - header('Location: admin_teams.php'); - exit(); - } - */ - - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); - // New login must be unique. - if ($cl_login != $user->login && ttUserHelper::getUserByLogin($cl_login)) - $err->add($i18n->getKey('error.user_exists')); - if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { - if (!ttValidString($cl_password1)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); - } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); - // Finished validating user input. - - if ($err->no()) { - if (ttUserHelper::update($user->id, array( - 'name' => $cl_name, - 'login' => $cl_login, - 'password' => $cl_password1, - 'email' => $cl_email, - 'status' => ACTIVE))) { - header('Location: admin_teams.php'); - exit(); - } else { - $err->add($i18n->getKey('error.db')); - } + import('ttAdmin'); + $admin = new ttAdmin($err); + $result = $admin->updateSelf($fields); + if ($result) { + header('Location: admin_teams.php'); + exit(); } } // isPost From da435f04300629fd13e7c2c90c3bbd3a8dc349aa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 14:25:28 +0000 Subject: [PATCH 0020/1848] Fixed a problem with deleting teams by supplying a required parameter. --- WEB-INF/lib/ttAdmin.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index 6008dcab3..d4b72e2e9 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -111,7 +111,7 @@ function markGroupDeleted($group_id) { // Keep the logic simple by returning false on first error. // Obtain subgroups and call self recursively on them. - $subgroups = $this->getSubgroups(); + $subgroups = $this->getSubgroups($group_id); foreach($subgroups as $subgroup) { if (!$this->markGroupDeleted($subgroup['id'])) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index efe88efdd..881616e0d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- \n"; } - $str .= "\n"; + $str .= "\n"; $str .= "
 Anuko Time Tracker 1.17.66.4140 | Copyright © Anuko | +  Anuko Time Tracker 1.17.67.4141 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 75b65e92b21d45e2b09fb12daef169fb214a7acd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 15:03:09 +0000 Subject: [PATCH 0021/1848] Refactoring. Replacing getKey() with get(). --- WEB-INF/lib/I18n.class.php | 15 +++++++---- WEB-INF/lib/form/Calendar.class.php | 2 +- WEB-INF/lib/form/CheckboxGroup.class.php | 4 +-- WEB-INF/lib/form/DateField.class.php | 6 ++--- WEB-INF/lib/ttAdmin.class.php | 32 ++++++++++++------------ WEB-INF/lib/ttImportHelper.class.php | 6 ++--- WEB-INF/lib/ttInvoiceHelper.class.php | 30 +++++++++++----------- WEB-INF/lib/ttRegistrator.class.php | 28 ++++++++++----------- WEB-INF/templates/footer.tpl | 2 +- 9 files changed, 65 insertions(+), 60 deletions(-) diff --git a/WEB-INF/lib/I18n.class.php b/WEB-INF/lib/I18n.class.php index 7155edb0c..ed7497d70 100644 --- a/WEB-INF/lib/I18n.class.php +++ b/WEB-INF/lib/I18n.class.php @@ -35,23 +35,28 @@ class I18n { var $holidays; var $keys = array(); // These are our localized strings. - // The getKey obtains localized keyword value. - function getKey($kword) { + // get - obtains a localized value from $keys array. + function get($key) { $value = ''; - $pos = strpos($kword, '.'); // Keywords can have separating dots such as in form.login.about. + $pos = strpos($key, '.'); // Keywords can have separating dots such as in form.login.about. if (!($pos === false)) { - $words = explode('.', $kword); + $words = explode('.', $key); $str = ''; foreach ($words as $word) { $str .= "['".$word."']"; } eval("\$value = \$this->keys".$str.";"); } else { - $value = $this->keys[$kword]; + $value = $this->keys[$key]; } return $value; } + // getKey is a legacy function that we are replacing with get. + function getKey($kword) { + return $this->get($kword); + } + // TODO: refactoring ongoing down from here... function getWeekDayName($id) { $id = (int) $id; diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index 555b6e149..4c835f62e 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -207,7 +207,7 @@ function toString($date="") { $str .= "
controlName."=".strftime(DB_DATEFORMAT)."\" tabindex=\"-1\">".$i18n->getKey('label.today')."
controlName."=".strftime(DB_DATEFORMAT)."\" tabindex=\"-1\">".$i18n->get('label.today')."
\n"; $str .= "controlName\" value=\"$indate\">\n"; diff --git a/WEB-INF/lib/form/CheckboxGroup.class.php b/WEB-INF/lib/form/CheckboxGroup.class.php index 810c96311..9488b5cce 100644 --- a/WEB-INF/lib/form/CheckboxGroup.class.php +++ b/WEB-INF/lib/form/CheckboxGroup.class.php @@ -60,8 +60,8 @@ function getGroupIn() { return $this->mGroupIn; } function localize() { global $i18n; - $this->lSelAll = $i18n->getKey('label.select_all'); - $this->lSelNone = $i18n->getKey('label.select_none'); + $this->lSelAll = $i18n->get('label.select_all'); + $this->lSelNone = $i18n->get('label.select_none'); } function getHtml() { diff --git a/WEB-INF/lib/form/DateField.class.php b/WEB-INF/lib/form/DateField.class.php index f8eef8cb8..9016dff0c 100644 --- a/WEB-INF/lib/form/DateField.class.php +++ b/WEB-INF/lib/form/DateField.class.php @@ -52,9 +52,9 @@ function localize() { $this->mMonthNames = $i18n->monthNames; $this->mWeekDayShortNames = $i18n->weekdayShortNames; - $this->lToday = $i18n->getKey('label.today'); - $this->lCalendarButtons['today'] = $i18n->getKey('label.today'); - $this->lCalendarButtons['close'] = $i18n->getKey('button.close'); + $this->lToday = $i18n->get('label.today'); + $this->lCalendarButtons['today'] = $i18n->get('label.today'); + $this->lCalendarButtons['close'] = $i18n->get('button.close'); $this->mDateFormat = $user->date_format; $this->mWeekStartDay = $user->week_start; diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index d4b72e2e9..fbcabd476 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -189,42 +189,42 @@ function validateGroupInfo($fields) { $result = true; if (!ttValidString($fields['group_name'], true)) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.team_name')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.team_name')); $result = false; } if (!ttValidString($fields['user_name'])) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_name')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.manager_name')); $result = false; } if (!ttValidString($fields['new_login'])) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_login')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.manager_login')); $result = false; } // If we change login, it must be unique. if ($fields['new_login'] != $fields['old_login']) { if (ttUserHelper::getUserByLogin($fields['new_login'])) { - $this->err->add($i18n->getKey('error.user_exists')); + $this->err->add($i18n->get('error.user_exists')); $result = false; } } if (!$auth->isPasswordExternal() && ($fields['password1'] || $fields['password2'])) { if (!ttValidString($fields['password1'])) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.password')); $result = false; } if (!ttValidString($fields['password2'])) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); $result = false; } if ($fields['password1'] !== $fields['password2']) { - $this->err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $this->err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); $result = false; } } if (!ttValidEmail($fields['email'], true)) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.email')); $result = false; } @@ -271,36 +271,36 @@ function validateUserInfo($fields) { $result = true; if (!ttValidString($fields['name'])) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.person_name')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.person_name')); $result = false; } if (!ttValidString($fields['login'])) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.login')); $result = false; } // If we change login, it must be unique. if ($fields['login'] != $user->login) { if (ttUserHelper::getUserByLogin($fields['login'])) { - $this->err->add($i18n->getKey('error.user_exists')); + $this->err->add($i18n->get('error.user_exists')); $result = false; } } if (!$auth->isPasswordExternal() && ($fields['password1'] || $fields['password2'])) { if (!ttValidString($fields['password1'])) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.password')); $result = false; } if (!ttValidString($fields['password2'])) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); $result = false; } if ($fields['password1'] !== $fields['password2']) { - $this->err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $this->err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); $result = false; } } if (!ttValidEmail($fields['email'], true)) { - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.email')); $result = false; } @@ -326,7 +326,7 @@ function updateSelf($fields) { $sql = 'update tt_users set '.$login_part.$password_part.$name_part.$email_part.$modified_part.'where id = '.$user_id; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) { - $this->err->add($i18n->getKey('error.db')); + $this->err->add($i18n->get('error.db')); return false; } diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 55fd15407..ca717caef 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -371,13 +371,13 @@ function importXml() { // If the file is compressed - uncompress it. if ($compressed) { if (!$this->uncompress($_FILES['xmlfile']['tmp_name'], $filename)) { - $this->errors->add($i18n->getKey('error.sys')); + $this->errors->add($i18n->get('error.sys')); return; } unlink($_FILES['xmlfile']['tmp_name']); } else { if (!move_uploaded_file($_FILES['xmlfile']['tmp_name'], $filename)) { - $this->errors->add($i18n->getKey('error.upload')); + $this->errors->add($i18n->get('error.upload')); return; } } @@ -397,7 +397,7 @@ function importXml() { xml_get_current_line_number($parser))); } if (!$this->canImport) { - $this->errors->add($i18n->getKey('error.user_exists')); + $this->errors->add($i18n->get('error.user_exists')); break; } } diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index fd701fe51..d58bc1161 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -429,16 +429,16 @@ static function prepareInvoiceBody($invoice_id, $comment) $body .= ''; // Output title. - $body .= '

'.$i18n->getKey('title.invoice').' '.htmlspecialchars($invoice['name']).'

'; + $body .= '

'.$i18n->get('title.invoice').' '.htmlspecialchars($invoice['name']).'

'; // Output comment. if($comment) $body .= '

'.htmlspecialchars($comment).'

'; // Output invoice info. $body .= ''; - $body .= ''; - $body .= ''; - $body .= ''; + $body .= ''; + $body .= ''; + $body .= ''; $body .= '
'.$i18n->getKey('label.date').': '.$invoice['date'].'
'.$i18n->getKey('label.client').': '.htmlspecialchars($client['name']).'
'.$i18n->getKey('label.client_address').': '.htmlspecialchars($client['address']).'
'.$i18n->get('label.date').': '.$invoice['date'].'
'.$i18n->get('label.client').': '.htmlspecialchars($client['name']).'
'.$i18n->get('label.client_address').': '.htmlspecialchars($client['address']).'
'; $body .= '

'; @@ -446,15 +446,15 @@ static function prepareInvoiceBody($invoice_id, $comment) // Output invoice items. $body .= ''; $body .= ''; - $body .= ''; - $body .= ''; + $body .= ''; + $body .= ''; if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) - $body .= ''; + $body .= ''; if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) - $body .= ''; - $body .= ''; - $body .= ''; - $body .= ''; + $body .= ''; + $body .= ''; + $body .= ''; + $body .= ''; $body .= ''; foreach ($invoice_items as $item) { $body .= ''; @@ -477,15 +477,15 @@ static function prepareInvoiceBody($invoice_id, $comment) $colspan += 2; $body .= ''; if ($tax) { - $body .= ''; - $body .= ''; + $body .= ''; + $body .= ''; } - $body .= ''; + $body .= ''; $body .= '
'.$i18n->getKey('label.date').''.$i18n->getKey('form.invoice.person').''.$i18n->get('label.date').''.$i18n->get('form.invoice.person').''.$i18n->getKey('label.project').''.$i18n->get('label.project').''.$i18n->getKey('label.task').''.$i18n->getKey('label.note').''.$i18n->getKey('label.duration').''.$i18n->getKey('label.cost').''.$i18n->get('label.task').''.$i18n->get('label.note').''.$i18n->get('label.duration').''.$i18n->get('label.cost').'
 
'.$i18n->getKey('label.subtotal').':'.$subtotal.'
'.$i18n->getKey('label.tax').':'.$tax.'
'.$i18n->get('label.subtotal').':'.$subtotal.'
'.$i18n->get('label.tax').':'.$tax.'
'.$i18n->getKey('label.total').':'.$total.'
'.$i18n->get('label.total').':'.$total.'
'; // Output footer. if (!defined('REPORT_FOOTER') || !(REPORT_FOOTER == false)) - $body .= '

'.$i18n->getKey('form.mail.footer').'

'; + $body .= '

'.$i18n->get('form.mail.footer').'

'; // Finish creating email body. $body .= ''; diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 71f49e690..7082e6bc2 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -62,21 +62,21 @@ function validate() { global $i18n; if (!ttValidString($this->group_name, true)) - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.team_name')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.team_name')); if (!ttValidString($this->currency, true)) - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.currency')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.currency')); if (!ttValidString($this->user_name)) - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_name')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.manager_name')); if (!ttValidString($this->login)) - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.manager_login')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.manager_login')); if (!ttValidString($this->password1)) - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.password')); if (!ttValidString($this->password2)) - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($this->password1 !== $this->password2) - $this->err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $this->err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); if (!ttValidEmail($this->email, true)) - $this->err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + $this->err->add($i18n->get('error.field'), $i18n->get('label.email')); } // The register function registers a user in Time Tracker. @@ -88,27 +88,27 @@ function register() { import('ttUserHelper'); if (ttUserHelper::getUserByLogin($this->login)) { // User login already exists. - $this->err->add($i18n->getKey('error.user_exists')); + $this->err->add($i18n->get('error.user_exists')); return false; } // Create a new group. $this->group_id = $this->createGroup(); if (!$this->group_id) { - $this->err->add($i18n->getKey('error.db')); + $this->err->add($i18n->get('error.db')); return false; } import('ttRoleHelper'); if (!ttRoleHelper::createPredefinedRoles($this->group_id, $this->lang)) { - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); return false; } $this->role_id = ttRoleHelper::getTopManagerRoleID(); $this->user_id = $this->createUser(); if (!$this->user_id) { - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); return false; } @@ -171,7 +171,7 @@ function setCreatedBy($user_id) { $sql = "update tt_teams set created_by = $user_id where id = $this->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) { - $this->err->add($i18n->getKey('error.db')); + $this->err->add($i18n->get('error.db')); return false; } @@ -179,7 +179,7 @@ function setCreatedBy($user_id) { $sql = "update tt_users set created_by = $user_id where id = $user_id and team_id = $this->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) { - $this->err->add($i18n->getKey('error.db')); + $this->err->add($i18n->get('error.db')); return false; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 881616e0d..d92f371af 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.67.4141 | Copyright © Anuko | +  Anuko Time Tracker 1.17.67.4142 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 5f64df1308fd641565631e6e38d282432f5e6250 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 15:27:29 +0000 Subject: [PATCH 0022/1848] Refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 92 +++++++++++++------------- WEB-INF/lib/ttRoleHelper.class.php | 40 +++++------ WEB-INF/lib/ttTeamHelper.class.php | 2 +- WEB-INF/lib/ttWeekViewHelper.class.php | 22 +++--- WEB-INF/templates/footer.tpl | 2 +- access_denied.php | 4 +- admin_options.php | 4 +- admin_team_add.php | 4 +- admin_team_delete.php | 8 +-- admin_team_edit.php | 6 +- admin_teams.php | 2 +- cf_custom_field_add.php | 12 ++-- 12 files changed, 99 insertions(+), 99 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 1f797ace4..b894b037d 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1188,7 +1188,7 @@ static function prepareReportBody($bean, $comment) $body .= ''; // Output title. - $body .= '

'.$i18n->getKey('form.mail.report_subject').': '.$totals['start_date'].' - '.$totals['end_date'].'

'; + $body .= '

'.$i18n->get('form.mail.report_subject').': '.$totals['start_date'].' - '.$totals['end_date'].'

'; // Output comment. if ($comment) $body .= '

'.htmlspecialchars($comment).'

'; @@ -1201,16 +1201,16 @@ static function prepareReportBody($bean, $comment) $group_by_header = htmlspecialchars($custom_fields->fields[0]['label']); else { $key = 'label.'.$group_by; - $group_by_header = $i18n->getKey($key); + $group_by_header = $i18n->get($key); } $body .= ''; $body .= ''; $body .= ''; if ($bean->getAttribute('chduration')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chcost')) - $body .= ''; + $body .= ''; $body .= ''; foreach($subtotals as $subtotal) { $body .= ''; @@ -1231,7 +1231,7 @@ static function prepareReportBody($bean, $comment) // Print totals. $body .= ''; $body .= ''; - $body .= ''; + $body .= ''; if ($bean->getAttribute('chduration')) { $body .= '
'.$group_by_header.''.$i18n->getKey('label.duration').''.$i18n->get('label.duration').''.$i18n->getKey('label.cost').''.$i18n->get('label.cost').'
 
'.$i18n->getKey('label.total').''.$i18n->get('label.total').''; if ($totals['time'] <> '0:00') $body .= $totals['time']; @@ -1251,33 +1251,33 @@ static function prepareReportBody($bean, $comment) // Print table header. $body .= ''; $body .= ''; - $body .= ''; + $body .= ''; if ($canViewReports || $isClient) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chclient')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chproject')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chtask')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chcf_1')) $body .= ''; if ($bean->getAttribute('chstart')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chfinish')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chduration')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chnote')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chcost')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chpaid')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chip')) - $body .= ''; + $body .= ''; if ($bean->getAttribute('chinvoice')) - $body .= ''; + $body .= ''; $body .= ''; // Initialize variables to print subtotals. @@ -1301,7 +1301,7 @@ static function prepareReportBody($bean, $comment) $cur_grouped_by = $record['grouped_by']; if ($cur_grouped_by != $prev_grouped_by && !$first_pass) { $body .= ''; - $body .= ''; + $body .= ''; $subtotal_name = htmlspecialchars($subtotals[$prev_grouped_by]['name']); if ($canViewReports || $isClient) $body .= ''; if ($bean->getAttribute('chclient')) $body .= ''; @@ -1353,7 +1353,7 @@ static function prepareReportBody($bean, $comment) $body .= ''; if ($bean->getAttribute('chpaid')) { $body .= ''; } if ($bean->getAttribute('chip')) { @@ -1374,7 +1374,7 @@ static function prepareReportBody($bean, $comment) // Print a terminating subtotal. if ($print_subtotals) { $body .= ''; - $body .= ''; + $body .= ''; $subtotal_name = htmlspecialchars($subtotals[$cur_grouped_by]['name']); if ($canViewReports || $isClient) $body .= ''; if ($bean->getAttribute('chclient')) $body .= ''; @@ -1399,7 +1399,7 @@ static function prepareReportBody($bean, $comment) // Print totals. $body .= ''; $body .= ''; - $body .= ''; + $body .= ''; if ($canViewReports || $isClient) $body .= ''; if ($bean->getAttribute('chclient')) $body .= ''; if ($bean->getAttribute('chproject')) $body .= ''; @@ -1424,7 +1424,7 @@ static function prepareReportBody($bean, $comment) // Output footer. if (!defined('REPORT_FOOTER') || !(REPORT_FOOTER == false)) - $body .= '

'.$i18n->getKey('form.mail.footer').'

'; + $body .= '

'.$i18n->get('form.mail.footer').'

'; // Finish creating email body. $body .= ''; @@ -1484,7 +1484,7 @@ static function prepareFavReportBody($report) $body .= ''; // Output title. - $body .= '

'.$i18n->getKey('form.mail.report_subject').': '.$totals['start_date'].' - '.$totals['end_date'].'

'; + $body .= '

'.$i18n->get('form.mail.report_subject').': '.$totals['start_date'].' - '.$totals['end_date'].'

'; // Output comment. // if ($comment) $body .= '

'.htmlspecialchars($comment).'

'; // No comment for fav. reports. @@ -1497,16 +1497,16 @@ static function prepareFavReportBody($report) $group_by_header = htmlspecialchars($custom_fields->fields[0]['label']); else { $key = 'label.'.$group_by; - $group_by_header = $i18n->getKey($key); + $group_by_header = $i18n->get($key); } $body .= '
'.$i18n->getKey('label.date').''.$i18n->get('label.date').''.$i18n->getKey('label.user').''.$i18n->get('label.user').''.$i18n->getKey('label.client').''.$i18n->get('label.client').''.$i18n->getKey('label.project').''.$i18n->get('label.project').''.$i18n->getKey('label.task').''.$i18n->get('label.task').''.htmlspecialchars($custom_fields->fields[0]['label']).''.$i18n->getKey('label.start').''.$i18n->get('label.start').''.$i18n->getKey('label.finish').''.$i18n->get('label.finish').''.$i18n->getKey('label.duration').''.$i18n->get('label.duration').''.$i18n->getKey('label.note').''.$i18n->get('label.note').''.$i18n->getKey('label.cost').''.$i18n->get('label.cost').''.$i18n->getKey('label.paid').''.$i18n->get('label.paid').''.$i18n->getKey('label.ip').''.$i18n->get('label.ip').''.$i18n->getKey('label.invoice').''.$i18n->get('label.invoice').'
'.$i18n->getKey('label.subtotal').''.$i18n->get('label.subtotal').''.($group_by == 'user' ? $subtotal_name : '').''.($group_by == 'client' ? $subtotal_name : '').''.$record['cost'].''; - $body .= $record['paid'] == 1 ? $i18n->getKey('label.yes') : $i18n->getKey('label.no'); + $body .= $record['paid'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); $body .= '
'.$i18n->getKey('label.subtotal').''.$i18n->get('label.subtotal').''.($group_by == 'user' ? $subtotal_name : '').''.($group_by == 'client' ? $subtotal_name : '').'
 
'.$i18n->getKey('label.total').''.$i18n->get('label.total').'
'; $body .= ''; $body .= ''; if ($report['show_duration']) - $body .= ''; + $body .= ''; if ($report['show_cost']) - $body .= ''; + $body .= ''; $body .= ''; foreach($subtotals as $subtotal) { $body .= ''; @@ -1527,7 +1527,7 @@ static function prepareFavReportBody($report) // Print totals. $body .= ''; $body .= ''; - $body .= ''; + $body .= ''; if ($report['show_duration']) { $body .= '
'.$group_by_header.''.$i18n->getKey('label.duration').''.$i18n->get('label.duration').''.$i18n->getKey('label.cost').''.$i18n->get('label.cost').'
 
'.$i18n->getKey('label.total').''.$i18n->get('label.total').''; if ($totals['time'] <> '0:00') $body .= $totals['time']; @@ -1547,33 +1547,33 @@ static function prepareFavReportBody($report) // Print table header. $body .= ''; $body .= ''; - $body .= ''; + $body .= ''; if ($canViewReports || $isClient) - $body .= ''; + $body .= ''; if ($report['show_client']) - $body .= ''; + $body .= ''; if ($report['show_project']) - $body .= ''; + $body .= ''; if ($report['show_task']) - $body .= ''; + $body .= ''; if ($report['show_custom_field_1']) $body .= ''; if ($report['show_start']) - $body .= ''; + $body .= ''; if ($report['show_end']) - $body .= ''; + $body .= ''; if ($report['show_duration']) - $body .= ''; + $body .= ''; if ($report['show_note']) - $body .= ''; + $body .= ''; if ($report['show_cost']) - $body .= ''; + $body .= ''; if ($report['show_paid']) - $body .= ''; + $body .= ''; if ($report['show_ip']) - $body .= ''; + $body .= ''; if ($report['show_invoice']) - $body .= ''; + $body .= ''; $body .= ''; // Initialize variables to print subtotals. @@ -1597,7 +1597,7 @@ static function prepareFavReportBody($report) $cur_grouped_by = $record['grouped_by']; if ($cur_grouped_by != $prev_grouped_by && !$first_pass) { $body .= ''; - $body .= ''; + $body .= ''; $subtotal_name = htmlspecialchars($subtotals[$prev_grouped_by]['name']); if ($canViewReports || $isClient) $body .= ''; if ($report['show_client']) $body .= ''; @@ -1649,7 +1649,7 @@ static function prepareFavReportBody($report) $body .= ''; if ($report['show_paid']) { $body .= ''; } if ($report['show_ip']) { @@ -1670,7 +1670,7 @@ static function prepareFavReportBody($report) // Print a terminating subtotal. if ($print_subtotals) { $body .= ''; - $body .= ''; + $body .= ''; $subtotal_name = htmlspecialchars($subtotals[$cur_grouped_by]['name']); if ($canViewReports || $isClient) $body .= ''; if ($report['show_client']) $body .= ''; @@ -1695,7 +1695,7 @@ static function prepareFavReportBody($report) // Print totals. $body .= ''; $body .= ''; - $body .= ''; + $body .= ''; if ($canViewReports || $isClient) $body .= ''; if ($report['show_client']) $body .= ''; if ($report['show_project']) $body .= ''; @@ -1720,7 +1720,7 @@ static function prepareFavReportBody($report) // Output footer. if (!defined('REPORT_FOOTER') || !(REPORT_FOOTER == false)) - $body .= '

'.$i18n->getKey('form.mail.footer').'

'; + $body .= '

'.$i18n->get('form.mail.footer').'

'; // Finish creating email body. $body .= ''; diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 18396704a..7629df422 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -190,32 +190,32 @@ static function createPredefinedRoles($team_id, $lang) $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; // Active roles. - $name = $mdb2->quote($i18n->getKey('role.user.label')); - $description = $mdb2->quote($i18n->getKey('role.user.description')); + $name = $mdb2->quote($i18n->get('role.user.label')); + $description = $mdb2->quote($i18n->get('role.user.description')); $rights = $mdb2->quote($rights_user); $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($team_id, $name, $description, 4, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $name = $mdb2->quote($i18n->getKey('role.client.label')); - $description = $mdb2->quote($i18n->getKey('role.client.description')); + $name = $mdb2->quote($i18n->get('role.client.label')); + $description = $mdb2->quote($i18n->get('role.client.description')); $rights = $mdb2->quote($rights_client); $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($team_id, $name, $description, 16, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $name = $mdb2->quote($i18n->getKey('role.comanager.label')); - $description = $mdb2->quote($i18n->getKey('role.comanager.description')); + $name = $mdb2->quote($i18n->get('role.comanager.label')); + $description = $mdb2->quote($i18n->get('role.comanager.description')); $rights = $mdb2->quote($rights_comanager); $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($team_id, $name, $description, 68, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $name = $mdb2->quote($i18n->getKey('role.manager.label')); - $description = $mdb2->quote($i18n->getKey('role.manager.description')); + $name = $mdb2->quote($i18n->get('role.manager.label')); + $description = $mdb2->quote($i18n->get('role.manager.description')); $rights = $mdb2->quote($rights_manager); $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($team_id, $name, $description, 324, $rights, 1)"; $affected = $mdb2->exec($sql); @@ -223,8 +223,8 @@ static function createPredefinedRoles($team_id, $lang) return false; // Inactive roles. - $name = $mdb2->quote($i18n->getKey('role.supervisor.label')); - $description = $mdb2->quote($i18n->getKey('role.supervisor.description')); + $name = $mdb2->quote($i18n->get('role.supervisor.label')); + $description = $mdb2->quote($i18n->get('role.supervisor.description')); $rights = $mdb2->quote($rights_supervisor); $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($team_id, $name, $description, 12, $rights, 0)"; $affected = $mdb2->exec($sql); @@ -248,32 +248,32 @@ static function createDefaultRoles() $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; // Active roles. - $name = $mdb2->quote($i18n->getKey('role.user.label')); - $description = $mdb2->quote($i18n->getKey('role.user.description')); + $name = $mdb2->quote($i18n->get('role.user.label')); + $description = $mdb2->quote($i18n->get('role.user.description')); $rights = $mdb2->quote($rights_user); $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($user->team_id, $name, $description, 4, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $name = $mdb2->quote($i18n->getKey('role.client.label')); - $description = $mdb2->quote($i18n->getKey('role.client.description')); + $name = $mdb2->quote($i18n->get('role.client.label')); + $description = $mdb2->quote($i18n->get('role.client.description')); $rights = $mdb2->quote($rights_client); $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($user->team_id, $name, $description, 16, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $name = $mdb2->quote($i18n->getKey('role.comanager.label')); - $description = $mdb2->quote($i18n->getKey('role.comanager.description')); + $name = $mdb2->quote($i18n->get('role.comanager.label')); + $description = $mdb2->quote($i18n->get('role.comanager.description')); $rights = $mdb2->quote($rights_comanager); $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($user->team_id, $name, $description, 68, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $name = $mdb2->quote($i18n->getKey('role.manager.label')); - $description = $mdb2->quote($i18n->getKey('role.manager.description')); + $name = $mdb2->quote($i18n->get('role.manager.label')); + $description = $mdb2->quote($i18n->get('role.manager.description')); $rights = $mdb2->quote($rights_manager); $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($user->team_id, $name, $description, 324, $rights, 1)"; $affected = $mdb2->exec($sql); @@ -281,8 +281,8 @@ static function createDefaultRoles() return false; // Inactive roles. - $name = $mdb2->quote($i18n->getKey('role.supervisor.label')); - $description = $mdb2->quote($i18n->getKey('role.supervisor.description')); + $name = $mdb2->quote($i18n->get('role.supervisor.label')); + $description = $mdb2->quote($i18n->get('role.supervisor.description')); $rights = $mdb2->quote($rights_supervisor); $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($user->team_id, $name, $description, 12, $rights, 0)"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 9f3e0a902..0d10a84f0 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -85,7 +85,7 @@ static function getActiveUsers($options = null) { while ($val = $res->fetchRow()) { // Localize top manager role name, as it is not localized in db. if ($val['rank'] == 512) - $val['role_name'] = $i18n->getKey('role.top_manager.label'); + $val['role_name'] = $i18n->get('role.top_manager.label'); $user_list[] = $val; } diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index af0960ae6..f4ee719f8 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -156,7 +156,7 @@ static function getDataForWeekView($records, $dayHeaders) { $dataArray = array(); // Construct the first row for a brand new entry. - $dataArray[] = array('row_id' => null,'label' => $i18n->getKey('form.week.new_entry').':'); // Insert row. + $dataArray[] = array('row_id' => null,'label' => $i18n->get('form.week.new_entry').':'); // Insert row. // Insert empty cells with proper control ids. for ($i = 0; $i < 7; $i++) { $control_id = '0_'. $dayHeaders[$i]; @@ -164,7 +164,7 @@ static function getDataForWeekView($records, $dayHeaders) { } if ($user->isPluginEnabled('wvns')) { // Construct the second row for daily comments for a brand new entry. - $dataArray[] = array('row_id' => null,'label' => $i18n->getKey('label.notes').':'); // Insert row. + $dataArray[] = array('row_id' => null,'label' => $i18n->get('label.notes').':'); // Insert row. // Insert empty cells with proper control ids. for ($i = 0; $i < 7; $i++) { $control_id = '1_'. $dayHeaders[$i]; @@ -197,7 +197,7 @@ static function getDataForWeekView($records, $dayHeaders) { } // Insert row for comments. if ($user->isPluginEnabled('wvns')) { - $dataArray[] = array('row_id' => $row_id.'_notes','label' => $i18n->getKey('label.notes').':'); + $dataArray[] = array('row_id' => $row_id.'_notes','label' => $i18n->get('label.notes').':'); $pos++; // Insert empty cells with proper control ids. for ($i = 0; $i < 7; $i++) { @@ -254,14 +254,14 @@ static function prePopulateFromPastWeeks($startDate, $dayHeaders) { } // Construct the first row for a brand new entry. - $dataArray[] = array('row_id' => null,'label' => $i18n->getKey('form.week.new_entry').':'); // Insert row. + $dataArray[] = array('row_id' => null,'label' => $i18n->get('form.week.new_entry').':'); // Insert row. // Insert empty cells with proper control ids. for ($i = 0; $i < 7; $i++) { $control_id = '0_'. $dayHeaders[$i]; $dataArray[0][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); } // Construct the second row for daily comments for a brand new entry. - $dataArray[] = array('row_id' => null,'label' => $i18n->getKey('label.notes').':'); // Insert row. + $dataArray[] = array('row_id' => null,'label' => $i18n->get('label.notes').':'); // Insert row. // Insert empty cells with proper control ids. for ($i = 0; $i < 7; $i++) { $control_id = '1_'. $dayHeaders[$i]; @@ -284,7 +284,7 @@ static function prePopulateFromPastWeeks($startDate, $dayHeaders) { $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); } // Insert row for comments. - $dataArray[] = array('row_id' => $row_id.'_notes','label' => $i18n->getKey('label.notes').':'); + $dataArray[] = array('row_id' => $row_id.'_notes','label' => $i18n->get('label.notes').':'); $pos++; // Insert empty cells with proper control ids. for ($i = 0; $i < 7; $i++) { @@ -325,7 +325,7 @@ static function getDayTotals($dataArray, $dayHeaders) { // Insert label. global $i18n; - $dayTotals['label'] = $i18n->getKey('label.day_total').':'; + $dayTotals['label'] = $i18n->get('label.day_total').':'; foreach ($dataArray as $row) { foreach($dayHeaders as $dayHeader) { @@ -485,7 +485,7 @@ static function insertDurationFromWeekView($fields, $custom_fields, $err) { if (!$user->future_entries && $fields['browser_today']) { $objBrowserToday = new DateAndTime(DB_DATEFORMAT, $fields['browser_today']); if ($objEntryDate->after($objBrowserToday)) { - $err->add($i18n->getKey('error.future_date')); + $err->add($i18n->get('error.future_date')); return false; } } @@ -550,7 +550,7 @@ static function canModify($tt_log_id, $new_duration, $err) { $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if (!$res->numRows()) { - $err->add($i18n->getKey('error.db')); // This is not expected. + $err->add($i18n->get('error.db')); // This is not expected. return false; } $val = $res->fetchRow(); @@ -571,7 +571,7 @@ static function canModify($tt_log_id, $new_duration, $err) { $newEndMinutes = $startMinutes + $newMinutes; if ($newEndMinutes > 1440) { // Invalid duration, as new duration puts the record beyond current day. - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.field'), $i18n->get('label.duration')); return false; } @@ -582,7 +582,7 @@ static function canModify($tt_log_id, $new_duration, $err) { $start = ttTimeHelper::toAbsDuration($startMinutes); $finish = ttTimeHelper::toAbsDuration($newEndMinutes); if (ttTimeHelper::overlaps($user_id, $date, $start, $finish, $tt_log_id)) { - $err->add($i18n->getKey('error.overlap')); + $err->add($i18n->get('error.overlap')); return false; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d92f371af..74eb876fb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
'.$i18n->getKey('label.date').''.$i18n->get('label.date').''.$i18n->getKey('label.user').''.$i18n->get('label.user').''.$i18n->getKey('label.client').''.$i18n->get('label.client').''.$i18n->getKey('label.project').''.$i18n->get('label.project').''.$i18n->getKey('label.task').''.$i18n->get('label.task').''.htmlspecialchars($custom_fields->fields[0]['label']).''.$i18n->getKey('label.start').''.$i18n->get('label.start').''.$i18n->getKey('label.finish').''.$i18n->get('label.finish').''.$i18n->getKey('label.duration').''.$i18n->get('label.duration').''.$i18n->getKey('label.note').''.$i18n->get('label.note').''.$i18n->getKey('label.cost').''.$i18n->get('label.cost').''.$i18n->getKey('label.paid').''.$i18n->get('label.paid').''.$i18n->getKey('label.ip').''.$i18n->get('label.ip').''.$i18n->getKey('label.invoice').''.$i18n->get('label.invoice').'
'.$i18n->getKey('label.subtotal').''.$i18n->get('label.subtotal').''.($group_by == 'user' ? $subtotal_name : '').''.($group_by == 'client' ? $subtotal_name : '').''.$record['cost'].''; - $body .= $record['paid'] == 1 ? $i18n->getKey('label.yes') : $i18n->getKey('label.no'); + $body .= $record['paid'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); $body .= '
'.$i18n->getKey('label.subtotal').''.$i18n->get('label.subtotal').''.($group_by == 'user' ? $subtotal_name : '').''.($group_by == 'client' ? $subtotal_name : '').'
 
'.$i18n->getKey('label.total').''.$i18n->get('label.total').'
-
 Anuko Time Tracker 1.17.67.4142 | Copyright © Anuko | +  Anuko Time Tracker 1.17.67.4143 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/access_denied.php b/access_denied.php index 65a5ed72d..72a28d192 100644 --- a/access_denied.php +++ b/access_denied.php @@ -28,9 +28,9 @@ require_once('initialize.php'); -$err->add($i18n->getKey('error.access_denied')); +$err->add($i18n->get('error.access_denied')); if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. -$smarty->assign('title', $i18n->getKey('label.error')); +$smarty->assign('title', $i18n->get('label.error')); $smarty->assign('content_page_name', 'access_denied.tpl'); $smarty->display('index.tpl'); diff --git a/admin_options.php b/admin_options.php index 14cb3f54c..cc9fd65c4 100644 --- a/admin_options.php +++ b/admin_options.php @@ -58,7 +58,7 @@ $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'password2','value'=>$cl_password2)); } $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { // Create fields array for ttAdmin instance. @@ -80,6 +80,6 @@ $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.options')); +$smarty->assign('title', $i18n->get('title.options')); $smarty->assign('content_page_name', 'admin_options.tpl'); $smarty->display('index.tpl'); diff --git a/admin_team_add.php b/admin_team_add.php index b270de172..6d5bc84f9 100644 --- a/admin_team_add.php +++ b/admin_team_add.php @@ -78,7 +78,7 @@ $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'password2','value'=>$cl_password2)); } $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'manager_email','value'=>$cl_manager_email)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { /* @@ -115,5 +115,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.teamForm.team.focus()"'); $smarty->assign('content_page_name', 'admin_team_add.tpl'); -$smarty->assign('title', $i18n->getKey('title.create_team')); +$smarty->assign('title', $i18n->get('title.create_team')); $smarty->display('index.tpl'); diff --git a/admin_team_delete.php b/admin_team_delete.php index b2b462ce6..a9ce1ee1b 100644 --- a/admin_team_delete.php +++ b/admin_team_delete.php @@ -42,8 +42,8 @@ $form = new Form('teamForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$team_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -54,7 +54,7 @@ header('Location: admin_teams.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } if ($request->getParameter('btn_cancel')) { @@ -65,6 +65,6 @@ $smarty->assign('team_to_delete', $team_name); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.delete_team')); +$smarty->assign('title', $i18n->get('title.delete_team')); $smarty->assign('content_page_name', 'admin_team_delete.tpl'); $smarty->display('index.tpl'); diff --git a/admin_team_edit.php b/admin_team_edit.php index 63f8fe7ad..a737050a8 100644 --- a/admin_team_edit.php +++ b/admin_team_edit.php @@ -69,8 +69,8 @@ } $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'manager_email','value'=>$cl_manager_email)); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$team_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_save')) { @@ -104,6 +104,6 @@ $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.teamForm.manager_name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.edit_team')); +$smarty->assign('title', $i18n->get('title.edit_team')); $smarty->assign('content_page_name', 'admin_team_edit.tpl'); $smarty->display('index.tpl'); diff --git a/admin_teams.php b/admin_teams.php index 55df54fc5..7d2b3dfa4 100644 --- a/admin_teams.php +++ b/admin_teams.php @@ -36,6 +36,6 @@ } $smarty->assign('teams', ttGroupHelper::getTopGroups()); -$smarty->assign('title', $i18n->getKey('title.teams')); +$smarty->assign('title', $i18n->get('title.teams')); $smarty->assign('content_page_name', 'admin_teams.tpl'); $smarty->display('index.tpl'); diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index f8ea01e01..30c82a5a4 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -47,15 +47,15 @@ $form = new Form('fieldForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>'')); $form->addInput(array('type'=>'combobox','name'=>'type', - 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->getKey('label.type_text'), - CustomFields::TYPE_DROPDOWN=>$i18n->getKey('label.type_dropdown')) + 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->get('label.type_text'), + CustomFields::TYPE_DROPDOWN=>$i18n->get('label.type_dropdown')) )); $form->addInput(array('type'=>'checkbox','name'=>'required')); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_field_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); + if (!ttValidString($cl_field_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if ($err->no()) { $res = CustomFields::insertField($cl_field_name, $cl_field_type, $cl_required); @@ -63,12 +63,12 @@ header('Location: cf_custom_fields.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fieldForm.name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.cf_add_custom_field')); +$smarty->assign('title', $i18n->get('title.cf_add_custom_field')); $smarty->assign('content_page_name', 'cf_custom_field_add.tpl'); $smarty->display('index.tpl'); From a0dd058ab6007cfc6a72713215a7f4abb96f1b45 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 15:37:45 +0000 Subject: [PATCH 0023/1848] Some more refactoring. --- WEB-INF/templates/footer.tpl | 2 +- cf_custom_field_delete.php | 10 +++++----- cf_custom_field_edit.php | 14 +++++++------- cf_custom_fields.php | 4 ++-- cf_dropdown_option_add.php | 10 +++++----- cf_dropdown_option_delete.php | 10 +++++----- cf_dropdown_option_edit.php | 10 +++++----- cf_dropdown_options.php | 4 ++-- charts.php | 18 +++++++++--------- client_add.php | 14 +++++++------- client_delete.php | 12 ++++++------ client_edit.php | 22 +++++++++++----------- 12 files changed, 65 insertions(+), 65 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 74eb876fb..7cf8ef60d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.67.4143 | Copyright © Anuko | +  Anuko Time Tracker 1.17.67.4144 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cf_custom_field_delete.php b/cf_custom_field_delete.php index caf858a29..f4de48098 100644 --- a/cf_custom_field_delete.php +++ b/cf_custom_field_delete.php @@ -48,7 +48,7 @@ header('Location: cf_custom_fields.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } if ($request->getParameter('btn_cancel')) { // Cancel button pressed. @@ -58,18 +58,18 @@ } else { $field = CustomFields::getField($id); if (false === $field) - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); if ($err->no()) { $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$id)); - $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); - $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); + $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); + $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); } } $smarty->assign('field', $field['label']); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fieldDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->getKey('title.cf_delete_custom_field')); +$smarty->assign('title', $i18n->get('title.cf_delete_custom_field')); $smarty->assign('content_page_name', 'cf_custom_field_delete.tpl'); $smarty->display('index.tpl'); diff --git a/cf_custom_field_edit.php b/cf_custom_field_edit.php index 295e40790..32ee3878d 100644 --- a/cf_custom_field_edit.php +++ b/cf_custom_field_edit.php @@ -39,7 +39,7 @@ $cl_id = $request->getParameter('id'); $field = CustomFields::getField($cl_id); if (false === $field) - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); $form = new Form('fieldForm'); if ($err->no()) { @@ -47,9 +47,9 @@ $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'checkbox','name'=>'required','value'=>$field['required'])); $form->addInput(array('type'=>'combobox','name'=>'type','value'=>$field['type'], - 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->getKey('label.type_text'), - CustomFields::TYPE_DROPDOWN=>$i18n->getKey('label.type_dropdown')))); - $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); + 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->get('label.type_text'), + CustomFields::TYPE_DROPDOWN=>$i18n->get('label.type_dropdown')))); + $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); } if ($request->isPost()) { @@ -60,7 +60,7 @@ $cl_required = 0; // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if ($err->no()) { $res = CustomFields::updateField($cl_id, $cl_name, $cl_type, $cl_required); @@ -68,12 +68,12 @@ header('Location: cf_custom_fields.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fieldForm.name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.cf_edit_custom_field')); +$smarty->assign('title', $i18n->get('title.cf_edit_custom_field')); $smarty->assign('content_page_name', 'cf_custom_field_edit.tpl'); $smarty->display('index.tpl'); diff --git a/cf_custom_fields.php b/cf_custom_fields.php index 539271c54..2b34fb76b 100644 --- a/cf_custom_fields.php +++ b/cf_custom_fields.php @@ -45,7 +45,7 @@ exit(); } } else { - $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->getKey('button.add'))); + $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); $fields = CustomFields::getFields(); // At this time only one custom field is supported. Disable the Add button if we already have one or more custom fields. @@ -55,6 +55,6 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('custom_fields', $fields); -$smarty->assign('title', $i18n->getKey('title.cf_custom_fields')); +$smarty->assign('title', $i18n->get('title.cf_custom_fields')); $smarty->assign('content_page_name', 'cf_custom_fields.tpl'); $smarty->display('index.tpl'); diff --git a/cf_dropdown_option_add.php b/cf_dropdown_option_add.php index f87003d15..b9500833d 100644 --- a/cf_dropdown_option_add.php +++ b/cf_dropdown_option_add.php @@ -39,20 +39,20 @@ $cl_field_id = $request->getParameter('field_id'); $field = CustomFields::getField($cl_field_id); if (false === $field) - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); $form = new Form('optionAddForm'); if ($err->no()) { $form->addInput(array('type'=>'hidden','name'=>'field_id','value'=>$cl_field_id)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>'')); - $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->getKey('button.add'))); + $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); } if ($request->isPost()) { $cl_option_name = trim($request->getParameter('name')); // Validate user input. - if (!ttValidString($cl_option_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); + if (!ttValidString($cl_option_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if ($err->no()) { $res = CustomFields::insertOption($cl_field_id, $cl_option_name); @@ -60,12 +60,12 @@ header("Location: cf_dropdown_options.php?field_id=$cl_field_id"); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.optionAddForm.name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.cf_add_dropdown_option')); +$smarty->assign('title', $i18n->get('title.cf_add_dropdown_option')); $smarty->assign('content_page_name', 'cf_dropdown_option_add.tpl'); $smarty->display('index.tpl'); diff --git a/cf_dropdown_option_delete.php b/cf_dropdown_option_delete.php index f4e442075..0a1f25ba0 100644 --- a/cf_dropdown_option_delete.php +++ b/cf_dropdown_option_delete.php @@ -50,7 +50,7 @@ header("Location: cf_dropdown_options.php?field_id=$field_id"); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } if ($request->getParameter('btn_cancel')) { // Cancel button pressed. @@ -60,18 +60,18 @@ } else { $option = CustomFields::getOptionName($cl_id); if (false === $option) - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); if ($err->no()) { $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); - $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); - $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); + $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); + $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); } } $smarty->assign('option', $option); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.optionDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->getKey('title.cf_delete_dropdown_option')); +$smarty->assign('title', $i18n->get('title.cf_delete_dropdown_option')); $smarty->assign('content_page_name', 'cf_dropdown_option_delete.tpl'); $smarty->display('index.tpl'); diff --git a/cf_dropdown_option_edit.php b/cf_dropdown_option_edit.php index 1013a54a4..5fc333d01 100644 --- a/cf_dropdown_option_edit.php +++ b/cf_dropdown_option_edit.php @@ -39,20 +39,20 @@ $cl_id = $request->getParameter('id'); $cl_name = CustomFields::getOptionName($cl_id); if (false === $cl_name) - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); $form = new Form('optionEditForm'); if ($err->no()) { $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); - $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); + $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); } if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if ($err->no()) { $res = CustomFields::updateOption($cl_id, $cl_name); @@ -62,12 +62,12 @@ header("Location: cf_dropdown_options.php?field_id=$field_id"); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.optionEditForm.name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.cf_edit_dropdown_option')); +$smarty->assign('title', $i18n->get('title.cf_edit_dropdown_option')); $smarty->assign('content_page_name', 'cf_dropdown_option_edit.tpl'); $smarty->display('index.tpl'); diff --git a/cf_dropdown_options.php b/cf_dropdown_options.php index 3ee5294eb..02f59f56b 100644 --- a/cf_dropdown_options.php +++ b/cf_dropdown_options.php @@ -39,13 +39,13 @@ $field_id = $request->getParameter('field_id'); $options = CustomFields::getOptions($field_id); if (false === $options) - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); $form = new Form('dropdownOptionsForm'); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('field_id', $field_id); $smarty->assign('options', $options); -$smarty->assign('title', $i18n->getKey('title.cf_dropdown_options')); +$smarty->assign('title', $i18n->get('title.cf_dropdown_options')); $smarty->assign('content_page_name', 'cf_dropdown_options.tpl'); $smarty->display('index.tpl'); diff --git a/charts.php b/charts.php index 9df70d55e..69997d87f 100644 --- a/charts.php +++ b/charts.php @@ -139,11 +139,11 @@ // Chart interval options. $intervals = array(); -$intervals[INTERVAL_THIS_DAY] = $i18n->getKey('dropdown.selected_day'); -$intervals[INTERVAL_THIS_WEEK] = $i18n->getKey('dropdown.selected_week'); -$intervals[INTERVAL_THIS_MONTH] = $i18n->getKey('dropdown.selected_month'); -$intervals[INTERVAL_THIS_YEAR] = $i18n->getKey('dropdown.selected_year'); -$intervals[INTERVAL_ALL_TIME] = $i18n->getKey('dropdown.all_time'); +$intervals[INTERVAL_THIS_DAY] = $i18n->get('dropdown.selected_day'); +$intervals[INTERVAL_THIS_WEEK] = $i18n->get('dropdown.selected_week'); +$intervals[INTERVAL_THIS_MONTH] = $i18n->get('dropdown.selected_month'); +$intervals[INTERVAL_THIS_YEAR] = $i18n->get('dropdown.selected_year'); +$intervals[INTERVAL_ALL_TIME] = $i18n->get('dropdown.all_time'); // Chart interval dropdown. $chart_form->addInput(array('type' => 'combobox', @@ -158,11 +158,11 @@ if ($chart_selector) { $types = array(); if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) - $types[CHART_PROJECTS] = $i18n->getKey('dropdown.projects'); + $types[CHART_PROJECTS] = $i18n->get('dropdown.projects'); if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) - $types[CHART_TASKS] = $i18n->getKey('dropdown.tasks'); + $types[CHART_TASKS] = $i18n->get('dropdown.tasks'); if ($user->isPluginEnabled('cl')) - $types[CHART_CLIENTS] = $i18n->getKey('dropdown.clients'); + $types[CHART_CLIENTS] = $i18n->get('dropdown.clients'); // Add chart type dropdown. $chart_form->addInput(array('type' => 'combobox', @@ -223,6 +223,6 @@ $smarty->assign('img_file_name', $img_ref); $smarty->assign('chart_selector', $chart_selector); $smarty->assign('forms', array($chart_form->getName() => $chart_form->toArray())); -$smarty->assign('title', $i18n->getKey('title.charts')); +$smarty->assign('title', $i18n->get('title.charts')); $smarty->assign('content_page_name', 'charts.tpl'); $smarty->display('index.tpl'); diff --git a/client_add.php b/client_add.php index 8dbb0d86a..c0526e51b 100644 --- a/client_add.php +++ b/client_add.php @@ -56,13 +56,13 @@ $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.tax')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); + if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); + if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); if ($err->no()) { if (!ttClientHelper::getClientByName($cl_name)) { @@ -76,14 +76,14 @@ header('Location: clients.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.client_exists')); + $err->add($i18n->get('error.client_exists')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.add_client')); +$smarty->assign('title', $i18n->get('title.add_client')); $smarty->assign('content_page_name', 'client_add.tpl'); $smarty->display('index.tpl'); diff --git a/client_delete.php b/client_delete.php index eae300500..b162ea844 100644 --- a/client_delete.php +++ b/client_delete.php @@ -44,9 +44,9 @@ $form = new Form('clientDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$id)); $form->addInput(array('type'=>'combobox','name'=>'delete_client_entries', - 'data'=>array('0'=>$i18n->getKey('dropdown.do_not_delete'),'1'=>$i18n->getKey('dropdown.delete')))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); + 'data'=>array('0'=>$i18n->get('dropdown.do_not_delete'),'1'=>$i18n->get('dropdown.delete')))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if(ttClientHelper::getClient($id)) { @@ -55,10 +55,10 @@ header('Location: clients.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); if ($request->getParameter('btn_cancel')) { header('Location: clients.php'); @@ -68,6 +68,6 @@ $smarty->assign('client_to_delete', $client_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.delete_client')); +$smarty->assign('title', $i18n->get('title.delete_client')); $smarty->assign('content_page_name', 'client_delete.tpl'); $smarty->display('index.tpl'); diff --git a/client_edit.php b/client_edit.php index 3099e8889..05203237f 100644 --- a/client_edit.php +++ b/client_edit.php @@ -65,17 +65,17 @@ $form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','style'=>'width: 350px; height: 80px;','value'=>$cl_address)); $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->getKey('dropdown.status_active'),INACTIVE=>$i18n->getKey('dropdown.status_inactive')))); + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'datakeys'=>array('id','name'),'layout'=>'H','value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->getKey('button.copy'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.tax')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); + if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); + if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); if ($err->no()) { if ($request->getParameter('btn_save')) { @@ -91,9 +91,9 @@ header('Location: clients.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.client_exists')); + $err->add($i18n->get('error.client_exists')); } if ($request->getParameter('btn_copy')) { @@ -108,14 +108,14 @@ header('Location: clients.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.client_exists')); + $err->add($i18n->get('error.client_exists')); } } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.edit_client')); +$smarty->assign('title', $i18n->get('title.edit_client')); $smarty->assign('content_page_name', 'client_edit.tpl'); $smarty->display('index.tpl'); From a62e4bdd1bc89ea4f3cf29507399b5b8f229597a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 16:09:47 +0000 Subject: [PATCH 0024/1848] Some more refactoring. --- clients.php | 2 +- expense_delete.php | 12 ++++++------ expense_edit.php | 38 +++++++++++++++++++------------------- expenses.php | 26 +++++++++++++------------- export.php | 10 +++++----- import.php | 6 +++--- invoice_add.php | 24 ++++++++++++------------ invoice_delete.php | 12 ++++++------ invoice_send.php | 20 ++++++++++---------- invoice_view.php | 6 +++--- invoices.php | 2 +- locking.php | 8 ++++---- login.php | 14 +++++++------- mobile/access_denied.php | 4 ++-- mobile/client_add.php | 14 +++++++------- mobile/client_delete.php | 12 ++++++------ mobile/client_edit.php | 24 ++++++++++++------------ mobile/clients.php | 2 +- 18 files changed, 118 insertions(+), 118 deletions(-) diff --git a/clients.php b/clients.php index f02d4b951..89b5c4a37 100644 --- a/clients.php +++ b/clients.php @@ -38,6 +38,6 @@ $smarty->assign('active_clients', ttTeamHelper::getActiveClients($user->team_id, true)); $smarty->assign('inactive_clients', ttTeamHelper::getInactiveClients($user->team_id, true)); -$smarty->assign('title', $i18n->getKey('title.clients')); +$smarty->assign('title', $i18n->get('title.clients')); $smarty->assign('content_page_name', 'clients.tpl'); $smarty->display('index.tpl'); diff --git a/expense_delete.php b/expense_delete.php index d5b4e8d27..06c9690b0 100644 --- a/expense_delete.php +++ b/expense_delete.php @@ -41,7 +41,7 @@ $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); // Prohibit deleting invoiced records. -if ($expense_item['invoice_id']) die($i18n->getKey('error.sys')); +if ($expense_item['invoice_id']) die($i18n->get('error.sys')); if ($request->isPost()) { if ($request->getParameter('delete_button')) { // Delete button pressed. @@ -49,7 +49,7 @@ // Determine if it is okay to delete the record. $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); if ($user->isDateLocked($item_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); if ($err->no()) { // Mark the record as deleted. @@ -57,7 +57,7 @@ header('Location: expenses.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } if ($request->getParameter('cancel_button')) { // Cancel button pressed. @@ -68,11 +68,11 @@ $form = new Form('expenseItemForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); $smarty->assign('expense_item', $expense_item); $smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('title', $i18n->getKey('title.delete_expense')); +$smarty->assign('title', $i18n->get('title.delete_expense')); $smarty->assign('content_page_name', 'expense_delete.tpl'); $smarty->display('index.tpl'); diff --git a/expense_edit.php b/expense_edit.php index dbd14d96d..9ea7c6493 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -44,7 +44,7 @@ $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); // Prohibit editing invoiced items. -if ($expense_item['invoice_id']) die($i18n->getKey('error.sys')); +if ($expense_item['invoice_id']) die($i18n->get('error.sys')); $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); @@ -80,7 +80,7 @@ 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Note: in other modes the client list is filtered to relevant clients only. See below. } @@ -93,7 +93,7 @@ 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { @@ -119,7 +119,7 @@ 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } // If predefined expenses are configured, add controls to select an expense and quantity. @@ -132,7 +132,7 @@ 'value'=>$cl_predefined_expense, 'data'=>$predefined_expenses, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); } $form->addInput(array('type'=>'textarea','maxlength'=>'800','name'=>'item_name','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_item_name)); @@ -143,20 +143,20 @@ // Hidden control for record id. $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.copy'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) - $err->add($i18n->getKey('error.client')); + $err->add($i18n->get('error.client')); if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->getKey('error.project')); + if (!$cl_project) $err->add($i18n->get('error.project')); } - if (!ttValidString($cl_item_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.item')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cost')); - if (!ttValidDate($cl_date)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.date')); + if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); + if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); + if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); // This is a new date for the expense item. $new_date = new DateAndTime($user->date_format, $cl_date); @@ -165,7 +165,7 @@ if (!$user->future_entries) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) - $err->add($i18n->getKey('error.future_date')); + $err->add($i18n->get('error.future_date')); } // Save record. @@ -177,11 +177,11 @@ // Now, step by step. // 1) Prohibit saving locked entries in any form. if ($user->isDateLocked($item_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // 2) Prohibit saving unlocked entries into locked range. if ($err->no() && $user->isDateLocked($new_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // Now, an update. if ($err->no()) { @@ -197,7 +197,7 @@ if ($request->getParameter('btn_copy')) { // We need to prohibit saving into locked interval. if ($user->isDateLocked($new_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // Now, a new insert. if ($err->no()) { @@ -206,7 +206,7 @@ header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } @@ -221,6 +221,6 @@ $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.edit_expense')); +$smarty->assign('title', $i18n->get('title.edit_expense')); $smarty->assign('content_page_name', 'expense_edit.tpl'); $smarty->display('index.tpl'); diff --git a/expenses.php b/expenses.php index ca681d413..bb7694816 100644 --- a/expenses.php +++ b/expenses.php @@ -84,7 +84,7 @@ 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Note: in other modes the client list is filtered to relevant clients only. See below. } @@ -98,7 +98,7 @@ 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { @@ -124,7 +124,7 @@ 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } // If predefined expenses are configured, add controls to select an expense and quantity. @@ -137,38 +137,38 @@ 'value'=>$cl_predefined_expense, 'data'=>$predefined_expenses, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); } $form->addInput(array('type'=>'textarea','maxlength'=>'800','name'=>'item_name','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_item_name)); $form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); $form->addInput(array('type'=>'calendar','name'=>'date','highlight'=>'expenses','value'=>$cl_date)); // calendar $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); // Submit. if ($request->isPost()) { if ($request->getParameter('btn_submit')) { // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) - $err->add($i18n->getKey('error.client')); + $err->add($i18n->get('error.client')); if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->getKey('error.project')); + if (!$cl_project) $err->add($i18n->get('error.project')); } - if (!ttValidString($cl_item_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.comment')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cost')); + if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); + if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); // Prohibit creating entries in future. if (!$user->future_entries) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) - $err->add($i18n->getKey('error.future_date')); + $err->add($i18n->get('error.future_date')); } // Finished validating input data. // Prohibit creating entries in locked range. if ($user->isDateLocked($selected_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // Insert record. if ($err->no()) { @@ -177,7 +177,7 @@ header('Location: expenses.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } elseif ($request->getParameter('onBehalfUser')) { if($user->canManageTeam()) { @@ -201,6 +201,6 @@ $smarty->assign('project_list', $project_list); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('timestring', $selected_date->toString($user->date_format)); -$smarty->assign('title', $i18n->getKey('title.expenses')); +$smarty->assign('title', $i18n->get('title.expenses')); $smarty->assign('content_page_name', 'expenses.tpl'); $smarty->display('index.tpl'); diff --git a/export.php b/export.php index 7ccce3308..4f1a571a1 100644 --- a/export.php +++ b/export.php @@ -37,13 +37,13 @@ } $cl_compression = $request->getParameter('compression'); -$compressors = array('' => $i18n->getKey('form.export.compression_none')); +$compressors = array('' => $i18n->get('form.export.compression_none')); if (function_exists('bzcompress')) - $compressors['bzip'] = $i18n->getKey('form.export.compression_bzip'); + $compressors['bzip'] = $i18n->get('form.export.compression_bzip'); $form = new Form('exportForm'); $form->addInput(array('type'=>'combobox','name'=>'compression','value'=>$cl_compression,'data'=>$compressors)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.export'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.export'))); if ($request->isPost()) { @@ -74,10 +74,10 @@ } exit; } else - $err->add($i18n->getKey('error.sys')); + $err->add($i18n->get('error.sys')); } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.export')); +$smarty->assign('title', $i18n->get('title.export')); $smarty->assign('content_page_name', 'export.tpl'); $smarty->display('index.tpl'); diff --git a/import.php b/import.php index dd30ad3a8..f822cb793 100644 --- a/import.php +++ b/import.php @@ -39,16 +39,16 @@ $form = new Form('importForm'); $form->addInput(array('type'=>'upload','name'=>'xmlfile','value'=>'browse','maxsize'=>67108864)); // 64 MB file upload limit. // Note: for the above limit to work make sure to set upload_max_filesize and post_max_size in php.ini to at least 64M. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.import'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.import'))); if ($request->isPost()) { $import = new ttImportHelper($err); $import->importXml(); - if ($err->no()) $msg->add($i18n->getKey('form.import.success')); + if ($err->no()) $msg->add($i18n->get('form.import.success')); } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray()) ); -$smarty->assign('title', $i18n->getKey('title.import')); +$smarty->assign('title', $i18n->get('title.import')); $smarty->assign('content_page_name', 'import.tpl'); $smarty->display('index.tpl'); diff --git a/invoice_add.php b/invoice_add.php index 01b77615e..ed0a8c526 100644 --- a/invoice_add.php +++ b/invoice_add.php @@ -52,33 +52,33 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { $clients = ttTeamHelper::getActiveClients($user->team_id); - $form->addInput(array('type'=>'combobox','name'=>'client','style'=>'width: 250px;','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + $form->addInput(array('type'=>'combobox','name'=>'client','style'=>'width: 250px;','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->get('dropdown.select')))); } // Dropdown for projects. if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { $projects = ttTeamHelper::getActiveProjects($user->team_id); - $form->addInput(array('type'=>'combobox','name'=>'project','style'=>'width: 250px;','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_project,'empty'=>array(''=>$i18n->getKey('dropdown.all')))); + $form->addInput(array('type'=>'combobox','name'=>'project','style'=>'width: 250px;','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_project,'empty'=>array(''=>$i18n->get('dropdown.all')))); } $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'number','style'=>'width: 250px;','value'=>$cl_number)); $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start','value'=>$cl_start)); $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'finish','value'=>$cl_finish)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_number)) $err->add($i18n->getKey('error.field'), $i18n->getKey('form.invoice.number')); - if (!ttValidDate($cl_date)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.date')); - if (!$cl_client) $err->add($i18n->getKey('error.client')); - if (!ttValidDate($cl_start)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.start_date')); - if (!ttValidDate($cl_finish)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.end_date')); + if (!ttValidString($cl_number)) $err->add($i18n->get('error.field'), $i18n->get('form.invoice.number')); + if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); + if (!$cl_client) $err->add($i18n->get('error.client')); + if (!ttValidDate($cl_start)) $err->add($i18n->get('error.field'), $i18n->get('label.start_date')); + if (!ttValidDate($cl_finish)) $err->add($i18n->get('error.field'), $i18n->get('label.end_date')); $fields = array('date'=>$cl_date,'name'=>$cl_number,'client_id'=>$cl_client,'project_id'=>$cl_project,'start_date'=>$cl_start,'end_date'=>$cl_finish); if ($err->no()) { if (ttInvoiceHelper::getInvoiceByName($cl_number)) - $err->add($i18n->getKey('error.invoice_exists')); + $err->add($i18n->get('error.invoice_exists')); if (!ttInvoiceHelper::invoiceableItemsExist($fields)) - $err->add($i18n->getKey('error.no_invoiceable_items')); + $err->add($i18n->get('error.no_invoiceable_items')); } if ($err->no()) { @@ -87,13 +87,13 @@ header('Location: invoices.php'); exit(); } else { - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.invoiceForm.number.focus()"'); -$smarty->assign('title', $i18n->getKey('title.add_invoice')); +$smarty->assign('title', $i18n->get('title.add_invoice')); $smarty->assign('content_page_name', 'invoice_add.tpl'); $smarty->display('index.tpl'); diff --git a/invoice_delete.php b/invoice_delete.php index 6fd8270d2..29160ba55 100644 --- a/invoice_delete.php +++ b/invoice_delete.php @@ -44,10 +44,10 @@ $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_invoice_id)); $form->addInput(array('type'=>'combobox', 'name'=>'delete_invoice_entries', - 'data'=>array('0'=>$i18n->getKey('dropdown.do_not_delete'),'1'=>$i18n->getKey('dropdown.delete')), + 'data'=>array('0'=>$i18n->get('dropdown.do_not_delete'),'1'=>$i18n->get('dropdown.delete')), )); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'),'onclick'=>'return confirm_deleting_entries();')); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'),'onclick'=>'return confirm_deleting_entries();')); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -56,9 +56,9 @@ header('Location: invoices.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { header('Location: invoices.php'); exit(); @@ -68,6 +68,6 @@ $smarty->assign('invoice_to_delete', $invoice_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.invoiceDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->getKey('title.delete_invoice')); +$smarty->assign('title', $i18n->get('title.delete_invoice')); $smarty->assign('content_page_name', 'invoice_delete.tpl'); $smarty->display('index.tpl'); diff --git a/invoice_send.php b/invoice_send.php index 48bc14f07..2c0894a35 100644 --- a/invoice_send.php +++ b/invoice_send.php @@ -43,7 +43,7 @@ // Security check. if (!$cl_invoice_id || !$invoice) - die ($i18n->getKey('error.sys')); + die ($i18n->get('error.sys')); if ($request->isPost()) { $cl_receiver = trim($request->getParameter('receiver')); @@ -53,7 +53,7 @@ } else { $cl_receiver = $sc->getValue(SYSC_LAST_INVOICE_EMAIL); $cl_cc = $sc->getValue(SYSC_LAST_INVOICE_CC); - $cl_subject = $i18n->getKey('title.invoice').' '.$invoice['name'].', '.$user->team; + $cl_subject = $i18n->get('title.invoice').' '.$invoice['name'].', '.$user->team; } $form = new Form('mailForm'); @@ -62,14 +62,14 @@ $form->addInput(array('type'=>'text','name'=>'cc','style'=>'width: 300px;','value'=>$cl_cc)); $form->addInput(array('type'=>'text','name'=>'subject','style'=>'width: 300px;','value'=>$cl_subject)); $form->addInput(array('type'=>'textarea','name'=>'comment','maxlength'=>'250','style'=>'width: 300px; height: 60px;')); -$form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->getKey('button.send'))); +$form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('button.send'))); if ($request->isPost()) { // Validate user input. - if (!ttValidEmailList($cl_receiver)) $err->add($i18n->getKey('error.field'), $i18n->getKey('form.mail.to')); - if (!ttValidEmailList($cl_cc, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cc')); - if (!ttValidString($cl_subject)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.subject')); - if (!ttValidString($cl_comment, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.comment')); + if (!ttValidEmailList($cl_receiver)) $err->add($i18n->get('error.field'), $i18n->get('form.mail.to')); + if (!ttValidEmailList($cl_cc, true)) $err->add($i18n->get('error.field'), $i18n->get('label.cc')); + if (!ttValidString($cl_subject)) $err->add($i18n->get('error.field'), $i18n->get('label.subject')); + if (!ttValidString($cl_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); if ($err->no()) { // Save last invoice emails for future use. @@ -90,9 +90,9 @@ $mailer->setReceiverBCC($user->bcc_email); $mailer->setMailMode(MAIL_MODE); if ($mailer->send($cl_subject, $body)) - $msg->add($i18n->getKey('form.mail.invoice_sent')); + $msg->add($i18n->get('form.mail.invoice_sent')); else - $err->add($i18n->getKey('error.mail_send')); + $err->add($i18n->get('error.mail_send')); } } // isPost @@ -106,7 +106,7 @@ } } -$smarty->assign('title', $i18n->getKey('title.send_invoice')); +$smarty->assign('title', $i18n->get('title.send_invoice')); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.mailForm.'.($cl_receiver?'comment':'receiver').'.focus()"'); $smarty->assign('content_page_name', 'mail.tpl'); diff --git a/invoice_view.php b/invoice_view.php index 4a6027a5b..3715b80a2 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -90,12 +90,12 @@ $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); // invoiceForm only contains controls for "Mark paid" block below invoice table. if ($user->isPluginEnabled('ps')) { - $mark_paid_action_options = array('1'=>$i18n->getKey('dropdown.paid'),'2'=>$i18n->getKey('dropdown.not_paid')); + $mark_paid_action_options = array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')); $form->addInput(array('type'=>'combobox', 'name'=>'mark_paid_action_options', 'data'=>$mark_paid_action_options, 'value'=>$cl_mark_paid_action_option)); - $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->getKey('button.submit'))); + $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->get('button.submit'))); } if ($request->isPost()) { @@ -120,6 +120,6 @@ $smarty->assign('client_address', $client['address']); $smarty->assign('invoice_items', $invoice_items); $smarty->assign('colspan', $colspan); -$smarty->assign('title', $i18n->getKey('title.view_invoice')); +$smarty->assign('title', $i18n->get('title.view_invoice')); $smarty->assign('content_page_name', 'invoice_view.tpl'); $smarty->display('index.tpl'); diff --git a/invoices.php b/invoices.php index 0617a44f2..a03579b08 100644 --- a/invoices.php +++ b/invoices.php @@ -39,6 +39,6 @@ $invoices = ttTeamHelper::getActiveInvoices(); $smarty->assign('invoices', $invoices); -$smarty->assign('title', $i18n->getKey('title.invoices')); +$smarty->assign('title', $i18n->get('title.invoices')); $smarty->assign('content_page_name', 'invoices.tpl'); $smarty->display('index.tpl'); diff --git a/locking.php b/locking.php index 1f9530c97..8a6f4304c 100644 --- a/locking.php +++ b/locking.php @@ -40,11 +40,11 @@ $form = new Form('lockingForm'); $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'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { // Validate user input. - if (!ttValidCronSpec($cl_lock_spec)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.schedule')); + if (!ttValidCronSpec($cl_lock_spec)) $err->add($i18n->get('error.field'), $i18n->get('label.schedule')); if ($err->no()) { if (ttTeamHelper::update($user->team_id, array( @@ -53,12 +53,12 @@ header('Location: profile_edit.php'); exit(); } else { - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.locking')); +$smarty->assign('title', $i18n->get('title.locking')); $smarty->assign('content_page_name', 'locking.tpl'); $smarty->display('index.tpl'); diff --git a/login.php b/login.php index 538147b02..e246e0a51 100644 --- a/login.php +++ b/login.php @@ -39,12 +39,12 @@ $form->addInput(array('type'=>'text','size'=>'25','maxlength'=>'100','name'=>'login','style'=>'width: 220px;','value'=>$cl_login)); $form->addInput(array('type'=>'password','size'=>'25','maxlength'=>'50','name'=>'password','style'=>'width: 220px;','value'=>$cl_password)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_login click. -$form->addInput(array('type'=>'submit','name'=>'btn_login','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.login'))); +$form->addInput(array('type'=>'submit','name'=>'btn_login','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.login'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); - if (!ttValidString($cl_password)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); + if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); + if (!ttValidString($cl_password)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); if ($err->no()) { // Use the "limit" plugin if we have one. Ignore include errors. @@ -71,12 +71,12 @@ } exit(); } else - $err->add($i18n->getKey('error.auth')); + $err->add($i18n->get('error.auth')); } } // isPost if(!isTrue(MULTITEAM_MODE) && !ttGroupHelper::getTopGroups()) - $err->add($i18n->getKey('error.no_teams')); + $err->add($i18n->get('error.no_teams')); // Determine whether to show login hint. It is currently used only for Windows LDAP authentication. $show_hint = ('ad' == $GLOBALS['AUTH_MODULE_PARAMS']['type']); @@ -84,7 +84,7 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_hint', $show_hint); $smarty->assign('onload', 'onLoad="document.loginForm.'.(!$cl_login?'login':'password').'.focus()"'); -$smarty->assign('title', $i18n->getKey('title.login')); +$smarty->assign('title', $i18n->get('title.login')); $smarty->assign('content_page_name', 'login.tpl'); -$smarty->assign('about_text', $i18n->getKey('form.login.about')); +$smarty->assign('about_text', $i18n->get('form.login.about')); $smarty->display('index.tpl'); diff --git a/mobile/access_denied.php b/mobile/access_denied.php index b0bc00281..6e7174a26 100644 --- a/mobile/access_denied.php +++ b/mobile/access_denied.php @@ -28,9 +28,9 @@ require_once('../initialize.php'); -$err->add($i18n->getKey('error.access_denied')); +$err->add($i18n->get('error.access_denied')); if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. -$smarty->assign('title', $i18n->getKey('label.error')); +$smarty->assign('title', $i18n->get('label.error')); $smarty->assign('content_page_name', 'mobile/access_denied.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/client_add.php b/mobile/client_add.php index 71f51ca13..134819bb1 100644 --- a/mobile/client_add.php +++ b/mobile/client_add.php @@ -56,13 +56,13 @@ $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.tax')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); + if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); + if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); if ($err->no()) { if (!ttClientHelper::getClientByName($cl_name)) { @@ -76,14 +76,14 @@ header('Location: clients.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.client_exists')); + $err->add($i18n->get('error.client_exists')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.add_client')); +$smarty->assign('title', $i18n->get('title.add_client')); $smarty->assign('content_page_name', 'mobile/client_add.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/client_delete.php b/mobile/client_delete.php index b57e581db..e23cd026b 100644 --- a/mobile/client_delete.php +++ b/mobile/client_delete.php @@ -44,9 +44,9 @@ $form = new Form('clientDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$id)); $form->addInput(array('type'=>'combobox','name'=>'delete_client_entries', - 'data'=>array('0'=>$i18n->getKey('dropdown.do_not_delete'),'1'=>$i18n->getKey('dropdown.delete')))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); + 'data'=>array('0'=>$i18n->get('dropdown.do_not_delete'),'1'=>$i18n->get('dropdown.delete')))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if(ttClientHelper::getClient($id)) { @@ -55,10 +55,10 @@ header('Location: clients.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); if ($request->getParameter('btn_cancel')) { header('Location: clients.php'); @@ -68,6 +68,6 @@ $smarty->assign('client_to_delete', $client_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.delete_client')); +$smarty->assign('title', $i18n->get('title.delete_client')); $smarty->assign('content_page_name', 'mobile/client_delete.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/client_edit.php b/mobile/client_edit.php index fc2203697..e4bc9b22b 100644 --- a/mobile/client_edit.php +++ b/mobile/client_edit.php @@ -65,18 +65,18 @@ $form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','class'=>'mobile-textarea','value'=>$cl_address)); $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->getKey('dropdown.status_active'),INACTIVE=>$i18n->getKey('dropdown.status_inactive')))); + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'datakeys'=>array('id','name'),'layout'=>'H','value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->getKey('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.tax')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); + if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); + if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); if ($err->no()) { if ($request->getParameter('btn_save')) { @@ -92,9 +92,9 @@ header('Location: clients.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.client_exists')); + $err->add($i18n->get('error.client_exists')); } if ($request->getParameter('btn_copy')) { @@ -109,9 +109,9 @@ header('Location: clients.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.client_exists')); + $err->add($i18n->get('error.client_exists')); } if ($request->getParameter('btn_delete')) { @@ -122,6 +122,6 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.edit_client')); +$smarty->assign('title', $i18n->get('title.edit_client')); $smarty->assign('content_page_name', 'mobile/client_edit.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/clients.php b/mobile/clients.php index aa6e6ad30..d1a49f1e1 100644 --- a/mobile/clients.php +++ b/mobile/clients.php @@ -38,6 +38,6 @@ $smarty->assign('active_clients', ttTeamHelper::getActiveClients($user->team_id, true)); $smarty->assign('inactive_clients', ttTeamHelper::getInactiveClients($user->team_id, true)); -$smarty->assign('title', $i18n->getKey('title.clients')); +$smarty->assign('title', $i18n->get('title.clients')); $smarty->assign('content_page_name', 'mobile/clients.tpl'); $smarty->display('mobile/index.tpl'); From fd0872d9e582113346fa1e93557f370286c5c9f2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 17:01:42 +0000 Subject: [PATCH 0025/1848] Replaced getKey() with get() calls. --- WEB-INF/lib/I18n.class.php | 5 --- WEB-INF/templates/footer.tpl | 2 +- mobile/expense_delete.php | 12 +++--- mobile/expense_edit.php | 38 +++++++++--------- mobile/expenses.php | 26 ++++++------- mobile/login.php | 12 +++--- mobile/project_add.php | 12 +++--- mobile/project_delete.php | 10 ++--- mobile/project_edit.php | 22 +++++------ mobile/projects.php | 2 +- mobile/task_add.php | 12 +++--- mobile/task_delete.php | 10 ++--- mobile/task_edit.php | 22 +++++------ mobile/tasks.php | 2 +- mobile/time.php | 48 +++++++++++------------ mobile/time_delete.php | 12 +++--- mobile/time_edit.php | 58 ++++++++++++++-------------- mobile/timer.php | 36 +++++++++--------- mobile/user_add.php | 30 +++++++-------- mobile/user_delete.php | 8 ++-- mobile/user_edit.php | 34 ++++++++--------- mobile/users.php | 2 +- notification_add.php | 20 +++++----- notification_delete.php | 10 ++--- notification_edit.php | 20 +++++----- notifications.php | 4 +- password_change.php | 12 +++--- password_reset.php | 18 ++++----- predefined_expense_add.php | 10 ++--- predefined_expense_delete.php | 10 ++--- predefined_expense_edit.php | 10 ++--- predefined_expenses.php | 4 +- profile_edit.php | 42 ++++++++++---------- project_add.php | 12 +++--- project_delete.php | 10 ++--- project_edit.php | 20 +++++----- projects.php | 2 +- quotas.php | 10 ++--- register.php | 4 +- report.php | 18 ++++----- report_send.php | 18 ++++----- reports.php | 72 +++++++++++++++++------------------ role_add.php | 12 +++--- role_delete.php | 10 ++--- role_edit.php | 22 +++++------ roles.php | 2 +- swap_roles.php | 6 +-- table_test.php | 4 +- task_add.php | 12 +++--- task_delete.php | 10 ++--- task_edit.php | 20 +++++----- tasks.php | 2 +- time.php | 50 ++++++++++++------------ time_delete.php | 12 +++--- time_edit.php | 68 ++++++++++++++++----------------- tofile.php | 34 ++++++++--------- topdf.php | 52 ++++++++++++------------- user_add.php | 32 ++++++++-------- user_delete.php | 8 ++-- user_edit.php | 34 ++++++++--------- users.php | 2 +- week.php | 26 ++++++------- week_view.php | 6 +-- 63 files changed, 580 insertions(+), 585 deletions(-) diff --git a/WEB-INF/lib/I18n.class.php b/WEB-INF/lib/I18n.class.php index ed7497d70..0e3dd02a4 100644 --- a/WEB-INF/lib/I18n.class.php +++ b/WEB-INF/lib/I18n.class.php @@ -52,11 +52,6 @@ function get($key) { return $value; } - // getKey is a legacy function that we are replacing with get. - function getKey($kword) { - return $this->get($kword); - } - // TODO: refactoring ongoing down from here... function getWeekDayName($id) { $id = (int) $id; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7cf8ef60d..21c302736 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - +
 Anuko Time Tracker 1.17.67.4144 | Copyright © Anuko | +  Anuko Time Tracker 1.17.67.4145 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/expense_delete.php b/mobile/expense_delete.php index da902b4f0..48051b426 100644 --- a/mobile/expense_delete.php +++ b/mobile/expense_delete.php @@ -41,7 +41,7 @@ $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); // Prohibit deleting invoiced records. -if ($expense_item['invoice_id']) die($i18n->getKey('error.sys')); +if ($expense_item['invoice_id']) die($i18n->get('error.sys')); if ($request->isPost()) { if ($request->getParameter('delete_button')) { // Delete button pressed. @@ -49,7 +49,7 @@ // Determine if it is okay to delete the record. $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); if ($user->isDateLocked($item_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); if ($err->no()) { // Mark the record as deleted. @@ -57,7 +57,7 @@ header('Location: expenses.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } if ($request->getParameter('cancel_button')) { // Cancel button pressed. @@ -68,11 +68,11 @@ $form = new Form('expenseItemForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); $smarty->assign('expense_item', $expense_item); $smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('title', $i18n->getKey('title.delete_expense')); +$smarty->assign('title', $i18n->get('title.delete_expense')); $smarty->assign('content_page_name', 'mobile/expense_delete.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index fff249e77..7107e7851 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -44,7 +44,7 @@ $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); // Prohibit editing invoiced items. -if ($expense_item['invoice_id']) die($i18n->getKey('error.sys')); +if ($expense_item['invoice_id']) die($i18n->get('error.sys')); $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); @@ -77,7 +77,7 @@ 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Note: in other modes the client list is filtered to relevant clients only. See below. } @@ -90,7 +90,7 @@ 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { @@ -116,7 +116,7 @@ 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } // If predefined expenses are configured, add controls to select an expense and quantity. @@ -129,7 +129,7 @@ 'value'=>$cl_predefined_expense, 'data'=>$predefined_expenses, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); } $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'item_name','style'=>'width: 250px;','value'=>$cl_item_name)); @@ -138,20 +138,20 @@ // Hidden control for record id. $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.copy'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) - $err->add($i18n->getKey('error.client')); + $err->add($i18n->get('error.client')); if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->getKey('error.project')); + if (!$cl_project) $err->add($i18n->get('error.project')); } - if (!ttValidString($cl_item_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.item')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cost')); - if (!ttValidDate($cl_date)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.date')); + if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); + if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); + if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); // This is a new date for the expense item. $new_date = new DateAndTime($user->date_format, $cl_date); @@ -160,7 +160,7 @@ if (!$user->future_entries) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) - $err->add($i18n->getKey('error.future_date')); + $err->add($i18n->get('error.future_date')); } // Save record. @@ -172,11 +172,11 @@ // Now, step by step. // 1) Prohibit saving locked entries in any form. if ($user->isDateLocked($item_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // 2) Prohibit saving unlocked entries into locked range. if ($err->no() && $user->isDateLocked($new_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // Now, an update. if ($err->no()) { @@ -192,7 +192,7 @@ if ($request->getParameter('btn_copy')) { // We need to prohibit saving into locked interval. if ($user->isDateLocked($new_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // Now, a new insert. if ($err->no()) { @@ -201,7 +201,7 @@ header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } @@ -216,6 +216,6 @@ $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.edit_expense')); +$smarty->assign('title', $i18n->get('title.edit_expense')); $smarty->assign('content_page_name', 'mobile/expense_edit.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/expenses.php b/mobile/expenses.php index 40b3a342e..934c63a78 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -88,7 +88,7 @@ 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Note: in other modes the client list is filtered to relevant clients only. See below. } @@ -102,7 +102,7 @@ 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { @@ -128,7 +128,7 @@ 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } // If predefined expenses are configured, add controls to select an expense and quantity. @@ -141,38 +141,38 @@ 'value'=>$cl_predefined_expense, 'data'=>$predefined_expenses, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); } $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'item_name','style'=>'width: 250px;','value'=>$cl_item_name)); $form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); $form->addInput(array('type'=>'calendar','name'=>'date','highlight'=>'expenses','value'=>$cl_date)); // calendar $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); // Submit. if ($request->isPost()) { if ($request->getParameter('btn_submit')) { // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) - $err->add($i18n->getKey('error.client')); + $err->add($i18n->get('error.client')); if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->getKey('error.project')); + if (!$cl_project) $err->add($i18n->get('error.project')); } - if (!ttValidString($cl_item_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.item')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cost')); + if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); + if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); // Prohibit creating entries in future. if (!$user->future_entries) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) - $err->add($i18n->getKey('error.future_date')); + $err->add($i18n->get('error.future_date')); } // Finished validating input data. // Prohibit creating entries in locked range. if ($user->isDateLocked($selected_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // Insert record. if ($err->no()) { @@ -181,7 +181,7 @@ header('Location: expenses.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } elseif ($request->getParameter('onBehalfUser')) { if($user->canManageTeam()) { @@ -207,6 +207,6 @@ $smarty->assign('project_list', $project_list); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('timestring', $selected_date->toString($user->date_format)); -$smarty->assign('title', $i18n->getKey('title.expenses')); +$smarty->assign('title', $i18n->get('title.expenses')); $smarty->assign('content_page_name', 'mobile/expenses.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/login.php b/mobile/login.php index 384cf8c7f..4d1412d3c 100644 --- a/mobile/login.php +++ b/mobile/login.php @@ -42,12 +42,12 @@ $form->addInput(array('type'=>'text','size'=>'25','maxlength'=>'100','name'=>'login','style'=>'width: 220px;','value'=>$cl_login)); $form->addInput(array('type'=>'password','size'=>'25','maxlength'=>'50','name'=>'password','style'=>'width: 220px;','value'=>$cl_password)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_login click. -$form->addInput(array('type'=>'submit','name'=>'btn_login','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.login'))); +$form->addInput(array('type'=>'submit','name'=>'btn_login','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.login'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); - if (!ttValidString($cl_password)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); + if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); + if (!ttValidString($cl_password)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); if ($err->no()) { @@ -76,12 +76,12 @@ } exit(); } else - $err->add($i18n->getKey('error.auth')); + $err->add($i18n->get('error.auth')); } } // isPost if(!isTrue(MULTITEAM_MODE) && !ttGroupHelper::getTopGroups()) - $err->add($i18n->getKey('error.no_teams')); + $err->add($i18n->get('error.no_teams')); // Determine whether to show login hint. It is currently used only for Windows LDAP authentication. $show_hint = ('ad' == $GLOBALS['AUTH_MODULE_PARAMS']['type']); @@ -89,6 +89,6 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_hint', $show_hint); $smarty->assign('onload', 'onLoad="document.loginForm.'.(!$cl_login?'login':'password').'.focus()"'); -$smarty->assign('title', $i18n->getKey('title.login')); +$smarty->assign('title', $i18n->get('title.login')); $smarty->assign('content_page_name', 'mobile/login.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/project_add.php b/mobile/project_add.php index f7dc3fbf8..bbaa8fa75 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -63,12 +63,12 @@ $form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { @@ -82,14 +82,14 @@ header('Location: projects.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.project_exists')); + $err->add($i18n->get('error.project_exists')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.add_project')); +$smarty->assign('title', $i18n->get('title.add_project')); $smarty->assign('content_page_name', 'mobile/project_add.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/project_delete.php b/mobile/project_delete.php index 6e57f4d49..d2b0b32b8 100644 --- a/mobile/project_delete.php +++ b/mobile/project_delete.php @@ -42,8 +42,8 @@ $form = new Form('projectDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -52,9 +52,9 @@ header('Location: projects.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { header('Location: projects.php'); exit(); @@ -64,6 +64,6 @@ $smarty->assign('project_to_delete', $project_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.projectDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->getKey('title.delete_project')); +$smarty->assign('title', $i18n->get('title.delete_project')); $smarty->assign('content_page_name', 'mobile/project_delete.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/project_edit.php b/mobile/project_edit.php index 4c84c7c5b..31ea65da4 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -75,18 +75,18 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->getKey('dropdown.status_active'),INACTIVE=>$i18n->getKey('dropdown.status_inactive')))); + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->getKey('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($err->no()) { if ($request->getParameter('btn_save')) { @@ -103,9 +103,9 @@ header('Location: projects.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.project_exists')); + $err->add($i18n->get('error.project_exists')); } if ($request->getParameter('btn_copy')) { @@ -120,9 +120,9 @@ header('Location: projects.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.project_exists')); + $err->add($i18n->get('error.project_exists')); } if ($request->getParameter('btn_delete')) { @@ -134,6 +134,6 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.edit_project')); +$smarty->assign('title', $i18n->get('title.edit_project')); $smarty->assign('content_page_name', 'mobile/project_edit.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/projects.php b/mobile/projects.php index a6aa0448d..5dec7ee36 100644 --- a/mobile/projects.php +++ b/mobile/projects.php @@ -44,6 +44,6 @@ $smarty->assign('active_projects', $active_projects); $smarty->assign('inactive_projects', $inactive_projects); -$smarty->assign('title', $i18n->getKey('title.projects')); +$smarty->assign('title', $i18n->get('title.projects')); $smarty->assign('content_page_name', 'mobile/projects.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/task_add.php b/mobile/task_add.php index b413002b8..0c405b6fa 100644 --- a/mobile/task_add.php +++ b/mobile/task_add.php @@ -53,12 +53,12 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($err->no()) { if (!ttTaskHelper::getTaskByName($cl_name)) { @@ -71,14 +71,14 @@ header('Location: tasks.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.task_exists')); + $err->add($i18n->get('error.task_exists')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.taskForm.name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.add_task')); +$smarty->assign('title', $i18n->get('title.add_task')); $smarty->assign('content_page_name', 'mobile/task_add.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/task_delete.php b/mobile/task_delete.php index 4b6b149df..df3c964a5 100644 --- a/mobile/task_delete.php +++ b/mobile/task_delete.php @@ -42,8 +42,8 @@ $form = new Form('taskDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_task_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -52,9 +52,9 @@ header('Location: tasks.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { header('Location: tasks.php'); exit(); @@ -64,6 +64,6 @@ $smarty->assign('task_to_delete', $task_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->getKey('title.delete_task')); +$smarty->assign('title', $i18n->get('title.delete_task')); $smarty->assign('content_page_name', 'mobile/task_delete.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/task_edit.php b/mobile/task_edit.php index c4bc9d333..2ba2cc554 100644 --- a/mobile/task_edit.php +++ b/mobile/task_edit.php @@ -61,17 +61,17 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->getKey('dropdown.status_active'),INACTIVE=>$i18n->getKey('dropdown.status_inactive')))); + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->getKey('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($err->no()) { if ($request->getParameter('btn_save')) { @@ -87,9 +87,9 @@ header('Location: tasks.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.task_exists')); + $err->add($i18n->get('error.task_exists')); } if ($request->getParameter('btn_copy')) { @@ -103,9 +103,9 @@ header('Location: tasks.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.task_exists')); + $err->add($i18n->get('error.task_exists')); } if ($request->getParameter('btn_delete')) { @@ -116,6 +116,6 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.edit_task')); +$smarty->assign('title', $i18n->get('title.edit_task')); $smarty->assign('content_page_name', 'mobile/task_edit.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/tasks.php b/mobile/tasks.php index 1e8b40a7a..25575eb65 100644 --- a/mobile/tasks.php +++ b/mobile/tasks.php @@ -38,6 +38,6 @@ $smarty->assign('active_tasks', ttTeamHelper::getActiveTasks($user->team_id)); $smarty->assign('inactive_tasks', ttTeamHelper::getInactiveTasks($user->team_id)); -$smarty->assign('title', $i18n->getKey('title.tasks')); +$smarty->assign('title', $i18n->get('title.tasks')); $smarty->assign('content_page_name', 'mobile/tasks.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/time.php b/mobile/time.php index fc1f68ff1..abde5e01d 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -97,7 +97,7 @@ 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Note: in other modes the client list is filtered to relevant clients only. See below. } @@ -111,7 +111,7 @@ 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { @@ -138,7 +138,7 @@ 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } @@ -150,7 +150,7 @@ 'value'=>$cl_task, 'data'=>$task_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { $form->addInput(array('type'=>'text','name'=>'start','value'=>$cl_start,'onchange'=>"formDisable('start');")); @@ -167,7 +167,7 @@ if ($user->isPluginEnabled('iv')) $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); // If we have custom fields - add controls for them. if ($custom_fields && $custom_fields->fields[0]) { @@ -179,7 +179,7 @@ 'style'=>'width: 250px;', 'value'=>$cl_cf_1, 'data'=>$custom_fields->options, - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } @@ -189,62 +189,62 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) - $err->add($i18n->getKey('error.client')); + $err->add($i18n->get('error.client')); if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->getKey('error.field'), $custom_fields->fields[0]['label']); + if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); } if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->getKey('error.project')); + if (!$cl_project) $err->add($i18n->get('error.project')); } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode && $user->task_required) { - if (!$cl_task) $err->add($i18n->getKey('error.task')); + if (!$cl_task) $err->add($i18n->get('error.task')); } if (strlen($cl_duration) == 0) { if ($cl_start || $cl_finish) { if (!ttTimeHelper::isValidTime($cl_start)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.start')); + $err->add($i18n->get('error.field'), $i18n->get('label.start')); if ($cl_finish) { if (!ttTimeHelper::isValidTime($cl_finish)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.finish')); + $err->add($i18n->get('error.field'), $i18n->get('label.finish')); if (!ttTimeHelper::isValidInterval($cl_start, $cl_finish)) - $err->add($i18n->getKey('error.interval'), $i18n->getKey('label.finish'), $i18n->getKey('label.start')); + $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); } } else { if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.start')); - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.finish')); + $err->add($i18n->get('error.empty'), $i18n->get('label.start')); + $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); } if ((TYPE_DURATION == $user->record_type) || (TYPE_ALL == $user->record_type)) - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); } } else { if (false === ttTimeHelper::postedDurationToMinutes($cl_duration)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.field'), $i18n->get('label.duration')); } - if (!ttValidString($cl_note, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.note')); + if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); // Finished validating user input. // Prohibit creating entries in future. if (!$user->future_entries) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) - $err->add($i18n->getKey('error.future_date')); + $err->add($i18n->get('error.future_date')); } // Prohibit creating entries in locked range. if ($user->isDateLocked($selected_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // Prohibit creating another uncompleted record. if ($err->no()) { if (($not_completed_rec = ttTimeHelper::getUncompleted($user->getActiveUser())) && (($cl_finish == '') && ($cl_duration == ''))) - $err->add($i18n->getKey('error.uncompleted_exists')." ".$i18n->getKey('error.goto_uncompleted').""); + $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); } // Prohibit creating an overlapping record. if ($err->no()) { if (ttTimeHelper::overlaps($user->getActiveUser(), $cl_date, $cl_start, $cl_finish)) - $err->add($i18n->getKey('error.overlap')); + $err->add($i18n->get('error.overlap')); } if ($err->no()) { @@ -273,7 +273,7 @@ header('Location: time.php'); exit(); } - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } } // isPost @@ -288,6 +288,6 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="fillDropdowns()"'); $smarty->assign('timestring', $selected_date->toString($user->date_format)); -$smarty->assign('title', $i18n->getKey('title.time')); +$smarty->assign('title', $i18n->get('title.time')); $smarty->assign('content_page_name', 'mobile/time.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/time_delete.php b/mobile/time_delete.php index 63884d233..33ba61468 100644 --- a/mobile/time_delete.php +++ b/mobile/time_delete.php @@ -42,7 +42,7 @@ $time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); // Prohibit deleting invoiced records. -if ($time_rec['invoice_id']) die($i18n->getKey('error.sys')); +if ($time_rec['invoice_id']) die($i18n->get('error.sys')); // Escape comment for presentation. $time_rec['comment'] = htmlspecialchars($time_rec['comment']); @@ -57,7 +57,7 @@ $uncompleted = ($time_rec['duration'] == '0:00'); if ($user->isDateLocked($item_date) && !$uncompleted) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); if ($err->no()) { @@ -68,7 +68,7 @@ header('Location: time.php'); exit(); } else { - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } } @@ -80,10 +80,10 @@ $form = new Form('timeRecordForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); $smarty->assign('time_rec', $time_rec); $smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('title', $i18n->getKey('title.delete_time_record')); +$smarty->assign('title', $i18n->get('title.delete_time_record')); $smarty->assign('content_page_name', 'mobile/time_delete.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 6ec41defb..683bab74f 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -53,7 +53,7 @@ $time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); // Prohibit editing invoiced records. -if ($time_rec['invoice_id']) die($i18n->getKey('error.sys')); +if ($time_rec['invoice_id']) die($i18n->get('error.sys')); $item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); @@ -98,7 +98,7 @@ if (strlen($cl_start) > 0 && $cl_start == $cl_finish && $cl_duration == '0:00') { $cl_finish = ''; $cl_duration = ''; - $msg->add($i18n->getKey('form.time_edit.uncompleted')); + $msg->add($i18n->get('form.time_edit.uncompleted')); } } @@ -115,7 +115,7 @@ 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Note: in other modes the client list is filtered to relevant clients only. See below. } @@ -129,7 +129,7 @@ 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { @@ -156,7 +156,7 @@ 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } @@ -168,7 +168,7 @@ 'value'=>$cl_task, 'data'=>$task_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } // Add other controls. @@ -196,7 +196,7 @@ 'style'=>'width: 250px;', 'value'=>$cl_cf_1, 'data'=>$custom_fields->options, - 'empty' => array('' => $i18n->getKey('dropdown.select')))); + 'empty' => array('' => $i18n->get('dropdown.select')))); } } // Hidden control for record id. @@ -204,49 +204,49 @@ if ($user->isPluginEnabled('iv')) $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save click. -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) - $err->add($i18n->getKey('error.client')); + $err->add($i18n->get('error.client')); if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->getKey('error.field'), $custom_fields->fields[0]['label']); + if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); } if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->getKey('error.project')); + if (!$cl_project) $err->add($i18n->get('error.project')); } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode && $user->task_required) { - if (!$cl_task) $err->add($i18n->getKey('error.task')); + if (!$cl_task) $err->add($i18n->get('error.task')); } if (!$cl_duration) { if ('0' == $cl_duration) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.field'), $i18n->get('label.duration')); elseif ($cl_start || $cl_finish) { if (!ttTimeHelper::isValidTime($cl_start)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.start')); + $err->add($i18n->get('error.field'), $i18n->get('label.start')); if ($cl_finish) { if (!ttTimeHelper::isValidTime($cl_finish)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.finish')); + $err->add($i18n->get('error.field'), $i18n->get('label.finish')); if (!ttTimeHelper::isValidInterval($cl_start, $cl_finish)) - $err->add($i18n->getKey('error.interval'), $i18n->getKey('label.finish'), $i18n->getKey('label.start')); + $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); } } else { if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.start')); - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.finish')); + $err->add($i18n->get('error.empty'), $i18n->get('label.start')); + $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); } if ((TYPE_DURATION == $user->record_type) || (TYPE_ALL == $user->record_type)) - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); } } else { if (false === ttTimeHelper::postedDurationToMinutes($cl_duration)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.field'), $i18n->get('label.duration')); } - if (!ttValidDate($cl_date)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.date')); - if (!ttValidString($cl_note, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.note')); + if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); + if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); // Finished validating user input. // This is a new date for the time record. @@ -256,7 +256,7 @@ if (!$user->future_entries) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) - $err->add($i18n->getKey('error.future_date')); + $err->add($i18n->get('error.future_date')); } // Save record. @@ -270,11 +270,11 @@ if ($err->no()) { // 1) Prohibit saving locked entries in any form. if ($user->isDateLocked($item_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // 2) Prohibit saving completed unlocked entries into locked range. if ($err->no() && $user->isDateLocked($new_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // 3) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. $uncompleted = ($cl_finish == '' && $cl_duration == ''); @@ -282,7 +282,7 @@ $not_completed_rec = ttTimeHelper::getUncompleted($user->getActiveUser()); if ($not_completed_rec && ($time_rec['id'] <> $not_completed_rec['id'])) { // We have another not completed record. - $err->add($i18n->getKey('error.uncompleted_exists')." ".$i18n->getKey('error.goto_uncompleted').""); + $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); } } } @@ -290,7 +290,7 @@ // Prohibit creating an overlapping record. if ($err->no()) { if (ttTimeHelper::overlaps($user->getActiveUser(), $new_date->toString(DB_DATEFORMAT), $cl_start, $cl_finish, $cl_id)) - $err->add($i18n->getKey('error.overlap')); + $err->add($i18n->get('error.overlap')); } // Now, an update. @@ -334,6 +334,6 @@ $smarty->assign('task_list', $task_list); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="fillDropdowns()"'); -$smarty->assign('title', $i18n->getKey('title.edit_time_record')); +$smarty->assign('title', $i18n->get('title.edit_time_record')); $smarty->assign('content_page_name', 'mobile/time_edit.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/timer.php b/mobile/timer.php index 6851052f0..059767edd 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -97,7 +97,7 @@ 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Note: in other modes the client list is filtered to relevant clients only. See below. } @@ -112,7 +112,7 @@ 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { @@ -139,7 +139,7 @@ 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } @@ -152,7 +152,7 @@ 'value'=>$cl_task, 'data'=>$task_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } if ($user->isPluginEnabled('iv')) $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable,'enable'=>$enable_controls)); @@ -160,9 +160,9 @@ $form->addInput(array('type'=>'hidden','name'=>'browser_time','value'=>'')); // User current time, which gets filled in on button click. $enable_start = $uncompleted ? false : true; if (!$uncompleted) - $form->addInput(array('type'=>'submit','name'=>'btn_start','onclick'=>'browser_time.value=get_time()','value'=>$i18n->getKey('label.start'),'enable'=>$enable_start)); + $form->addInput(array('type'=>'submit','name'=>'btn_start','onclick'=>'browser_time.value=get_time()','value'=>$i18n->get('label.start'),'enable'=>$enable_start)); else - $form->addInput(array('type'=>'submit','name'=>'btn_stop','onclick'=>'browser_time.value=get_time()','value'=>$i18n->getKey('label.finish'),'enable'=>!$enable_start)); + $form->addInput(array('type'=>'submit','name'=>'btn_stop','onclick'=>'browser_time.value=get_time()','value'=>$i18n->get('label.finish'),'enable'=>!$enable_start)); // If we have custom fields - add controls for them. if ($custom_fields && $custom_fields->fields[0]) { @@ -174,7 +174,7 @@ 'style'=>'width: 250px;', 'value'=>$cl_cf_1, 'data'=>$custom_fields->options, - 'empty'=>array(''=>$i18n->getKey('dropdown.select')) + 'empty'=>array(''=>$i18n->get('dropdown.select')) )); } } @@ -187,15 +187,15 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) - $err->add($i18n->getKey('error.client')); + $err->add($i18n->get('error.client')); if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->getKey('error.field'), $custom_fields->fields[0]['label']); + if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); } if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->getKey('error.project')); + if (!$cl_project) $err->add($i18n->get('error.project')); } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_task) $err->add($i18n->getKey('error.task')); + if (!$cl_task) $err->add($i18n->get('error.task')); } // Finished validating user input. @@ -203,22 +203,22 @@ if (!$user->future_entries) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) - $err->add($i18n->getKey('error.future_date')); + $err->add($i18n->get('error.future_date')); } // Prohibit creating time entries in locked interval. if ($user->isDateLocked($selected_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // Prohibit creating another uncompleted record. if ($err->no() && $uncompleted) { - $err->add($i18n->getKey('error.uncompleted_exists')." ".$i18n->getKey('error.goto_uncompleted').""); + $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); } // Prohibit creating an overlapping record. if ($err->no()) { if (ttTimeHelper::overlaps($user->getActiveUser(), $cl_date, $cl_start, $cl_finish)) - $err->add($i18n->getKey('error.overlap')); + $err->add($i18n->get('error.overlap')); } if ($err->no()) { @@ -247,7 +247,7 @@ header('Location: timer.php'); exit(); } - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } if ($request->getParameter('btn_stop')) { @@ -272,7 +272,7 @@ header('Location: timer.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else { // Cannot complete, redirect for manual edit. header('Location: time_edit.php?id='.$record['id']); @@ -296,6 +296,6 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="fillDropdowns()"'); $smarty->assign('timestring', $selected_date->toString($user->date_format)); -$smarty->assign('title', $i18n->getKey('title.time')); +$smarty->assign('title', $i18n->get('title.time')); $smarty->assign('content_page_name', 'mobile/timer.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/user_add.php b/mobile/user_add.php index 7fff9a064..838981de4 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -67,7 +67,7 @@ $project_with_rate['rate'] = $request->getParameter('rate_'.$p); $assigned_projects[] = $project_with_rate; } else - $err->add($i18n->getKey('error.field'), 'rate_'.$p); + $err->add($i18n->get('error.field'), 'rate_'.$p); } } } @@ -84,7 +84,7 @@ $active_roles = ttTeamHelper::getActiveRolesForUser(); $form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles,'datakeys'=>array('id', 'name'))); if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); @@ -120,24 +120,24 @@ function render(&$table, $value, $row, $column, $selected = false) { $table->setData($projects); $table->setKeyField('id'); $table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->getKey('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->getKey('form.users.rate'), new RateCellRenderer())); +$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); +$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); $form->addInputElement($table); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); + if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); if (!$auth->isPasswordExternal()) { - if (!ttValidString($cl_password1)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); + if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($cl_password1 !== $cl_password2) - $err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('form.users.default_rate')); + if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); + if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); if ($err->no()) { if (!ttUserHelper::getUserByLogin($cl_login)) { @@ -155,9 +155,9 @@ function render(&$table, $value, $row, $column, $selected = false) { header('Location: users.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.user_exists')); + $err->add($i18n->get('error.user_exists')); } } // isPost @@ -165,6 +165,6 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('active_roles', $active_roles); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); -$smarty->assign('title', $i18n->getKey('title.add_user')); +$smarty->assign('title', $i18n->get('title.add_user')); $smarty->assign('content_page_name', 'mobile/user_add.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/user_delete.php b/mobile/user_delete.php index cb0e1a2cd..d8400456a 100644 --- a/mobile/user_delete.php +++ b/mobile/user_delete.php @@ -58,8 +58,8 @@ // Create confirmation form. $form = new Form('userDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$user_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -82,7 +82,7 @@ } exit(); } else { - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } if ($request->getParameter('btn_cancel')) { @@ -92,6 +92,6 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.delete_user')); +$smarty->assign('title', $i18n->get('title.delete_user')); $smarty->assign('content_page_name', 'mobile/user_delete.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/user_edit.php b/mobile/user_edit.php index 89a473cb6..285c3442b 100644 --- a/mobile/user_edit.php +++ b/mobile/user_edit.php @@ -82,7 +82,7 @@ $project_with_rate['rate'] = $request->getParameter('rate_'.$p); $assigned_projects[] = $project_with_rate; } else - $err->add($i18n->getKey('error.field'), 'rate_'.$p); + $err->add($i18n->get('error.field'), 'rate_'.$p); } } } else { @@ -112,10 +112,10 @@ $active_roles = ttTeamHelper::getActiveRolesForUser(); $form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles,'datakeys'=>array('id', 'name'))); if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->getKey('dropdown.status_active'),INACTIVE=>$i18n->getKey('dropdown.status_inactive')))); + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); // Define classes for the projects table. @@ -148,27 +148,27 @@ function render(&$table, $value, $row, $column, $selected = false) { $table->setData($projects); $table->setKeyField('id'); $table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->getKey('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->getKey('form.users.rate'), new RateCellRenderer())); +$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); +$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); $form->addInputElement($table); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$user_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { if ($request->getParameter('btn_submit')) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); + if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { - if (!ttValidString($cl_password1)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); + if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($cl_password1 !== $cl_password2) - $err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('form.users.default_rate')); + if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); + if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); if ($err->no()) { $existing_user = ttUserHelper::getUserByLogin($cl_login); @@ -214,9 +214,9 @@ function render(&$table, $value, $row, $column, $selected = false) { exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.user_exists')); + $err->add($i18n->get('error.user_exists')); } } @@ -234,6 +234,6 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); $smarty->assign('user_id', $user_id); -$smarty->assign('title', $i18n->getKey('title.edit_user')); +$smarty->assign('title', $i18n->get('title.edit_user')); $smarty->assign('content_page_name', 'mobile/user_edit.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/users.php b/mobile/users.php index 8ae0fc930..131d2b44c 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -55,6 +55,6 @@ $smarty->assign('active_users', $active_users); $smarty->assign('inactive_users', $inactive_users); $smarty->assign('can_delete_manager', $can_delete_manager); -$smarty->assign('title', $i18n->getKey('title.users')); +$smarty->assign('title', $i18n->get('title.users')); $smarty->assign('content_page_name', 'mobile/users.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/notification_add.php b/notification_add.php index 3cac65217..6d0e4d31a 100644 --- a/notification_add.php +++ b/notification_add.php @@ -59,23 +59,23 @@ 'value'=>$cl_fav_report, 'data'=>$fav_reports, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')) + 'empty'=>array(''=>$i18n->get('dropdown.select')) )); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'cron_spec','style'=>'width: 250px;','value'=>$cl_cron_spec)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','style'=>'width: 250px;','value'=>$cl_email)); $form->addInput(array('type'=>'text','name'=>'cc','style'=>'width: 300px;','value'=>$cl_cc)); $form->addInput(array('type'=>'text','name'=>'subject','style'=>'width: 300px;','value'=>$cl_subject)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'report_condition','style'=>'width: 250px;','value'=>$cl_report_condition)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. - if (!$cl_fav_report) $err->add($i18n->getKey('error.report')); - if (!ttValidCronSpec($cl_cron_spec)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.schedule')); - if (!ttValidEmail($cl_email)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); - if (!ttValidEmail($cl_cc, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cc')); - if (!ttValidString($cl_subject, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.subject')); - if (!ttValidCondition($cl_report_condition)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.condition')); + if (!$cl_fav_report) $err->add($i18n->get('error.report')); + if (!ttValidCronSpec($cl_cron_spec)) $err->add($i18n->get('error.field'), $i18n->get('label.schedule')); + if (!ttValidEmail($cl_email)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); + if (!ttValidEmail($cl_cc, true)) $err->add($i18n->get('error.field'), $i18n->get('label.cc')); + if (!ttValidString($cl_subject, true)) $err->add($i18n->get('error.field'), $i18n->get('label.subject')); + if (!ttValidCondition($cl_report_condition)) $err->add($i18n->get('error.field'), $i18n->get('label.condition')); if ($err->no()) { // Calculate next execution time. @@ -94,11 +94,11 @@ header('Location: notifications.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.add_notification')); +$smarty->assign('title', $i18n->get('title.add_notification')); $smarty->assign('content_page_name', 'notification_add.tpl'); $smarty->display('index.tpl'); diff --git a/notification_delete.php b/notification_delete.php index 0b6cf5ccc..46de065d6 100644 --- a/notification_delete.php +++ b/notification_delete.php @@ -42,8 +42,8 @@ $form = new Form('notificationDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_notification_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -52,9 +52,9 @@ header('Location: notifications.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { header('Location: notifications.php'); exit(); @@ -64,6 +64,6 @@ $smarty->assign('notification_to_delete', $notification_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.notificationDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->getKey('title.delete_notification')); +$smarty->assign('title', $i18n->get('title.delete_notification')); $smarty->assign('content_page_name', 'notification_delete.tpl'); $smarty->display('index.tpl'); diff --git a/notification_edit.php b/notification_edit.php index ec26f610b..431798285 100644 --- a/notification_edit.php +++ b/notification_edit.php @@ -67,22 +67,22 @@ 'value'=>$cl_fav_report, 'data'=>$fav_reports, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'cron_spec','style'=>'width: 250px;','value'=>$cl_cron_spec)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','style'=>'width: 250px;','value'=>$cl_email)); $form->addInput(array('type'=>'text','name'=>'cc','style'=>'width: 300px;','value'=>$cl_cc)); $form->addInput(array('type'=>'text','name'=>'subject','style'=>'width: 300px;','value'=>$cl_subject)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'report_condition','style'=>'width: 250px;','value'=>$cl_report_condition)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.save'))); if ($request->isPost()) { // Validate user input. - if (!$cl_fav_report) $err->add($i18n->getKey('error.report')); - if (!ttValidCronSpec($cl_cron_spec)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.schedule')); - if (!ttValidEmail($cl_email)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); - if (!ttValidEmail($cl_cc, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cc')); - if (!ttValidString($cl_subject, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.subject')); - if (!ttValidCondition($cl_report_condition)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.condition')); + if (!$cl_fav_report) $err->add($i18n->get('error.report')); + if (!ttValidCronSpec($cl_cron_spec)) $err->add($i18n->get('error.field'), $i18n->get('label.schedule')); + if (!ttValidEmail($cl_email)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); + if (!ttValidEmail($cl_cc, true)) $err->add($i18n->get('error.field'), $i18n->get('label.cc')); + if (!ttValidString($cl_subject, true)) $err->add($i18n->get('error.field'), $i18n->get('label.subject')); + if (!ttValidCondition($cl_report_condition)) $err->add($i18n->get('error.field'), $i18n->get('label.condition')); if ($err->no()) { // Calculate next execution time. @@ -102,11 +102,11 @@ header('Location: notifications.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.edit_notification')); +$smarty->assign('title', $i18n->get('title.edit_notification')); $smarty->assign('content_page_name', 'notification_edit.tpl'); $smarty->display('index.tpl'); diff --git a/notifications.php b/notifications.php index 4205dffaf..c03378d29 100644 --- a/notifications.php +++ b/notifications.php @@ -45,12 +45,12 @@ exit(); } } else { - $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->getKey('button.add'))); + $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); $notifications = ttTeamHelper::getNotifications($user->team_id); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('notifications', $notifications); -$smarty->assign('title', $i18n->getKey('title.notifications')); +$smarty->assign('title', $i18n->get('title.notifications')); $smarty->assign('content_page_name', 'notifications.tpl'); $smarty->display('index.tpl'); diff --git a/password_change.php b/password_change.php index 89e79c7ff..bcbd5f4ad 100644 --- a/password_change.php +++ b/password_change.php @@ -62,14 +62,14 @@ $form->addInput(array('type'=>'password','maxlength'=>'120','name'=>'password1','value'=>$cl_password1)); $form->addInput(array('type'=>'password','maxlength'=>'120','name'=>'password2','value'=>$cl_password2)); $form->addInput(array('type'=>'hidden','name'=>'ref','value'=>$cl_ref)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_password1)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); + if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($cl_password1 !== $cl_password2) - $err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); if ($err->no()) { // Use the "limit" plugin if we have one. Ignore include errors. @@ -91,12 +91,12 @@ } exit(); } else { - $err->add($i18n->getKey('error.auth')); + $err->add($i18n->get('error.auth')); } } } // isPost $smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('title', $i18n->getKey('title.change_password')); +$smarty->assign('title', $i18n->get('title.change_password')); $smarty->assign('content_page_name', 'password_change.tpl'); $smarty->display('index.tpl'); diff --git a/password_reset.php b/password_reset.php index e73dcf816..1ee4711ed 100644 --- a/password_reset.php +++ b/password_reset.php @@ -38,13 +38,13 @@ $form = new Form('resetPasswordForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','style'=>'width: 300px;')); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.reset_password'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.reset_password'))); if ($request->isPost()) { $cl_login = $request->getParameter('login'); // Validate user input. - if (!ttValidString($cl_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); + if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); if ($err->no()) { if (!ttUserHelper::getUserByLogin($cl_login)) { @@ -55,9 +55,9 @@ if ($login) $cl_login = $login; else - $err->add($i18n->getKey('error.no_login')); + $err->add($i18n->get('error.no_login')); } else - $err->add($i18n->getKey('error.no_login')); + $err->add($i18n->get('error.no_login')); } } @@ -83,7 +83,7 @@ if (ttValidEmail($cl_login)) $receiver = $cl_login; else - $err->add($i18n->getKey('error.no_email')); + $err->add($i18n->get('error.no_email')); } if ($receiver) { @@ -99,21 +99,21 @@ else $http = 'http'; - $cl_subject = $user_i18n->getKey('form.reset_password.email_subject'); + $cl_subject = $user_i18n->get('form.reset_password.email_subject'); if (APP_NAME) $pass_edit_url = $http.'://'.$_SERVER['HTTP_HOST'].'/'.APP_NAME.'/password_change.php?ref='.$temp_ref; else $pass_edit_url = $http.'://'.$_SERVER['HTTP_HOST'].'/password_change.php?ref='.$temp_ref; $sender->setMailMode(MAIL_MODE); - $res = $sender->send($cl_subject, sprintf($user_i18n->getKey('form.reset_password.email_body'), $_SERVER['REMOTE_ADDR'], $pass_edit_url)); - $smarty->assign('result_message', $res ? $i18n->getKey('form.reset_password.message') : $i18n->getKey('error.mail_send')); + $res = $sender->send($cl_subject, sprintf($user_i18n->get('form.reset_password.email_body'), $_SERVER['REMOTE_ADDR'], $pass_edit_url)); + $smarty->assign('result_message', $res ? $i18n->get('form.reset_password.message') : $i18n->get('error.mail_send')); } } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.resetPasswordForm.login.focus()"'); -$smarty->assign('title', $i18n->getKey('title.reset_password')); +$smarty->assign('title', $i18n->get('title.reset_password')); $smarty->assign('content_page_name', 'password_reset.tpl'); $smarty->display('index.tpl'); diff --git a/predefined_expense_add.php b/predefined_expense_add.php index 5e7305996..82cf99b63 100644 --- a/predefined_expense_add.php +++ b/predefined_expense_add.php @@ -44,12 +44,12 @@ $form = new Form('predefinedExpenseForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cost')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); if ($err->no()) { if (ttPredefinedExpenseHelper::insert(array( 'team_id' => $user->team_id, @@ -58,11 +58,11 @@ header('Location: predefined_expenses.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.add_predefined_expense')); +$smarty->assign('title', $i18n->get('title.add_predefined_expense')); $smarty->assign('content_page_name', 'predefined_expense_add.tpl'); $smarty->display('index.tpl'); diff --git a/predefined_expense_delete.php b/predefined_expense_delete.php index 3b1cde554..c8ae1c822 100644 --- a/predefined_expense_delete.php +++ b/predefined_expense_delete.php @@ -42,8 +42,8 @@ $form = new Form('predefinedExpenseDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_predefined_expense_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -52,9 +52,9 @@ header('Location: predefined_expenses.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { header('Location: predefined_expenses.php'); exit(); @@ -64,6 +64,6 @@ $smarty->assign('predefined_expense_to_delete', $predefined_expense_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.predefinedExpenseDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->getKey('title.delete_predefined_expense')); +$smarty->assign('title', $i18n->get('title.delete_predefined_expense')); $smarty->assign('content_page_name', 'predefined_expense_delete.tpl'); $smarty->display('index.tpl'); diff --git a/predefined_expense_edit.php b/predefined_expense_edit.php index 64bf9d84d..220778a98 100644 --- a/predefined_expense_edit.php +++ b/predefined_expense_edit.php @@ -51,12 +51,12 @@ $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$predefined_expense_id)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cost')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); if ($err->no()) { if (ttPredefinedExpenseHelper::update(array( 'id' => $predefined_expense_id, @@ -66,11 +66,11 @@ header('Location: predefined_expenses.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.edit_predefined_expense')); +$smarty->assign('title', $i18n->get('title.edit_predefined_expense')); $smarty->assign('content_page_name', 'predefined_expense_edit.tpl'); $smarty->display('index.tpl'); diff --git a/predefined_expenses.php b/predefined_expenses.php index 9db98e0ea..4e799121b 100644 --- a/predefined_expenses.php +++ b/predefined_expenses.php @@ -45,12 +45,12 @@ exit(); } } else { - $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->getKey('button.add'))); + $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); $predefinedExpenses = ttTeamHelper::getPredefinedExpenses($user->team_id); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('predefined_expenses', $predefinedExpenses); -$smarty->assign('title', $i18n->getKey('title.predefined_expenses')); +$smarty->assign('title', $i18n->get('title.predefined_expenses')); $smarty->assign('content_page_name', 'predefined_expenses.tpl'); $smarty->display('index.tpl'); diff --git a/profile_edit.php b/profile_edit.php index ba157a9ca..9c27ab41a 100644 --- a/profile_edit.php +++ b/profile_edit.php @@ -165,8 +165,8 @@ $form->addInput(array('type'=>'combobox','name'=>'date_format','style'=>'width: 150px;','data'=>$DATE_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_date_format, 'onchange'=>'MakeFormatPreview("date_format_preview", this);')); $TIME_FORMAT_OPTIONS = array( - array('id'=>'%H:%M','name'=>$i18n->getKey('form.profile.24_hours')), - array('id'=>'%I:%M %p','name'=>$i18n->getKey('form.profile.12_hours'))); + array('id'=>'%H:%M','name'=>$i18n->get('form.profile.24_hours')), + array('id'=>'%I:%M %p','name'=>$i18n->get('form.profile.12_hours'))); $form->addInput(array('type'=>'combobox','name'=>'time_format','style'=>'width: 150px;','data'=>$TIME_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_time_format, 'onchange'=>'MakeFormatPreview("time_format_preview", this);')); @@ -182,18 +182,18 @@ // Prepare tracking mode choices. $tracking_mode_options = array(); - $tracking_mode_options[MODE_TIME] = $i18n->getKey('form.profile.mode_time'); - $tracking_mode_options[MODE_PROJECTS] = $i18n->getKey('form.profile.mode_projects'); - $tracking_mode_options[MODE_PROJECTS_AND_TASKS] = $i18n->getKey('form.profile.mode_projects_and_tasks'); + $tracking_mode_options[MODE_TIME] = $i18n->get('form.profile.mode_time'); + $tracking_mode_options[MODE_PROJECTS] = $i18n->get('form.profile.mode_projects'); + $tracking_mode_options[MODE_PROJECTS_AND_TASKS] = $i18n->get('form.profile.mode_projects_and_tasks'); $form->addInput(array('type'=>'combobox','name'=>'tracking_mode','style'=>'width: 150px;','data'=>$tracking_mode_options,'value'=>$cl_tracking_mode,'onchange'=>'handleTaskRequiredCheckbox()')); $form->addInput(array('type'=>'checkbox','name'=>'project_required','value'=>$cl_project_required)); $form->addInput(array('type'=>'checkbox','name'=>'task_required','value'=>$cl_task_required)); // Prepare record type choices. $record_type_options = array(); - $record_type_options[TYPE_ALL] = $i18n->getKey('form.profile.type_all'); - $record_type_options[TYPE_START_FINISH] = $i18n->getKey('form.profile.type_start_finish'); - $record_type_options[TYPE_DURATION] = $i18n->getKey('form.profile.type_duration'); + $record_type_options[TYPE_ALL] = $i18n->get('form.profile.type_all'); + $record_type_options[TYPE_START_FINISH] = $i18n->get('form.profile.type_start_finish'); + $record_type_options[TYPE_DURATION] = $i18n->get('form.profile.type_duration'); $form->addInput(array('type'=>'combobox','name'=>'record_type','style'=>'width: 150px;','data'=>$record_type_options,'value'=>$cl_record_type)); // Punch mode checkbox. @@ -227,30 +227,30 @@ $form->addInput(array('type'=>'checkbox','name'=>'quotas','value'=>$cl_quotas,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'checkbox','name'=>'week_view','value'=>$cl_week_view,'onchange'=>'handlePluginCheckboxes()')); } -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.person_name')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); if ($can_change_login) { - if (!ttValidString($cl_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); + if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); // New login must be unique. if ($cl_login != $user->login && ttUserHelper::getUserByLogin($cl_login)) - $err->add($i18n->getKey('error.user_exists')); + $err->add($i18n->get('error.user_exists')); } if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { - if (!ttValidString($cl_password1)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); + if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($cl_password1 !== $cl_password2) - $err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); if ($user->canManageTeam()) { - if (!ttValidString($cl_team, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.team_name')); - if (!ttValidString($cl_currency, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.currency')); + if (!ttValidString($cl_team, true)) $err->add($i18n->get('error.field'), $i18n->get('label.team_name')); + if (!ttValidString($cl_currency, true)) $err->add($i18n->get('error.field'), $i18n->get('label.currency')); if ($user->isManager()) { - if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.bcc')); + if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.bcc')); } } // Finished validating user input. @@ -338,13 +338,13 @@ header('Location: time.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } // isPost $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="handleTaskRequiredCheckbox(); handlePluginCheckboxes();"'); -$smarty->assign('title', $i18n->getKey('title.profile')); +$smarty->assign('title', $i18n->get('title.profile')); $smarty->assign('content_page_name', 'profile_edit.tpl'); $smarty->display('index.tpl'); diff --git a/project_add.php b/project_add.php index 99f8c6d5f..6b55019cb 100644 --- a/project_add.php +++ b/project_add.php @@ -63,12 +63,12 @@ $form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { @@ -82,14 +82,14 @@ header('Location: projects.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.project_exists')); + $err->add($i18n->get('error.project_exists')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.add_project')); +$smarty->assign('title', $i18n->get('title.add_project')); $smarty->assign('content_page_name', 'project_add.tpl'); $smarty->display('index.tpl'); diff --git a/project_delete.php b/project_delete.php index a6b6ed532..683dbc50c 100644 --- a/project_delete.php +++ b/project_delete.php @@ -42,8 +42,8 @@ $form = new Form('projectDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -52,9 +52,9 @@ header('Location: projects.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { header('Location: projects.php'); exit(); @@ -64,6 +64,6 @@ $smarty->assign('project_to_delete', $project_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.projectDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->getKey('title.delete_project')); +$smarty->assign('title', $i18n->get('title.delete_project')); $smarty->assign('content_page_name', 'project_delete.tpl'); $smarty->display('index.tpl'); diff --git a/project_edit.php b/project_edit.php index d7b67565c..be0e90fa9 100644 --- a/project_edit.php +++ b/project_edit.php @@ -75,17 +75,17 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->getKey('dropdown.status_active'),INACTIVE=>$i18n->getKey('dropdown.status_inactive')))); + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->getKey('button.copy'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($err->no()) { if ($request->getParameter('btn_save')) { @@ -102,9 +102,9 @@ header('Location: projects.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.project_exists')); + $err->add($i18n->get('error.project_exists')); } if ($request->getParameter('btn_copy')) { @@ -119,15 +119,15 @@ header('Location: projects.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.project_exists')); + $err->add($i18n->get('error.project_exists')); } } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.projectForm.name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.edit_project')); +$smarty->assign('title', $i18n->get('title.edit_project')); $smarty->assign('content_page_name', 'project_edit.tpl'); $smarty->display('index.tpl'); diff --git a/projects.php b/projects.php index ce7bb9a1a..ed0103a4e 100644 --- a/projects.php +++ b/projects.php @@ -44,6 +44,6 @@ $smarty->assign('active_projects', $active_projects); $smarty->assign('inactive_projects', $inactive_projects); -$smarty->assign('title', $i18n->getKey('title.projects')); +$smarty->assign('title', $i18n->get('title.projects')); $smarty->assign('content_page_name', 'projects.tpl'); $smarty->display('index.tpl'); diff --git a/quotas.php b/quotas.php index 06fdbbe5a..19e70e505 100644 --- a/quotas.php +++ b/quotas.php @@ -72,12 +72,12 @@ if ($request->isPost()){ // Validate user input. if (false === ttTimeHelper::postedDurationToMinutes($request->getParameter('workdayHours'))) - $err->add($i18n->getKey('error.field'), $i18n->getKey('form.quota.workday_hours')); + $err->add($i18n->get('error.field'), $i18n->get('form.quota.workday_hours')); for ($i = 0; $i < count($months); $i++){ $val = $request->getParameter($months[$i]); if (false === ttTimeHelper::postedDurationToMinutes($val, 44640/*24*60*31*/)) - $err->add($i18n->getKey('error.field'), $months[$i]); + $err->add($i18n->get('error.field'), $months[$i]); } // Finished validating user input. @@ -87,7 +87,7 @@ $workday_minutes = ttTimeHelper::postedDurationToMinutes($request->getParameter('workdayHours')); if ($workday_minutes != $user->workday_minutes) { if (!ttTeamHelper::update($user->team_id, array('name'=>$user->team,'workday_minutes'=>$workday_minutes))) - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } // Handle monthly quotas for a selected year. @@ -95,7 +95,7 @@ for ($i = 0; $i < count($months); $i++){ $quota_in_minutes = ttTimeHelper::postedDurationToMinutes($request->getParameter($months[$i]), 44640/*24*60*31*/); if (!$quota->update($selectedYear, $i+1, $quota_in_minutes)) - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } if ($err->no()) { @@ -125,6 +125,6 @@ $smarty->assign('months', $months); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.monthly_quotas')); +$smarty->assign('title', $i18n->get('title.monthly_quotas')); $smarty->assign('content_page_name', 'quotas.tpl'); $smarty->display('index.tpl'); diff --git a/register.php b/register.php index 3ddcb9902..32fed57ad 100644 --- a/register.php +++ b/register.php @@ -80,7 +80,7 @@ $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'password1','value'=>$cl_password1)); $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'password2','value'=>$cl_password2)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'manager_email','value'=>$cl_manager_email)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { // Create fields array for ttRegistrator instance. @@ -111,7 +111,7 @@ } } // isPost -$smarty->assign('title', $i18n->getKey('title.create_team')); +$smarty->assign('title', $i18n->get('title.create_team')); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.profileForm.team.focus()"'); $smarty->assign('content_page_name', 'register.tpl'); diff --git a/report.php b/report.php index c4bfd0683..190dff8ee 100644 --- a/report.php +++ b/report.php @@ -75,17 +75,17 @@ // Controls for "Mark paid" block. if ($bean->getAttribute('chpaid')) { - $mark_paid_select_options = array('1'=>$i18n->getKey('dropdown.all'),'2'=>$i18n->getKey('dropdown.select')); + $mark_paid_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); $form->addInput(array('type'=>'combobox', 'name'=>'mark_paid_select_options', 'data'=>$mark_paid_select_options, 'value'=>$cl_mark_paid_select_option)); - $mark_paid_action_options = array('1'=>$i18n->getKey('dropdown.paid'),'2'=>$i18n->getKey('dropdown.not_paid')); + $mark_paid_action_options = array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')); $form->addInput(array('type'=>'combobox', 'name'=>'mark_paid_action_options', 'data'=>$mark_paid_action_options, 'value'=>$cl_mark_paid_action_option)); - $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->getKey('button.submit'))); + $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->get('button.submit'))); $smarty->assign('use_mark_paid', true); } @@ -94,7 +94,7 @@ // Client is selected and we are displaying the invoice column. $recent_invoices = ttTeamHelper::getRecentInvoices($user->team_id, $client_id); if ($recent_invoices) { - $assign_invoice_select_options = array('1'=>$i18n->getKey('dropdown.all'),'2'=>$i18n->getKey('dropdown.select')); + $assign_invoice_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); $form->addInput(array('type'=>'combobox', 'name'=>'assign_invoice_select_options', 'data'=>$assign_invoice_select_options, @@ -104,8 +104,8 @@ 'data'=>$recent_invoices, 'datakeys'=>array('id','name'), 'value'=>$cl_recent_invoice_option, - 'empty'=>array(''=>$i18n->getKey('dropdown.select_invoice')))); - $form->addInput(array('type'=>'submit','name'=>'btn_assign','value'=>$i18n->getKey('button.submit'))); + 'empty'=>array(''=>$i18n->get('dropdown.select_invoice')))); + $form->addInput(array('type'=>'submit','name'=>'btn_assign','value'=>$i18n->get('button.submit'))); $smarty->assign('use_assign_to_invoice', true); } } @@ -122,7 +122,7 @@ if ('item_id_' == substr($key, 0, 8)) $expense_item_ids[] = substr($key, 8); } - if (!$time_log_ids && !$expense_item_ids) $err->Add($i18n->getKey('error.record')); // There are no selected records. + if (!$time_log_ids && !$expense_item_ids) $err->Add($i18n->get('error.record')); // There are no selected records. // Validation of parameteres ended here. } else { // We are assigning all report items. Get the arrays from session. @@ -193,7 +193,7 @@ $smarty->assign('group_by_header', $custom_fields->fields[0]['label']); else { $key = 'label.'.$group_by; - $smarty->assign('group_by_header', $i18n->getKey($key)); + $smarty->assign('group_by_header', $i18n->get($key)); } } // Assign variables that are used to alternate color of rows for different dates. @@ -207,6 +207,6 @@ $smarty->assign('subtotals', $subtotals); $smarty->assign('totals', $totals); $smarty->assign('bean', $bean); -$smarty->assign('title', $i18n->getKey('title.report').": ".$totals['start_date']." - ".$totals['end_date']); +$smarty->assign('title', $i18n->get('title.report').": ".$totals['start_date']." - ".$totals['end_date']); $smarty->assign('content_page_name', 'report.tpl'); $smarty->display('index.tpl'); diff --git a/report_send.php b/report_send.php index 9be9676fd..b420b3aca 100644 --- a/report_send.php +++ b/report_send.php @@ -48,7 +48,7 @@ } else { $cl_receiver = $sc->getValue(SYSC_LAST_REPORT_EMAIL); $cl_cc = $sc->getValue(SYSC_LAST_REPORT_CC); - $cl_subject = $i18n->getKey('form.mail.report_subject'); + $cl_subject = $i18n->get('form.mail.report_subject'); } $form = new Form('mailForm'); @@ -56,14 +56,14 @@ $form->addInput(array('type'=>'text','name'=>'cc','style'=>'width: 300px;','value'=>$cl_cc)); $form->addInput(array('type'=>'text','name'=>'subject','style'=>'width: 300px;','value'=>$cl_subject)); $form->addInput(array('type'=>'textarea','name'=>'comment','maxlength'=>'250','style'=>'width: 300px; height: 60px;')); -$form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->getKey('button.send'))); +$form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('button.send'))); if ($request->isPost()) { // Validate user input. - if (!ttValidEmailList($cl_receiver)) $err->add($i18n->getKey('error.field'), $i18n->getKey('form.mail.to')); - if (!ttValidEmailList($cl_cc, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cc')); - if (!ttValidString($cl_subject)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.subject')); - if (!ttValidString($cl_comment, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.comment')); + if (!ttValidEmailList($cl_receiver)) $err->add($i18n->get('error.field'), $i18n->get('form.mail.to')); + if (!ttValidEmailList($cl_cc, true)) $err->add($i18n->get('error.field'), $i18n->get('label.cc')); + if (!ttValidString($cl_subject)) $err->add($i18n->get('error.field'), $i18n->get('label.subject')); + if (!ttValidString($cl_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); if ($err->no()) { // Save last report emails for future use. @@ -87,9 +87,9 @@ $mailer->setReceiverBCC($user->bcc_email); $mailer->setMailMode(MAIL_MODE); if ($mailer->send($cl_subject, $body)) - $msg->add($i18n->getKey('form.mail.report_sent')); + $msg->add($i18n->get('form.mail.report_sent')); else - $err->add($i18n->getKey('error.mail_send')); + $err->add($i18n->get('error.mail_send')); } } @@ -103,7 +103,7 @@ } } -$smarty->assign('title', $i18n->getKey('title.send_report')); +$smarty->assign('title', $i18n->get('title.send_report')); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.mailForm.'.($cl_receiver?'comment':'receiver').'.focus()"'); $smarty->assign('content_page_name', 'mail.tpl'); diff --git a/reports.php b/reports.php index f6655d702..390c85c68 100644 --- a/reports.php +++ b/reports.php @@ -59,11 +59,11 @@ 'style'=>'width: 250px;', 'data'=>$report_list, 'datakeys'=>array('id','name'), - 'empty'=>array('-1'=>$i18n->getKey('dropdown.no')))); + 'empty'=>array('-1'=>$i18n->get('dropdown.no')))); $form->addInput(array('type'=>'hidden','name'=>'fav_report_changed')); // Generate and Delete buttons. -$form->addInput(array('type'=>'submit','name'=>'btn_generate','value'=>$i18n->getKey('button.generate'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'),'onclick'=>"return confirm('".$i18n->getKey('form.reports.confirm_delete')."')")); +$form->addInput(array('type'=>'submit','name'=>'btn_generate','value'=>$i18n->get('button.generate'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'),'onclick'=>"return confirm('".$i18n->get('form.reports.confirm_delete')."')")); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl') && !($user->isClient() && $user->client_id)) { @@ -76,7 +76,7 @@ 'style'=>'width: 250px;', 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.all')))); + 'empty'=>array(''=>$i18n->get('dropdown.all')))); } // If we have a TYPE_DROPDOWN custom field - add control to select an option. @@ -85,7 +85,7 @@ 'style'=>'width: 250px;', 'value'=>$cl_cf_1, 'data'=>$custom_fields->options, - 'empty'=>array(''=>$i18n->getKey('dropdown.all')))); + 'empty'=>array(''=>$i18n->get('dropdown.all')))); } // Add controls for projects and tasks. @@ -102,7 +102,7 @@ 'style'=>'width: 250px;', 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.all')))); + 'empty'=>array(''=>$i18n->get('dropdown.all')))); if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { $task_list = ttTeamHelper::getActiveTasks($user->team_id); $form->addInput(array('type'=>'combobox', @@ -110,36 +110,36 @@ 'style'=>'width: 250px;', 'data'=>$task_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.all')))); + 'empty'=>array(''=>$i18n->get('dropdown.all')))); } // Add include records control. -$include_options = array('1'=>$i18n->getKey('form.reports.include_billable'), - '2'=>$i18n->getKey('form.reports.include_not_billable')); +$include_options = array('1'=>$i18n->get('form.reports.include_billable'), + '2'=>$i18n->get('form.reports.include_not_billable')); $form->addInput(array('type'=>'combobox', 'name'=>'include_records', 'style'=>'width: 250px;', 'data'=>$include_options, - 'empty'=>array(''=>$i18n->getKey('dropdown.all')))); + 'empty'=>array(''=>$i18n->get('dropdown.all')))); if ($user->canManageTeam() && $user->isPluginEnabled('ps')) { $form->addInput(array('type'=>'combobox', 'name'=>'paid_status', 'style'=>'width: 250px;', - 'data'=>array('1'=>$i18n->getKey('dropdown.paid'),'2'=>$i18n->getKey('dropdown.not_paid')), - 'empty'=>array(''=>$i18n->getKey('dropdown.all')) + 'data'=>array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')), + 'empty'=>array(''=>$i18n->get('dropdown.all')) )); } // Add invoiced / not invoiced selector. -$invoice_options = array('1'=>$i18n->getKey('form.reports.include_invoiced'), - '2'=>$i18n->getKey('form.reports.include_not_invoiced')); +$invoice_options = array('1'=>$i18n->get('form.reports.include_invoiced'), + '2'=>$i18n->get('form.reports.include_not_invoiced')); $form->addInput(array('type'=>'combobox', 'name'=>'invoice', 'style'=>'width: 250px;', 'data'=>$invoice_options, - 'empty'=>array(''=>$i18n->getKey('dropdown.all')))); + 'empty'=>array(''=>$i18n->get('dropdown.all')))); $user_list = array(); if ($user->canManageTeam() || $user->isClient()) { @@ -171,13 +171,13 @@ $form->addInput(array('type'=>'combobox', 'name'=>'period', 'style'=>'width: 250px;', - 'data'=>array(INTERVAL_THIS_MONTH=>$i18n->getKey('dropdown.current_month'), - INTERVAL_LAST_MONTH=>$i18n->getKey('dropdown.previous_month'), - INTERVAL_THIS_WEEK=>$i18n->getKey('dropdown.current_week'), - INTERVAL_LAST_WEEK=>$i18n->getKey('dropdown.previous_week'), - INTERVAL_THIS_DAY=>$i18n->getKey('dropdown.current_day'), - INTERVAL_LAST_DAY=>$i18n->getKey('dropdown.previous_day')), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'data'=>array(INTERVAL_THIS_MONTH=>$i18n->get('dropdown.current_month'), + INTERVAL_LAST_MONTH=>$i18n->get('dropdown.previous_month'), + INTERVAL_THIS_WEEK=>$i18n->get('dropdown.current_week'), + INTERVAL_LAST_WEEK=>$i18n->get('dropdown.previous_week'), + INTERVAL_THIS_DAY=>$i18n->get('dropdown.current_day'), + INTERVAL_LAST_DAY=>$i18n->get('dropdown.previous_day')), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Add controls for start and end dates. $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start_date')); $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'end_date')); @@ -206,16 +206,16 @@ if ($custom_fields && $custom_fields->fields[0]) $form->addInput(array('type'=>'checkbox','name'=>'chcf_1')); // Add group by control. -$group_by_options['no_grouping'] = $i18n->getKey('form.reports.group_by_no'); -$group_by_options['date'] = $i18n->getKey('form.reports.group_by_date'); +$group_by_options['no_grouping'] = $i18n->get('form.reports.group_by_no'); +$group_by_options['date'] = $i18n->get('form.reports.group_by_date'); if ($user->canManageTeam() || $user->isClient()) - $group_by_options['user'] = $i18n->getKey('form.reports.group_by_user'); + $group_by_options['user'] = $i18n->get('form.reports.group_by_user'); if ($user->isPluginEnabled('cl') && !($user->isClient() && $user->client_id)) - $group_by_options['client'] = $i18n->getKey('form.reports.group_by_client'); + $group_by_options['client'] = $i18n->get('form.reports.group_by_client'); if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) - $group_by_options['project'] = $i18n->getKey('form.reports.group_by_project'); + $group_by_options['project'] = $i18n->get('form.reports.group_by_project'); if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) - $group_by_options['task'] = $i18n->getKey('form.reports.group_by_task'); + $group_by_options['task'] = $i18n->get('form.reports.group_by_task'); if ($custom_fields && $custom_fields->fields[0] && $custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { $group_by_options['cf_1'] = $custom_fields->fields[0]['label']; } @@ -225,9 +225,9 @@ // Add text field for a new favorite report name. $form->addInput(array('type'=>'text','name'=>'new_fav_report','maxlength'=>'30','style'=>'width: 250px;')); // Save button. -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_generate','value'=>$i18n->getKey('button.generate'))); +$form->addInput(array('type'=>'submit','name'=>'btn_generate','value'=>$i18n->get('button.generate'))); // Create a bean (which is a mechanism to remember form values in session). $bean = new ActionForm('reportBean', $form, $request); @@ -278,12 +278,12 @@ } } elseif ($bean->getAttribute('btn_save')) { // User clicked the Save button. We need to save form options as new favorite report. - if (!ttValidString($bean->getAttribute('new_fav_report'))) $err->add($i18n->getKey('error.field'), $i18n->getKey('form.reports.save_as_favorite')); + if (!ttValidString($bean->getAttribute('new_fav_report'))) $err->add($i18n->get('error.field'), $i18n->get('form.reports.save_as_favorite')); if ($err->no()) { $id = ttFavReportHelper::saveReport($user->id, $bean); if (!$id) - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); if ($err->no()) { $bean->setAttribute('favorite_report', $id); $bean->saveBean(); @@ -310,14 +310,14 @@ $start_date = new DateAndTime($user->date_format, $bean->getAttribute('start_date')); if ($start_date->isError() || !$bean->getAttribute('start_date')) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.start_date')); + $err->add($i18n->get('error.field'), $i18n->get('label.start_date')); $end_date = new DateAndTime($user->date_format, $bean->getAttribute('end_date')); if ($end_date->isError() || !$bean->getAttribute('end_date')) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.end_date')); + $err->add($i18n->get('error.field'), $i18n->get('label.end_date')); if ($start_date->compare($end_date) > 0) - $err->add($i18n->getKey('error.interval'), $i18n->getKey('label.end_date'), $i18n->getKey('label.start_date')); + $err->add($i18n->get('error.interval'), $i18n->get('label.end_date'), $i18n->get('label.start_date')); } $bean->saveBean(); @@ -335,6 +335,6 @@ $smarty->assign('assigned_projects', $assigned_projects); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="handleCheckboxes()"'); -$smarty->assign('title', $i18n->getKey('title.reports')); +$smarty->assign('title', $i18n->get('title.reports')); $smarty->assign('content_page_name', 'reports.tpl'); $smarty->display('index.tpl'); diff --git a/role_add.php b/role_add.php index bd9f3e46f..e4cbb9644 100644 --- a/role_add.php +++ b/role_add.php @@ -50,12 +50,12 @@ $rank_data[] = $i; } $form->addInput(array('type'=>'combobox','name'=>'rank','data'=>$rank_data)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($err->no()) { $existing_role = ttRoleHelper::getRoleByRank($cl_rank, $user->team_id); @@ -71,13 +71,13 @@ header('Location: roles.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.role_exists')); + $err->add($i18n->get('error.role_exists')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.add_role')); +$smarty->assign('title', $i18n->get('title.add_role')); $smarty->assign('content_page_name', 'role_add.tpl'); $smarty->display('index.tpl'); diff --git a/role_delete.php b/role_delete.php index 7bf6ae692..086e7affb 100644 --- a/role_delete.php +++ b/role_delete.php @@ -42,8 +42,8 @@ $form = new Form('roleDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_role_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -52,9 +52,9 @@ header('Location: roles.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { header('Location: roles.php'); exit(); @@ -64,6 +64,6 @@ $smarty->assign('role_to_delete', $role_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->getKey('title.delete_role')); +$smarty->assign('title', $i18n->get('title.delete_role')); $smarty->assign('content_page_name', 'role_delete.tpl'); $smarty->display('index.tpl'); diff --git a/role_edit.php b/role_edit.php index 946f83476..3eb7696b0 100644 --- a/role_edit.php +++ b/role_edit.php @@ -67,20 +67,20 @@ } $form->addInput(array('type'=>'combobox','name'=>'rank','data'=>$rank_data,'value'=>$cl_rank)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->getKey('dropdown.status_active'),INACTIVE=>$i18n->getKey('dropdown.status_inactive')))); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); // Multiple select controls for assigned and available rights. $form->addInput(array('type'=>'combobox','name'=>'assigned_rights','style'=>'width: 250px;','multiple'=>true,'data'=>$assigned_rights)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('button.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('button.delete'))); $form->addInput(array('type'=>'combobox','name'=>'available_rights','style'=>'width: 250px;','multiple'=>true,'data'=>$available_rights)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { if ($request->getParameter('btn_save')) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($err->no()) { $existing_role = ttRoleHelper::getRoleByName($cl_name); @@ -95,9 +95,9 @@ header('Location: roles.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.object_exists')); + $err->add($i18n->get('error.object_exists')); } } if ($request->getParameter('btn_delete') && $request->getParameter('assigned_rights')) { @@ -113,7 +113,7 @@ header('Location: role_edit.php?id='.$role['id']); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } if ($request->getParameter('btn_add') && $request->getParameter('available_rights')) { $rights = $role['rights']; @@ -132,11 +132,11 @@ header('Location: role_edit.php?id='.$role['id']); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.edit_role')); +$smarty->assign('title', $i18n->get('title.edit_role')); $smarty->assign('content_page_name', 'role_edit.tpl'); $smarty->display('index.tpl'); diff --git a/roles.php b/roles.php index 64a1ee4a9..ec79020ee 100644 --- a/roles.php +++ b/roles.php @@ -39,6 +39,6 @@ $smarty->assign('active_roles', ttTeamHelper::getActiveRolesForUser()); $smarty->assign('inactive_roles', ttTeamHelper::getInactiveRolesForUser()); -$smarty->assign('title', $i18n->getKey('title.roles')); +$smarty->assign('title', $i18n->get('title.roles')); $smarty->assign('content_page_name', 'roles.tpl'); $smarty->display('index.tpl'); diff --git a/swap_roles.php b/swap_roles.php index 5ee472486..0c5257049 100644 --- a/swap_roles.php +++ b/swap_roles.php @@ -44,17 +44,17 @@ $form = new Form('swapForm'); $form->addInput(array('type'=>'combobox','name'=>'swap_with','style'=>'width: 250px;','data'=>$users,'datakeys'=>array('id','name'))); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { if (ttTeamHelper::swapRolesWith($cl_id)) { header('Location: users.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.swap_roles')); +$smarty->assign('title', $i18n->get('title.swap_roles')); $smarty->assign('content_page_name', 'swap_roles.tpl'); $smarty->display('index.tpl'); diff --git a/table_test.php b/table_test.php index f8b4c7251..7cd5cda35 100644 --- a/table_test.php +++ b/table_test.php @@ -104,7 +104,7 @@ function render(&$table, $value, $row, $column, $selected = false) { $table->setInteractive(false); $form->addInputElement($table); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); // Submit. if ($request->isPost()) { @@ -113,6 +113,6 @@ function render(&$table, $value, $row, $column, $selected = false) { } $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.time')); +$smarty->assign('title', $i18n->get('title.time')); $smarty->assign('content_page_name', 'table_test.tpl'); $smarty->display('index.tpl'); diff --git a/task_add.php b/task_add.php index 40eb4887d..12c54464d 100644 --- a/task_add.php +++ b/task_add.php @@ -53,12 +53,12 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.add'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($err->no()) { if (!ttTaskHelper::getTaskByName($cl_name)) { @@ -71,14 +71,14 @@ header('Location: tasks.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.task_exists')); + $err->add($i18n->get('error.task_exists')); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.taskForm.name.focus()"'); -$smarty->assign('title', $i18n->getKey('title.add_task')); +$smarty->assign('title', $i18n->get('title.add_task')); $smarty->assign('content_page_name', 'task_add.tpl'); $smarty->display('index.tpl'); diff --git a/task_delete.php b/task_delete.php index 3cdb5b691..d72220d2f 100644 --- a/task_delete.php +++ b/task_delete.php @@ -42,8 +42,8 @@ $form = new Form('taskDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_task_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -52,9 +52,9 @@ header('Location: tasks.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { header('Location: tasks.php'); exit(); @@ -64,6 +64,6 @@ $smarty->assign('task_to_delete', $task_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->getKey('title.delete_task')); +$smarty->assign('title', $i18n->get('title.delete_task')); $smarty->assign('content_page_name', 'task_delete.tpl'); $smarty->display('index.tpl'); diff --git a/task_edit.php b/task_edit.php index 5c70f11b9..36e717d7e 100644 --- a/task_edit.php +++ b/task_edit.php @@ -61,15 +61,15 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->getKey('dropdown.status_active'),INACTIVE=>$i18n->getKey('dropdown.status_inactive')))); + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->getKey('button.copy'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($err->no()) { if ($request->getParameter('btn_save')) { @@ -85,9 +85,9 @@ header('Location: tasks.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.task_exists')); + $err->add($i18n->get('error.task_exists')); } if ($request->getParameter('btn_copy')) { @@ -101,14 +101,14 @@ header('Location: tasks.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.task_exists')); + $err->add($i18n->get('error.task_exists')); } } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.edit_task')); +$smarty->assign('title', $i18n->get('title.edit_task')); $smarty->assign('content_page_name', 'task_edit.tpl'); $smarty->display('index.tpl'); diff --git a/tasks.php b/tasks.php index a1033a5c0..5bc3fd459 100644 --- a/tasks.php +++ b/tasks.php @@ -38,6 +38,6 @@ $smarty->assign('active_tasks', ttTeamHelper::getActiveTasks($user->team_id)); $smarty->assign('inactive_tasks', ttTeamHelper::getInactiveTasks($user->team_id)); -$smarty->assign('title', $i18n->getKey('title.tasks')); +$smarty->assign('title', $i18n->get('title.tasks')); $smarty->assign('content_page_name', 'tasks.tpl'); $smarty->display('index.tpl'); diff --git a/time.php b/time.php index 7f9b1849e..270a8aaef 100644 --- a/time.php +++ b/time.php @@ -127,7 +127,7 @@ 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Note: in other modes the client list is filtered to relevant clients only. See below. } @@ -141,7 +141,7 @@ 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { @@ -168,7 +168,7 @@ 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } @@ -180,7 +180,7 @@ 'value'=>$cl_task, 'data'=>$task_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } // Add other controls. @@ -202,7 +202,7 @@ if ($user->isPluginEnabled('iv')) $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); // If we have custom fields - add controls for them. if ($custom_fields && $custom_fields->fields[0]) { @@ -214,7 +214,7 @@ 'style'=>'width: 250px;', 'value'=>$cl_cf_1, 'data'=>$custom_fields->options, - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } @@ -224,62 +224,62 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) - $err->add($i18n->getKey('error.client')); + $err->add($i18n->get('error.client')); if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->getKey('error.field'), $custom_fields->fields[0]['label']); + if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); } if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->getKey('error.project')); + if (!$cl_project) $err->add($i18n->get('error.project')); } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode && $user->task_required) { - if (!$cl_task) $err->add($i18n->getKey('error.task')); + if (!$cl_task) $err->add($i18n->get('error.task')); } if (strlen($cl_duration) == 0) { if ($cl_start || $cl_finish) { if (!ttTimeHelper::isValidTime($cl_start)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.start')); + $err->add($i18n->get('error.field'), $i18n->get('label.start')); if ($cl_finish) { if (!ttTimeHelper::isValidTime($cl_finish)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.finish')); + $err->add($i18n->get('error.field'), $i18n->get('label.finish')); if (!ttTimeHelper::isValidInterval($cl_start, $cl_finish)) - $err->add($i18n->getKey('error.interval'), $i18n->getKey('label.finish'), $i18n->getKey('label.start')); + $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); } } else { if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.start')); - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.finish')); + $err->add($i18n->get('error.empty'), $i18n->get('label.start')); + $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); } if ((TYPE_DURATION == $user->record_type) || (TYPE_ALL == $user->record_type)) - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); } } else { if (false === ttTimeHelper::postedDurationToMinutes($cl_duration)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.field'), $i18n->get('label.duration')); } - if (!ttValidString($cl_note, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.note')); + if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); // Finished validating user input. // Prohibit creating entries in future. if (!$user->future_entries) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) - $err->add($i18n->getKey('error.future_date')); + $err->add($i18n->get('error.future_date')); } // Prohibit creating entries in locked range. if ($user->isDateLocked($selected_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // Prohibit creating another uncompleted record. if ($err->no()) { if (($not_completed_rec = ttTimeHelper::getUncompleted($user->getActiveUser())) && (($cl_finish == '') && ($cl_duration == ''))) - $err->add($i18n->getKey('error.uncompleted_exists')." ".$i18n->getKey('error.goto_uncompleted').""); + $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); } // Prohibit creating an overlapping record. if ($err->no()) { if (ttTimeHelper::overlaps($user->getActiveUser(), $cl_date, $cl_start, $cl_finish)) - $err->add($i18n->getKey('error.overlap')); + $err->add($i18n->get('error.overlap')); } // Insert record. @@ -308,7 +308,7 @@ header('Location: time.php'); exit(); } - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } elseif ($request->getParameter('btn_stop')) { // Stop button pressed to finish an uncompleted record. @@ -333,7 +333,7 @@ 'note'=>$record['comment'], 'billable'=>$record['billable'])); if (!$res) - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else { // Cannot complete, redirect for manual edit. header('Location: time_edit.php?id='.$record_id); @@ -367,6 +367,6 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="fillDropdowns()"'); $smarty->assign('timestring', $selected_date->toString($user->date_format)); -$smarty->assign('title', $i18n->getKey('title.time')); +$smarty->assign('title', $i18n->get('title.time')); $smarty->assign('content_page_name', 'time.tpl'); $smarty->display('index.tpl'); diff --git a/time_delete.php b/time_delete.php index 0cdd8816e..2ad3ea412 100644 --- a/time_delete.php +++ b/time_delete.php @@ -42,7 +42,7 @@ $time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); // Prohibit deleting invoiced records. -if ($time_rec['invoice_id']) die($i18n->getKey('error.sys')); +if ($time_rec['invoice_id']) die($i18n->get('error.sys')); // Escape comment for presentation. $time_rec['comment'] = htmlspecialchars($time_rec['comment']); @@ -57,7 +57,7 @@ $uncompleted = ($time_rec['duration'] == '0:00'); if ($user->isDateLocked($item_date) && !$uncompleted) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); if ($err->no()) { @@ -68,7 +68,7 @@ header('Location: time.php'); exit(); } else { - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } } @@ -80,11 +80,11 @@ $form = new Form('timeRecordForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); $smarty->assign('time_rec', $time_rec); $smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('title', $i18n->getKey('title.delete_time_record')); +$smarty->assign('title', $i18n->get('title.delete_time_record')); $smarty->assign('content_page_name', 'time_delete.tpl'); $smarty->display('index.tpl'); diff --git a/time_edit.php b/time_edit.php index 59ae7531b..dd3edde13 100644 --- a/time_edit.php +++ b/time_edit.php @@ -53,7 +53,7 @@ $time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); // Prohibit editing invoiced records. -if ($time_rec['invoice_id']) die($i18n->getKey('error.sys')); +if ($time_rec['invoice_id']) die($i18n->get('error.sys')); $item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); @@ -101,7 +101,7 @@ if (strlen($cl_start) > 0 && $cl_start == $cl_finish && $cl_duration == '0:00') { $cl_finish = ''; $cl_duration = ''; - $msg->add($i18n->getKey('form.time_edit.uncompleted')); + $msg->add($i18n->get('form.time_edit.uncompleted')); } } @@ -118,7 +118,7 @@ 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Note: in other modes the client list is filtered to relevant clients only. See below. } @@ -132,7 +132,7 @@ 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { @@ -159,7 +159,7 @@ 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } @@ -171,7 +171,7 @@ 'value'=>$cl_task, 'data'=>$task_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } // Add other controls. @@ -199,7 +199,7 @@ 'style'=>'width: 250px;', 'value'=>$cl_cf_1, 'data'=>$custom_fields->options, - 'empty' => array('' => $i18n->getKey('dropdown.select')))); + 'empty' => array('' => $i18n->get('dropdown.select')))); } } // Hidden control for record id. @@ -209,50 +209,50 @@ if ($user->canManageTeam() && $user->isPluginEnabled('ps')) $form->addInput(array('type'=>'checkbox','name'=>'paid','value'=>$cl_paid)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.copy'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) - $err->add($i18n->getKey('error.client')); + $err->add($i18n->get('error.client')); if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->getKey('error.field'), $custom_fields->fields[0]['label']); + if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); } if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->getKey('error.project')); + if (!$cl_project) $err->add($i18n->get('error.project')); } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode && $user->task_required) { - if (!$cl_task) $err->add($i18n->getKey('error.task')); + if (!$cl_task) $err->add($i18n->get('error.task')); } if (!$cl_duration) { if ('0' == $cl_duration) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.field'), $i18n->get('label.duration')); elseif ($cl_start || $cl_finish) { if (!ttTimeHelper::isValidTime($cl_start)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.start')); + $err->add($i18n->get('error.field'), $i18n->get('label.start')); if ($cl_finish) { if (!ttTimeHelper::isValidTime($cl_finish)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.finish')); + $err->add($i18n->get('error.field'), $i18n->get('label.finish')); if (!ttTimeHelper::isValidInterval($cl_start, $cl_finish)) - $err->add($i18n->getKey('error.interval'), $i18n->getKey('label.finish'), $i18n->getKey('label.start')); + $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); } } else { if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.start')); - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.finish')); + $err->add($i18n->get('error.empty'), $i18n->get('label.start')); + $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); } if ((TYPE_DURATION == $user->record_type) || (TYPE_ALL == $user->record_type)) - $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); } } else { if (false === ttTimeHelper::postedDurationToMinutes($cl_duration)) - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.field'), $i18n->get('label.duration')); } - if (!ttValidDate($cl_date)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.date')); - if (!ttValidString($cl_note, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.note')); + if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); + if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); // Finished validating user input. // This is a new date for the time record. @@ -262,7 +262,7 @@ if (!$user->future_entries) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) - $err->add($i18n->getKey('error.future_date')); + $err->add($i18n->get('error.future_date')); } // Save record. @@ -276,11 +276,11 @@ if ($err->no()) { // 1) Prohibit saving locked entries in any form. if ($user->isDateLocked($item_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // 2) Prohibit saving completed unlocked entries into locked range. if ($err->no() && $user->isDateLocked($new_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // 3) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. $uncompleted = ($cl_finish == '' && $cl_duration == ''); @@ -288,7 +288,7 @@ $not_completed_rec = ttTimeHelper::getUncompleted($user->getActiveUser()); if ($not_completed_rec && ($time_rec['id'] <> $not_completed_rec['id'])) { // We have another not completed record. - $err->add($i18n->getKey('error.uncompleted_exists')." ".$i18n->getKey('error.goto_uncompleted').""); + $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); } } } @@ -296,7 +296,7 @@ // Prohibit creating an overlapping record. if ($err->no()) { if (ttTimeHelper::overlaps($user->getActiveUser(), $new_date->toString(DB_DATEFORMAT), $cl_start, $cl_finish, $cl_id)) - $err->add($i18n->getKey('error.overlap')); + $err->add($i18n->get('error.overlap')); } // Now, an update. @@ -340,7 +340,7 @@ if ($err->no()) { // 1) Prohibit saving into locked range. if ($user->isDateLocked($new_date)) - $err->add($i18n->getKey('error.range_locked')); + $err->add($i18n->get('error.range_locked')); // 2) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. $uncompleted = ($cl_finish == '' && $cl_duration == ''); @@ -348,7 +348,7 @@ $not_completed_rec = ttTimeHelper::getUncompleted($user->getActiveUser()); if ($not_completed_rec) { // We have another not completed record. - $err->add($i18n->getKey('error.uncompleted_exists')." ".$i18n->getKey('error.goto_uncompleted').""); + $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); } } } @@ -356,7 +356,7 @@ // Prohibit creating an overlapping record. if ($err->no()) { if (ttTimeHelper::overlaps($user->getActiveUser(), $new_date->toString(DB_DATEFORMAT), $cl_start, $cl_finish)) - $err->add($i18n->getKey('error.overlap')); + $err->add($i18n->get('error.overlap')); } // Now, a new insert. @@ -387,7 +387,7 @@ header('Location: time.php?date='.$new_date->toString(DB_DATEFORMAT)); exit(); } - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } @@ -402,6 +402,6 @@ $smarty->assign('task_list', $task_list); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="fillDropdowns()"'); -$smarty->assign('title', $i18n->getKey('title.edit_time_record')); +$smarty->assign('title', $i18n->get('title.edit_time_record')); $smarty->assign('content_page_name', 'time_edit.tpl'); $smarty->display('index.tpl'); diff --git a/tofile.php b/tofile.php index 534cb9430..67c5b31ce 100644 --- a/tofile.php +++ b/tofile.php @@ -63,7 +63,7 @@ $items = ttReportHelper::getItems($bean); // Build a string to use as filename for the files being downloaded. -$filename = strtolower($i18n->getKey('title.report')).'_'.$bean->mValues['start_date'].'_'.$bean->mValues['end_date']; +$filename = strtolower($i18n->get('title.report')).'_'.$bean->mValues['start_date'].'_'.$bean->mValues['end_date']; header('Pragma: public'); // This is needed for IE8 to download files over https. header('Content-Type: text/html; charset=utf-8'); @@ -164,13 +164,13 @@ $group_by_header = $custom_fields->fields[0]['label']; else { $key = 'label.'.$group_by; - $group_by_header = $i18n->getKey($key); + $group_by_header = $i18n->get($key); } // Print headers. print '"'.$group_by_header.'"'; - if ($bean->getAttribute('chduration')) print ',"'.$i18n->getKey('label.duration').'"'; - if ($bean->getAttribute('chcost')) print ',"'.$i18n->getKey('label.cost').'"'; + if ($bean->getAttribute('chduration')) print ',"'.$i18n->get('label.duration').'"'; + if ($bean->getAttribute('chcost')) print ',"'.$i18n->get('label.cost').'"'; print "\n"; // Print subtotals. @@ -192,20 +192,20 @@ } } else { // Normal report. Print headers. - print '"'.$i18n->getKey('label.date').'"'; - if ($user->canManageTeam() || $user->isClient()) print ',"'.$i18n->getKey('label.user').'"'; - if ($bean->getAttribute('chclient')) print ',"'.$i18n->getKey('label.client').'"'; - if ($bean->getAttribute('chproject')) print ',"'.$i18n->getKey('label.project').'"'; - if ($bean->getAttribute('chtask')) print ',"'.$i18n->getKey('label.task').'"'; + print '"'.$i18n->get('label.date').'"'; + if ($user->canManageTeam() || $user->isClient()) print ',"'.$i18n->get('label.user').'"'; + if ($bean->getAttribute('chclient')) print ',"'.$i18n->get('label.client').'"'; + if ($bean->getAttribute('chproject')) print ',"'.$i18n->get('label.project').'"'; + if ($bean->getAttribute('chtask')) print ',"'.$i18n->get('label.task').'"'; if ($bean->getAttribute('chcf_1')) print ',"'.$custom_fields->fields[0]['label'].'"'; - if ($bean->getAttribute('chstart')) print ',"'.$i18n->getKey('label.start').'"'; - if ($bean->getAttribute('chfinish')) print ',"'.$i18n->getKey('label.finish').'"'; - if ($bean->getAttribute('chduration')) print ',"'.$i18n->getKey('label.duration').'"'; - if ($bean->getAttribute('chnote')) print ',"'.$i18n->getKey('label.note').'"'; - if ($bean->getAttribute('chcost')) print ',"'.$i18n->getKey('label.cost').'"'; - if ($bean->getAttribute('chpaid')) print ',"'.$i18n->getKey('label.paid').'"'; - if ($bean->getAttribute('chip')) print ',"'.$i18n->getKey('label.ip').'"'; - if ($bean->getAttribute('chinvoice')) print ',"'.$i18n->getKey('label.invoice').'"'; + if ($bean->getAttribute('chstart')) print ',"'.$i18n->get('label.start').'"'; + if ($bean->getAttribute('chfinish')) print ',"'.$i18n->get('label.finish').'"'; + if ($bean->getAttribute('chduration')) print ',"'.$i18n->get('label.duration').'"'; + if ($bean->getAttribute('chnote')) print ',"'.$i18n->get('label.note').'"'; + if ($bean->getAttribute('chcost')) print ',"'.$i18n->get('label.cost').'"'; + if ($bean->getAttribute('chpaid')) print ',"'.$i18n->get('label.paid').'"'; + if ($bean->getAttribute('chip')) print ',"'.$i18n->get('label.ip').'"'; + if ($bean->getAttribute('chinvoice')) print ',"'.$i18n->get('label.invoice').'"'; print "\n"; // Print items. diff --git a/topdf.php b/topdf.php index 68a1eb5c3..b8f6684c4 100644 --- a/topdf.php +++ b/topdf.php @@ -68,7 +68,7 @@ $group_by_header = $custom_fields->fields[0]['label']; else { $key = 'label.'.$group_by; - $group_by_header = $i18n->getKey($key); + $group_by_header = $i18n->get($key); } } @@ -88,7 +88,7 @@ } // Build a string to use as filename for the files being downloaded. -$filename = strtolower($i18n->getKey('title.report')).'_'.$bean->mValues['start_date'].'_'.$bean->mValues['end_date']; +$filename = strtolower($i18n->get('title.report')).'_'.$bean->mValues['start_date'].'_'.$bean->mValues['end_date']; // Start preparing HTML to build PDF from. $styleHeader = 'style="background-color:#a6ccf7;"'; @@ -96,7 +96,7 @@ $styleCentered = 'style="text-align:center;"'; $styleRightAligned = 'style="text-align:right;"'; -$title = $i18n->getKey('title.report').": ".$totals['start_date']." - ".$totals['end_date']; +$title = $i18n->get('title.report').": ".$totals['start_date']." - ".$totals['end_date']; $html = '

'.$title.'

'; $html .= ''; @@ -107,8 +107,8 @@ $html .= ''; $html .= ""; $html .= ''; - if ($bean->getAttribute('chduration')) { $colspan++; $html .= "'; } - if ($bean->getAttribute('chcost')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chduration')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chcost')) { $colspan++; $html .= "'; } $html .= ''; $html .= ''; // Print subtotals. @@ -129,7 +129,7 @@ // Print totals. $html .= ''; $html .= ""; - $html .= ''; + $html .= ''; if ($bean->getAttribute('chduration')) $html .= "'; if ($bean->getAttribute('chcost')) { $html .= "'; $html .= ""; - $html .= ''; - if ($user->canManageTeam() || $user->isClient()) { $colspan++; $html .= ''; } - if ($bean->getAttribute('chclient')) { $colspan++; $html .= ''; } - if ($bean->getAttribute('chproject')) { $colspan++; $html .= ''; } - if ($bean->getAttribute('chtask')) { $colspan++; $html .= ''; } + $html .= ''; + if ($user->canManageTeam() || $user->isClient()) { $colspan++; $html .= ''; } + if ($bean->getAttribute('chclient')) { $colspan++; $html .= ''; } + if ($bean->getAttribute('chproject')) { $colspan++; $html .= ''; } + if ($bean->getAttribute('chtask')) { $colspan++; $html .= ''; } if ($bean->getAttribute('chcf_1')) { $colspan++; $html .= ''; } - if ($bean->getAttribute('chstart')) { $colspan++; $html .= "'; } - if ($bean->getAttribute('chfinish')) { $colspan++; $html .= "'; } - if ($bean->getAttribute('chduration')) { $colspan++; $html .= "'; } - if ($bean->getAttribute('chnote')) { $colspan++; $html .= ''; } - if ($bean->getAttribute('chcost')) { $colspan++; $html .= "'; } - if ($bean->getAttribute('chpaid')) { $colspan++; $html .= "'; } - if ($bean->getAttribute('chip')) { $colspan++; $html .= "'; } - if ($bean->getAttribute('chinvoice')) { $colspan++; $html .= ''; } + if ($bean->getAttribute('chstart')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chfinish')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chduration')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chnote')) { $colspan++; $html .= ''; } + if ($bean->getAttribute('chcost')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chpaid')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chip')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chinvoice')) { $colspan++; $html .= ''; } $html .= ''; $html .= ''; @@ -172,7 +172,7 @@ $cur_grouped_by = $item['grouped_by']; if ($cur_grouped_by != $prev_grouped_by && !$first_pass) { $html .= ''; - $html .= ''; + $html .= ''; if ($user->canManageTeam() || $user->isClient()) { $html .= ''; } if ($bean->getAttribute('chip')) { @@ -259,7 +259,7 @@ // Print a terminating subtotal. if ($print_subtotals) { $html .= ''; - $html .= ''; + $html .= ''; if ($user->canManageTeam() || $user->isClient()) { $html .= ''; $html .= ''; - $html .= ''; + $html .= ''; if ($user->canManageTeam() || $user->isClient()) $html .= ''; if ($bean->getAttribute('chclient')) $html .= ''; if ($bean->getAttribute('chproject')) $html .= ''; @@ -333,12 +333,12 @@ // Output footer. if (!defined('REPORT_FOOTER') || !(REPORT_FOOTER == false)) // By default we print it unless explicitely defined as false. - $html .= '

'.$i18n->getKey('form.mail.footer').'

'; + $html .= '

'.$i18n->get('form.mail.footer').'

'; // By this time we have html ready. // Determine title for report. -$title = $i18n->getKey('title.report').": ".$totals['start_date']." - ".$totals['end_date']; +$title = $i18n->get('title.report').": ".$totals['start_date']." - ".$totals['end_date']; header('Pragma: public'); // This is needed for IE8 to download files over https. header('Content-Type: text/html; charset=utf-8'); @@ -394,7 +394,7 @@ public function Footer() { $pdf->SetImageFile('images/'.$user->team_id.'.png'); // Set page word for the footer. -$pdf->SetPageWord($i18n->getKey('label.page')); +$pdf->SetPageWord($i18n->get('label.page')); // Set document information. $pdf->SetCreator(PDF_CREATOR); diff --git a/user_add.php b/user_add.php index a31669c7e..91286537d 100644 --- a/user_add.php +++ b/user_add.php @@ -68,7 +68,7 @@ $project_with_rate['rate'] = $request->getParameter('rate_'.$p); $assigned_projects[] = $project_with_rate; } else - $err->add($i18n->getKey('error.field'), 'rate_'.$p); + $err->add($i18n->get('error.field'), 'rate_'.$p); } } } @@ -85,7 +85,7 @@ $active_roles = ttTeamHelper::getActiveRolesForUser(); $form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles,'datakeys'=>array('id', 'name'))); if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); @@ -121,26 +121,26 @@ function render(&$table, $value, $row, $column, $selected = false) { $table->setData($projects); $table->setKeyField('id'); $table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->getKey('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->getKey('form.users.rate'), new RateCellRenderer())); +$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); +$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); $form->addInputElement($table); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); + if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); if (!$auth->isPasswordExternal()) { - if (!ttValidString($cl_password1)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); + if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($cl_password1 !== $cl_password2) - $err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); // Require selection of a client for a client role. - if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->getKey('error.client')); - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('form.users.default_rate')); + if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); + if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); if ($err->no()) { if (!ttUserHelper::getUserByLogin($cl_login)) { @@ -158,9 +158,9 @@ function render(&$table, $value, $row, $column, $selected = false) { header('Location: users.php'); exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.user_exists')); + $err->add($i18n->get('error.user_exists')); } } // isPost @@ -168,6 +168,6 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('active_roles', $active_roles); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); -$smarty->assign('title', $i18n->getKey('title.add_user')); +$smarty->assign('title', $i18n->get('title.add_user')); $smarty->assign('content_page_name', 'user_add.tpl'); $smarty->display('index.tpl'); diff --git a/user_delete.php b/user_delete.php index 97b255725..a88454bf9 100644 --- a/user_delete.php +++ b/user_delete.php @@ -57,8 +57,8 @@ // Create confirmation form. $form = new Form('userDeleteForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$user_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->getKey('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->getKey('button.cancel'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { @@ -81,7 +81,7 @@ } exit(); } else { - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } if ($request->getParameter('btn_cancel')) { @@ -91,6 +91,6 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.delete_user')); +$smarty->assign('title', $i18n->get('title.delete_user')); $smarty->assign('content_page_name', 'user_delete.tpl'); $smarty->display('index.tpl'); diff --git a/user_edit.php b/user_edit.php index ee572a7f6..531e84242 100644 --- a/user_edit.php +++ b/user_edit.php @@ -83,7 +83,7 @@ $project_with_rate['rate'] = $request->getParameter('rate_'.$p); $assigned_projects[] = $project_with_rate; } else - $err->add($i18n->getKey('error.field'), 'rate_'.$p); + $err->add($i18n->get('error.field'), 'rate_'.$p); } } } else { @@ -113,10 +113,10 @@ $active_roles = ttTeamHelper::getActiveRolesForUser(); $form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles, 'datakeys'=>array('id', 'name'))); if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->getKey('dropdown.status_active'),INACTIVE=>$i18n->getKey('dropdown.status_inactive')))); + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); // Define classes for the projects table. @@ -150,27 +150,27 @@ function render(&$table, $value, $row, $column, $selected = false) { $table->setData($projects); $table->setKeyField('id'); $table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->getKey('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->getKey('form.users.rate'), new RateCellRenderer())); +$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); +$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); $form->addInputElement($table); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$user_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.save'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.login')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); + if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { - if (!ttValidString($cl_password1)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.confirm_password')); + if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); + if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($cl_password1 !== $cl_password2) - $err->add($i18n->getKey('error.not_equal'), $i18n->getKey('label.password'), $i18n->getKey('label.confirm_password')); + $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.email')); + if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); // Require selection of a client for a client role. - if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->getKey('error.client')); - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('form.users.default_rate')); + if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); + if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); if ($err->no()) { $existing_user = ttUserHelper::getUserByLogin($cl_login); @@ -216,9 +216,9 @@ function render(&$table, $value, $row, $column, $selected = false) { exit(); } else - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } else - $err->add($i18n->getKey('error.user_exists')); + $err->add($i18n->get('error.user_exists')); } } // isPost @@ -230,6 +230,6 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); $smarty->assign('user_id', $user_id); -$smarty->assign('title', $i18n->getKey('title.edit_user')); +$smarty->assign('title', $i18n->get('title.edit_user')); $smarty->assign('content_page_name', 'user_edit.tpl'); $smarty->display('index.tpl'); diff --git a/users.php b/users.php index 28a37227a..860218638 100644 --- a/users.php +++ b/users.php @@ -56,6 +56,6 @@ $smarty->assign('active_users', $active_users); $smarty->assign('inactive_users', $inactive_users); $smarty->assign('can_delete_manager', $can_delete_manager); -$smarty->assign('title', $i18n->getKey('title.users')); +$smarty->assign('title', $i18n->get('title.users')); $smarty->assign('content_page_name', 'users.tpl'); $smarty->display('index.tpl'); diff --git a/week.php b/week.php index 29c15e479..e26aa1192 100644 --- a/week.php +++ b/week.php @@ -235,7 +235,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Note: in other modes the client list is filtered to relevant clients only. See below. } @@ -249,7 +249,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { @@ -276,7 +276,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } @@ -288,7 +288,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'value'=>$cl_task, 'data'=>$task_list, 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } if (!defined('NOTE_INPUT_HEIGHT')) define('NOTE_INPUT_HEIGHT', 40); @@ -299,7 +299,7 @@ function render(&$table, $value, $row, $column, $selected = false) { if ($user->isPluginEnabled('iv')) $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'get_date()')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->getKey('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); // If we have custom fields - add controls for them. if ($custom_fields && $custom_fields->fields[0]) { @@ -311,7 +311,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'style'=>'width: 250px;', 'value'=>$cl_cf_1, 'data'=>$custom_fields->options, - 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } @@ -330,15 +330,15 @@ function render(&$table, $value, $row, $column, $selected = false) { } if ($newEntryPosted) { if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) - $err->add($i18n->getKey('error.client')); + $err->add($i18n->get('error.client')); if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->getKey('error.field'), $custom_fields->fields[0]['label']); + if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); } if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->getKey('error.project')); + if (!$cl_project) $err->add($i18n->get('error.project')); } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode && $user->task_required) { - if (!$cl_task) $err->add($i18n->getKey('error.task')); + if (!$cl_task) $err->add($i18n->get('error.task')); } } // Finished validating user input for row 0. @@ -369,7 +369,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // If posted value is not null, check and normalize it. if ($postedDuration) { if (false === ttTimeHelper::postedDurationToMinutes($postedDuration)) { - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.duration')); + $err->add($i18n->get('error.field'), $i18n->get('label.duration')); $result = false; break; // Break out. Stop any further processing. } else { $minutes = ttTimeHelper::postedDurationToMinutes($postedDuration); @@ -433,7 +433,7 @@ function render(&$table, $value, $row, $column, $selected = false) { $existingComment = $dataArray[$rowNumber][$dayHeader]['note']; // If posted value is not null, check it. if ($postedComment && !ttValidString($postedComment, true)) { - $err->add($i18n->getKey('error.field'), $i18n->getKey('label.note')); + $err->add($i18n->get('error.field'), $i18n->get('label.note')); $result = false; break; // Break out. Stop any further processing. } // Do not process if value has not changed. @@ -490,6 +490,6 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('timestring', $startDate->toString($user->date_format).' - '.$endDate->toString($user->date_format)); $smarty->assign('time_records', $records); -$smarty->assign('title', $i18n->getKey('title.time')); +$smarty->assign('title', $i18n->get('title.time')); $smarty->assign('content_page_name', 'week.tpl'); $smarty->display('index.tpl'); diff --git a/week_view.php b/week_view.php index 99dc2eee9..b273d2789 100644 --- a/week_view.php +++ b/week_view.php @@ -52,17 +52,17 @@ $form->addInput(array('type'=>'checkbox','name'=>'week_note','value'=>$cl_week_note)); $form->addInput(array('type'=>'checkbox','name'=>'week_list','value'=>$cl_week_list)); $form->addInput(array('type'=>'checkbox','name'=>'notes','value'=>$cl_notes)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()){ if (!ttTeamHelper::enablePlugin('wvn', $cl_week_note) || !ttTeamHelper::enablePlugin('wvl', $cl_week_list) || !ttTeamHelper::enablePlugin('wvns', $cl_notes)) { - $err->add($i18n->getKey('error.db')); + $err->add($i18n->get('error.db')); } } $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->getKey('title.week_view')); +$smarty->assign('title', $i18n->get('title.week_view')); $smarty->assign('content_page_name', 'week_view.tpl'); $smarty->display('index.tpl'); From 86381310c0914f345eb6c88d4e9ec621996f493c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 17:48:20 +0000 Subject: [PATCH 0026/1848] Replaced timestamp column with datetime type in tt_tmp_refs. --- WEB-INF/lib/ttUserHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 12 ++++++++---- mysql.sql | 4 ++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 9513a721a..e4591ea43 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -415,10 +415,10 @@ static function delete($user_id) { static function saveTmpRef($ref, $user_id) { $mdb2 = getConnection(); - $sql = "delete from tt_tmp_refs where timestamp + 86400 < now()"; + $sql = "delete from tt_tmp_refs where created < now() - interval 1 hour"; $affected = $mdb2->exec($sql); - $sql = "insert into tt_tmp_refs (ref, user_id) values(".$mdb2->quote($ref).", $user_id)"; + $sql = "insert into tt_tmp_refs (created, ref, user_id) values(now(), ".$mdb2->quote($ref).", $user_id)"; $affected = $mdb2->exec($sql); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 21c302736..8f2c0a6cc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
'.htmlspecialchars($group_by_header).'".$i18n->getKey('label.duration').'".$i18n->getKey('label.cost').'".$i18n->get('label.duration').'".$i18n->get('label.cost').'
 
'.$i18n->getKey('label.total').''.$i18n->get('label.total').'".$totals['time'].'"; @@ -148,20 +148,20 @@ // Table header. $html .= '
'.$i18n->getKey('label.date').''.$i18n->getKey('label.user').''.$i18n->getKey('label.client').''.$i18n->getKey('label.project').''.$i18n->getKey('label.task').''.$i18n->get('label.date').''.$i18n->get('label.user').''.$i18n->get('label.client').''.$i18n->get('label.project').''.$i18n->get('label.task').''.htmlspecialchars($custom_fields->fields[0]['label']).'".$i18n->getKey('label.start').'".$i18n->getKey('label.finish').'".$i18n->getKey('label.duration').''.$i18n->getKey('label.note').'".$i18n->getKey('label.cost').'".$i18n->getKey('label.paid').'".$i18n->getKey('label.ip').''.$i18n->getKey('label.invoice').'".$i18n->get('label.start').'".$i18n->get('label.finish').'".$i18n->get('label.duration').''.$i18n->get('label.note').'".$i18n->get('label.cost').'".$i18n->get('label.paid').'".$i18n->get('label.ip').''.$i18n->get('label.invoice').'
'.$i18n->getKey('label.subtotal').''.$i18n->get('label.subtotal').''; if ($group_by == 'user') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); @@ -241,7 +241,7 @@ } if ($bean->getAttribute('chpaid')) { $html .= ''; - $html .= $item['paid'] == 1 ? $i18n->getKey('label.yes') : $i18n->getKey('label.no'); + $html .= $item['paid'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); $html .= '
'.$i18n->getKey('label.subtotal').''.$i18n->get('label.subtotal').''; if ($group_by == 'user') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); @@ -306,7 +306,7 @@ // Print totals. $html .= '
 
'.$i18n->getKey('label.total').''.$i18n->get('label.total').'
- - - + +
 Anuko Time Tracker 1.17.67.4145 | Copyright © Anuko | +  Anuko Time Tracker 1.17.67.4146 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 9c2d041b6..4d7feeb25 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11766"]) { + if ($_POST["convert11744to11767"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -856,6 +856,10 @@ function setChange($sql) { setChange("ALTER TABLE `tt_teams` drop `timestamp`"); setChange("ALTER TABLE `tt_users` drop `timestamp`"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.66', modified = now() where param_name = 'version_db' and param_value = '1.17.65'"); + setChange("ALTER TABLE `tt_tmp_refs` ADD `created` datetime default NULL AFTER `timestamp`"); + setChange("ALTER TABLE `tt_tmp_refs` drop `timestamp`"); + setChange("delete from `tt_tmp_refs`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.67', modified = now() where param_name = 'version_db' and param_value = '1.17.66'"); } if ($_POST["cleanup"]) { @@ -901,7 +905,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.66) + Create database structure (v1.17.67)
(applies only to new installations, do not execute when updating)
@@ -941,8 +945,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.66)Update database structure (v1.17.44 to v1.17.67)
diff --git a/mysql.sql b/mysql.sql index 48ec08331..df34b7759 100644 --- a/mysql.sql +++ b/mysql.sql @@ -226,7 +226,7 @@ create unique index name_idx on tt_invoices(team_id, name, status); # Structure for table tt_tmp_refs. Used for reset password mechanism. # CREATE TABLE `tt_tmp_refs` ( - `timestamp` timestamp default CURRENT_TIMESTAMP, # creation timestamp + `created` datetime default NULL, # creation timestamp `ref` char(32) NOT NULL default '', # unique reference for user, used in urls `user_id` int(11) NOT NULL # user id ); @@ -450,4 +450,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.66', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.67', now()); # TODO: change when structure changes. From a003ad003dfa29eb043c45f18e7f395cb3331aa5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 20:26:41 +0000 Subject: [PATCH 0027/1848] Put a swap roles link on user_edit.php. --- WEB-INF/lib/ttUser.class.php | 4 +++- WEB-INF/resources/en.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/swap_roles.tpl | 4 +++- WEB-INF/templates/user_edit.tpl | 6 ++++++ 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index e0bbbe5ac..0a1048884 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -32,6 +32,7 @@ class ttUser { var $id = null; // User id. var $team_id = null; // Team id. var $role_id = null; // Role id. + var $role_name = null; // Role name. var $rank = null; // User role rank. var $client_id = null; // Client id for client user role. var $behalf_id = null; // User id, on behalf of whom we are working. @@ -71,7 +72,7 @@ function __construct($login, $id = null) { $mdb2 = getConnection(); - $sql = "SELECT u.id, u.login, u.name, u.team_id, u.role_id, r.rank, r.rights, u.client_id, u.email, t.name as team_name, + $sql = "SELECT u.id, u.login, u.name, u.team_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id, u.email, t.name as team_name, t.currency, t.lang, t.decimal_mark, t.date_format, t.time_format, t.week_start, t.tracking_mode, t.project_required, t.task_required, t.record_type, t.bcc_email, t.plugins, t.config, t.lock_spec, t.workday_minutes, t.custom_logo @@ -94,6 +95,7 @@ function __construct($login, $id = null) { $this->id = $val['id']; $this->team_id = $val['team_id']; $this->role_id = $val['role_id']; + $this->role_name = $val['role_name']; $this->rights = explode(',', $val['rights']); $this->is_client = !in_array('track_own_time', $this->rights); $this->rank = $val['rank']; diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index ce65dc622..bedc4f6a7 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -427,6 +427,7 @@ 'form.teams.hint' => 'Create a new team by creating a new team manager account.
You can also import team data from an xml file from another Anuko Time Tracker server (no login collisions are allowed).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 hours', 'form.profile.24_hours' => '24 hours', 'form.profile.show_holidays' => 'Show holidays', @@ -460,6 +461,7 @@ 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. +'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8f2c0a6cc..6ca757e04 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.67.4146 | Copyright © Anuko | +  Anuko Time Tracker 1.17.68.4147 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/swap_roles.tpl b/WEB-INF/templates/swap_roles.tpl index d2d99240e..b96334f0b 100644 --- a/WEB-INF/templates/swap_roles.tpl +++ b/WEB-INF/templates/swap_roles.tpl @@ -1,8 +1,10 @@ {$forms.swapForm.open}
+ - + diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index 85e2cd44d..15bf3fe27 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -104,6 +104,12 @@ function handleClientControl() { +{/if} +{if $user->id == $user_id} + + + + {/if} From 341186de71fff2ecf47786a15adc96178c566e96 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 21:46:05 +0000 Subject: [PATCH 0028/1848] Added a Cancel button on the swap roles page. --- WEB-INF/templates/admin_team_delete.tpl | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/swap_roles.tpl | 2 +- swap_roles.php | 15 ++++++++++++--- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/admin_team_delete.tpl b/WEB-INF/templates/admin_team_delete.tpl index a8b0712f7..865c3fa99 100644 --- a/WEB-INF/templates/admin_team_delete.tpl +++ b/WEB-INF/templates/admin_team_delete.tpl @@ -10,7 +10,7 @@ - +
{$i18n.form.swap.hint}
 
{$i18n.form.swap.swap_with}:{$i18n.form.swap.swap_with}: {$forms.swapForm.swap_with.control}
{$i18n.label.status}: {$forms.userForm.status.control}
{$i18n.form.users.role}:{$user->role_name} {if $user->can('swap_roles')}{$i18n.form.profile.swap_roles}{/if}
{$i18n.form.users.default_rate} (0{$user->decimal_mark}00): 
{$forms.teamForm.btn_delete.control} {$forms.teamForm.btn_delete.control}    {$forms.teamForm.btn_cancel.control}
diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6ca757e04..2765c4c88 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - +
 Anuko Time Tracker 1.17.68.4147 | Copyright © Anuko | +  Anuko Time Tracker 1.17.68.4148 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/swap_roles.tpl b/WEB-INF/templates/swap_roles.tpl index b96334f0b..2d3086329 100644 --- a/WEB-INF/templates/swap_roles.tpl +++ b/WEB-INF/templates/swap_roles.tpl @@ -8,7 +8,7 @@ {$forms.swapForm.swap_with.control}
{$forms.swapForm.btn_submit.control}{$forms.swapForm.btn_submit.control} {$forms.swapForm.btn_cancel.control}
diff --git a/swap_roles.php b/swap_roles.php index 0c5257049..09178cd94 100644 --- a/swap_roles.php +++ b/swap_roles.php @@ -45,16 +45,25 @@ $form = new Form('swapForm'); $form->addInput(array('type'=>'combobox','name'=>'swap_with','style'=>'width: 250px;','data'=>$users,'datakeys'=>array('id','name'))); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { - if (ttTeamHelper::swapRolesWith($cl_id)) { + if ($request->getParameter('btn_submit')) { + if (ttTeamHelper::swapRolesWith($cl_id)) { + header('Location: users.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } + + if ($request->getParameter('btn_cancel')) { header('Location: users.php'); exit(); - } else - $err->add($i18n->get('error.db')); + } } $smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.swapForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.swap_roles')); $smarty->assign('content_page_name', 'swap_roles.tpl'); $smarty->display('index.tpl'); From a8334a66f49ce583f575ec1b4a71c7d746a1bcdc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 22:01:49 +0000 Subject: [PATCH 0029/1848] Added modification info to swap role operation. --- WEB-INF/lib/ttTeamHelper.class.php | 6 ++++-- WEB-INF/templates/admin_team_delete.tpl | 2 +- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 0d10a84f0..de034794f 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -116,14 +116,16 @@ static function swapRolesWith($user_id) { if (!$val['id'] || !$val['role_id']) return false; + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); + // Promote user. - $sql = "update tt_users set role_id = $user->role_id where id = $user_id and team_id = $user->team_id"; + $sql = "update tt_users set role_id = $user->role_id".$modified_part." where id = $user_id and team_id = $user->team_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Demote self. $role_id = $val['role_id']; - $sql = "update tt_users set role_id = $role_id where id = $user->id and team_id = $user->team_id"; + $sql = "update tt_users set role_id = $role_id".$modified_part." where id = $user->id and team_id = $user->team_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/admin_team_delete.tpl b/WEB-INF/templates/admin_team_delete.tpl index 865c3fa99..a8b0712f7 100644 --- a/WEB-INF/templates/admin_team_delete.tpl +++ b/WEB-INF/templates/admin_team_delete.tpl @@ -10,7 +10,7 @@
 
{$forms.teamForm.btn_delete.control}  {$forms.teamForm.btn_delete.control}   {$forms.teamForm.btn_cancel.control}
diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2765c4c88..aaa0fd750 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.68.4148 | Copyright © Anuko | +  Anuko Time Tracker 1.17.68.4149 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From dd3a0ade5b3c342fb4352b00dac4f654409fd3e5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 22:18:29 +0000 Subject: [PATCH 0030/1848] Put form.profile.swap_roles into localization files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 45 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 078eaf5cd..bd7e479a2 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -488,6 +488,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 91ead1a9b..9a1c45fa3 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -501,6 +501,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 397dc7f57..4892fb060 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -441,6 +441,8 @@ 'form.teams.hint' => 'Opret et nyt team ved at oprette en ny teamadministrator konto.
Du kan også importere teamdata fra en xml-fil fra en anden Anuko Time Tracker-server (eksisterende brugernavne er ikke tilladt).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 timers', 'form.profile.24_hours' => '24 timers', // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 279feee7a..12207a889 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -439,6 +439,8 @@ 'form.teams.hint' => 'Das Erzeugen eines neuen Manager Kontos, erzeugt eine neues Team.
Diese Teams können auch von XML-Dateien importiert werden.', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 Stunden', 'form.profile.24_hours' => '24 Stunden', // TODO: translate the following. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index b760badc6..21eb29333 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -501,6 +501,8 @@ 'form.teams.hint' => 'Crear un nuevo grupo, creando una nueva cuenta del manejador del equipo.
También puede importar datos de grupos, de un archivo xml de otro servidor Anuko Time Tracker (no estan permitidad colisiones de e-mail).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 horas', 'form.profile.24_hours' => '24 horas', // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 21fbcc0c2..ea2dfc672 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -498,6 +498,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f9c7a3b9d..4d8bff0ea 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -469,6 +469,8 @@ 'form.teams.hint' => 'Create a new team by creating a new team manager account.
You can also import team data from an xml file from another Anuko Time Tracker server (no login collisions are allowed).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 ساعت', 'form.profile.24_hours' => '24 ساعت', // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index d722106d4..600557cbf 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -449,6 +449,8 @@ 'form.teams.hint' => 'Luo uusi tiimi luomalla ensin tiimin esimiehen käyttäjätili.
Tiimin tiedot voi myös tuoda toiselta Anuko Time Tracker -palvelimelta xml-muodossa (käyttäjänimien oltava uusia).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12-tuntinen', 'form.profile.24_hours' => '24-tuntinen', // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index c999d6380..ac61f4b27 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -438,6 +438,8 @@ 'form.teams.hint' => 'Créez une nouvelle équipe en créant un nouveau compte de responsable d\\\'équipe.
Vous pouvez également importer des données d\\\'une équipe depuis un fichier xml provenant d\\\'un autre serveur Anuko Time Tracker (les doublons d\\\'identifiants ne sont pas autorisés).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 heures', 'form.profile.24_hours' => '24 heures', // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 1a7bfa1a3..4bef25ead 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -426,6 +426,8 @@ 'form.teams.hint' => 'Δημιουργήστε μια νέα ομάδα δημιουργώντας ένα νέο λογαριασμό διαχειριστή ομάδας.
Μπορείτε επίσης να εισαγάγετε δεδομένα ομάδας από ένα αρχείο xml από άλλο διακομιστή Anuko Time Tracker (δεν επιτρέπονται συγκρούσεις σύνδεσης).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 ώρες', 'form.profile.24_hours' => '24 ώρες', 'form.profile.show_holidays' => 'Προβολή διακοπών', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index fc54004ed..0964fd615 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -475,6 +475,8 @@ 'form.teams.hint' => 'ניתן ליצור צוות חדש על-ידי יצירת מנהל צוות חדש.
ניתן לייבא נתוני צוות מקובץ XML משרת Anuko Time Tracker אחר (אין אפשרות לשמות משתמש זהים)', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 שעות', 'form.profile.24_hours' => '24 שעות', // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 0ef9f2888..337f96d08 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -493,6 +493,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 6df19a3b6..5770b2784 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -441,6 +441,8 @@ 'form.teams.hint' => 'Crea un nuovo gruppo creando un account gruppo manager.
Puoi anche importare i dati di un gruppo da un file xml esportato da un altro server Anuko Time Tracker (non sono ammessi login duplicati).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 ore', 'form.profile.24_hours' => '24 ore', 'form.profile.show_holidays' => 'Mostra vacanze', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index c1845d73e..86d60fff9 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -493,6 +493,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 101cfd713..2e3a49d67 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -491,6 +491,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index fa65b754c..d7d09442d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -434,6 +434,8 @@ 'form.teams.hint' => 'Maak een nieuw team door een team manager account aan te maken.
U kunt ook teamgegevens importeren uit een xml file van een andere Anuko Time Tracker server (login namen moeten uniek zijn).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 uurs', 'form.profile.24_hours' => '24 uurs', 'form.profile.show_holidays' => 'Toon vakantiedagen', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index c467d9798..2aa8b4099 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -489,6 +489,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index f7b380672..54082f2f0 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -451,6 +451,8 @@ 'form.teams.hint' => 'Załóż nowy zespół najpierw tworząc konto managera.
Możesz także zaimportować plik xml z danymi zespołu z innego serwera Anuko Time Tracker (nazwy loginów nie mogą się powtarzać).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 godzin', 'form.profile.24_hours' => '24 godziny', // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index aa7bb7620..31a9d2b3c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -446,6 +446,8 @@ 'form.teams.hint' => 'Crie uma nova equipe fazendo uma nova conta de gerente.
você também pode importar os dados de um arquivo xml de outro servidor Anuko Time Tracker (não havendo colisão de usuários).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 horas', 'form.profile.24_hours' => '24 horas', // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index feaff31cc..0ec583c12 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -477,6 +477,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 96cf3a102..c58ed6b18 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -497,6 +497,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 07e1c619b..2407e3540 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -424,6 +424,7 @@ 'form.teams.hint' => 'Cоздайте новую команду, сделав новый аккаунт для её менеджера.
Также вы можете импортировать данные команды через xml файл из другого Anuko Time Tracker сервера (запрещено дублирование логинов).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +'form.profile.swap_roles' => 'Обменять роль', 'form.profile.12_hours' => '12 часов', 'form.profile.24_hours' => '24 часа', 'form.profile.show_holidays' => 'Показывать праздники', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 2b6f43eb0..b7b6eb36f 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -466,6 +466,8 @@ 'form.teams.hint' => 'Pomocou vytvorenia nového účtu tímového manažéra vytvorte nový tím.
Taktiež môžete importovať údaje o tíme z xml súboru z iného Anuko Time Tracker serveru (nie sú povolené kolízie v prihlasovacom mene).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12-hodinový', 'form.profile.24_hours' => '24-hodinový', // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 91e11c6f6..832af1215 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -475,6 +475,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index e5e04f935..ce480f600 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -450,6 +450,8 @@ 'form.teams.hint' => 'Napravite novi tim. Počnite sa otvaranjem naloga za Menadžera.
Takođe možete uvoziti podatke iz xml fajla sa drugog Anuko Time Tracker server-a (dupliranje prijava nisu dozvoljeni).', // Forma profila. Pogledajte primer na at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12 časova', 'form.profile.24_hours' => '24 časova', // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index d2ec27626..3d4081b6e 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -447,6 +447,8 @@ 'form.teams.hint' => 'Skapa en ny arbetsgrupp genom att skapa ett konto för en ansvarig person. Du kan även importera arbetsgrupper från en tidigare installation av Anuko Time Tracker via en XML-fil. Se till att inga användarnamn krockar när filen importeras.', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. +// TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', 'form.profile.12_hours' => '12-timmars', 'form.profile.24_hours' => '24-timmars', // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 6df4b32f1..d195f62f1 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -509,6 +509,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 3d9c34d19..26f90ebf6 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -476,6 +476,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 66b885cfd..5c4170fcd 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -486,6 +486,7 @@ // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. // TODO: translate the following. +// 'form.profile.swap_roles' => 'Swap roles', // 'form.profile.12_hours' => '12 hours', // 'form.profile.24_hours' => '24 hours', // 'form.profile.show_holidays' => 'Show holidays', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index aaa0fd750..45319e90a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.68.4149 | Copyright © Anuko | +  Anuko Time Tracker 1.17.68.4150 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 182ed39acb3600d991ff4742848a75c5ed2ba728 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Mar 2018 23:08:40 +0000 Subject: [PATCH 0031/1848] Put form.swap.hint into translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 30 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index bd7e479a2..6de09521f 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -525,6 +525,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 9a1c45fa3..1eae00b84 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -538,6 +538,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 4892fb060..85bf3e638 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -479,6 +479,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 12207a889..8534dd105 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -478,6 +478,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 21eb29333..703f9a35d 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -541,6 +541,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index ea2dfc672..b262a9b40 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -535,6 +535,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 4d8bff0ea..c224a01a5 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -509,6 +509,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 600557cbf..128d025e0 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -488,6 +488,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index ac61f4b27..85b22cce2 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -476,6 +476,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 4bef25ead..2e2a14b23 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -462,6 +462,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 0964fd615..2de2f23ec 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -514,6 +514,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 337f96d08..9732292d4 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -530,6 +530,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 5770b2784..8802caa11 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -478,6 +478,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 86d60fff9..1edccd0a1 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -530,6 +530,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 2e3a49d67..5bb4e50c6 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -528,6 +528,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index d7d09442d..eb69d0dc0 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -470,6 +470,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 2aa8b4099..4d178534b 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -526,6 +526,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 54082f2f0..016123fff 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -490,6 +490,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 31a9d2b3c..4878919fb 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -485,6 +485,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 0ec583c12..223368c64 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -514,6 +514,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index c58ed6b18..0f77cab77 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -534,6 +534,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 2407e3540..69fa16d87 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -458,6 +458,7 @@ 'form.quota.hint' => 'При пустых значениях квоты автоматически определяются из длительности рабочего дня и праздников.', // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. +'form.swap.hint' => 'Уменьшите свою роль, обменявшись с другим пользователем. Роль не может восстановлена.', 'form.swap.swap_with' => 'Обменять роль с', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index b7b6eb36f..cd7a1eee0 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -505,6 +505,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 832af1215..2e3f79a0d 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -512,6 +512,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index ce480f600..558050d14 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -489,6 +489,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 3d4081b6e..1f6b444cc 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -485,6 +485,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index d195f62f1..2f2997249 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -546,6 +546,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 26f90ebf6..7972e72fe 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -513,6 +513,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 5c4170fcd..a10108ea2 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -523,6 +523,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. // TODO: translate the following. +// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 45319e90a..223a757c3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.68.4150 | Copyright © Anuko | +  Anuko Time Tracker 1.17.68.4151 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 2ffa361a7610cbd1334754da314e4783226df689 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 11:22:56 +0000 Subject: [PATCH 0032/1848] Added some protection from bot registrations. --- WEB-INF/lib/ttRegistrator.class.php | 24 ++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 7082e6bc2..3c424f486 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -85,6 +85,12 @@ function register() { global $i18n; + // Protection fom too many recent bot registrations from user IP. + if ($this->registeredRecently()) { + $this->err->add($i18n->get('error.access_denied')); + return false; + } + import('ttUserHelper'); if (ttUserHelper::getUserByLogin($this->login)) { // User login already exists. @@ -185,4 +191,22 @@ function setCreatedBy($user_id) { return true; } + + // registeredRecently determines if we already have a successful recent registration from user IP. + // "recent" means "within the last minute" and is set in a query by the following condition: + // "and created > now() - interval 1 minute". Change if necessary. + function registeredRecently() { + $mdb2 = getConnection(); + + $ip_part = ' created_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']); + $sql = 'select created from tt_teams where '.$ip_part.' and created > now() - interval 1 minute'; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) + return false; + $val = $res->fetchRow(); + if ($val) + return true; + + return false; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 223a757c3..4beb89559 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.68.4151 | Copyright © Anuko | +  Anuko Time Tracker 1.17.69.4152 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a8a191541d6f05b08bd8331bdf409af5abfac896 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 16:04:24 +0000 Subject: [PATCH 0033/1848] Introduced feature_disabled.php for better error description. --- WEB-INF/resources/en.lang.php | 1 + admin_team_add.php | 3 ++- cf_custom_field_add.php | 8 ++++++-- cf_custom_field_delete.php | 8 ++++++-- cf_custom_field_edit.php | 8 ++++++-- cf_custom_fields.php | 8 ++++++-- cf_dropdown_option_add.php | 8 ++++++-- cf_dropdown_option_delete.php | 8 ++++++-- cf_dropdown_option_edit.php | 8 ++++++-- cf_dropdown_options.php | 8 ++++++-- charts.php | 10 ++++++++-- feature_disabled.php | 36 +++++++++++++++++++++++++++++++++++ 12 files changed, 95 insertions(+), 19 deletions(-) create mode 100644 feature_disabled.php diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index bedc4f6a7..732141a4a 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -69,6 +69,7 @@ 'error.access_denied' => 'Access denied.', 'error.sys' => 'System error.', 'error.db' => 'Database error.', +'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Incorrect "{0}" data.', 'error.empty' => 'Field "{0}" is empty.', 'error.not_equal' => 'Field "{0}" is not equal to field "{1}".', diff --git a/admin_team_add.php b/admin_team_add.php index 6d5bc84f9..6a8b05d57 100644 --- a/admin_team_add.php +++ b/admin_team_add.php @@ -81,9 +81,10 @@ $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { + /* * Note: creating a group by admin is pretty much the same as self-registration, - * except that created_by gields for group and user must be set to admin account. + * except that created_by fields for group and user must be set to admin account. * Therefore, we'll reuse ttRegistrator instance to create a group here * and override created_by fields using ttRegistrator::setCreatedBy() function. */ diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index 30c82a5a4..922d83b7c 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -30,11 +30,15 @@ require_once('plugins/CustomFields.class.php'); import('form.Form'); -// Access check. -if (!ttAccessAllowed('manage_custom_fields') || !$user->isPluginEnabled('cf')) { +// Access checks. +if (!ttAccessAllowed('manage_custom_fields')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cf')) { + header('Location: feature_disabled.php'); + exit(); +} if ($request->isPost()) { $cl_field_name = trim($request->getParameter('name')); diff --git a/cf_custom_field_delete.php b/cf_custom_field_delete.php index f4de48098..86c10b1ff 100644 --- a/cf_custom_field_delete.php +++ b/cf_custom_field_delete.php @@ -30,11 +30,15 @@ require_once('plugins/CustomFields.class.php'); import('form.Form'); -// Access check. -if (!ttAccessAllowed('manage_custom_fields') || !$user->isPluginEnabled('cf')) { +// Access checks. +if (!ttAccessAllowed('manage_custom_fields')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cf')) { + header('Location: feature_disabled.php'); + exit(); +} $id = $request->getParameter('id'); diff --git a/cf_custom_field_edit.php b/cf_custom_field_edit.php index 32ee3878d..499f6d02a 100644 --- a/cf_custom_field_edit.php +++ b/cf_custom_field_edit.php @@ -30,11 +30,15 @@ require_once('plugins/CustomFields.class.php'); import('form.Form'); -// Access check. -if (!ttAccessAllowed('manage_custom_fields') || !$user->isPluginEnabled('cf')) { +// Access checks. +if (!ttAccessAllowed('manage_custom_fields')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cf')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_id = $request->getParameter('id'); $field = CustomFields::getField($cl_id); diff --git a/cf_custom_fields.php b/cf_custom_fields.php index 2b34fb76b..53f80e400 100644 --- a/cf_custom_fields.php +++ b/cf_custom_fields.php @@ -30,11 +30,15 @@ require_once('plugins/CustomFields.class.php'); import('form.Form'); -// Access check. -if (!ttAccessAllowed('manage_custom_fields') || !$user->isPluginEnabled('cf')) { +// Access checks. +if (!ttAccessAllowed('manage_custom_fields')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cf')) { + header('Location: feature_disabled.php'); + exit(); +} $form = new Form('customFieldsForm'); diff --git a/cf_dropdown_option_add.php b/cf_dropdown_option_add.php index b9500833d..7b49424e5 100644 --- a/cf_dropdown_option_add.php +++ b/cf_dropdown_option_add.php @@ -30,11 +30,15 @@ require_once('plugins/CustomFields.class.php'); import('form.Form'); -// Access check. -if (!ttAccessAllowed('manage_custom_fields') || !$user->isPluginEnabled('cf')) { +// Access checks. +if (!ttAccessAllowed('manage_custom_fields')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cf')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_field_id = $request->getParameter('field_id'); $field = CustomFields::getField($cl_field_id); diff --git a/cf_dropdown_option_delete.php b/cf_dropdown_option_delete.php index 0a1f25ba0..4cb2aca8a 100644 --- a/cf_dropdown_option_delete.php +++ b/cf_dropdown_option_delete.php @@ -30,11 +30,15 @@ require_once('plugins/CustomFields.class.php'); import('form.Form'); -// Access check. -if (!ttAccessAllowed('manage_custom_fields') || !$user->isPluginEnabled('cf')) { +// Access checks. +if (!ttAccessAllowed('manage_custom_fields')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cf')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_id = $request->getParameter('id'); $form = new Form('optionDeleteForm'); diff --git a/cf_dropdown_option_edit.php b/cf_dropdown_option_edit.php index 5fc333d01..5522accf1 100644 --- a/cf_dropdown_option_edit.php +++ b/cf_dropdown_option_edit.php @@ -30,11 +30,15 @@ require_once('plugins/CustomFields.class.php'); import('form.Form'); -// Access check. -if (!ttAccessAllowed('manage_custom_fields') || !$user->isPluginEnabled('cf')) { +// Access checks. +if (!ttAccessAllowed('manage_custom_fields')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cf')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_id = $request->getParameter('id'); $cl_name = CustomFields::getOptionName($cl_id); diff --git a/cf_dropdown_options.php b/cf_dropdown_options.php index 02f59f56b..1afce7348 100644 --- a/cf_dropdown_options.php +++ b/cf_dropdown_options.php @@ -30,11 +30,15 @@ require_once('plugins/CustomFields.class.php'); import('form.Form'); -// Access check. -if (!ttAccessAllowed('manage_custom_fields') || !$user->isPluginEnabled('cf')) { +// Access checks. +if (!ttAccessAllowed('manage_custom_fields')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cf')) { + header('Location: feature_disabled.php'); + exit(); +} $field_id = $request->getParameter('field_id'); $options = CustomFields::getOptions($field_id); diff --git a/charts.php b/charts.php index 69997d87f..959cfe36a 100644 --- a/charts.php +++ b/charts.php @@ -37,11 +37,17 @@ import('ttUserHelper'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('view_own_charts') || !$user->isPluginEnabled('ch')) { +// Access checks. +if (!ttAccessAllowed('view_own_charts')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ch')) { + header('Location: feature_disabled.php'); + exit(); +} + + // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); diff --git a/feature_disabled.php b/feature_disabled.php new file mode 100644 index 000000000..7f0bb81f5 --- /dev/null +++ b/feature_disabled.php @@ -0,0 +1,36 @@ +add($i18n->get('error.feature_disabled')); +if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. + +$smarty->assign('title', $i18n->get('label.error')); +$smarty->assign('content_page_name', 'access_denied.tpl'); +$smarty->display('index.tpl'); From 62b36719d92eec21e5e132811c1ec88e5f495117 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 16:17:16 +0000 Subject: [PATCH 0034/1848] Added error.feature_disabled to translation files. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 55 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 6de09521f..3b429f5d5 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -77,6 +77,8 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', 'error.db' => 'Error de la base de dades.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Dada "{0}" incorrecta.', 'error.empty' => 'L\\\'Arxiu "{0}" està buit.', 'error.not_equal' => 'L\\\'Arxiu "{0}" no és igual al arxiu "{1}".', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 1eae00b84..0eccd9fdc 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -79,6 +79,8 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', 'error.db' => 'Chyba databáze.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Nesprávná "{0}" data.', 'error.empty' => 'Pole "{0}" je prázdné.', 'error.not_equal' => 'Pole "{0}" neodpovídá poli "{1}".', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 85bf3e638..424346667 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -68,6 +68,8 @@ 'error.access_denied' => 'Adgang nægtet.', 'error.sys' => 'System fejl.', 'error.db' => 'Database fejl.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Forkert "{0}" data.', 'error.empty' => 'Felt "{0}" er tom.', 'error.not_equal' => 'Felt "{0}" er ikke lig med "{1}".', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 8534dd105..34d050c05 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -68,6 +68,8 @@ 'error.access_denied' => 'Zugriff verweigert.', 'error.sys' => 'Systemfehler.', 'error.db' => 'Datenbankfehler.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Ungültige "{0}" Daten.', 'error.empty' => 'Feld "{0}" ist leer.', 'error.not_equal' => 'Feld "{0}" ist nicht gleich Feld "{1}".', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 703f9a35d..3c5f91532 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -76,6 +76,8 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', 'error.db' => 'Error de la base de datos.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Dato "{0}" incorrecto.', 'error.empty' => 'El archivo "{0}" esta vacío.', 'error.not_equal' => 'El archivo "{0}" no es igual al archivo "{1}".', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index b262a9b40..33085b1d2 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -79,6 +79,8 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', 'error.db' => 'Andmebaasi viga.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Valed "{0}" andmed.', 'error.empty' => 'Väli "{0}" on tühi.', 'error.not_equal' => 'Väli "{0}" ei ole väljaga "{1}" võrdne.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index c224a01a5..654674b1a 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -72,6 +72,8 @@ // 'error.access_denied' => 'Access denied.', 'error.sys' => 'خطا در سیستم.', 'error.db' => 'خطا در پایگاه داده.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'داده اشتباه در "{0}".', 'error.empty' => 'فیلد "{0}" خالیست.', 'error.not_equal' => 'فیلد "{0}" با فیلد "{1}" برابر نیست.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 128d025e0..967c251d8 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -70,6 +70,8 @@ 'error.access_denied' => 'Pääsy estetty.', 'error.sys' => 'Järjestelmävirhe.', 'error.db' => 'Tietokantavirhe.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Virheellinen "{0}" tieto.', 'error.empty' => 'Kenttä "{0}" on tyhjä.', 'error.not_equal' => 'Kentät "{0}" ja "{1}" eivät ole samat.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 85b22cce2..aafbb5dca 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -68,6 +68,8 @@ 'error.access_denied' => 'Accès refusé.', 'error.sys' => 'Erreur système.', 'error.db' => 'Erreur de base de données.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Donnée "{0}" incorrecte.', 'error.empty' => 'Le champ "{0}" est vide.', 'error.not_equal' => 'Le champ "{0}" n\\\'est pas égal au champ "{1}".', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 2e2a14b23..e9f4790c0 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -68,6 +68,8 @@ 'error.access_denied' => 'Δεν επιτρέπεται η πρόσβαση.', 'error.sys' => 'Σφάλμα συστήματος.', 'error.db' => 'Σφάλμα βάσης δεδομένων.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Λανθασμένο "{0}" δεδομένο.', 'error.empty' => 'Το πεδίο "{0}" είναι κενό.', 'error.not_equal' => 'Το πεδίο "{0}" δεν είναι ίσο με το πεδίο "{1}".', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2de2f23ec..3426aa870 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -75,6 +75,8 @@ // 'error.access_denied' => 'Access denied.', 'error.sys' => 'שגיאת מערכת', 'error.db' => 'שגיאה של בסיס הנתונים', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'נתון "{0}" שגוי', 'error.empty' => 'השדה "{0}" ריק', 'error.not_equal' => 'השדה "{1}" אינו שווה לשדה "{0}"', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 9732292d4..fb891c8c0 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -77,6 +77,8 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', 'error.db' => 'Adatbázis hiba.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Hibás "{0}" mező tartalma.', 'error.empty' => 'A "{0}" mező üres.', 'error.not_equal' => 'A "{0}" mező tartalma nem egyezik meg a "{1}" mező tartalmával.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 8802caa11..e2258bb74 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -70,6 +70,8 @@ 'error.access_denied' => 'Accesso negato.', 'error.sys' => 'Errore di sistema.', 'error.db' => 'Errore database.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Dato "{0}" errato.', 'error.empty' => 'Il campo "{0}" è vuoto.', 'error.not_equal' => 'Il campo "{0}" non è uguale al campo "{1}".', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 1edccd0a1..880b95cd8 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -77,6 +77,8 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', 'error.db' => 'データベースのエラー。', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => '不正確な"{0}"データ。', 'error.empty' => '"{0}"のフィールドが空白です。', 'error.not_equal' => '"{0}"のフィールドは"{1}"のフィールドと違います。', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 5bb4e50c6..6e0a7e292 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -77,6 +77,8 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', 'error.db' => '데이터베이스 오류.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => '부정확한 "{0}" 의 데이터.', 'error.empty' => '"{0}" 의 필드가 비어있습니다.', 'error.not_equal' => '"{0}" 의 필드가 "{1}" 의 필드와 같지 않습니다.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index eb69d0dc0..be2fcf622 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -68,6 +68,8 @@ 'error.access_denied' => 'Toegang geweigerd.', 'error.sys' => 'Systeem fout.', 'error.db' => 'Database fout.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Incorrecte gegevens: "{0}".', 'error.empty' => 'Veld "{0}" is leeg.', 'error.not_equal' => 'Veld "{0}" is niet gelijk aan veld "{1}".', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 4d178534b..71a8959cf 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -76,6 +76,8 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', 'error.db' => 'Databasefeil.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Feil "{0}" data.', 'error.empty' => 'Feltet "{0}" er tomt.', 'error.not_equal' => 'Feltet "{0}" stemmer ikke med "{1}".', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 016123fff..fd599500f 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -71,6 +71,8 @@ 'error.access_denied' => 'Odmowa dostępu.', 'error.sys' => 'Błąd systemu.', 'error.db' => 'Błąd bazy danych.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Niepoprawne dane: "{0}".', 'error.empty' => 'Pole "{0}" jest puste.', 'error.not_equal' => 'Wartość z pola "{0}" jest inna niż wartość z pola "{1}".', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 4878919fb..6fcd6c3ce 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -68,6 +68,8 @@ 'error.access_denied' => 'Acesso negado.', 'error.sys' => 'Erro no sistema.', 'error.db' => 'Erro no banco de dados.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Dados incorretos "{0}".', 'error.empty' => 'Campo "{0}" está vazio.', 'error.not_equal' => 'Campo "{0}" é diferente do campo "{1}".', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 223368c64..7b87af001 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -79,6 +79,7 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', // 'error.db' => 'Database error.', +// 'error.feature_disabled' => 'Feature is disabled.', // 'error.field' => 'Incorrect "{0}" data.', // 'error.empty' => 'Field "{0}" is empty.', // 'error.not_equal' => 'Field "{0}" is not equal to field "{1}".', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 0f77cab77..357d6448e 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -81,6 +81,7 @@ // 'error.sys' => 'System error.', 'error.db' => 'Eroare baza de date.', // TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', // 'error.field' => 'Incorrect "{0}" data.', 'error.empty' => 'Campul "{0}" este gol.', 'error.not_equal' => 'Campul "{0}" nu este egal cu campul "{1}".', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 69fa16d87..14b3e6e8d 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -68,6 +68,7 @@ 'error.access_denied' => 'Доступ запрещён.', 'error.sys' => 'Системная ошибка.', 'error.db' => 'Ошибка базы данных.', +'error.feature_disabled' => 'Функция отключена.', 'error.field' => 'Некорректные данные в поле "{0}".', 'error.empty' => 'Пустое поле "{0}".', 'error.not_equal' => 'Значение "{0}" не соответствует "{1}".', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index cd7a1eee0..4dbffff2f 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -73,6 +73,8 @@ // 'error.access_denied' => 'Access denied.', 'error.sys' => 'Systémová chyba.', 'error.db' => 'Databázová chyba.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Nesprávne "{0}" údaje.', 'error.empty' => 'Pole "{0}" je prázdne.', 'error.not_equal' => 'Pole "{0}" nie je zhodné s poľom "{1}".', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 2e3f79a0d..8c93e4000 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -79,6 +79,7 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', // 'error.db' => 'Database error.', +// 'error.feature_disabled' => 'Feature is disabled.', // 'error.field' => 'Incorrect "{0}" data.', // 'error.empty' => 'Field "{0}" is empty.', // 'error.not_equal' => 'Field "{0}" is not equal to field "{1}".', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 558050d14..5e7f56e9f 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -68,6 +68,8 @@ 'error.access_denied' => 'Pristup odbijen.', 'error.sys' => 'Greška u sistemu.', 'error.db' => 'Greška u bazi podataka.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Pogrešan "{0}" podatak.', 'error.empty' => 'Polje "{0}" je prazno.', 'error.not_equal' => 'Polje "{0}" nije jednak polju "{1}".', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 1f6b444cc..37e8dffe3 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -69,6 +69,8 @@ 'error.access_denied' => 'Åtkomst nekad.', 'error.sys' => 'Systemfel.', 'error.db' => 'Databasfel.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => '"{0}" innehåller ett felaktigt värde.', 'error.empty' => '"{0}" kan inte vara tomt.', 'error.not_equal' => '"{0}" matchar inte "{1}".', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 2f2997249..bbf97dbf8 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -80,6 +80,8 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', 'error.db' => 'Veritabanı hatası.', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => 'Hatalı veri "{0}".', 'error.empty' => 'Alan "{0}" boştur.', // TODO: confirm that error.not_equal is translated correctly. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7972e72fe..558427534 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -69,6 +69,8 @@ 'error.access_denied' => '拒绝访问。', 'error.sys' => '系统错误。', 'error.db' => '数据库错误。', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => '不正确的"{0}"数据。', 'error.empty' => '栏目"{0}"为空。', 'error.not_equal' => '栏目"{0}"不等于栏目"{1}"。', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index a10108ea2..16c806222 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -75,6 +75,8 @@ // 'error.access_denied' => 'Access denied.', // 'error.sys' => 'System error.', 'error.db' => '資料庫錯誤。', +// TODO: translate the following. +// 'error.feature_disabled' => 'Feature is disabled.', 'error.field' => '不正確的"{0}"資料。', 'error.empty' => '欄目"{0}"為空。', 'error.not_equal' => '欄目"{0}"不等於欄目"{1}"。', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4beb89559..0f0b9fc5e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.69.4152 | Copyright © Anuko | +  Anuko Time Tracker 1.17.69.4153 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b9fc6bb058ab933c980b72c54eea0b5afcab03e7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 16:48:47 +0000 Subject: [PATCH 0035/1848] Fixed header to print a revamped role name. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- charts.php | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0f0b9fc5e..10499fb25 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.69.4153 | Copyright © Anuko | +  Anuko Time Tracker 1.17.69.4154 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index e0fd8057a..101c84a6c 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -150,7 +150,7 @@ {if $title} - +
{$title}{if $timestring}: {$timestring}{/if}
{$user->name|escape}{if $user->isAdmin()} {$i18n.label.role_admin}{elseif $user->isManager()} {$i18n.label.role_manager}{elseif $user->canManageTeam()} {$i18n.label.role_comanager}{/if}{if $user->behalf_id > 0} {$i18n.label.on_behalf} {$user->behalf_name|escape}{/if}{if $user->team}, {$user->team|escape}{/if}
{$user->name|escape} - {$user->role_name|escape} {if $user->behalf_id > 0}{$i18n.label.on_behalf} {$user->behalf_name|escape}{/if}{if $user->team}, {$user->team|escape}{/if}
{/if} diff --git a/charts.php b/charts.php index 959cfe36a..f2b01f16f 100644 --- a/charts.php +++ b/charts.php @@ -47,8 +47,6 @@ exit(); } - - // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); if(!$cl_date) { @@ -111,7 +109,7 @@ } // If user has changed - set behalf_id accordingly in the session. if ($request->getParameter('onBehalfUser')) { - if($user->canManageTeam()) { + if($user->can('view_charts')) { unset($_SESSION['behalf_id']); unset($_SESSION['behalf_name']); @@ -129,7 +127,7 @@ $chart_form = new Form('chartForm'); // User dropdown. Changes the user "on behalf" of whom we are working. -if ($user->canManageTeam()) { +if ($user->can('view_charts')) { $user_list = ttTeamHelper::getActiveUsers(array('putSelfFirst'=>true)); if (count($user_list) > 1) { $chart_form->addInput(array('type'=>'combobox', From e59d57b1fcf105382028dcfc0157a6ca84b0dc46 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 16:52:06 +0000 Subject: [PATCH 0036/1848] One more fix to header output. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 10499fb25..2403c2b26 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.69.4154 | Copyright © Anuko | +  Anuko Time Tracker 1.17.69.4155 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 101c84a6c..1d6622165 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -150,7 +150,7 @@ {if $title} - +
{$title}{if $timestring}: {$timestring}{/if}
{$user->name|escape} - {$user->role_name|escape} {if $user->behalf_id > 0}{$i18n.label.on_behalf} {$user->behalf_name|escape}{/if}{if $user->team}, {$user->team|escape}{/if}
{$user->name|escape} - {$user->role_name|escape}{if $user->behalf_id > 0} {$i18n.label.on_behalf} {$user->behalf_name|escape}{/if}{if $user->team}, {$user->team|escape}{/if}
{/if} From 4dcb88a76a3de466ee6116ae0852f53ba2b259a5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 18:05:53 +0000 Subject: [PATCH 0037/1848] Some refactoring of access checks - in progress. --- WEB-INF/templates/footer.tpl | 2 +- client_add.php | 8 ++++-- client_delete.php | 8 ++++-- client_edit.php | 8 ++++-- clients.php | 8 ++++-- expense_delete.php | 10 +++++-- expense_edit.php | 8 ++++-- expenses.php | 8 ++++-- index.php | 2 +- invoice_add.php | 8 ++++-- invoice_delete.php | 8 ++++-- invoice_send.php | 8 ++++-- invoice_view.php | 8 ++++-- invoices.php | 8 ++++-- locking.php | 8 ++++-- login.php | 2 +- mobile/expenses.php | 8 ++++-- mobile/feature_disabled.php | 36 +++++++++++++++++++++++++ mysql.sql | 52 ++++++++++++++++++------------------ notification_add.php | 8 ++++-- notification_delete.php | 8 ++++-- notification_edit.php | 8 ++++-- notifications.php | 8 ++++-- password_change.php | 2 +- 24 files changed, 176 insertions(+), 66 deletions(-) create mode 100644 mobile/feature_disabled.php diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2403c2b26..8b84e12b6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.69.4155 | Copyright © Anuko | +  Anuko Time Tracker 1.17.69.4156 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/client_add.php b/client_add.php index c0526e51b..5ae5997fa 100644 --- a/client_add.php +++ b/client_add.php @@ -31,11 +31,15 @@ import('ttClientHelper'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_clients') || !$user->isPluginEnabled('cl')) { +// Access checks. +if (!ttAccessAllowed('manage_clients')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cl')) { + header('Location: feature_disabled.php'); + exit(); +} $projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/client_delete.php b/client_delete.php index b162ea844..22ae9d4a6 100644 --- a/client_delete.php +++ b/client_delete.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttClientHelper'); -// Access check. -if (!ttAccessAllowed('manage_clients') || !$user->isPluginEnabled('cl')) { +// Access checks. +if (!ttAccessAllowed('manage_clients')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cl')) { + header('Location: feature_disabled.php'); + exit(); +} $id = (int)$request->getParameter('id'); $client = ttClientHelper::getClient($id); diff --git a/client_edit.php b/client_edit.php index 05203237f..b74fb3150 100644 --- a/client_edit.php +++ b/client_edit.php @@ -31,11 +31,15 @@ import('ttClientHelper'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_clients') || !$user->isPluginEnabled('cl')) { +// Access checks. +if (!ttAccessAllowed('manage_clients')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cl')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_id = (int) $request->getParameter('id'); diff --git a/clients.php b/clients.php index 89b5c4a37..6ac6f5a1d 100644 --- a/clients.php +++ b/clients.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_clients') || !$user->isPluginEnabled('cl')) { +// Access checks. +if (!ttAccessAllowed('manage_clients')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cl')) { + header('Location: feature_disabled.php'); + exit(); +} $smarty->assign('active_clients', ttTeamHelper::getActiveClients($user->team_id, true)); $smarty->assign('inactive_clients', ttTeamHelper::getInactiveClients($user->team_id, true)); diff --git a/expense_delete.php b/expense_delete.php index 06c9690b0..42a6add80 100644 --- a/expense_delete.php +++ b/expense_delete.php @@ -31,11 +31,17 @@ import('DateAndTime'); import('ttExpenseHelper'); -// Access check. -if (!ttAccessAllowed('track_own_expenses') || !$user->isPluginEnabled('ex')) { +// Access checks. +if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses'))) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ex')) { + header('Location: feature_disabled.php'); + exit(); +} + + $cl_id = $request->getParameter('id'); $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); diff --git a/expense_edit.php b/expense_edit.php index 9ea7c6493..15cfcfaf5 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -32,11 +32,15 @@ import('DateAndTime'); import('ttExpenseHelper'); -// Access check. -if (!ttAccessAllowed('track_own_expenses') || !$user->isPluginEnabled('ex')) { +// Access checks. +if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses'))) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ex')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_id = $request->getParameter('id'); diff --git a/expenses.php b/expenses.php index bb7694816..00b43179c 100644 --- a/expenses.php +++ b/expenses.php @@ -33,11 +33,15 @@ import('DateAndTime'); import('ttExpenseHelper'); -// Access check. -if (!ttAccessAllowed('track_own_expenses') || !$user->isPluginEnabled('ex')) { +// Access checks. +if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses'))) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ex')) { + header('Location: feature_disabled.php'); + exit(); +} // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); diff --git a/index.php b/index.php index 51e1e016f..fd4dde8ed 100644 --- a/index.php +++ b/index.php @@ -30,7 +30,7 @@ // Redirects for admin and client roles. if ($auth->isAuthenticated()) { - if ($user->isAdmin()) { + if ($user->can('administer_site')) { header('Location: admin_teams.php'); exit(); } elseif ($user->isClient()) { diff --git a/invoice_add.php b/invoice_add.php index ed0a8c526..5267056c0 100644 --- a/invoice_add.php +++ b/invoice_add.php @@ -31,11 +31,15 @@ import('ttTeamHelper'); import('ttInvoiceHelper'); -// Access check. -if (!ttAccessAllowed('manage_invoices') || !$user->isPluginEnabled('iv')) { +// Access checks. +if (!ttAccessAllowed('manage_invoices')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('iv')) { + header('Location: feature_disabled.php'); + exit(); +} if ($request->isPost()) { $cl_date = $request->getParameter('date'); diff --git a/invoice_delete.php b/invoice_delete.php index 29160ba55..2bca58ce3 100644 --- a/invoice_delete.php +++ b/invoice_delete.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttInvoiceHelper'); -// Access check. -if (!ttAccessAllowed('manage_invoices') || !$user->isPluginEnabled('iv')) { +// Access checks. +if (!ttAccessAllowed('manage_invoices')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('iv')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_invoice_id = (int)$request->getParameter('id'); $invoice = ttInvoiceHelper::getInvoice($cl_invoice_id); diff --git a/invoice_send.php b/invoice_send.php index 2c0894a35..f0e30bc4b 100644 --- a/invoice_send.php +++ b/invoice_send.php @@ -31,11 +31,15 @@ import('ttInvoiceHelper'); import('ttSysConfig'); -// Access check. -if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices')) || !$user->isPluginEnabled('iv')) { +// Access checks. +if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices'))) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('iv')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_invoice_id = (int)$request->getParameter('id'); $invoice = ttInvoiceHelper::getInvoice($cl_invoice_id); diff --git a/invoice_view.php b/invoice_view.php index 3715b80a2..62f0cbbff 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -32,11 +32,15 @@ import('ttClientHelper'); import('form.Form'); -// Access check. -if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices')) || !$user->isPluginEnabled('iv')) { +// Access checks. +if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices'))) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('iv')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_id = (int)$request->getParameter('id'); $invoice = ttInvoiceHelper::getInvoice($cl_id); diff --git a/invoices.php b/invoices.php index a03579b08..1723a8d1d 100644 --- a/invoices.php +++ b/invoices.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices')) || !$user->isPluginEnabled('iv')) { +// Access checks. +if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices'))) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('iv')) { + header('Location: feature_disabled.php'); + exit(); +} $invoices = ttTeamHelper::getActiveInvoices(); diff --git a/locking.php b/locking.php index 8a6f4304c..2b49b8375 100644 --- a/locking.php +++ b/locking.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('lk')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('lk')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_lock_spec = $request->isPost() ? $request->getParameter('lock_spec') : $user->lock_spec; diff --git a/login.php b/login.php index e246e0a51..a3345d0e0 100644 --- a/login.php +++ b/login.php @@ -62,7 +62,7 @@ $user = new ttUser(null, $auth->getUserId()); // Redirect, depending on user role. - if ($user->isAdmin()) { + if ($user->can('administer_site')) { header('Location: admin_teams.php'); } elseif ($user->isClient()) { header('Location: reports.php'); diff --git a/mobile/expenses.php b/mobile/expenses.php index 934c63a78..f0fc5c304 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -33,11 +33,15 @@ import('DateAndTime'); import('ttExpenseHelper'); -// Access check. -if (!ttAccessAllowed('track_own_expenses') || !$user->isPluginEnabled('ex')) { +// Access checks. +if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses'))) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ex')) { + header('Location: feature_disabled.php'); + exit(); +} // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); diff --git a/mobile/feature_disabled.php b/mobile/feature_disabled.php new file mode 100644 index 000000000..cf399568e --- /dev/null +++ b/mobile/feature_disabled.php @@ -0,0 +1,36 @@ +add($i18n->get('error.feature_disabled')); +if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. + +$smarty->assign('title', $i18n->get('label.error')); +$smarty->assign('content_page_name', 'mobile/access_denied.tpl'); +$smarty->display('mobile/index.tpl'); diff --git a/mysql.sql b/mysql.sql index df34b7759..ebe59936a 100644 --- a/mysql.sql +++ b/mysql.sql @@ -13,32 +13,32 @@ # This table stores settings common to all team members such as language, week start day, etc. # CREATE TABLE `tt_teams` ( - `id` int(11) NOT NULL auto_increment, # team id - `name` varchar(80) default NULL, # team name - `currency` varchar(7) default NULL, # team currency symbol - `decimal_mark` char(1) NOT NULL default '.', # separator in decimals - `lang` varchar(10) NOT NULL default 'en', # language - `date_format` varchar(20) NOT NULL default '%Y-%m-%d', # date format - `time_format` varchar(20) NOT NULL default '%H:%M', # time format - `week_start` smallint(2) NOT NULL default 0, # Week start day, 0 == Sunday. - `tracking_mode` smallint(2) NOT NULL default 1, # tracking mode ("time", "projects" or "projects and tasks") - `project_required` smallint(2) NOT NULL default 0, # whether a project selection is required or optional - `task_required` smallint(2) NOT NULL default 0, # whether a task selection is required or optional - `record_type` smallint(2) NOT NULL default 0, # time record type ("start and finish", "duration", or both) - `bcc_email` varchar(100) default NULL, # bcc email to copy all reports to - `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". - `workday_minutes` smallint(4) default 480, # number of work minutes in a regular working day - `custom_logo` tinyint(4) default 0, # whether to use a custom logo or not - `config` text default NULL, # miscellaneous team configuration settings - `created` datetime default NULL, # creation timestamp - `created_ip` varchar(45) default NULL, # creator ip - `created_by` int(11) default NULL, # creator user_id - `modified` datetime default NULL, # modification timestamp - `modified_ip` varchar(45) default NULL, # modifier ip - `modified_by` int(11) default NULL, # modifier user_id - `status` tinyint(4) default 1, # team status + `id` int(11) NOT NULL auto_increment, # team id + `name` varchar(80) default NULL, # team name + `currency` varchar(7) default NULL, # team currency symbol + `decimal_mark` char(1) NOT NULL default '.', # separator in decimals + `lang` varchar(10) NOT NULL default 'en', # language + `date_format` varchar(20) NOT NULL default '%Y-%m-%d', # date format + `time_format` varchar(20) NOT NULL default '%H:%M', # time format + `week_start` smallint(2) NOT NULL default 0, # Week start day, 0 == Sunday. + `tracking_mode` smallint(2) NOT NULL default 1, # tracking mode ("time", "projects" or "projects and tasks") + `project_required` smallint(2) NOT NULL default 0, # whether a project selection is required or optional + `task_required` smallint(2) NOT NULL default 0, # whether a task selection is required or optional + `record_type` smallint(2) NOT NULL default 0, # time record type ("start and finish", "duration", or both) + `bcc_email` varchar(100) default NULL, # bcc email to copy all reports to + `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". + `workday_minutes` smallint(4) default 480, # number of work minutes in a regular working day + `custom_logo` tinyint(4) default 0, # whether to use a custom logo or not + `config` text default NULL, # miscellaneous team configuration settings + `created` datetime default NULL, # creation timestamp + `created_ip` varchar(45) default NULL, # creator ip + `created_by` int(11) default NULL, # creator user_id + `modified` datetime default NULL, # modification timestamp + `modified_ip` varchar(45) default NULL, # modifier ip + `modified_by` int(11) default NULL, # modifier user_id + `status` tinyint(4) default 1, # team status PRIMARY KEY (`id`) ); diff --git a/notification_add.php b/notification_add.php index 6d0e4d31a..7dd680ff3 100644 --- a/notification_add.php +++ b/notification_add.php @@ -33,11 +33,15 @@ import('ttFavReportHelper'); import('ttNotificationHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('no')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('no')) { + header('Location: feature_disabled.php'); + exit(); +} $fav_reports = ttFavReportHelper::getReports($user->id); diff --git a/notification_delete.php b/notification_delete.php index 46de065d6..b18ac614f 100644 --- a/notification_delete.php +++ b/notification_delete.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttNotificationHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('no')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('no')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_notification_id = (int)$request->getParameter('id'); $notification = ttNotificationHelper::get($cl_notification_id); diff --git a/notification_edit.php b/notification_edit.php index 431798285..1c36865f3 100644 --- a/notification_edit.php +++ b/notification_edit.php @@ -33,11 +33,15 @@ import('ttFavReportHelper'); import('ttNotificationHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('no')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('no')) { + header('Location: feature_disabled.php'); + exit(); +} $notification_id = (int) $request->getParameter('id'); $fav_reports = ttFavReportHelper::getReports($user->id); diff --git a/notifications.php b/notifications.php index c03378d29..6dcf33fd2 100644 --- a/notifications.php +++ b/notifications.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('no')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('no')) { + header('Location: feature_disabled.php'); + exit(); +} $form = new Form('notificationsForm'); diff --git a/password_change.php b/password_change.php index bcbd5f4ad..832118f6c 100644 --- a/password_change.php +++ b/password_change.php @@ -82,7 +82,7 @@ if ($auth->doLogin($user->login, $cl_password1)) { setcookie('tt_login', $user->login, time() + COOKIE_EXPIRE, '/'); // Redirect, depending on user role. - if ($user->isAdmin()) { + if ($user->can('administer_site')) { header('Location: admin_teams.php'); } elseif ($user->isClient()) { header('Location: reports.php'); From 030d2c3ffbf8229cc945427e9e9f7704226effe1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 19:37:00 +0000 Subject: [PATCH 0038/1848] A bit more progress on refactoring access checks. --- WEB-INF/lib/ttTeamHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/user_edit.tpl | 2 +- expense_delete.php | 2 -- predefined_expense_add.php | 8 ++++++-- predefined_expense_delete.php | 8 ++++++-- predefined_expense_edit.php | 8 ++++++-- predefined_expenses.php | 8 ++++++-- project_add.php | 8 ++++++-- project_delete.php | 8 ++++++-- project_edit.php | 8 ++++++-- projects.php | 8 ++++++-- quotas.php | 8 ++++++-- report.php | 2 +- report_send.php | 2 +- reports.php | 2 +- role_edit.php | 3 ++- swap_roles.php | 11 +++++++---- user_edit.php | 8 ++++++++ 19 files changed, 77 insertions(+), 31 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index de034794f..5aeee2196 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -143,7 +143,7 @@ static function getUsersForSwap() { if (is_a($res, 'PEAR_Error')) return false; while ($val = $res->fetchRow()) { - $isClient = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have data entry right. + $isClient = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have track_own_time right. if ($isClient) continue; // Skip adding clients. $user_list[] = $val; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8b84e12b6..b99c720bf 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + {/if} diff --git a/expense_delete.php b/expense_delete.php index 42a6add80..1f7fbb34b 100644 --- a/expense_delete.php +++ b/expense_delete.php @@ -41,8 +41,6 @@ exit(); } - - $cl_id = $request->getParameter('id'); $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); diff --git a/predefined_expense_add.php b/predefined_expense_add.php index 82cf99b63..2f1621cac 100644 --- a/predefined_expense_add.php +++ b/predefined_expense_add.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttPredefinedExpenseHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('ex')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ex')) { + header('Location: feature_disabled.php'); + exit(); +} if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); diff --git a/predefined_expense_delete.php b/predefined_expense_delete.php index c8ae1c822..9b4450325 100644 --- a/predefined_expense_delete.php +++ b/predefined_expense_delete.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttPredefinedExpenseHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('ex')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ex')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_predefined_expense_id = (int)$request->getParameter('id'); $predefined_expense = ttPredefinedExpenseHelper::get($cl_predefined_expense_id); diff --git a/predefined_expense_edit.php b/predefined_expense_edit.php index 220778a98..7791b2440 100644 --- a/predefined_expense_edit.php +++ b/predefined_expense_edit.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttPredefinedExpenseHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('ex')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ex')) { + header('Location: feature_disabled.php'); + exit(); +} $predefined_expense_id = (int) $request->getParameter('id'); diff --git a/predefined_expenses.php b/predefined_expenses.php index 4e799121b..7aed7ad60 100644 --- a/predefined_expenses.php +++ b/predefined_expenses.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('ex')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ex')) { + header('Location: feature_disabled.php'); + exit(); +} $form = new Form('predefinedExpensesForm'); diff --git a/project_add.php b/project_add.php index 6b55019cb..55b83b42a 100644 --- a/project_add.php +++ b/project_add.php @@ -31,11 +31,15 @@ import('ttProjectHelper'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_projects') || (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode)) { +// Access checks. +if (!ttAccessAllowed('manage_projects')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $users = ttTeamHelper::getActiveUsers(); foreach ($users as $user_item) diff --git a/project_delete.php b/project_delete.php index 683dbc50c..2373bbead 100644 --- a/project_delete.php +++ b/project_delete.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttProjectHelper'); -// Access check. -if (!ttAccessAllowed('manage_projects') || (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode)) { +// Access checks. +if (!ttAccessAllowed('manage_projects')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $cl_project_id = (int)$request->getParameter('id'); $project = ttProjectHelper::get($cl_project_id); diff --git a/project_edit.php b/project_edit.php index be0e90fa9..d30782ab5 100644 --- a/project_edit.php +++ b/project_edit.php @@ -31,11 +31,15 @@ import('ttProjectHelper'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_projects') || (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode)) { +// Access checks. +if (!ttAccessAllowed('manage_projects')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $cl_project_id = (int)$request->getParameter('id'); diff --git a/projects.php b/projects.php index ed0103a4e..5315c4f70 100644 --- a/projects.php +++ b/projects.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('track_own_time') || (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode)) { +// Access checks. +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} if($user->canManageTeam()) { $active_projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/quotas.php b/quotas.php index 19e70e505..c921fba4c 100644 --- a/quotas.php +++ b/quotas.php @@ -32,11 +32,15 @@ import('ttTeamHelper'); import('ttTimeHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('mq')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('mq')) { + header('Location: feature_disabled.php'); + exit(); +} // Start and end fallback values for the Year dropdown. $yearStart = 2015; diff --git a/report.php b/report.php index 190dff8ee..c59f6b5e3 100644 --- a/report.php +++ b/report.php @@ -33,7 +33,7 @@ import('ttTeamHelper'); // Access check. -if (!ttAccessAllowed('view_own_reports')) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { header('Location: access_denied.php'); exit(); } diff --git a/report_send.php b/report_send.php index b420b3aca..d7c031fd7 100644 --- a/report_send.php +++ b/report_send.php @@ -33,7 +33,7 @@ import('ttReportHelper'); // Access check. -if (!ttAccessAllowed('view_own_reports')) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { header('Location: access_denied.php'); exit(); } diff --git a/reports.php b/reports.php index 390c85c68..3a7367e77 100644 --- a/reports.php +++ b/reports.php @@ -37,7 +37,7 @@ import('ttClientHelper'); // Access check. -if (!ttAccessAllowed('view_own_reports')) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { header('Location: access_denied.php'); exit(); } diff --git a/role_edit.php b/role_edit.php index 3eb7696b0..f5f3762b3 100644 --- a/role_edit.php +++ b/role_edit.php @@ -32,7 +32,7 @@ import('ttTaskHelper'); // TODO: remove this? import('ttRoleHelper'); -// Access check. +// Access checks. if (!ttAccessAllowed('manage_roles')) { header('Location: access_denied.php'); exit(); @@ -43,6 +43,7 @@ header('Location: access_denied.php'); exit(); } + $assigned_rights = explode(',', $role['rights']); $available_rights = array_diff($user->rights, $assigned_rights); diff --git a/swap_roles.php b/swap_roles.php index 09178cd94..59a726c5b 100644 --- a/swap_roles.php +++ b/swap_roles.php @@ -30,20 +30,23 @@ import('form.Form'); import('ttUserHelper'); -// Access check. +// Access checks. if (!ttAccessAllowed('swap_roles')) { header('Location: access_denied.php'); exit(); } - -$users = ttTeamHelper::getUsersForSwap(); +$users_for_swap = ttTeamHelper::getUsersForSwap(); +if (!is_array($users_for_swap) || sizeof($users_for_swap) == 0) { + header('Location: access_denied.php'); + exit(); +} if ($request->isPost()) { $cl_id = $request->getParameter('swap_with'); } $form = new Form('swapForm'); -$form->addInput(array('type'=>'combobox','name'=>'swap_with','style'=>'width: 250px;','data'=>$users,'datakeys'=>array('id','name'))); +$form->addInput(array('type'=>'combobox','name'=>'swap_with','style'=>'width: 250px;','data'=>$users_for_swap,'datakeys'=>array('id','name'))); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); diff --git a/user_edit.php b/user_edit.php index 531e84242..75d89e506 100644 --- a/user_edit.php +++ b/user_edit.php @@ -222,11 +222,19 @@ function render(&$table, $value, $row, $column, $selected = false) { } } // isPost +$can_swap = false; +if ($user->id == $user_id && $user->can('swap_roles')) { + $users_for_swap = ttTeamHelper::getUsersForSwap(); + if (is_array($users_for_swap) && sizeof($users_for_swap) > 0) + $can_swap = true; +} + $rates = ttProjectHelper::getRates($user_id); $smarty->assign('rates', $rates); $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('active_roles', $active_roles); +$smarty->assign('can_swap', $can_swap); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); $smarty->assign('user_id', $user_id); From a8a4278a6a87c600835890a10c774dfdc58e930a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 19:52:42 +0000 Subject: [PATCH 0039/1848] More improvements to access checks. --- WEB-INF/templates/footer.tpl | 2 +- task_add.php | 8 ++++++-- task_delete.php | 8 ++++++-- task_edit.php | 8 ++++++-- tasks.php | 8 ++++++-- time.php | 2 +- time_delete.php | 2 +- time_edit.php | 2 +- tofile.php | 2 +- topdf.php | 2 +- users.php | 2 +- week.php | 8 ++++++-- week_view.php | 8 ++++++-- 13 files changed, 43 insertions(+), 19 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b99c720bf..a4a020e71 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.17.69.4156 | Copyright © Anuko | +  Anuko Time Tracker 1.17.69.4157 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index 15bf3fe27..6b09881d8 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -108,7 +108,7 @@ function handleClientControl() { {if $user->id == $user_id}
{$i18n.form.users.role}:{$user->role_name} {if $user->can('swap_roles')}{$i18n.form.profile.swap_roles}{/if}{$user->role_name} {if $can_swap}{$i18n.form.profile.swap_roles}{/if}
-
 Anuko Time Tracker 1.17.69.4157 | Copyright © Anuko | +  Anuko Time Tracker 1.17.69.4158 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/task_add.php b/task_add.php index 12c54464d..a5149e840 100644 --- a/task_add.php +++ b/task_add.php @@ -32,11 +32,15 @@ import('ttTeamHelper'); import('ttTaskHelper'); -// Access check. -if (!ttAccessAllowed('manage_tasks') || MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +// Access checks. +if (!ttAccessAllowed('manage_tasks')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/task_delete.php b/task_delete.php index d72220d2f..0e9f40cfe 100644 --- a/task_delete.php +++ b/task_delete.php @@ -30,11 +30,15 @@ import('ttTaskHelper'); import('form.Form'); -// Access check. -if (!ttAccessAllowed('manage_tasks') || MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +// Access checks. +if (!ttAccessAllowed('manage_tasks')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $cl_task_id = (int)$request->getParameter('id'); $task = ttTaskHelper::get($cl_task_id); diff --git a/task_edit.php b/task_edit.php index 36e717d7e..bba89bebd 100644 --- a/task_edit.php +++ b/task_edit.php @@ -31,11 +31,15 @@ import('ttTeamHelper'); import('ttTaskHelper'); -// Access check. -if (!ttAccessAllowed('manage_tasks') || MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +// Access checks. +if (!ttAccessAllowed('manage_tasks')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $cl_task_id = (int)$request->getParameter('id'); $projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/tasks.php b/tasks.php index 5bc3fd459..5505e6ddd 100644 --- a/tasks.php +++ b/tasks.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_tasks') || MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +// Access checks. +if (!ttAccessAllowed('manage_tasks')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $smarty->assign('active_tasks', ttTeamHelper::getActiveTasks($user->team_id)); $smarty->assign('inactive_tasks', ttTeamHelper::getInactiveTasks($user->team_id)); diff --git a/time.php b/time.php index 270a8aaef..1c29aa8f6 100644 --- a/time.php +++ b/time.php @@ -42,7 +42,7 @@ // } // Access check. -if (!ttAccessAllowed('track_own_time')) { +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } diff --git a/time_delete.php b/time_delete.php index 2ad3ea412..ec3c677cc 100644 --- a/time_delete.php +++ b/time_delete.php @@ -33,7 +33,7 @@ import('DateAndTime'); // Access check. -if (!ttAccessAllowed('track_own_time')) { +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } diff --git a/time_edit.php b/time_edit.php index dd3edde13..c14928f56 100644 --- a/time_edit.php +++ b/time_edit.php @@ -35,7 +35,7 @@ import('DateAndTime'); // Access check. -if (!ttAccessAllowed('track_own_time')) { +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } diff --git a/tofile.php b/tofile.php index 67c5b31ce..abd1f278b 100644 --- a/tofile.php +++ b/tofile.php @@ -32,7 +32,7 @@ import('ttReportHelper'); // Access check. -if (!ttAccessAllowed('view_own_reports')) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { header('Location: access_denied.php'); exit(); } diff --git a/topdf.php b/topdf.php index b8f6684c4..3177d1559 100644 --- a/topdf.php +++ b/topdf.php @@ -36,7 +36,7 @@ import('ttReportHelper'); // Access check. -if (!ttAccessAllowed('view_own_reports')) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { header('Location: access_denied.php'); exit(); } diff --git a/users.php b/users.php index 860218638..35fd4168c 100644 --- a/users.php +++ b/users.php @@ -33,7 +33,7 @@ import('ttRoleHelper'); // Access check. -if (!ttAccessAllowed('view_users')) { +if (!(ttAccessAllowed('view_users') || ttAccessAllowed('manage_users'))) { header('Location: access_denied.php'); exit(); } diff --git a/week.php b/week.php index e26aa1192..f1dc78893 100644 --- a/week.php +++ b/week.php @@ -38,11 +38,15 @@ import('ttTimeHelper'); import('DateAndTime'); -// Access check. -if (!ttAccessAllowed('track_own_time') || !$user->isPluginEnabled('wv')) { +// Access checks. +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('wv')) { + header('Location: feature_disabled.php'); + exit(); +} // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); diff --git a/week_view.php b/week_view.php index b273d2789..e5ec14796 100644 --- a/week_view.php +++ b/week_view.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_advanced_settings') || !$user->isPluginEnabled('wv')) { +// Access checks. +if (!ttAccessAllowed('manage_advanced_settings')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('wv')) { + header('Location: feature_disabled.php'); + exit(); +} if ($request->isPost()) { $cl_week_note = $request->getParameter('week_note'); From dd2ba64b1b4aaddacec2b9f6763c0ed7a35efc3b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 21:08:52 +0000 Subject: [PATCH 0040/1848] Finished improving access checks by providing separate error msg for disabled features. --- WEB-INF/templates/footer.tpl | 2 +- mobile/client_add.php | 8 ++++++-- mobile/client_delete.php | 8 ++++++-- mobile/client_edit.php | 8 ++++++-- mobile/clients.php | 8 ++++++-- mobile/expense_delete.php | 8 ++++++-- mobile/expense_edit.php | 8 ++++++-- mobile/index.php | 2 +- mobile/project_add.php | 8 ++++++-- mobile/project_delete.php | 8 ++++++-- mobile/project_edit.php | 8 ++++++-- mobile/projects.php | 8 ++++++-- mobile/task_add.php | 8 ++++++-- mobile/task_delete.php | 8 ++++++-- mobile/task_edit.php | 8 ++++++-- mobile/tasks.php | 8 ++++++-- mobile/users.php | 2 +- 17 files changed, 87 insertions(+), 31 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a4a020e71..4eb4fd678 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- @@ -95,33 +97,35 @@
 Anuko Time Tracker 1.17.69.4158 | Copyright © Anuko | +  Anuko Time Tracker 1.17.70.4159 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/client_add.php b/mobile/client_add.php index 134819bb1..fc57853d7 100644 --- a/mobile/client_add.php +++ b/mobile/client_add.php @@ -31,11 +31,15 @@ import('ttClientHelper'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_clients') || !$user->isPluginEnabled('cl')) { +// Access checks. +if (!ttAccessAllowed('manage_clients')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cl')) { + header('Location: feature_disabled.php'); + exit(); +} $projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/mobile/client_delete.php b/mobile/client_delete.php index e23cd026b..154d89308 100644 --- a/mobile/client_delete.php +++ b/mobile/client_delete.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttClientHelper'); -// Access check. -if (!ttAccessAllowed('manage_clients') || !$user->isPluginEnabled('cl')) { +// Access checks. +if (!ttAccessAllowed('manage_clients')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cl')) { + header('Location: feature_disabled.php'); + exit(); +} $id = (int)$request->getParameter('id'); $client = ttClientHelper::getClient($id); diff --git a/mobile/client_edit.php b/mobile/client_edit.php index e4bc9b22b..eb8592290 100644 --- a/mobile/client_edit.php +++ b/mobile/client_edit.php @@ -31,11 +31,15 @@ import('ttClientHelper'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_clients') || !$user->isPluginEnabled('cl')) { +// Access checks. +if (!ttAccessAllowed('manage_clients')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cl')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_id = (int) $request->getParameter('id'); diff --git a/mobile/clients.php b/mobile/clients.php index d1a49f1e1..43e6848ae 100644 --- a/mobile/clients.php +++ b/mobile/clients.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_clients') || !$user->isPluginEnabled('cl')) { +// Access checks. +if (!ttAccessAllowed('manage_clients')) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('cl')) { + header('Location: feature_disabled.php'); + exit(); +} $smarty->assign('active_clients', ttTeamHelper::getActiveClients($user->team_id, true)); $smarty->assign('inactive_clients', ttTeamHelper::getInactiveClients($user->team_id, true)); diff --git a/mobile/expense_delete.php b/mobile/expense_delete.php index 48051b426..cca61b7c1 100644 --- a/mobile/expense_delete.php +++ b/mobile/expense_delete.php @@ -31,11 +31,15 @@ import('DateAndTime'); import('ttExpenseHelper'); -// Access check. -if (!ttAccessAllowed('track_own_expenses') || !$user->isPluginEnabled('ex')) { +// Access checks. +if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses'))) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ex')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_id = $request->getParameter('id'); $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index 7107e7851..8da55a1eb 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -32,11 +32,15 @@ import('DateAndTime'); import('ttExpenseHelper'); -// Access check. -if (!ttAccessAllowed('track_own_expenses') || !$user->isPluginEnabled('ex')) { +// Access checks. +if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses'))) { header('Location: access_denied.php'); exit(); } +if (!$user->isPluginEnabled('ex')) { + header('Location: feature_disabled.php'); + exit(); +} $cl_id = $request->getParameter('id'); diff --git a/mobile/index.php b/mobile/index.php index 1c7cf231c..9b2ed530f 100644 --- a/mobile/index.php +++ b/mobile/index.php @@ -30,7 +30,7 @@ // Redirects for admin and client roles. if ($auth->isAuthenticated()) { - if ($user->isAdmin()) { + if ($user->can('administer_site')) { header('Location: ../admin_teams.php'); exit(); } elseif ($user->isClient()) { diff --git a/mobile/project_add.php b/mobile/project_add.php index bbaa8fa75..a9495d715 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -31,11 +31,15 @@ import('ttProjectHelper'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_projects') || (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode)) { +// Access checks. +if (!ttAccessAllowed('manage_projects')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $users = ttTeamHelper::getActiveUsers(); foreach ($users as $user_item) diff --git a/mobile/project_delete.php b/mobile/project_delete.php index d2b0b32b8..c8753b844 100644 --- a/mobile/project_delete.php +++ b/mobile/project_delete.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttProjectHelper'); -// Access check. -if (!ttAccessAllowed('manage_projects') || (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode)) { +// Access checks. +if (!ttAccessAllowed('manage_projects')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $cl_project_id = (int)$request->getParameter('id'); $project = ttProjectHelper::get($cl_project_id); diff --git a/mobile/project_edit.php b/mobile/project_edit.php index 31ea65da4..74454ec41 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -31,11 +31,15 @@ import('ttProjectHelper'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_projects') || (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode)) { +// Access checks. +if (!ttAccessAllowed('manage_projects')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $cl_project_id = (int)$request->getParameter('id'); diff --git a/mobile/projects.php b/mobile/projects.php index 5dec7ee36..93261d425 100644 --- a/mobile/projects.php +++ b/mobile/projects.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('track_own_time') || (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode)) { +// Access checks. +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} if($user->canManageTeam()) { $active_projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/mobile/task_add.php b/mobile/task_add.php index 0c405b6fa..a976ac5c9 100644 --- a/mobile/task_add.php +++ b/mobile/task_add.php @@ -32,11 +32,15 @@ import('ttTeamHelper'); import('ttTaskHelper'); -// Access check. -if (!ttAccessAllowed('manage_tasks') || MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +// Access checks. +if (!ttAccessAllowed('manage_tasks')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/mobile/task_delete.php b/mobile/task_delete.php index df3c964a5..1146a2ac2 100644 --- a/mobile/task_delete.php +++ b/mobile/task_delete.php @@ -30,11 +30,15 @@ import('ttTaskHelper'); import('form.Form'); -// Access check. -if (!ttAccessAllowed('manage_tasks') || MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +// Access checks. +if (!ttAccessAllowed('manage_tasks')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $cl_task_id = (int)$request->getParameter('id'); $task = ttTaskHelper::get($cl_task_id); diff --git a/mobile/task_edit.php b/mobile/task_edit.php index 2ba2cc554..346899dce 100644 --- a/mobile/task_edit.php +++ b/mobile/task_edit.php @@ -31,11 +31,15 @@ import('ttTeamHelper'); import('ttTaskHelper'); -// Access check. -if (!ttAccessAllowed('manage_tasks') || MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +// Access checks. +if (!ttAccessAllowed('manage_tasks')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $cl_task_id = (int)$request->getParameter('id'); $projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/mobile/tasks.php b/mobile/tasks.php index 25575eb65..edb57089e 100644 --- a/mobile/tasks.php +++ b/mobile/tasks.php @@ -30,11 +30,15 @@ import('form.Form'); import('ttTeamHelper'); -// Access check. -if (!ttAccessAllowed('manage_tasks') || MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +// Access checks. +if (!ttAccessAllowed('manage_tasks')) { header('Location: access_denied.php'); exit(); } +if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { + header('Location: feature_disabled.php'); + exit(); +} $smarty->assign('active_tasks', ttTeamHelper::getActiveTasks($user->team_id)); $smarty->assign('inactive_tasks', ttTeamHelper::getInactiveTasks($user->team_id)); diff --git a/mobile/users.php b/mobile/users.php index 131d2b44c..67654376e 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -32,7 +32,7 @@ import('ttTimeHelper'); // Access check. -if (!ttAccessAllowed('view_users')) { +if (!(ttAccessAllowed('view_users') || ttAccessAllowed('manage_users'))) { header('Location: access_denied.php'); exit(); } From e02d7592b0556895e35f4d028939197c132f6b09 Mon Sep 17 00:00:00 2001 From: bonnedav Date: Sat, 24 Mar 2018 15:39:39 -0600 Subject: [PATCH 0041/1848] Refactor header to use user rights. (#57) * Refactor header to use user rights. * use "manage_own_settings" for porfile link --- WEB-INF/templates/header.tpl | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 1d6622165..9ed099a63 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -83,7 +83,9 @@
  {$i18n.menu.logout} · - {$i18n.menu.profile} · + {if $user->can('manage_own_settings')} + {$i18n.menu.profile} · + {/if} {$i18n.menu.forum} · {$i18n.menu.help}
From 31c09561b78ef5a9e40f8ff5b18e068f6ff881bc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 22:00:19 +0000 Subject: [PATCH 0042/1848] Some fixes for desktop header.tpl. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4eb4fd678..aa964b0a4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
  - {if !$user->isClient()} + {if $user->can('track_time') || $user->can('track_own_time')} {$i18n.menu.time} {/if} - {if $user->isPluginEnabled('ex') && !$user->isClient()} + {if $user->isPluginEnabled('ex') && ($user->can('track_expenses') || $user->can('track_own_expenses'))} · {$i18n.menu.expenses} {/if} - {if !$user->isClient()}· {/if}{$i18n.menu.reports} + {if $user->can('view_invoices') || $user->can('view_own_reports')} + · {$i18n.menu.reports} + {/if} {if $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->can('view_own_invoices'))} · {$i18n.title.invoices} {/if} - {if ($user->isPluginEnabled('ch') && !$user->isClient()) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode + {if ($user->isPluginEnabled('ch') && ($user->can('view_charts') || $user->can('view_own_charts'))) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode || $user->isPluginEnabled('cl'))} · {$i18n.menu.charts} {/if} - {if !$user->isClient() && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $user->can('manage_projects') && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} · {$i18n.menu.projects} {/if} {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode) && $user->can('manage_tasks')} · {$i18n.menu.tasks} {/if} - {if !$user->isClient()} + {if $user->can('view_users') || $user->can('manage_users')} · {$i18n.menu.users} {/if} {if $user->isPluginEnabled('cl') && $user->can('manage_clients')} · {$i18n.menu.clients} {/if} - {if $user->isManager()} + {if $user->can('export_data')} · {$i18n.menu.export} {/if}
-
 Anuko Time Tracker 1.17.70.4159 | Copyright © Anuko | +  Anuko Time Tracker 1.17.70.4160 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 9ed099a63..f33bc6b73 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -54,7 +54,7 @@ {if $authenticated} - {if $user->isAdmin()} + {if $user->can('administer_site')} @@ -83,9 +83,9 @@ @@ -97,23 +97,23 @@
  {$i18n.menu.logout} · - {if $user->can('manage_own_settings')} - {$i18n.menu.profile} · - {/if} + {if $user->can('manage_own_settings')} + {$i18n.menu.profile} · + {/if} {$i18n.menu.forum} · {$i18n.menu.help}
  - {if $user->can('track_time') || $user->can('track_own_time')} + {if $user->can('track_own_time') || $user->can('track_time')} {$i18n.menu.time} {/if} - {if $user->isPluginEnabled('ex') && ($user->can('track_expenses') || $user->can('track_own_expenses'))} + {if $user->isPluginEnabled('ex') && ($user->can('track_own_expenses') || $user->can('track_expenses'))} · {$i18n.menu.expenses} {/if} - {if $user->can('view_invoices') || $user->can('view_own_reports')} + {if $user->can('view_own_reports') || $user->can('view_reports')} · {$i18n.menu.reports} {/if} - {if $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->can('view_own_invoices'))} + {if $user->isPluginEnabled('iv') && ($user->can('view_own_invoices') || $user->can('manage_invoices'))} · {$i18n.title.invoices} {/if} - {if ($user->isPluginEnabled('ch') && ($user->can('view_charts') || $user->can('view_own_charts'))) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode + {if ($user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts'))) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode || $user->isPluginEnabled('cl'))} · {$i18n.menu.charts} {/if} - {if $user->can('manage_projects') && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if ($user->can('track_own_time') || $user->can('track_time')) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} · {$i18n.menu.projects} {/if} {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode) && $user->can('manage_tasks')} From e60508fb73602f118d17c06a9103532da05306c5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 22:05:41 +0000 Subject: [PATCH 0043/1848] Fixed projects menu for users with manage_projects right. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index aa964b0a4..c2bbeb8b7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.70.4160 | Copyright © Anuko | +  Anuko Time Tracker 1.17.70.4161 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index f33bc6b73..97ee53dae 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -113,7 +113,7 @@ || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode || $user->isPluginEnabled('cl'))} · {$i18n.menu.charts} {/if} - {if ($user->can('track_own_time') || $user->can('track_time')) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if ($user->can('manage_projects') || $user->can('track_own_time') || $user->can('track_time')) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} · {$i18n.menu.projects} {/if} {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode) && $user->can('manage_tasks')} From c7f2e7126f6f508487a23d0770ca4f8543278379 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Mar 2018 22:16:05 +0000 Subject: [PATCH 0044/1848] Refactored mobile header to use access rights. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/header.tpl | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c2bbeb8b7..5f16dbdf0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.70.4161 | Copyright © Anuko | +  Anuko Time Tracker 1.17.70.4162 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index 87d2c4012..507a07e02 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -55,7 +55,7 @@ {if $authenticated} - {if $user->isAdmin()} + {if $user->can('administer_site')} @@ -73,22 +73,22 @@
From 68a5cc5aff88d6144b6db95f7d01315c15e2ebda Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Mar 2018 16:22:57 +0000 Subject: [PATCH 0045/1848] Fixed the charts tab to work better for lower roles only. --- WEB-INF/lib/ttUser.class.php | 54 ++++++++++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/users.tpl | 12 ++++---- charts.php | 10 +++++-- 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 0a1048884..95edd6e48 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -241,4 +241,58 @@ function canOverridePunchMode() return true; } + + // getUsers obtains users in a group, as specififed by options. + function getUsers($options) { + + $mdb2 = getConnection(); + + $skipClients = !isset($options['include_clients']); + $includeSelf = isset($options['include_self']); + + $select_part = 'select u.id, u.name'; + if (!isset($options['include_clients'])) $select_part .= ', r.rights'; + + $from_part = ' from tt_users u'; + + $left_joins = null; + if (isset($options['max_rank']) || $skipClients) + $left_joins .= ' left join tt_roles r on (u.role_id = r.id)'; + + $where_part = " where u.team_id = $this->team_id"; + if (isset($options['status'])) $where_part .= ' and u.status = '.(int)$options['status']; + if ($includeSelf) { + $where_part .= " and (u.id = $this->id || r.rank <= ".(int)$options['max_rank'].')'; + } else { + if (isset($options['max_rank'])) $where_part .= ' and r.rank <= '.(int)$options['max_rank']; + } + + $sql = $select_part.$from_part.$left_joins.$where_part; + $res = $mdb2->query($sql); + $user_list = array(); + if (is_a($res, 'PEAR_Error')) + return false; + + while ($val = $res->fetchRow()) { + if ($skipClients) { + $isClient = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have track_own_time right. + if ($isClient) + continue; // Skip adding clients. + } + $user_list[] = $val; + } + + if (isset($options['self_first'])) { + // Put own entry at the front. + $cnt = count($user_list); + for($i = 0; $i < $cnt; $i++) { + if ($user_list[$i]['id'] == $this->id) { + $self = $user_list[$i]; // Found self. + array_unshift($user_list, $self); // Put own entry at the front. + array_splice($user_list, $i+1, 1); // Remove duplicate. + } + } + } + return $user_list; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5f16dbdf0..a470afaac 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
  - {if !$user->isClient()} + {if $user->can('track_own_time') || $user->can('track_time')} {$i18n.menu.time} {/if} - {if $user->isPluginEnabled('ex') && !$user->isClient()} + {if $user->isPluginEnabled('ex') && ($user->can('track_own_expenses') || $user->can('track_expenses'))} · {$i18n.menu.expenses} {/if} - {if !$user->isClient() && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if ($user->can('manage_projects') || $user->can('track_own_time') || $user->can('track_time')) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} · {$i18n.menu.projects} {/if} - {if $user->canManageTeam() && ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $user->can('manage_tasks') && $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode} · {$i18n.menu.tasks} {/if} - {if !$user->isClient()} + {if $user->can('view_users') || $user->can('manage_users')} · {$i18n.menu.users} {/if} - {if $user->canManageTeam() && $user->isPluginEnabled('cl')} + {if $user->isPluginEnabled('cl') && $user->can('manage_clients')} · {$i18n.menu.clients} {/if}
- {/if} - - - + + + @@ -52,9 +52,9 @@
 Anuko Time Tracker 1.17.70.4162 | Copyright © Anuko | +  Anuko Time Tracker 1.17.71.4163 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/users.tpl b/WEB-INF/templates/users.tpl index f47435322..008413391 100644 --- a/WEB-INF/templates/users.tpl +++ b/WEB-INF/templates/users.tpl @@ -11,9 +11,9 @@
{$i18n.form.users.active_users}
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role} {$i18n.label.edit} {$i18n.label.delete}
- - - + + + diff --git a/charts.php b/charts.php index f2b01f16f..a44c9926d 100644 --- a/charts.php +++ b/charts.php @@ -38,7 +38,7 @@ import('ttTeamHelper'); // Access checks. -if (!ttAccessAllowed('view_own_charts')) { +if (!(ttAccessAllowed('view_own_charts') || ttAccessAllowed('view_charts'))) { header('Location: access_denied.php'); exit(); } @@ -128,8 +128,12 @@ // User dropdown. Changes the user "on behalf" of whom we are working. if ($user->can('view_charts')) { - $user_list = ttTeamHelper::getActiveUsers(array('putSelfFirst'=>true)); - if (count($user_list) > 1) { + if ($user->can('view_own_charts')) + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_self'=>true,'self_first'=>true); + else + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1); + $user_list = $user->getUsers($options); + if (count($user_list) >= 1) { $chart_form->addInput(array('type'=>'combobox', 'onchange'=>'this.form.submit();', 'name'=>'onBehalfUser', From 2ff04a2baeaa449ab30b822e2bb52ff792776753 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Mar 2018 20:25:40 +0000 Subject: [PATCH 0046/1848] A bit better job with access checks for charts. --- WEB-INF/lib/ttUser.class.php | 33 +++++++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- charts.php | 8 ++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 95edd6e48..85b26d517 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -295,4 +295,37 @@ function getUsers($options) { } return $user_list; } + + // checkBehalfId checks whether behalf_id is appropriate. + // On behalf user must be active and have lower rank. + function checkBehalfId() { + $options = array('status'=>ACTIVE,'max_rank'=>$this->rank-1); + $users = $this->getUsers($options); + foreach($users as $one_user) { + if ($one_user['id'] == $this->behalf_id) + return true; + } + + return false; + } + + // adjustBehalfId attempts to adjust behalf_id and behalf_name to a first found + // aapropriate user. + // + // Needed for situations when use does not have do_own_something right. + // Example: has view_charts but does not have view_own_charts. + // In this case we still allow access to charts, but set behalf_id to someone else. + function adjustBehalfId() { + $options = array('status'=>ACTIVE,'max_rank'=>$this->rank-1); + $users = $this->getUsers($options); + foreach($users as $one_user) { + // Fake loop to access first element. + $this->behalf_id = $one_user['id']; + $this->behalf_name = $one_user['name']; + $_SESSION['behalf_id'] = $this->behalf_id; + $_SESSION['behalf_name'] = $this->behalf_name; + return true; + } + return false; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a470afaac..d003b9bd7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.users.inactive_users}
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role} {$i18n.label.edit} {$i18n.label.delete}
-
 Anuko Time Tracker 1.17.71.4163 | Copyright © Anuko | +  Anuko Time Tracker 1.17.71.4164 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/charts.php b/charts.php index a44c9926d..d6707038f 100644 --- a/charts.php +++ b/charts.php @@ -46,6 +46,14 @@ header('Location: feature_disabled.php'); exit(); } +if ($user->behalf_id && (!$user->can('view_charts') || !$user->checkBehalfId())) { + header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. + exit(); +} +if (!$user->behalf_id && !$user->can('view_own_charts') && !$user->adjustBehalfId()) { + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to view on behalf. + exit(); +} // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); From 5f1b7a5bed3563565e28a5bf851298d3ed7df8c7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Mar 2018 20:28:44 +0000 Subject: [PATCH 0047/1848] Fixed typos. --- WEB-INF/lib/ttUser.class.php | 5 ++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 85b26d517..3461ac5bf 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -305,14 +305,13 @@ function checkBehalfId() { if ($one_user['id'] == $this->behalf_id) return true; } - return false; } // adjustBehalfId attempts to adjust behalf_id and behalf_name to a first found - // aapropriate user. + // apropriate user. // - // Needed for situations when use does not have do_own_something right. + // Needed for situations when user does not have do_own_something right. // Example: has view_charts but does not have view_own_charts. // In this case we still allow access to charts, but set behalf_id to someone else. function adjustBehalfId() { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d003b9bd7..7a02ae7b0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.71.4164 | Copyright © Anuko | +  Anuko Time Tracker 1.17.71.4165 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e7b081c97f2f2cfa69ca8df99afdeb8506eff726 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Mar 2018 20:43:45 +0000 Subject: [PATCH 0048/1848] Improved time page with a better filter for on behalf users - lower roles only. --- WEB-INF/templates/footer.tpl | 2 +- time.php | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7a02ae7b0..d1cf3d01b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.71.4165 | Copyright © Anuko | +  Anuko Time Tracker 1.17.71.4166 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/time.php b/time.php index 1c29aa8f6..18979fe22 100644 --- a/time.php +++ b/time.php @@ -41,11 +41,19 @@ // die ("Your browser's cookie functionality is turned off. Please turn it on."); // } -// Access check. +// Access checks. if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } +if ($user->behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { + header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. + exit(); +} +if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to view on behalf. + exit(); +} // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -103,9 +111,13 @@ // Elements of timeRecordForm. $form = new Form('timeRecordForm'); -if ($user->canManageTeam()) { - $user_list = ttTeamHelper::getActiveUsers(array('putSelfFirst'=>true)); - if (count($user_list) > 1) { +if ($user->can('track_time')) { + if ($user->can('track_own_time')) + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_self'=>true,'self_first'=>true); + else + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1); + $user_list = $user->getUsers($options); + if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'this.form.submit();', 'name'=>'onBehalfUser', From e560c531255da8d1fa40295c58cc5c4b1bb4e9d3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Mar 2018 21:32:25 +0000 Subject: [PATCH 0049/1848] Improved population of on behalf dropdowns on week view and expenses pages. --- WEB-INF/templates/footer.tpl | 2 +- expenses.php | 18 +++++++++++++++--- mobile/expenses.php | 18 +++++++++++++++--- time.php | 2 +- week.php | 16 ++++++++++++++-- 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d1cf3d01b..2be4b9359 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.71.4166 | Copyright © Anuko | +  Anuko Time Tracker 1.17.71.4167 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expenses.php b/expenses.php index 00b43179c..7291414aa 100644 --- a/expenses.php +++ b/expenses.php @@ -42,6 +42,14 @@ header('Location: feature_disabled.php'); exit(); } +if ($user->behalf_id && (!$user->can('track_expenses') || !$user->checkBehalfId())) { + header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. + exit(); +} +if (!$user->behalf_id && !$user->can('track_own_expenses') && !$user->adjustBehalfId()) { + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. + exit(); +} // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -64,9 +72,13 @@ // Elements of expensesForm. $form = new Form('expensesForm'); -if ($user->canManageTeam()) { - $user_list = ttTeamHelper::getActiveUsers(array('putSelfFirst'=>true)); - if (count($user_list) > 1) { +if ($user->can('track_expenses')) { + if ($user->can('track_own_expenses')) + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_self'=>true,'self_first'=>true); + else + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1); + $user_list = $user->getUsers($options); + if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'this.form.submit();', 'name'=>'onBehalfUser', diff --git a/mobile/expenses.php b/mobile/expenses.php index f0fc5c304..1cd39c04c 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -42,6 +42,14 @@ header('Location: feature_disabled.php'); exit(); } +if ($user->behalf_id && (!$user->can('track_expenses') || !$user->checkBehalfId())) { + header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. + exit(); +} +if (!$user->behalf_id && !$user->can('track_own_expenses') && !$user->adjustBehalfId()) { + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. + exit(); +} // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -68,9 +76,13 @@ // Elements of expensesForm. $form = new Form('expensesForm'); -if ($user->canManageTeam()) { - $user_list = ttTeamHelper::getActiveUsers(array('putSelfFirst'=>true)); - if (count($user_list) > 1) { +if ($user->can('track_expenses')) { + if ($user->can('track_own_expenses')) + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_self'=>true,'self_first'=>true); + else + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1); + $user_list = $user->getUsers($options); + if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'this.form.submit();', 'name'=>'onBehalfUser', diff --git a/time.php b/time.php index 18979fe22..98a383fdd 100644 --- a/time.php +++ b/time.php @@ -51,7 +51,7 @@ exit(); } if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to view on behalf. + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. exit(); } diff --git a/week.php b/week.php index f1dc78893..741a2bb4e 100644 --- a/week.php +++ b/week.php @@ -47,6 +47,14 @@ header('Location: feature_disabled.php'); exit(); } +if ($user->behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { + header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. + exit(); +} +if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. + exit(); +} // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -203,8 +211,12 @@ function render(&$table, $value, $row, $column, $selected = false) { $form = new Form('weekTimeForm'); if ($user->can('track_time')) { - $user_list = ttTeamHelper::getActiveUsers(array('putSelfFirst'=>true)); - if (count($user_list) > 1) { + if ($user->can('track_own_time')) + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_self'=>true,'self_first'=>true); + else + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1); + $user_list = $user->getUsers($options); + if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'this.form.submit();', 'name'=>'onBehalfUser', From 0a7886b373c91ef0c2c41307f81177d043c807be Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Mar 2018 22:31:31 +0000 Subject: [PATCH 0050/1848] Access check improvements for time and expense edits and deletes. --- WEB-INF/templates/footer.tpl | 2 +- expense_delete.php | 12 +++++++----- expense_edit.php | 12 ++++++------ mobile/expense_delete.php | 12 +++++++----- mobile/expense_edit.php | 12 ++++++------ mobile/time_delete.php | 14 ++++++++------ mobile/time_edit.php | 16 ++++++++-------- time_delete.php | 14 ++++++++------ time_edit.php | 18 +++++++++--------- 9 files changed, 60 insertions(+), 52 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2be4b9359..658d120a3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.71.4167 | Copyright © Anuko | +  Anuko Time Tracker 1.17.72.4168 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expense_delete.php b/expense_delete.php index 1f7fbb34b..49bb8ac1b 100644 --- a/expense_delete.php +++ b/expense_delete.php @@ -40,12 +40,14 @@ header('Location: feature_disabled.php'); exit(); } - -$cl_id = $request->getParameter('id'); +$cl_id = (int)$request->getParameter('id'); +// Get the expense item we are deleting. $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); - -// Prohibit deleting invoiced records. -if ($expense_item['invoice_id']) die($i18n->get('error.sys')); +if (!$expense_item || $expense_item['invoice_id']) { + // Prohibit deleting not ours or invoiced items. + header('Location: access_denied.php'); + exit(); +} if ($request->isPost()) { if ($request->getParameter('delete_button')) { // Delete button pressed. diff --git a/expense_edit.php b/expense_edit.php index 15cfcfaf5..99503b06b 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -41,14 +41,14 @@ header('Location: feature_disabled.php'); exit(); } - -$cl_id = $request->getParameter('id'); - +$cl_id = (int)$request->getParameter('id'); // Get the expense item we are editing. $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); - -// Prohibit editing invoiced items. -if ($expense_item['invoice_id']) die($i18n->get('error.sys')); +if (!$expense_item || $expense_item['invoice_id']) { + // Prohibit editing not ours or invoiced items. + header('Location: access_denied.php'); + exit(); +} $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); diff --git a/mobile/expense_delete.php b/mobile/expense_delete.php index cca61b7c1..a6f0989e6 100644 --- a/mobile/expense_delete.php +++ b/mobile/expense_delete.php @@ -40,12 +40,14 @@ header('Location: feature_disabled.php'); exit(); } - -$cl_id = $request->getParameter('id'); +$cl_id = (int)$request->getParameter('id'); +// Get the expense item we are deleting. $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); - -// Prohibit deleting invoiced records. -if ($expense_item['invoice_id']) die($i18n->get('error.sys')); +if (!$expense_item || $expense_item['invoice_id']) { + // Prohibit deleting not ours or invoiced items. + header('Location: access_denied.php'); + exit(); +} if ($request->isPost()) { if ($request->getParameter('delete_button')) { // Delete button pressed. diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index 8da55a1eb..1611378d9 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -41,14 +41,14 @@ header('Location: feature_disabled.php'); exit(); } - -$cl_id = $request->getParameter('id'); - +$cl_id = (int)$request->getParameter('id'); // Get the expense item we are editing. $expense_item = ttExpenseHelper::getItem($cl_id, $user->getActiveUser()); - -// Prohibit editing invoiced items. -if ($expense_item['invoice_id']) die($i18n->get('error.sys')); +if (!$expense_item || $expense_item['invoice_id']) { + // Prohibit editing not ours or invoiced items. + header('Location: access_denied.php'); + exit(); +} $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); diff --git a/mobile/time_delete.php b/mobile/time_delete.php index 33ba61468..5d6918c59 100644 --- a/mobile/time_delete.php +++ b/mobile/time_delete.php @@ -32,17 +32,19 @@ import('ttTimeHelper'); import('DateAndTime'); -// Access check. +// Access checks. if (!ttAccessAllowed('track_own_time')) { header('Location: access_denied.php'); exit(); } - -$cl_id = $request->getParameter('id'); +$cl_id = (int)$request->getParameter('id'); +// Get the time record we are deleting. $time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); - -// Prohibit deleting invoiced records. -if ($time_rec['invoice_id']) die($i18n->get('error.sys')); +if (!$time_rec || $time_rec['invoice_id']) { + // Prohibit deleting not ours or invoiced records. + header('Location: access_denied.php'); + exit(); +} // Escape comment for presentation. $time_rec['comment'] = htmlspecialchars($time_rec['comment']); diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 683bab74f..eff9b3358 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -39,6 +39,14 @@ header('Location: access_denied.php'); exit(); } +$cl_id = (int)$request->getParameter('id'); +// Get the time record we are editing. +$time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); +if (!$time_rec || $time_rec['invoice_id']) { + // Prohibit editing not ours or invoiced records. + header('Location: access_denied.php'); + exit(); +} // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { @@ -47,14 +55,6 @@ $smarty->assign('custom_fields', $custom_fields); } -$cl_id = $request->getParameter('id'); - -// Get the time record we are editing. -$time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); - -// Prohibit editing invoiced records. -if ($time_rec['invoice_id']) die($i18n->get('error.sys')); - $item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); // Initialize variables. diff --git a/time_delete.php b/time_delete.php index ec3c677cc..060311e87 100644 --- a/time_delete.php +++ b/time_delete.php @@ -32,17 +32,19 @@ import('ttTimeHelper'); import('DateAndTime'); -// Access check. +// Access checks. if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } - -$cl_id = $request->getParameter('id'); +$cl_id = (int)$request->getParameter('id'); +// Get the time record we are deleting. $time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); - -// Prohibit deleting invoiced records. -if ($time_rec['invoice_id']) die($i18n->get('error.sys')); +if (!$time_rec || $time_rec['invoice_id']) { + // Prohibit deleting not ours or invoiced records. + header('Location: access_denied.php'); + exit(); +} // Escape comment for presentation. $time_rec['comment'] = htmlspecialchars($time_rec['comment']); diff --git a/time_edit.php b/time_edit.php index c14928f56..05db97c02 100644 --- a/time_edit.php +++ b/time_edit.php @@ -34,11 +34,19 @@ import('ttTimeHelper'); import('DateAndTime'); -// Access check. +// Access checks. if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } +$cl_id = (int)$request->getParameter('id'); +// Get the time record we are editing. +$time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); +if (!$time_rec || $time_rec['invoice_id']) { + // Prohibit editing not ours or invoiced records. + header('Location: access_denied.php'); + exit(); +} // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { @@ -47,14 +55,6 @@ $smarty->assign('custom_fields', $custom_fields); } -$cl_id = $request->getParameter('id'); - -// Get the time record we are editing. -$time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); - -// Prohibit editing invoiced records. -if ($time_rec['invoice_id']) die($i18n->get('error.sys')); - $item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); // Initialize variables. From 9f4ffc38746c7d23beb7b48ba342dd0cc8e8b19a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 00:10:07 +0000 Subject: [PATCH 0051/1848] Improved users page a bit in accordance with user rights. --- WEB-INF/lib/ttUser.class.php | 4 +++- WEB-INF/templates/footer.tpl | 2 +- users.php | 17 +++++++++++------ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 3461ac5bf..5321e74d9 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -251,12 +251,14 @@ function getUsers($options) { $includeSelf = isset($options['include_self']); $select_part = 'select u.id, u.name'; + if (isset($options['include_login'])) $select_part .= ', u.login'; if (!isset($options['include_clients'])) $select_part .= ', r.rights'; + if (isset($options['include_role'])) $select_part .= ', r.name as role_name, r.rank'; $from_part = ' from tt_users u'; $left_joins = null; - if (isset($options['max_rank']) || $skipClients) + if (isset($options['max_rank']) || $skipClients || isset($options['include_role'])) $left_joins .= ' left join tt_roles r on (u.role_id = r.id)'; $where_part = " where u.team_id = $this->team_id"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 658d120a3..e9e28a35e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.72.4168 | Copyright © Anuko | +  Anuko Time Tracker 1.17.72.4169 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/users.php b/users.php index 35fd4168c..f5335455f 100644 --- a/users.php +++ b/users.php @@ -38,11 +38,17 @@ exit(); } -// Get users. -$active_users = ttTeamHelper::getActiveUsers(array('getAllFields'=>true)); -if($user->canManageTeam()) { - $can_delete_manager = (1 == count($active_users)); - $inactive_users = ttTeamHelper::getInactiveUsers($user->team_id, true); +// Prepare a list of active users. +if ($user->can('view_users')) + $options = array('status'=>ACTIVE,'include_clients'=>true,'include_login'=>true,'include_role'=>true); +else /* if ($user->can('manage_users')) */ + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_clients'=>true,'include_self'=>true,'self_first'=>true,'include_login'=>true,'include_role'=>true); +$active_users = $user->getUsers($options); + +// Prepare a list of inactive users. +if($user->can('manage_users')) { + $options = array('status'=>INACTIVE,'max_rank'=>$user->rank-1,'include_clients'=>true,'include_login'=>true,'include_role'=>true); + $inactive_users = $user->getUsers($options); } // Check if the team is set to show indicators for uncompleted time entries. @@ -55,7 +61,6 @@ $smarty->assign('active_users', $active_users); $smarty->assign('inactive_users', $inactive_users); -$smarty->assign('can_delete_manager', $can_delete_manager); $smarty->assign('title', $i18n->get('title.users')); $smarty->assign('content_page_name', 'users.tpl'); $smarty->display('index.tpl'); From 2178ec6d4efd6cad07b8f137415ecec207efcdad Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 00:14:45 +0000 Subject: [PATCH 0052/1848] Removed self_first option from Users page display - unneeded. --- WEB-INF/templates/footer.tpl | 2 +- users.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e9e28a35e..7239c1384 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.72.4169 | Copyright © Anuko | +  Anuko Time Tracker 1.17.72.4170 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/users.php b/users.php index f5335455f..8787844b4 100644 --- a/users.php +++ b/users.php @@ -42,7 +42,7 @@ if ($user->can('view_users')) $options = array('status'=>ACTIVE,'include_clients'=>true,'include_login'=>true,'include_role'=>true); else /* if ($user->can('manage_users')) */ - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_clients'=>true,'include_self'=>true,'self_first'=>true,'include_login'=>true,'include_role'=>true); + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_clients'=>true,'include_self'=>true,'include_login'=>true,'include_role'=>true); $active_users = $user->getUsers($options); // Prepare a list of inactive users. From 9339284bfdaba5a0c2a4e3c9fa000194a508d0bf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 13:14:51 +0000 Subject: [PATCH 0053/1848] Improved getUserDetails to not return info for deleted users. --- WEB-INF/lib/ttUserHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- mobile/user_delete.php | 1 - mobile/user_edit.php | 1 - user_delete.php | 9 +++------ user_edit.php | 7 ++----- 6 files changed, 7 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index e4591ea43..583049bd7 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -36,7 +36,7 @@ static function getUserDetails($user_id) { global $user; $mdb2 = getConnection(); - $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.id = $user_id and u.team_id = $user->team_id"; + $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.id = $user_id and u.team_id = $user->team_id and u.status is not null"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7239c1384..77e160e9b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.72.4170 | Copyright © Anuko | +  Anuko Time Tracker 1.17.72.4171 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/user_delete.php b/mobile/user_delete.php index d8400456a..0e045d018 100644 --- a/mobile/user_delete.php +++ b/mobile/user_delete.php @@ -45,7 +45,6 @@ // Security checks. if (!$user_details || // No details. - $user_details['team_id'] <> $user->team_id || // User not in team. $user_details['rank'] > $user->rank || // User has a bigger rank. ($user_details['rank'] == $user->rank && $user_details['id'] <> $user->id) // Same rank but not us. ) { diff --git a/mobile/user_edit.php b/mobile/user_edit.php index 285c3442b..497812261 100644 --- a/mobile/user_edit.php +++ b/mobile/user_edit.php @@ -47,7 +47,6 @@ // Security checks. if (!$user_details || // No details. - $user_details['team_id'] <> $user->team_id || // User not in team. $user_details['rank'] > $user->rank || // User has a bigger rank. ($user_details['rank'] == $user->rank && $user_details['id'] <> $user->id) // Same rank but not us. ) { diff --git a/user_delete.php b/user_delete.php index a88454bf9..b8ec5e9ad 100644 --- a/user_delete.php +++ b/user_delete.php @@ -30,27 +30,24 @@ import('form.Form'); import('ttUserHelper'); -// Access check. +// Access checks. if (!ttAccessAllowed('manage_users')) { header('Location: access_denied.php'); exit(); } - -// Get user id we are deleting from the request. +// Get user id we are deleting. // A cast to int is for safety against manipulation of request parameter (sql injection). $user_id = (int) $request->getParameter('id'); // We need user name and login to display. $user_details = ttUserHelper::getUserDetails($user_id); - -// Security checks. if (!$user_details || // No details. - $user_details['team_id'] <> $user->team_id || // User not in team. $user_details['rank'] > $user->rank || // User has a bigger rank. ($user_details['rank'] == $user->rank && $user_details['id'] <> $user->id) // Same rank but not us. ) { header('Location: access_denied.php'); exit(); } +// End of access checks. $smarty->assign('user_to_delete', $user_details['name']." (".$user_details['login'].")"); diff --git a/user_edit.php b/user_edit.php index 75d89e506..5ceac373e 100644 --- a/user_edit.php +++ b/user_edit.php @@ -35,26 +35,23 @@ import('form.TableColumn'); import('ttRoleHelper'); -// Access check. +// Access checks. if (!ttAccessAllowed('manage_users')) { header('Location: access_denied.php'); exit(); } - // Get user id we are editing from the request. $user_id = (int) $request->getParameter('id'); // Get user details. $user_details = ttUserHelper::getUserDetails($user_id); - -// Security checks. if (!$user_details || // No details. - $user_details['team_id'] <> $user->team_id || // User not in team. $user_details['rank'] > $user->rank || // User has a bigger rank. ($user_details['rank'] == $user->rank && $user_details['id'] <> $user->id) // Same rank but not us. ) { header('Location: access_denied.php'); exit(); } +// End of access checks. if ($user->isPluginEnabled('cl')) $clients = ttTeamHelper::getActiveClients($user->team_id); From bdbf162130c02c6a5510205c7704ef7d5e8f22ea Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 14:19:37 +0000 Subject: [PATCH 0054/1848] A bit of refactoring of access checks in user edits and deletes. --- WEB-INF/lib/ttUser.class.php | 19 +++++++++++++++++++ WEB-INF/lib/ttUserHelper.class.php | 15 --------------- WEB-INF/templates/footer.tpl | 2 +- mobile/user_delete.php | 15 +++------------ mobile/user_edit.php | 13 +++---------- user_delete.php | 10 ++-------- user_edit.php | 9 ++------- 7 files changed, 30 insertions(+), 53 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 5321e74d9..7f9894efd 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -298,6 +298,25 @@ function getUsers($options) { return $user_list; } + // getUser function is used to manage users in group and returns user details. + // At the moment, the function is used for user edits and deletes. + function getUser($user_id) { + if (!$this->can('manage_users')) return false; + + $mdb2 = getConnection(); + + $sql = "select u.id, u.name, u.login, u.role_id, u.status, u.rate, u.email, r.rank from tt_users u". + " left join tt_roles r on (u.role_id = r.id)". + " where u.id = $user_id and u.team_id = $this->team_id and u.status is not null". + " and (r.rank < $this->rank or (r.rank = $this->rank and u.id = $this->id))"; // Users with lesser roles or self. + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + return $val; + } + return false; + } + // checkBehalfId checks whether behalf_id is appropriate. // On behalf user must be active and have lower rank. function checkBehalfId() { diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 583049bd7..31c7bde4d 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -31,21 +31,6 @@ // Class ttUserHelper contains helper functions for operations with users. class ttUserHelper { - // The getUserDetails function returns user details. - static function getUserDetails($user_id) { - global $user; - $mdb2 = getConnection(); - - $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.id = $user_id and u.team_id = $user->team_id and u.status is not null"; - $res = $mdb2->query($sql); - - if (!is_a($res, 'PEAR_Error')) { - $val = $res->fetchRow(); - return $val; - } - return false; - } - // The getUserName function returns user name. static function getUserName($user_id) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 77e160e9b..851570f35 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.72.4171 | Copyright © Anuko | +  Anuko Time Tracker 1.17.72.4172 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/user_delete.php b/mobile/user_delete.php index 0e045d018..4c9aad878 100644 --- a/mobile/user_delete.php +++ b/mobile/user_delete.php @@ -35,22 +35,13 @@ header('Location: access_denied.php'); exit(); } - -// Get user id we are deleting from the request. -// A cast to int is for safety against manipulation of request parameter (sql injection). $user_id = (int) $request->getParameter('id'); - -// We need user name and login to display. -$user_details = ttUserHelper::getUserDetails($user_id); - -// Security checks. -if (!$user_details || // No details. - $user_details['rank'] > $user->rank || // User has a bigger rank. - ($user_details['rank'] == $user->rank && $user_details['id'] <> $user->id) // Same rank but not us. - ) { +$user_details = $user->getUser($user_id); +if (!$user_details) { header('Location: access_denied.php'); exit(); } +// End of access checks. $smarty->assign('user_to_delete', $user_details['name']." (".$user_details['login'].")"); diff --git a/mobile/user_edit.php b/mobile/user_edit.php index 497812261..3baaf1e93 100644 --- a/mobile/user_edit.php +++ b/mobile/user_edit.php @@ -39,20 +39,13 @@ header('Location: access_denied.php'); exit(); } - -// Get user id we are editing from the request. $user_id = (int) $request->getParameter('id'); -// Get user details. -$user_details = ttUserHelper::getUserDetails($user_id); - -// Security checks. -if (!$user_details || // No details. - $user_details['rank'] > $user->rank || // User has a bigger rank. - ($user_details['rank'] == $user->rank && $user_details['id'] <> $user->id) // Same rank but not us. - ) { +$user_details = $user->getUser($user_id); +if (!$user_details) { header('Location: access_denied.php'); exit(); } +// End of access checks. if ($user->isPluginEnabled('cl')) $clients = ttTeamHelper::getActiveClients($user->team_id); diff --git a/user_delete.php b/user_delete.php index b8ec5e9ad..d06463b8a 100644 --- a/user_delete.php +++ b/user_delete.php @@ -35,15 +35,9 @@ header('Location: access_denied.php'); exit(); } -// Get user id we are deleting. -// A cast to int is for safety against manipulation of request parameter (sql injection). $user_id = (int) $request->getParameter('id'); -// We need user name and login to display. -$user_details = ttUserHelper::getUserDetails($user_id); -if (!$user_details || // No details. - $user_details['rank'] > $user->rank || // User has a bigger rank. - ($user_details['rank'] == $user->rank && $user_details['id'] <> $user->id) // Same rank but not us. - ) { +$user_details = $user->getUser($user_id); +if (!$user_details) { header('Location: access_denied.php'); exit(); } diff --git a/user_edit.php b/user_edit.php index 5ceac373e..8f588db97 100644 --- a/user_edit.php +++ b/user_edit.php @@ -40,14 +40,9 @@ header('Location: access_denied.php'); exit(); } -// Get user id we are editing from the request. $user_id = (int) $request->getParameter('id'); -// Get user details. -$user_details = ttUserHelper::getUserDetails($user_id); -if (!$user_details || // No details. - $user_details['rank'] > $user->rank || // User has a bigger rank. - ($user_details['rank'] == $user->rank && $user_details['id'] <> $user->id) // Same rank but not us. - ) { +$user_details = $user->getUser($user_id); +if (!$user_details) { header('Location: access_denied.php'); exit(); } From 5c3193f4b25f637d737c2acb714164ada39b4788 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 14:25:58 +0000 Subject: [PATCH 0055/1848] Removed rank field from the query as it is currently not used. --- WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 7f9894efd..27b90a425 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -305,7 +305,7 @@ function getUser($user_id) { $mdb2 = getConnection(); - $sql = "select u.id, u.name, u.login, u.role_id, u.status, u.rate, u.email, r.rank from tt_users u". + $sql = "select u.id, u.name, u.login, u.role_id, u.status, u.rate, u.email from tt_users u". " left join tt_roles r on (u.role_id = r.id)". " where u.id = $user_id and u.team_id = $this->team_id and u.status is not null". " and (r.rank < $this->rank or (r.rank = $this->rank and u.id = $this->id))"; // Users with lesser roles or self. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 851570f35..e965d2a58 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.72.4172 | Copyright © Anuko | +  Anuko Time Tracker 1.17.72.4173 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From d685a57ec1f70438af9aa66ed578a5f6cf4deb00 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 14:34:22 +0000 Subject: [PATCH 0056/1848] Added ordering by name to getUsers. --- WEB-INF/lib/ttUser.class.php | 4 +++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 27b90a425..d58a71679 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -269,7 +269,9 @@ function getUsers($options) { if (isset($options['max_rank'])) $where_part .= ' and r.rank <= '.(int)$options['max_rank']; } - $sql = $select_part.$from_part.$left_joins.$where_part; + $order_part = " order by upper(u.name)"; + + $sql = $select_part.$from_part.$left_joins.$where_part.$order_part; $res = $mdb2->query($sql); $user_list = array(); if (is_a($res, 'PEAR_Error')) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e965d2a58..ab703fb7e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.72.4173 | Copyright © Anuko | +  Anuko Time Tracker 1.17.72.4174 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From d9ef3e94c49d9b5e8c7532efc8b460c3e1135fdd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 15:12:52 +0000 Subject: [PATCH 0057/1848] Fixed reports to include users of lesser roles only. --- WEB-INF/lib/ttUser.class.php | 5 ++++- WEB-INF/templates/footer.tpl | 2 +- reports.php | 31 ++++++++++++++++++------------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index d58a71679..f9edc8cc7 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -262,7 +262,10 @@ function getUsers($options) { $left_joins .= ' left join tt_roles r on (u.role_id = r.id)'; $where_part = " where u.team_id = $this->team_id"; - if (isset($options['status'])) $where_part .= ' and u.status = '.(int)$options['status']; + if (isset($options['status'])) + $where_part .= ' and u.status = '.(int)$options['status']; + else + $where_part .= ' and u.status is not null'; if ($includeSelf) { $where_part .= " and (u.id = $this->id || r.rank <= ".(int)$options['max_rank'].')'; } else { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ab703fb7e..4b5b36f6b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.72.4174 | Copyright © Anuko | +  Anuko Time Tracker 1.17.73.4175 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 3a7367e77..59f3c0f92 100644 --- a/reports.php +++ b/reports.php @@ -122,16 +122,6 @@ 'data'=>$include_options, 'empty'=>array(''=>$i18n->get('dropdown.all')))); -if ($user->canManageTeam() && $user->isPluginEnabled('ps')) { - $form->addInput(array('type'=>'combobox', - 'name'=>'paid_status', - 'style'=>'width: 250px;', - 'data'=>array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')), - 'empty'=>array(''=>$i18n->get('dropdown.all')) - )); -} - - // Add invoiced / not invoiced selector. $invoice_options = array('1'=>$i18n->get('form.reports.include_invoiced'), '2'=>$i18n->get('form.reports.include_not_invoiced')); @@ -141,11 +131,26 @@ 'data'=>$invoice_options, 'empty'=>array(''=>$i18n->get('dropdown.all')))); +if ($user->canManageTeam() && $user->isPluginEnabled('ps')) { + $form->addInput(array('type'=>'combobox', + 'name'=>'paid_status', + 'style'=>'width: 250px;', + 'data'=>array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')), + 'empty'=>array(''=>$i18n->get('dropdown.all')) + )); +} + $user_list = array(); -if ($user->canManageTeam() || $user->isClient()) { +if ($user->can('view_reports') || $user->isClient()) { // Prepare user and assigned projects arrays. - if ($user->canManageTeam()) - $users = ttTeamHelper::getUsers(); // Active and inactive users for managers. + if ($user->can('view_reports')) { + // $users = ttTeamHelper::getUsers(); // Active and inactive users for managers. + if ($user->can('view_own_reports')) + $options = array('max_rank'=>$user->rank-1,'include_self'=>true); + else + $options = array('max_rank'=>$user->rank-1); + $users = $user->getUsers($options); // Active and inactive users for managers. + } elseif ($user->isClient()) $users = ttTeamHelper::getUsersForClient(); // Active and inactive users for clients. From b187fdd5442216e598a181f732da57e268f46dd8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 15:16:10 +0000 Subject: [PATCH 0058/1848] Fixed a comment. --- WEB-INF/templates/footer.tpl | 2 +- reports.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4b5b36f6b..c7c23da32 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.73.4175 | Copyright © Anuko | +  Anuko Time Tracker 1.17.73.4176 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 59f3c0f92..3aba9cdf7 100644 --- a/reports.php +++ b/reports.php @@ -144,12 +144,11 @@ if ($user->can('view_reports') || $user->isClient()) { // Prepare user and assigned projects arrays. if ($user->can('view_reports')) { - // $users = ttTeamHelper::getUsers(); // Active and inactive users for managers. if ($user->can('view_own_reports')) $options = array('max_rank'=>$user->rank-1,'include_self'=>true); else $options = array('max_rank'=>$user->rank-1); - $users = $user->getUsers($options); // Active and inactive users for managers. + $users = $user->getUsers($options); // Active and inactive users. } elseif ($user->isClient()) $users = ttTeamHelper::getUsersForClient(); // Active and inactive users for clients. From 3c5c333f6d7a4a3f54fb711547dbd48403912c3a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 16:19:03 +0000 Subject: [PATCH 0059/1848] Improved ttClientHelper::delete() function. --- WEB-INF/lib/ttClientHelper.class.php | 16 ++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 14788ae4c..288cd45be 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -120,8 +120,9 @@ static function delete($id, $delete_client_entries) { } // Handle time records. + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); if ($delete_client_entries) { - $sql = "update tt_log set status = NULL where client_id = $id"; + $sql = 'update tt_log set status = NULL'.$modified_part." where client_id = $id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -129,7 +130,7 @@ static function delete($id, $delete_client_entries) { // Handle expense items. if ($delete_client_entries) { - $sql = "update tt_expense_items set status = NULL where client_id = $id"; + $sql = 'update tt_expense_items set status = NULL'.$modified_part." where client_id = $id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -137,7 +138,7 @@ static function delete($id, $delete_client_entries) { // Handle invoices. if ($delete_client_entries) { - $sql = "update tt_invoices set status = NULL where client_id = $id"; + $sql = "update tt_invoices set status = NULL where client_id = $id and team_id = $user->team_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -149,7 +150,14 @@ static function delete($id, $delete_client_entries) { if (is_a($affected, 'PEAR_Error')) return false; - $sql = "update tt_clients set status = NULL where id = $id and team_id = ".$user->team_id; + // Handle users for client. + $sql = 'update tt_users set status = NULL'.$modified_part." where client_id = $id and team_id = $user->team_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Mark client deleted. + $sql = "update tt_clients set status = NULL where id = $id and team_id = $user->team_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c7c23da32..3e9eb18dc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.73.4176 | Copyright © Anuko | +  Anuko Time Tracker 1.17.73.4177 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 926b8d63a0be596b0c95cb55f01addae410af50c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 17:09:46 +0000 Subject: [PATCH 0060/1848] Improved access checks for invoices. --- WEB-INF/templates/footer.tpl | 2 +- invoice_add.php | 1 + invoice_delete.php | 7 ++++++- invoice_send.php | 13 +++++++------ invoice_view.php | 8 +++----- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3e9eb18dc..2aa36a25b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.73.4177 | Copyright © Anuko | +  Anuko Time Tracker 1.17.73.4178 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/invoice_add.php b/invoice_add.php index 5267056c0..ad9c3cfb8 100644 --- a/invoice_add.php +++ b/invoice_add.php @@ -40,6 +40,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. if ($request->isPost()) { $cl_date = $request->getParameter('date'); diff --git a/invoice_delete.php b/invoice_delete.php index 2bca58ce3..ffdcf2c17 100644 --- a/invoice_delete.php +++ b/invoice_delete.php @@ -39,9 +39,14 @@ header('Location: feature_disabled.php'); exit(); } - $cl_invoice_id = (int)$request->getParameter('id'); $invoice = ttInvoiceHelper::getInvoice($cl_invoice_id); +if (!$invoice) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + $invoice_to_delete = $invoice['name']; $form = new Form('invoiceDeleteForm'); diff --git a/invoice_send.php b/invoice_send.php index f0e30bc4b..20c3c1870 100644 --- a/invoice_send.php +++ b/invoice_send.php @@ -40,14 +40,15 @@ header('Location: feature_disabled.php'); exit(); } - $cl_invoice_id = (int)$request->getParameter('id'); -$invoice = ttInvoiceHelper::getInvoice($cl_invoice_id); -$sc = new ttSysConfig($user->id); +$invoice = ttInvoiceHelper::getInvoice($cl_invoice_id); +if (!$invoice) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. -// Security check. -if (!$cl_invoice_id || !$invoice) - die ($i18n->get('error.sys')); +$sc = new ttSysConfig($user->id); if ($request->isPost()) { $cl_receiver = trim($request->getParameter('receiver')); diff --git a/invoice_view.php b/invoice_view.php index 62f0cbbff..fd8424a39 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -41,15 +41,13 @@ header('Location: feature_disabled.php'); exit(); } - -$cl_id = (int)$request->getParameter('id'); -$invoice = ttInvoiceHelper::getInvoice($cl_id); -// Temporary fix for invalid invoice id. TODO: implement properly and review security of other pages, -// where item id is passed (or posted) as parameter. +$cl_invoice_id = (int)$request->getParameter('id'); +$invoice = ttInvoiceHelper::getInvoice($cl_invoice_id); if (!$invoice) { header('Location: access_denied.php'); exit(); } +// End of access checks. $invoice_date = new DateAndTime(DB_DATEFORMAT, $invoice['date']); $client = ttClientHelper::getClient($invoice['client_id'], true); From 11bfec0ff88b649a934556e8b4812d65715c7509 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 18:45:28 +0000 Subject: [PATCH 0061/1848] Security fix - improved access checks for task edit and deletes. --- WEB-INF/templates/footer.tpl | 2 +- mobile/task_add.php | 1 + mobile/task_delete.php | 7 ++++++- mobile/task_edit.php | 10 +++++++--- mobile/tasks.php | 1 + mobile/time.php | 3 ++- mobile/time_delete.php | 2 +- mobile/time_edit.php | 4 ++-- mobile/user_add.php | 3 ++- mobile/user_delete.php | 4 ++-- mobile/user_edit.php | 4 ++-- mobile/users.php | 3 ++- task_add.php | 1 + task_delete.php | 7 ++++++- task_edit.php | 10 +++++++--- tasks.php | 1 + time.php | 8 +------- time_delete.php | 2 +- time_edit.php | 2 +- tofile.php | 3 ++- topdf.php | 3 ++- user_add.php | 3 ++- user_delete.php | 2 +- user_edit.php | 2 +- users.php | 3 ++- week.php | 1 + 26 files changed, 58 insertions(+), 34 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2aa36a25b..b9939f90e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.73.4178 | Copyright © Anuko | +  Anuko Time Tracker 1.17.74.4179 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/task_add.php b/mobile/task_add.php index a976ac5c9..fd1fb4649 100644 --- a/mobile/task_add.php +++ b/mobile/task_add.php @@ -41,6 +41,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. $projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/mobile/task_delete.php b/mobile/task_delete.php index 1146a2ac2..153f3a2d8 100644 --- a/mobile/task_delete.php +++ b/mobile/task_delete.php @@ -39,9 +39,14 @@ header('Location: feature_disabled.php'); exit(); } - $cl_task_id = (int)$request->getParameter('id'); $task = ttTaskHelper::get($cl_task_id); +if (!$task) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + $task_to_delete = $task['name']; $form = new Form('taskDeleteForm'); diff --git a/mobile/task_edit.php b/mobile/task_edit.php index 346899dce..f1748c7e9 100644 --- a/mobile/task_edit.php +++ b/mobile/task_edit.php @@ -40,8 +40,14 @@ header('Location: feature_disabled.php'); exit(); } - $cl_task_id = (int)$request->getParameter('id'); +$task = ttTaskHelper::get($cl_task_id); +if (!$task) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + $projects = ttTeamHelper::getActiveProjects($user->team_id); if ($request->isPost()) { @@ -50,11 +56,9 @@ $cl_status = $request->getParameter('status'); $cl_projects = $request->getParameter('projects'); } else { - $task = ttTaskHelper::get($cl_task_id); $cl_name = $task['name']; $cl_description = $task['description']; $cl_status = $task['status']; - $assigned_projects = ttTaskHelper::getAssignedProjects($cl_task_id); foreach ($assigned_projects as $project_item) $cl_projects[] = $project_item['id']; diff --git a/mobile/tasks.php b/mobile/tasks.php index edb57089e..e49498c4c 100644 --- a/mobile/tasks.php +++ b/mobile/tasks.php @@ -39,6 +39,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. $smarty->assign('active_tasks', ttTeamHelper::getActiveTasks($user->team_id)); $smarty->assign('inactive_tasks', ttTeamHelper::getInactiveTasks($user->team_id)); diff --git a/mobile/time.php b/mobile/time.php index abde5e01d..8c6721d49 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -34,11 +34,12 @@ import('ttTimeHelper'); import('DateAndTime'); -// Access check. +// Access checks. if (!ttAccessAllowed('track_own_time')) { header('Location: access_denied.php'); exit(); } +// End of access checks. // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); diff --git a/mobile/time_delete.php b/mobile/time_delete.php index 5d6918c59..399895c7a 100644 --- a/mobile/time_delete.php +++ b/mobile/time_delete.php @@ -38,13 +38,13 @@ exit(); } $cl_id = (int)$request->getParameter('id'); -// Get the time record we are deleting. $time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); if (!$time_rec || $time_rec['invoice_id']) { // Prohibit deleting not ours or invoiced records. header('Location: access_denied.php'); exit(); } +// End of access checks. // Escape comment for presentation. $time_rec['comment'] = htmlspecialchars($time_rec['comment']); diff --git a/mobile/time_edit.php b/mobile/time_edit.php index eff9b3358..a1a56e37c 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -34,19 +34,19 @@ import('ttTimeHelper'); import('DateAndTime'); -// Access check. +// Access checks. if (!ttAccessAllowed('track_own_time')) { header('Location: access_denied.php'); exit(); } $cl_id = (int)$request->getParameter('id'); -// Get the time record we are editing. $time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); if (!$time_rec || $time_rec['invoice_id']) { // Prohibit editing not ours or invoiced records. header('Location: access_denied.php'); exit(); } +// End of access checks. // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { diff --git a/mobile/user_add.php b/mobile/user_add.php index 838981de4..53b9842fa 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -33,11 +33,12 @@ import('form.Table'); import('form.TableColumn'); -// Access check. +// Access checks. if (!ttAccessAllowed('manage_users')) { header('Location: access_denied.php'); exit(); } +// End of access checks. // Use the "limit" plugin if we have one. Ignore include errors. // The "limit" plugin is not required for normal operation of the Time Tracker. diff --git a/mobile/user_delete.php b/mobile/user_delete.php index 4c9aad878..b5c8dae12 100644 --- a/mobile/user_delete.php +++ b/mobile/user_delete.php @@ -30,12 +30,12 @@ import('form.Form'); import('ttUserHelper'); -// Access check. +// Access checks. if (!ttAccessAllowed('manage_users')) { header('Location: access_denied.php'); exit(); } -$user_id = (int) $request->getParameter('id'); +$user_id = (int)$request->getParameter('id'); $user_details = $user->getUser($user_id); if (!$user_details) { header('Location: access_denied.php'); diff --git a/mobile/user_edit.php b/mobile/user_edit.php index 3baaf1e93..f82d9314a 100644 --- a/mobile/user_edit.php +++ b/mobile/user_edit.php @@ -34,12 +34,12 @@ import('form.Table'); import('form.TableColumn'); -// Access check. +// Access checks. if (!ttAccessAllowed('manage_users')) { header('Location: access_denied.php'); exit(); } -$user_id = (int) $request->getParameter('id'); +$user_id = (int)$request->getParameter('id'); $user_details = $user->getUser($user_id); if (!$user_details) { header('Location: access_denied.php'); diff --git a/mobile/users.php b/mobile/users.php index 67654376e..18ad2e5fa 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -31,11 +31,12 @@ import('ttTeamHelper'); import('ttTimeHelper'); -// Access check. +// Access checks. if (!(ttAccessAllowed('view_users') || ttAccessAllowed('manage_users'))) { header('Location: access_denied.php'); exit(); } +// End of access checks. // Get users. $active_users = ttTeamHelper::getActiveUsers(array('getAllFields'=>true)); diff --git a/task_add.php b/task_add.php index a5149e840..eaaba5e8d 100644 --- a/task_add.php +++ b/task_add.php @@ -41,6 +41,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. $projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/task_delete.php b/task_delete.php index 0e9f40cfe..d8e14399f 100644 --- a/task_delete.php +++ b/task_delete.php @@ -39,9 +39,14 @@ header('Location: feature_disabled.php'); exit(); } - $cl_task_id = (int)$request->getParameter('id'); $task = ttTaskHelper::get($cl_task_id); +if (!$task) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + $task_to_delete = $task['name']; $form = new Form('taskDeleteForm'); diff --git a/task_edit.php b/task_edit.php index bba89bebd..324f1dbb8 100644 --- a/task_edit.php +++ b/task_edit.php @@ -40,8 +40,14 @@ header('Location: feature_disabled.php'); exit(); } - $cl_task_id = (int)$request->getParameter('id'); +$task = ttTaskHelper::get($cl_task_id); +if (!$task) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + $projects = ttTeamHelper::getActiveProjects($user->team_id); if ($request->isPost()) { @@ -50,11 +56,9 @@ $cl_status = $request->getParameter('status'); $cl_projects = $request->getParameter('projects'); } else { - $task = ttTaskHelper::get($cl_task_id); $cl_name = $task['name']; $cl_description = $task['description']; $cl_status = $task['status']; - $assigned_projects = ttTaskHelper::getAssignedProjects($cl_task_id); foreach ($assigned_projects as $project_item) $cl_projects[] = $project_item['id']; diff --git a/tasks.php b/tasks.php index 5505e6ddd..2d310d011 100644 --- a/tasks.php +++ b/tasks.php @@ -39,6 +39,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. $smarty->assign('active_tasks', ttTeamHelper::getActiveTasks($user->team_id)); $smarty->assign('inactive_tasks', ttTeamHelper::getInactiveTasks($user->team_id)); diff --git a/time.php b/time.php index 98a383fdd..d75854c83 100644 --- a/time.php +++ b/time.php @@ -34,13 +34,6 @@ import('ttTimeHelper'); import('DateAndTime'); -// This is a now removed check whether user browser supports cookies. -// if (!isset($_COOKIE['tt_PHPSESSID'])) { - // This test gives a false-positive if user goes directly to this page - // as from a desktop shortcut (on first request only). - // die ("Your browser's cookie functionality is turned off. Please turn it on."); -// } - // Access checks. if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); @@ -54,6 +47,7 @@ header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. exit(); } +// End of access checks. // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); diff --git a/time_delete.php b/time_delete.php index 060311e87..5d721ab1f 100644 --- a/time_delete.php +++ b/time_delete.php @@ -38,13 +38,13 @@ exit(); } $cl_id = (int)$request->getParameter('id'); -// Get the time record we are deleting. $time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); if (!$time_rec || $time_rec['invoice_id']) { // Prohibit deleting not ours or invoiced records. header('Location: access_denied.php'); exit(); } +// End of access checks. // Escape comment for presentation. $time_rec['comment'] = htmlspecialchars($time_rec['comment']); diff --git a/time_edit.php b/time_edit.php index 05db97c02..507f28abb 100644 --- a/time_edit.php +++ b/time_edit.php @@ -40,13 +40,13 @@ exit(); } $cl_id = (int)$request->getParameter('id'); -// Get the time record we are editing. $time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser()); if (!$time_rec || $time_rec['invoice_id']) { // Prohibit editing not ours or invoiced records. header('Location: access_denied.php'); exit(); } +// End of access checks. // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { diff --git a/tofile.php b/tofile.php index abd1f278b..e7b9ed963 100644 --- a/tofile.php +++ b/tofile.php @@ -31,11 +31,12 @@ import('form.ActionForm'); import('ttReportHelper'); -// Access check. +// Access checks. if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { header('Location: access_denied.php'); exit(); } +// End of access checks. // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { diff --git a/topdf.php b/topdf.php index 3177d1559..475522ef9 100644 --- a/topdf.php +++ b/topdf.php @@ -35,11 +35,12 @@ import('form.ActionForm'); import('ttReportHelper'); -// Access check. +// Access checks. if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { header('Location: access_denied.php'); exit(); } +// End of access checks. // Check whether TCPDF library is available. if (!file_exists('WEB-INF/lib/tcpdf/')) diff --git a/user_add.php b/user_add.php index 91286537d..b235cbd17 100644 --- a/user_add.php +++ b/user_add.php @@ -34,11 +34,12 @@ import('form.TableColumn'); import('ttRoleHelper'); -// Access check. +// Access checks. if (!ttAccessAllowed('manage_users')) { header('Location: access_denied.php'); exit(); } +// End of access checks. // Use the "limit" plugin if we have one. Ignore include errors. // The "limit" plugin is not required for normal operation of the Time Tracker. diff --git a/user_delete.php b/user_delete.php index d06463b8a..647f21728 100644 --- a/user_delete.php +++ b/user_delete.php @@ -35,7 +35,7 @@ header('Location: access_denied.php'); exit(); } -$user_id = (int) $request->getParameter('id'); +$user_id = (int)$request->getParameter('id'); $user_details = $user->getUser($user_id); if (!$user_details) { header('Location: access_denied.php'); diff --git a/user_edit.php b/user_edit.php index 8f588db97..95ed29e79 100644 --- a/user_edit.php +++ b/user_edit.php @@ -40,7 +40,7 @@ header('Location: access_denied.php'); exit(); } -$user_id = (int) $request->getParameter('id'); +$user_id = (int)$request->getParameter('id'); $user_details = $user->getUser($user_id); if (!$user_details) { header('Location: access_denied.php'); diff --git a/users.php b/users.php index 8787844b4..af5389021 100644 --- a/users.php +++ b/users.php @@ -32,11 +32,12 @@ import('ttTimeHelper'); import('ttRoleHelper'); -// Access check. +// Access checks. if (!(ttAccessAllowed('view_users') || ttAccessAllowed('manage_users'))) { header('Location: access_denied.php'); exit(); } +// End of access checks. // Prepare a list of active users. if ($user->can('view_users')) diff --git a/week.php b/week.php index 741a2bb4e..1d72ce400 100644 --- a/week.php +++ b/week.php @@ -55,6 +55,7 @@ header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. exit(); } +// End of access checks. // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); From 81ca36ba9b5294ecb417d9b82196752211c652b7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 18:56:07 +0000 Subject: [PATCH 0062/1848] Included team_id in task update sql to avoid risk of misuse. --- WEB-INF/lib/ttTaskHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttTaskHelper.class.php b/WEB-INF/lib/ttTaskHelper.class.php index 2bb99da42..24831cb26 100644 --- a/WEB-INF/lib/ttTaskHelper.class.php +++ b/WEB-INF/lib/ttTaskHelper.class.php @@ -198,7 +198,7 @@ static function update($fields) $projects = $fields['projects']; $sql = "update tt_tasks set name = ".$mdb2->quote($name).", description = ".$mdb2->quote($description). - ", status = $status where id = $task_id"; + ", status = $status where id = $task_id and team_id = $user->team_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b9939f90e..9defcca82 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.74.4179 | Copyright © Anuko | +  Anuko Time Tracker 1.17.74.4180 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 2f5b2dc68a73954b497c7aaa3223be7f3db1d117 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 19:18:51 +0000 Subject: [PATCH 0063/1848] Improved access checks for swap_roles.php. --- WEB-INF/lib/ttTeamHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- swap_roles.php | 11 ++++++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 5aeee2196..fb74d8e10 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -108,6 +108,7 @@ static function swapRolesWith($user_id) { global $user; $mdb2 = getConnection(); + // Obtain role id for the user we are swapping ourselves with. $sql = "select u.id, u.role_id from tt_users u left join tt_roles r on (u.role_id = r.id) where u.id = $user_id and u.team_id = $user->team_id and u.status = 1 and r.rank < $user->rank"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9defcca82..6646f126b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.74.4180 | Copyright © Anuko | +  Anuko Time Tracker 1.17.74.4181 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/swap_roles.php b/swap_roles.php index 59a726c5b..05485018b 100644 --- a/swap_roles.php +++ b/swap_roles.php @@ -40,10 +40,15 @@ header('Location: access_denied.php'); exit(); } - if ($request->isPost()) { - $cl_id = $request->getParameter('swap_with'); + $user_id = (int)$request->getParameter('swap_with'); + $user_details = $user->getUser($user_id); + if (!$user_details) { + header('Location: access_denied.php'); + exit(); + } } +// End of access checks. $form = new Form('swapForm'); $form->addInput(array('type'=>'combobox','name'=>'swap_with','style'=>'width: 250px;','data'=>$users_for_swap,'datakeys'=>array('id','name'))); @@ -52,7 +57,7 @@ if ($request->isPost()) { if ($request->getParameter('btn_submit')) { - if (ttTeamHelper::swapRolesWith($cl_id)) { + if (ttTeamHelper::swapRolesWith($user_id)) { header('Location: users.php'); exit(); } else From dab1057395c8eb9c5dce5480a738de1467e83ba5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 19:45:10 +0000 Subject: [PATCH 0064/1848] Improved input checking for role editor. --- WEB-INF/templates/footer.tpl | 2 +- role_add.php | 3 ++- role_delete.php | 7 ++++++- role_edit.php | 4 ++-- roles.php | 3 ++- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6646f126b..7c8bd634f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.74.4181 | Copyright © Anuko | +  Anuko Time Tracker 1.17.74.4182 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/role_add.php b/role_add.php index e4cbb9644..d26cb6ad0 100644 --- a/role_add.php +++ b/role_add.php @@ -40,7 +40,7 @@ if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_description = trim($request->getParameter('description')); - $cl_rank = (int) $request->getParameter('rank'); + $cl_rank = (int)$request->getParameter('rank'); } $form = new Form('roleForm'); @@ -56,6 +56,7 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if ($cl_rank >= $user->rank || $cl_rank < 0) $err->add($i18n->get('error.field'), $i18n->get('form.roles.rank')); if ($err->no()) { $existing_role = ttRoleHelper::getRoleByRank($cl_rank, $user->team_id); diff --git a/role_delete.php b/role_delete.php index 086e7affb..a3ce2985d 100644 --- a/role_delete.php +++ b/role_delete.php @@ -35,9 +35,14 @@ header('Location: access_denied.php'); exit(); } - $cl_role_id = (int)$request->getParameter('id'); $role = ttRoleHelper::get($cl_role_id); +if (!$role) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + $role_to_delete = $role['name']; $form = new Form('roleDeleteForm'); diff --git a/role_edit.php b/role_edit.php index f5f3762b3..972d4540c 100644 --- a/role_edit.php +++ b/role_edit.php @@ -28,8 +28,6 @@ require_once('initialize.php'); import('form.Form'); -import('ttTeamHelper'); // TODO: remove this? -import('ttTaskHelper'); // TODO: remove this? import('ttRoleHelper'); // Access checks. @@ -43,6 +41,7 @@ header('Location: access_denied.php'); exit(); } +// End of access checks. $assigned_rights = explode(',', $role['rights']); $available_rights = array_diff($user->rights, $assigned_rights); @@ -82,6 +81,7 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if ($cl_rank >= $user->rank || $cl_rank < 0) $err->add($i18n->get('error.field'), $i18n->get('form.roles.rank')); if ($err->no()) { $existing_role = ttRoleHelper::getRoleByName($cl_name); diff --git a/roles.php b/roles.php index ec79020ee..cd17da3c4 100644 --- a/roles.php +++ b/roles.php @@ -31,11 +31,12 @@ import('ttTeamHelper'); import('ttRoleHelper'); -// Access check. +// Access checks. if (!ttAccessAllowed('manage_roles')) { header('Location: access_denied.php'); exit(); } +// End of access checks. $smarty->assign('active_roles', ttTeamHelper::getActiveRolesForUser()); $smarty->assign('inactive_roles', ttTeamHelper::getInactiveRolesForUser()); From 75ef763b9bd7f515280a6d130e5ad81720d72156 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Mar 2018 20:31:45 +0000 Subject: [PATCH 0065/1848] Security fix for project edits. --- WEB-INF/templates/footer.tpl | 2 +- mobile/project_delete.php | 16 +++++++++------- mobile/project_edit.php | 8 ++++++-- mobile/projects.php | 5 +++-- project_delete.php | 16 +++++++++------- project_edit.php | 8 ++++++-- projects.php | 6 ++++-- 7 files changed, 38 insertions(+), 23 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7c8bd634f..95bed59a1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.74.4182 | Copyright © Anuko | +  Anuko Time Tracker 1.17.75.4183 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/project_delete.php b/mobile/project_delete.php index c8753b844..5785496aa 100644 --- a/mobile/project_delete.php +++ b/mobile/project_delete.php @@ -39,9 +39,14 @@ header('Location: feature_disabled.php'); exit(); } - $cl_project_id = (int)$request->getParameter('id'); $project = ttProjectHelper::get($cl_project_id); +if (!$project) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + $project_to_delete = $project['name']; $form = new Form('projectDeleteForm'); @@ -51,12 +56,9 @@ if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if(ttProjectHelper::get($cl_project_id)) { - if (ttProjectHelper::delete($cl_project_id)) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); + if (ttProjectHelper::delete($cl_project_id)) { + header('Location: projects.php'); + exit(); } else $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { diff --git a/mobile/project_edit.php b/mobile/project_edit.php index 74454ec41..6adb475e4 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -40,8 +40,13 @@ header('Location: feature_disabled.php'); exit(); } - $cl_project_id = (int)$request->getParameter('id'); +$project = ttProjectHelper::get($cl_project_id); +if (!$project) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. $users = ttTeamHelper::getActiveUsers(); foreach ($users as $user_item) @@ -58,7 +63,6 @@ $cl_users = $request->getParameter('users', array()); $cl_tasks = $request->getParameter('tasks', array()); } else { - $project = ttProjectHelper::get($cl_project_id); $cl_name = $project['name']; $cl_description = $project['description']; $cl_status = $project['status']; diff --git a/mobile/projects.php b/mobile/projects.php index 93261d425..938eab82a 100644 --- a/mobile/projects.php +++ b/mobile/projects.php @@ -31,7 +31,8 @@ import('ttTeamHelper'); // Access checks. -if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { +// TODO: introduce view_projects right to keep access checks simple. +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time') || ttAccessAllowed('manage_projects'))) { header('Location: access_denied.php'); exit(); } @@ -40,7 +41,7 @@ exit(); } -if($user->canManageTeam()) { +if($user->can('manage_projects')) { $active_projects = ttTeamHelper::getActiveProjects($user->team_id); $inactive_projects = ttTeamHelper::getInactiveProjects($user->team_id); } else diff --git a/project_delete.php b/project_delete.php index 2373bbead..450241e79 100644 --- a/project_delete.php +++ b/project_delete.php @@ -39,9 +39,14 @@ header('Location: feature_disabled.php'); exit(); } - $cl_project_id = (int)$request->getParameter('id'); $project = ttProjectHelper::get($cl_project_id); +if (!$project) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + $project_to_delete = $project['name']; $form = new Form('projectDeleteForm'); @@ -51,12 +56,9 @@ if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if(ttProjectHelper::get($cl_project_id)) { - if (ttProjectHelper::delete($cl_project_id)) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); + if (ttProjectHelper::delete($cl_project_id)) { + header('Location: projects.php'); + exit(); } else $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { diff --git a/project_edit.php b/project_edit.php index d30782ab5..543c532ef 100644 --- a/project_edit.php +++ b/project_edit.php @@ -40,8 +40,13 @@ header('Location: feature_disabled.php'); exit(); } - $cl_project_id = (int)$request->getParameter('id'); +$project = ttProjectHelper::get($cl_project_id); +if (!$project) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. $users = ttTeamHelper::getActiveUsers(); foreach ($users as $user_item) @@ -58,7 +63,6 @@ $cl_users = $request->getParameter('users', array()); $cl_tasks = $request->getParameter('tasks', array()); } else { - $project = ttProjectHelper::get($cl_project_id); $cl_name = $project['name']; $cl_description = $project['description']; $cl_status = $project['status']; diff --git a/projects.php b/projects.php index 5315c4f70..1d5f7e2e4 100644 --- a/projects.php +++ b/projects.php @@ -31,7 +31,8 @@ import('ttTeamHelper'); // Access checks. -if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { +// TODO: introduce view_projects right to keep access checks simple. +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time') || ttAccessAllowed('manage_projects'))) { header('Location: access_denied.php'); exit(); } @@ -39,8 +40,9 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. -if($user->canManageTeam()) { +if($user->can('manage_projects')) { $active_projects = ttTeamHelper::getActiveProjects($user->team_id); $inactive_projects = ttTeamHelper::getInactiveProjects($user->team_id); } else From f39d6bdcde7c4de3f38dc63e500824d28aa1939c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 01:32:29 +0000 Subject: [PATCH 0066/1848] Introduced parent_id and org_id fields in tt_teams. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 16 +++++++++------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 95bed59a1..ceaf9982e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.75.4183 | Copyright © Anuko | +  Anuko Time Tracker 1.17.76.4184 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 4d7feeb25..1f876470d 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11767"]) { + if ($_POST["convert11744to11776"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -860,6 +860,9 @@ function setChange($sql) { setChange("ALTER TABLE `tt_tmp_refs` drop `timestamp`"); setChange("delete from `tt_tmp_refs`"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.67', modified = now() where param_name = 'version_db' and param_value = '1.17.66'"); + setChange("ALTER TABLE `tt_teams` ADD `parent_id` int(11) default NULL AFTER `id`"); + setChange("ALTER TABLE `tt_teams` ADD `org_id` int(11) default NULL AFTER `parent_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.76', modified = now() where param_name = 'version_db' and param_value = '1.17.67'"); } if ($_POST["cleanup"]) { @@ -905,7 +908,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.67) + Create database structure (v1.17.76)
(applies only to new installations, do not execute when updating)
@@ -945,8 +948,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.67)Update database structure (v1.17.44 to v1.17.76)
diff --git a/mysql.sql b/mysql.sql index ebe59936a..3e4805fe1 100644 --- a/mysql.sql +++ b/mysql.sql @@ -10,12 +10,14 @@ # # Structure for table tt_teams. A team is a group of users for whom we are tracking work time. -# This table stores settings common to all team members such as language, week start day, etc. +# This table stores settings common to all group members such as language, week start day, etc. # CREATE TABLE `tt_teams` ( - `id` int(11) NOT NULL auto_increment, # team id - `name` varchar(80) default NULL, # team name - `currency` varchar(7) default NULL, # team currency symbol + `id` int(11) NOT NULL auto_increment, # group id + `parent_id` int(11) default NULL, # parent group id + `org_id` int(11) default NULL, # organization id (id of top group) + `name` varchar(80) default NULL, # group name + `currency` varchar(7) default NULL, # currency symbol `decimal_mark` char(1) NOT NULL default '.', # separator in decimals `lang` varchar(10) NOT NULL default 'en', # language `date_format` varchar(20) NOT NULL default '%Y-%m-%d', # date format @@ -31,14 +33,14 @@ CREATE TABLE `tt_teams` ( # for example: "0 10 * * 1" for "weekly on Mon at 10:00". `workday_minutes` smallint(4) default 480, # number of work minutes in a regular working day `custom_logo` tinyint(4) default 0, # whether to use a custom logo or not - `config` text default NULL, # miscellaneous team configuration settings + `config` text default NULL, # miscellaneous group configuration settings `created` datetime default NULL, # creation timestamp `created_ip` varchar(45) default NULL, # creator ip `created_by` int(11) default NULL, # creator user_id `modified` datetime default NULL, # modification timestamp `modified_ip` varchar(45) default NULL, # modifier ip `modified_by` int(11) default NULL, # modifier user_id - `status` tinyint(4) default 1, # team status + `status` tinyint(4) default 1, # group status PRIMARY KEY (`id`) ); @@ -450,4 +452,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.67', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.76', now()); # TODO: change when structure changes. From a575a9147976a06263d8a7eae006d6ba3372446e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 09:57:42 +0000 Subject: [PATCH 0067/1848] Added team_id to project delete and update queries to reduce risk of misuse. --- WEB-INF/lib/ttProjectHelper.class.php | 37 +++++++++++++-------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 06605c76a..d3e0eb1b7 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -154,33 +154,31 @@ static function getProjectByName($name) { // delete - deletes things associated with a project and marks the project as deleted. static function delete($id) { + global $user; $mdb2 = getConnection(); - + + // Start with project itself. Reason: if the passed in project_id is bogus, + // we'll fail right here and don't damage any other data. + + // Mark project as deleted and remove associated tasks. + $sql = "update tt_projects set status = NULL, tasks = NULL where id = $id and team_id = $user->team_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error') || 0 == $affected) + return false; // An error ocurred, or 0 rows updated. + // Delete user binds to this project. $sql = "delete from tt_user_project_binds where project_id = $id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - // Delete task binds to this project. - $sql = "delete from tt_project_task_binds where project_id = $id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - // Remove associated tasks. - $sql = "update tt_projects set tasks = NULL where id = $id"; - $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - // Mark project as deleted. - $sql = "update tt_projects set status = NULL where id = $id"; + // Delete task binds to this project. + $sql = "delete from tt_project_task_binds where project_id = $id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - return true; + return true; } // insert function inserts a new project into database. @@ -236,8 +234,8 @@ static function insert($fields) } // update function - updates the project in database. - static function update($fields) - { + static function update($fields) { + global $user; $mdb2 = getConnection(); $project_id = $fields['id']; // Project we are updating. @@ -313,7 +311,8 @@ static function update($fields) // Update project name, description, tasks and status in tt_projects table. $comma_separated = implode(",", $tasks_to_bind); // This is a comma-separated list of associated task ids. - $sql = "update tt_projects set name = ".$mdb2->quote($name).", description = ".$mdb2->quote($description).", tasks = ".$mdb2->quote($comma_separated).", status = $status where id = $project_id"; + $sql = "update tt_projects set name = ".$mdb2->quote($name).", description = ".$mdb2->quote($description). + ", tasks = ".$mdb2->quote($comma_separated).", status = $status where id = $project_id and team_id = $user->team_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ceaf9982e..37e220f6e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.76.4184 | Copyright © Anuko | +  Anuko Time Tracker 1.17.76.4185 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6380ce5acad1e2911e44db3d339183646e3963ac Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 15:16:08 +0000 Subject: [PATCH 0068/1848] Fixed page title. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 4 ++++ profile_edit.php | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 37e220f6e..31553a4f6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.76.4185 | Copyright © Anuko | +  Anuko Time Tracker 1.17.76.4186 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 97ee53dae..ac6e99fe4 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -154,7 +154,11 @@ {if $title} + {if $user->name} + {else} + + {/if}
{$title}{if $timestring}: {$timestring}{/if}
{$user->name|escape} - {$user->role_name|escape}{if $user->behalf_id > 0} {$i18n.label.on_behalf} {$user->behalf_name|escape}{/if}{if $user->team}, {$user->team|escape}{/if}
 
{/if} diff --git a/profile_edit.php b/profile_edit.php index 9c27ab41a..2fed4f6ba 100644 --- a/profile_edit.php +++ b/profile_edit.php @@ -31,11 +31,12 @@ import('ttUserHelper'); import('ttRoleHelper'); -// Access check. +// Access checks. if (!ttAccessAllowed('manage_own_settings')) { header('Location: access_denied.php'); exit(); } +// End of access checks. if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); $can_change_login = $user->canManageTeam(); From 3209a25c21cd59c6476d820624545963a5a4a857 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 16:11:35 +0000 Subject: [PATCH 0069/1848] Added import timestamp and IP for team import operation. --- WEB-INF/lib/ttTeamHelper.class.php | 4 ++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index fb74d8e10..2aff793bc 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -756,6 +756,7 @@ static function getTeamDetails($team_id) { // The insert function creates a new team. static function insert($fields) { + global $user; $mdb2 = getConnection(); // Start with team name and currency. @@ -838,6 +839,9 @@ static function insert($fields) { $values .= ', '.$mdb2->quote($fields['config']); } + $columns .= ', created, created_ip, created_by'; + $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); + $sql = "insert into tt_teams ($columns) values($values)"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 31553a4f6..d3cf38900 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.76.4186 | Copyright © Anuko | +  Anuko Time Tracker 1.17.76.4187 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 1a11a94d4ec3f33d7f92145ad8d6fa8eec4b18ac Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 17:22:47 +0000 Subject: [PATCH 0070/1848] Introduced manage_own_account right. --- WEB-INF/lib/ttRoleHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 7629df422..e4465e52d 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -186,7 +186,7 @@ static function createPredefinedRoles($team_id, $lang) $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; - $rights_comanager = $rights_supervisor.',manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices'; + $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices'; $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; // Active roles. @@ -244,7 +244,7 @@ static function createDefaultRoles() $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; - $rights_comanager = $rights_supervisor.',manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices'; + $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices'; $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; // Active roles. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d3cf38900..e3d4db5f0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.76.4187 | Copyright © Anuko | +  Anuko Time Tracker 1.17.77.4188 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 1f876470d..164a15df8 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11776"]) { + if ($_POST["convert11744to11777"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -863,6 +863,8 @@ function setChange($sql) { setChange("ALTER TABLE `tt_teams` ADD `parent_id` int(11) default NULL AFTER `id`"); setChange("ALTER TABLE `tt_teams` ADD `org_id` int(11) default NULL AFTER `parent_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.76', modified = now() where param_name = 'version_db' and param_value = '1.17.67'"); + setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.76') set rights = replace(rights, ',manage_users', ',manage_own_account,manage_users')"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.77', modified = now() where param_name = 'version_db' and param_value = '1.17.76'"); } if ($_POST["cleanup"]) { @@ -908,7 +910,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.76) + Create database structure (v1.17.77)
(applies only to new installations, do not execute when updating)
@@ -948,8 +950,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.76)Update database structure (v1.17.44 to v1.17.77)
diff --git a/mysql.sql b/mysql.sql index 3e4805fe1..f20e45823 100644 --- a/mysql.sql +++ b/mysql.sql @@ -73,7 +73,7 @@ create unique index role_idx on tt_roles(team_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'); +INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'); # @@ -452,4 +452,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.76', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.77', now()); # TODO: change when structure changes. From b462dba60a4686a99189cb9a6329c2cc99f5f7ac Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 17:47:15 +0000 Subject: [PATCH 0071/1848] Work in progress handling manage_own_account right. --- WEB-INF/templates/footer.tpl | 2 +- profile_edit.php | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e3d4db5f0..c75544271 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.77.4188 | Copyright © Anuko | +  Anuko Time Tracker 1.17.77.4189 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/profile_edit.php b/profile_edit.php index 2fed4f6ba..c64b95bd9 100644 --- a/profile_edit.php +++ b/profile_edit.php @@ -39,7 +39,7 @@ // End of access checks. if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); -$can_change_login = $user->canManageTeam(); +$can_manage_account = $user->can('manage_own_account'); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -125,13 +125,13 @@ } $form = new Form('profileForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','value'=>$cl_login,'enable'=>$can_change_login)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name,'enable'=>$can_manage_account)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','value'=>$cl_login,'enable'=>$can_manage_account)); if (!$auth->isPasswordExternal()) { $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'password1','value'=>$cl_password1)); $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'password2','value'=>$cl_password2)); } -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email,'enable'=>$can_change_login)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email,'enable'=>$can_manage_account)); if ($user->canManageTeam()) { $form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'team_name','value'=>$cl_team)); $form->addInput(array('type'=>'text','maxlength'=>'7','name'=>'currency','value'=>$cl_currency)); @@ -233,13 +233,12 @@ if ($request->isPost()) { // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); - if ($can_change_login) { - if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); + if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); + + // New login must be unique. + if ($cl_login != $user->login && ttUserHelper::getUserByLogin($cl_login)) + $err->add($i18n->get('error.user_exists')); - // New login must be unique. - if ($cl_login != $user->login && ttUserHelper::getUserByLogin($cl_login)) - $err->add($i18n->get('error.user_exists')); - } if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); From bb9bcdeebd85a41052f2e8a0ca63a7b1b0c86985 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 20:07:43 +0000 Subject: [PATCH 0072/1848] Introduced view_projects right. --- WEB-INF/lib/ttRoleHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index e4465e52d..7461ee2cc 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -184,7 +184,7 @@ static function createPredefinedRoles($team_id, $lang) $mdb2 = getConnection(); $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; - $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,manage_own_settings,view_users'; + $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,manage_own_settings,view_projects,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices'; $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; @@ -242,7 +242,7 @@ static function createDefaultRoles() global $user; $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; - $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,manage_own_settings,view_users'; + $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,manage_own_settings,view_projects,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices'; $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c75544271..28e6fffaf 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.77.4189 | Copyright © Anuko | +  Anuko Time Tracker 1.17.78.4190 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 164a15df8..42234bce1 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11777"]) { + if ($_POST["convert11744to11778"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -865,6 +865,8 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.17.76', modified = now() where param_name = 'version_db' and param_value = '1.17.67'"); setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.76') set rights = replace(rights, ',manage_users', ',manage_own_account,manage_users')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.77', modified = now() where param_name = 'version_db' and param_value = '1.17.76'"); + setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.77') set rights = replace(rights, 'manage_own_settings,view_users', 'manage_own_settings,view_projects,view_users')"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.78', modified = now() where param_name = 'version_db' and param_value = '1.17.77'"); } if ($_POST["cleanup"]) { @@ -910,7 +912,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.77) + Create database structure (v1.17.78)
(applies only to new installations, do not execute when updating)
@@ -950,8 +952,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.77)Update database structure (v1.17.44 to v1.17.78)
diff --git a/mysql.sql b/mysql.sql index f20e45823..c82db686b 100644 --- a/mysql.sql +++ b/mysql.sql @@ -73,7 +73,7 @@ create unique index role_idx on tt_roles(team_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'); +INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,manage_own_settings,view_projects,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'); # @@ -452,4 +452,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.77', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.78', now()); # TODO: change when structure changes. From 21054f67875d0c0c947cc46fe438f407dbe94ee7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 20:35:51 +0000 Subject: [PATCH 0073/1848] Renamed view_projects right to view_own_projects. --- WEB-INF/lib/ttRoleHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mobile/projects.php | 2 +- mysql.sql | 4 ++-- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 7461ee2cc..c6cd02ba6 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -184,7 +184,7 @@ static function createPredefinedRoles($team_id, $lang) $mdb2 = getConnection(); $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; - $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,manage_own_settings,view_projects,view_users'; + $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices'; $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; @@ -242,7 +242,7 @@ static function createDefaultRoles() global $user; $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; - $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,manage_own_settings,view_projects,view_users'; + $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices'; $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 28e6fffaf..67a6e0a06 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.78.4190 | Copyright © Anuko | +  Anuko Time Tracker 1.17.79.4191 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 42234bce1..8f1e867f2 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11778"]) { + if ($_POST["convert11744to11779"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -867,6 +867,8 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.17.77', modified = now() where param_name = 'version_db' and param_value = '1.17.76'"); setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.77') set rights = replace(rights, 'manage_own_settings,view_users', 'manage_own_settings,view_projects,view_users')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.78', modified = now() where param_name = 'version_db' and param_value = '1.17.77'"); + setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.78') set rights = replace(rights, 'manage_own_settings,view_projects,view_users', 'view_own_projects,manage_own_settings,view_users')"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.79', modified = now() where param_name = 'version_db' and param_value = '1.17.78'"); } if ($_POST["cleanup"]) { @@ -912,7 +914,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.78) + Create database structure (v1.17.79)
(applies only to new installations, do not execute when updating)
@@ -952,8 +954,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.78)Update database structure (v1.17.44 to v1.17.79)
diff --git a/mobile/projects.php b/mobile/projects.php index 938eab82a..c35e738af 100644 --- a/mobile/projects.php +++ b/mobile/projects.php @@ -31,7 +31,7 @@ import('ttTeamHelper'); // Access checks. -// TODO: introduce view_projects right to keep access checks simple. +// TODO: introduce view_own_projects right to keep access checks simple. if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time') || ttAccessAllowed('manage_projects'))) { header('Location: access_denied.php'); exit(); diff --git a/mysql.sql b/mysql.sql index c82db686b..9d2f1e7b4 100644 --- a/mysql.sql +++ b/mysql.sql @@ -73,7 +73,7 @@ create unique index role_idx on tt_roles(team_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,manage_own_settings,view_projects,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'); +INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,view_own_projects,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'); # @@ -452,4 +452,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.78', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.79', now()); # TODO: change when structure changes. From 216d1c29ae204a1404a5d38cad77abce516e2386 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 20:47:40 +0000 Subject: [PATCH 0074/1848] Refactored headers to use view_own_projects right check. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- WEB-INF/templates/mobile/header.tpl | 2 +- mobile/project_add.php | 1 + mobile/projects.php | 4 ++-- projects.php | 3 +-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 67a6e0a06..e939e021e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.79.4191 | Copyright © Anuko | +  Anuko Time Tracker 1.17.79.4192 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index ac6e99fe4..b74923ba8 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -113,7 +113,7 @@ || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode || $user->isPluginEnabled('cl'))} · {$i18n.menu.charts} {/if} - {if ($user->can('manage_projects') || $user->can('track_own_time') || $user->can('track_time')) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if ($user->can('view_own_projects') || $user->can('manage_projects')) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} · {$i18n.menu.projects} {/if} {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode) && $user->can('manage_tasks')} diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index 507a07e02..7118cfa4e 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -79,7 +79,7 @@ {if $user->isPluginEnabled('ex') && ($user->can('track_own_expenses') || $user->can('track_expenses'))} · {$i18n.menu.expenses} {/if} - {if ($user->can('manage_projects') || $user->can('track_own_time') || $user->can('track_time')) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if ($user->can('view_own_projects') || $user->can('manage_projects')) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} · {$i18n.menu.projects} {/if} {if $user->can('manage_tasks') && $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode} diff --git a/mobile/project_add.php b/mobile/project_add.php index a9495d715..bb0f1d096 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -40,6 +40,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. $users = ttTeamHelper::getActiveUsers(); foreach ($users as $user_item) diff --git a/mobile/projects.php b/mobile/projects.php index c35e738af..a9f8ab02d 100644 --- a/mobile/projects.php +++ b/mobile/projects.php @@ -31,8 +31,7 @@ import('ttTeamHelper'); // Access checks. -// TODO: introduce view_own_projects right to keep access checks simple. -if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time') || ttAccessAllowed('manage_projects'))) { +if (!(ttAccessAllowed('view_own_projects') || ttAccessAllowed('manage_projects'))) { header('Location: access_denied.php'); exit(); } @@ -40,6 +39,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. if($user->can('manage_projects')) { $active_projects = ttTeamHelper::getActiveProjects($user->team_id); diff --git a/projects.php b/projects.php index 1d5f7e2e4..bf6aed1cb 100644 --- a/projects.php +++ b/projects.php @@ -31,8 +31,7 @@ import('ttTeamHelper'); // Access checks. -// TODO: introduce view_projects right to keep access checks simple. -if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time') || ttAccessAllowed('manage_projects'))) { +if (!(ttAccessAllowed('view_own_projects') || ttAccessAllowed('manage_projects'))) { header('Location: access_denied.php'); exit(); } From 1955bb54c5569f779a16eb3b8de9b4684b5f11b4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 23:17:04 +0000 Subject: [PATCH 0075/1848] Split profile page into two for account and group settings to reduce complexity. --- WEB-INF/resources/en.lang.php | 2 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 248 ++++++++++++++++++++++++ WEB-INF/templates/header.tpl | 3 + WEB-INF/templates/profile_edit.tpl | 235 ---------------------- group_edit.php | 301 +++++++++++++++++++++++++++++ profile_edit.php | 248 +----------------------- 7 files changed, 556 insertions(+), 483 deletions(-) create mode 100644 WEB-INF/templates/group_edit.tpl create mode 100644 group_edit.php diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 732141a4a..1613fec90 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -46,6 +46,7 @@ 'menu.help' => 'Help', 'menu.create_team' => 'Create Team', 'menu.profile' => 'Profile', +'menu.group' => 'Group', 'menu.time' => 'Time', 'menu.expenses' => 'Expenses', 'menu.reports' => 'Reports', @@ -268,6 +269,7 @@ 'title.import' => 'Importing Team Data', 'title.options' => 'Options', 'title.profile' => 'Profile', +'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Custom Fields', 'title.cf_add_custom_field' => 'Adding Custom Field', 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e939e021e..35039df11 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.79.4192 | Copyright © Anuko | +  Anuko Time Tracker 1.17.80.4193 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl new file mode 100644 index 000000000..9b341b674 --- /dev/null +++ b/WEB-INF/templates/group_edit.tpl @@ -0,0 +1,248 @@ + + +{$forms.groupForm.open} + +{if $user->canManageTeam()} +{include file="datetime_format_preview.tpl"} +{/if} + + + + + +
+ +{if $user->isManager() || ($user->canManageTeam() && !defined(MANAGER_ONLY_TEAM_SETTINGS))} + + + + + + + + + {if $user->can('manage_roles')} + + + + + {/if} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{if $user->isManager()} + + + + +{/if} + {* initialize preview text *} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{/if} + + + + + + + +
{$i18n.label.team_name}:{$forms.groupForm.team_name.control}
{$i18n.label.currency}:{$forms.groupForm.currency.control}
{$i18n.label.roles}:{$i18n.label.configure}
{$i18n.label.language}:{$forms.groupForm.lang.control}
{$i18n.label.decimal_mark}:{$forms.groupForm.decimal_mark.control}  
{$i18n.label.date_format}:{$forms.groupForm.date_format.control}  
{$i18n.label.time_format}:{$forms.groupForm.time_format.control}  
{$i18n.label.week_start}:{$forms.groupForm.start_week.control}
{$i18n.form.profile.show_holidays}:{$forms.groupForm.show_holidays.control} {$i18n.label.what_is_it}
{$i18n.form.profile.tracking_mode}:{$forms.groupForm.tracking_mode.control} {$forms.profileForm.task_required.control}
{$i18n.form.profile.record_type}:{$forms.groupForm.record_type.control}
{$i18n.form.profile.punch_mode}:{$forms.groupForm.punch_mode.control} {$i18n.label.what_is_it}
{$i18n.form.profile.allow_overlap}:{$forms.groupForm.allow_overlap.control} {$i18n.label.what_is_it}
{$i18n.form.profile.future_entries}:{$forms.groupForm.future_entries.control} {$i18n.label.what_is_it}
{$i18n.form.profile.uncompleted_indicators}:{$forms.groupForm.uncompleted_indicators.control} {$i18n.label.what_is_it}
{$i18n.label.bcc}:{$forms.groupForm.bcc_email.control} {$i18n.label.what_is_it}
  
{$i18n.form.profile.plugins}
 
{$forms.groupForm.charts.control}
{$forms.groupForm.clients.control} {$forms.profileForm.client_required.control}
{$forms.groupForm.invoices.control}
{$forms.groupForm.paid_status.control}
{$forms.groupForm.custom_fields.control} {$i18n.label.configure}
{$forms.groupForm.expenses.control} {$forms.profileForm.tax_expenses.control} {$i18n.label.configure}
{$forms.groupForm.notifications.control} {$i18n.label.configure}
{$forms.groupForm.locking.control} {$i18n.label.configure}
{$forms.groupForm.quotas.control} {$i18n.label.configure}
{$forms.groupForm.week_view.control} {$i18n.label.configure}
 
{$forms.groupForm.btn_save.control}
+
+{$forms.groupForm.close} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index b74923ba8..3ad3fb5fc 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -85,6 +85,9 @@ {$i18n.menu.logout} · {if $user->can('manage_own_settings')} {$i18n.menu.profile} · + {/if} + {if $user->can('manage_basic_settings')} + {$i18n.menu.group} · {/if} {$i18n.menu.forum} · {$i18n.menu.help} diff --git a/WEB-INF/templates/profile_edit.tpl b/WEB-INF/templates/profile_edit.tpl index 244c6cb15..1fb040005 100644 --- a/WEB-INF/templates/profile_edit.tpl +++ b/WEB-INF/templates/profile_edit.tpl @@ -1,103 +1,5 @@ - - {$forms.profileForm.open} -{if $user->canManageTeam()} -{include file="datetime_format_preview.tpl"} -{/if} - - -{if $user->isManager() || ($user->canManageTeam() && !defined(MANAGER_ONLY_TEAM_SETTINGS))} - - - - - - - - - - - - {if $user->can('manage_roles')} - - - - - {/if} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{if $user->isManager()} - - - - -{/if} - {* initialize preview text *} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{/if} - diff --git a/group_edit.php b/group_edit.php new file mode 100644 index 000000000..0ce93582f --- /dev/null +++ b/group_edit.php @@ -0,0 +1,301 @@ +isPost()) { + $cl_team = trim($request->getParameter('team_name')); + $cl_currency = trim($request->getParameter('currency')); + if (!$cl_currency) $cl_currency = CURRENCY_DEFAULT; + $cl_lang = $request->getParameter('lang'); + $cl_decimal_mark = $request->getParameter('decimal_mark'); + $cl_date_format = $request->getParameter('date_format'); + $cl_time_format = $request->getParameter('time_format'); + $cl_start_week = $request->getParameter('start_week'); + $cl_show_holidays = $request->getParameter('show_holidays'); + $cl_tracking_mode = $request->getParameter('tracking_mode'); + $cl_project_required = $request->getParameter('project_required'); + $cl_task_required = $request->getParameter('task_required'); + $cl_record_type = $request->getParameter('record_type'); + $cl_punch_mode = $request->getParameter('punch_mode'); + $cl_allow_overlap = $request->getParameter('allow_overlap'); + $cl_future_entries = $request->getParameter('future_entries'); + $cl_uncompleted_indicators = $request->getParameter('uncompleted_indicators'); + $cl_bcc_email = trim($request->getParameter('bcc_email')); + + // Plugin checkboxes. + $cl_charts = $request->getParameter('charts'); + $cl_clients = $request->getParameter('clients'); + $cl_client_required = $request->getParameter('client_required'); + $cl_invoices = $request->getParameter('invoices'); + $cl_paid_status = $request->getParameter('paid_status'); + $cl_custom_fields = $request->getParameter('custom_fields'); + $cl_expenses = $request->getParameter('expenses'); + $cl_tax_expenses = $request->getParameter('tax_expenses'); + $cl_notifications = $request->getParameter('notifications'); + $cl_locking = $request->getParameter('locking'); + $cl_quotas = $request->getParameter('quotas'); + $cl_week_view = $request->getParameter('week_view'); +} else { + $cl_team = $user->team; + $cl_currency = ($user->currency == ''? CURRENCY_DEFAULT : $user->currency); + $cl_lang = $user->lang; + $cl_decimal_mark = $user->decimal_mark; + $cl_date_format = $user->date_format; + $cl_time_format = $user->time_format; + $cl_start_week = $user->week_start; + $cl_show_holidays = $user->show_holidays; + $cl_tracking_mode = $user->tracking_mode; + $cl_project_required = $user->project_required; + $cl_task_required = $user->task_required; + $cl_record_type = $user->record_type; + $cl_punch_mode = $user->punch_mode; + $cl_allow_overlap = $user->allow_overlap; + $cl_future_entries = $user->future_entries; + $cl_uncompleted_indicators = $user->uncompleted_indicators; + $cl_bcc_email = $user->bcc_email; + + // Which plugins do we have enabled? + $plugins = explode(',', $user->plugins); + $cl_charts = in_array('ch', $plugins); + $cl_clients = in_array('cl', $plugins); + $cl_client_required = in_array('cm', $plugins); + $cl_invoices = in_array('iv', $plugins); + $cl_paid_status = in_array('ps', $plugins); + $cl_custom_fields = in_array('cf', $plugins); + $cl_expenses = in_array('ex', $plugins); + $cl_tax_expenses = in_array('et', $plugins); + $cl_notifications = in_array('no', $plugins); + $cl_locking = in_array('lk', $plugins); + $cl_quotas = in_array('mq', $plugins); + $cl_week_view = in_array('wv', $plugins); +} + +$form = new Form('groupForm'); +$form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'team_name','value'=>$cl_team)); +$form->addInput(array('type'=>'text','maxlength'=>'7','name'=>'currency','value'=>$cl_currency)); + +// Prepare an array of available languages. +$lang_files = I18n::getLangFileList(); +foreach ($lang_files as $lfile) { + $content = file(RESOURCE_DIR."/".$lfile); + $lname = ''; + foreach ($content as $line) { + if (strstr($line, 'i18n_language')) { + $a = explode('=', $line); + $lname = trim(str_replace(';','',str_replace("'","",$a[1]))); + break; + } + } + unset($content); + $longname_lang[] = array('id'=>I18n::getLangFromFilename($lfile),'name'=>$lname); +} +$longname_lang = mu_sort($longname_lang, 'name'); +$form->addInput(array('type'=>'combobox','name'=>'lang','style'=>'width: 200px','data'=>$longname_lang,'datakeys'=>array('id','name'),'value'=>$cl_lang)); + +$DECIMAL_MARK_OPTIONS = array(array('id'=>'.','name'=>'.'),array('id'=>',','name'=>',')); +$form->addInput(array('type'=>'combobox','name'=>'decimal_mark','style'=>'width: 150px','data'=>$DECIMAL_MARK_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_decimal_mark, + 'onchange'=>'adjustDecimalPreview()')); + +$DATE_FORMAT_OPTIONS = array( + array('id'=>'%Y-%m-%d','name'=>'Y-m-d'), + array('id'=>'%m/%d/%Y','name'=>'m/d/Y'), + array('id'=>'%d.%m.%Y','name'=>'d.m.Y'), + array('id'=>'%d.%m.%Y %a','name'=>'d.m.Y a')); +$form->addInput(array('type'=>'combobox','name'=>'date_format','style'=>'width: 150px;','data'=>$DATE_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_date_format, + 'onchange'=>'MakeFormatPreview("date_format_preview", this);')); +$TIME_FORMAT_OPTIONS = array( + array('id'=>'%H:%M','name'=>$i18n->get('form.profile.24_hours')), + array('id'=>'%I:%M %p','name'=>$i18n->get('form.profile.12_hours'))); +$form->addInput(array('type'=>'combobox','name'=>'time_format','style'=>'width: 150px;','data'=>$TIME_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_time_format, + 'onchange'=>'MakeFormatPreview("time_format_preview", this);')); + +// Prepare week start choices. +$week_start_options = array(); +foreach ($i18n->weekdayNames as $id => $week_dn) { + $week_start_options[] = array('id' => $id, 'name' => $week_dn); +} +$form->addInput(array('type'=>'combobox','name'=>'start_week','style'=>'width: 150px;','data'=>$week_start_options,'datakeys'=>array('id','name'),'value'=>$cl_start_week)); + +// Show holidays checkbox. +$form->addInput(array('type'=>'checkbox','name'=>'show_holidays','value'=>$cl_show_holidays)); + +// Prepare tracking mode choices. +$tracking_mode_options = array(); +$tracking_mode_options[MODE_TIME] = $i18n->get('form.profile.mode_time'); +$tracking_mode_options[MODE_PROJECTS] = $i18n->get('form.profile.mode_projects'); +$tracking_mode_options[MODE_PROJECTS_AND_TASKS] = $i18n->get('form.profile.mode_projects_and_tasks'); +$form->addInput(array('type'=>'combobox','name'=>'tracking_mode','style'=>'width: 150px;','data'=>$tracking_mode_options,'value'=>$cl_tracking_mode,'onchange'=>'handleTaskRequiredCheckbox()')); +$form->addInput(array('type'=>'checkbox','name'=>'project_required','value'=>$cl_project_required)); +$form->addInput(array('type'=>'checkbox','name'=>'task_required','value'=>$cl_task_required)); + +// Prepare record type choices. +$record_type_options = array(); +$record_type_options[TYPE_ALL] = $i18n->get('form.profile.type_all'); +$record_type_options[TYPE_START_FINISH] = $i18n->get('form.profile.type_start_finish'); +$record_type_options[TYPE_DURATION] = $i18n->get('form.profile.type_duration'); +$form->addInput(array('type'=>'combobox','name'=>'record_type','style'=>'width: 150px;','data'=>$record_type_options,'value'=>$cl_record_type)); + +// Punch mode checkbox. +$form->addInput(array('type'=>'checkbox','name'=>'punch_mode','value'=>$cl_punch_mode)); + +// Allow overlap checkbox. +$form->addInput(array('type'=>'checkbox','name'=>'allow_overlap','value'=>$cl_allow_overlap)); + +// Future entries checkbox. +$form->addInput(array('type'=>'checkbox','name'=>'future_entries','value'=>$cl_future_entries)); + +// Uncompleted indicators checkbox. +$form->addInput(array('type'=>'checkbox','name'=>'uncompleted_indicators','value'=>$cl_uncompleted_indicators)); + +// Add bcc email control, for manager only. +if ($user->can('manage_advanced_settings')) { + $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'bcc_email','value'=>$cl_bcc_email)); +} + +// Plugin checkboxes. +$form->addInput(array('type'=>'checkbox','name'=>'charts','value'=>$cl_charts)); +$form->addInput(array('type'=>'checkbox','name'=>'clients','value'=>$cl_clients,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'client_required','value'=>$cl_client_required)); +$form->addInput(array('type'=>'checkbox','name'=>'invoices','value'=>$cl_invoices)); +$form->addInput(array('type'=>'checkbox','name'=>'paid_status','value'=>$cl_paid_status)); +$form->addInput(array('type'=>'checkbox','name'=>'custom_fields','value'=>$cl_custom_fields,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'expenses','value'=>$cl_expenses,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'tax_expenses','value'=>$cl_tax_expenses)); +$form->addInput(array('type'=>'checkbox','name'=>'notifications','value'=>$cl_notifications,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'locking','value'=>$cl_locking,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'quotas','value'=>$cl_quotas,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'week_view','value'=>$cl_week_view,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_team, true)) $err->add($i18n->get('error.field'), $i18n->get('label.team_name')); + if (!ttValidString($cl_currency, true)) $err->add($i18n->get('error.field'), $i18n->get('label.currency')); + if ($user->can('manage_advanced_settings')) { + if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.bcc')); + } + // Finished validating user input. + + if ($err->no()) { + $update_result = true; + if ($user->canManageTeam()) { + + // Prepare plugins string. + if ($cl_charts) + $plugins .= ',ch'; + if ($cl_clients) + $plugins .= ',cl'; + if ($cl_client_required) + $plugins .= ',cm'; + if ($cl_invoices) + $plugins .= ',iv'; + if ($cl_paid_status) + $plugins .= ',ps'; + if ($cl_custom_fields) + $plugins .= ',cf'; + if ($cl_expenses) + $plugins .= ',ex'; + if ($cl_tax_expenses) + $plugins .= ',et'; + if ($cl_notifications) + $plugins .= ',no'; + if ($cl_locking) + $plugins .= ',lk'; + if ($cl_quotas) + $plugins .= ',mq'; + if ($cl_week_view) + $plugins .= ',wv'; + + // Recycle week view plugin options as they are not configured on this page. + $existing_plugins = explode(',', $user->plugins); + if (in_array('wvn', $existing_plugins)) + $plugins .= ',wvn'; + if (in_array('wvl', $existing_plugins)) + $plugins .= ',wvl'; + if (in_array('wvns', $existing_plugins)) + $plugins .= ',wvns'; + + $plugins = trim($plugins, ','); + + // Prepare config string. + if ($cl_show_holidays) + $config .= ',show_holidays'; + if ($cl_punch_mode) + $config .= ',punch_mode'; + if ($cl_allow_overlap) + $config .= ',allow_overlap'; + if ($cl_future_entries) + $config .= ',future_entries'; + if ($cl_uncompleted_indicators) + $config .= ',uncompleted_indicators'; + $config = trim($config, ','); + + $update_result = ttTeamHelper::update($user->team_id, array( + 'name' => $cl_team, + 'currency' => $cl_currency, + 'lang' => $cl_lang, + 'decimal_mark' => $cl_decimal_mark, + 'date_format' => $cl_date_format, + 'time_format' => $cl_time_format, + 'week_start' => $cl_start_week, + 'tracking_mode' => $cl_tracking_mode, + 'project_required' => $cl_project_required, + 'task_required' => $cl_task_required, + 'record_type' => $cl_record_type, + 'uncompleted_indicators' => $cl_uncompleted_indicators, + 'bcc_email' => $cl_bcc_email, + 'plugins' => $plugins, + 'config' => $config)); + } + if ($update_result) { + header('Location: time.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } +} // isPost + +$smarty->assign('auth_external', $auth->isPasswordExternal()); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="handleTaskRequiredCheckbox(); handlePluginCheckboxes();"'); +$smarty->assign('title', $i18n->get('title.group')); +$smarty->assign('content_page_name', 'group_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/profile_edit.php b/profile_edit.php index c64b95bd9..9de1820ee 100644 --- a/profile_edit.php +++ b/profile_edit.php @@ -38,7 +38,6 @@ } // End of access checks. -if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); $can_manage_account = $user->can('manage_own_account'); if ($request->isPost()) { @@ -49,79 +48,10 @@ $cl_password2 = $request->getParameter('password2'); } $cl_email = trim($request->getParameter('email')); - - if ($user->canManageTeam()) { - $cl_team = trim($request->getParameter('team_name')); - $cl_currency = trim($request->getParameter('currency')); - if (!$cl_currency) $cl_currency = CURRENCY_DEFAULT; - $cl_lang = $request->getParameter('lang'); - $cl_decimal_mark = $request->getParameter('decimal_mark'); - $cl_date_format = $request->getParameter('date_format'); - $cl_time_format = $request->getParameter('time_format'); - $cl_start_week = $request->getParameter('start_week'); - $cl_show_holidays = $request->getParameter('show_holidays'); - $cl_tracking_mode = $request->getParameter('tracking_mode'); - $cl_project_required = $request->getParameter('project_required'); - $cl_task_required = $request->getParameter('task_required'); - $cl_record_type = $request->getParameter('record_type'); - $cl_punch_mode = $request->getParameter('punch_mode'); - $cl_allow_overlap = $request->getParameter('allow_overlap'); - $cl_future_entries = $request->getParameter('future_entries'); - $cl_uncompleted_indicators = $request->getParameter('uncompleted_indicators'); - $cl_bcc_email = trim($request->getParameter('bcc_email')); - - // Plugin checkboxes. - $cl_charts = $request->getParameter('charts'); - $cl_clients = $request->getParameter('clients'); - $cl_client_required = $request->getParameter('client_required'); - $cl_invoices = $request->getParameter('invoices'); - $cl_paid_status = $request->getParameter('paid_status'); - $cl_custom_fields = $request->getParameter('custom_fields'); - $cl_expenses = $request->getParameter('expenses'); - $cl_tax_expenses = $request->getParameter('tax_expenses'); - $cl_notifications = $request->getParameter('notifications'); - $cl_locking = $request->getParameter('locking'); - $cl_quotas = $request->getParameter('quotas'); - $cl_week_view = $request->getParameter('week_view'); - } } else { $cl_name = $user->name; $cl_login = $user->login; $cl_email = $user->email; - if ($user->canManageTeam()) { - $cl_team = $user->team; - $cl_currency = ($user->currency == ''? CURRENCY_DEFAULT : $user->currency); - $cl_lang = $user->lang; - $cl_decimal_mark = $user->decimal_mark; - $cl_date_format = $user->date_format; - $cl_time_format = $user->time_format; - $cl_start_week = $user->week_start; - $cl_show_holidays = $user->show_holidays; - $cl_tracking_mode = $user->tracking_mode; - $cl_project_required = $user->project_required; - $cl_task_required = $user->task_required; - $cl_record_type = $user->record_type; - $cl_punch_mode = $user->punch_mode; - $cl_allow_overlap = $user->allow_overlap; - $cl_future_entries = $user->future_entries; - $cl_uncompleted_indicators = $user->uncompleted_indicators; - $cl_bcc_email = $user->bcc_email; - - // Which plugins do we have enabled? - $plugins = explode(',', $user->plugins); - $cl_charts = in_array('ch', $plugins); - $cl_clients = in_array('cl', $plugins); - $cl_client_required = in_array('cm', $plugins); - $cl_invoices = in_array('iv', $plugins); - $cl_paid_status = in_array('ps', $plugins); - $cl_custom_fields = in_array('cf', $plugins); - $cl_expenses = in_array('ex', $plugins); - $cl_tax_expenses = in_array('et', $plugins); - $cl_notifications = in_array('no', $plugins); - $cl_locking = in_array('lk', $plugins); - $cl_quotas = in_array('mq', $plugins); - $cl_week_view = in_array('wv', $plugins); - } } $form = new Form('profileForm'); @@ -132,102 +62,6 @@ $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'password2','value'=>$cl_password2)); } $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email,'enable'=>$can_manage_account)); -if ($user->canManageTeam()) { - $form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'team_name','value'=>$cl_team)); - $form->addInput(array('type'=>'text','maxlength'=>'7','name'=>'currency','value'=>$cl_currency)); - - // Prepare an array of available languages. - $lang_files = I18n::getLangFileList(); - foreach ($lang_files as $lfile) { - $content = file(RESOURCE_DIR."/".$lfile); - $lname = ''; - foreach ($content as $line) { - if (strstr($line, 'i18n_language')) { - $a = explode('=', $line); - $lname = trim(str_replace(';','',str_replace("'","",$a[1]))); - break; - } - } - unset($content); - $longname_lang[] = array('id'=>I18n::getLangFromFilename($lfile),'name'=>$lname); - } - $longname_lang = mu_sort($longname_lang, 'name'); - $form->addInput(array('type'=>'combobox','name'=>'lang','style'=>'width: 200px','data'=>$longname_lang,'datakeys'=>array('id','name'),'value'=>$cl_lang)); - - $DECIMAL_MARK_OPTIONS = array(array('id'=>'.','name'=>'.'),array('id'=>',','name'=>',')); - $form->addInput(array('type'=>'combobox','name'=>'decimal_mark','style'=>'width: 150px','data'=>$DECIMAL_MARK_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_decimal_mark, - 'onchange'=>'adjustDecimalPreview()')); - - $DATE_FORMAT_OPTIONS = array( - array('id'=>'%Y-%m-%d','name'=>'Y-m-d'), - array('id'=>'%m/%d/%Y','name'=>'m/d/Y'), - array('id'=>'%d.%m.%Y','name'=>'d.m.Y'), - array('id'=>'%d.%m.%Y %a','name'=>'d.m.Y a')); - $form->addInput(array('type'=>'combobox','name'=>'date_format','style'=>'width: 150px;','data'=>$DATE_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_date_format, - 'onchange'=>'MakeFormatPreview("date_format_preview", this);')); - $TIME_FORMAT_OPTIONS = array( - array('id'=>'%H:%M','name'=>$i18n->get('form.profile.24_hours')), - array('id'=>'%I:%M %p','name'=>$i18n->get('form.profile.12_hours'))); - $form->addInput(array('type'=>'combobox','name'=>'time_format','style'=>'width: 150px;','data'=>$TIME_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_time_format, - 'onchange'=>'MakeFormatPreview("time_format_preview", this);')); - - // Prepare week start choices. - $week_start_options = array(); - foreach ($i18n->weekdayNames as $id => $week_dn) { - $week_start_options[] = array('id' => $id, 'name' => $week_dn); - } - $form->addInput(array('type'=>'combobox','name'=>'start_week','style'=>'width: 150px;','data'=>$week_start_options,'datakeys'=>array('id','name'),'value'=>$cl_start_week)); - - // Show holidays checkbox. - $form->addInput(array('type'=>'checkbox','name'=>'show_holidays','value'=>$cl_show_holidays)); - - // Prepare tracking mode choices. - $tracking_mode_options = array(); - $tracking_mode_options[MODE_TIME] = $i18n->get('form.profile.mode_time'); - $tracking_mode_options[MODE_PROJECTS] = $i18n->get('form.profile.mode_projects'); - $tracking_mode_options[MODE_PROJECTS_AND_TASKS] = $i18n->get('form.profile.mode_projects_and_tasks'); - $form->addInput(array('type'=>'combobox','name'=>'tracking_mode','style'=>'width: 150px;','data'=>$tracking_mode_options,'value'=>$cl_tracking_mode,'onchange'=>'handleTaskRequiredCheckbox()')); - $form->addInput(array('type'=>'checkbox','name'=>'project_required','value'=>$cl_project_required)); - $form->addInput(array('type'=>'checkbox','name'=>'task_required','value'=>$cl_task_required)); - - // Prepare record type choices. - $record_type_options = array(); - $record_type_options[TYPE_ALL] = $i18n->get('form.profile.type_all'); - $record_type_options[TYPE_START_FINISH] = $i18n->get('form.profile.type_start_finish'); - $record_type_options[TYPE_DURATION] = $i18n->get('form.profile.type_duration'); - $form->addInput(array('type'=>'combobox','name'=>'record_type','style'=>'width: 150px;','data'=>$record_type_options,'value'=>$cl_record_type)); - - // Punch mode checkbox. - $form->addInput(array('type'=>'checkbox','name'=>'punch_mode','value'=>$cl_punch_mode)); - - // Allow overlap checkbox. - $form->addInput(array('type'=>'checkbox','name'=>'allow_overlap','value'=>$cl_allow_overlap)); - - // Future entries checkbox. - $form->addInput(array('type'=>'checkbox','name'=>'future_entries','value'=>$cl_future_entries)); - - // Uncompleted indicators checkbox. - $form->addInput(array('type'=>'checkbox','name'=>'uncompleted_indicators','value'=>$cl_uncompleted_indicators)); - - // Add bcc email control, for manager only. - if ($user->isManager()) { - $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'bcc_email','value'=>$cl_bcc_email)); - } - - // Plugin checkboxes. - $form->addInput(array('type'=>'checkbox','name'=>'charts','value'=>$cl_charts)); - $form->addInput(array('type'=>'checkbox','name'=>'clients','value'=>$cl_clients,'onchange'=>'handlePluginCheckboxes()')); - $form->addInput(array('type'=>'checkbox','name'=>'client_required','value'=>$cl_client_required)); - $form->addInput(array('type'=>'checkbox','name'=>'invoices','value'=>$cl_invoices)); - $form->addInput(array('type'=>'checkbox','name'=>'paid_status','value'=>$cl_paid_status)); - $form->addInput(array('type'=>'checkbox','name'=>'custom_fields','value'=>$cl_custom_fields,'onchange'=>'handlePluginCheckboxes()')); - $form->addInput(array('type'=>'checkbox','name'=>'expenses','value'=>$cl_expenses,'onchange'=>'handlePluginCheckboxes()')); - $form->addInput(array('type'=>'checkbox','name'=>'tax_expenses','value'=>$cl_tax_expenses)); - $form->addInput(array('type'=>'checkbox','name'=>'notifications','value'=>$cl_notifications,'onchange'=>'handlePluginCheckboxes()')); - $form->addInput(array('type'=>'checkbox','name'=>'locking','value'=>$cl_locking,'onchange'=>'handlePluginCheckboxes()')); - $form->addInput(array('type'=>'checkbox','name'=>'quotas','value'=>$cl_quotas,'onchange'=>'handlePluginCheckboxes()')); - $form->addInput(array('type'=>'checkbox','name'=>'week_view','value'=>$cl_week_view,'onchange'=>'handlePluginCheckboxes()')); -} $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { @@ -246,94 +80,15 @@ $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); } if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - if ($user->canManageTeam()) { - if (!ttValidString($cl_team, true)) $err->add($i18n->get('error.field'), $i18n->get('label.team_name')); - if (!ttValidString($cl_currency, true)) $err->add($i18n->get('error.field'), $i18n->get('label.currency')); - if ($user->isManager()) { - if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.bcc')); - } - } // Finished validating user input. if ($err->no()) { - $update_result = true; - if ($user->canManageTeam()) { - - // Prepare plugins string. - if ($cl_charts) - $plugins .= ',ch'; - if ($cl_clients) - $plugins .= ',cl'; - if ($cl_client_required) - $plugins .= ',cm'; - if ($cl_invoices) - $plugins .= ',iv'; - if ($cl_paid_status) - $plugins .= ',ps'; - if ($cl_custom_fields) - $plugins .= ',cf'; - if ($cl_expenses) - $plugins .= ',ex'; - if ($cl_tax_expenses) - $plugins .= ',et'; - if ($cl_notifications) - $plugins .= ',no'; - if ($cl_locking) - $plugins .= ',lk'; - if ($cl_quotas) - $plugins .= ',mq'; - if ($cl_week_view) - $plugins .= ',wv'; - - // Recycle week view plugin options as they are not configured on this page. - $existing_plugins = explode(',', $user->plugins); - if (in_array('wvn', $existing_plugins)) - $plugins .= ',wvn'; - if (in_array('wvl', $existing_plugins)) - $plugins .= ',wvl'; - if (in_array('wvns', $existing_plugins)) - $plugins .= ',wvns'; - - $plugins = trim($plugins, ','); - - // Prepare config string. - if ($cl_show_holidays) - $config .= ',show_holidays'; - if ($cl_punch_mode) - $config .= ',punch_mode'; - if ($cl_allow_overlap) - $config .= ',allow_overlap'; - if ($cl_future_entries) - $config .= ',future_entries'; - if ($cl_uncompleted_indicators) - $config .= ',uncompleted_indicators'; - $config = trim($config, ','); - - $update_result = ttTeamHelper::update($user->team_id, array( - 'name' => $cl_team, - 'currency' => $cl_currency, - 'lang' => $cl_lang, - 'decimal_mark' => $cl_decimal_mark, - 'date_format' => $cl_date_format, - 'time_format' => $cl_time_format, - 'week_start' => $cl_start_week, - 'tracking_mode' => $cl_tracking_mode, - 'project_required' => $cl_project_required, - 'task_required' => $cl_task_required, - 'record_type' => $cl_record_type, - 'uncompleted_indicators' => $cl_uncompleted_indicators, - 'bcc_email' => $cl_bcc_email, - 'plugins' => $plugins, - 'config' => $config)); - } - if ($update_result) { - $update_result = ttUserHelper::update($user->id, array( + $update_result = ttUserHelper::update($user->id, array( 'name' => $cl_name, 'login' => $cl_login, 'password' => $cl_password1, 'email' => $cl_email, 'status' => ACTIVE)); - } if ($update_result) { header('Location: time.php'); exit(); @@ -344,7 +99,6 @@ $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="handleTaskRequiredCheckbox(); handlePluginCheckboxes();"'); $smarty->assign('title', $i18n->get('title.profile')); $smarty->assign('content_page_name', 'profile_edit.tpl'); $smarty->display('index.tpl'); From a490f47a3440b85efc7ef9c1795dd59dac60c83b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 23:30:07 +0000 Subject: [PATCH 0076/1848] Introduced menu.group into translation files. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 55 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 3b429f5d5..3e7cc33ac 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -48,6 +48,8 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', 'menu.profile' => 'Perfil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Temps', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 0eccd9fdc..961a69b5e 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -51,6 +51,7 @@ // 'menu.create_team' => 'Create Team', 'menu.profile' => 'Profil', // TODO: translate the following. +// 'menu.group' => 'Group', // 'menu.time' => 'Time', // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Sestavy', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 424346667..fd707ea4f 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Hjælp', 'menu.create_team' => 'Lav et team', 'menu.profile' => 'Profil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Tid', 'menu.expenses' => 'Udgifter', 'menu.reports' => 'Rapporter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 34d050c05..0a515068b 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Hilfe', 'menu.create_team' => 'Neues Team', 'menu.profile' => 'Profil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Zeiten', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Berichte', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 3c5f91532..a238cdd84 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -47,6 +47,8 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', 'menu.profile' => 'Perfil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Tiempo', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 33085b1d2..9a3e4de39 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -50,6 +50,8 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', 'menu.profile' => 'Profiili', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Aeg', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 654674b1a..d1a5f2507 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -47,6 +47,8 @@ 'menu.help' => 'راهنما', 'menu.create_team' => 'ایجاد گروه', 'menu.profile' => 'پروفايل', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'زمان', 'menu.expenses' => 'هزينه ها', 'menu.reports' => 'گزارشات', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 967c251d8..e288d1d79 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Apua', 'menu.create_team' => 'Luo tiimi', 'menu.profile' => 'Profiili', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Tunnit', 'menu.expenses' => 'Kulut', 'menu.reports' => 'Raportit', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index aafbb5dca..54309ae19 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Aide', 'menu.create_team' => 'Créer une équipe', 'menu.profile' => 'Profil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Temps', 'menu.expenses' => 'Dépenses', 'menu.reports' => 'Rapports', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index e9f4790c0..a3827d17c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Βοήθεια', 'menu.create_team' => 'Δημιουργία ομάδας', 'menu.profile' => 'Προφίλ', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Χρόνος', 'menu.expenses' => 'Έξοδα', 'menu.reports' => 'Αναφορές', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 3426aa870..a6ceca7fa 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -47,6 +47,8 @@ 'menu.help' => 'עזרה', 'menu.create_team' => 'צור צוות', 'menu.profile' => 'פרופיל', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'זמן', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index fb891c8c0..904ccdefe 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -48,6 +48,8 @@ 'menu.help' => 'Segítség', 'menu.create_team' => 'Csoport létrehozása', 'menu.profile' => 'Profil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Munkaidő', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index e2258bb74..6cc4b7571 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -48,6 +48,8 @@ 'menu.help' => 'Aiuto', 'menu.create_team' => 'Crea gruppo', 'menu.profile' => 'Profilo', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Tempo', 'menu.expenses' => 'Spese', 'menu.reports' => 'Rapporti', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 880b95cd8..e92a03e0d 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -48,6 +48,8 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', 'menu.profile' => 'プロファイル', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => '時間', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 6e0a7e292..85754e635 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -48,6 +48,8 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', 'menu.profile' => '프로필', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => '시간', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index be2fcf622..e083705e9 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Help', 'menu.create_team' => 'Maak team', 'menu.profile' => 'Profiel', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Tijden', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Rapporten', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 71a8959cf..0acce80cd 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -49,6 +49,8 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', 'menu.profile' => 'Profil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Tid', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index fd599500f..ccb7dc2b9 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Pomoc', 'menu.create_team' => 'Stwórz zespół', 'menu.profile' => 'Profil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Czas', 'menu.expenses' => 'Wydatki', 'menu.reports' => 'Raporty', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 6fcd6c3ce..6691dad1f 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Ajuda', 'menu.create_team' => 'Criar equipe', 'menu.profile' => 'Perfil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Tempo', 'menu.expenses' => 'Gastos', 'menu.reports' => 'Relatórios', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 7b87af001..d05a39cab 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -50,6 +50,8 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', 'menu.profile' => 'Perfil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Tempo', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 357d6448e..a649d3ac8 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -50,6 +50,8 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', 'menu.profile' => 'Profil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Timpul', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 14b3e6e8d..cfdee9220 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -46,6 +46,7 @@ 'menu.help' => 'Справка', 'menu.create_team' => 'Создать команду', 'menu.profile' => 'Профиль', +'menu.group' => 'Группа', 'menu.time' => 'Время', 'menu.expenses' => 'Расходы', 'menu.reports' => 'Отчёты', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 4dbffff2f..1790729c9 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Pomoc', 'menu.create_team' => 'Vytvoriť tím', 'menu.profile' => 'Profil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Časový záznam', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 8c93e4000..3b417fb49 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -51,6 +51,7 @@ // 'menu.create_team' => 'Create Team', 'menu.profile' => 'Profil', // TODO: translate the following. +// 'menu.group' => 'Group', // 'menu.time' => 'Time', // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Poročila', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 5e7f56e9f..32d789ddc 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Pomoć', 'menu.create_team' => 'Napravi tim', 'menu.profile' => 'Profil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Vreme', 'menu.expenses' => 'Troškovi', 'menu.reports' => 'Izveštaji', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 37e8dffe3..bdc2fa87e 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -46,6 +46,8 @@ 'menu.help' => 'Hjälp', 'menu.create_team' => 'Skapa arbetsgrupp', 'menu.profile' => 'Profil', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Tider', 'menu.expenses' => 'Kostnader', 'menu.reports' => 'Rapporter', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index bbf97dbf8..6828cb857 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -50,6 +50,8 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', 'menu.profile' => 'Profili', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => 'Zaman', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 558427534..de8b5d746 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -47,6 +47,8 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', 'menu.profile' => '简介', +// TODO: translate the following. +// 'menu.group' => 'Group', 'menu.time' => '时间记录', 'menu.expenses' => '费用', 'menu.reports' => '报告', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 16c806222..d5bd872f4 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -48,6 +48,7 @@ // TODO: translate the following. // 'menu.create_team' => 'Create Team', // 'menu.profile' => 'Profile', +// 'menu.group' => 'Group', // 'menu.time' => 'Time', // 'menu.expenses' => 'Expenses', 'menu.reports' => '報告', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 35039df11..ccba58341 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
@@ -128,143 +30,6 @@ function handlePluginCheckboxes() { {$i18n.label.required_fields}
 
{$i18n.label.team_name}:{$forms.profileForm.team_name.control}
{$i18n.label.currency}:{$forms.profileForm.currency.control}
{$i18n.label.roles}:{$i18n.label.configure}
{$i18n.label.language}:{$forms.profileForm.lang.control}
{$i18n.label.decimal_mark}:{$forms.profileForm.decimal_mark.control}  
{$i18n.label.date_format}:{$forms.profileForm.date_format.control}  
{$i18n.label.time_format}:{$forms.profileForm.time_format.control}  
{$i18n.label.week_start}:{$forms.profileForm.start_week.control}
{$i18n.form.profile.show_holidays}:{$forms.profileForm.show_holidays.control} {$i18n.label.what_is_it}
{$i18n.form.profile.tracking_mode}:{$forms.profileForm.tracking_mode.control} {$forms.profileForm.task_required.control}
{$i18n.form.profile.record_type}:{$forms.profileForm.record_type.control}
{$i18n.form.profile.punch_mode}:{$forms.profileForm.punch_mode.control} {$i18n.label.what_is_it}
{$i18n.form.profile.allow_overlap}:{$forms.profileForm.allow_overlap.control} {$i18n.label.what_is_it}
{$i18n.form.profile.future_entries}:{$forms.profileForm.future_entries.control} {$i18n.label.what_is_it}
{$i18n.form.profile.uncompleted_indicators}:{$forms.profileForm.uncompleted_indicators.control} {$i18n.label.what_is_it}
{$i18n.label.bcc}:{$forms.profileForm.bcc_email.control} {$i18n.label.what_is_it}
  
{$i18n.form.profile.plugins}
 
{$forms.profileForm.charts.control}
{$forms.profileForm.clients.control} {$forms.profileForm.client_required.control}
{$forms.profileForm.invoices.control}
{$forms.profileForm.paid_status.control}
{$forms.profileForm.custom_fields.control} {$i18n.label.configure}
{$forms.profileForm.expenses.control} {$forms.profileForm.tax_expenses.control} {$i18n.label.configure}
{$forms.profileForm.notifications.control} {$i18n.label.configure}
{$forms.profileForm.locking.control} {$i18n.label.configure}
{$forms.profileForm.quotas.control} {$i18n.label.configure}
{$forms.profileForm.week_view.control} {$i18n.label.configure}
 
-
 Anuko Time Tracker 1.17.80.4193 | Copyright © Anuko | +  Anuko Time Tracker 1.17.80.4194 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c13fcda70448cc81d1555fe2ee25a5d0ed2f74c7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Mar 2018 23:41:51 +0000 Subject: [PATCH 0077/1848] Introduced title.group into translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 44 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 3e7cc33ac..6f7aa90e3 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -314,6 +314,7 @@ 'title.options' => 'Opcions', 'title.profile' => 'Perfil', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 961a69b5e..7410ac064 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -324,6 +324,7 @@ // 'title.options' => 'Options', 'title.profile' => 'Profil', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index fd707ea4f..a515b6bef 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -281,6 +281,8 @@ 'title.import' => 'Importer Team Data', 'title.options' => 'Indstillinger', 'title.profile' => 'Profil', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Brugerdefineret Felt', 'title.cf_add_custom_field' => 'Tilføj Brugerdefineret Felt', 'title.cf_edit_custom_field' => 'Redigér Brugerdefineret Felt', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 0a515068b..6e56c7044 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -273,6 +273,8 @@ 'title.import' => 'Daten importieren', 'title.options' => 'Optionen', 'title.profile' => 'Profil', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Benutzerfelder', 'title.cf_add_custom_field' => 'Benutzerfeld hinzufügen', 'title.cf_edit_custom_field' => 'Benutzerfeld bearbeiten', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index a238cdd84..f668046e6 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -313,6 +313,7 @@ 'title.options' => 'Opciones', 'title.profile' => 'Perfil', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 9a3e4de39..d852de894 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -320,6 +320,7 @@ 'title.options' => 'Suvandid', 'title.profile' => 'Profiili', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index d1a5f2507..90ca57bf5 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -291,6 +291,8 @@ 'title.import' => 'وارد کردن اطلاعات تیم', 'title.options' => 'گزینه ها', 'title.profile' => 'پروفایل', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'فیلدهای سفارشی', 'title.cf_add_custom_field' => 'درج فیلد سفارشی', 'title.cf_edit_custom_field' => 'ویرایش فیلد سفارشی', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index e288d1d79..24fadbf55 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -282,6 +282,8 @@ 'title.import' => 'Tiimitietojen tunti', 'title.options' => 'Optiot', 'title.profile' => 'Profiili', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Omat kentät', 'title.cf_add_custom_field' => 'Oman kentän lisäys', 'title.cf_edit_custom_field' => 'Oman kentän muokkaus', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 54309ae19..947bc0bce 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -275,6 +275,8 @@ 'title.import' => 'Importation des données', 'title.options' => 'Options', 'title.profile' => 'Profil', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Champs personalisés', 'title.cf_add_custom_field' => 'Ajout d\\\'un champ', 'title.cf_edit_custom_field' => 'Édition d\\\'un champ', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index a3827d17c..93b3eab86 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -271,6 +271,8 @@ 'title.import' => 'Εισαγωγή δεδομένων ομάδας', 'title.options' => 'Επιλογές', 'title.profile' => 'Προφίλ', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Προσαρμοσμένα πεδία', 'title.cf_add_custom_field' => 'Προσθήκη προσαρμοσμένου πεδίου', 'title.cf_edit_custom_field' => 'Επεξεργασία προσαρμοσμένου πεδίου', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index a6ceca7fa..baa85d710 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -302,6 +302,8 @@ 'title.import' => 'ייבוא נתוני צוות', 'title.options' => 'אפשרויות', 'title.profile' => 'פרופיל', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'שדות אישיים', 'title.cf_add_custom_field' => 'הוספת שדה אישי', 'title.cf_edit_custom_field' => 'עריכת שדה אישי', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 904ccdefe..4fbec7a5e 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -312,6 +312,7 @@ 'title.options' => 'Opciók', 'title.profile' => 'Profil', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 6cc4b7571..ce173ee31 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -281,6 +281,8 @@ 'title.import' => 'Importa i dati del gruppo', 'title.options' => 'Opzioni', 'title.profile' => 'Profilo', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Campi personalizzati', 'title.cf_add_custom_field' => 'Aggiunta campo personalizzato', 'title.cf_edit_custom_field' => 'Modifica campo personalizzato', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index e92a03e0d..e13f2d9dd 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -318,6 +318,7 @@ 'title.options' => 'オプション', 'title.profile' => 'プロファイル', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 85754e635..b066e55fd 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -319,6 +319,7 @@ 'title.options' => '옵션', 'title.profile' => '프로필', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index e083705e9..320da1d97 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -274,6 +274,8 @@ 'title.import' => 'Importeer teamgegevens', 'title.options' => 'Opties', 'title.profile' => 'Profiel', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Eigen velden', 'title.cf_add_custom_field' => 'Eigen veld toevoegen', 'title.cf_edit_custom_field' => 'Eigen veld bewerken', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 0acce80cd..aeff48725 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -314,6 +314,7 @@ 'title.options' => 'Opsjoner', 'title.profile' => 'Profil', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index ccb7dc2b9..62702bf20 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -282,6 +282,8 @@ 'title.import' => 'Import danych zespołu', 'title.options' => 'Opcje', 'title.profile' => 'Profil', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Pola niestandardowe', 'title.cf_add_custom_field' => 'Dodawanie pola niestandardowego', 'title.cf_edit_custom_field' => 'Edytowanie pola niestandardowego', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 6691dad1f..3ad934e2d 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -279,6 +279,8 @@ 'title.import' => 'Importando dados de equipe', 'title.options' => 'Opções', 'title.profile' => 'Perfil', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Campos personalizados', 'title.cf_add_custom_field' => 'Adicionando campo personalizado', 'title.cf_edit_custom_field' => 'Editando campo personalizado', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d05a39cab..d33922f63 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -301,6 +301,7 @@ 'title.options' => 'Opções', 'title.profile' => 'Perfil', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index a649d3ac8..4deeb3ee1 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -320,6 +320,7 @@ // 'title.options' => 'Options', 'title.profile' => 'Profil', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index cfdee9220..34368cdd2 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -268,6 +268,7 @@ 'title.import' => 'Импортирование данных команды', 'title.options' => 'Опции', 'title.profile' => 'Профиль', +'title.group' => 'Настройки группы', 'title.cf_custom_fields' => 'Дополнительные поля', 'title.cf_add_custom_field' => 'Добавление поля', 'title.cf_edit_custom_field' => 'Редактирование поля', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 1790729c9..8ff080e2b 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -292,6 +292,8 @@ 'title.import' => 'Importovanie údajov o tíme', 'title.options' => 'Nastavenia', 'title.profile' => 'Profil', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Vlastné polia', 'title.cf_add_custom_field' => 'Pridávanie vlastného poľa', 'title.cf_edit_custom_field' => 'Upravovanie vlastného poľa', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 3b417fb49..9696b526c 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -296,6 +296,7 @@ // 'title.options' => 'Options', 'title.profile' => 'Profil', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 32d789ddc..06b087b7c 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -281,6 +281,8 @@ 'title.import' => 'Uvoz podataka tim-a', 'title.options' => 'Opcije', 'title.profile' => 'Profil', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Dodatna polja', 'title.cf_add_custom_field' => 'Dodavanje dodatnih polja', 'title.cf_edit_custom_field' => 'Izmena dodatnih polja', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index bdc2fa87e..2c6992320 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -282,6 +282,8 @@ 'title.import' => 'Importera arbetsgrupp', 'title.options' => 'Alternativ', 'title.profile' => 'Profil', +// TODO: translate the following. +// 'title.group' => 'Group Settings', 'title.cf_custom_fields' => 'Egna fält', 'title.cf_add_custom_field' => 'Lägg till fält', 'title.cf_edit_custom_field' => 'Redigera fält', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 6828cb857..d7a513bf9 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -329,6 +329,7 @@ // 'title.options' => 'Options', 'title.profile' => 'Profili', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index de8b5d746..72f4317e1 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -306,6 +306,7 @@ 'title.options' => '选项', 'title.profile' => '简介', // TODO: translate the following. +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index d5bd872f4..0ef227efb 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -313,6 +313,7 @@ 'title.options' => '選項', // TODO: translate the following. // 'title.profile' => 'Profile', +// 'title.group' => 'Group Settings', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ccba58341..f0473bb12 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.80.4194 | Copyright © Anuko | +  Anuko Time Tracker 1.17.80.4195 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 40e7c879cbbc4f00227c039f1a86d48f81e10101 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 28 Mar 2018 00:28:31 +0000 Subject: [PATCH 0078/1848] Ongoing process of renaming team to group. --- WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/cs.lang.php | 2 +- WEB-INF/resources/da.lang.php | 3 ++- WEB-INF/resources/de.lang.php | 3 ++- WEB-INF/resources/en.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 3 ++- WEB-INF/resources/fi.lang.php | 3 ++- WEB-INF/resources/fr.lang.php | 3 ++- WEB-INF/resources/gr.lang.php | 3 ++- WEB-INF/resources/he.lang.php | 3 ++- WEB-INF/resources/hu.lang.php | 5 ++--- WEB-INF/resources/it.lang.php | 3 +-- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 3 ++- WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 3 ++- WEB-INF/resources/pt-br.lang.php | 3 ++- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 3 ++- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 3 ++- WEB-INF/resources/sv.lang.php | 5 ++--- WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- WEB-INF/resources/zh-tw.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- 32 files changed, 46 insertions(+), 37 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 6f7aa90e3..9ccf24e94 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -46,7 +46,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => 'Ajuda', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Perfil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 7410ac064..e73597079 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -48,7 +48,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => 'Pomoc', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index a515b6bef..88b905ba0 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -44,7 +44,8 @@ 'menu.logout' => 'Log ud', 'menu.forum' => 'Forum', 'menu.help' => 'Hjælp', -'menu.create_team' => 'Lav et team', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 6e56c7044..47ac5c52a 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -44,7 +44,8 @@ 'menu.logout' => 'Abmelden', 'menu.forum' => 'Forum', 'menu.help' => 'Hilfe', -'menu.create_team' => 'Neues Team', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 1613fec90..b4fdb8a73 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -44,7 +44,7 @@ 'menu.logout' => 'Logout', 'menu.forum' => 'Forum', 'menu.help' => 'Help', -'menu.create_team' => 'Create Team', +'menu.create_group' => 'Create Group', 'menu.profile' => 'Profile', 'menu.group' => 'Group', 'menu.time' => 'Time', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index f668046e6..1d6926810 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -45,7 +45,7 @@ 'menu.forum' => 'Foro', 'menu.help' => 'Ayuda', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Perfil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index d852de894..2eea5d4bf 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -48,7 +48,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => 'Abiinfo', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profiili', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 90ca57bf5..a9834b0a6 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -45,7 +45,8 @@ 'menu.logout' => 'خروج', 'menu.forum' => 'فروم', 'menu.help' => 'راهنما', -'menu.create_team' => 'ایجاد گروه', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'پروفايل', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 24fadbf55..3b904500e 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -44,7 +44,8 @@ 'menu.logout' => 'Kirjaudu ulos', 'menu.forum' => 'Keskustelupalsta', 'menu.help' => 'Apua', -'menu.create_team' => 'Luo tiimi', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profiili', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 947bc0bce..ae46dc664 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -44,7 +44,8 @@ 'menu.logout' => 'Quitter', 'menu.forum' => 'Forum', 'menu.help' => 'Aide', -'menu.create_team' => 'Créer une équipe', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 93b3eab86..616aad7c0 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -44,7 +44,8 @@ 'menu.logout' => 'Αποσύνδεση', 'menu.forum' => 'Φόρουμ', 'menu.help' => 'Βοήθεια', -'menu.create_team' => 'Δημιουργία ομάδας', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Προφίλ', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index baa85d710..a8bcf9254 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -45,7 +45,8 @@ 'menu.logout' => 'יציאה', 'menu.forum' => 'פורום', 'menu.help' => 'עזרה', -'menu.create_team' => 'צור צוות', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'פרופיל', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 4fbec7a5e..b0f9d2e61 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -46,10 +46,9 @@ 'menu.logout' => 'Kijelentkezés', 'menu.forum' => 'Fórum', 'menu.help' => 'Segítség', -'menu.create_team' => 'Csoport létrehozása', +'menu.create_group' => 'Csoport létrehozása', 'menu.profile' => 'Profil', -// TODO: translate the following. -// 'menu.group' => 'Group', +'menu.group' => 'Csoport', 'menu.time' => 'Munkaidő', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ce173ee31..200f490b4 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -48,8 +48,7 @@ 'menu.help' => 'Aiuto', 'menu.create_team' => 'Crea gruppo', 'menu.profile' => 'Profilo', -// TODO: translate the following. -// 'menu.group' => 'Group', +'menu.group' => 'Gruppo', 'menu.time' => 'Tempo', 'menu.expenses' => 'Spese', 'menu.reports' => 'Rapporti', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index e13f2d9dd..aaf501104 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -46,7 +46,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => 'ヘルプ', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'プロファイル', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index b066e55fd..7b429a562 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -46,7 +46,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => '도움말', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => '프로필', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 320da1d97..a247160bb 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -44,7 +44,8 @@ 'menu.logout' => 'Afmelden', 'menu.forum' => 'Forum', 'menu.help' => 'Help', -'menu.create_team' => 'Maak team', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profiel', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index aeff48725..0de21ef18 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -47,7 +47,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => 'Hjelp', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 62702bf20..36e1940d6 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -44,7 +44,8 @@ 'menu.logout' => 'Wyloguj', 'menu.forum' => 'Forum', 'menu.help' => 'Pomoc', -'menu.create_team' => 'Stwórz zespół', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 3ad934e2d..2387937fa 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -44,7 +44,8 @@ 'menu.logout' => 'Logout', 'menu.forum' => 'Fórum', 'menu.help' => 'Ajuda', -'menu.create_team' => 'Criar equipe', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Perfil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d33922f63..5a9e39849 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -48,7 +48,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => 'Ajuda', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Perfil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 4deeb3ee1..476ad3f1c 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -48,7 +48,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => 'Ajutor', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 34368cdd2..f1f18b09f 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -44,7 +44,7 @@ 'menu.logout' => 'Выйти', 'menu.forum' => 'Форум', 'menu.help' => 'Справка', -'menu.create_team' => 'Создать команду', +'menu.create_group' => 'Создать группу', 'menu.profile' => 'Профиль', 'menu.group' => 'Группа', 'menu.time' => 'Время', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 8ff080e2b..2608643af 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -44,7 +44,8 @@ 'menu.logout' => 'Odhlásenie', 'menu.forum' => 'Fórum', 'menu.help' => 'Pomoc', -'menu.create_team' => 'Vytvoriť tím', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 9696b526c..7c181ae6c 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -48,7 +48,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => 'Pomoč', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 06b087b7c..839b60bd8 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -44,7 +44,8 @@ 'menu.logout' => 'Odjava', 'menu.forum' => 'Forum', 'menu.help' => 'Pomoć', -'menu.create_team' => 'Napravi tim', +// TODO: translate the following. +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 2c6992320..93e3348bb 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -44,10 +44,9 @@ 'menu.logout' => 'Logga ut', 'menu.forum' => 'Forum', 'menu.help' => 'Hjälp', -'menu.create_team' => 'Skapa arbetsgrupp', +'menu.create_group' => 'Skapa grupp', 'menu.profile' => 'Profil', -// TODO: translate the following. -// 'menu.group' => 'Group', +'menu.group' => 'Grupp', 'menu.time' => 'Tider', 'menu.expenses' => 'Kostnader', 'menu.reports' => 'Rapporter', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index d7a513bf9..727188a6c 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -48,7 +48,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => 'Yardım', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profili', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 72f4317e1..5b2e2dccb 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -45,7 +45,7 @@ 'menu.forum' => '论坛', 'menu.help' => '帮助', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', 'menu.profile' => '简介', // TODO: translate the following. // 'menu.group' => 'Group', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 0ef227efb..5a9a072b5 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -46,7 +46,7 @@ // 'menu.forum' => 'Forum', 'menu.help' => '幫助', // TODO: translate the following. -// 'menu.create_team' => 'Create Team', +// 'menu.create_group' => 'Create Group', // 'menu.profile' => 'Profile', // 'menu.group' => 'Group', // 'menu.time' => 'Time', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f0473bb12..8d3bd12b7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.80.4195 | Copyright © Anuko | +  Anuko Time Tracker 1.17.80.4196 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 3ad3fb5fc..454365fbb 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -143,7 +143,7 @@   {$i18n.menu.login} · {if isTrue($smarty.const.MULTITEAM_MODE) && $smarty.const.AUTH_MODULE == 'db'} - {$i18n.menu.create_team} · + {$i18n.menu.create_group} · {/if} {$i18n.menu.forum} · {$i18n.menu.help} From e0ec0364d761e2dff5a7c0032f04ec1dbae50980 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 28 Mar 2018 01:42:40 +0000 Subject: [PATCH 0079/1848] A bit more progress with renaming teams to groups. --- WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/cs.lang.php | 3 ++- WEB-INF/resources/da.lang.php | 3 ++- WEB-INF/resources/de.lang.php | 3 ++- WEB-INF/resources/en.lang.php | 2 +- WEB-INF/resources/es.lang.php | 4 ++-- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 3 ++- WEB-INF/resources/fi.lang.php | 3 ++- WEB-INF/resources/fr.lang.php | 3 ++- WEB-INF/resources/gr.lang.php | 8 +++----- WEB-INF/resources/he.lang.php | 3 ++- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 3 ++- WEB-INF/resources/no.lang.php | 3 ++- WEB-INF/resources/pl.lang.php | 3 ++- WEB-INF/resources/pt-br.lang.php | 3 ++- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 3 ++- WEB-INF/resources/sl.lang.php | 3 +-- WEB-INF/resources/sr.lang.php | 3 ++- WEB-INF/resources/sv.lang.php | 2 +- WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 3 ++- WEB-INF/resources/zh-tw.lang.php | 3 ++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- WEB-INF/templates/mobile/header.tpl | 2 +- 33 files changed, 51 insertions(+), 39 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 9ccf24e94..27abaeac3 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -60,7 +60,7 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', 'menu.users' => 'Usuaris', -'menu.teams' => 'Grups', +'menu.groups' => 'Grups', // TODO: translate the following. // 'menu.export' => 'Export', 'menu.clients' => 'Clients', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index e73597079..4c9a50c2c 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -61,7 +61,8 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', 'menu.users' => 'Uživatelů', -'menu.teams' => 'Týmy', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Export', 'menu.clients' => 'Zákazníci', // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 88b905ba0..d49ab64ab 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -56,7 +56,8 @@ 'menu.projects' => 'Projekter', 'menu.tasks' => 'Opgaver', 'menu.users' => 'Brugere', -'menu.teams' => 'Teams', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Eksport', 'menu.clients' => 'Kunder', 'menu.options' => 'Indstillinger', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 47ac5c52a..9712b6329 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -56,7 +56,8 @@ 'menu.projects' => 'Projekte', 'menu.tasks' => 'Aufgaben', 'menu.users' => 'Personen', -'menu.teams' => 'Teams', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Exportieren', 'menu.clients' => 'Kunden', 'menu.options' => 'Optionen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index b4fdb8a73..2063f4eec 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -54,7 +54,7 @@ 'menu.projects' => 'Projects', 'menu.tasks' => 'Tasks', 'menu.users' => 'Users', -'menu.teams' => 'Teams', +'menu.groups' => 'Groups', 'menu.export' => 'Export', 'menu.clients' => 'Clients', 'menu.options' => 'Options', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 1d6926810..f294df6c7 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -59,9 +59,9 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', 'menu.users' => 'Personas', -'menu.teams' => 'Equipos', // TODO: translate the following. -// menu.export' => 'Export', +// 'menu.groups' => 'Groups', +// 'menu.export' => 'Export', 'menu.clients' => 'Clientes', 'menu.options' => 'Opciones', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 2eea5d4bf..7a7640e39 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -62,8 +62,8 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', 'menu.users' => 'Kasutajad', -'menu.teams' => 'Meeskonnad', // TODO: translate the following. +// 'menu.groups' => 'Groups', // 'menu.export' => 'Export', 'menu.clients' => 'Kliendid', 'menu.options' => 'Suvandid', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index a9834b0a6..e290791be 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -57,7 +57,8 @@ 'menu.projects' => 'پروژه ها', 'menu.tasks' => 'وظايف', 'menu.users' => 'کاربران', -'menu.teams' => 'گروه ها', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'پشتیبانی', 'menu.clients' => 'مشتری ها', 'menu.options' => 'تنظیمات', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 3b904500e..9d4bcba63 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -56,7 +56,8 @@ 'menu.projects' => 'Projektit', 'menu.tasks' => 'Tehtävät', 'menu.users' => 'Käyttäjät', -'menu.teams' => 'Tiimit', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Vie', 'menu.clients' => 'Asiakkaat', 'menu.options' => 'Optiot', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index ae46dc664..57f3d10c9 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -56,7 +56,8 @@ 'menu.projects' => 'Projets', 'menu.tasks' => 'Tâches', 'menu.users' => 'Utilisateurs', -'menu.teams' => 'Équipes', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Exporter', 'menu.clients' => 'Clients', 'menu.options' => 'Options', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 616aad7c0..396719e9c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -44,11 +44,9 @@ 'menu.logout' => 'Αποσύνδεση', 'menu.forum' => 'Φόρουμ', 'menu.help' => 'Βοήθεια', -// TODO: translate the following. -// 'menu.create_group' => 'Create Group', +'menu.create_group' => 'Δημιουργία ομάδας', 'menu.profile' => 'Προφίλ', -// TODO: translate the following. -// 'menu.group' => 'Group', +'menu.group' => 'Ομάδα', 'menu.time' => 'Χρόνος', 'menu.expenses' => 'Έξοδα', 'menu.reports' => 'Αναφορές', @@ -56,7 +54,7 @@ 'menu.projects' => 'Έργα', 'menu.tasks' => 'Εργασίες', 'menu.users' => 'Χρήστες', -'menu.teams' => 'Ομάδες', +'menu.groups' => 'Ομάδες', 'menu.export' => 'Εξαγωγή', 'menu.clients' => 'Πελάτες', 'menu.options' => 'Επιλογές', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index a8bcf9254..a657bdc30 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -58,7 +58,8 @@ 'menu.projects' => 'פרוייקטים', 'menu.tasks' => 'משימות', 'menu.users' => 'משתמשים', -'menu.teams' => 'צוותים', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'ייצוא', 'menu.clients' => 'לקוחות', 'menu.options' => 'אפשרויות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index b0f9d2e61..3c96206b0 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -59,7 +59,7 @@ // 'menu.tasks' => 'Tasks', // TODO: translate the following. // 'menu.users' => 'Users', -'menu.teams' => 'Csoportok', +'menu.groups' => 'Csoportok', // TODO: translate the following. // 'menu.export' => 'Export', 'menu.clients' => 'Ügyfelek', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 200f490b4..927417b9c 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -56,7 +56,7 @@ 'menu.projects' => 'Progetti', 'menu.tasks' => 'Compiti', 'menu.users' => 'Utenti', -'menu.teams' => 'Gruppi', +'menu.groups' => 'Gruppi', 'menu.export' => 'Esportazione', 'menu.clients' => 'Clienti', 'menu.options' => 'Opzioni', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index aaf501104..534eb3db7 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -60,8 +60,8 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', 'menu.users' => 'ユーザー', -'menu.teams' => 'チーム', // TODO: translate the following. +// 'menu.groups' => 'Groups', // 'menu.export' => 'Export', 'menu.clients' => 'クライアント', 'menu.options' => 'オプション', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 7b429a562..67b6d5054 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -60,8 +60,8 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', 'menu.users' => '사용자', -'menu.teams' => '팀', // TODO: translate the following. +// 'menu.groups' => 'Groups', // 'menu.export' => 'Export', 'menu.clients' => '클라이언트', 'menu.options' => '옵션', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index a247160bb..ff4514512 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -56,7 +56,8 @@ 'menu.projects' => 'Projecten', 'menu.tasks' => 'Taken', 'menu.users' => 'Medewerkers', -'menu.teams' => 'Teams', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Exporteren', 'menu.clients' => 'Klanten', 'menu.options' => 'Opties', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 0de21ef18..077ee2984 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -60,7 +60,8 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', 'menu.users' => 'Brukere', -// 'menu.teams' => 'Teams', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Eksport', 'menu.clients' => 'Klienter', 'menu.options' => 'Opsjoner', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 36e1940d6..166edfed7 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -56,7 +56,8 @@ 'menu.projects' => 'Projekty', 'menu.tasks' => 'Zadania', 'menu.users' => 'Użytkownicy', -'menu.teams' => 'Zespoły', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Eksport', 'menu.clients' => 'Klienci', 'menu.options' => 'Opcje', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 2387937fa..dd8fc8250 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -56,7 +56,8 @@ 'menu.projects' => 'Projetos', 'menu.tasks' => 'Tarefas', 'menu.users' => 'Usuários', -'menu.teams' => 'Equipes', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Exportar', 'menu.clients' => 'Clientes', 'menu.options' => 'Opções', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 5a9e39849..66cf565ba 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -63,7 +63,7 @@ // 'menu.tasks' => 'Tasks', 'menu.users' => 'Usuários', // TODO: translate the following. -// 'menu.teams' => 'Teams', +// 'menu.groups' => 'Groups', // 'menu.export' => 'Export', // 'menu.clients' => 'Clients', 'menu.options' => 'Opções', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 476ad3f1c..eeba69563 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -62,8 +62,8 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', 'menu.users' => 'Utilizatori', -'menu.teams' => 'Echipe', // TODO: translate the following. +// 'menu.groups' => 'Groups', // 'menu.export' => 'Export', 'menu.clients' => 'Clienti', // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index f1f18b09f..8d1331d81 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -54,7 +54,7 @@ 'menu.projects' => 'Проекты', 'menu.tasks' => 'Задачи', 'menu.users' => 'Пользователи', -'menu.teams' => 'Команды', +'menu.groups' => 'Группы', 'menu.export' => 'Экспорт', 'menu.clients' => 'Клиенты', 'menu.options' => 'Опции', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 2608643af..66efd058d 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -57,7 +57,8 @@ 'menu.projects' => 'Projekty', 'menu.tasks' => 'Úlohy', 'menu.users' => 'Používatelia', -'menu.teams' => 'Tímy', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Export', 'menu.clients' => 'Klienti', 'menu.options' => 'Nastavenia', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 7c181ae6c..5fba7a9c6 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -61,8 +61,7 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', // 'menu.users' => 'Users', -'menu.teams' => 'Timi', -// TODO: translate the following. +// 'menu.groups' => 'Groups', // 'menu.export' => 'Export', 'menu.clients' => 'Stranke', 'menu.options' => 'Možnosti', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 839b60bd8..5fa432f6e 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -56,7 +56,8 @@ 'menu.projects' => 'Projekti', 'menu.tasks' => 'Zadaci', 'menu.users' => 'Korisnici', -'menu.teams' => 'Timovi', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => 'Izvoz', 'menu.clients' => 'Klijenti', 'menu.options' => 'Opcije', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 93e3348bb..a45921b1c 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -54,7 +54,7 @@ 'menu.projects' => 'Projekt', 'menu.tasks' => 'Arbetsuppgifter', 'menu.users' => 'Användare', -'menu.teams' => 'Arbetsgrupper', +'menu.groups' => 'Grupper', 'menu.export' => 'Exportera', 'menu.clients' => 'Kunder', 'menu.options' => 'Alternativ', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 727188a6c..0cb44dfd7 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -62,8 +62,8 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', 'menu.users' => 'Kullanıcılar', -'menu.teams' => 'Ekipler', // TODO: translate the following. +// 'menu.groups' => 'Groups', // 'menu.export' => 'Export', 'menu.clients' => 'Müşteriler', // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5b2e2dccb..8439f6b3e 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -56,7 +56,8 @@ 'menu.projects' => '项目', 'menu.tasks' => '任务', 'menu.users' => '用户', -'menu.teams' => '团队', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => '导出数据', 'menu.clients' => '客户', 'menu.options' => '选项', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 5a9a072b5..33ea3114b 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -58,7 +58,8 @@ // TODO: translate the following. // 'menu.tasks' => 'Tasks', 'menu.users' => '用戶', -'menu.teams' => '團隊', +// TODO: translate the following. +// 'menu.groups' => 'Groups', 'menu.export' => '輸出資料', 'menu.clients' => '客戶', 'menu.options' => '選項', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8d3bd12b7..0acdf55c7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.80.4196 | Copyright © Anuko | +  Anuko Time Tracker 1.17.80.4197 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 454365fbb..a5f0d022d 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -71,7 +71,7 @@ diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index 7118cfa4e..f61b7119a 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -61,7 +61,7 @@
  - {$i18n.menu.teams} · + {$i18n.menu.groups} · {$i18n.menu.options}
From dfc50841cd4b60eb8f2172044d6dd08785fe3df4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 29 Mar 2018 10:35:44 +0000 Subject: [PATCH 0080/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 44 ++++++++++++++--------------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index ff4514512..4e06cc0ec 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -72,8 +72,7 @@ 'error.access_denied' => 'Toegang geweigerd.', 'error.sys' => 'Systeem fout.', 'error.db' => 'Database fout.', -// TODO: translate the following. -// 'error.feature_disabled' => 'Feature is disabled.', +'error.feature_disabled' => 'Functie is uitgeschakeld.', 'error.field' => 'Incorrecte gegevens: "{0}".', 'error.empty' => 'Veld "{0}" is leeg.', 'error.not_equal' => 'Veld "{0}" is niet gelijk aan veld "{1}".', @@ -82,17 +81,18 @@ 'error.task' => 'Kies taak.', 'error.client' => 'Kies klant.', 'error.report' => 'Kies rapport.', -'error.record' => 'Selecteer record.', // TODO: why not Kies as above? +'error.record' => 'Kies record.', 'error.auth' => 'Onjuiste inlognaam of wachtwoord.', 'error.user_exists' => 'Een gebruiker met deze inlognaam bestaat al.', -// TODO: translate the following. -// 'error.object_exists' => 'Object with this name already exists.', +'error.object_exists' => 'Een object met deze naam bestaat al.', 'error.project_exists' => 'Een project met deze naam bestaat al.', 'error.task_exists' => 'Er bestaat al een taak met deze naam.', 'error.client_exists' => 'Een klant met deze naam bestaat al.', 'error.invoice_exists' => 'Dit nummer is al eens toegekend aan een factuur.', -// TODO: translate the following. +// TODO: translate the following. It seems like rank is misplaced ith rights. // 'error.role_exists' => 'Role with this rank already exists.', +// 'error.role_exists' => 'Een rol met deze rechten bestaat al.', // TODO: rank is not rights. Rank is a number. + // Rights (rechten) is a set of permissions ("view_users", etc.). 'error.no_invoiceable_items' => 'Er zijn geen factuureerbare onderdelen.', 'error.no_login' => 'Een medewerker met deze inlognaam bestaat niet.', 'error.no_teams' => 'Uw database is leeg. Meld je aan als admin en maak een nieuw team.', @@ -161,8 +161,7 @@ 'label.notes' => 'Notities', 'label.item' => 'Artikel', 'label.cost' => 'Kosten', -// TODO: translate the following. -// 'label.ip' => 'IP', +'label.ip' => 'IP adres', 'label.day_total' => 'Dag totaal', 'label.week_total' => 'Week totaal', 'label.month_total' => 'Maand totaal', @@ -208,8 +207,7 @@ 'label.type_text' => 'tekst', 'label.required' => 'Verplicht veld', 'label.fav_report' => 'Standaard rapport', -// TODO: translate the following. -// 'label.schedule' => 'Schedule', +'label.schedule' => 'Planning', 'label.what_is_it' => 'Wat betekent dit?', 'label.expense' => 'Kosten', 'label.quantity' => 'Hoeveelheid', @@ -288,8 +286,7 @@ 'title.cf_delete_dropdown_option' => 'Uitvouwmogelijkheid verwijderen', 'title.locking' => 'Blokkeren', 'title.week_view' => 'Week overzicht', -// TODO: translate the following. -// 'title.swap_roles' => 'Swapping Roles', +'title.swap_roles' => 'Rollen verruilen', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. @@ -332,10 +329,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Het verzoek om het wachtwoord te herstellen is verzonden per email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker wachtwoord herstel verzoek', -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", -// "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Geachte medewerker,\n\nIemand, IP %s, heeft verzocht uw wachtwoord in Anuko Time Tracker te herstellen. Klik op deze link als u uw wachtwoord wil wijzigen.\n\n%s\n\nAnuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem. Bezoek https://www.anuko.com voor meer informatie.\n\n", +'form.reset_password.email_body' => "Geachte medewerker,\n\nIemand, met IP adres %s, heeft verzocht uw wachtwoord in Anuko Time Tracker te herstellen. Klik op deze link als u uw wachtwoord wil wijzigen.\n\n%s\n\nAnuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem. Bezoek https://www.anuko.com voor meer informatie.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Voer het nieuwe wachtwoord in en klik op Bewaren.', @@ -412,12 +406,10 @@ // Roles form. See example at https://timetracker.anuko.com/roles.php 'form.roles.active_roles' => 'Actieve rollen', 'form.roles.inactive_roles' => 'Inactieve rollen', -// TODO: translate the following. -// 'form.roles.rank' => 'Rank', +'form.roles.rank' => 'Volgorde', 'form.roles.rights' => 'Rechten', -// TODO: translate the following. -// 'form.roles.assigned' => 'Assigned', -// 'form.roles.not_assigned' => 'Not assigned', +'form.roles.assigned' => 'Toegewezen', +'form.roles.not_assigned' => 'Niet toegewezen', // Clients form. See example at https://timetracker.anuko.com/clients.php 'form.clients.active_clients' => 'Actieve klanten', @@ -442,8 +434,7 @@ 'form.teams.hint' => 'Maak een nieuw team door een team manager account aan te maken.
U kunt ook teamgegevens importeren uit een xml file van een andere Anuko Time Tracker server (login namen moeten uniek zijn).', // Profile form. See example at https://timetracker.anuko.com/profile_edit.php. -// TODO: translate the following. -// 'form.profile.swap_roles' => 'Swap roles', +'form.profile.swap_roles' => 'Rollen verruilen', 'form.profile.12_hours' => '12 uurs', 'form.profile.24_hours' => '24 uurs', 'form.profile.show_holidays' => 'Toon vakantiedagen', @@ -477,9 +468,8 @@ 'form.quota.hint' => 'Als de velden leeg worden gelaten, dan zullen de doelen worden berekend op bassis van het aantal werkuren per dag en vakantiedagen.', // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. -// TODO: translate the following. -// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', -// 'form.swap.swap_with' => 'Swap roles with', +'form.swap.hint' => 'Degradeer jezelf naar een lagere rol door een rol te verruilen met iemand anders. Dit kan niet ongedaan worden gemaakt.', +'form.swap.swap_with' => 'Verruil rol met', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. 'role.user.label' => 'Gebruiker', @@ -502,5 +492,5 @@ 'role.top_manager.description' => 'Top groepsbeheerder. Kan alle groepen beheren.', 'role.admin.label' => 'Administrator', 'role.admin.low_case_label' => 'administrator', -'role.admin.description' => 'Website beheerder.', // TODO: perhaps, 'Time Tracker administrator.'? +'role.admin.description' => 'Time Tracker beheerder.', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0acdf55c7..e70cdbeae 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
  - {$i18n.menu.teams} · + {$i18n.menu.groups} · {$i18n.menu.options}
-
 Anuko Time Tracker 1.17.80.4197 | Copyright © Anuko | +  Anuko Time Tracker 1.17.80.4198 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 82113b6a111dc3f716c71fb8fb55b11845cbd697 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 29 Mar 2018 19:32:52 +0000 Subject: [PATCH 0081/1848] Refactoring. Renamed tt_teams table to tt_groups. --- WEB-INF/lib/ttAdmin.class.php | 4 ++-- WEB-INF/lib/ttGroupHelper.class.php | 4 ++-- WEB-INF/lib/ttRegistrator.class.php | 8 ++++---- WEB-INF/lib/ttTeamHelper.class.php | 18 +++++++++--------- WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/lib/ttUserHelper.class.php | 2 +- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 13 ++++++++----- mysql.sql | 13 +++++-------- 10 files changed, 34 insertions(+), 34 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index fbcabd476..ed1b280c3 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -174,7 +174,7 @@ function markGroupDeleted($group_id) { // Mark group deleted. global $user; $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); - $sql = "update tt_teams set status = NULL $modified_part where id = $group_id"; + $sql = "update tt_groups set status = NULL $modified_part where id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -242,7 +242,7 @@ function updateGroup($team_id, $fields) { if ($fields['old_group_name'] != $fields['new_group_name']) { $name_part = 'name = '.$mdb2->quote($fields['new_group_name']); $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); - $sql = 'update tt_teams set '.$name_part.$modified_part.' where id = '.$team_id; + $sql = 'update tt_groups set '.$name_part.$modified_part.' where id = '.$team_id; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; } diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 9fcb8443e..6ffa6b21a 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -35,8 +35,8 @@ static function getTopGroups() { $result = array(); $mdb2 = getConnection(); - // TODO: when we have subgroups, improve the query to return only top groups. - $sql = "select id, name, created, lang from tt_teams where status = 1 order by id desc"; + $sql = "select id, name, created, lang from tt_groups". + " where status = 1 and org_id is NULL order by id desc"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 3c424f486..23df23eab 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -135,11 +135,11 @@ function createGroup() { $created = 'now()'; $created_ip = $mdb2->quote($_SERVER['REMOTE_ADDR']); - $sql = "insert into tt_teams (name, currency, lang, created, created_ip) values($name, $currency, $lang, $created, $created_ip)"; + $sql = "insert into tt_groups (name, currency, lang, created, created_ip) values($name, $currency, $lang, $created, $created_ip)"; $affected = $mdb2->exec($sql); if (!is_a($affected, 'PEAR_Error')) { - $group_id = $mdb2->lastInsertID('tt_teams', 'id'); + $group_id = $mdb2->lastInsertID('tt_groups', 'id'); return $group_id; } return false; @@ -174,7 +174,7 @@ function setCreatedBy($user_id) { $mdb2 = getConnection(); // Update group. - $sql = "update tt_teams set created_by = $user_id where id = $this->group_id"; + $sql = "update tt_groups set created_by = $user_id where id = $this->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) { $this->err->add($i18n->get('error.db')); @@ -199,7 +199,7 @@ function registeredRecently() { $mdb2 = getConnection(); $ip_part = ' created_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']); - $sql = 'select created from tt_teams where '.$ip_part.' and created > now() - interval 1 minute'; + $sql = 'select created from tt_groups where '.$ip_part.' and created > now() - interval 1 minute'; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 2aff793bc..d5a7f51de 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -725,8 +725,8 @@ static function markDeleted($team_id) { $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - // Mark team deleted. - $sql = "update tt_teams set status = NULL where id = $team_id"; + // Mark group deleted. + $sql = "update tt_groups set status = NULL where id = $team_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -739,7 +739,7 @@ static function getTeamDetails($team_id) { $mdb2 = getConnection(); $sql = "select t.name as team_name, u.id as manager_id, u.name as manager_name, u.login as manager_login, u.email as manager_email - from tt_teams t + from tt_groups t inner join tt_users u on (u.team_id = t.id) inner join tt_roles r on (r.id = u.role_id and r.rank = 512) where t.id = $team_id"; @@ -842,11 +842,11 @@ static function insert($fields) { $columns .= ', created, created_ip, created_by'; $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); - $sql = "insert into tt_teams ($columns) values($values)"; + $sql = "insert into tt_groups ($columns) values($values)"; $affected = $mdb2->exec($sql); if (!is_a($affected, 'PEAR_Error')) { - $team_id = $mdb2->lastInsertID('tt_teams', 'id'); + $team_id = $mdb2->lastInsertID('tt_groups', 'id'); return $team_id; } @@ -889,7 +889,7 @@ static function update($team_id, $fields) if (isset($fields['workday_minutes'])) $workday_minutes_part = ', workday_minutes = '.$mdb2->quote($fields['workday_minutes']); $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); - $sql = "update tt_teams set $name_part $currency_part $lang_part $decimal_mark_part + $sql = "update tt_groups set $name_part $currency_part $lang_part $decimal_mark_part $date_format_part $time_format_part $week_start_part $tracking_mode_part $task_required_part $record_type_part $bcc_email_part $plugins_part $config_part $lock_spec_part $workday_minutes_part $modified_part where id = $team_id"; $affected = $mdb2->exec($sql); @@ -906,7 +906,7 @@ static function getInactiveTeams() { // Get all team ids for teams created or modified more than 8 months ago. // $ts = date('Y-m-d', strtotime('-1 year')); $ts = $mdb2->quote(date('Y-m-d', strtotime('-8 month'))); - $sql = "select id from tt_teams where created < $ts and (modified is null or modified < $ts) order by id"; + $sql = "select id from tt_groups where created < $ts and (modified is null or modified < $ts) order by id"; $res = $mdb2->query($sql); $count = 0; @@ -1014,8 +1014,8 @@ static function delete($team_id) { $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - // Delete team. - $sql = "delete from tt_teams where id = $team_id"; + // Delete group. + $sql = "delete from tt_groups where id = $team_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index f9edc8cc7..7e167f612 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -76,7 +76,7 @@ function __construct($login, $id = null) { t.currency, t.lang, t.decimal_mark, t.date_format, t.time_format, t.week_start, t.tracking_mode, t.project_required, t.task_required, t.record_type, t.bcc_email, t.plugins, t.config, t.lock_spec, t.workday_minutes, t.custom_logo - FROM tt_users u LEFT JOIN tt_teams t ON (u.team_id = t.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; + FROM tt_users u LEFT JOIN tt_groups t ON (u.team_id = t.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; if ($id) $sql .= "u.id = $id"; else diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 31c7bde4d..dab51297c 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -318,7 +318,7 @@ static function markDeleted($user_id) { return false; // Mark team deleted. - $sql = "update tt_teams set status = NULL where id = $user->team_id"; + $sql = "update tt_groups set status = NULL where id = $user->team_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 4e06cc0ec..9631a87b6 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -89,7 +89,7 @@ 'error.task_exists' => 'Er bestaat al een taak met deze naam.', 'error.client_exists' => 'Een klant met deze naam bestaat al.', 'error.invoice_exists' => 'Dit nummer is al eens toegekend aan een factuur.', -// TODO: translate the following. It seems like rank is misplaced ith rights. +// TODO: translate the following. It seems like rank is misplaced with rights. // 'error.role_exists' => 'Role with this rank already exists.', // 'error.role_exists' => 'Een rol met deze rechten bestaat al.', // TODO: rank is not rights. Rank is a number. // Rights (rechten) is a set of permissions ("view_users", etc.). diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e70cdbeae..1a5dbf67f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.80.4198 | Copyright © Anuko | +  Anuko Time Tracker 1.17.80.4199 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 8f1e867f2..190ff7eea 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11779"]) { + if ($_POST["convert11744to11780"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -869,6 +869,9 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.17.78', modified = now() where param_name = 'version_db' and param_value = '1.17.77'"); setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.78') set rights = replace(rights, 'manage_own_settings,view_projects,view_users', 'view_own_projects,manage_own_settings,view_users')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.79', modified = now() where param_name = 'version_db' and param_value = '1.17.78'"); + setChange("RENAME TABLE `tt_teams` TO `tt_groups`"); + setChange("ALTER TABLE `tt_monthly_quotas` DROP FOREIGN KEY FK_TT_TEAM_CONSTRAING"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.80', modified = now() where param_name = 'version_db' and param_value = '1.17.79'"); } if ($_POST["cleanup"]) { @@ -897,7 +900,7 @@ function setChange($sql) { setChange("OPTIMIZE TABLE tt_project_task_binds"); setChange("OPTIMIZE TABLE tt_projects"); setChange("OPTIMIZE TABLE tt_tasks"); - setChange("OPTIMIZE TABLE tt_teams"); + setChange("OPTIMIZE TABLE tt_groups"); setChange("OPTIMIZE TABLE tt_tmp_refs"); setChange("OPTIMIZE TABLE tt_user_project_binds"); setChange("OPTIMIZE TABLE tt_users"); @@ -914,7 +917,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.79) + Create database structure (v1.17.80)
(applies only to new installations, do not execute when updating)
@@ -954,8 +957,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.79)Update database structure (v1.17.44 to v1.17.80)
diff --git a/mysql.sql b/mysql.sql index 9d2f1e7b4..4a48a662c 100644 --- a/mysql.sql +++ b/mysql.sql @@ -9,10 +9,10 @@ # -# Structure for table tt_teams. A team is a group of users for whom we are tracking work time. +# Structure for table tt_groups. A team is a group of users for whom we are tracking work time. # This table stores settings common to all group members such as language, week start day, etc. # -CREATE TABLE `tt_teams` ( +CREATE TABLE `tt_groups` ( `id` int(11) NOT NULL auto_increment, # group id `parent_id` int(11) default NULL, # parent group id `org_id` int(11) default NULL, # organization id (id of top group) @@ -425,19 +425,16 @@ CREATE TABLE `tt_predefined_expenses` ( # # Structure for table tt_monthly_quotas. -# This table keeps monthly work hour quotas for teams. +# This table keeps monthly work hour quotas for groups. # CREATE TABLE `tt_monthly_quotas` ( - `team_id` int(11) NOT NULL, # team id + `team_id` int(11) NOT NULL, # group id `year` smallint(5) UNSIGNED NOT NULL, # quota year `month` tinyint(3) UNSIGNED NOT NULL, # quota month `minutes` int(11) default NULL, # quota in minutes in specified month and year PRIMARY KEY (`team_id`,`year`,`month`) ); -ALTER TABLE `tt_monthly_quotas` - ADD CONSTRAINT `FK_TT_TEAM_CONSTRAING` FOREIGN KEY (`team_id`) REFERENCES `tt_teams` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; - # # Structure for table tt_site_config. This table stores configuration data @@ -452,4 +449,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.79', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.80', now()); # TODO: change when structure changes. From 45c855269d952873285f7a835e82fc2b3eff3971 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 29 Mar 2018 23:35:58 +0000 Subject: [PATCH 0082/1848] Refactoring. Renamed team_id fields to become group_id. --- WEB-INF/lib/ttAdmin.class.php | 22 +- WEB-INF/lib/ttClientHelper.class.php | 30 +-- WEB-INF/lib/ttCustomFieldHelper.class.php | 6 +- WEB-INF/lib/ttExportHelper.class.php | 24 +- WEB-INF/lib/ttImportHelper.class.php | 30 +-- WEB-INF/lib/ttInvoiceHelper.class.php | 16 +- WEB-INF/lib/ttNotificationHelper.class.php | 14 +- .../lib/ttPredefinedExpenseHelper.class.php | 14 +- WEB-INF/lib/ttProjectHelper.class.php | 28 +-- WEB-INF/lib/ttRegistrator.class.php | 4 +- WEB-INF/lib/ttReportHelper.class.php | 12 +- WEB-INF/lib/ttRoleHelper.class.php | 44 ++-- WEB-INF/lib/ttTaskHelper.class.php | 18 +- WEB-INF/lib/ttTeamHelper.class.php | 206 +++++++++--------- WEB-INF/lib/ttUser.class.php | 14 +- WEB-INF/lib/ttUserHelper.class.php | 24 +- WEB-INF/lib/ttWeekViewHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- admin_team_delete.php | 8 +- admin_team_edit.php | 8 +- client_add.php | 4 +- client_edit.php | 4 +- clients.php | 4 +- dbinstall.php | 11 + expense_edit.php | 6 +- expenses.php | 6 +- group_edit.php | 2 +- initialize.php | 4 +- invoice_add.php | 4 +- locking.php | 2 +- mobile/client_add.php | 4 +- mobile/client_edit.php | 4 +- mobile/clients.php | 4 +- mobile/expense_edit.php | 6 +- mobile/expenses.php | 6 +- mobile/project_add.php | 4 +- mobile/project_edit.php | 4 +- mobile/projects.php | 4 +- mobile/task_add.php | 4 +- mobile/task_edit.php | 4 +- mobile/tasks.php | 4 +- mobile/time.php | 8 +- mobile/time_edit.php | 8 +- mobile/timer.php | 8 +- mobile/user_add.php | 6 +- mobile/user_edit.php | 4 +- mobile/users.php | 2 +- mysql.sql | 44 ++-- notification_add.php | 2 +- notification_edit.php | 2 +- notifications.php | 2 +- password_change.php | 4 +- plugins/CustomFields.class.php | 30 +-- plugins/MonthlyQuota.class.php | 18 +- predefined_expense_add.php | 2 +- predefined_expense_edit.php | 2 +- predefined_expenses.php | 2 +- project_add.php | 4 +- project_edit.php | 4 +- projects.php | 4 +- quotas.php | 2 +- report.php | 4 +- reports.php | 4 +- role_add.php | 4 +- task_add.php | 4 +- task_edit.php | 4 +- tasks.php | 4 +- time.php | 8 +- time_edit.php | 8 +- tofile.php | 2 +- topdf.php | 6 +- user_add.php | 6 +- user_edit.php | 4 +- week.php | 8 +- 74 files changed, 428 insertions(+), 417 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index ed1b280c3..83b93a767 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -47,7 +47,7 @@ function getSubgroups($group_id) { // getUsers obtains user ids in a group. function getUsers($group_id) { $mdb2 = getConnection(); - $sql = "select id from tt_users where team_id = $group_id"; + $sql = "select id from tt_users where group_id = $group_id"; $res = $mdb2->query($sql); $users = array(); if (!is_a($res, 'PEAR_Error')) { @@ -85,7 +85,7 @@ function markUserDeleted($user_id) { // The markTasksDeleted deletes task binds and marks the tasks as deleted for a group. function markTasksDeleted($group_id) { $mdb2 = getConnection(); - $sql = "select id from tt_tasks where team_id = $group_id"; + $sql = "select id from tt_tasks where group_id = $group_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; @@ -120,7 +120,7 @@ function markGroupDeleted($group_id) { // Now that we are done with subgroups, handle this group. $users = $this->getUsers($group_id); - // Iterate through team users and mark them as deleted. + // Iterate through group users and mark them as deleted. foreach ($users as $one_user) { if (!$this->markUserDeleted($one_user['id'])) return false; @@ -132,32 +132,32 @@ function markGroupDeleted($group_id) { $mdb2 = getConnection(); // Mark roles deleted. - $sql = "update tt_roles set status = NULL where team_id = $group_id"; + $sql = "update tt_roles set status = NULL where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark projects deleted. - $sql = "update tt_projects set status = NULL where team_id = $group_id"; + $sql = "update tt_projects set status = NULL where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark clients deleted. - $sql = "update tt_clients set status = NULL where team_id = $group_id"; + $sql = "update tt_clients set status = NULL where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark invoices deleted. - $sql = "update tt_invoices set status = NULL where team_id = $group_id"; + $sql = "update tt_invoices set status = NULL where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark custom fields deleted. - $sql = "update tt_custom_fields set status = NULL where team_id = $group_id"; + $sql = "update tt_custom_fields set status = NULL where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark notifications deleted. - $sql = "update tt_cron set status = NULL where team_id = $group_id"; + $sql = "update tt_cron set status = NULL where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -232,7 +232,7 @@ function validateGroupInfo($fields) { } // updateGroup validates user input and updates the group with new information. - function updateGroup($team_id, $fields) { + function updateGroup($group_id, $fields) { if (!$this->validateGroupInfo($fields)) return false; // Can't continue as user input is invalid. global $user; @@ -242,7 +242,7 @@ function updateGroup($team_id, $fields) { if ($fields['old_group_name'] != $fields['new_group_name']) { $name_part = 'name = '.$mdb2->quote($fields['new_group_name']); $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); - $sql = 'update tt_groups set '.$name_part.$modified_part.' where id = '.$team_id; + $sql = 'update tt_groups set '.$name_part.$modified_part.' where id = '.$group_id; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; } diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 288cd45be..f11edc90f 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -41,7 +41,7 @@ static function getClient($client_id, $all_fields = false) { else $sql .= 'name '; - $sql .= "from tt_clients where team_id = $user->team_id + $sql .= "from tt_clients where group_id = $user->group_id and id = $client_id and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -60,7 +60,7 @@ static function getClients() $mdb2 = getConnection(); $sql = "select id, name from tt_clients - where team_id = $user->team_id and (status = 0 or status = 1) order by upper(name)"; + where group_id = $user->group_id and (status = 0 or status = 1) order by upper(name)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -76,7 +76,7 @@ static function getClientByName($client_name) { $mdb2 = getConnection(); global $user; - $sql = "select id from tt_clients where team_id = $user->team_id and name = ". + $sql = "select id from tt_clients where group_id = $user->group_id and name = ". $mdb2->quote($client_name)." and (status = 1 or status = 0)"; $res = $mdb2->query($sql); @@ -95,7 +95,7 @@ static function getDeletedClient($client_id) { $mdb2 = getConnection(); global $user; - $sql = "select name, address from tt_clients where team_id = $user->team_id + $sql = "select name, address from tt_clients where group_id = $user->group_id and id = $client_id and status is NULL"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -138,7 +138,7 @@ static function delete($id, $delete_client_entries) { // Handle invoices. if ($delete_client_entries) { - $sql = "update tt_invoices set status = NULL where client_id = $id and team_id = $user->team_id"; + $sql = "update tt_invoices set status = NULL where client_id = $id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -151,13 +151,13 @@ static function delete($id, $delete_client_entries) { return false; // Handle users for client. - $sql = 'update tt_users set status = NULL'.$modified_part." where client_id = $id and team_id = $user->team_id"; + $sql = 'update tt_users set status = NULL'.$modified_part." where client_id = $id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark client deleted. - $sql = "update tt_clients set status = NULL where id = $id and team_id = $user->team_id"; + $sql = "update tt_clients set status = NULL where id = $id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -168,7 +168,7 @@ static function insert($fields) global $user; $mdb2 = getConnection(); - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $name = $fields['name']; $address = $fields['address']; $tax = $fields['tax']; @@ -180,8 +180,8 @@ static function insert($fields) $tax = str_replace(',', '.', $tax); if ($tax == '') $tax = 0; - $sql = "insert into tt_clients (team_id, name, address, tax, projects, status) - values ($team_id, ".$mdb2->quote($name).", ".$mdb2->quote($address).", $tax, ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_clients (group_id, name, address, tax, projects, status)". + " values ($group_id, ".$mdb2->quote($name).", ".$mdb2->quote($address).", $tax, ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) @@ -236,16 +236,16 @@ static function update($fields) // Update client properties in tt_clients table. $comma_separated = implode(",", $projects); // This is a comma-separated list of associated project ids. $sql = "update tt_clients set name = ".$mdb2->quote($name).", address = ".$mdb2->quote($address). - ", tax = $tax, projects = ".$mdb2->quote($comma_separated).", status = $status where team_id = ".$user->team_id." and id = ".$id; + ", tax = $tax, projects = ".$mdb2->quote($comma_separated).", status = $status where group_id = ".$user->group_id." and id = ".$id; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } // The setMappedClient function is used during team import to change client_id value for tt_users to a mapped value. - static function setMappedClient($team_id, $imported_id, $mapped_id) + static function setMappedClient($group_id, $imported_id, $mapped_id) { $mdb2 = getConnection(); - $sql = "update tt_users set client_id = $mapped_id where client_id = $imported_id and team_id = $team_id "; + $sql = "update tt_users set client_id = $mapped_id where client_id = $imported_id and group_id = $group_id "; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -272,7 +272,7 @@ static function getAssignedProjects($client_id) // Do a query with inner join to get assigned projects. $sql = "select p.id, p.name from tt_projects p inner join tt_client_project_binds cpb on (cpb.client_id = $client_id and cpb.project_id = p.id) - where p.team_id = $user->team_id and p.status = 1 order by p.name"; + where p.group_id = $user->group_id and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -318,7 +318,7 @@ static function getAssignedProjectsForUser($client_id) $sql = "select p.id, p.name from tt_projects p inner join tt_client_project_binds cpb on (cpb.client_id = $client_id and cpb.project_id = p.id) inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id and upb.status = 1) - where p.team_id = $user->team_id and p.status = 1 order by p.name"; + where p.group_id = $user->group_id and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/lib/ttCustomFieldHelper.class.php b/WEB-INF/lib/ttCustomFieldHelper.class.php index f12675083..15c7ca054 100644 --- a/WEB-INF/lib/ttCustomFieldHelper.class.php +++ b/WEB-INF/lib/ttCustomFieldHelper.class.php @@ -34,14 +34,14 @@ static function insertField($fields) { $mdb2 = getConnection(); - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $type = (int) $fields['type']; $label = $fields['label']; $required = (int) $fields['required']; $status = $fields['status']; - $sql = "insert into tt_custom_fields (team_id, type, label, required, status) - values ($team_id, $type, ".$mdb2->quote($label).", $required, ".$mdb2->quote($status).")"; + $sql = "insert into tt_custom_fields (group_id, type, label, required, status)". + " values ($group_id, $type, ".$mdb2->quote($label).", $required, ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) diff --git a/WEB-INF/lib/ttExportHelper.class.php b/WEB-INF/lib/ttExportHelper.class.php index 375de2f37..22521c739 100644 --- a/WEB-INF/lib/ttExportHelper.class.php +++ b/WEB-INF/lib/ttExportHelper.class.php @@ -83,17 +83,17 @@ function createDataFile($compress = false) { $this->userMap[$user_item['id']] = $key + 1; // Prepare project map. - $projects = ttTeamHelper::getAllProjects($user->team_id, true); + $projects = ttTeamHelper::getAllProjects($user->group_id, true); foreach ($projects as $key=>$project_item) $this->projectMap[$project_item['id']] = $key + 1; // Prepare task map. - $tasks = ttTeamHelper::getAllTasks($user->team_id, true); + $tasks = ttTeamHelper::getAllTasks($user->group_id, true); foreach ($tasks as $key=>$task_item) $this->taskMap[$task_item['id']] = $key + 1; // Prepare client map. - $clients = ttTeamHelper::getAllClients($user->team_id, true); + $clients = ttTeamHelper::getAllClients($user->group_id, true); foreach ($clients as $key=>$client_item) $this->clientMap[$client_item['id']] = $key + 1; @@ -103,12 +103,12 @@ function createDataFile($compress = false) { $this->invoiceMap[$invoice_item['id']] = $key + 1; // Prepare custom fields map. - $custom_fields = ttTeamHelper::getAllCustomFields($user->team_id); + $custom_fields = ttTeamHelper::getAllCustomFields($user->group_id); foreach ($custom_fields as $key=>$custom_field) $this->customFieldMap[$custom_field['id']] = $key + 1; // Prepare custom field options map. - $custom_field_options = ttTeamHelper::getAllCustomFieldOptions($user->team_id); + $custom_field_options = ttTeamHelper::getAllCustomFieldOptions($user->group_id); foreach ($custom_field_options as $key=>$option) $this->customFieldOptionMap[$option['id']] = $key + 1; @@ -164,7 +164,7 @@ function createDataFile($compress = false) { // Write user to project binds. fwrite($file, "\n"); - $user_binds = ttTeamHelper::getUserToProjectBinds($user->team_id); + $user_binds = ttTeamHelper::getUserToProjectBinds($user->group_id); foreach ($user_binds as $bind) { $user_id = $this->userMap[$bind['user_id']]; $project_id = $this->projectMap[$bind['project_id']]; @@ -222,7 +222,7 @@ function createDataFile($compress = false) { unset($custom_field_options); // Write monthly quotas. - $quotas = ttTeamHelper::getMonthlyQuotas($user->team_id); + $quotas = ttTeamHelper::getMonthlyQuotas($user->group_id); fwrite($file, "\n"); foreach ($quotas as $quota) { fwrite($file, " \n"); @@ -246,7 +246,7 @@ function createDataFile($compress = false) { unset($records); // Write custom field log. - $custom_field_log = ttTeamHelper::getCustomFieldLog($user->team_id); + $custom_field_log = ttTeamHelper::getCustomFieldLog($user->group_id); fwrite($file, "\n"); foreach ($custom_field_log as $entry) { fwrite($file, " logMap[$entry['log_id']]."\" field_id=\"".$this->customFieldMap[$entry['field_id']]."\" option_id=\"".$this->customFieldOptionMap[$entry['option_id']]."\" status=\"".$entry['status']."\">\n"); @@ -257,7 +257,7 @@ function createDataFile($compress = false) { unset($custom_field_log); // Write expense items. - $expense_items = ttTeamHelper::getExpenseItems($user->team_id); + $expense_items = ttTeamHelper::getExpenseItems($user->group_id); fwrite($file, "\n"); foreach ($expense_items as $expense_item) { fwrite($file, " userMap[$expense_item['user_id']]."\" client_id=\"".$this->clientMap[$expense_item['client_id']]."\" project_id=\"".$this->projectMap[$expense_item['project_id']]."\" cost=\"".$expense_item['cost']."\" invoice_id=\"".$this->invoiceMap[$expense_item['invoice_id']]."\" paid=\"".$expense_item['paid']."\" status=\"".$expense_item['status']."\">\n"); @@ -269,7 +269,7 @@ function createDataFile($compress = false) { // Write fav reports. fwrite($file, "\n"); - $fav_reports = ttTeamHelper::getFavReports($user->team_id); + $fav_reports = ttTeamHelper::getFavReports($user->group_id); foreach ($fav_reports as $fav_report) { $user_list = ''; if (strlen($fav_report['users']) > 0) { @@ -381,7 +381,7 @@ function getRoles() { $mdb2 = getConnection(); $result = array(); - $sql = "select * from tt_roles where team_id = $user->team_id"; + $sql = "select * from tt_roles where group_id = $user->group_id"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -398,7 +398,7 @@ function getUsers() { global $user; $mdb2 = getConnection(); - $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.team_id = $user->team_id order by upper(u.name)"; // Note: deleted users are included. + $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $user->group_id order by upper(u.name)"; // Note: deleted users are included. $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index ca717caef..ea54d0edc 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -47,7 +47,7 @@ class ttImportHelper { var $canImport = true; // False if we cannot import data due to a login collision. var $teamData = array(); // Array of team data such as team name, etc. - var $team_id = null; // New team id we are importing. It is created during the import operation. + var $group_id = null; // New group id we are importing. It is created during the import operation. var $roles = array(); // Array of arrays of role properties. var $users = array(); // Array of arrays of user properties. var $top_role_id = null; // Top manager role id on the new server. @@ -124,7 +124,7 @@ function endElement($parser, $name) { // Now we can create a team. if ($this->canImport) { $this->top_role_id = ttRoleHelper::getRoleByRank(512, 0); - $team_id = ttTeamHelper::insert(array( + $group_id = ttTeamHelper::insert(array( 'name' => $this->teamData['NAME'], 'currency' => $this->teamData['CURRENCY'], 'decimal_mark' => $this->teamData['DECIMAL_MARK'], @@ -141,13 +141,13 @@ function endElement($parser, $name) { 'lock_spec' => $this->teamData['LOCK_SPEC'], 'workday_minutes' => $this->teamData['WORKDAY_MINUTES'], 'config' => $this->teamData['CONFIG'])); - if ($team_id) { - $this->team_id = $team_id; + if ($group_id) { + $this->group_id = $group_id; // Create roles. foreach ($this->roles as $key=>$role_item) { $role_id = ttRoleHelper::insert(array( - 'team_id' => $this->team_id, + 'group_id' => $this->group_id, 'name' => $role_item['NAME'], 'rank' => $role_item['RANK'], 'rights' => $role_item['RIGHTS'], @@ -158,7 +158,7 @@ function endElement($parser, $name) { foreach ($this->users as $key=>$user_item) { $role_id = $user_item['ROLE_ID'] === '0' ? $this->top_role_id : $this->roleMap[$user_item['ROLE_ID']]; // 0 (not null) means top manager role. $user_id = ttUserHelper::insert(array( - 'team_id' => $this->team_id, + 'group_id' => $this->group_id, 'role_id' => $role_id, 'client_id' => $user_item['CLIENT_ID'], // Note: NOT mapped value, replaced in CLIENT handler. 'name' => $user_item['NAME'], @@ -176,7 +176,7 @@ function endElement($parser, $name) { if ($name == 'TASK' && $this->canImport) { $this->taskMap[$this->currentElement['ID']] = ttTaskHelper::insert(array( - 'team_id' => $this->team_id, + 'group_id' => $this->group_id, 'name' => $this->currentElement['NAME'], 'description' => $this->currentElement['DESCRIPTION'], 'status' => $this->currentElement['STATUS'])); @@ -190,7 +190,7 @@ function endElement($parser, $name) { // Add a new project. $this->projectMap[$this->currentElement['ID']] = ttProjectHelper::insert(array( - 'team_id' => $this->team_id, + 'group_id' => $this->group_id, 'name' => $this->currentElement['NAME'], 'description' => $this->currentElement['DESCRIPTION'], 'tasks' => $mapped_tasks, @@ -214,7 +214,7 @@ function endElement($parser, $name) { $this->clientMap[$this->currentElement['ID']] = ttClientHelper::insert(array( - 'team_id' => $this->team_id, + 'group_id' => $this->group_id, 'name' => $this->currentElement['NAME'], 'address' => $this->currentElement['ADDRESS'], 'tax' => $this->currentElement['TAX'], @@ -224,13 +224,13 @@ function endElement($parser, $name) { // Update client_id for tt_users to a mapped value. // We did not do it during user insertion because clientMap was not ready then. if ($this->currentElement['ID'] != $this->clientMap[$this->currentElement['ID']]) - ttClientHelper::setMappedClient($this->team_id, $this->currentElement['ID'], $this->clientMap[$this->currentElement['ID']]); + ttClientHelper::setMappedClient($this->group_id, $this->currentElement['ID'], $this->clientMap[$this->currentElement['ID']]); } if ($name == 'INVOICE' && $this->canImport) { $this->invoiceMap[$this->currentElement['ID']] = ttInvoiceHelper::insert(array( - 'team_id' => $this->team_id, + 'group_id' => $this->group_id, 'name' => $this->currentElement['NAME'], 'date' => $this->currentElement['DATE'], 'client_id' => $this->clientMap[$this->currentElement['CLIENT_ID']], @@ -239,7 +239,7 @@ function endElement($parser, $name) { } if ($name == 'MONTHLY_QUOTA' && $this->canImport) { - $this->insertMonthlyQuota($this->team_id, $this->currentElement['YEAR'], $this->currentElement['MONTH'], $this->currentElement['MINUTES']); + $this->insertMonthlyQuota($this->group_id, $this->currentElement['YEAR'], $this->currentElement['MONTH'], $this->currentElement['MINUTES']); } if ($name == 'LOG_ITEM' && $this->canImport) { @@ -263,7 +263,7 @@ function endElement($parser, $name) { if ($name == 'CUSTOM_FIELD' && $this->canImport) { $this->customFieldMap[$this->currentElement['ID']] = ttCustomFieldHelper::insertField(array( - 'team_id' => $this->team_id, + 'group_id' => $this->group_id, 'type' => $this->currentElement['TYPE'], 'label' => $this->currentElement['LABEL'], 'required' => $this->currentElement['REQUIRED'], @@ -433,9 +433,9 @@ function uncompress($in, $out) { } // insertMonthlyQuota - a helper function to insert a monthly quota. - private function insertMonthlyQuota($team_id, $year, $month, $minutes) { + private function insertMonthlyQuota($group_id, $year, $month, $minutes) { $mdb2 = getConnection(); - $sql = "INSERT INTO tt_monthly_quotas (team_id, year, month, minutes) values ($team_id, $year, $month, $minutes)"; + $sql = "INSERT INTO tt_monthly_quotas (group_id, year, month, minutes) values ($group_id, $year, $month, $minutes)"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index d58bc1161..d35aa3486 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -37,7 +37,7 @@ static function insert($fields) { $mdb2 = getConnection(); - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $name = $fields['name']; if (!$name) return false; @@ -49,8 +49,8 @@ static function insert($fields) } // Insert a new invoice record. - $sql = "insert into tt_invoices (team_id, name, date, client_id $status_f) - values($team_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id $status_v)"; + $sql = "insert into tt_invoices (group_id, name, date, client_id $status_f)". + " values($group_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id $status_v)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -71,7 +71,7 @@ static function getInvoice($invoice_id) { if ($user->isClient()) $client_part = " and client_id = $user->client_id"; - $sql = "select * from tt_invoices where id = $invoice_id and team_id = $user->team_id $client_part and status = 1"; + $sql = "select * from tt_invoices where id = $invoice_id and group_id = $user->group_id $client_part and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) @@ -86,7 +86,7 @@ static function getInvoiceByName($invoice_name) { $mdb2 = getConnection(); global $user; - $sql = "select id from tt_invoices where team_id = $user->team_id and name = ".$mdb2->quote($invoice_name)." and status = 1"; + $sql = "select id from tt_invoices where group_id = $user->group_id and name = ".$mdb2->quote($invoice_name)." and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -233,7 +233,7 @@ static function delete($invoice_id, $delete_invoice_items) { $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $sql = "update tt_invoices set status = NULL where id = $invoice_id and team_id = $user->team_id"; + $sql = "update tt_invoices set status = NULL where id = $invoice_id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -328,8 +328,8 @@ static function createInvoice($fields) { if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; // Create a new invoice record. - $sql = "insert into tt_invoices (team_id, name, date, client_id) - values($user->team_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id)"; + $sql = "insert into tt_invoices (group_id, name, date, client_id) + values($user->group_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttNotificationHelper.class.php b/WEB-INF/lib/ttNotificationHelper.class.php index ee7880c45..34c852769 100644 --- a/WEB-INF/lib/ttNotificationHelper.class.php +++ b/WEB-INF/lib/ttNotificationHelper.class.php @@ -41,7 +41,7 @@ static function get($id) $sql = "select c.id, c.cron_spec, c.report_id, c.email, c.cc, c.subject, c.report_condition, c.status, fr.name from tt_cron c left join tt_fav_reports fr on (fr.id = c.report_id) - where c.id = $id and c.team_id = $user->team_id"; + where c.id = $id and c.group_id = $user->group_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -57,7 +57,7 @@ static function delete($id) { $mdb2 = getConnection(); - $sql = "delete from tt_cron where id = $id and team_id = $user->team_id"; + $sql = "delete from tt_cron where id = $id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -70,7 +70,7 @@ static function insert($fields) { $mdb2 = getConnection(); - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $cron_spec = $fields['cron_spec']; $next = (int) $fields['next']; $report_id = (int) $fields['report_id']; @@ -80,8 +80,8 @@ static function insert($fields) $report_condition = $fields['report_condition']; $status = $fields['status']; - $sql = "insert into tt_cron (team_id, cron_spec, next, report_id, email, cc, subject, report_condition, status) - values ($team_id, ".$mdb2->quote($cron_spec).", $next, $report_id, ".$mdb2->quote($email).", ".$mdb2->quote($cc).", ".$mdb2->quote($subject).", ".$mdb2->quote($report_condition).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_cron (group_id, cron_spec, next, report_id, email, cc, subject, report_condition, status) + values ($group_id, ".$mdb2->quote($cron_spec).", $next, $report_id, ".$mdb2->quote($email).", ".$mdb2->quote($cc).", ".$mdb2->quote($subject).", ".$mdb2->quote($report_condition).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -95,7 +95,7 @@ static function update($fields) $mdb2 = getConnection(); $notification_id = (int) $fields['id']; - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $cron_spec = $fields['cron_spec']; $next = (int) $fields['next']; $report_id = (int) $fields['report_id']; @@ -106,7 +106,7 @@ static function update($fields) $status = $fields['status']; $sql = "update tt_cron set cron_spec = ".$mdb2->quote($cron_spec).", next = $next, report_id = $report_id, email = ".$mdb2->quote($email).", cc = ".$mdb2->quote($cc).", subject = ".$mdb2->quote($subject).", report_condition = ".$mdb2->quote($report_condition).", status = ".$mdb2->quote($status). - " where id = $notification_id and team_id = $team_id"; + " where id = $notification_id and group_id = $group_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php index 556bc42f6..c292870fb 100644 --- a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php +++ b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php @@ -39,7 +39,7 @@ static function get($id) $mdb2 = getConnection(); $sql = "select id, name, cost from tt_predefined_expenses - where id = $id and team_id = $user->team_id"; + where id = $id and group_id = $user->group_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -58,7 +58,7 @@ static function delete($id) { $mdb2 = getConnection(); - $sql = "delete from tt_predefined_expenses where id = $id and team_id = $user->team_id"; + $sql = "delete from tt_predefined_expenses where id = $id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -73,14 +73,14 @@ static function insert($fields) $mdb2 = getConnection(); - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $name = $fields['name']; $cost = $fields['cost']; if ('.' != $user->decimal_mark) $cost = str_replace($user->decimal_mark, '.', $cost); - $sql = "insert into tt_predefined_expenses (team_id, name, cost) - values ($team_id, ".$mdb2->quote($name).", ".$mdb2->quote($cost).")"; + $sql = "insert into tt_predefined_expenses (group_id, name, cost) + values ($group_id, ".$mdb2->quote($name).", ".$mdb2->quote($cost).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -96,14 +96,14 @@ static function update($fields) $mdb2 = getConnection(); $predefined_expense_id = (int) $fields['id']; - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $name = $fields['name']; $cost = $fields['cost']; if ('.' != $user->decimal_mark) $cost = str_replace($user->decimal_mark, '.', $cost); $sql = "update tt_predefined_expenses set name = ".$mdb2->quote($name).", cost = ".$mdb2->quote($cost). - " where id = $predefined_expense_id and team_id = $team_id"; + " where id = $predefined_expense_id and group_id = $group_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index d3e0eb1b7..ff154af45 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -35,7 +35,7 @@ class ttProjectHelper { // getAssignedProjects - returns an array of assigned projects. static function getAssignedProjects($user_id) { - global $user; + global $user; $result = array(); $mdb2 = getConnection(); @@ -43,7 +43,7 @@ static function getAssignedProjects($user_id) // Do a query with inner join to get assigned projects. $sql = "select p.id, p.name, p.tasks, upb.rate from tt_projects p inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id and upb.status = 1) - where p.team_id = $user->team_id and p.status = 1 order by p.name"; + where p.group_id = $user->group_id and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -63,7 +63,7 @@ static function getRates($user_id) $sql = "select p.id, upb.rate from tt_projects p inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id) - where team_id = $user->team_id"; + where group_id = $user->group_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -82,8 +82,8 @@ static function getProjects() $result = array(); $mdb2 = getConnection(); - $sql = "select id, name, tasks from tt_projects - where team_id = $user->team_id and (status = 0 or status = 1) order by name"; + $sql = "select id, name, tasks from tt_projects". + " where group_id = $user->group_id and (status = 0 or status = 1) order by name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -104,7 +104,7 @@ static function getProjectsForClient() $sql = "select p.id, p.name, p.tasks from tt_projects p inner join tt_client_project_binds cpb on (cpb.client_id = $user->client_id and cpb.project_id = p.id) - where p.team_id = $user->team_id and (p.status = 0 or p.status = 1) + where p.group_id = $user->group_id and (p.status = 0 or p.status = 1) order by p.name"; $res = $mdb2->query($sql); @@ -124,7 +124,7 @@ static function get($id) $mdb2 = getConnection(); - $sql = "select id, name, description, status, tasks from tt_projects where id = $id and team_id = $user->team_id and (status = 0 or status = 1)"; + $sql = "select id, name, description, status, tasks from tt_projects where id = $id and group_id = $user->group_id and (status = 0 or status = 1)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -140,7 +140,7 @@ static function getProjectByName($name) { $mdb2 = getConnection(); global $user; - $sql = "select id from tt_projects where team_id = $user->team_id and name = ". + $sql = "select id from tt_projects where group_id = $user->group_id and name = ". $mdb2->quote($name)." and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -161,7 +161,7 @@ static function delete($id) { // we'll fail right here and don't damage any other data. // Mark project as deleted and remove associated tasks. - $sql = "update tt_projects set status = NULL, tasks = NULL where id = $id and team_id = $user->team_id"; + $sql = "update tt_projects set status = NULL, tasks = NULL where id = $id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error') || 0 == $affected) return false; // An error ocurred, or 0 rows updated. @@ -186,7 +186,7 @@ static function insert($fields) { $mdb2 = getConnection(); - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $name = $fields['name']; $description = $fields['description']; @@ -195,8 +195,8 @@ static function insert($fields) $comma_separated = implode(',', $tasks); // This is a comma-separated list of associated task ids. $status = $fields['status']; - $sql = "insert into tt_projects (team_id, name, description, tasks, status) - values ($team_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_projects (group_id, name, description, tasks, status) + values ($group_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -220,7 +220,7 @@ static function insert($fields) } // Bind the project to tasks in tt_project_task_binds table. - $all_tasks = ttTeamHelper::getAllTasks($team_id); + $all_tasks = ttTeamHelper::getAllTasks($group_id); foreach ($all_tasks as $task) { if(in_array($task['id'], $tasks)) { $sql = "insert into tt_project_task_binds (project_id, task_id) values($last_id, ".$task['id'].")"; @@ -312,7 +312,7 @@ static function update($fields) { // Update project name, description, tasks and status in tt_projects table. $comma_separated = implode(",", $tasks_to_bind); // This is a comma-separated list of associated task ids. $sql = "update tt_projects set name = ".$mdb2->quote($name).", description = ".$mdb2->quote($description). - ", tasks = ".$mdb2->quote($comma_separated).", status = $status where id = $project_id and team_id = $user->team_id"; + ", tasks = ".$mdb2->quote($comma_separated).", status = $status where id = $project_id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 23df23eab..a82ebd3f4 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -157,7 +157,7 @@ function createUser() { $created_ip = $mdb2->quote($_SERVER['REMOTE_ADDR']); $values = "values($login, $password, $name, $this->group_id, $this->role_id, $email, $created, $created_ip)"; - $sql = 'insert into tt_users (login, password, name, team_id, role_id, email, created, created_ip) '.$values; + $sql = 'insert into tt_users (login, password, name, group_id, role_id, email, created, created_ip) '.$values; $affected = $mdb2->exec($sql); if (!is_a($affected, 'PEAR_Error')) { $user_id = $mdb2->lastInsertID('tt_users', 'id'); @@ -182,7 +182,7 @@ function setCreatedBy($user_id) { } // Update top manager. - $sql = "update tt_users set created_by = $user_id where id = $user_id and team_id = $this->group_id"; + $sql = "update tt_users set created_by = $user_id where id = $user_id and group_id = $this->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) { $this->err->add($i18n->get('error.db')); diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index b894b037d..67f1da263 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -257,7 +257,7 @@ static function getItems($bean) { // Add custom field. $include_cf_1 = $bean->getAttribute('chcf_1') || 'cf_1' == $group_by_option; if ($include_cf_1) { - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $cf_1_type = $custom_fields->fields[0]['type']; if ($cf_1_type == CustomFields::TYPE_TEXT) { array_push($fields, 'cfl.value as cf_1'); @@ -522,7 +522,7 @@ static function getFavItems($report) { // Add custom field. $include_cf_1 = $report['show_custom_field_1'] || 'cf_1' == $group_by_option; if ($include_cf_1) { - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $cf_1_type = $custom_fields->fields[0]['type']; if ($cf_1_type == CustomFields::TYPE_TEXT) { array_push($fields, 'cfl.value as cf_1'); @@ -756,7 +756,7 @@ static function getSubtotals($bean) { break; case 'cf_1': $group_field = 'cfo.value'; - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) $group_join = 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id) '; elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) @@ -884,7 +884,7 @@ static function getFavSubtotals($report) { break; case 'cf_1': $group_field = 'cfo.value'; - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) $group_join = 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id) '; elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) @@ -1168,7 +1168,7 @@ static function prepareReportBody($bean, $comment) // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); // Define some styles to use in email. $style_title = 'text-align: center; font-size: 15pt; font-family: Arial, Helvetica, sans-serif;'; @@ -1464,7 +1464,7 @@ static function prepareFavReportBody($report) // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); // Define some styles to use in email. $style_title = 'text-align: center; font-size: 15pt; font-family: Arial, Helvetica, sans-serif;'; diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index c6cd02ba6..25d714194 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -37,7 +37,7 @@ static function get($id) $mdb2 = getConnection(); $sql = "select id, name, description, rank, rights, status from tt_roles - where id = $id and team_id = $user->team_id and (status = 0 or status = 1)"; + where id = $id and group_id = $user->group_id and (status = 0 or status = 1)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -56,7 +56,7 @@ static function getRoleByName($role_name) { $mdb2 = getConnection(); global $user; - $sql = "select id from tt_roles where team_id = $user->team_id and name = ". + $sql = "select id from tt_roles where group_id = $user->group_id and name = ". $mdb2->quote($role_name)." and (status = 1 or status = 0)"; $res = $mdb2->query($sql); @@ -72,7 +72,7 @@ static function getRoleByName($role_name) { static function getTopManagerRoleID() { $mdb2 = getConnection(); - $sql = "select id from tt_roles where team_id = 0 and rank = 512"; + $sql = "select id from tt_roles where group_id = 0 and rank = 512"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -89,7 +89,7 @@ static function isClientRole($role_id) { global $user; $mdb2 = getConnection(); - $sql = "select rights from tt_roles where team_id = $user->team_id and id = $role_id"; + $sql = "select rights from tt_roles where group_id = $user->group_id and id = $role_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -102,13 +102,13 @@ static function isClientRole($role_id) { } // getRoleByRank looks up a role by its rank. - static function getRoleByRank($rank, $team_id) { + static function getRoleByRank($rank, $group_id) { global $user; $mdb2 = getConnection(); $rank = (int) $rank; // Cast to int just in case for better security. - $sql = "select id from tt_roles where team_id = $team_id and rank = $rank and (status = 1 or status = 0)"; + $sql = "select id from tt_roles where group_id = $group_id and rank = $rank and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -131,7 +131,7 @@ static function update($fields) { if (isset($fields['status'])) $status_part = ', status = '.(int)$fields['status']; if (isset($fields['rights'])) $rights_part = ', rights = '.$mdb2->quote($fields['rights']); $parts = trim($name_part.$rank_part.$descr_part.$status_part.$rights_part, ','); - $sql = "update tt_roles set $parts where id = $id and team_id = $user->team_id"; + $sql = "update tt_roles set $parts where id = $id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -143,7 +143,7 @@ static function delete($role_id) { $mdb2 = getConnection(); // Mark the task as deleted. - $sql = "update tt_roles set status = NULL where id = $role_id and team_id = $user->team_id"; + $sql = "update tt_roles set status = NULL where id = $role_id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -153,15 +153,15 @@ static function insert($fields) { $mdb2 = getConnection(); - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $name = $fields['name']; $rank = (int) $fields['rank']; $description = $fields['description']; $rights = $fields['rights']; $status = $fields['status']; - $sql = "insert into tt_roles (team_id, name, rank, description, rights, status) - values ($team_id, ".$mdb2->quote($name).", $rank, ".$mdb2->quote($description).", ".$mdb2->quote($rights).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_roles (group_id, name, rank, description, rights, status) + values ($group_id, ".$mdb2->quote($name).", $rank, ".$mdb2->quote($description).", ".$mdb2->quote($rights).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -174,7 +174,7 @@ static function insert($fields) } // createPredefinedRoles - creates a set of predefined roles for the team to use. - static function createPredefinedRoles($team_id, $lang) + static function createPredefinedRoles($group_id, $lang) { // We need localized role names and a new I18n object to obtain them. import('I18n'); @@ -193,7 +193,7 @@ static function createPredefinedRoles($team_id, $lang) $name = $mdb2->quote($i18n->get('role.user.label')); $description = $mdb2->quote($i18n->get('role.user.description')); $rights = $mdb2->quote($rights_user); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($team_id, $name, $description, 4, $rights, 1)"; + $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($group_id, $name, $description, 4, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -201,7 +201,7 @@ static function createPredefinedRoles($team_id, $lang) $name = $mdb2->quote($i18n->get('role.client.label')); $description = $mdb2->quote($i18n->get('role.client.description')); $rights = $mdb2->quote($rights_client); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($team_id, $name, $description, 16, $rights, 1)"; + $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($group_id, $name, $description, 16, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -209,7 +209,7 @@ static function createPredefinedRoles($team_id, $lang) $name = $mdb2->quote($i18n->get('role.comanager.label')); $description = $mdb2->quote($i18n->get('role.comanager.description')); $rights = $mdb2->quote($rights_comanager); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($team_id, $name, $description, 68, $rights, 1)"; + $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($group_id, $name, $description, 68, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -217,7 +217,7 @@ static function createPredefinedRoles($team_id, $lang) $name = $mdb2->quote($i18n->get('role.manager.label')); $description = $mdb2->quote($i18n->get('role.manager.description')); $rights = $mdb2->quote($rights_manager); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($team_id, $name, $description, 324, $rights, 1)"; + $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($group_id, $name, $description, 324, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -226,7 +226,7 @@ static function createPredefinedRoles($team_id, $lang) $name = $mdb2->quote($i18n->get('role.supervisor.label')); $description = $mdb2->quote($i18n->get('role.supervisor.description')); $rights = $mdb2->quote($rights_supervisor); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($team_id, $name, $description, 12, $rights, 0)"; + $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($group_id, $name, $description, 12, $rights, 0)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -251,7 +251,7 @@ static function createDefaultRoles() $name = $mdb2->quote($i18n->get('role.user.label')); $description = $mdb2->quote($i18n->get('role.user.description')); $rights = $mdb2->quote($rights_user); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($user->team_id, $name, $description, 4, $rights, 1)"; + $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($user->group_id, $name, $description, 4, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -259,7 +259,7 @@ static function createDefaultRoles() $name = $mdb2->quote($i18n->get('role.client.label')); $description = $mdb2->quote($i18n->get('role.client.description')); $rights = $mdb2->quote($rights_client); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($user->team_id, $name, $description, 16, $rights, 1)"; + $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($user->group_id, $name, $description, 16, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -267,7 +267,7 @@ static function createDefaultRoles() $name = $mdb2->quote($i18n->get('role.comanager.label')); $description = $mdb2->quote($i18n->get('role.comanager.description')); $rights = $mdb2->quote($rights_comanager); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($user->team_id, $name, $description, 68, $rights, 1)"; + $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($user->group_id, $name, $description, 68, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -275,7 +275,7 @@ static function createDefaultRoles() $name = $mdb2->quote($i18n->get('role.manager.label')); $description = $mdb2->quote($i18n->get('role.manager.description')); $rights = $mdb2->quote($rights_manager); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($user->team_id, $name, $description, 324, $rights, 1)"; + $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($user->group_id, $name, $description, 324, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -284,7 +284,7 @@ static function createDefaultRoles() $name = $mdb2->quote($i18n->get('role.supervisor.label')); $description = $mdb2->quote($i18n->get('role.supervisor.description')); $rights = $mdb2->quote($rights_supervisor); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($user->team_id, $name, $description, 12, $rights, 0)"; + $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($user->group_id, $name, $description, 12, $rights, 0)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttTaskHelper.class.php b/WEB-INF/lib/ttTaskHelper.class.php index 24831cb26..e09c882d3 100644 --- a/WEB-INF/lib/ttTaskHelper.class.php +++ b/WEB-INF/lib/ttTaskHelper.class.php @@ -37,7 +37,7 @@ static function get($id) $mdb2 = getConnection(); $sql = "select id, name, description, status from tt_tasks - where id = $id and team_id = $user->team_id and (status = 0 or status = 1)"; + where id = $id and group_id = $user->group_id and (status = 0 or status = 1)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -61,7 +61,7 @@ static function getAssignedProjects($task_id) // Do a query with inner join to get assigned projects. $sql = "select p.id, p.name from tt_projects p inner join tt_project_task_binds ptb on (ptb.project_id = p.id and ptb.task_id = $task_id) - where p.team_id = $user->team_id and p.status = 1 order by p.name"; + where p.group_id = $user->group_id and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -77,7 +77,7 @@ static function getTaskByName($task_name) { $mdb2 = getConnection(); global $user; - $sql = "select id from tt_tasks where team_id = $user->team_id and name = ". + $sql = "select id from tt_tasks where group_id = $user->group_id and name = ". $mdb2->quote($task_name)." and (status = 1 or status = 0)"; $res = $mdb2->query($sql); @@ -103,7 +103,7 @@ static function delete($task_id) { // Delete project binds to this task from the tasks field in tt_projects table. // Get projects where tasks is not NULL. - $sql = "select id, tasks from tt_projects where team_id = $user->team_id and tasks is not NULL"; + $sql = "select id, tasks from tt_projects where group_id = $user->group_id and tasks is not NULL"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; @@ -135,14 +135,14 @@ static function insert($fields) { $mdb2 = getConnection(); - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $name = $fields['name']; $description = $fields['description']; $projects = $fields['projects']; $status = $fields['status']; - $sql = "insert into tt_tasks (team_id, name, description, status) - values ($team_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_tasks (group_id, name, description, status) + values ($group_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); $last_id = 0; if (is_a($affected, 'PEAR_Error')) @@ -198,7 +198,7 @@ static function update($fields) $projects = $fields['projects']; $sql = "update tt_tasks set name = ".$mdb2->quote($name).", description = ".$mdb2->quote($description). - ", status = $status where id = $task_id and team_id = $user->team_id"; + ", status = $status where id = $task_id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); @@ -220,7 +220,7 @@ static function update($fields) // We need to either delete or insert task id in all affected projects. // Get all not deleted projects for team. - $sql = "select id, tasks from tt_projects where team_id = $user->team_id and status is not NULL"; + $sql = "select id, tasks from tt_projects where group_id = $user->group_id and status is not NULL"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die($res->getMessage()); diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index d5a7f51de..01b0db360 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -34,10 +34,10 @@ class ttTeamHelper { // The getUserCount function returns number of people in team. - static function getUserCount($team_id) { + static function getUserCount($group_id) { $mdb2 = getConnection(); - $sql = "select count(id) as cnt from tt_users where team_id = $team_id and status = 1"; + $sql = "select count(id) as cnt from tt_users where group_id = $group_id and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -75,9 +75,9 @@ static function getActiveUsers($options = null) { $mdb2 = getConnection(); if (isset($options['getAllFields'])) - $sql = "select u.*, r.name as role_name, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.team_id = $user->team_id and u.status = 1 order by upper(u.name)"; + $sql = "select u.*, r.name as role_name, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $user->group_id and u.status = 1 order by upper(u.name)"; else - $sql = "select id, name from tt_users where team_id = $user->team_id and status = 1 order by upper(name)"; + $sql = "select id, name from tt_users where group_id = $user->group_id and status = 1 order by upper(name)"; $res = $mdb2->query($sql); $user_list = array(); if (is_a($res, 'PEAR_Error')) @@ -109,7 +109,7 @@ static function swapRolesWith($user_id) { $mdb2 = getConnection(); // Obtain role id for the user we are swapping ourselves with. - $sql = "select u.id, u.role_id from tt_users u left join tt_roles r on (u.role_id = r.id) where u.id = $user_id and u.team_id = $user->team_id and u.status = 1 and r.rank < $user->rank"; + $sql = "select u.id, u.role_id from tt_users u left join tt_roles r on (u.role_id = r.id) where u.id = $user_id and u.group_id = $user->group_id and u.status = 1 and r.rank < $user->rank"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; @@ -120,13 +120,13 @@ static function swapRolesWith($user_id) { $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); // Promote user. - $sql = "update tt_users set role_id = $user->role_id".$modified_part." where id = $user_id and team_id = $user->team_id"; + $sql = "update tt_users set role_id = $user->role_id".$modified_part." where id = $user_id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Demote self. $role_id = $val['role_id']; - $sql = "update tt_users set role_id = $role_id".$modified_part." where id = $user->id and team_id = $user->team_id"; + $sql = "update tt_users set role_id = $role_id".$modified_part." where id = $user->id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -138,7 +138,7 @@ static function getUsersForSwap() { global $user; $mdb2 = getConnection(); - $sql = "select u.id, u.name, r.rank, r.rights from tt_users u left join tt_roles r on (u.role_id = r.id) where u.team_id = $user->team_id and u.status = 1 and r.rank < $user->rank order by upper(u.name)"; + $sql = "select u.id, u.name, r.rank, r.rights from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $user->group_id and u.status = 1 and r.rank < $user->rank order by upper(u.name)"; $res = $mdb2->query($sql); $user_list = array(); if (is_a($res, 'PEAR_Error')) @@ -157,7 +157,7 @@ static function getUsersForSwap() { static function getUsers() { global $user; $mdb2 = getConnection(); - $sql = "select id, name from tt_users where team_id = $user->team_id and (status = 1 or status = 0) order by upper(name)"; + $sql = "select id, name from tt_users where group_id = $user->group_id and (status = 1 or status = 0) order by upper(name)"; $res = $mdb2->query($sql); $user_list = array(); if (is_a($res, 'PEAR_Error')) @@ -169,13 +169,13 @@ static function getUsers() { } // The getInactiveUsers obtains all inactive users in a given team. - static function getInactiveUsers($team_id, $all_fields = false) { + static function getInactiveUsers($group_id, $all_fields = false) { $mdb2 = getConnection(); if ($all_fields) - $sql = "select u.*, r.name as role_name from tt_users u left join tt_roles r on (u.role_id = r.id) where u.team_id = $team_id and u.status = 0 order by upper(u.name)"; + $sql = "select u.*, r.name as role_name from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $group_id and u.status = 0 order by upper(u.name)"; else - $sql = "select id, name from tt_users where team_id = $team_id and status = 0 order by upper(name)"; + $sql = "select id, name from tt_users where group_id = $group_id and status = 0 order by upper(name)"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -188,12 +188,12 @@ static function getInactiveUsers($team_id, $all_fields = false) { } // The getAllUsers obtains all users in a given team. - static function getAllUsers($team_id, $all_fields = false) { + static function getAllUsers($group_id, $all_fields = false) { $mdb2 = getConnection(); if ($all_fields) - $sql = "select * from tt_users where team_id = $team_id order by upper(name)"; + $sql = "select * from tt_users where group_id = $group_id order by upper(name)"; else - $sql = "select id, name from tt_users where team_id = $team_id order by upper(name)"; + $sql = "select id, name from tt_users where group_id = $group_id order by upper(name)"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -206,13 +206,13 @@ static function getAllUsers($team_id, $all_fields = false) { } // getActiveProjects - returns an array of active projects for team. - static function getActiveProjects($team_id) + static function getActiveProjects($group_id) { $result = array(); $mdb2 = getConnection(); $sql = "select id, name, description, tasks from tt_projects - where team_id = $team_id and status = 1 order by upper(name)"; + where group_id = $group_id and status = 1 order by upper(name)"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -224,13 +224,13 @@ static function getActiveProjects($team_id) } // getInactiveProjects - returns an array of inactive projects for team. - static function getInactiveProjects($team_id) + static function getInactiveProjects($group_id) { $result = array(); $mdb2 = getConnection(); $sql = "select id, name, description, tasks from tt_projects - where team_id = $team_id and status = 0 order by upper(name)"; + where group_id = $group_id and status = 0 order by upper(name)"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -242,13 +242,13 @@ static function getInactiveProjects($team_id) } // The getAllProjects obtains all projects in a given team. - static function getAllProjects($team_id, $all_fields = false) { + static function getAllProjects($group_id, $all_fields = false) { $mdb2 = getConnection(); if ($all_fields) - $sql = "select * from tt_projects where team_id = $team_id order by status, upper(name)"; + $sql = "select * from tt_projects where group_id = $group_id order by status, upper(name)"; else - $sql = "select id, name from tt_projects where team_id = $team_id order by status, upper(name)"; + $sql = "select id, name from tt_projects where group_id = $group_id order by status, upper(name)"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -261,12 +261,12 @@ static function getAllProjects($team_id, $all_fields = false) { } // getActiveTasks - returns an array of active tasks for team. - static function getActiveTasks($team_id) + static function getActiveTasks($group_id) { $result = array(); $mdb2 = getConnection(); - $sql = "select id, name, description from tt_tasks where team_id = $team_id and status = 1 order by upper(name)"; + $sql = "select id, name, description from tt_tasks where group_id = $group_id and status = 1 order by upper(name)"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -278,13 +278,13 @@ static function getActiveTasks($team_id) } // getInactiveTasks - returns an array of inactive tasks for team. - static function getInactiveTasks($team_id) + static function getInactiveTasks($group_id) { $result = array(); $mdb2 = getConnection(); $sql = "select id, name, description from tt_tasks - where team_id = $team_id and status = 0 order by upper(name)"; + where group_id = $group_id and status = 0 order by upper(name)"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -296,13 +296,13 @@ static function getInactiveTasks($team_id) } // The getAllTasks obtains all tasks in a given team. - static function getAllTasks($team_id, $all_fields = false) { + static function getAllTasks($group_id, $all_fields = false) { $mdb2 = getConnection(); if ($all_fields) - $sql = "select * from tt_tasks where team_id = $team_id order by status, upper(name)"; + $sql = "select * from tt_tasks where group_id = $group_id order by status, upper(name)"; else - $sql = "select id, name from tt_tasks where team_id = $team_id order by status, upper(name)"; + $sql = "select id, name from tt_tasks where group_id = $group_id order by status, upper(name)"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -322,7 +322,7 @@ static function getActiveRolesForUser() $result = array(); $mdb2 = getConnection(); - $sql = "select id, name, description, rank, rights from tt_roles where team_id = $user->team_id and rank < $user->rank and status = 1 order by rank"; + $sql = "select id, name, description, rank, rights from tt_roles where group_id = $user->group_id and rank < $user->rank and status = 1 order by rank"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -337,12 +337,12 @@ static function getActiveRolesForUser() } // getActiveRoles - returns an array of active roles for team. - static function getActiveRoles($team_id) + static function getActiveRoles($group_id) { $result = array(); $mdb2 = getConnection(); - $sql = "select id, name, description, rank, rights from tt_roles where team_id = $team_id and status = 1 order by rank"; + $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and status = 1 order by rank"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -355,13 +355,13 @@ static function getActiveRoles($team_id) } // getInactiveRoles - returns an array of inactive roles for team. - static function getInactiveRoles($team_id) + static function getInactiveRoles($group_id) { $result = array(); $mdb2 = getConnection(); $sql = "select id, name, rank, description from tt_roles - where team_id = $team_id and status = 0 order by rank"; + where group_id = $group_id and status = 0 order by rank"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -380,7 +380,7 @@ static function getInactiveRolesForUser() $result = array(); $mdb2 = getConnection(); - $sql = "select id, name, description, rank, rights from tt_roles where team_id = $user->team_id and rank < $user->rank and status = 0 order by rank"; + $sql = "select id, name, description, rank, rights from tt_roles where group_id = $user->group_id and rank < $user->rank and status = 0 order by rank"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -395,15 +395,15 @@ static function getInactiveRolesForUser() } // The getActiveClients returns an array of active clients for team. - static function getActiveClients($team_id, $all_fields = false) + static function getActiveClients($group_id, $all_fields = false) { $result = array(); $mdb2 = getConnection(); if ($all_fields) - $sql = "select * from tt_clients where team_id = $team_id and status = 1 order by upper(name)"; + $sql = "select * from tt_clients where group_id = $group_id and status = 1 order by upper(name)"; else - $sql = "select id, name from tt_clients where team_id = $team_id and status = 1 order by upper(name)"; + $sql = "select id, name from tt_clients where group_id = $group_id and status = 1 order by upper(name)"; $res = $mdb2->query($sql); $result = array(); @@ -416,15 +416,15 @@ static function getActiveClients($team_id, $all_fields = false) } // The getInactiveClients returns an array of inactive clients for team. - static function getInactiveClients($team_id, $all_fields = false) + static function getInactiveClients($group_id, $all_fields = false) { $result = array(); $mdb2 = getConnection(); if ($all_fields) - $sql = "select * from tt_clients where team_id = $team_id and status = 0 order by upper(name)"; + $sql = "select * from tt_clients where group_id = $group_id and status = 0 order by upper(name)"; else - $sql = "select id, name from tt_clients where team_id = $team_id and status = 0 order by upper(name)"; + $sql = "select id, name from tt_clients where group_id = $group_id and status = 0 order by upper(name)"; $res = $mdb2->query($sql); $result = array(); @@ -437,13 +437,13 @@ static function getInactiveClients($team_id, $all_fields = false) } // The getAllClients obtains all clients in a given team. - static function getAllClients($team_id, $all_fields = false) { + static function getAllClients($group_id, $all_fields = false) { $mdb2 = getConnection(); if ($all_fields) - $sql = "select * from tt_clients where team_id = $team_id order by status, upper(name)"; + $sql = "select * from tt_clients where group_id = $group_id order by status, upper(name)"; else - $sql = "select id, name from tt_clients where team_id = $team_id order by status, upper(name)"; + $sql = "select id, name from tt_clients where group_id = $group_id order by status, upper(name)"; $res = $mdb2->query($sql); $result = array(); @@ -470,7 +470,7 @@ static function getActiveInvoices($localizeDates = true) $sql = "select i.id, i.name, i.date, i.client_id, i.status, c.name as client_name from tt_invoices i left join tt_clients c on (c.id = i.client_id) - where i.status = 1 and i.team_id = $user->team_id $client_part order by i.name"; + where i.status = 1 and i.group_id = $user->group_id $client_part order by i.name"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -496,7 +496,7 @@ static function getAllInvoices() $result = array(); $mdb2 = getConnection(); - $sql = "select * from tt_invoices where team_id = $user->team_id"; + $sql = "select * from tt_invoices where group_id = $user->group_id"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -509,7 +509,7 @@ static function getAllInvoices() } // The getRecentInvoices returns an array of recent invoices (max 3) for a client. - static function getRecentInvoices($team_id, $client_id) + static function getRecentInvoices($group_id, $client_id) { global $user; @@ -518,7 +518,7 @@ static function getRecentInvoices($team_id, $client_id) $sql = "select i.id, i.name from tt_invoices i left join tt_clients c on (c.id = i.client_id) - where i.team_id = $team_id and i.status = 1 and c.id = $client_id + where i.group_id = $group_id and i.status = 1 and c.id = $client_id order by i.id desc limit 3"; $res = $mdb2->query($sql); $result = array(); @@ -532,11 +532,11 @@ static function getRecentInvoices($team_id, $client_id) } // getUserToProjectBinds - obtains all user to project binds for a team. - static function getUserToProjectBinds($team_id) { + static function getUserToProjectBinds($group_id) { $mdb2 = getConnection(); $result = array(); - $sql = "select * from tt_user_project_binds where user_id in (select id from tt_users where team_id = $team_id) order by user_id, status, project_id"; + $sql = "select * from tt_user_project_binds where user_id in (select id from tt_users where group_id = $group_id) order by user_id, status, project_id"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -549,10 +549,10 @@ static function getUserToProjectBinds($team_id) { } // The getAllCustomFields obtains all custom fields in a given team. - static function getAllCustomFields($team_id) { + static function getAllCustomFields($group_id) { $mdb2 = getConnection(); - $sql = "select * from tt_custom_fields where team_id = $team_id order by status"; + $sql = "select * from tt_custom_fields where group_id = $group_id order by status"; $res = $mdb2->query($sql); $result = array(); @@ -566,10 +566,10 @@ static function getAllCustomFields($team_id) { } // The getAllCustomFieldOptions obtains all custom field options in a given team. - static function getAllCustomFieldOptions($team_id) { + static function getAllCustomFieldOptions($group_id) { $mdb2 = getConnection(); - $sql = "select * from tt_custom_field_options where field_id in (select id from tt_custom_fields where team_id = $team_id) order by id"; + $sql = "select * from tt_custom_field_options where field_id in (select id from tt_custom_fields where group_id = $group_id) order by id"; $res = $mdb2->query($sql); $result = array(); @@ -583,10 +583,10 @@ static function getAllCustomFieldOptions($team_id) { } // The getCustomFieldLog obtains all custom field log entries for a given team. - static function getCustomFieldLog($team_id) { + static function getCustomFieldLog($group_id) { $mdb2 = getConnection(); - $sql = "select * from tt_custom_field_log where field_id in (select id from tt_custom_fields where team_id = $team_id) order by id"; + $sql = "select * from tt_custom_field_log where field_id in (select id from tt_custom_fields where group_id = $group_id) order by id"; $res = $mdb2->query($sql); $result = array(); @@ -600,11 +600,11 @@ static function getCustomFieldLog($team_id) { } // getFavReports - obtains all favorite reports for all users in team. - static function getFavReports($team_id) { + static function getFavReports($group_id) { $mdb2 = getConnection(); $result = array(); - $sql = "select * from tt_fav_reports where user_id in (select id from tt_users where team_id = $team_id)"; + $sql = "select * from tt_fav_reports where user_id in (select id from tt_users where group_id = $group_id)"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -617,11 +617,11 @@ static function getFavReports($team_id) { } // getExpenseItems - obtains all expense items for all users in team. - static function getExpenseItems($team_id) { + static function getExpenseItems($group_id) { $mdb2 = getConnection(); $result = array(); - $sql = "select * from tt_expense_items where user_id in (select id from tt_users where team_id = $team_id)"; + $sql = "select * from tt_expense_items where user_id in (select id from tt_users where group_id = $group_id)"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -634,14 +634,14 @@ static function getExpenseItems($team_id) { } // getPredefinedExpenses - obtains predefined expenses for team. - static function getPredefinedExpenses($team_id) { + static function getPredefinedExpenses($group_id) { global $user; $replaceDecimalMark = ('.' != $user->decimal_mark); $mdb2 = getConnection(); $result = array(); - $sql = "select id, name, cost from tt_predefined_expenses where team_id = $team_id"; + $sql = "select id, name, cost from tt_predefined_expenses where group_id = $group_id"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -656,13 +656,13 @@ static function getPredefinedExpenses($team_id) { } // getNotifications - obtains notification descriptions for team. - static function getNotifications($team_id) { + static function getNotifications($group_id) { $mdb2 = getConnection(); $result = array(); $sql = "select c.id, c.cron_spec, c.email, c.report_condition, fr.name from tt_cron c left join tt_fav_reports fr on (fr.id = c.report_id) - where c.team_id = $team_id and c.status = 1 and fr.status = 1"; + where c.group_id = $group_id and c.status = 1 and fr.status = 1"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -675,11 +675,11 @@ static function getNotifications($team_id) { } // getMonthlyQuotas - obtains monthly quotas for team. - static function getMonthlyQuotas($team_id) { + static function getMonthlyQuotas($group_id) { $mdb2 = getConnection(); $result = array(); - $sql = "select year, month, minutes from tt_monthly_quotas where team_id = $team_id"; + $sql = "select year, month, minutes from tt_monthly_quotas where group_id = $group_id"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -692,41 +692,41 @@ static function getMonthlyQuotas($team_id) { } // The markDeleted function marks the team and everything in it as deleted. - static function markDeleted($team_id) { + static function markDeleted($group_id) { // Iterate through team users and mark them as deleted. - $users = ttTeamHelper::getAllUsers($team_id); + $users = ttTeamHelper::getAllUsers($group_id); foreach ($users as $one_user) { if (!ttUserHelper::markDeleted($one_user['id'])) return false; } // Mark tasks deleted. - if (!ttTeamHelper::markTasksDeleted($team_id)) return false; + if (!ttTeamHelper::markTasksDeleted($group_id)) return false; $mdb2 = getConnection(); // Mark roles deleted. - $sql = "update tt_roles set status = NULL where team_id = $team_id"; + $sql = "update tt_roles set status = NULL where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark projects deleted. - $sql = "update tt_projects set status = NULL where team_id = $team_id"; + $sql = "update tt_projects set status = NULL where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark clients deleted. - $sql = "update tt_clients set status = NULL where team_id = $team_id"; + $sql = "update tt_clients set status = NULL where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark custom fields deleted. - $sql = "update tt_custom_fields set status = NULL where team_id = $team_id"; + $sql = "update tt_custom_fields set status = NULL where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark group deleted. - $sql = "update tt_groups set status = NULL where id = $team_id"; + $sql = "update tt_groups set status = NULL where id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -734,15 +734,15 @@ static function markDeleted($team_id) { } // The getTeamDetails function returns team details. - static function getTeamDetails($team_id) { + static function getTeamDetails($group_id) { $result = array(); $mdb2 = getConnection(); $sql = "select t.name as team_name, u.id as manager_id, u.name as manager_name, u.login as manager_login, u.email as manager_email from tt_groups t - inner join tt_users u on (u.team_id = t.id) + inner join tt_users u on (u.group_id = t.id) inner join tt_roles r on (r.id = u.role_id and r.rank = 512) - where t.id = $team_id"; + where t.id = $group_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -846,15 +846,15 @@ static function insert($fields) { $affected = $mdb2->exec($sql); if (!is_a($affected, 'PEAR_Error')) { - $team_id = $mdb2->lastInsertID('tt_groups', 'id'); - return $team_id; + $group_id = $mdb2->lastInsertID('tt_groups', 'id'); + return $group_id; } return false; } // The update function updates team information. - static function update($team_id, $fields) + static function update($group_id, $fields) { global $user; $mdb2 = getConnection(); @@ -891,7 +891,7 @@ static function update($team_id, $fields) $sql = "update tt_groups set $name_part $currency_part $lang_part $decimal_mark_part $date_format_part $time_format_part $week_start_part $tracking_mode_part $task_required_part $record_type_part - $bcc_email_part $plugins_part $config_part $lock_spec_part $workday_minutes_part $modified_part where id = $team_id"; + $bcc_email_part $plugins_part $config_part $lock_spec_part $workday_minutes_part $modified_part where id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -912,10 +912,10 @@ static function getInactiveTeams() { $count = 0; if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { - $team_id = $val['id']; - if (ttTeamHelper::isTeamActive($team_id) == false) { + $group_id = $val['id']; + if (ttTeamHelper::isTeamActive($group_id) == false) { $count++; - $inactive_teams[] = $team_id; + $inactive_teams[] = $group_id; // Limit the array size for perfomance by allowing this operation on small chunks only. if ($count >= 100) break; } @@ -926,11 +926,11 @@ static function getInactiveTeams() { } // The isTeamActive determines if a team is using Time Tracker or abandoned it. - static function isTeamActive($team_id) { + static function isTeamActive($group_id) { $users = array(); $mdb2 = getConnection(); - $sql = "select id from tt_users where team_id = $team_id"; + $sql = "select id from tt_users where group_id = $group_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die($res->getMessage()); while ($val = $res->fetchRow()) { @@ -971,11 +971,11 @@ static function isTeamActive($team_id) { } // The delete function permanently deletes all data for a team. - static function delete($team_id) { + static function delete($group_id) { $mdb2 = getConnection(); // Delete users. - $sql = "select id from tt_users where team_id = $team_id"; + $sql = "select id from tt_users where group_id = $group_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; while ($val = $res->fetchRow()) { @@ -984,38 +984,38 @@ static function delete($team_id) { } // Delete tasks. - if (!ttTeamHelper::deleteTasks($team_id)) return false; + if (!ttTeamHelper::deleteTasks($group_id)) return false; // Delete client to project binds. - $sql = "delete from tt_client_project_binds where client_id in (select id from tt_clients where team_id = $team_id)"; + $sql = "delete from tt_client_project_binds where client_id in (select id from tt_clients where group_id = $group_id)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Delete projects. - $sql = "delete from tt_projects where team_id = $team_id"; + $sql = "delete from tt_projects where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Delete clients. - $sql = "delete from tt_clients where team_id = $team_id"; + $sql = "delete from tt_clients where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Delete invoices. - $sql = "delete from tt_invoices where team_id = $team_id"; + $sql = "delete from tt_invoices where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Delete custom fields. - if (!ttTeamHelper::deleteCustomFields($team_id)) return false; + if (!ttTeamHelper::deleteCustomFields($group_id)) return false; // Delete roles. - $sql = "delete from tt_roles where team_id = $team_id"; + $sql = "delete from tt_roles where group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Delete group. - $sql = "delete from tt_groups where id = $team_id"; + $sql = "delete from tt_groups where id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -1023,9 +1023,9 @@ static function delete($team_id) { } // The markTasksDeleted deletes task binds and marks the tasks as deleted for a team. - static function markTasksDeleted($team_id) { + static function markTasksDeleted($group_id) { $mdb2 = getConnection(); - $sql = "select id from tt_tasks where team_id = $team_id"; + $sql = "select id from tt_tasks where group_id = $group_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; @@ -1047,9 +1047,9 @@ static function markTasksDeleted($team_id) { } // The deleteTasks deletes all tasks and task binds for an inactive team. - static function deleteTasks($team_id) { + static function deleteTasks($group_id) { $mdb2 = getConnection(); - $sql = "select id from tt_tasks where team_id = $team_id"; + $sql = "select id from tt_tasks where group_id = $group_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; @@ -1071,9 +1071,9 @@ static function deleteTasks($team_id) { } // The deleteCustomFields cleans up tt_custom_field_log, tt_custom_field_options and tt_custom_fields tables for an inactive team. - static function deleteCustomFields($team_id) { + static function deleteCustomFields($group_id) { $mdb2 = getConnection(); - $sql = "select id from tt_custom_fields where team_id = $team_id"; + $sql = "select id from tt_custom_fields where group_id = $group_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; @@ -1118,7 +1118,7 @@ static function enablePlugin($plugin, $enable = true) $plugins = implode(',', $plugin_array); if ($plugins != $user->plugins) { - if (!ttTeamHelper::update($user->team_id, array('name' => $user->team,'plugins' => $plugins))) + if (!ttTeamHelper::update($user->group_id, array('name' => $user->team,'plugins' => $plugins))) return false; $user->plugins = $plugins; } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 7e167f612..70e550402 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -30,7 +30,7 @@ class ttUser { var $login = null; // User login. var $name = null; // User name. var $id = null; // User id. - var $team_id = null; // Team id. + var $group_id = null; // Group id. var $role_id = null; // Role id. var $role_name = null; // Role name. var $rank = null; // User role rank. @@ -72,11 +72,11 @@ function __construct($login, $id = null) { $mdb2 = getConnection(); - $sql = "SELECT u.id, u.login, u.name, u.team_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id, u.email, t.name as team_name, + $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id, u.email, t.name as team_name, t.currency, t.lang, t.decimal_mark, t.date_format, t.time_format, t.week_start, t.tracking_mode, t.project_required, t.task_required, t.record_type, t.bcc_email, t.plugins, t.config, t.lock_spec, t.workday_minutes, t.custom_logo - FROM tt_users u LEFT JOIN tt_groups t ON (u.team_id = t.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; + FROM tt_users u LEFT JOIN tt_groups t ON (u.group_id = t.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; if ($id) $sql .= "u.id = $id"; else @@ -93,7 +93,7 @@ function __construct($login, $id = null) { $this->login = $val['login']; $this->name = $val['name']; $this->id = $val['id']; - $this->team_id = $val['team_id']; + $this->group_id = $val['group_id']; $this->role_id = $val['role_id']; $this->role_name = $val['role_name']; $this->rights = explode(',', $val['rights']); @@ -193,7 +193,7 @@ function getAssignedProjects() // Do a query with inner join to get assigned projects. $sql = "select p.id, p.name, p.description, p.tasks, upb.rate from tt_projects p inner join tt_user_project_binds upb on (upb.user_id = ".$this->getActiveUser()." and upb.project_id = p.id and upb.status = 1) - where p.team_id = $this->team_id and p.status = 1 order by p.name"; + where p.group_id = $this->group_id and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -261,7 +261,7 @@ function getUsers($options) { if (isset($options['max_rank']) || $skipClients || isset($options['include_role'])) $left_joins .= ' left join tt_roles r on (u.role_id = r.id)'; - $where_part = " where u.team_id = $this->team_id"; + $where_part = " where u.group_id = $this->group_id"; if (isset($options['status'])) $where_part .= ' and u.status = '.(int)$options['status']; else @@ -312,7 +312,7 @@ function getUser($user_id) { $sql = "select u.id, u.name, u.login, u.role_id, u.status, u.rate, u.email from tt_users u". " left join tt_roles r on (u.role_id = r.id)". - " where u.id = $user_id and u.team_id = $this->team_id and u.status is not null". + " where u.id = $user_id and u.group_id = $this->group_id and u.status is not null". " and (r.rank < $this->rank or (r.rank = $this->rank and u.id = $this->id))"; // Users with lesser roles or self. $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index dab51297c..40cd78293 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -101,7 +101,7 @@ static function insert($fields, $hash = true) { if($hash) $password = 'md5('.$password.')'; $email = isset($fields['email']) ? $fields['email'] : ''; - $team_id = (int) $fields['team_id']; + $group_id = (int) $fields['group_id']; $rate = str_replace(',', '.', isset($fields['rate']) ? $fields['rate'] : 0); if($rate == '') $rate = 0; @@ -112,9 +112,9 @@ static function insert($fields, $hash = true) { $created_ip_v = ', '.$mdb2->quote($_SERVER['REMOTE_ADDR']); $created_by_v = ', '.$mdb2->quote($user->id); - $sql = "insert into tt_users (name, login, password, team_id, role_id, client_id, rate, email, created, created_ip, created_by $status_f) values (". + $sql = "insert into tt_users (name, login, password, group_id, role_id, client_id, rate, email, created, created_ip, created_by $status_f) values (". $mdb2->quote($fields['name']).", ".$mdb2->quote($fields['login']). - ", $password, $team_id, ".$mdb2->quote($fields['role_id']).", ".$mdb2->quote($fields['client_id']).", $rate, ".$mdb2->quote($email).", now() $created_ip_v $created_by_v $status_v)"; + ", $password, $group_id, ".$mdb2->quote($fields['role_id']).", ".$mdb2->quote($fields['client_id']).", $rate, ".$mdb2->quote($email).", now() $created_ip_v $created_by_v $status_v)"; $affected = $mdb2->exec($sql); // Now deal with project assignment. @@ -191,7 +191,7 @@ static function update($user_id, $fields) { // otherwise de-activate the bind (set its status to inactive). This will keep the bind // and its rate in database for reporting. - $all_projects = ttTeamHelper::getAllProjects($user->team_id); + $all_projects = ttTeamHelper::getAllProjects($user->group_id); $assigned_projects = isset($fields['projects']) ? $fields['projects'] : array(); foreach($all_projects as $p) { @@ -282,13 +282,13 @@ static function markDeleted($user_id) { return false; // Mark user as deleted. - $sql = "update tt_users set status = NULL where id = $user_id and team_id = ".$user->team_id; + $sql = "update tt_users set status = NULL where id = $user_id and group_id = ".$user->group_id; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; } elseif ($user->isManager()) { - $user_count = ttTeamHelper::getUserCount($user->team_id); + $user_count = ttTeamHelper::getUserCount($user->group_id); // Marking deleted a manager with active users is not allowed. if (($user_id == $user->id) && ($user_count > 1)) @@ -296,29 +296,29 @@ static function markDeleted($user_id) { if (1 == $user_count) { // Mark tasks deleted. - if (!ttTeamHelper::markTasksDeleted($user->team_id)) + if (!ttTeamHelper::markTasksDeleted($user->group_id)) return false; // Mark projects deleted. - $sql = "update tt_projects set status = NULL where team_id = $user->team_id"; + $sql = "update tt_projects set status = NULL where group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark clients deleted. - $sql = "update tt_clients set status = NULL where team_id = $user->team_id"; + $sql = "update tt_clients set status = NULL where group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark custom fields deleted. - $sql = "update tt_custom_fields set status = NULL where team_id = $user->team_id"; + $sql = "update tt_custom_fields set status = NULL where group_id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark team deleted. - $sql = "update tt_groups set status = NULL where id = $user->team_id"; + $sql = "update tt_groups set status = NULL where id = $user->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -337,7 +337,7 @@ static function markDeleted($user_id) { return false; // Mark user as deleted. - $sql = "update tt_users set status = NULL where id = $user_id and team_id = ".$user->team_id; + $sql = "update tt_users set status = NULL where id = $user_id and group_id = ".$user->group_id; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index f4ee719f8..27a1bbcf5 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -45,7 +45,7 @@ static function getRecordsForInterval($user_id, $start_date, $end_date) { $custom_field_1 = null; if ($user->isPluginEnabled('cf')) { - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $cf_1_type = $custom_fields->fields[0]['type']; if ($cf_1_type == CustomFields::TYPE_TEXT) { $custom_field_1 = ', cfl.value as cf_1_value'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1a5dbf67f..10419c01b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.80.4199 | Copyright © Anuko | +  Anuko Time Tracker 1.17.81.4200 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_team_delete.php b/admin_team_delete.php index a9ce1ee1b..61a17041e 100644 --- a/admin_team_delete.php +++ b/admin_team_delete.php @@ -36,12 +36,12 @@ exit(); } -$team_id = (int)$request->getParameter('id'); -$team_details = ttTeamHelper::getTeamDetails($team_id); +$group_id = (int)$request->getParameter('id'); +$team_details = ttTeamHelper::getTeamDetails($group_id); $team_name = $team_details['team_name']; $form = new Form('teamForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$team_id)); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$group_id)); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); @@ -49,7 +49,7 @@ if ($request->getParameter('btn_delete')) { import('ttAdmin'); $admin = new ttAdmin(); - $result = $admin->markGroupDeleted($team_id); + $result = $admin->markGroupDeleted($group_id); if ($result) { header('Location: admin_teams.php'); exit(); diff --git a/admin_team_edit.php b/admin_team_edit.php index a737050a8..05bfec8b1 100644 --- a/admin_team_edit.php +++ b/admin_team_edit.php @@ -37,8 +37,8 @@ exit(); } -$team_id = $request->getParameter('id'); -$team_details = ttTeamHelper::getTeamDetails($team_id); +$group_id = $request->getParameter('id'); +$team_details = ttTeamHelper::getTeamDetails($group_id); if ($request->isPost()) { $cl_team_name = trim($request->getParameter('team_name')); @@ -68,7 +68,7 @@ $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'password2','value'=>$cl_password2)); } $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'manager_email','value'=>$cl_manager_email)); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$team_id)); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$group_id)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); @@ -88,7 +88,7 @@ import('ttAdmin'); $admin = new ttAdmin($err); - $result = $admin->updateGroup($team_id, $fields); + $result = $admin->updateGroup($group_id, $fields); if ($result) { header('Location: admin_teams.php'); exit(); diff --git a/client_add.php b/client_add.php index 5ae5997fa..3afcbc072 100644 --- a/client_add.php +++ b/client_add.php @@ -41,7 +41,7 @@ exit(); } -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -71,7 +71,7 @@ if ($err->no()) { if (!ttClientHelper::getClientByName($cl_name)) { if (ttClientHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, diff --git a/client_edit.php b/client_edit.php index b74fb3150..74062d06e 100644 --- a/client_edit.php +++ b/client_edit.php @@ -43,7 +43,7 @@ $cl_id = (int) $request->getParameter('id'); -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -103,7 +103,7 @@ if ($request->getParameter('btn_copy')) { if (!ttClientHelper::getClientByName($cl_name)) { if (ttClientHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, diff --git a/clients.php b/clients.php index 6ac6f5a1d..177bd61ee 100644 --- a/clients.php +++ b/clients.php @@ -40,8 +40,8 @@ exit(); } -$smarty->assign('active_clients', ttTeamHelper::getActiveClients($user->team_id, true)); -$smarty->assign('inactive_clients', ttTeamHelper::getInactiveClients($user->team_id, true)); +$smarty->assign('active_clients', ttTeamHelper::getActiveClients($user->group_id, true)); +$smarty->assign('inactive_clients', ttTeamHelper::getInactiveClients($user->group_id, true)); $smarty->assign('title', $i18n->get('title.clients')); $smarty->assign('content_page_name', 'clients.tpl'); $smarty->display('index.tpl'); diff --git a/dbinstall.php b/dbinstall.php index 190ff7eea..97a5085da 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -872,6 +872,17 @@ function setChange($sql) { setChange("RENAME TABLE `tt_teams` TO `tt_groups`"); setChange("ALTER TABLE `tt_monthly_quotas` DROP FOREIGN KEY FK_TT_TEAM_CONSTRAING"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.80', modified = now() where param_name = 'version_db' and param_value = '1.17.79'"); + setChange("ALTER TABLE `tt_roles` CHANGE `team_id` `group_id` int(11) NOT NULL"); + setChange("ALTER TABLE `tt_users` CHANGE `team_id` `group_id` int(11) NOT NULL"); + setChange("ALTER TABLE `tt_projects` CHANGE `team_id` `group_id` int(11) NOT NULL"); + setChange("ALTER TABLE `tt_tasks` CHANGE `team_id` `group_id` int(11) NOT NULL"); + setChange("ALTER TABLE `tt_invoices` CHANGE `team_id` `group_id` int(11) NOT NULL"); + setChange("ALTER TABLE `tt_cron` CHANGE `team_id` `group_id` int(11) NOT NULL"); + setChange("ALTER TABLE `tt_clients` CHANGE `team_id` `group_id` int(11) NOT NULL"); + setChange("ALTER TABLE `tt_custom_fields` CHANGE `team_id` `group_id` int(11) NOT NULL"); + setChange("ALTER TABLE `tt_predefined_expenses` CHANGE `team_id` `group_id` int(11) NOT NULL"); + setChange("ALTER TABLE `tt_monthly_quotas` CHANGE `team_id` `group_id` int(11) NOT NULL"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.81', modified = now() where param_name = 'version_db' and param_value = '1.17.80'"); } if ($_POST["cleanup"]) { diff --git a/expense_edit.php b/expense_edit.php index 99503b06b..3e8b18e9b 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -76,7 +76,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -101,7 +101,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -127,7 +127,7 @@ } } // If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->team_id); +$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->group_id); if ($predefined_expenses) { $form->addInput(array('type'=>'combobox', 'onchange'=>'recalculateCost();', diff --git a/expenses.php b/expenses.php index 7291414aa..fee812051 100644 --- a/expenses.php +++ b/expenses.php @@ -92,7 +92,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -118,7 +118,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -144,7 +144,7 @@ } } // If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->team_id); +$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->group_id); if ($predefined_expenses) { $form->addInput(array('type'=>'combobox', 'onchange'=>'recalculateCost();', diff --git a/group_edit.php b/group_edit.php index 0ce93582f..1d71cc17d 100644 --- a/group_edit.php +++ b/group_edit.php @@ -268,7 +268,7 @@ $config .= ',uncompleted_indicators'; $config = trim($config, ','); - $update_result = ttTeamHelper::update($user->team_id, array( + $update_result = ttTeamHelper::update($user->group_id, array( 'name' => $cl_team, 'currency' => $cl_currency, 'lang' => $cl_lang, diff --git a/initialize.php b/initialize.php index 5d721b803..261ec7479 100644 --- a/initialize.php +++ b/initialize.php @@ -170,8 +170,8 @@ import('ttUser'); $user = new ttUser(null, $auth->getUserId()); if ($user->custom_logo) { - $smarty->assign('custom_logo', 'images/'.$user->team_id.'.png'); - $smarty->assign('mobile_custom_logo', '../images/'.$user->team_id.'.png'); + $smarty->assign('custom_logo', 'images/'.$user->group_id.'.png'); + $smarty->assign('mobile_custom_logo', '../images/'.$user->group_id.'.png'); } $smarty->assign('user', $user); diff --git a/invoice_add.php b/invoice_add.php index ad9c3cfb8..61568e2aa 100644 --- a/invoice_add.php +++ b/invoice_add.php @@ -56,12 +56,12 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $clients = ttTeamHelper::getActiveClients($user->team_id); + $clients = ttTeamHelper::getActiveClients($user->group_id); $form->addInput(array('type'=>'combobox','name'=>'client','style'=>'width: 250px;','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->get('dropdown.select')))); } // Dropdown for projects. if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $projects = ttTeamHelper::getActiveProjects($user->team_id); + $projects = ttTeamHelper::getActiveProjects($user->group_id); $form->addInput(array('type'=>'combobox','name'=>'project','style'=>'width: 250px;','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_project,'empty'=>array(''=>$i18n->get('dropdown.all')))); } $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'number','style'=>'width: 250px;','value'=>$cl_number)); diff --git a/locking.php b/locking.php index 2b49b8375..99e79a217 100644 --- a/locking.php +++ b/locking.php @@ -51,7 +51,7 @@ if (!ttValidCronSpec($cl_lock_spec)) $err->add($i18n->get('error.field'), $i18n->get('label.schedule')); if ($err->no()) { - if (ttTeamHelper::update($user->team_id, array( + if (ttTeamHelper::update($user->group_id, array( 'name' => $user->team, 'lock_spec' => $cl_lock_spec))) { header('Location: profile_edit.php'); diff --git a/mobile/client_add.php b/mobile/client_add.php index fc57853d7..f83c720ae 100644 --- a/mobile/client_add.php +++ b/mobile/client_add.php @@ -41,7 +41,7 @@ exit(); } -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -71,7 +71,7 @@ if ($err->no()) { if (!ttClientHelper::getClientByName($cl_name)) { if (ttClientHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, diff --git a/mobile/client_edit.php b/mobile/client_edit.php index eb8592290..093e9668c 100644 --- a/mobile/client_edit.php +++ b/mobile/client_edit.php @@ -43,7 +43,7 @@ $cl_id = (int) $request->getParameter('id'); -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -104,7 +104,7 @@ if ($request->getParameter('btn_copy')) { if (!ttClientHelper::getClientByName($cl_name)) { if (ttClientHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, diff --git a/mobile/clients.php b/mobile/clients.php index 43e6848ae..4f03510ce 100644 --- a/mobile/clients.php +++ b/mobile/clients.php @@ -40,8 +40,8 @@ exit(); } -$smarty->assign('active_clients', ttTeamHelper::getActiveClients($user->team_id, true)); -$smarty->assign('inactive_clients', ttTeamHelper::getInactiveClients($user->team_id, true)); +$smarty->assign('active_clients', ttTeamHelper::getActiveClients($user->group_id, true)); +$smarty->assign('inactive_clients', ttTeamHelper::getInactiveClients($user->group_id, true)); $smarty->assign('title', $i18n->get('title.clients')); $smarty->assign('content_page_name', 'mobile/clients.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index 1611378d9..f560f5574 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -73,7 +73,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -98,7 +98,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -124,7 +124,7 @@ } } // If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->team_id); +$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->group_id); if ($predefined_expenses) { $form->addInput(array('type'=>'combobox', 'onchange'=>'recalculateCost();', diff --git a/mobile/expenses.php b/mobile/expenses.php index 1cd39c04c..815a4fc34 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -96,7 +96,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -122,7 +122,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -148,7 +148,7 @@ } } // If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->team_id); +$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->group_id); if ($predefined_expenses) { $form->addInput(array('type'=>'combobox', 'onchange'=>'recalculateCost();', diff --git a/mobile/project_add.php b/mobile/project_add.php index bb0f1d096..b0d5394d4 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -46,7 +46,7 @@ foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; -$tasks = ttTeamHelper::getActiveTasks($user->team_id); +$tasks = ttTeamHelper::getActiveTasks($user->group_id); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; @@ -78,7 +78,7 @@ if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { if (ttProjectHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, diff --git a/mobile/project_edit.php b/mobile/project_edit.php index 6adb475e4..94f3e514d 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -52,7 +52,7 @@ foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; -$tasks = ttTeamHelper::getActiveTasks($user->team_id); +$tasks = ttTeamHelper::getActiveTasks($user->group_id); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; @@ -119,7 +119,7 @@ if ($request->getParameter('btn_copy')) { if (!ttProjectHelper::getProjectByName($cl_name)) { if (ttProjectHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, diff --git a/mobile/projects.php b/mobile/projects.php index a9f8ab02d..e3dc2f87e 100644 --- a/mobile/projects.php +++ b/mobile/projects.php @@ -42,8 +42,8 @@ // End of access checks. if($user->can('manage_projects')) { - $active_projects = ttTeamHelper::getActiveProjects($user->team_id); - $inactive_projects = ttTeamHelper::getInactiveProjects($user->team_id); + $active_projects = ttTeamHelper::getActiveProjects($user->group_id); + $inactive_projects = ttTeamHelper::getInactiveProjects($user->group_id); } else $active_projects = $user->getAssignedProjects(); diff --git a/mobile/task_add.php b/mobile/task_add.php index fd1fb4649..4b257edc5 100644 --- a/mobile/task_add.php +++ b/mobile/task_add.php @@ -43,7 +43,7 @@ } // End of access checks. -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -68,7 +68,7 @@ if ($err->no()) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => ACTIVE, diff --git a/mobile/task_edit.php b/mobile/task_edit.php index f1748c7e9..f1e256892 100644 --- a/mobile/task_edit.php +++ b/mobile/task_edit.php @@ -48,7 +48,7 @@ } // End of access checks. -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -103,7 +103,7 @@ if ($request->getParameter('btn_copy')) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => $cl_status, diff --git a/mobile/tasks.php b/mobile/tasks.php index e49498c4c..9ad18a170 100644 --- a/mobile/tasks.php +++ b/mobile/tasks.php @@ -41,8 +41,8 @@ } // End of access checks. -$smarty->assign('active_tasks', ttTeamHelper::getActiveTasks($user->team_id)); -$smarty->assign('inactive_tasks', ttTeamHelper::getInactiveTasks($user->team_id)); +$smarty->assign('active_tasks', ttTeamHelper::getActiveTasks($user->group_id)); +$smarty->assign('inactive_tasks', ttTeamHelper::getInactiveTasks($user->group_id)); $smarty->assign('title', $i18n->get('title.tasks')); $smarty->assign('content_page_name', 'mobile/tasks.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/time.php b/mobile/time.php index 8c6721d49..2649ff279 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -57,7 +57,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('../plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $smarty->assign('custom_fields', $custom_fields); } @@ -90,7 +90,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -116,7 +116,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -144,7 +144,7 @@ } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->team_id); + $task_list = ttTeamHelper::getActiveTasks($user->group_id); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/mobile/time_edit.php b/mobile/time_edit.php index a1a56e37c..40f58e8d9 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -51,7 +51,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('../plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $smarty->assign('custom_fields', $custom_fields); } @@ -107,7 +107,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -133,7 +133,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -161,7 +161,7 @@ } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->team_id); + $task_list = ttTeamHelper::getActiveTasks($user->group_id); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/mobile/timer.php b/mobile/timer.php index 059767edd..e547c256d 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -53,7 +53,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('../plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $smarty->assign('custom_fields', $custom_fields); } @@ -88,7 +88,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -116,7 +116,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -144,7 +144,7 @@ } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->team_id); + $task_list = ttTeamHelper::getActiveTasks($user->group_id); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/mobile/user_add.php b/mobile/user_add.php index 53b9842fa..934114528 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -45,7 +45,7 @@ @include('plugins/limit/user_add.php'); if ($user->isPluginEnabled('cl')) - $clients = ttTeamHelper::getActiveClients($user->team_id); + $clients = ttTeamHelper::getActiveClients($user->group_id); $assigned_projects = array(); if ($request->isPost()) { @@ -89,7 +89,7 @@ $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { @@ -147,7 +147,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'login' => $cl_login, 'password' => $cl_password1, 'rate' => $cl_rate, - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'role_id' => $cl_role_id, 'client_id' => $cl_client_id, 'projects' => $assigned_projects, diff --git a/mobile/user_edit.php b/mobile/user_edit.php index f82d9314a..46646bcaf 100644 --- a/mobile/user_edit.php +++ b/mobile/user_edit.php @@ -48,9 +48,9 @@ // End of access checks. if ($user->isPluginEnabled('cl')) - $clients = ttTeamHelper::getActiveClients($user->team_id); + $clients = ttTeamHelper::getActiveClients($user->group_id); -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); $assigned_projects = array(); if ($request->isPost()) { diff --git a/mobile/users.php b/mobile/users.php index 18ad2e5fa..4723543d8 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -42,7 +42,7 @@ $active_users = ttTeamHelper::getActiveUsers(array('getAllFields'=>true)); if($user->canManageTeam()) { $can_delete_manager = (1 == count($active_users)); - $inactive_users = ttTeamHelper::getInactiveUsers($user->team_id, true); + $inactive_users = ttTeamHelper::getInactiveUsers($user->group_id, true); } // Check if the team is set to show indicators for uncompleted time entries. diff --git a/mysql.sql b/mysql.sql index 4a48a662c..78ee25abc 100644 --- a/mysql.sql +++ b/mysql.sql @@ -50,7 +50,7 @@ CREATE TABLE `tt_groups` ( # CREATE TABLE `tt_roles` ( `id` int(11) NOT NULL auto_increment, # Role id. Identifies roles for all groups on the server. - `team_id` int(11) NOT NULL, # Team id the role is defined for. + `group_id` int(11) NOT NULL, # Group id the role is defined for. `name` varchar(80) default NULL, # Role name - custom role name. In case we are editing a # predefined role (USER, etc.), we can rename the role here. `description` varchar(255) default NULL, # Role description. @@ -69,11 +69,11 @@ CREATE TABLE `tt_roles` ( ); # Create an index that guarantees unique active and inactive role ranks in each group. -create unique index role_idx on tt_roles(team_id, rank, status); +create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. -INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,view_own_projects,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,view_own_projects,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'); # @@ -84,7 +84,7 @@ CREATE TABLE `tt_users` ( `login` varchar(50) COLLATE utf8_bin NOT NULL, # user login `password` varchar(50) default NULL, # password hash `name` varchar(100) default NULL, # user name - `team_id` int(11) NOT NULL, # team id + `group_id` int(11) NOT NULL, # group id `role_id` int(11) default NULL, # role id `client_id` int(11) default NULL, # client id for "client" user role `rate` float(6,2) NOT NULL default '0.00', # default hourly rate @@ -106,7 +106,7 @@ create unique index login_idx on tt_users(login, status); # Create admin account with password 'secret'. Admin is a superuser, who can create teams. DELETE from `tt_users` WHERE login = 'admin'; -INSERT INTO `tt_users` (`login`, `password`, `name`, `team_id`, `role_id`) VALUES ('admin', md5('secret'), 'Admin', '0', (select id from tt_roles where rank = 1024)); +INSERT INTO `tt_users` (`login`, `password`, `name`, `group_id`, `role_id`) VALUES ('admin', md5('secret'), 'Admin', '0', (select id from tt_roles where rank = 1024)); # @@ -114,7 +114,7 @@ INSERT INTO `tt_users` (`login`, `password`, `name`, `team_id`, `role_id`) VALUE # CREATE TABLE `tt_projects` ( `id` int(11) NOT NULL auto_increment, # project id - `team_id` int(11) NOT NULL, # team id + `group_id` int(11) NOT NULL, # group id `name` varchar(80) COLLATE utf8_bin NOT NULL, # project name `description` varchar(255) default NULL, # project description `tasks` text default NULL, # comma-separated list of task ids associated with this project @@ -122,8 +122,8 @@ CREATE TABLE `tt_projects` ( PRIMARY KEY (`id`) ); -# Create an index that guarantees unique active and inactive projects per team. -create unique index project_idx on tt_projects(team_id, name, status); +# Create an index that guarantees unique active and inactive projects per group. +create unique index project_idx on tt_projects(group_id, name, status); # @@ -131,15 +131,15 @@ create unique index project_idx on tt_projects(team_id, name, status); # CREATE TABLE `tt_tasks` ( `id` int(11) NOT NULL auto_increment, # task id - `team_id` int(11) NOT NULL, # team id + `group_id` int(11) NOT NULL, # group id `name` varchar(80) COLLATE utf8_bin NOT NULL, # task name `description` varchar(255) default NULL, # task description `status` tinyint(4) default 1, # task status PRIMARY KEY (`id`) ); -# Create an index that guarantees unique active and inactive tasks per team. -create unique index task_idx on tt_tasks(team_id, name, status); +# Create an index that guarantees unique active and inactive tasks per group. +create unique index task_idx on tt_tasks(group_id, name, status); # @@ -212,7 +212,7 @@ create index task_idx on tt_log(task_id); # CREATE TABLE `tt_invoices` ( `id` int(11) NOT NULL auto_increment, # invoice id - `team_id` int(11) NOT NULL, # team id + `group_id` int(11) NOT NULL, # group id `name` varchar(80) COLLATE utf8_bin NOT NULL, # invoice name `date` date NOT NULL, # invoice date `client_id` int(11) NOT NULL, # client id @@ -221,7 +221,7 @@ CREATE TABLE `tt_invoices` ( ); # Create an index that guarantees unique invoice names per team. -create unique index name_idx on tt_invoices(team_id, name, status); +create unique index name_idx on tt_invoices(group_id, name, status); # @@ -277,7 +277,7 @@ CREATE TABLE `tt_fav_reports` ( # CREATE TABLE `tt_cron` ( `id` int(11) NOT NULL auto_increment, # entry id - `team_id` int(11) NOT NULL, # team id + `group_id` int(11) NOT NULL, # group id `cron_spec` varchar(255) NOT NULL, # cron specification, "0 1 * * *" for "daily at 01:00" `last` int(11) default NULL, # UNIX timestamp of when job was last run `next` int(11) default NULL, # UNIX timestamp of when to run next job @@ -296,7 +296,7 @@ CREATE TABLE `tt_cron` ( # CREATE TABLE `tt_clients` ( `id` int(11) NOT NULL AUTO_INCREMENT, # client id - `team_id` int(11) NOT NULL, # team id + `group_id` int(11) NOT NULL, # group id `name` varchar(80) COLLATE utf8_bin NOT NULL, # client name `address` varchar(255) default NULL, # client address `tax` float(6,2) default '0.00', # applicable tax for this client @@ -306,7 +306,7 @@ CREATE TABLE `tt_clients` ( ); # Create an index that guarantees unique active and inactive clients per team. -create unique index client_name_idx on tt_clients(team_id, name, status); +create unique index client_name_idx on tt_clients(group_id, name, status); # @@ -343,7 +343,7 @@ create unique index param_idx on tt_config(user_id, param_name); # CREATE TABLE `tt_custom_fields` ( `id` int(11) NOT NULL auto_increment, # custom field id - `team_id` int(11) NOT NULL, # team id + `group_id` int(11) NOT NULL, # group id `type` tinyint(4) NOT NULL default 0, # custom field type (text or dropdown) `label` varchar(32) NOT NULL default '', # custom field label `required` tinyint(4) default 0, # whether this custom field is mandatory for time records @@ -416,7 +416,7 @@ create index invoice_idx on tt_expense_items(invoice_id); # CREATE TABLE `tt_predefined_expenses` ( `id` int(11) NOT NULL auto_increment, # predefined expense id - `team_id` int(11) NOT NULL, # team id + `group_id` int(11) NOT NULL, # group id `name` varchar(255) NOT NULL, # predefined expense name, such as mileage `cost` decimal(10,2) default '0.00', # cost for one unit PRIMARY KEY (`id`) @@ -428,11 +428,11 @@ CREATE TABLE `tt_predefined_expenses` ( # This table keeps monthly work hour quotas for groups. # CREATE TABLE `tt_monthly_quotas` ( - `team_id` int(11) NOT NULL, # group id + `group_id` int(11) NOT NULL, # group id `year` smallint(5) UNSIGNED NOT NULL, # quota year `month` tinyint(3) UNSIGNED NOT NULL, # quota month `minutes` int(11) default NULL, # quota in minutes in specified month and year - PRIMARY KEY (`team_id`,`year`,`month`) + PRIMARY KEY (`group_id`,`year`,`month`) ); @@ -449,4 +449,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.80', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.81', now()); # TODO: change when structure changes. diff --git a/notification_add.php b/notification_add.php index 7dd680ff3..e30970afa 100644 --- a/notification_add.php +++ b/notification_add.php @@ -86,7 +86,7 @@ $next = tdCron::getNextOccurrence($cl_cron_spec, mktime()); if (ttNotificationHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'cron_spec' => $cl_cron_spec, 'next' => $next, 'report_id' => $cl_fav_report, diff --git a/notification_edit.php b/notification_edit.php index 1c36865f3..69535815d 100644 --- a/notification_edit.php +++ b/notification_edit.php @@ -94,7 +94,7 @@ if (ttNotificationHelper::update(array( 'id' => $notification_id, - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'cron_spec' => $cl_cron_spec, 'next' => $next, 'report_id' => $cl_fav_report, diff --git a/notifications.php b/notifications.php index 6dcf33fd2..23400beb4 100644 --- a/notifications.php +++ b/notifications.php @@ -50,7 +50,7 @@ } } else { $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - $notifications = ttTeamHelper::getNotifications($user->team_id); + $notifications = ttTeamHelper::getNotifications($user->group_id); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); diff --git a/password_change.php b/password_change.php index 832118f6c..f8c47112a 100644 --- a/password_change.php +++ b/password_change.php @@ -49,8 +49,8 @@ $smarty->assign('i18n', $i18n->keys); } if ($user->custom_logo) { - $smarty->assign('custom_logo', 'images/'.$user->team_id.'.png'); - $smarty->assign('mobile_custom_logo', '../images/'.$user->team_id.'.png'); + $smarty->assign('custom_logo', 'images/'.$user->group_id.'.png'); + $smarty->assign('mobile_custom_logo', '../images/'.$user->group_id.'.png'); } $smarty->assign('user', $user); } diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index f9592f1c8..afb59dae9 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -37,11 +37,11 @@ class CustomFields { var $options = array(); // Array of options for a dropdown custom field. // Constructor. - function __construct($team_id) { + function __construct($group_id) { $mdb2 = getConnection(); // Get fields. - $sql = "select id, type, label, required from tt_custom_fields where team_id = $team_id and status = 1 and type > 0"; + $sql = "select id, type, label, required from tt_custom_fields where group_id = $group_id and status = 1 and type > 0"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -149,12 +149,12 @@ static function deleteOption($id) { $field_id = CustomFields::getFieldIdForOption($id); // First make sure that the field is ours. - $sql = "select team_id from tt_custom_fields where id = $field_id"; + $sql = "select group_id from tt_custom_fields where id = $field_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; $val = $res->fetchRow(); - if ($user->team_id != $val['team_id']) + if ($user->group_id != $val['group_id']) return false; // Delete log entries with this option. @@ -176,12 +176,12 @@ static function getOptions($field_id) { $options = array(); // First make sure that the field is ours. - $sql = "select team_id from tt_custom_fields where id = $field_id"; + $sql = "select group_id from tt_custom_fields where id = $field_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; $val = $res->fetchRow(); - if ($user->team_id != $val['team_id']) + if ($user->group_id != $val['group_id']) return false; // Get options. @@ -204,12 +204,12 @@ static function getOptionName($id) { $field_id = CustomFields::getFieldIdForOption($id); // First make sure that the field is ours. - $sql = "select team_id from tt_custom_fields where id = $field_id"; + $sql = "select group_id from tt_custom_fields where id = $field_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; $val = $res->fetchRow(); - if ($user->team_id != $val['team_id']) + if ($user->group_id != $val['group_id']) return false; // Get option name. @@ -229,7 +229,7 @@ static function getFields() { $mdb2 = getConnection(); $fields = array(); - $sql = "select id, type, label from tt_custom_fields where team_id = $user->team_id and status = 1 and type > 0"; + $sql = "select id, type, label from tt_custom_fields where group_id = $user->group_id and status = 1 and type > 0"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -245,7 +245,7 @@ static function getField($id) { global $user; $mdb2 = getConnection(); - $sql = "select label, type, required from tt_custom_fields where id = $id and team_id = $user->team_id"; + $sql = "select label, type, required from tt_custom_fields where id = $id and group_id = $user->group_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -274,7 +274,7 @@ static function getFieldIdForOption($option_id) { static function insertField($field_name, $field_type, $required) { global $user; $mdb2 = getConnection(); - $sql = "insert into tt_custom_fields (team_id, type, label, required, status) values($user->team_id, $field_type, ".$mdb2->quote($field_name).", $required, 1)"; + $sql = "insert into tt_custom_fields (group_id, type, label, required, status) values($user->group_id, $field_type, ".$mdb2->quote($field_name).", $required, 1)"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -283,7 +283,7 @@ static function insertField($field_name, $field_type, $required) { static function updateField($id, $name, $type, $required) { global $user; $mdb2 = getConnection(); - $sql = "update tt_custom_fields set label = ".$mdb2->quote($name).", type = $type, required = $required where id = $id and team_id = $user->team_id"; + $sql = "update tt_custom_fields set label = ".$mdb2->quote($name).", type = $type, required = $required where id = $id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -299,12 +299,12 @@ static function deleteField($field_id) { $mdb2 = getConnection(); // First make sure that the field is ours so that we can safely delete it. - $sql = "select team_id from tt_custom_fields where id = $field_id"; + $sql = "select group_id from tt_custom_fields where id = $field_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; $val = $res->fetchRow(); - if ($user->team_id != $val['team_id']) + if ($user->group_id != $val['group_id']) return false; // Mark log entries as deleted. @@ -320,7 +320,7 @@ static function deleteField($field_id) { return false; // Delete the field. - $sql = "delete from tt_custom_fields where id = $field_id and team_id = $user->team_id"; + $sql = "delete from tt_custom_fields where id = $field_id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/plugins/MonthlyQuota.class.php b/plugins/MonthlyQuota.class.php index a4be6ee32..de1f7cd20 100644 --- a/plugins/MonthlyQuota.class.php +++ b/plugins/MonthlyQuota.class.php @@ -32,21 +32,21 @@ class MonthlyQuota { var $db; // Database connection. - var $team_id; // Team id. + var $group_id; // Group id. function __construct() { $this->db = getConnection(); global $user; - $this->team_id = $user->team_id; + $this->group_id = $user->group_id; } // update - deletes a quota, then inserts a new one. public function update($year, $month, $minutes) { - $team_id = $this->team_id; - $deleteSql = "DELETE FROM tt_monthly_quotas WHERE year = $year AND month = $month AND team_id = $team_id"; + $group_id = $this->group_id; + $deleteSql = "DELETE FROM tt_monthly_quotas WHERE year = $year AND month = $month AND group_id = $group_id"; $this->db->exec($deleteSql); if ($minutes){ - $insertSql = "INSERT INTO tt_monthly_quotas (team_id, year, month, minutes) values ($team_id, $year, $month, $minutes)"; + $insertSql = "INSERT INTO tt_monthly_quotas (group_id, year, month, minutes) values ($group_id, $year, $month, $minutes)"; $affected = $this->db->exec($insertSql); return (!is_a($affected, 'PEAR_Error')); } @@ -64,8 +64,8 @@ public function get($year, $month = null) { // getSingle - obtains a quota for a single month. private function getSingle($year, $month) { - $team_id = $this->team_id; - $sql = "SELECT minutes FROM tt_monthly_quotas WHERE year = $year AND month = $month AND team_id = $team_id"; + $group_id = $this->group_id; + $sql = "SELECT minutes FROM tt_monthly_quotas WHERE year = $year AND month = $month AND group_id = $group_id"; $reader = $this->db->query($sql); if (is_a($reader, 'PEAR_Error')) { return false; @@ -83,8 +83,8 @@ private function getSingle($year, $month) { // getMany - returns an array of quotas for a given year for team. private function getMany($year){ - $team_id = $this->team_id; - $sql = "SELECT month, minutes FROM tt_monthly_quotas WHERE year = $year AND team_id = $team_id"; + $group_id = $this->group_id; + $sql = "SELECT month, minutes FROM tt_monthly_quotas WHERE year = $year AND group_id = $group_id"; $result = array(); $res = $this->db->query($sql); if (is_a($res, 'PEAR_Error')) { diff --git a/predefined_expense_add.php b/predefined_expense_add.php index 2f1621cac..e653192b8 100644 --- a/predefined_expense_add.php +++ b/predefined_expense_add.php @@ -56,7 +56,7 @@ if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); if ($err->no()) { if (ttPredefinedExpenseHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'cost' => $cl_cost))) { header('Location: predefined_expenses.php'); diff --git a/predefined_expense_edit.php b/predefined_expense_edit.php index 7791b2440..9b3727bf1 100644 --- a/predefined_expense_edit.php +++ b/predefined_expense_edit.php @@ -64,7 +64,7 @@ if ($err->no()) { if (ttPredefinedExpenseHelper::update(array( 'id' => $predefined_expense_id, - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'cost' => $cl_cost))) { header('Location: predefined_expenses.php'); diff --git a/predefined_expenses.php b/predefined_expenses.php index 7aed7ad60..88ac44d70 100644 --- a/predefined_expenses.php +++ b/predefined_expenses.php @@ -50,7 +50,7 @@ } } else { $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - $predefinedExpenses = ttTeamHelper::getPredefinedExpenses($user->team_id); + $predefinedExpenses = ttTeamHelper::getPredefinedExpenses($user->group_id); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); diff --git a/project_add.php b/project_add.php index 55b83b42a..980870250 100644 --- a/project_add.php +++ b/project_add.php @@ -45,7 +45,7 @@ foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; -$tasks = ttTeamHelper::getActiveTasks($user->team_id); +$tasks = ttTeamHelper::getActiveTasks($user->group_id); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; @@ -77,7 +77,7 @@ if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { if (ttProjectHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, diff --git a/project_edit.php b/project_edit.php index 543c532ef..14e8e7713 100644 --- a/project_edit.php +++ b/project_edit.php @@ -52,7 +52,7 @@ foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; -$tasks = ttTeamHelper::getActiveTasks($user->team_id); +$tasks = ttTeamHelper::getActiveTasks($user->group_id); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; @@ -118,7 +118,7 @@ if ($request->getParameter('btn_copy')) { if (!ttProjectHelper::getProjectByName($cl_name)) { if (ttProjectHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, diff --git a/projects.php b/projects.php index bf6aed1cb..d206fe8c2 100644 --- a/projects.php +++ b/projects.php @@ -42,8 +42,8 @@ // End of access checks. if($user->can('manage_projects')) { - $active_projects = ttTeamHelper::getActiveProjects($user->team_id); - $inactive_projects = ttTeamHelper::getInactiveProjects($user->team_id); + $active_projects = ttTeamHelper::getActiveProjects($user->group_id); + $inactive_projects = ttTeamHelper::getInactiveProjects($user->group_id); } else $active_projects = $user->getAssignedProjects(); diff --git a/quotas.php b/quotas.php index c921fba4c..8e6f59c4d 100644 --- a/quotas.php +++ b/quotas.php @@ -90,7 +90,7 @@ // Handle workday hours. $workday_minutes = ttTimeHelper::postedDurationToMinutes($request->getParameter('workdayHours')); if ($workday_minutes != $user->workday_minutes) { - if (!ttTeamHelper::update($user->team_id, array('name'=>$user->team,'workday_minutes'=>$workday_minutes))) + if (!ttTeamHelper::update($user->group_id, array('name'=>$user->team,'workday_minutes'=>$workday_minutes))) $err->add($i18n->get('error.db')); } diff --git a/report.php b/report.php index c59f6b5e3..d712968d9 100644 --- a/report.php +++ b/report.php @@ -54,7 +54,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $smarty->assign('custom_fields', $custom_fields); } @@ -92,7 +92,7 @@ // Controls for "Assign to invoice" block. if ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by')) && !$user->isClient()) { // Client is selected and we are displaying the invoice column. - $recent_invoices = ttTeamHelper::getRecentInvoices($user->team_id, $client_id); + $recent_invoices = ttTeamHelper::getRecentInvoices($user->group_id, $client_id); if ($recent_invoices) { $assign_invoice_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); $form->addInput(array('type'=>'combobox', diff --git a/reports.php b/reports.php index 3aba9cdf7..99683c1ab 100644 --- a/reports.php +++ b/reports.php @@ -45,7 +45,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $smarty->assign('custom_fields', $custom_fields); } @@ -104,7 +104,7 @@ 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.all')))); if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->team_id); + $task_list = ttTeamHelper::getActiveTasks($user->group_id); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/role_add.php b/role_add.php index d26cb6ad0..086da632c 100644 --- a/role_add.php +++ b/role_add.php @@ -59,11 +59,11 @@ if ($cl_rank >= $user->rank || $cl_rank < 0) $err->add($i18n->get('error.field'), $i18n->get('form.roles.rank')); if ($err->no()) { - $existing_role = ttRoleHelper::getRoleByRank($cl_rank, $user->team_id); + $existing_role = ttRoleHelper::getRoleByRank($cl_rank, $user->group_id); if (!$existing_role) { // Insert a role with default user rights. if (ttRoleHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'rank' => $cl_rank, 'description' => $cl_description, diff --git a/task_add.php b/task_add.php index eaaba5e8d..e25fa3908 100644 --- a/task_add.php +++ b/task_add.php @@ -43,7 +43,7 @@ } // End of access checks. -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -68,7 +68,7 @@ if ($err->no()) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => ACTIVE, diff --git a/task_edit.php b/task_edit.php index 324f1dbb8..feff4e52d 100644 --- a/task_edit.php +++ b/task_edit.php @@ -48,7 +48,7 @@ } // End of access checks. -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -101,7 +101,7 @@ if ($request->getParameter('btn_copy')) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => $cl_status, diff --git a/tasks.php b/tasks.php index 2d310d011..e967e095e 100644 --- a/tasks.php +++ b/tasks.php @@ -41,8 +41,8 @@ } // End of access checks. -$smarty->assign('active_tasks', ttTeamHelper::getActiveTasks($user->team_id)); -$smarty->assign('inactive_tasks', ttTeamHelper::getInactiveTasks($user->team_id)); +$smarty->assign('active_tasks', ttTeamHelper::getActiveTasks($user->group_id)); +$smarty->assign('inactive_tasks', ttTeamHelper::getInactiveTasks($user->group_id)); $smarty->assign('title', $i18n->get('title.tasks')); $smarty->assign('content_page_name', 'tasks.tpl'); $smarty->display('index.tpl'); diff --git a/time.php b/time.php index d75854c83..24cc7c8ae 100644 --- a/time.php +++ b/time.php @@ -61,7 +61,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $smarty->assign('custom_fields', $custom_fields); } @@ -125,7 +125,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -151,7 +151,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -179,7 +179,7 @@ } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->team_id); + $task_list = ttTeamHelper::getActiveTasks($user->group_id); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/time_edit.php b/time_edit.php index 507f28abb..812594360 100644 --- a/time_edit.php +++ b/time_edit.php @@ -51,7 +51,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $smarty->assign('custom_fields', $custom_fields); } @@ -110,7 +110,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -136,7 +136,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -164,7 +164,7 @@ } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->team_id); + $task_list = ttTeamHelper::getActiveTasks($user->group_id); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/tofile.php b/tofile.php index e7b9ed963..62632fa97 100644 --- a/tofile.php +++ b/tofile.php @@ -41,7 +41,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); } // Report settings are stored in session bean before we get here. diff --git a/topdf.php b/topdf.php index 475522ef9..9149e1c69 100644 --- a/topdf.php +++ b/topdf.php @@ -52,7 +52,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); } // Report settings are stored in session bean before we get here. @@ -391,8 +391,8 @@ public function Footer() { $pdf = new ttPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); // If custom logo file exists - set it. -if (file_exists('images/'.$user->team_id.'.png')) - $pdf->SetImageFile('images/'.$user->team_id.'.png'); +if (file_exists('images/'.$user->group_id.'.png')) + $pdf->SetImageFile('images/'.$user->group_id.'.png'); // Set page word for the footer. $pdf->SetPageWord($i18n->get('label.page')); diff --git a/user_add.php b/user_add.php index b235cbd17..1ed0cb725 100644 --- a/user_add.php +++ b/user_add.php @@ -46,7 +46,7 @@ @include('plugins/limit/user_add.php'); if ($user->isPluginEnabled('cl')) - $clients = ttTeamHelper::getActiveClients($user->team_id); + $clients = ttTeamHelper::getActiveClients($user->group_id); $assigned_projects = array(); if ($request->isPost()) { @@ -90,7 +90,7 @@ $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { @@ -150,7 +150,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'login' => $cl_login, 'password' => $cl_password1, 'rate' => $cl_rate, - 'team_id' => $user->team_id, + 'group_id' => $user->group_id, 'role_id' => $cl_role_id, 'client_id' => $cl_client_id, 'projects' => $assigned_projects, diff --git a/user_edit.php b/user_edit.php index 95ed29e79..f370f451d 100644 --- a/user_edit.php +++ b/user_edit.php @@ -49,9 +49,9 @@ // End of access checks. if ($user->isPluginEnabled('cl')) - $clients = ttTeamHelper::getActiveClients($user->team_id); + $clients = ttTeamHelper::getActiveClients($user->group_id); -$projects = ttTeamHelper::getActiveProjects($user->team_id); +$projects = ttTeamHelper::getActiveProjects($user->group_id); $assigned_projects = array(); if ($request->isPost()) { diff --git a/week.php b/week.php index 1d72ce400..c71a2ccd0 100644 --- a/week.php +++ b/week.php @@ -83,7 +83,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->team_id); + $custom_fields = new CustomFields($user->group_id); $smarty->assign('custom_fields', $custom_fields); } @@ -244,7 +244,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -270,7 +270,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -298,7 +298,7 @@ function render(&$table, $value, $row, $column, $selected = false) { } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->team_id); + $task_list = ttTeamHelper::getActiveTasks($user->group_id); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', From a6c4fa37379736e1c7568ccea1c5d371de7c6271 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Mar 2018 11:28:07 +0000 Subject: [PATCH 0083/1848] Introduced view_all_reports right and added it to co-manager role. --- WEB-INF/lib/ttRoleHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 4 ++-- report.php | 2 +- reports.php | 12 +++++++----- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 25d714194..f4168094e 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -186,7 +186,7 @@ static function createPredefinedRoles($group_id, $lang) $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; - $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices'; + $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,view_all_reports'; $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; // Active roles. @@ -244,7 +244,7 @@ static function createDefaultRoles() $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; - $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices'; + $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,view_all_reports'; $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; // Active roles. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 10419c01b..8a97233ce 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.81.4200 | Copyright © Anuko | +  Anuko Time Tracker 1.17.82.4201 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 97a5085da..e8f282fa6 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11780"]) { + if ($_POST["convert11744to11782"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -883,6 +883,8 @@ function setChange($sql) { setChange("ALTER TABLE `tt_predefined_expenses` CHANGE `team_id` `group_id` int(11) NOT NULL"); setChange("ALTER TABLE `tt_monthly_quotas` CHANGE `team_id` `group_id` int(11) NOT NULL"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.81', modified = now() where param_name = 'version_db' and param_value = '1.17.80'"); + setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.81') set rights = replace(rights, ',manage_invoices', ',manage_invoices,view_all_reports')"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.82', modified = now() where param_name = 'version_db' and param_value = '1.17.81'"); } if ($_POST["cleanup"]) { @@ -928,7 +930,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.80) + Create database structure (v1.17.82)
(applies only to new installations, do not execute when updating)
@@ -968,8 +970,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.80)Update database structure (v1.17.44 to v1.17.82)
diff --git a/mysql.sql b/mysql.sql index 78ee25abc..6d6ce5fb0 100644 --- a/mysql.sql +++ b/mysql.sql @@ -73,7 +73,7 @@ create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,view_own_projects,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,view_own_projects,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,view_all_reports,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'); # @@ -449,4 +449,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.81', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.82', now()); # TODO: change when structure changes. diff --git a/report.php b/report.php index d712968d9..1f0ec87c6 100644 --- a/report.php +++ b/report.php @@ -33,7 +33,7 @@ import('ttTeamHelper'); // Access check. -if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports'))) { header('Location: access_denied.php'); exit(); } diff --git a/reports.php b/reports.php index 99683c1ab..0028e9957 100644 --- a/reports.php +++ b/reports.php @@ -37,7 +37,7 @@ import('ttClientHelper'); // Access check. -if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports'))) { header('Location: access_denied.php'); exit(); } @@ -141,13 +141,15 @@ } $user_list = array(); -if ($user->can('view_reports') || $user->isClient()) { +if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { // Prepare user and assigned projects arrays. - if ($user->can('view_reports')) { + if ($user->can('view_reports') || $user->can('view_all_reports')) { + $max_rank = $user->rank-1; + if ($user->can('view_all_reports')) $max_rank = 512; if ($user->can('view_own_reports')) - $options = array('max_rank'=>$user->rank-1,'include_self'=>true); + $options = array('max_rank'=>$max_rank,'include_self'=>true); else - $options = array('max_rank'=>$user->rank-1); + $options = array('max_rank'=>$max_rank); $users = $user->getUsers($options); // Active and inactive users. } elseif ($user->isClient()) From 0437aa573277bc54ef4365f2df6ec72f40b5ef29 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Mar 2018 12:04:42 +0000 Subject: [PATCH 0084/1848] Added conditional display of invoice related items on reports. --- WEB-INF/templates/footer.tpl | 2 +- report.php | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8a97233ce..fb117e2f9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.82.4201 | Copyright © Anuko | +  Anuko Time Tracker 1.17.82.4202 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index 1f0ec87c6..3f2074491 100644 --- a/report.php +++ b/report.php @@ -70,11 +70,12 @@ // Do we need to show checkboxes? if ($bean->getAttribute('chpaid') || ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by')) && !$user->isClient())) { - $smarty->assign('use_checkboxes', true); + if ($user->can('manage_invoices')) + $smarty->assign('use_checkboxes', true); } // Controls for "Mark paid" block. -if ($bean->getAttribute('chpaid')) { +if ($user->can('manage_invoices') && $bean->getAttribute('chpaid')) { $mark_paid_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); $form->addInput(array('type'=>'combobox', 'name'=>'mark_paid_select_options', @@ -90,7 +91,8 @@ } // Controls for "Assign to invoice" block. -if ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by')) && !$user->isClient()) { +if ($user->can('manage_invoices') && + ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by')) && !$user->isClient())) { // Client is selected and we are displaying the invoice column. $recent_invoices = ttTeamHelper::getRecentInvoices($user->group_id, $client_id); if ($recent_invoices) { From b3ed433e388b83e055958b395ebc0e08172cd079 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Mar 2018 20:07:13 +0000 Subject: [PATCH 0085/1848] Introduced IP based access control for groups. --- WEB-INF/lib/common.lib.php | 15 +++++++++++++++ WEB-INF/lib/ttRoleHelper.class.php | 4 ++-- WEB-INF/lib/ttTeamHelper.class.php | 4 +++- WEB-INF/lib/ttUser.class.php | 14 ++++++++------ WEB-INF/resources/en.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 6 +++++- dbinstall.php | 11 +++++++---- group_edit.php | 6 ++++++ mysql.sql | 5 +++-- 10 files changed, 51 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 7086fe298..210ec41cd 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -339,6 +339,21 @@ function ttAccessAllowed($required_right) exit(); } + // Check IP restriction, if set. + if ($user->allow_ip && !$user->can('override_allow_ip')) { + $access_allowed = false; + $user_ip = $_SERVER['REMOTE_ADDR']; + $allowed_ip_array = explode(',', $user->allow_ip); + foreach ($allowed_ip_array as $allowed_ip) { + $len = strlen($allowed_ip); + if (substr($user_ip, 0, $len) === $allowed_ip) { + $access_allowed = true; + break; + } + } + if (!$access_allowed) return false; + } + // Check if user has the right. if (in_array($required_right, $user->rights)) { import('ttUserHelper'); diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index f4168094e..a5f16f9cb 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -186,7 +186,7 @@ static function createPredefinedRoles($group_id, $lang) $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; - $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,view_all_reports'; + $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,view_all_reports'; $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; // Active roles. @@ -244,7 +244,7 @@ static function createDefaultRoles() $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; - $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,view_all_reports'; + $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,view_all_reports'; $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; // Active roles. diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 01b0db360..0093e9280 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -869,6 +869,7 @@ static function update($group_id, $fields) $task_required_part = ' , task_required = '.(int) $fields['task_required']; $record_type_part = ''; $bcc_email_part = ''; + $allow_ip = ''; $plugins_part = ''; $config_part = ''; $lock_spec_part = ''; @@ -883,6 +884,7 @@ static function update($group_id, $fields) if (isset($fields['tracking_mode'])) $tracking_mode_part = ', tracking_mode = '.(int) $fields['tracking_mode']; if (isset($fields['record_type'])) $record_type_part = ', record_type = '.(int) $fields['record_type']; if (isset($fields['bcc_email'])) $bcc_email_part = ', bcc_email = '.$mdb2->quote($fields['bcc_email']); + if (isset($fields['allow_ip'])) $allow_ip_part = ', allow_ip = '.$mdb2->quote($fields['allow_ip']); if (isset($fields['plugins'])) $plugins_part = ', plugins = '.$mdb2->quote($fields['plugins']); if (isset($fields['config'])) $config_part = ', config = '.$mdb2->quote($fields['config']); if (isset($fields['lock_spec'])) $lock_spec_part = ', lock_spec = '.$mdb2->quote($fields['lock_spec']); @@ -891,7 +893,7 @@ static function update($group_id, $fields) $sql = "update tt_groups set $name_part $currency_part $lang_part $decimal_mark_part $date_format_part $time_format_part $week_start_part $tracking_mode_part $task_required_part $record_type_part - $bcc_email_part $plugins_part $config_part $lock_spec_part $workday_minutes_part $modified_part where id = $group_id"; + $bcc_email_part $allow_ip_part $plugins_part $config_part $lock_spec_part $workday_minutes_part $modified_part where id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 70e550402..2781ea6f2 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -53,6 +53,7 @@ class ttUser { var $future_entries = 0; // Whether to allow creating future entries. var $uncompleted_indicators = 0; // Uncompleted time entry indicators (show nowhere or on users page). var $bcc_email = null; // Bcc email. + var $allow_ip = null; // Specification from where user is allowed access. var $currency = null; // Currency. var $plugins = null; // Comma-separated list of enabled plugins. var $config = null; // Comma-separated list of miscellaneous config options. @@ -72,11 +73,11 @@ function __construct($login, $id = null) { $mdb2 = getConnection(); - $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id, u.email, t.name as team_name, - t.currency, t.lang, t.decimal_mark, t.date_format, t.time_format, t.week_start, - t.tracking_mode, t.project_required, t.task_required, t.record_type, - t.bcc_email, t.plugins, t.config, t.lock_spec, t.workday_minutes, t.custom_logo - FROM tt_users u LEFT JOIN tt_groups t ON (u.group_id = t.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; + $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id, u.email, g.name as group_name, + g.currency, g.lang, g.decimal_mark, g.date_format, g.time_format, g.week_start, + g.tracking_mode, g.project_required, g.task_required, g.record_type, + g.bcc_email, g.allow_ip, g.plugins, g.config, g.lock_spec, g.workday_minutes, g.custom_logo + FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; if ($id) $sql .= "u.id = $id"; else @@ -111,7 +112,8 @@ function __construct($login, $id = null) { $this->task_required = $val['task_required']; $this->record_type = $val['record_type']; $this->bcc_email = $val['bcc_email']; - $this->team = $val['team_name']; + $this->allow_ip = $val['allow_ip']; + $this->team = $val['group_name']; $this->currency = $val['currency']; $this->plugins = $val['plugins']; $this->lock_spec = $val['lock_spec']; diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 2063f4eec..7e930e4f4 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -446,6 +446,7 @@ 'form.profile.allow_overlap' => 'Allow overlap', 'form.profile.future_entries' => 'Future entries', 'form.profile.uncompleted_indicators' => 'Uncompleted indicators', +'form.profile.allow_ip' => 'Allow IP', 'form.profile.plugins' => 'Plugins', // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fb117e2f9..873d5ec4c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- -{if $user->isManager()} +{if $user->can('manage_advanced_settings')} + + + + {/if} {* initialize preview text *}
 Anuko Time Tracker 1.17.82.4202 | Copyright © Anuko | +  Anuko Time Tracker 1.17.83.4203 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index 9b341b674..4dedafdf1 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -164,11 +164,15 @@ function handlePluginCheckboxes() { {$i18n.form.profile.uncompleted_indicators}: {$forms.groupForm.uncompleted_indicators.control} {$i18n.label.what_is_it}
{$i18n.label.bcc}: {$forms.groupForm.bcc_email.control} {$i18n.label.what_is_it}
{$i18n.form.profile.allow_ip}:{$forms.groupForm.allow_ip.control} {$i18n.label.what_is_it}
- +
{$i18n.form.teams.hint}
{$i18n.form.groups.hint}
diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5b5463a77..b931f0c79 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.86.4221 | Copyright © Anuko | +  Anuko Time Tracker 1.17.86.4222 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 317b22c142b15ad3ba4b12d07be9b4f4680e0b5a Mon Sep 17 00:00:00 2001 From: bonnedav Date: Mon, 2 Apr 2018 19:14:01 -0600 Subject: [PATCH 0106/1848] Refactor export.tpl to use rights checks (#60) --- WEB-INF/templates/export.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WEB-INF/templates/export.tpl b/WEB-INF/templates/export.tpl index 1c9866edc..487f00978 100644 --- a/WEB-INF/templates/export.tpl +++ b/WEB-INF/templates/export.tpl @@ -2,7 +2,7 @@
-{if $user->isManager()} +{if $user->can('export_data')} From b9026f8ab6535160feb9d4d1caf95495f5b159be Mon Sep 17 00:00:00 2001 From: bonnedav Date: Mon, 2 Apr 2018 19:15:53 -0600 Subject: [PATCH 0107/1848] Refactor canManageTeam in group_edit.tpl (#59) --- WEB-INF/templates/group_edit.tpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index 5a5711b07..72222c094 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -94,7 +94,7 @@ function handlePluginCheckboxes() { {$forms.groupForm.open} -{if $user->canManageTeam()} +{if $user->can('manage_basic_settings')} {include file="datetime_format_preview.tpl"} {/if} @@ -102,7 +102,7 @@ function handlePluginCheckboxes() { diff --git a/reports.php b/reports.php index fcefd047b..0565cf71d 100644 --- a/reports.php +++ b/reports.php @@ -214,6 +214,9 @@ // If we have a custom field - add a checkbox for it. if ($custom_fields && $custom_fields->fields[0]) $form->addInput(array('type'=>'checkbox','name'=>'chcf_1')); +if ($user->isPluginEnabled('wu')) + $form->addInput(array('type'=>'checkbox','name'=>'chunits')); + // Add group by control. $group_by_options['no_grouping'] = $i18n->get('form.reports.group_by_no'); $group_by_options['date'] = $i18n->get('form.reports.group_by_date'); @@ -260,6 +263,7 @@ $form->setValueByElement('chfinish', '1'); $form->setValueByElement('chnote', '1'); $form->setValueByElement('chcf_1', '0'); + $form->setValueByElement('chunits', '0'); $form->setValueByElement('chtotalsonly', '0'); } diff --git a/work_units.php b/work_units.php index 3340ec151..dd01488a7 100644 --- a/work_units.php +++ b/work_units.php @@ -46,8 +46,8 @@ $cl_minutes_in_unit = $request->getParameter('minutes_in_unit'); $cl_1st_unit_threshold = $request->getParameter('1st_unit_threshold'); } else { - $cl_minutes_in_unit = $config->getIntValue('minutes_in_unit'); - $cl_1st_unit_threshold = $config->getIntValue('1st_unit_threshold'); + $cl_minutes_in_unit = $user->minutes_in_unit; + $cl_1st_unit_threshold = $user->first_unit_threshold; } $form = new Form('workUnitsForm'); From f7ec54ba04c4899a9ec343ef8c1c96109feeabb7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Jul 2018 16:55:45 +0000 Subject: [PATCH 0171/1848] Removed conditional include of the Work units plugin to facilitate user testing. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 2 -- group_edit.php | 4 +--- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3ad220b3d..95dec6289 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-{if $user->isManager() || ($user->canManageTeam() && !defined(MANAGER_ONLY_TEAM_SETTINGS))} +{if $user->can('manage_basic_settings')} From db7dd4684cf7d63cfd840119e6ea47a4a888f02b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 3 Apr 2018 01:20:25 +0000 Subject: [PATCH 0108/1848] Cosmetic. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b931f0c79..223b24dd7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.group_name}: {$forms.groupForm.team_name.control}
- -{if $user->can('manage_advanced_settings')} + {if $user->can('manage_advanced_settings')} @@ -173,7 +173,7 @@ function handlePluginCheckboxes() { -{/if} + {/if} {* initialize preview text *} @@ -239,6 +247,12 @@ function handlePluginCheckboxes() { + {if defined('WORK_UNITS_DEBUG')} + + + + + {/if} {/if} diff --git a/group_edit.php b/group_edit.php index d79ba2d35..676a4d777 100644 --- a/group_edit.php +++ b/group_edit.php @@ -75,6 +75,7 @@ $cl_locking = $request->getParameter('locking'); $cl_quotas = $request->getParameter('quotas'); $cl_week_view = $request->getParameter('week_view'); + $cl_work_units = $request->getParameter('work_units'); } else { $cl_group = $user->group; $cl_currency = ($user->currency == ''? CURRENCY_DEFAULT : $user->currency); @@ -109,6 +110,7 @@ $cl_locking = in_array('lk', $plugins); $cl_quotas = in_array('mq', $plugins); $cl_week_view = in_array('wv', $plugins); + $cl_work_units = in_array('wu', $plugins); } $form = new Form('groupForm'); @@ -207,6 +209,10 @@ $form->addInput(array('type'=>'checkbox','name'=>'locking','value'=>$cl_locking,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'checkbox','name'=>'quotas','value'=>$cl_quotas,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'checkbox','name'=>'week_view','value'=>$cl_week_view,'onchange'=>'handlePluginCheckboxes()')); +if (defined('WORK_UNITS_DEBUG')) { + $form->addInput(array('type'=>'checkbox','name'=>'work_units','value'=>$cl_work_units,'onchange'=>'handlePluginCheckboxes()')); +} + $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($user->can('delete_group')) $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('button.delete'))); From a67c7fec533237be9be83379eb19fbbf51174c9a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Jul 2018 21:08:04 +0000 Subject: [PATCH 0168/1848] Resource file changes for work units plugin (in progress). --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + 30 files changed, 31 insertions(+) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index ad3f5879c..74f299cc8 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -329,6 +329,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index eb1565e96..7e30f0e5e 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -340,6 +340,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index d506f28df..c461cc373 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -298,6 +298,7 @@ // TODO: translate the following. // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index b4ee16f98..23b13c1c8 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -290,6 +290,7 @@ // TODO: translate the following. // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 35958adaf..55c158e82 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -284,6 +284,7 @@ 'title.locking' => 'Locking', 'title.week_view' => 'Week View', 'title.swap_roles' => 'Swapping Roles', +'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 8693dbb8f..a665fabde 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -328,6 +328,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index aa327deeb..e1aa2e384 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -335,6 +335,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 6fc87e51b..7d99e4d3f 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -310,6 +310,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 5d1417f20..a7920c7fb 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -299,6 +299,7 @@ // TODO: translate the following. // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index be9abdeae..46eb3f330 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -292,6 +292,7 @@ // TODO: translate the following. // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 89d0e50c9..ec6fdf8ab 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -286,6 +286,7 @@ 'title.week_view' => 'Προβολή εβδομάδας', // TODO: translate the following. // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 482a74399..599826e3e 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -321,6 +321,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 375664b86..fb64b80ce 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -326,6 +326,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 60310ebd6..09fe6b72a 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -297,6 +297,7 @@ 'title.locking' => 'Bloccaggio', 'title.week_view' => 'Vista settimanale', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 9241d735f..6386d5f26 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -333,6 +333,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 0d39209b4..4bc1ec8d2 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -334,6 +334,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 961651fd0..db0e1907a 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -282,6 +282,8 @@ 'title.locking' => 'Blokkeren', 'title.week_view' => 'Week overzicht', 'title.swap_roles' => 'Rollen verruilen', +// TODO: translate the following. +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index d218341f5..a20743158 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -330,6 +330,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index e218b929e..42c75f27a 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -301,6 +301,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index a90308127..dff078974 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -296,6 +296,7 @@ // TODO: translate the following. // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 30ed9bded..9520d3eb3 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -316,6 +316,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index f4f0c85bb..a86a3640d 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -335,6 +335,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index d3276d88f..718f32461 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -281,6 +281,7 @@ 'title.locking' => 'Блокировка', 'title.week_view' => 'Неделя', 'title.swap_roles' => 'Обмен ролей', +'title.work_units' => 'Единицы работы', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 3f5081218..7ed5339e7 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -311,6 +311,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index f85164b9c..ab858b90a 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -310,6 +310,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index a2287f384..4dc9e58e3 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -300,6 +300,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 0b96da48d..e47f8939d 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -298,6 +298,7 @@ // TODO: translate the following. // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 3683e3aff..665b23e10 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -344,6 +344,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 519faa960..eb571eadc 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -322,6 +322,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 0cf2d6c66..50a0960bc 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -329,6 +329,7 @@ // 'title.locking' => 'Locking', // 'title.week_view' => 'Week View', // 'title.swap_roles' => 'Swapping Roles', +// 'title.work_units' => 'Work Units', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. From 99041558bf625b082fc5058a93e1bd2634c2c9d2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Jul 2018 23:53:58 +0000 Subject: [PATCH 0169/1848] A bit more progress on Work units plugin, made its config page working. --- WEB-INF/lib/ttConfigHelper.class.php | 98 ++++++++++++++++++++++++++++ WEB-INF/resources/ca.lang.php | 5 ++ WEB-INF/resources/cs.lang.php | 5 ++ WEB-INF/resources/da.lang.php | 5 ++ WEB-INF/resources/de.lang.php | 5 ++ WEB-INF/resources/en.lang.php | 4 ++ WEB-INF/resources/es.lang.php | 5 ++ WEB-INF/resources/et.lang.php | 5 ++ WEB-INF/resources/fa.lang.php | 5 ++ WEB-INF/resources/fi.lang.php | 5 ++ WEB-INF/resources/fr.lang.php | 5 ++ WEB-INF/resources/gr.lang.php | 5 ++ WEB-INF/resources/he.lang.php | 5 ++ WEB-INF/resources/hu.lang.php | 5 ++ WEB-INF/resources/it.lang.php | 5 ++ WEB-INF/resources/ja.lang.php | 5 ++ WEB-INF/resources/ko.lang.php | 5 ++ WEB-INF/resources/nl.lang.php | 5 ++ WEB-INF/resources/no.lang.php | 5 ++ WEB-INF/resources/pl.lang.php | 5 ++ WEB-INF/resources/pt-br.lang.php | 5 ++ WEB-INF/resources/pt.lang.php | 5 ++ WEB-INF/resources/ro.lang.php | 5 ++ WEB-INF/resources/ru.lang.php | 4 ++ WEB-INF/resources/sk.lang.php | 5 ++ WEB-INF/resources/sl.lang.php | 5 ++ WEB-INF/resources/sr.lang.php | 5 ++ WEB-INF/resources/sv.lang.php | 5 ++ WEB-INF/resources/tr.lang.php | 5 ++ WEB-INF/resources/zh-cn.lang.php | 5 ++ WEB-INF/resources/zh-tw.lang.php | 5 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 2 +- WEB-INF/templates/work_units.tpl | 18 +++++ group_edit.php | 2 + work_units.php | 76 +++++++++++++++++++++ 36 files changed, 344 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/lib/ttConfigHelper.class.php create mode 100644 WEB-INF/templates/work_units.tpl create mode 100644 work_units.php diff --git a/WEB-INF/lib/ttConfigHelper.class.php b/WEB-INF/lib/ttConfigHelper.class.php new file mode 100644 index 000000000..95cd12186 --- /dev/null +++ b/WEB-INF/lib/ttConfigHelper.class.php @@ -0,0 +1,98 @@ +config = $config; + $this->config_array = explode(',', $this->config); + } + + // getDefinedValue determines if a value identified by name is defined. + function getDefinedValue($name) { + return in_array($name, $this->$config_array); + } + + // The getIntValue parses an integer value from the source config string. + function getIntValue($name) { + $name_with_colon = $name.':'; + $len = strlen($name_with_colon); + + foreach ($this->config_array as $unparsed_value) { + if (substr($unparsed_value, 0, $len) === $name_with_colon) { + // Found value. + $unparsed_len = strlen($unparsed_value); + $int_value = (int) substr($unparsed_value, -($unparsed_len - $len)); + return $int_value; + } + + } + return false; + } + + // The setIntValue sets an integer value into config array. + function setIntValue($name, $value) { + // Try to find and replace an already existing value. + $name_with_colon = $name.':'; + $len = strlen($name_with_colon); + + foreach ($this->config_array as $key => $unparsed_value) { + if (substr($unparsed_value, 0, $len) === $name_with_colon) { + // Found an already existing value. + // Remove value if our new value is NULL. + if ($value !== null) { + // Replace value. + $this->config_array[$key] = $name.':'.$value; + } else { + // Remove value. + unset($this->config_array[$key]); + } + $this->config = implode(',', $this->config_array); + return; + } + } + // If we get here, the value was not found, so add it. + $this->config_array[] = $name.':'.$value; + $this->config = implode(',', $this->config_array); + return; + } + + // The getConfig returns the config string. + function getConfig() { + return $this->config; + } +} diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 74f299cc8..6f499dd6f 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -544,6 +544,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 7e30f0e5e..21e16a6f9 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -558,6 +558,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index c461cc373..3b6487ed5 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -502,6 +502,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 23b13c1c8..cf112e99e 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -500,6 +500,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 55c158e82..7e57b2fe4 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -475,6 +475,10 @@ 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +'form.work_units.minutes_in_unit' => 'Minutes in unit', +'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. 'role.user.label' => 'User', 'role.user.low_case_label' => 'user', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index a665fabde..d3ab0e8c6 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -559,6 +559,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index e1aa2e384..8547caf76 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -554,6 +554,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 7d99e4d3f..9b06bb13a 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -530,6 +530,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index a7920c7fb..cf4d0b833 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -510,6 +510,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 46eb3f330..010d6792c 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -498,6 +498,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index ec6fdf8ab..42b7986d7 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -481,6 +481,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. 'role.user.label' => 'Χρήστης', 'role.user.low_case_label' => 'χρήστης', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 599826e3e..646e12a27 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -536,6 +536,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index fb64b80ce..74c3bd2f8 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -547,6 +547,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 09fe6b72a..ed335fe40 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -497,6 +497,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 6386d5f26..7902decf6 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -550,6 +550,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 4bc1ec8d2..4128eb67d 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -548,6 +548,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index db0e1907a..25b8148f7 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -474,6 +474,11 @@ 'form.swap.hint' => 'Degradeer jezelf naar een lagere rol door een rol te verruilen met iemand anders. Dit kan niet ongedaan worden gemaakt.', 'form.swap.swap_with' => 'Verruil rol met', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. 'role.user.label' => 'Gebruiker', 'role.user.low_case_label' => 'gebruiker', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index a20743158..3bd4cc24c 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -547,6 +547,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 42c75f27a..5a6150eb8 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -512,6 +512,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index dff078974..c4f9f6a7b 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -507,6 +507,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9520d3eb3..5e43040d8 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -531,6 +531,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index a86a3640d..002a38c97 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -553,6 +553,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 718f32461..804d9cd5b 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -472,6 +472,10 @@ 'form.swap.hint' => 'Уменьшите свою роль, обменявшись с другим пользователем. Роль не может восстановлена.', 'form.swap.swap_with' => 'Обменять роль с', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +'form.work_units.minutes_in_unit' => 'Минут в единице работы', +'form.work_units.1st_unit_threshold' => 'Порог для 1-й единицы', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. 'role.user.label' => 'Пользователь', 'role.user.low_case_label' => 'пользователь', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 7ed5339e7..45d16c833 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -527,6 +527,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ab858b90a..8dc9a6d05 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -527,6 +527,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 4dc9e58e3..648f26e24 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -511,6 +511,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index e47f8939d..1e0567168 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -505,6 +505,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 665b23e10..6449a7cd9 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -566,6 +566,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index eb571eadc..cbd7de326 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -534,6 +534,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 50a0960bc..6a77cff58 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -542,6 +542,11 @@ // 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', // 'form.swap.swap_with' => 'Swap roles with', +// Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. +// TODO: translate the following. +// 'form.work_units.minutes_in_unit' => 'Minutes in unit', +// 'form.work_units.1st_unit_threshold' => '1st unit threshold', + // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. // TODO: translate the following. // 'role.user.label' => 'User', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9ed4365f4..3f71f0ef2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.17.86.4222 | Copyright © Anuko | +  Anuko Time Tracker 1.17.86.4223 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index 72222c094..0aff38535 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -164,7 +164,7 @@ function handlePluginCheckboxes() { {$i18n.form.profile.uncompleted_indicators}: {$forms.groupForm.uncompleted_indicators.control} {$i18n.label.what_is_it}
{$i18n.label.bcc}: {$forms.groupForm.bcc_email.control} {$i18n.label.what_is_it}{$i18n.form.profile.allow_ip}: {$forms.groupForm.allow_ip.control} {$i18n.label.what_is_it}
{$forms.groupForm.week_view.control} {$i18n.label.configure}
{$forms.groupForm.work_units.control} {$i18n.label.configure}
- - + {/if} {/if} diff --git a/WEB-INF/templates/work_units.tpl b/WEB-INF/templates/work_units.tpl new file mode 100644 index 000000000..9c2e64da8 --- /dev/null +++ b/WEB-INF/templates/work_units.tpl @@ -0,0 +1,18 @@ +{$forms.workUnitsForm.open} +
 Anuko Time Tracker 1.17.91.4274 | Copyright © Anuko | +  Anuko Time Tracker 1.17.91.4275 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index a8f56a2d7..dd059114c 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -250,7 +250,7 @@ function handlePluginCheckboxes() { {if defined('WORK_UNITS_DEBUG')}
{$forms.groupForm.work_units.control} {$i18n.label.configure} {$i18n.label.configure}
+ + + + + + + + + + + + + + +
{$i18n.form.work_units.minutes_in_unit}:{$forms.workUnitsForm.minutes_in_unit.control} {$i18n.label.what_is_it}
{$i18n.form.work_units.1st_unit_threshold}:{$forms.workUnitsForm.1st_unit_threshold.control} {$i18n.label.what_is_it}
 
{$forms.workUnitsForm.btn_save.control}
+{$forms.weekViewForm.close} diff --git a/group_edit.php b/group_edit.php index 676a4d777..a5a85d1dd 100644 --- a/group_edit.php +++ b/group_edit.php @@ -259,6 +259,8 @@ $plugins .= ',mq'; if ($cl_week_view) $plugins .= ',wv'; + if ($cl_work_units) + $plugins .= ',wu'; // Recycle week view plugin options as they are not configured on this page. $existing_plugins = explode(',', $user->plugins); diff --git a/work_units.php b/work_units.php new file mode 100644 index 000000000..3340ec151 --- /dev/null +++ b/work_units.php @@ -0,0 +1,76 @@ +isPluginEnabled('wu')) { + header('Location: feature_disabled.php'); + exit(); +} + +$config = new ttConfigHelper($user->config); + +if ($request->isPost()) { + $cl_minutes_in_unit = $request->getParameter('minutes_in_unit'); + $cl_1st_unit_threshold = $request->getParameter('1st_unit_threshold'); +} else { + $cl_minutes_in_unit = $config->getIntValue('minutes_in_unit'); + $cl_1st_unit_threshold = $config->getIntValue('1st_unit_threshold'); +} + +$form = new Form('workUnitsForm'); +$form->addInput(array('type'=>'text', 'name'=>'minutes_in_unit', 'value'=>$cl_minutes_in_unit, 'style'=>'width:40px')); +$form->addInput(array('type'=>'text', 'name'=>'1st_unit_threshold', 'value'=>$cl_1st_unit_threshold, 'style'=>'width:40px')); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()){ + // Validate user input. + if (!ttValidInteger($cl_minutes_in_unit)) $err->add($i18n->get('error.field'), $i18n->get('form.work_units.minutes_in_unit')); + if (!ttValidInteger($cl_1st_unit_threshold, true) ||($cl_minutes_in_unit && $cl_1st_unit_threshold > $cl_minutes_in_unit)) $err->add($i18n->get('error.field'), $i18n->get('form.work_units.1st_unit_threshold')); + // Finished validating user input. + + if ($err->no()) { + $config->setIntValue('minutes_in_unit', $cl_minutes_in_unit); + $config->setIntValue('1st_unit_threshold', $cl_1st_unit_threshold); + if (!$user->updateGroup(array('config' => $config->getConfig()))) { + $err->add($i18n->get('error.db')); + } + } +} + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.work_units')); +$smarty->assign('content_page_name', 'work_units.tpl'); +$smarty->display('index.tpl'); From 6968ef66a0264c35eff9bdd8ed92af48b34b8d19 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Jul 2018 16:06:16 +0000 Subject: [PATCH 0170/1848] Initial work done on Work units plugin. Still in debug mode. --- WEB-INF/lib/ttConfigHelper.class.php | 2 +- WEB-INF/lib/ttReportHelper.class.php | 42 ++++++++++++++++++++-------- WEB-INF/lib/ttUser.class.php | 25 +++++++++++------ WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 8 ++++++ WEB-INF/templates/reports.tpl | 8 ++++++ reports.php | 4 +++ work_units.php | 4 +-- 37 files changed, 101 insertions(+), 23 deletions(-) diff --git a/WEB-INF/lib/ttConfigHelper.class.php b/WEB-INF/lib/ttConfigHelper.class.php index 95cd12186..b33734c81 100644 --- a/WEB-INF/lib/ttConfigHelper.class.php +++ b/WEB-INF/lib/ttConfigHelper.class.php @@ -44,7 +44,7 @@ function __construct($config) { // getDefinedValue determines if a value identified by name is defined. function getDefinedValue($name) { - return in_array($name, $this->$config_array); + return in_array($name, $this->config_array); } // The getIntValue parses an integer value from the source config string. diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 67f1da263..daaad46c8 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -303,6 +303,10 @@ static function getItems($bean) { if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice')) array_push($fields, 'i.name as invoice'); + // Add work units. + if ($bean->getAttribute('chunits')) + array_push($fields, "if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit)) as units"); + // Prepare sql query part for left joins. $left_joins = null; if ($bean->getAttribute('chclient') || 'client' == $group_by_option) @@ -380,6 +384,10 @@ static function getItems($bean) { if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice')) array_push($fields, 'i.name as invoice'); + // Add work units. + if ($bean->getAttribute('chunits')) + array_push($fields, 'null'); // null for work units. + // Prepare sql query part for left joins. $left_joins = null; if ($canViewReports || $isClient) @@ -769,21 +777,25 @@ static function getSubtotals($bean) { if (MODE_TIME == $user->tracking_mode) { if ($group_by_option != 'user') $left_join = 'left join tt_users u on (l.user_id = u.id)'; - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, + sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, null as expenses from tt_log l $group_join $left_join $where group by $group_field"; } else { // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, + sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l $group_join left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where group by $group_field"; } } else { - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, null as expenses from tt_log l - $group_join $where group by $group_field"; + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, + sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units, + null as expenses from tt_log l + $group_join $where group by $group_field"; } // By now we have sql for time items. @@ -813,13 +825,13 @@ static function getSubtotals($bean) { } $where = ttReportHelper::getExpenseWhere($bean); - $sql_for_expenses = "select $group_field as group_field, null as time, sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei + $sql_for_expenses = "select $group_field as group_field, null as time, null as units, sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $group_join $where"; // Add a "group by" clause if we are grouping. if ('null' != $group_field) $sql_for_expenses .= " group by $group_field"; // Create a combined query. - $sql = "select group_field, sum(time) as time, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; + $sql = "select group_field, sum(time) as time, sum(units) as units, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; } // Execute query. @@ -839,9 +851,9 @@ static function getSubtotals($bean) { $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']); } - $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time,'cost'=>$val['cost'],'expenses'=>$val['expenses']); + $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time, 'units'=> $val['units'],'cost'=>$val['cost'],'expenses'=>$val['expenses']); } else - $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time); + $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time, 'units'=> $val['units']); } return $subtotals; @@ -984,30 +996,37 @@ static function getTotals($bean) $where = ttReportHelper::getWhere($bean); + // TODO: build query in parts so the work units inclusion is conditional. + // Start with a query for time items. if ($bean->getAttribute('chcost')) { if (MODE_TIME == $user->tracking_mode) { $sql = "select sum(time_to_sec(l.duration)) as time, + sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l left join tt_users u on (l.user_id = u.id) $where"; } else { $sql = "select sum(time_to_sec(l.duration)) as time, + sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where"; } } else - $sql = "select sum(time_to_sec(l.duration)) as time, null as cost, null as expenses from tt_log l $where"; + $sql = "select sum(time_to_sec(l.duration)) as time," + ." sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units," + ." null as cost, null as expenses from tt_log l $where"; // If we have expenses, query becomes a bit more complex. if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) { $where = ttReportHelper::getExpenseWhere($bean); - $sql_for_expenses = "select null as time, sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; + $sql_for_expenses = "select null as time, null as units, sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; + // Create a combined query. - $sql = "select sum(time) as time, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t"; + $sql = "select sum(time) as time, sum(units) as units, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t"; } // Execute query. @@ -1039,6 +1058,7 @@ static function getTotals($bean) $totals['start_date'] = $period->getStartDate(); $totals['end_date'] = $period->getEndDate(); $totals['time'] = $total_time; + $totals['units'] = $val['units']; $totals['cost'] = $total_cost; $totals['expenses'] = $total_expenses; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 07d810b89..281659313 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -26,6 +26,8 @@ // | https://www.anuko.com/time_tracker/credits.htm // +----------------------------------------------------------------------+ +import('ttConfigHelper'); + class ttUser { var $login = null; // User login. var $name = null; // User name. @@ -64,6 +66,8 @@ class ttUser { var $workday_minutes = 480; // Number of work minutes in a regular day. var $rights = array(); // An array of user rights such as 'track_own_time', etc. var $is_client = false; // Whether user is a client as determined by missing 'track_own_time' right. + var $minutes_in_unit = 15; // Number of minutes in unit for Work units plugin. + var $first_unit_threshold = 0;// Threshold for 1st unit for Work units plugin. // Constructor. function __construct($login, $id = null) { @@ -123,15 +127,20 @@ function __construct($login, $id = null) { $this->custom_logo = $val['custom_logo']; $this->config = $val['config']; - $config_array = explode(',', $this->config); - + $config = new ttConfigHelper($this->config); // Set user config options. - $this->show_holidays = in_array('show_holidays', $config_array); - $this->punch_mode = in_array('punch_mode', $config_array); - $this->allow_overlap = in_array('allow_overlap', $config_array); - $this->future_entries = in_array('future_entries', $config_array); - $this->uncompleted_indicators = in_array('uncompleted_indicators', $config_array); - + $this->show_holidays = $config->getDefinedValue('show_holidays'); + $this->punch_mode = $config->getDefinedValue('punch_mode'); + $this->allow_overlap = $config->getDefinedValue('allow_overlap'); + $this->future_entries = $config->getDefinedValue('future_entries'); + $this->uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators'); + if ($this->isPluginEnabled('wu')) { + $minutes_in_unit = $config->getIntValue('minutes_in_unit'); + if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit; + $first_unit_threshold = $config->getIntValue('1st_unit_threshold'); + if ($first_unit_threshold) $this->first_unit_threshold = $first_unit_threshold; + } + // Set "on behalf" id and name. if (isset($_SESSION['behalf_id'])) { $this->behalf_id = $_SESSION['behalf_id']; diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 6f499dd6f..0e909ab89 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -244,6 +244,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 21e16a6f9..282296efd 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -254,6 +254,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 3b6487ed5..38e9f43d9 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -225,6 +225,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Login', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index cf112e99e..613bdc7c9 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -221,6 +221,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Anmelden', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 7e57b2fe4..e4abce9f5 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -212,6 +212,7 @@ 'label.week_note' => 'Week note', 'label.week_list' => 'Week list', 'label.work_units' => 'Work units', +'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Login', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index d3ab0e8c6..5a040b80b 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -247,6 +247,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Sesión iniciada', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 8547caf76..2b1bdde35 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -250,6 +250,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 9b06bb13a..c567d072c 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -237,6 +237,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'ورود', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index cf4d0b833..48b5089f1 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -229,6 +229,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Kirjautuminen', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 010d6792c..888e0ee8b 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -223,6 +223,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Connexion', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 42b7986d7..e8f03b019 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -214,6 +214,7 @@ 'label.week_list' => 'Λίστα εβδομάδων', // TODO: translate the following. // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Σύνδεση', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 646e12a27..e513d5fc9 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -247,6 +247,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'כניסה', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 74c3bd2f8..cf6b0878a 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -247,6 +247,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Bejelentkezés', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ed335fe40..ae1dae459 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -219,6 +219,7 @@ 'label.week_list' => 'Lista settimanale', // TODO: translate the following. // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 7902decf6..fa4b4bec7 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -252,6 +252,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'ログイン', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 4128eb67d..b4c79c23e 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -252,6 +252,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => '로그인', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 25b8148f7..0107a7085 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -212,6 +212,7 @@ 'label.week_list' => 'Week overzicht', // TODO: translate the following. // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Aanmelden', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 3bd4cc24c..1bfc0534b 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -250,6 +250,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Innlogging', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 5a6150eb8..ec6b78488 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -230,6 +230,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Logowanie', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index c4f9f6a7b..db390eb28 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -227,6 +227,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Login', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 5e43040d8..4b9727fa0 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -239,6 +239,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Login', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 002a38c97..b9c122019 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -251,6 +251,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 804d9cd5b..114ecc541 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -211,6 +211,7 @@ 'label.week_note' => 'Комментарий недели', 'label.week_list' => 'Список недели', 'label.work_units' => 'Единицы работы', +'label.work_units_short' => 'Единицы', // Form titles. 'title.login' => 'Вход в систему', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 45d16c833..87beb6f65 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -237,6 +237,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Prihlásenie', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 8dc9a6d05..732286b9f 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -234,6 +234,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => 'Prijava', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 1e0567168..11eff1948 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -223,6 +223,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Rubriker för formulär 'title.login' => 'Logga in', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 6449a7cd9..ee3b4456a 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -258,6 +258,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. // Form titles. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index cbd7de326..1cb84d714 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -241,6 +241,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => '登录', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 6a77cff58..fc3ec9957 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -248,6 +248,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +// 'label.work_units_short' => 'Units', // Form titles. 'title.login' => '登錄', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3f71f0ef2..3ad220b3d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chcost')}{/if} {foreach $subtotals as $subtotal} {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chcost')}{/if} {/foreach} @@ -30,6 +32,7 @@ {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chcost')}{/if} {else} @@ -44,6 +47,7 @@ {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote')}{/if} {if $bean->getAttribute('chcost')}{/if} {if $bean->getAttribute('chpaid')}{/if} @@ -66,6 +70,7 @@ {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote')}{/if} {if $bean->getAttribute('chcost')}{/if} {if $bean->getAttribute('chpaid')}{/if} @@ -91,6 +96,7 @@ {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote')}{/if} {if $bean->getAttribute('chcost')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote')}{/if} {if $bean->getAttribute('chcost')}{/if} {if $bean->getAttribute('chpaid')}{/if} @@ -136,6 +143,7 @@ {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote')}{/if} {if $bean->getAttribute('chcost')}{/if} {if $bean->getAttribute('chpaid')}{/if} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index a70a3f072..b57ba8410 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -284,6 +284,14 @@ function handleCheckboxes() { {/if} +{if $user->isPluginEnabled('wu')} + + + + + + +{/if}
 Anuko Time Tracker 1.17.91.4275 | Copyright © Anuko | +  Anuko Time Tracker 1.17.92.4276 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index ddea591af..55438428c 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -16,12 +16,14 @@
{$group_by_header|escape}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.cost}
{if $subtotal['name']}{$subtotal['name']|escape}{else} {/if}{$subtotal['time']}{$subtotal['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotal['cost']}{else}{$subtotal['expenses']}{/if}
{$i18n.label.total}{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.note}{$i18n.label.cost}{$i18n.label.paid}{$subtotals[$prev_grouped_by]['time']}{$subtotals[$prev_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}{$item.start}{$item.finish}{$item.duration}{$item.units}{$item.note|escape}{if $user->can('manage_invoices') || $user->isClient()}{$item.cost}{else}{$item.expense}{/if}{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{/if} @@ -116,6 +122,7 @@ {if $bean->getAttribute('chstart')}{$subtotals[$cur_grouped_by]['time']}{$subtotals[$cur_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$cur_grouped_by]['cost']}{else}{$subtotals[$cur_grouped_by]['expenses']}{/if}{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
- - {if defined('WORK_UNITS_DEBUG')} - {/if} {/if} diff --git a/group_edit.php b/group_edit.php index a5a85d1dd..8c7012a50 100644 --- a/group_edit.php +++ b/group_edit.php @@ -209,9 +209,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'locking','value'=>$cl_locking,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'checkbox','name'=>'quotas','value'=>$cl_quotas,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'checkbox','name'=>'week_view','value'=>$cl_week_view,'onchange'=>'handlePluginCheckboxes()')); -if (defined('WORK_UNITS_DEBUG')) { - $form->addInput(array('type'=>'checkbox','name'=>'work_units','value'=>$cl_work_units,'onchange'=>'handlePluginCheckboxes()')); -} +$form->addInput(array('type'=>'checkbox','name'=>'work_units','value'=>$cl_work_units,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($user->can('delete_group')) $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('button.delete'))); From a536a682560e3f5d21c960994ebe410e5aef5931 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Jul 2018 18:29:32 +0000 Subject: [PATCH 0172/1848] Fixed export to CSV and XML to include work units. --- WEB-INF/templates/footer.tpl | 2 +- tofile.php | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 95dec6289..3d617784a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.17.92.4276 | Copyright © Anuko | +  Anuko Time Tracker 1.17.92.4277 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index dd059114c..db66201c5 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -247,12 +247,10 @@ function handlePluginCheckboxes() { {$forms.groupForm.week_view.control} {$i18n.label.configure}
{$forms.groupForm.work_units.control} {$i18n.label.configure}
-
 Anuko Time Tracker 1.17.92.4277 | Copyright © Anuko | +  Anuko Time Tracker 1.17.92.4278 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/tofile.php b/tofile.php index 909fdd3eb..a06a98667 100644 --- a/tofile.php +++ b/tofile.php @@ -95,6 +95,9 @@ $val = time_to_decimal($val); print "\t\n"; } + if ($bean->getAttribute('chunits')) { + print "\t\n"; + } if ($bean->getAttribute('chcost')) { print "\tcan('manage_invoices') || $user->isClient()) @@ -124,6 +127,7 @@ $duration = time_to_decimal($duration); print "\t\n"; } + if ($bean->getAttribute('chunits')) print "\t\n"; if ($bean->getAttribute('chnote')) print "\t\n"; if ($bean->getAttribute('chcost')) { print "\tgetAttribute('chduration')) print ',"'.$i18n->get('label.duration').'"'; + if ($bean->getAttribute('chunits')) print ',"'.$i18n->get('label.work_units_short').'"'; if ($bean->getAttribute('chcost')) print ',"'.$i18n->get('label.cost').'"'; print "\n"; @@ -183,6 +188,7 @@ $val = time_to_decimal($val); print ',"'.$val.'"'; } + if ($bean->getAttribute('chunits')) print ',"'.$subtotal['units'].'"'; if ($bean->getAttribute('chcost')) { if ($user->can('manage_invoices') || $user->isClient()) print ',"'.$subtotal['cost'].'"'; @@ -202,6 +208,7 @@ if ($bean->getAttribute('chstart')) print ',"'.$i18n->get('label.start').'"'; if ($bean->getAttribute('chfinish')) print ',"'.$i18n->get('label.finish').'"'; if ($bean->getAttribute('chduration')) print ',"'.$i18n->get('label.duration').'"'; + if ($bean->getAttribute('chunits')) print ',"'.$i18n->get('label.work_units_short').'"'; if ($bean->getAttribute('chnote')) print ',"'.$i18n->get('label.note').'"'; if ($bean->getAttribute('chcost')) print ',"'.$i18n->get('label.cost').'"'; if ($bean->getAttribute('chpaid')) print ',"'.$i18n->get('label.paid').'"'; @@ -225,6 +232,7 @@ $val = time_to_decimal($val); print ',"'.$val.'"'; } + if ($bean->getAttribute('chunits')) print ',"'.$item['units'].'"'; if ($bean->getAttribute('chnote')) print ',"'.str_replace('"','""',$item['note']).'"'; if ($bean->getAttribute('chcost')) { if ($user->can('manage_invoices') || $user->isClient()) From e171b4e97c8dd9322362d88d6722551f7c44f6cf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Jul 2018 18:44:26 +0000 Subject: [PATCH 0173/1848] Fixed export to PDF to include work units. --- WEB-INF/templates/footer.tpl | 2 +- topdf.php | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3d617784a..d7c29536c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- "; $html .= ''; if ($bean->getAttribute('chduration')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chunits')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chcost')) { $colspan++; $html .= "'; } $html .= ''; $html .= ''; @@ -117,6 +118,7 @@ $html .= ''; $html .= ''; if ($bean->getAttribute('chduration')) $html .= "'; + if ($bean->getAttribute('chunits')) $html .= "'; if ($bean->getAttribute('chcost')) { $html .= ""; $html .= ''; if ($bean->getAttribute('chduration')) $html .= "'; + if ($bean->getAttribute('chunits')) $html .= "'; if ($bean->getAttribute('chcost')) { $html .= "'; } if ($bean->getAttribute('chfinish')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chduration')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chunits')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chnote')) { $colspan++; $html .= ''; } if ($bean->getAttribute('chcost')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chpaid')) { $colspan++; $html .= "'; } @@ -202,6 +206,7 @@ if ($bean->getAttribute('chstart')) $html .= ''; if ($bean->getAttribute('chfinish')) $html .= ''; if ($bean->getAttribute('chduration')) $html .= "'; + if ($bean->getAttribute('chunits')) $html .= "'; if ($bean->getAttribute('chnote')) $html .= ''; if ($bean->getAttribute('chcost')) { $html .= "'; if ($bean->getAttribute('chfinish')) $html .= "'; if ($bean->getAttribute('chduration')) $html .= "'; + if ($bean->getAttribute('chunits')) $html .= "'; if ($bean->getAttribute('chnote')) $html .= ''; if ($bean->getAttribute('chcost')) { $html .= "'; if ($bean->getAttribute('chfinish')) $html .= ''; if ($bean->getAttribute('chduration')) $html .= "'; + if ($bean->getAttribute('chunits')) $html .= "'; if ($bean->getAttribute('chnote')) $html .= ''; if ($bean->getAttribute('chcost')) { $html .= "'; if ($bean->getAttribute('chfinish')) $html .= ''; if ($bean->getAttribute('chduration')) $html .= "'; + if ($bean->getAttribute('chunits')) $html .= "'; if ($bean->getAttribute('chnote')) $html .= ''; if ($bean->getAttribute('chcost')) { $html .= "
 Anuko Time Tracker 1.17.92.4278 | Copyright © Anuko | +  Anuko Time Tracker 1.17.92.4279 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/topdf.php b/topdf.php index eb09bc452..b7ac19d52 100644 --- a/topdf.php +++ b/topdf.php @@ -109,6 +109,7 @@ $html .= "
'.htmlspecialchars($group_by_header).'".$i18n->get('label.duration').'".$i18n->get('label.work_units_short').'".$i18n->get('label.cost').'
'.htmlspecialchars($subtotal['name']).'".$subtotal['time'].'".$subtotal['units'].'"; if ($user->can('manage_invoices') || $user->isClient()) @@ -132,6 +134,7 @@ $html .= "
'.$i18n->get('label.total').'".$totals['time'].'".$totals['units'].'"; $html .= htmlspecialchars($user->currency).' '; @@ -158,6 +161,7 @@ if ($bean->getAttribute('chstart')) { $colspan++; $html .= "".$i18n->get('label.start').'".$i18n->get('label.finish').'".$i18n->get('label.duration').'".$i18n->get('label.work_units_short').''.$i18n->get('label.note').'".$i18n->get('label.cost').'".$i18n->get('label.paid').'".$subtotals[$prev_grouped_by]['time'].'".$subtotals[$prev_grouped_by]['units'].'"; @@ -231,6 +236,7 @@ if ($bean->getAttribute('chstart')) $html .= "".$item['start'].'".$item['finish'].'".$item['duration'].'".$item['units'].''.htmlspecialchars($item['note']).'"; @@ -289,6 +295,7 @@ if ($bean->getAttribute('chstart')) $html .= '".$subtotals[$prev_grouped_by]['time'].'".$subtotals[$prev_grouped_by]['units'].'"; @@ -316,6 +323,7 @@ if ($bean->getAttribute('chstart')) $html .= '".$totals['time'].'".$totals['units'].'".htmlspecialchars($user->currency).' '; From c5c7ed2be4f41e34e63ee90158f499a6f76a76c1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Jul 2018 20:29:13 +0000 Subject: [PATCH 0174/1848] Adjusted Work units plugin to count only bullable units. --- WEB-INF/lib/ttReportHelper.class.php | 14 +++++++------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index daaad46c8..170dc2a9f 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -305,7 +305,7 @@ static function getItems($bean) { // Add work units. if ($bean->getAttribute('chunits')) - array_push($fields, "if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit)) as units"); + array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); // Prepare sql query part for left joins. $left_joins = null; @@ -778,14 +778,14 @@ static function getSubtotals($bean) { if ($group_by_option != 'user') $left_join = 'left join tt_users u on (l.user_id = u.id)'; $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, - sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, null as expenses from tt_log l $group_join $left_join $where group by $group_field"; } else { // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, - sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l $group_join @@ -793,7 +793,7 @@ static function getSubtotals($bean) { } } else { $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, - sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, null as expenses from tt_log l $group_join $where group by $group_field"; } @@ -1002,14 +1002,14 @@ static function getTotals($bean) if ($bean->getAttribute('chcost')) { if (MODE_TIME == $user->tracking_mode) { $sql = "select sum(time_to_sec(l.duration)) as time, - sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l left join tt_users u on (l.user_id = u.id) $where"; } else { $sql = "select sum(time_to_sec(l.duration)) as time, - sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l @@ -1017,7 +1017,7 @@ static function getTotals($bean) } } else $sql = "select sum(time_to_sec(l.duration)) as time," - ." sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units," + ." sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units," ." null as cost, null as expenses from tt_log l $where"; // If we have expenses, query becomes a bit more complex. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d7c29536c..c12472533 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.92.4279 | Copyright © Anuko | +  Anuko Time Tracker 1.17.92.4280 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 7a58c9da8ffac9b0832a047fe4ef1b93618179f0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 22 Jul 2018 14:01:07 +0000 Subject: [PATCH 0175/1848] Enhanced ttConfigHelper class a bit. --- WEB-INF/lib/ttConfigHelper.class.php | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttConfigHelper.class.php b/WEB-INF/lib/ttConfigHelper.class.php index b33734c81..13a2a8511 100644 --- a/WEB-INF/lib/ttConfigHelper.class.php +++ b/WEB-INF/lib/ttConfigHelper.class.php @@ -47,6 +47,28 @@ function getDefinedValue($name) { return in_array($name, $this->config_array); } + // setDefinedValue either sets or deletes a defined value identified by name. + function setDefinedValue($name, $set = true) { + if ($set) { + // Setting part. + if (!$this->getDefinedValue($name)) { + $this->config_array[] = $name; + $this->config = implode(',', $this->config_array); + return; + } + + } else { + // Deleting part. + foreach ($this->config_array as $key => $value) { + if ($value === $name) { + unset($this->config_array[$key]); + $this->config = implode(',', $this->config_array); + return; + } + } + } + } + // The getIntValue parses an integer value from the source config string. function getIntValue($name) { $name_with_colon = $name.':'; @@ -73,12 +95,11 @@ function setIntValue($name, $value) { foreach ($this->config_array as $key => $unparsed_value) { if (substr($unparsed_value, 0, $len) === $name_with_colon) { // Found an already existing value. - // Remove value if our new value is NULL. if ($value !== null) { // Replace value. $this->config_array[$key] = $name.':'.$value; } else { - // Remove value. + // Remove value if our new value is NULL. unset($this->config_array[$key]); } $this->config = implode(',', $this->config_array); From a9d5914d51687f6f760b9c0e72fc4e99101f2830 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 22 Jul 2018 15:36:43 +0000 Subject: [PATCH 0176/1848] Introduced show_work_units field in tt_fav_reports table. --- WEB-INF/lib/ttConfigHelper.class.php | 1 - WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 ++- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttConfigHelper.class.php b/WEB-INF/lib/ttConfigHelper.class.php index 13a2a8511..20af19ad0 100644 --- a/WEB-INF/lib/ttConfigHelper.class.php +++ b/WEB-INF/lib/ttConfigHelper.class.php @@ -56,7 +56,6 @@ function setDefinedValue($name, $set = true) { $this->config = implode(',', $this->config_array); return; } - } else { // Deleting part. foreach ($this->config_array as $key => $value) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c12472533..f33073f1f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.92.4280 | Copyright © Anuko | +  Anuko Time Tracker 1.17.92.4281 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 31d5fbf10..b49824987 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11788"]) { + if ($_POST["convert11744to11792"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -899,6 +899,8 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.17.87', modified = now() where param_name = 'version_db' and param_value = '1.17.86'"); setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.87') set rights = replace(rights, 'manage_subgroups', 'manage_subgroups,delete_group') where rank = 512"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.88', modified = now() where param_name = 'version_db' and param_value = '1.17.87'"); + setChange("ALTER TABLE `tt_fav_reports` ADD `show_work_units` tinyint(4) NOT NULL DEFAULT '0' AFTER `show_custom_field_1`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.92', modified = now() where param_name = 'version_db' and param_value = '1.17.88'"); } if ($_POST["cleanup"]) { @@ -944,7 +946,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.88) + Create database structure (v1.17.92)
(applies only to new installations, do not execute when updating)
@@ -984,8 +986,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.88)Update database structure (v1.17.44 to v1.17.92)
diff --git a/mysql.sql b/mysql.sql index 37ad65e76..267d842dc 100644 --- a/mysql.sql +++ b/mysql.sql @@ -265,6 +265,7 @@ CREATE TABLE `tt_fav_reports` ( `show_end` tinyint(4) NOT NULL default 0, # whether to show end field `show_note` tinyint(4) NOT NULL default 0, # whether to show note column `show_custom_field_1` tinyint(4) NOT NULL default 0, # whether to show custom field 1 + `show_work_units` tinyint(4) NOT NULL default 0, # whether to show work units `show_totals_only` tinyint(4) NOT NULL default 0, # whether to show totals only `group_by` varchar(20) default NULL, # group by field `status` tinyint(4) default 1, # favorite report status @@ -449,4 +450,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.88', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.92', now()); # TODO: change when structure changes. From 7b81d0e15ca73f1ee3558f4b042c513933d8735a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 22 Jul 2018 15:58:05 +0000 Subject: [PATCH 0177/1848] Added handling of show work units in fav reports and export / import. --- WEB-INF/lib/ttExportHelper.class.php | 1 + WEB-INF/lib/ttFavReportHelper.class.php | 9 +++++++-- WEB-INF/lib/ttImportHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttExportHelper.class.php b/WEB-INF/lib/ttExportHelper.class.php index ca202ad78..d0b533952 100644 --- a/WEB-INF/lib/ttExportHelper.class.php +++ b/WEB-INF/lib/ttExportHelper.class.php @@ -303,6 +303,7 @@ function createDataFile($compress = false) { " show_end=\"".$fav_report['show_end']."\"". " show_note=\"".$fav_report['show_note']."\"". " show_custom_field_1=\"".$fav_report['show_custom_field_1']."\"". + " show_work_units=\"".$fav_report['show_work_units']."\"". " group_by=\"".$fav_report['group_by']."\"". " show_totals_only=\"".$fav_report['show_totals_only']."\">\n"); fwrite($file, " \n"); diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 60acc12c9..006d55676 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -83,7 +83,7 @@ static function insertReport($fields) { billable, invoice, paid_status, users, period, period_start, period_end, show_client, show_invoice, show_paid, show_ip, show_project, show_start, show_duration, show_cost, - show_task, show_end, show_note, show_custom_field_1, + show_task, show_end, show_note, show_custom_field_1, show_work_units, group_by, show_totals_only) values(". $mdb2->quote($fields['name']).", ".$fields['user_id'].", ". @@ -95,7 +95,7 @@ static function insertReport($fields) { $mdb2->quote($fields['from']).", ".$mdb2->quote($fields['to']).", ". $fields['chclient'].", ".$fields['chinvoice'].", ".$fields['chpaid'].", ".$fields['chip'].", ". $fields['chproject'].", ".$fields['chstart'].", ".$fields['chduration'].", ".$fields['chcost'].", ". - $fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ".$fields['chcf_1'].", ". + $fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ".$fields['chcf_1'].", ".$fields['chunits'].", ". $mdb2->quote($fields['group_by']).", ".$fields['chtotalsonly'].")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) @@ -138,6 +138,7 @@ function updateReport($fields) { "show_end = ".$fields['chfinish'].", ". "show_note = ".$fields['chnote'].", ". "show_custom_field_1 = ".$fields['chcf_1'].", ". + "show_work_units = ".$fields['chunits'].", ". "group_by = ".$mdb2->quote($fields['group_by']).", ". "show_totals_only = ".$fields['chtotalsonly']. " where id = ".$fields['id']; @@ -166,6 +167,7 @@ static function saveReport($user_id, $bean) { if (!$bean->getAttribute('chfinish')) $bean->setAttribute('chfinish', 0); if (!$bean->getAttribute('chnote')) $bean->setAttribute('chnote', 0); if (!$bean->getAttribute('chcf_1')) $bean->setAttribute('chcf_1', 0); + if (!$bean->getAttribute('chunits')) $bean->setAttribute('chunits', 0); if (!$bean->getAttribute('chtotalsonly')) $bean->setAttribute('chtotalsonly', 0); if ($bean->getAttribute('users') && is_array($bean->getAttribute('users'))) { @@ -221,6 +223,7 @@ static function saveReport($user_id, $bean) { 'chfinish'=>$bean->getAttribute('chfinish'), 'chnote'=>$bean->getAttribute('chnote'), 'chcf_1'=>$bean->getAttribute('chcf_1'), + 'chunits'=>$bean->getAttribute('chunits'), 'group_by'=>$bean->getAttribute('group_by'), 'chtotalsonly'=>$bean->getAttribute('chtotalsonly')); @@ -292,6 +295,7 @@ static function loadReport($user_id, &$bean) { $bean->setAttribute('chfinish', $val['show_end']); $bean->setAttribute('chnote', $val['show_note']); $bean->setAttribute('chcf_1', $val['show_custom_field_1']); + $bean->setAttribute('chunits', $val['show_work_units']); $bean->setAttribute('group_by', $val['group_by']); $bean->setAttribute('chtotalsonly', $val['show_totals_only']); $bean->setAttribute('new_fav_report', $val['name']); @@ -316,6 +320,7 @@ static function loadReport($user_id, &$bean) { 'chfinish'=>'1', 'chnote'=>'1', 'chcf_1'=>'', + 'chunits'=>'', 'group_by'=>'', 'chtotalsonly'=>'', 'new_fav_report'=>'')); diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index dfa3be597..7b68ba7ce 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -332,6 +332,7 @@ function endElement($parser, $name) { 'chfinish' => (int) $this->currentElement['SHOW_END'], 'chnote' => (int) $this->currentElement['SHOW_NOTE'], 'chcf_1' => (int) $this->currentElement['SHOW_CUSTOM_FIELD_1'], + 'chunits' => (int) $this->currentElement['SHOW_WORK_UNITS'], 'group_by' => $this->currentElement['GROUP_BY'], 'chtotalsonly' => (int) $this->currentElement['SHOW_TOTALS_ONLY'])); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f33073f1f..1b04936fb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- '; if ($bean->getAttribute('chduration')) $body .= ''; + if ($bean->getAttribute('chunits')) + $body .= ''; if ($bean->getAttribute('chcost')) $body .= ''; $body .= ''; @@ -1240,6 +1247,11 @@ static function prepareReportBody($bean, $comment) if ($subtotal['time'] <> '0:00') $body .= $subtotal['time']; $body .= ''; } + if ($bean->getAttribute('chunits')) { + $body .= ''; + } if ($bean->getAttribute('chcost')) { $body .= ''; } + if ($bean->getAttribute('chunits')) { + $body .= ''; + } if ($bean->getAttribute('chcost')) { $body .= ''; if ($bean->getAttribute('chduration')) $body .= ''; + if ($bean->getAttribute('chunits')) + $body .= ''; if ($bean->getAttribute('chnote')) $body .= ''; if ($bean->getAttribute('chcost')) @@ -1331,6 +1350,7 @@ static function prepareReportBody($bean, $comment) if ($bean->getAttribute('chstart')) $body .= ''; if ($bean->getAttribute('chfinish')) $body .= ''; if ($bean->getAttribute('chduration')) $body .= ''; + if ($bean->getAttribute('chunits')) $body .= ''; if ($bean->getAttribute('chnote')) $body .= ''; if ($bean->getAttribute('chcost')) { $body .= ''; if ($bean->getAttribute('chduration')) $body .= ''; + if ($bean->getAttribute('chunits')) + $body .= ''; if ($bean->getAttribute('chnote')) $body .= ''; if ($bean->getAttribute('chcost')) @@ -1404,6 +1426,7 @@ static function prepareReportBody($bean, $comment) if ($bean->getAttribute('chstart')) $body .= ''; if ($bean->getAttribute('chfinish')) $body .= ''; if ($bean->getAttribute('chduration')) $body .= ''; + if ($bean->getAttribute('chunits')) $body .= ''; if ($bean->getAttribute('chnote')) $body .= ''; if ($bean->getAttribute('chcost')) { $body .= ''; if ($bean->getAttribute('chfinish')) $body .= ''; if ($bean->getAttribute('chduration')) $body .= ''; + if ($bean->getAttribute('chunits')) $body .= ''; if ($bean->getAttribute('chnote')) $body .= ''; if ($bean->getAttribute('chcost')) { $body .= '
 Anuko Time Tracker 1.17.92.4281 | Copyright © Anuko | +  Anuko Time Tracker 1.17.92.4282 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From de20a2009639bd1064c8d2b61a79d449c352409c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 22 Jul 2018 17:31:54 +0000 Subject: [PATCH 0178/1848] Added work units in output for emailed reports. --- WEB-INF/lib/ttReportHelper.class.php | 30 +++++++++++++++++++++++++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 170dc2a9f..224d7f177 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1078,26 +1078,30 @@ static function getFavTotals($report) if ($report['show_cost']) { if (MODE_TIME == $user->tracking_mode) { $sql = "select sum(time_to_sec(l.duration)) as time, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l left join tt_users u on (l.user_id = u.id) $where"; } else { $sql = "select sum(time_to_sec(l.duration)) as time, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where"; } } else - $sql = "select sum(time_to_sec(l.duration)) as time, null as cost, null as expenses from tt_log l $where"; + $sql = "select sum(time_to_sec(l.duration)) as time, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, + null as cost, null as expenses from tt_log l $where"; // If we have expenses, query becomes a bit more complex. if ($report['show_cost'] && $user->isPluginEnabled('ex')) { $where = ttReportHelper::getFavExpenseWhere($report); - $sql_for_expenses = "select null as time, sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; + $sql_for_expenses = "select null as time, null as units, sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; // Create a combined query. - $sql = "select sum(time) as time, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t"; + $sql = "select sum(time) as time, sum(units) as units, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t"; } // Execute query. @@ -1129,6 +1133,7 @@ static function getFavTotals($report) $totals['start_date'] = $period->getStartDate(); $totals['end_date'] = $period->getEndDate(); $totals['time'] = $total_time; + $totals['units'] = $val['units']; $totals['cost'] = $total_cost; $totals['expenses'] = $total_expenses; @@ -1229,6 +1234,8 @@ static function prepareReportBody($bean, $comment) $body .= ''.$group_by_header.''.$i18n->get('label.duration').''.$i18n->get('label.work_units_short').''.$i18n->get('label.cost').'
'; + $body .= $subtotal['units']; + $body .= ''; $body .= ($canViewReports || $isClient) ? $subtotal['cost'] : $subtotal['expenses']; @@ -1257,6 +1269,11 @@ static function prepareReportBody($bean, $comment) if ($totals['time'] <> '0:00') $body .= $totals['time']; $body .= ''; + $body .= $totals['units']; + $body .= ''.htmlspecialchars($user->currency).' '; $body .= ($canViewReports || $isClient) ? $totals['cost'] : $totals['expenses']; @@ -1288,6 +1305,8 @@ static function prepareReportBody($bean, $comment) $body .= ''.$i18n->get('label.finish').''.$i18n->get('label.duration').''.$i18n->get('label.work_units_short').''.$i18n->get('label.note').''.$subtotals[$prev_grouped_by]['time'].''.$subtotals[$prev_grouped_by]['units'].''; @@ -1367,6 +1387,8 @@ static function prepareReportBody($bean, $comment) $body .= ''.$record['finish'].''.$record['duration'].''.$record['units'].''.htmlspecialchars($record['note']).''.$subtotals[$cur_grouped_by]['time'].''.$subtotals[$cur_grouped_by]['units'].''; @@ -1428,6 +1451,7 @@ static function prepareReportBody($bean, $comment) if ($bean->getAttribute('chstart')) $body .= ''.$totals['time'].''.$totals['units'].''.htmlspecialchars($user->currency).' '; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1b04936fb..8f0779f2d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- '; if ($report['show_duration']) $body .= ''; + if ($report['show_work_units']) + $body .= ''; if ($report['show_cost']) $body .= ''; $body .= ''; @@ -1560,6 +1571,11 @@ static function prepareFavReportBody($report) if ($subtotal['time'] <> '0:00') $body .= $subtotal['time']; $body .= ''; } + if ($report['show_work_units']) { + $body .= ''; + } if ($report['show_cost']) { $body .= ''; } + if ($report['show_work_units']) { + $body .= ''; + } if ($report['show_cost']) { $body .= ''; if ($report['show_duration']) $body .= ''; + if ($report['show_work_units']) + $body .= ''; if ($report['show_note']) $body .= ''; if ($report['show_cost']) @@ -1651,6 +1674,7 @@ static function prepareFavReportBody($report) if ($report['show_start']) $body .= ''; if ($report['show_end']) $body .= ''; if ($report['show_duration']) $body .= ''; + if ($report['show_work_units']) $body .= ''; if ($report['show_note']) $body .= ''; if ($report['show_cost']) { $body .= ''; if ($report['show_duration']) $body .= ''; + if ($report['show_work_units']) + $body .= ''; if ($report['show_note']) $body .= ''; if ($report['show_cost']) @@ -1724,6 +1750,7 @@ static function prepareFavReportBody($report) if ($report['show_start']) $body .= ''; if ($report['show_end']) $body .= ''; if ($report['show_duration']) $body .= ''; + if ($report['show_work_units']) $body .= ''; if ($report['show_note']) $body .= ''; if ($report['show_cost']) { $body .= ''; if ($report['show_end']) $body .= ''; if ($report['show_duration']) $body .= ''; + if ($report['show_work_units']) $body .= ''; if ($report['show_note']) $body .= ''; if ($report['show_cost']) { $body .= ' + + + + diff --git a/work_units.php b/work_units.php index dd01488a7..32b2616b8 100644 --- a/work_units.php +++ b/work_units.php @@ -53,6 +53,7 @@ $form = new Form('workUnitsForm'); $form->addInput(array('type'=>'text', 'name'=>'minutes_in_unit', 'value'=>$cl_minutes_in_unit, 'style'=>'width:40px')); $form->addInput(array('type'=>'text', 'name'=>'1st_unit_threshold', 'value'=>$cl_1st_unit_threshold, 'style'=>'width:40px')); +$form->addInput(array('type'=>'checkbox','name'=>'totals_only','value'=>$cl_totals_only)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()){ From 6dbcf228dba9d1175ffd0c177f0739c58ce0f199 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Jul 2018 01:25:03 +0000 Subject: [PATCH 0181/1848] Introduced totals only option for work units. --- WEB-INF/lib/ttReportHelper.class.php | 203 +++++++++++++++++---------- WEB-INF/lib/ttUser.class.php | 2 + WEB-INF/templates/footer.tpl | 2 +- group_edit.php | 23 ++- work_units.php | 3 + 5 files changed, 146 insertions(+), 87 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 0900f7f9d..4da47ec07 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -277,8 +277,12 @@ static function getItems($bean) { if ($bean->getAttribute('chduration')) array_push($fields, "TIME_FORMAT(l.duration, '%k:%i') as duration"); // Add work units. - if ($bean->getAttribute('chunits')) - array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); + if ($bean->getAttribute('chunits')) { + if ($user->unit_totals_only) + array_push($fields, "null as units"); + else + array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); + } // Add note. if ($bean->getAttribute('chnote')) array_push($fields, 'l.comment as note'); @@ -363,6 +367,9 @@ static function getItems($bean) { array_push($fields, 'null'); // null for finish. if ($bean->getAttribute('chduration')) array_push($fields, 'null'); // null for duration. + // Add work units. + if ($bean->getAttribute('chunits')) + array_push($fields, 'null as units'); // null for work units. // Use the note field to print item name. if ($bean->getAttribute('chnote')) array_push($fields, 'ei.name as note'); @@ -383,10 +390,6 @@ static function getItems($bean) { if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice')) array_push($fields, 'i.name as invoice'); - // Add work units. - if ($bean->getAttribute('chunits')) - array_push($fields, 'null'); // null for work units. - // Prepare sql query part for left joins. $left_joins = null; if ($canViewReports || $isClient) @@ -549,8 +552,12 @@ static function getFavItems($report) { if ($report['show_duration']) array_push($fields, "TIME_FORMAT(l.duration, '%k:%i') as duration"); // Add work units. - if ($report['show_work_units']) - array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); + if ($report['show_work_units']) { + if ($user->unit_totals_only) + array_push($fields, "null as units"); + else + array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); + } // Add note. if ($report['show_note']) @@ -636,7 +643,7 @@ static function getFavItems($report) { if ($report['show_duration']) array_push($fields, 'null'); // null for duration. if ($report['show_work_units']) - array_push($fields, 'null'); // null for work units. + array_push($fields, 'null as units'); // null for work units. // Use the note field to print item name. if ($report['show_note']) array_push($fields, 'ei.name as note'); @@ -782,24 +789,39 @@ static function getSubtotals($bean) { if (MODE_TIME == $user->tracking_mode) { if ($group_by_option != 'user') $left_join = 'left join tt_users u on (l.user_id = u.id)'; - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + if ($bean->getAttribute('chunits')) { + if ($user->unit_totals_only) + $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + else + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + } + $sql .= ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, null as expenses from tt_log l $group_join $left_join $where group by $group_field"; } else { // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + if ($bean->getAttribute('chunits')) { + if ($user->unit_totals_only) + $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + else + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + } + $sql .= ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l $group_join left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where group by $group_field"; } } else { - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - null as expenses from tt_log l + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + if ($bean->getAttribute('chunits')) { + if ($user->unit_totals_only) + $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + else + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + } + $sql .= ", null as expenses from tt_log l $group_join $where group by $group_field"; } // By now we have sql for time items. @@ -830,13 +852,17 @@ static function getSubtotals($bean) { } $where = ttReportHelper::getExpenseWhere($bean); - $sql_for_expenses = "select $group_field as group_field, null as time, null as units, sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei - $group_join $where"; + $sql_for_expenses = "select $group_field as group_field, null as time"; + if ($bean->getAttribute('chunits')) $sql_for_expenses .= ", null as units"; + $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $group_join $where"; // Add a "group by" clause if we are grouping. if ('null' != $group_field) $sql_for_expenses .= " group by $group_field"; // Create a combined query. - $sql = "select group_field, sum(time) as time, sum(units) as units, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; + $combined = "select group_field, sum(time) as time"; + if ($bean->getAttribute('chunits')) $combined .= ", sum(units) as units"; + $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; + $sql = $combined; } // Execute query. @@ -914,24 +940,40 @@ static function getFavSubtotals($report) { if (MODE_TIME == $user->tracking_mode) { if ($group_by_option != 'user') $left_join = 'left join tt_users u on (l.user_id = u.id)'; - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + if ($report['show_work_units']) { + if ($user->unit_totals_only) + $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + else + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + } + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + $sql .= ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, null as expenses from tt_log l $group_join $left_join $where group by $group_field"; } else { // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + if ($report['show_work_units']) { + if ($user->unit_totals_only) + $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + else + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + } + $sql .= ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l $group_join left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where group by $group_field"; } } else { - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - null as expenses from tt_log l + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + if ($report['show_work_units']) { + if ($user->unit_totals_only) + $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + else + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + } + $sql .= ", null as expenses from tt_log l $group_join $where group by $group_field"; } // By now we have sql for time items. @@ -962,13 +1004,17 @@ static function getFavSubtotals($report) { } $where = ttReportHelper::getFavExpenseWhere($report); - $sql_for_expenses = "select $group_field as group_field, null as time, null as units, sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei - $group_join $where"; + $sql_for_expenses = "select $group_field as group_field, null as time"; + if ($report['show_work_units']) $sql_for_expenses .= ", null as units"; + $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $group_join $where"; // Add a "group by" clause if we are grouping. if ('null' != $group_field) $sql_for_expenses .= " group by $group_field"; // Create a combined query. - $sql = "select group_field, sum(time) as time, sum(units) as units, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; + $combined = "select group_field, sum(time) as time"; + if ($report['show_work_units']) $combined .= ", sum(units) as units"; + $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; + $sql = $combined; } // Execute query. @@ -1005,37 +1051,41 @@ static function getTotals($bean) $where = ttReportHelper::getWhere($bean); - // TODO: build query in parts so the work units inclusion is conditional. - - // Start with a query for time items. + // Prepare parts. + $time_part = "sum(time_to_sec(l.duration)) as time"; + if ($bean->getAttribute('chunits')) { + $units_part = $user->unit_totals_only ? ", null as units" : ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + } + if ($bean->getAttribute('chcost')) { + if (MODE_TIME == $user->tracking_mode) + $cost_part = ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses"; + else + $cost_part = ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses"; + } else { + $cost_part = ", null as cost, null as expenses"; + } if ($bean->getAttribute('chcost')) { if (MODE_TIME == $user->tracking_mode) { - $sql = "select sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, - null as expenses - from tt_log l - left join tt_users u on (l.user_id = u.id) $where"; + $left_joins = "left join tt_users u on (l.user_id = u.id)"; } else { - $sql = "select sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, - null as expenses - from tt_log l - left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where"; + $left_joins = "left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; } - } else - $sql = "select sum(time_to_sec(l.duration)) as time," - ." sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units," - ." null as cost, null as expenses from tt_log l $where"; + } + // Prepare a query for time items. + $sql = "select $time_part $units_part $cost_part from tt_log l $left_joins $where"; // If we have expenses, query becomes a bit more complex. if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) { $where = ttReportHelper::getExpenseWhere($bean); - $sql_for_expenses = "select null as time, null as units, sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; + $sql_for_expenses = "select null as time"; + if ($bean->getAttribute('chunits')) $sql_for_expenses .= ", null as units"; + $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; // Create a combined query. - $sql = "select sum(time) as time, sum(units) as units, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t"; + $combined = "select sum(time) as time"; + if ($bean->getAttribute('chunits')) $combined .= ", sum(units) as units"; + $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t"; + $sql = $combined; } // Execute query. @@ -1083,34 +1133,41 @@ static function getFavTotals($report) $where = ttReportHelper::getFavWhere($report); - // Start with a query for time items. + // Prepare parts. + $time_part = "sum(time_to_sec(l.duration)) as time"; + if ($report['show_work_units']) { + $units_part = $user->unit_totals_only ? ", null as units" : ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + } + if ($report['show_cost']) { + if (MODE_TIME == $user->tracking_mode) + $cost_part = ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses"; + else + $cost_part = ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses"; + } else { + $cost_part = ", null as cost, null as expenses"; + } if ($report['show_cost']) { if (MODE_TIME == $user->tracking_mode) { - $sql = "select sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, - null as expenses - from tt_log l - left join tt_users u on (l.user_id = u.id) $where"; + $left_joins = "left join tt_users u on (l.user_id = u.id)"; } else { - $sql = "select sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, - null as expenses - from tt_log l - left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where"; + $left_joins = "left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; } - } else - $sql = "select sum(time_to_sec(l.duration)) as time, - sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, - null as cost, null as expenses from tt_log l $where"; + } + // Prepare a query for time items. + $sql = "select $time_part $units_part $cost_part from tt_log l $left_joins $where"; // If we have expenses, query becomes a bit more complex. if ($report['show_cost'] && $user->isPluginEnabled('ex')) { $where = ttReportHelper::getFavExpenseWhere($report); - $sql_for_expenses = "select null as time, null as units, sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; + $sql_for_expenses = "select null as time"; + if ($report['show_work_units']) $sql_for_expenses .= ", null as units"; + $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; + // Create a combined query. - $sql = "select sum(time) as time, sum(units) as units, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t"; + $combined = "select sum(time) as time"; + if ($report['show_work_units']) $combined .= ", sum(units) as units"; + $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t"; + $sql = $combined; } // Execute query. diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 281659313..e498cde0e 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -68,6 +68,7 @@ class ttUser { var $is_client = false; // Whether user is a client as determined by missing 'track_own_time' right. var $minutes_in_unit = 15; // Number of minutes in unit for Work units plugin. var $first_unit_threshold = 0;// Threshold for 1st unit for Work units plugin. + var $unit_totals_only = 0; // Totlas only option for the Work units plugin. // Constructor. function __construct($login, $id = null) { @@ -139,6 +140,7 @@ function __construct($login, $id = null) { if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit; $first_unit_threshold = $config->getIntValue('1st_unit_threshold'); if ($first_unit_threshold) $this->first_unit_threshold = $first_unit_threshold; + $this->unit_totals_only = $config->getDefinedValue('unit_totals_only'); } // Set "on behalf" id and name. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c2010946b..6b39e764c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.17.92.4282 | Copyright © Anuko | +  Anuko Time Tracker 1.17.92.4283 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 8ec1dac1bcf71ce282ab116413d335f582b5e8f3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 22 Jul 2018 17:53:59 +0000 Subject: [PATCH 0179/1848] Added work units to emailed fav reports. --- WEB-INF/lib/ttReportHelper.class.php | 52 +++++++++++++++++++++------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 224d7f177..0900f7f9d 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -276,6 +276,9 @@ static function getItems($bean) { // Add duration. if ($bean->getAttribute('chduration')) array_push($fields, "TIME_FORMAT(l.duration, '%k:%i') as duration"); + // Add work units. + if ($bean->getAttribute('chunits')) + array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); // Add note. if ($bean->getAttribute('chnote')) array_push($fields, 'l.comment as note'); @@ -303,10 +306,6 @@ static function getItems($bean) { if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice')) array_push($fields, 'i.name as invoice'); - // Add work units. - if ($bean->getAttribute('chunits')) - array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); - // Prepare sql query part for left joins. $left_joins = null; if ($bean->getAttribute('chclient') || 'client' == $group_by_option) @@ -549,6 +548,10 @@ static function getFavItems($report) { // Add duration. if ($report['show_duration']) array_push($fields, "TIME_FORMAT(l.duration, '%k:%i') as duration"); + // Add work units. + if ($report['show_work_units']) + array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); + // Add note. if ($report['show_note']) array_push($fields, 'l.comment as note'); @@ -632,6 +635,8 @@ static function getFavItems($report) { array_push($fields, 'null'); // null for finish. if ($report['show_duration']) array_push($fields, 'null'); // null for duration. + if ($report['show_work_units']) + array_push($fields, 'null'); // null for work units. // Use the note field to print item name. if ($report['show_note']) array_push($fields, 'ei.name as note'); @@ -909,21 +914,25 @@ static function getFavSubtotals($report) { if (MODE_TIME == $user->tracking_mode) { if ($group_by_option != 'user') $left_join = 'left join tt_users u on (l.user_id = u.id)'; - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, null as expenses from tt_log l $group_join $left_join $where group by $group_field"; } else { // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l $group_join left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where group by $group_field"; } } else { - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, null as expenses from tt_log l - $group_join $where group by $group_field"; + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, + sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units, + null as expenses from tt_log l + $group_join $where group by $group_field"; } // By now we have sql for time items. @@ -953,13 +962,13 @@ static function getFavSubtotals($report) { } $where = ttReportHelper::getFavExpenseWhere($report); - $sql_for_expenses = "select $group_field as group_field, null as time, sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei + $sql_for_expenses = "select $group_field as group_field, null as time, null as units, sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $group_join $where"; // Add a "group by" clause if we are grouping. if ('null' != $group_field) $sql_for_expenses .= " group by $group_field"; // Create a combined query. - $sql = "select group_field, sum(time) as time, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; + $sql = "select group_field, sum(time) as time, sum(units) as units, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; } // Execute query. @@ -979,9 +988,9 @@ static function getFavSubtotals($report) { $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']); } - $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time,'cost'=>$val['cost'],'expenses'=>$val['expenses']); + $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time, 'units'=> $val['units'], 'cost'=>$val['cost'],'expenses'=>$val['expenses']); } else - $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time); + $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time, 'units'=> $val['units']); } return $subtotals; @@ -1549,6 +1558,8 @@ static function prepareFavReportBody($report) $body .= ''.$group_by_header.''.$i18n->get('label.duration').''.$i18n->get('label.work_units_short').''.$i18n->get('label.cost').'
'; + $body .= $subtotal['units']; + $body .= ''; $body .= ($canViewReports || $isClient) ? $subtotal['cost'] : $subtotal['expenses']; @@ -1577,6 +1593,11 @@ static function prepareFavReportBody($report) if ($totals['time'] <> '0:00') $body .= $totals['time']; $body .= ''; + $body .= $totals['units']; + $body .= ''.htmlspecialchars($user->currency).' '; $body .= ($canViewReports || $isClient) ? $totals['cost'] : $totals['expenses']; @@ -1608,6 +1629,8 @@ static function prepareFavReportBody($report) $body .= ''.$i18n->get('label.finish').''.$i18n->get('label.duration').''.$i18n->get('label.work_units_short').''.$i18n->get('label.note').''.$subtotals[$prev_grouped_by]['time'].''.$subtotals[$prev_grouped_by]['units'].''; @@ -1687,6 +1711,8 @@ static function prepareFavReportBody($report) $body .= ''.$record['finish'].''.$record['duration'].''.$record['units'].''.htmlspecialchars($record['note']).''.$subtotals[$cur_grouped_by]['time'].''.$subtotals[$cur_grouped_by]['units'].''; @@ -1748,6 +1775,7 @@ static function prepareFavReportBody($report) if ($report['show_start']) $body .= ''.$totals['time'].''.$totals['units'].''.htmlspecialchars($user->currency).' '; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8f0779f2d..c2010946b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - +
 Anuko Time Tracker 1.17.92.4283 | Copyright © Anuko | +  Anuko Time Tracker 1.17.92.4284 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 928c8528504a757cebd2bebcebfa5a393ac19b05 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 24 Jul 2018 17:49:57 +0000 Subject: [PATCH 0180/1848] Work in progress on totals only config option for Work units plugin. --- WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/cs.lang.php | 2 +- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/en.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 4 +--- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 +- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 +- WEB-INF/resources/sv.lang.php | 2 +- WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- WEB-INF/resources/zh-tw.lang.php | 2 +- WEB-INF/templates/reports.tpl | 2 +- WEB-INF/templates/work_units.tpl | 4 ++++ work_units.php | 1 + 33 files changed, 36 insertions(+), 33 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 0e909ab89..e856fc463 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -245,6 +245,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Només totals', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -415,7 +416,6 @@ 'form.reports.group_by_project' => 'projecte', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -'form.reports.totals_only' => 'Només totals', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 282296efd..aa9037a33 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -255,6 +255,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Pouze součty', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -425,7 +426,6 @@ 'form.reports.group_by_project' => 'projekt', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -'form.reports.totals_only' => 'Pouze součty', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 38e9f43d9..7010608cd 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -226,6 +226,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Kun Total', // Form titles. 'title.login' => 'Login', @@ -379,7 +380,6 @@ 'form.reports.group_by_client' => 'Klient', 'form.reports.group_by_project' => 'Projekt', 'form.reports.group_by_task' => 'Opgave', -'form.reports.totals_only' => 'Kun Total', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 613bdc7c9..b7e0f5314 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -222,6 +222,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Nur Gesamtstunden', // Form titles. 'title.login' => 'Anmelden', @@ -372,7 +373,6 @@ 'form.reports.group_by_client' => 'Kunde', 'form.reports.group_by_project' => 'Projekt', 'form.reports.group_by_task' => 'Aufgabe', -'form.reports.totals_only' => 'Nur Gesamtstunden', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index e4abce9f5..5f1145bd6 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -213,6 +213,7 @@ 'label.week_list' => 'Week list', 'label.work_units' => 'Work units', 'label.work_units_short' => 'Units', +'label.totals_only' => 'Totals only', // Form titles. 'title.login' => 'Login', @@ -363,7 +364,6 @@ 'form.reports.group_by_client' => 'client', 'form.reports.group_by_project' => 'project', 'form.reports.group_by_task' => 'task', -'form.reports.totals_only' => 'Totals only', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 5a040b80b..d804fa0be 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -248,6 +248,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Solo totales', // Form titles. 'title.login' => 'Sesión iniciada', @@ -428,7 +429,6 @@ 'form.reports.group_by_project' => 'proyecto', // TODO: traslate the following string. // 'form.reports.group_by_task' => 'task', -'form.reports.totals_only' => 'Solo totales', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 2b1bdde35..2c9b04aa6 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -251,6 +251,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Ainult summad', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -423,7 +424,6 @@ 'form.reports.group_by_project' => 'projekt', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -'form.reports.totals_only' => 'Ainult summad', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index c567d072c..28bcf8102 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -238,6 +238,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +// 'label.totals_only' => 'Totals only', // Form titles. 'title.login' => 'ورود', @@ -402,9 +403,6 @@ 'form.reports.group_by_client' => 'مشتری', 'form.reports.group_by_project' => 'پروژه', 'form.reports.group_by_task' => 'وظیفه', -// TODO: translate form.reports.totals_only. Selecting this option means to print subtotals only for a "grouped by" report. -// In other words, items are not printed, only subtotals for grouped items are printed. -// 'form.reports.totals_only' => 'Totals only', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 48b5089f1..99b40f489 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -230,6 +230,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Vain yhteissummat', // Form titles. 'title.login' => 'Kirjautuminen', @@ -386,7 +387,6 @@ 'form.reports.group_by_client' => 'asiakas', 'form.reports.group_by_project' => 'projekti', 'form.reports.group_by_task' => 'tehtävä', -'form.reports.totals_only' => 'Vain yhteissummat', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 888e0ee8b..a08f34f4f 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -224,6 +224,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Totaux uniquement', // Form titles. 'title.login' => 'Connexion', @@ -376,7 +377,6 @@ 'form.reports.group_by_client' => 'Client', 'form.reports.group_by_project' => 'Projet', 'form.reports.group_by_task' => 'Tâche', -'form.reports.totals_only' => 'Totaux uniquement', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index e8f03b019..7eeead9cb 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -215,6 +215,7 @@ // TODO: translate the following. // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Σύνολα μόνο', // Form titles. 'title.login' => 'Σύνδεση', @@ -365,7 +366,6 @@ 'form.reports.group_by_client' => 'πελάτης', 'form.reports.group_by_project' => 'έργο', 'form.reports.group_by_task' => 'εργασία', -'form.reports.totals_only' => 'Σύνολα μόνο', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index e513d5fc9..c99ce8eb9 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -248,6 +248,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'labl.totals_only' => 'סיכומים בלבד', // Form titles. 'title.login' => 'כניסה', @@ -410,7 +411,6 @@ 'form.reports.group_by_client' => 'לקוח', 'form.reports.group_by_project' => 'פרוייקט', 'form.reports.group_by_task' => 'משימה', -'form.reports.totals_only' => 'סיכומים בלבד', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index cf6b0878a..73165fae2 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -248,6 +248,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +// 'label.totals_only' => 'Totals only', // Form titles. 'title.login' => 'Bejelentkezés', @@ -417,7 +418,6 @@ 'form.reports.group_by_project' => 'projekt', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -// 'form.reports.totals_only' => 'Totals only', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ae1dae459..1c6769b7f 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -220,6 +220,7 @@ // TODO: translate the following. // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Solo i totali', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -379,7 +380,6 @@ 'form.reports.group_by_client' => 'cliente', 'form.reports.group_by_project' => 'progetto', 'form.reports.group_by_task' => 'compito', -'form.reports.totals_only' => 'Solo i totali', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index fa4b4bec7..01782d63d 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -253,6 +253,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => '全体だけ', // Form titles. 'title.login' => 'ログイン', @@ -422,7 +423,6 @@ 'form.reports.group_by_project' => 'プロジェクト', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -'form.reports.totals_only' => '全体だけ', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index b4c79c23e..971c67d6c 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -253,6 +253,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => '오직 전체만', // Form titles. 'title.login' => '로그인', @@ -420,7 +421,6 @@ 'form.reports.group_by_project' => '프로젝트', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -'form.reports.totals_only' => '오직 전체만', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 0107a7085..8719b4712 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -213,6 +213,7 @@ // TODO: translate the following. // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Alleen totalen', // Form titles. 'title.login' => 'Aanmelden', @@ -362,7 +363,6 @@ 'form.reports.group_by_client' => 'klant', 'form.reports.group_by_project' => 'project', 'form.reports.group_by_task' => 'taak', -'form.reports.totals_only' => 'Alleen totalen', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 1bfc0534b..b3d58cc0f 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -251,6 +251,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +// 'label.totals_only' => 'Totals only', // Form titles. 'title.login' => 'Innlogging', @@ -418,7 +419,6 @@ 'form.reports.group_by_project' => 'prosjekt', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -// 'form.reports.totals_only' => 'Totals only', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index ec6b78488..1b4665e62 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -231,6 +231,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Tylko sumy', // Form titles. 'title.login' => 'Logowanie', @@ -388,7 +389,6 @@ 'form.reports.group_by_client' => 'klientów', 'form.reports.group_by_project' => 'projektów', 'form.reports.group_by_task' => 'zadań', -'form.reports.totals_only' => 'Tylko sumy', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index db390eb28..13fc33a8c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -228,6 +228,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Somente totais', // Form titles. 'title.login' => 'Login', @@ -383,7 +384,6 @@ 'form.reports.group_by_client' => 'cliente', 'form.reports.group_by_project' => 'projeto', 'form.reports.group_by_task' => 'tarefa', -'form.reports.totals_only' => 'Somente totais', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 4b9727fa0..53795d38e 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -240,6 +240,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +// 'label.totals_only' => 'Totals only', // Form titles. 'title.login' => 'Login', @@ -400,7 +401,6 @@ // 'form.reports.group_by_client' => 'client', // 'form.reports.group_by_project' => 'project', // 'form.reports.group_by_task' => 'task', -// 'form.reports.totals_only' => 'Totals only', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index b9c122019..aad8d8831 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -252,6 +252,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Numai totaluri', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -423,7 +424,6 @@ 'form.reports.group_by_project' => 'proiect', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -'form.reports.totals_only' => 'Numai totaluri', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 114ecc541..3b2c67dbc 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -212,6 +212,7 @@ 'label.week_list' => 'Список недели', 'label.work_units' => 'Единицы работы', 'label.work_units_short' => 'Единицы', +'label.totals_only' => 'Только итоги', // Form titles. 'title.login' => 'Вход в систему', @@ -360,7 +361,6 @@ 'form.reports.group_by_client' => 'клиенту', 'form.reports.group_by_project' => 'проекту', 'form.reports.group_by_task' => 'задаче', -'form.reports.totals_only' => 'Только итоги', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 87beb6f65..d22c4b7eb 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -238,6 +238,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Iba celkové', // Form titles. 'title.login' => 'Prihlásenie', @@ -402,7 +403,6 @@ 'form.reports.group_by_client' => 'klient', 'form.reports.group_by_project' => 'projekt', 'form.reports.group_by_task' => 'úloha', -'form.reports.totals_only' => 'Iba celkové', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 732286b9f..ab53c5b23 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -235,6 +235,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +// 'label.totals_only' => 'Totals only', // Form titles. 'title.login' => 'Prijava', @@ -397,7 +398,6 @@ 'form.reports.group_by_project' => 'projekt', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -// 'form.reports.totals_only' => 'Totals only', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 648f26e24..b9bbf149e 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -229,6 +229,7 @@ // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', +'label.totals_only' => 'Samo zbirno', // Form titles. 'title.login' => 'Prijava', @@ -386,7 +387,6 @@ 'form.reports.group_by_client' => 'klijent', 'form.reports.group_by_project' => 'projekat', 'form.reports.group_by_task' => 'zadatak', -'form.reports.totals_only' => 'Samo zbirno', // Forma izveštaja. Pogledajte primer na https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 11eff1948..c2159bb1a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -224,6 +224,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Visa endast summeringar', // Rubriker för formulär 'title.login' => 'Logga in', @@ -382,7 +383,6 @@ 'form.reports.group_by_client' => 'Kund', 'form.reports.group_by_project' => 'Projekt', 'form.reports.group_by_task' => 'Arbetsuppgift', -'form.reports.totals_only' => 'Visa endast summeringar', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index ee3b4456a..3508153e6 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -259,6 +259,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +'label.totals_only' => 'Sadece toplamlar', // Form titles. // Form titles. @@ -435,7 +436,6 @@ 'form.reports.group_by_project' => 'proje', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -'form.reports.totals_only' => 'Sadece toplamlar', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 1cb84d714..6fbcb0232 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -242,6 +242,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +// 'label.totals_only' => 'Totals only', // Form titles. 'title.login' => '登录', @@ -406,7 +407,6 @@ 'form.reports.group_by_project' => '项目', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -// 'form.reports.totals_only' => 'Totals only', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index fc3ec9957..4ada9fc2e 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -249,6 +249,7 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', +// 'label.totals_only' => 'Totals only', // Form titles. 'title.login' => '登錄', @@ -414,7 +415,6 @@ 'form.reports.group_by_project' => '項目', // TODO: translate the following. // 'form.reports.group_by_task' => 'task', -// 'form.reports.totals_only' => 'Totals only', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index b57ba8410..af674785e 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -299,7 +299,7 @@ function handleCheckboxes() { {$i18n.form.reports.group_by}
{$forms.reportForm.group_by.control} {$forms.reportForm.group_by.control}
diff --git a/WEB-INF/templates/work_units.tpl b/WEB-INF/templates/work_units.tpl index 9c2e64da8..a4fb6b578 100644 --- a/WEB-INF/templates/work_units.tpl +++ b/WEB-INF/templates/work_units.tpl @@ -8,6 +8,10 @@
{$i18n.form.work_units.1st_unit_threshold}: {$forms.workUnitsForm.1st_unit_threshold.control} {$i18n.label.what_is_it}
{$i18n.label.totals_only}:{$forms.workUnitsForm.totals_only.control} {$i18n.label.what_is_it}
 
-
 Anuko Time Tracker 1.17.92.4284 | Copyright © Anuko | +  Anuko Time Tracker 1.17.93.4285 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_edit.php b/group_edit.php index 8c7012a50..01d2ecdc4 100644 --- a/group_edit.php +++ b/group_edit.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttUserHelper'); import('ttRoleHelper'); +import('ttConfigHelper'); // Access checks. if (!(ttAccessAllowed('manage_basic_settings') || ttAccessAllowed('manage_advanced_settings'))) { @@ -38,6 +39,8 @@ } // End of access checks. +$config = new ttConfigHelper($user->config); + $advanced_settings = $user->can('manage_advanced_settings'); if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); @@ -271,18 +274,12 @@ $plugins = trim($plugins, ','); - // Prepare config string. - if ($cl_show_holidays) - $config .= ',show_holidays'; - if ($cl_punch_mode) - $config .= ',punch_mode'; - if ($cl_allow_overlap) - $config .= ',allow_overlap'; - if ($cl_future_entries) - $config .= ',future_entries'; - if ($cl_uncompleted_indicators) - $config .= ',uncompleted_indicators'; - $config = trim($config, ','); + // Update config. + $config->setDefinedValue('show_holidays', $cl_show_holidays); + $config->setDefinedValue('punch_mode', $cl_punch_mode); + $config->setDefinedValue('allow_overlap', $cl_allow_overlap); + $config->setDefinedValue('future_entries', $cl_future_entries); + $config->setDefinedValue('uncompleted_indicators', $cl_uncompleted_indicators); if ($user->updateGroup(array( 'name' => $cl_group, @@ -300,7 +297,7 @@ 'bcc_email' => $cl_bcc_email, 'allow_ip' => $cl_allow_ip, 'plugins' => $plugins, - 'config' => $config))) { + 'config' => $config->getConfig()))) { header('Location: time.php'); exit(); } else diff --git a/work_units.php b/work_units.php index 32b2616b8..b2373adab 100644 --- a/work_units.php +++ b/work_units.php @@ -45,9 +45,11 @@ if ($request->isPost()) { $cl_minutes_in_unit = $request->getParameter('minutes_in_unit'); $cl_1st_unit_threshold = $request->getParameter('1st_unit_threshold'); + $cl_totals_only = $request->getParameter('totals_only'); } else { $cl_minutes_in_unit = $user->minutes_in_unit; $cl_1st_unit_threshold = $user->first_unit_threshold; + $cl_totals_only = $user->unit_totals_only; } $form = new Form('workUnitsForm'); @@ -65,6 +67,7 @@ if ($err->no()) { $config->setIntValue('minutes_in_unit', $cl_minutes_in_unit); $config->setIntValue('1st_unit_threshold', $cl_1st_unit_threshold); + $config->setDefinedValue('unit_totals_only', $cl_totals_only); if (!$user->updateGroup(array('config' => $config->getConfig()))) { $err->add($i18n->get('error.db')); } From 0e60d28bba29fbd47e415ac55bdcb39a284613ee Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Jul 2018 02:35:16 +0000 Subject: [PATCH 0182/1848] Fixed typo in a comment. --- WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/cs.lang.php | 2 +- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/en.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 +- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 +- WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- WEB-INF/resources/zh-tw.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index e856fc463..9d446f2a4 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -490,7 +490,7 @@ // 'form.export.compression_none' => 'none', // 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Importar dades del grup des d\\\'un arxiu xml.', 'form.import.file' => 'Sel·leccioni l\\\'arxiu', 'form.import.success' => 'Importació finalitzada amb èxit.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index aa9037a33..fccc92b51 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -502,7 +502,7 @@ // 'form.export.compression_none' => 'none', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Importovat týmová data z xml souboru.', // TODO: replace "team" with "group". 'form.import.file' => 'Výběr souboru', 'form.import.success' => 'Import byl úspěšně dokončen.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 7010608cd..4390e22bb 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -448,7 +448,7 @@ 'form.export.compression_none' => 'Ingen', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Importer teamdata fra en xml-fil.', // TODO: replace "team" with "group". 'form.import.file' => 'Vælg fil', 'form.import.success' => 'Import sluttede med succes.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index b7e0f5314..ac6423de6 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -446,7 +446,7 @@ 'form.export.compression_none' => 'Keine', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Teamdaten von einer XML-Datei importieren.', // TODO: replace "team" with "group". 'form.import.file' => 'Datei auswählen', 'form.import.success' => 'Import erfolgreich abgeschlossen.', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 5f1145bd6..50180602a 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -427,7 +427,7 @@ 'form.export.compression_none' => 'none', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Import group data from an xml file.', 'form.import.file' => 'Select file', 'form.import.success' => 'Import completed successfully.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index d804fa0be..f03a331b1 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -503,7 +503,7 @@ // 'form.export.compression_none' => 'none', // 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Importar datos del grupo desde un archivo xml.', 'form.import.file' => 'Seleccione el archivo', 'form.import.success' => 'Importación finalizada con éxito.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 2c9b04aa6..f59da5646 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -500,7 +500,7 @@ // 'form.export.compression_none' => 'none', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Impordi meeskonna andmed xml-failist.', // TODO: replace "team" with "group". 'form.import.file' => 'Vali fail', 'form.import.success' => 'Andmed imporditud.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 28bcf8102..f2a033312 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -473,7 +473,7 @@ 'form.export.compression_none' => 'هیچ کدام', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'وارد کردن اطلاعات تیم از یک فایل xml', // TODO: replace "team" with "group". 'form.import.file' => 'انتخاب فایل', 'form.import.success' => 'وارد کردن اطلاعات با موفقیت انجام شد', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 99b40f489..f06429daa 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -456,7 +456,7 @@ 'form.export.compression_none' => 'ei pakata', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Tuo tiimitiedot xml-tiedostosta.', // TODO: replace "team" with "group". 'form.import.file' => 'Valitse tiedosto', 'form.import.success' => 'Tietojen tuonti onnistui.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a08f34f4f..49825603c 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -445,7 +445,7 @@ 'form.export.compression_none' => 'Aucune', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Importer les donnés des équipes depuis un fichier xml.', // TODO: replace "team" with "group". Also, it's about 1 group, not many. 'form.import.file' => 'Sélectionner le fichier', 'form.import.success' => 'Importation réussie.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 7eeead9cb..3c6d78a2e 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -430,7 +430,7 @@ 'form.export.compression_none' => 'χωρίς', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Εισαγωγή δεδομένων ομάδας από αρχείο xml.', 'form.import.file' => 'Επιλογή αρχείου', 'form.import.success' => 'Η εισαγωγή ολοκληρώθηκε με επιτυχία.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index c99ce8eb9..cd61af660 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -482,7 +482,7 @@ 'form.export.compression_none' => 'ללא', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'ייבא נתוני צוות מתוך קובץ XML.', // TODO: replace "team" with "group". 'form.import.file' => 'בחר קובץ', 'form.import.success' => 'הייבוא הושלם בהצלחה.', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 73165fae2..f0dacf13e 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -493,7 +493,7 @@ // 'form.export.compression_none' => 'none', // 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Csoport adatok importja XML file-ból.', 'form.import.file' => 'Válassz file', 'form.import.success' => 'Az importálás sikeresen véget ért.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 1c6769b7f..ceedf9f52 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -445,7 +445,7 @@ 'form.export.compression_none' => 'niente', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Importa i dati del gruppo da un file xml.', 'form.import.file' => 'Seleziona il file', 'form.import.success' => 'Importazione eseguita con successo.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 01782d63d..07dc50b9f 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -496,7 +496,7 @@ 'form.export.compression_none' => 'なし', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'xmlファイルからチームのデータをインポート。', // TODO: replace "team" with "group". 'form.import.file' => 'ファイルの選択', 'form.import.success' => 'インポートが成功的に完了されました。', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 971c67d6c..21c34a561 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -494,7 +494,7 @@ 'form.export.compression_none' => '없음', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'xml 파일로부터 팀 데이터를 임포트.', // TODO: replace "team" with "group". 'form.import.file' => '파일 선택', 'form.import.success' => '성과적으로 완료된 임포트.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 8719b4712..907b4a496 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -426,7 +426,7 @@ 'form.export.compression_none' => 'geen', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Importeer groepsgegevens uit een xml bestand.', 'form.import.file' => 'Kies bestand', 'form.import.success' => 'Importeren gelukt.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index b3d58cc0f..436f59016 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -493,7 +493,7 @@ 'form.export.compression_none' => 'ingen', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Import team data fra en xml fil.', // TODO: replace "team" with "group". 'form.import.file' => 'Velg fil', 'form.import.success' => 'Import gjennomført vellykket.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 1b4665e62..6b262c22d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -458,7 +458,7 @@ 'form.export.compression_none' => 'brak', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Import danych zespołu z pliku xml.', // TODO: replace "team" with "group". 'form.import.file' => 'Wybierz plik', 'form.import.success' => 'Import zakończony powodzeniem.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 13fc33a8c..afdd8eb94 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -453,7 +453,7 @@ 'form.export.compression_none' => 'nenhuma', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Importar dados de equipe de um arquivo xml.', // TODO: replace "team" with "group". 'form.import.file' => 'Selecionar arquivo', 'form.import.success' => 'Importação realizada com sucesso.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 53795d38e..834aaaf56 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -476,7 +476,7 @@ // 'form.export.compression_none' => 'none', // 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). // TODO: translate the following. // 'form.import.hint' => 'Import group data from an xml file.', // 'form.import.file' => 'Select file', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index aad8d8831..f00956294 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -498,7 +498,7 @@ // 'form.export.compression_none' => 'none', // 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Importa date echipa dintr-un fisier xml.', // TODO: replace "team" with "group". 'form.import.file' => 'Alege fisier', 'form.import.success' => 'Importul s-a incheiat cu succes.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3b2c67dbc..85155b423 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -424,7 +424,7 @@ 'form.export.compression_none' => 'нет', 'form.export.compression_bzip' => 'в формате bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Импортируйте данные группы из xml файла.', 'form.import.file' => 'Укажите файл', 'form.import.success' => 'Импорт успешно выполнен.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d22c4b7eb..f79f4abd5 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -473,7 +473,7 @@ 'form.export.compression_none' => 'žiadna', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Importovať dáta o tíme z xml súboru.', // TODO: replace "team" with "group". 'form.import.file' => 'Vyberte súbor', 'form.import.success' => 'Import úspešne dokončený.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ab53c5b23..3e24c2541 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -472,7 +472,7 @@ // 'form.export.compression_none' => 'none', // 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). // TODO: translate the following. // 'form.import.hint' => 'Import group data from an xml file.', // 'form.import.file' => 'Select file', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index b9bbf149e..7e7d7f4d1 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -456,7 +456,7 @@ 'form.export.compression_none' => 'ništa', 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Uvezi podatke timova iz xml fajla.', // TODO: replace "team" with "group". 'form.import.file' => 'Odaberi datoteku', 'form.import.success' => 'Uvoz uspešan.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 3508153e6..0159c7a9c 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -511,7 +511,7 @@ // 'form.export.compression_none' => 'none', // 'form.export.compression_bzip' => 'bzip', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => 'Ekip bilgileri bir xml dosyasından içe aktar.', // TODO: replace "team" with "group". 'form.import.file' => 'Dosya seç', 'form.import.success' => 'Içe aktarma başarıyla tamamlandı.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 6fbcb0232..4265532fd 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -480,7 +480,7 @@ 'form.export.compression_none' => '不压缩', 'form.export.compression_bzip' => 'bzip格式', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => '从xml文件导入团队数据。', // TODO: replace "team" with "group". 'form.import.file' => '选择档', 'form.import.success' => '成功完成导入。', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 4ada9fc2e..09712f483 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -488,7 +488,7 @@ 'form.export.compression_none' => '不压缩', 'form.export.compression_bzip' => 'bzip格式', -// Importing Group Data form. See example at https://timetracker.anuko.com/imort.php (login as admin first). +// Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). 'form.import.hint' => '從xml檔導入團隊資料。', // TODO: replace "team" with "group". 'form.import.file' => '選擇檔', 'form.import.success' => '成功完成導入。', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6b39e764c..b8d80a7b2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.93.4285 | Copyright © Anuko | +  Anuko Time Tracker 1.17.93.4286 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 259a4673f7475125e1ab6b68f77a67401fa52d06 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Jul 2018 14:06:39 +0000 Subject: [PATCH 0183/1848] Refactoring of reports started. --- WEB-INF/lib/ttFavReportHelper.class.php | 22 ++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- cron.php | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 006d55676..88a1338d6 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -327,4 +327,26 @@ static function loadReport($user_id, &$bean) { $bean->setAttributes($attrs); } } + + // getReportOptions - returns an array of fav report options from database data. + // Note: this function is a part of refactoring to simplify maintenance of report + // generating functions, as we currently have 2 sets: normal reporting (from bean), + // and fav report emailing (from db fields). Using options obtained from either db or bean + // shall allow us to use only one set of functions. + static function getReportOptions($id) { + + // Start with getting the fields from the database. + $db_fields = ttFavReportHelper::getReport($id); + if (!$db_fields) return false; + + // Prepare an array of report options. + $options = $db_fields; // For now, use db field names as options. + // Drop things we don't need in reports. + unset($options['id']); + unset($options['report_spec']); // Currently not used. + unset($options['status']); + + // $options now is a subset of db fields from tt_fav_reports table. + return $options; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b8d80a7b2..5c25eb60a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.93.4286 | Copyright © Anuko | +  Anuko Time Tracker 1.17.93.4287 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cron.php b/cron.php index 9424802ef..262cafe54 100644 --- a/cron.php +++ b/cron.php @@ -59,7 +59,7 @@ // We have jobs to execute in user language. // Get favorite report details. - $report = ttFavReportHelper::getReport($val['report_id']); + $report = ttFavReportHelper::getReportOptions($val['report_id']); if (!$report) continue; // Skip not found report. // Recycle global $user object, as user settings are specific for each report. From 187a16b0ffee5ae6af51b010ff90a194048d3457 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Jul 2018 15:28:04 +0000 Subject: [PATCH 0184/1848] A bit more refactoring in reports. --- WEB-INF/lib/ttReportHelper.class.php | 90 ++++++++++++++++++++++------ WEB-INF/templates/footer.tpl | 2 +- report.php | 7 ++- tofile.php | 5 +- topdf.php | 7 ++- 5 files changed, 84 insertions(+), 27 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 4da47ec07..e0993525c 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -37,13 +37,14 @@ class ttReportHelper { // getWhere prepares a WHERE clause for a report query. - static function getWhere($bean) { + // Note: $options is a future replacement of $bean, which is work in progress. + static function getWhere($bean, $options) { global $user; // Prepare dropdown parts. $dropdown_parts = ''; - if ($bean->getAttribute('client')) - $dropdown_parts .= ' and l.client_id = '.$bean->getAttribute('client'); + if ($options['client_id']) + $dropdown_parts .= ' and l.client_id = '.$options['client_id']; elseif ($user->isClient() && $user->client_id) $dropdown_parts .= ' and l.client_id = '.$user->client_id; if ($bean->getAttribute('option')) $dropdown_parts .= ' and l.id in(select log_id from tt_custom_field_log where status = 1 and option_id = '.$bean->getAttribute('option').')'; @@ -135,13 +136,13 @@ static function getFavWhere($report) { } // getExpenseWhere prepares WHERE clause for expenses query in a report. - static function getExpenseWhere($bean) { + static function getExpenseWhere($bean, $options) { global $user; // Prepare dropdown parts. $dropdown_parts = ''; - if ($bean->getAttribute('client')) - $dropdown_parts .= ' and ei.client_id = '.$bean->getAttribute('client'); + if ($options['client_id']) + $dropdown_parts .= ' and l.client_id = '.$options['client_id']; elseif ($user->isClient() && $user->client_id) $dropdown_parts .= ' and ei.client_id = '.$user->client_id; if ($bean->getAttribute('project')) $dropdown_parts .= ' and ei.project_id = '.$bean->getAttribute('project'); @@ -227,7 +228,7 @@ static function getFavExpenseWhere($report) { // getItems retrieves all items associated with a report. // It combines tt_log and tt_expense_items in one array for presentation in one table using mysql union all. // Expense items use the "note" field for item name. - static function getItems($bean) { + static function getItems($bean, $options) { global $user; $mdb2 = getConnection(); @@ -333,7 +334,7 @@ static function getItems($bean) { if ($includeCost && MODE_TIME != $user->tracking_mode) $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; - $where = ttReportHelper::getWhere($bean); + $where = ttReportHelper::getWhere($bean, $options); // Construct sql query for tt_log items. $sql = "select ".join(', ', $fields)." from tt_log l $left_joins $where"; @@ -401,7 +402,7 @@ static function getItems($bean) { if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice')) $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; - $where = ttReportHelper::getExpenseWhere($bean); + $where = ttReportHelper::getExpenseWhere($bean, $options); // Construct sql query for expense items. $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $where"; @@ -742,7 +743,7 @@ static function getFavItems($report) { // getSubtotals calculates report items subtotals when a report is grouped by. // Without expenses, it's a simple select with group by. // With expenses, it becomes a select with group by from a combined set of records obtained with "union all". - static function getSubtotals($bean) { + static function getSubtotals($bean, $options) { global $user; $group_by_option = $bean->getAttribute('group_by'); @@ -784,7 +785,7 @@ static function getSubtotals($bean) { break; } - $where = ttReportHelper::getWhere($bean); + $where = ttReportHelper::getWhere($bean, $options); if ($bean->getAttribute('chcost')) { if (MODE_TIME == $user->tracking_mode) { if ($group_by_option != 'user') @@ -851,7 +852,7 @@ static function getSubtotals($bean) { break; } - $where = ttReportHelper::getExpenseWhere($bean); + $where = ttReportHelper::getExpenseWhere($bean, $options); $sql_for_expenses = "select $group_field as group_field, null as time"; if ($bean->getAttribute('chunits')) $sql_for_expenses .= ", null as units"; $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $group_join $where"; @@ -1043,13 +1044,13 @@ static function getFavSubtotals($report) { } // getTotals calculates total hours and cost for all report items. - static function getTotals($bean) + static function getTotals($bean, $options) { global $user; $mdb2 = getConnection(); - $where = ttReportHelper::getWhere($bean); + $where = ttReportHelper::getWhere($bean, $options); // Prepare parts. $time_part = "sum(time_to_sec(l.duration)) as time"; @@ -1076,7 +1077,7 @@ static function getTotals($bean) // If we have expenses, query becomes a bit more complex. if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) { - $where = ttReportHelper::getExpenseWhere($bean); + $where = ttReportHelper::getExpenseWhere($bean, $options); $sql_for_expenses = "select null as time"; if ($bean->getAttribute('chunits')) $sql_for_expenses .= ", null as units"; $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; @@ -1250,12 +1251,13 @@ static function prepareReportBody($bean, $comment) // Determine these once as they are used in multiple places in this function. $canViewReports = $user->can('view_reports'); $isClient = $user->isClient(); + $options = ttReportHelper::getReportOptions($bean); - $items = ttReportHelper::getItems($bean); + $items = ttReportHelper::getItems($bean, $options); $group_by = $bean->getAttribute('group_by'); if ($group_by && 'no_grouping' != $group_by) - $subtotals = ttReportHelper::getSubtotals($bean); - $totals = ttReportHelper::getTotals($bean); + $subtotals = ttReportHelper::getSubtotals($bean, $options); + $totals = ttReportHelper::getTotals($bean, $options); // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) @@ -1884,4 +1886,56 @@ static function sendFavReport($report, $subject, $email, $cc) { return true; } + + // getReportOptions - returns an array of report options constructed from session bean. + // + // Note: similarly to ttFavReportHelper::getReportOptions, this function is a part of + // refactoring to simplify maintenance of report generating functions, as we currently + // have 2 sets: normal reporting (from bean), and fav report emailing (from db fields). + // Using options obtained from either db or bean shall allow us to use only one set of functions. + static function getReportOptions($bean) { + global $user; + + // Prepare an array of report options. + $options = array(); + + // Construct one by one. + $options['name'] = null; // No name required. + $options['user_id'] = $user->id; // Not sure if we need user_id here. Fav reports use it to recycle $user object in cron.php. + $options['client_id'] = $bean->getAttribute('client'); + +/* + * TODO: remaining fields to fill in... + `client_id` int(11) default NULL, # client id (if selected) + `cf_1_option_id` int(11) default NULL, # custom field 1 option id (if selected) + `project_id` int(11) default NULL, # project id (if selected) + `task_id` int(11) default NULL, # task id (if selected) + `billable` tinyint(4) default NULL, # whether to include billable, not billable, or all records + `invoice` tinyint(4) default NULL, # whether to include invoiced, not invoiced, or all records + `paid_status` tinyint(4) default NULL, # whether to include paid, not paid, or all records + `users` text default NULL, # Comma-separated list of user ids. Nothing here means "all" users. + `period` tinyint(4) default NULL, # selected period type for report + `period_start` date default NULL, # period start + `period_end` date default NULL, # period end + `show_client` tinyint(4) NOT NULL default 0, # whether to show client column + `show_invoice` tinyint(4) NOT NULL default 0, # whether to show invoice column + `show_paid` tinyint(4) NOT NULL default 0, # whether to show paid column + `show_ip` tinyint(4) NOT NULL default 0, # whether to show ip column + `show_project` tinyint(4) NOT NULL default 0, # whether to show project column + `show_start` tinyint(4) NOT NULL default 0, # whether to show start field + `show_duration` tinyint(4) NOT NULL default 0, # whether to show duration field + `show_cost` tinyint(4) NOT NULL default 0, # whether to show cost field + `show_task` tinyint(4) NOT NULL default 0, # whether to show task column + `show_end` tinyint(4) NOT NULL default 0, # whether to show end field + `show_note` tinyint(4) NOT NULL default 0, # whether to show note column + `show_custom_field_1` tinyint(4) NOT NULL default 0, # whether to show custom field 1 + `show_work_units` tinyint(4) NOT NULL default 0, # whether to show work units + `show_totals_only` tinyint(4) NOT NULL default 0, # whether to show totals only + `group_by` varchar(20) default NULL, # group by field + `status` tinyint(4) default 1, # favorite report status + PRIMARY KEY (`id`) +); + */ + return $options; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5c25eb60a..bbef7b8d3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.93.4287 | Copyright © Anuko | +  Anuko Time Tracker 1.17.93.4288 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index 3f2074491..61b3587ff 100644 --- a/report.php +++ b/report.php @@ -172,14 +172,15 @@ $group_by = $bean->getAttribute('group_by'); -$report_items = ttReportHelper::getItems($bean); +$options = ttReportHelper::getReportOptions($bean); +$report_items = ttReportHelper::getItems($bean, $options); // Store record ids in session in case user wants to act on records such as marking them all paid. if ($request->isGet() && $user->isPluginEnabled('ps')) ttReportHelper::putInSession($report_items); if ('no_grouping' != $group_by) - $subtotals = ttReportHelper::getSubtotals($bean); -$totals = ttReportHelper::getTotals($bean); + $subtotals = ttReportHelper::getSubtotals($bean, $options); +$totals = ttReportHelper::getTotals($bean, $options); // Assign variables that are used to print subtotals. if ($report_items && 'no_grouping' != $group_by) { diff --git a/tofile.php b/tofile.php index a06a98667..5a190f4bb 100644 --- a/tofile.php +++ b/tofile.php @@ -58,10 +58,11 @@ $totals_only = $bean->getAttribute('chtotalsonly'); // Obtain items. +$options = ttReportHelper::getReportOptions($bean); if ($totals_only) - $subtotals = ttReportHelper::getSubtotals($bean); + $subtotals = ttReportHelper::getSubtotals($bean, $options); else - $items = ttReportHelper::getItems($bean); + $items = ttReportHelper::getItems($bean, $options); // Build a string to use as filename for the files being downloaded. $filename = strtolower($i18n->get('title.report')).'_'.$bean->mValues['start_date'].'_'.$bean->mValues['end_date']; diff --git a/topdf.php b/topdf.php index b7ac19d52..9d3164af1 100644 --- a/topdf.php +++ b/topdf.php @@ -74,11 +74,12 @@ } // Obtain items for report. +$options = ttReportHelper::getReportOptions($bean); if (!$totals_only) - $items = ttReportHelper::getItems($bean); // Individual entries. + $items = ttReportHelper::getItems($bean, $options); // Individual entries. if ($totals_only || 'no_grouping' != $group_by) - $subtotals = ttReportHelper::getSubtotals($bean); // Subtotals for groups of items. -$totals = ttReportHelper::getTotals($bean); // Totals for the entire report. + $subtotals = ttReportHelper::getSubtotals($bean, $options); // Subtotals for groups of items. +$totals = ttReportHelper::getTotals($bean, $options); // Totals for the entire report. // Assign variables that are used to print subtotals. if ($items && 'no_grouping' != $group_by) { From 582bcea8035519f2b93be44023ec2cd032ef2504 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Jul 2018 16:21:42 +0000 Subject: [PATCH 0185/1848] Some renaming for ongoing report refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 364 +++++++++++++-------------- WEB-INF/templates/footer.tpl | 2 +- cron.php | 10 +- 3 files changed, 188 insertions(+), 188 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index e0993525c..ae5698d2c 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -83,30 +83,30 @@ static function getWhere($bean, $options) { } // getFavWhere prepares a WHERE clause for a favorite report query. - static function getFavWhere($report) { + static function getFavWhere($options) { global $user; // Prepare dropdown parts. $dropdown_parts = ''; - if ($report['client_id']) - $dropdown_parts .= ' and l.client_id = '.$report['client_id']; + if ($options['client_id']) + $dropdown_parts .= ' and l.client_id = '.$options['client_id']; elseif ($user->isClient() && $user->client_id) $dropdown_parts .= ' and l.client_id = '.$user->client_id; - if ($report['cf_1_option_id']) $dropdown_parts .= ' and l.id in(select log_id from tt_custom_field_log where status = 1 and option_id = '.$report['cf_1_option_id'].')'; - if ($report['project_id']) $dropdown_parts .= ' and l.project_id = '.$report['project_id']; - if ($report['task_id']) $dropdown_parts .= ' and l.task_id = '.$report['task_id']; - if ($report['billable']=='1') $dropdown_parts .= ' and l.billable = 1'; - if ($report['billable']=='2') $dropdown_parts .= ' and l.billable = 0'; - if ($report['invoice']=='1') $dropdown_parts .= ' and l.invoice_id is not NULL'; - if ($report['invoice']=='2') $dropdown_parts .= ' and l.invoice_id is NULL'; - if ($report['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; - if ($report['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; + if ($options['cf_1_option_id']) $dropdown_parts .= ' and l.id in(select log_id from tt_custom_field_log where status = 1 and option_id = '.$options['cf_1_option_id'].')'; + if ($options['project_id']) $dropdown_parts .= ' and l.project_id = '.$options['project_id']; + if ($options['task_id']) $dropdown_parts .= ' and l.task_id = '.$options['task_id']; + if ($options['billable']=='1') $dropdown_parts .= ' and l.billable = 1'; + if ($options['billable']=='2') $dropdown_parts .= ' and l.billable = 0'; + if ($options['invoice']=='1') $dropdown_parts .= ' and l.invoice_id is not NULL'; + if ($options['invoice']=='2') $dropdown_parts .= ' and l.invoice_id is NULL'; + if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; + if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; // Prepare user list part. $userlist = -1; if (($user->can('view_reports') || $user->isClient())) { - if ($report['users']) - $userlist = $report['users']; + if ($options['users']) + $userlist = $options['users']; else { $active_users = ttTeamHelper::getActiveUsers(); foreach ($active_users as $single_user) @@ -122,13 +122,13 @@ static function getFavWhere($report) { $user_list_part = " and l.user_id = ".$user->id; // Prepare sql query part for where. - if ($report['period']) - $period = new Period($report['period'], new DateAndTime($user->date_format)); + if ($options['period']) + $period = new Period($options['period'], new DateAndTime($user->date_format)); else { $period = new Period(); $period->setPeriod( - new DateAndTime($user->date_format, $report['period_start']), - new DateAndTime($user->date_format, $report['period_end'])); + new DateAndTime($user->date_format, $options['period_start']), + new DateAndTime($user->date_format, $options['period_end'])); } $where = " where l.status = 1 and l.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". " $user_list_part $dropdown_parts"; @@ -177,26 +177,26 @@ static function getExpenseWhere($bean, $options) { } // getFavExpenseWhere prepares a WHERE clause for expenses query in a favorite report. - static function getFavExpenseWhere($report) { + static function getFavExpenseWhere($options) { global $user; // Prepare dropdown parts. $dropdown_parts = ''; - if ($report['client_id']) - $dropdown_parts .= ' and ei.client_id = '.$report['client_id']; + if ($options['client_id']) + $dropdown_parts .= ' and ei.client_id = '.$options['client_id']; elseif ($user->isClient() && $user->client_id) $dropdown_parts .= ' and ei.client_id = '.$user->client_id; - if ($report['project_id']) $dropdown_parts .= ' and ei.project_id = '.$report['project_id']; - if ($report['invoice']=='1') $dropdown_parts .= ' and ei.invoice_id is not NULL'; - if ($report['invoice']=='2') $dropdown_parts .= ' and ei.invoice_id is NULL'; - if ($report['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; - if ($report['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; + if ($options['project_id']) $dropdown_parts .= ' and ei.project_id = '.$options['project_id']; + if ($options['invoice']=='1') $dropdown_parts .= ' and ei.invoice_id is not NULL'; + if ($options['invoice']=='2') $dropdown_parts .= ' and ei.invoice_id is NULL'; + if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; + if ($options['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; // Prepare user list part. $userlist = -1; if (($user->can('view_reports') || $user->isClient())) { - if ($report['users']) - $userlist = $report['users']; + if ($options['users']) + $userlist = $options['users']; else { $active_users = ttTeamHelper::getActiveUsers(); foreach ($active_users as $single_user) @@ -212,13 +212,13 @@ static function getFavExpenseWhere($report) { $user_list_part = " and ei.user_id = ".$user->id; // Prepare sql query part for where. - if ($report['period']) - $period = new Period($report['period'], new DateAndTime($user->date_format)); + if ($options['period']) + $period = new Period($options['period'], new DateAndTime($user->date_format)); else { $period = new Period(); $period->setPeriod( - new DateAndTime($user->date_format, $report['period_start']), - new DateAndTime($user->date_format, $report['period_end'])); + new DateAndTime($user->date_format, $options['period_start']), + new DateAndTime($user->date_format, $options['period_end'])); } $where = " where ei.status = 1 and ei.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and ei.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". " $user_list_part $dropdown_parts"; @@ -503,7 +503,7 @@ static function getFromSession() { // getFavItems retrieves all items associated with a favorite report. // It combines tt_log and tt_expense_items in one array for presentation in one table using mysql union all. // Expense items use the "note" field for item name. - static function getFavItems($report) { + static function getFavItems($options) { global $user; $mdb2 = getConnection(); @@ -511,8 +511,8 @@ static function getFavItems($report) { $canViewReports = $user->can('view_reports'); $isClient = $user->isClient(); - $group_by_option = $report['group_by']; - $convertTo12Hour = ('%I:%M %p' == $user->time_format) && ($report['show_start'] || $report['show_end']); + $group_by_option = $options['group_by']; + $convertTo12Hour = ('%I:%M %p' == $user->time_format) && ($options['show_start'] || $options['show_end']); // Prepare a query for time items in tt_log table. $fields = array(); // An array of fields for database query. @@ -522,16 +522,16 @@ static function getFavItems($report) { if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. - if ($report['show_client'] || 'client' == $group_by_option) + if ($options['show_client'] || 'client' == $group_by_option) array_push($fields, 'c.name as client'); // Add project name if it is selected. - if ($report['show_project'] || 'project' == $group_by_option) + if ($options['show_project'] || 'project' == $group_by_option) array_push($fields, 'p.name as project'); // Add task name if it is selected. - if ($report['show_task'] || 'task' == $group_by_option) + if ($options['show_task'] || 'task' == $group_by_option) array_push($fields, 't.name as task'); // Add custom field. - $include_cf_1 = $report['show_custom_field_1'] || 'cf_1' == $group_by_option; + $include_cf_1 = $options['show_custom_field_1'] || 'cf_1' == $group_by_option; if ($include_cf_1) { $custom_fields = new CustomFields($user->group_id); $cf_1_type = $custom_fields->fields[0]['type']; @@ -542,18 +542,18 @@ static function getFavItems($report) { } } // Add start time. - if ($report['show_start']) { + if ($options['show_start']) { array_push($fields, "l.start as unformatted_start"); array_push($fields, "TIME_FORMAT(l.start, '%k:%i') as start"); } // Add finish time. - if ($report['show_end']) + if ($options['show_end']) array_push($fields, "TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), '%k:%i') as finish"); // Add duration. - if ($report['show_duration']) + if ($options['show_duration']) array_push($fields, "TIME_FORMAT(l.duration, '%k:%i') as duration"); // Add work units. - if ($report['show_work_units']) { + if ($options['show_work_units']) { if ($user->unit_totals_only) array_push($fields, "null as units"); else @@ -561,10 +561,10 @@ static function getFavItems($report) { } // Add note. - if ($report['show_note']) + if ($options['show_note']) array_push($fields, 'l.comment as note'); // Handle cost. - $includeCost = $report['show_cost']; + $includeCost = $options['show_cost']; if ($includeCost) { if (MODE_TIME == $user->tracking_mode) array_push($fields, "cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use default user rate. @@ -573,30 +573,30 @@ static function getFavItems($report) { array_push($fields, "null as expense"); } // Add paid status. - if ($canViewReports && $report['show_paid']) + if ($canViewReports && $options['show_paid']) array_push($fields, 'l.paid as paid'); // Add IP address. - if ($canViewReports && $report['show_ip']) { + if ($canViewReports && $options['show_ip']) { array_push($fields, 'l.created as created'); array_push($fields, 'l.created_ip as created_ip'); array_push($fields, 'l.modified as modified'); array_push($fields, 'l.modified_ip as modified_ip'); } // Add invoice name if it is selected. - if (($canViewReports || $isClient) && $report['show_invoice']) + if (($canViewReports || $isClient) && $options['show_invoice']) array_push($fields, 'i.name as invoice'); // Prepare sql query part for left joins. $left_joins = null; - if ($report['show_client'] || 'client' == $group_by_option) + if ($options['show_client'] || 'client' == $group_by_option) $left_joins .= " left join tt_clients c on (c.id = l.client_id)"; - if (($canViewReports || $isClient) && $report['show_invoice']) + if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = l.invoice_id and i.status = 1)"; if ($canViewReports || $isClient || $user->isPluginEnabled('ex')) $left_joins .= " left join tt_users u on (u.id = l.user_id)"; - if ($report['show_project'] || 'project' == $group_by_option) + if ($options['show_project'] || 'project' == $group_by_option) $left_joins .= " left join tt_projects p on (p.id = l.project_id)"; - if ($report['show_task'] || 'task' == $group_by_option) + if ($options['show_task'] || 'task' == $group_by_option) $left_joins .= " left join tt_tasks t on (t.id = l.task_id)"; if ($include_cf_1) { if ($cf_1_type == CustomFields::TYPE_TEXT) @@ -609,7 +609,7 @@ static function getFavItems($report) { if ($includeCost && MODE_TIME != $user->tracking_mode) $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; - $where = ttReportHelper::getFavWhere($report); + $where = ttReportHelper::getFavWhere($options); // Construct sql query for tt_log items. $sql = "select ".join(', ', $fields)." from tt_log l $left_joins $where"; @@ -617,7 +617,7 @@ static function getFavItems($report) { // with an exception of sorting part, that is added in the end. // However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table. - if ($report['show_cost'] && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled + if ($options['show_cost'] && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled $fields = array(); // An array of fields for database query. array_push($fields, 'ei.id'); @@ -626,56 +626,56 @@ static function getFavItems($report) { if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. - if ($report['show_client'] || 'client' == $group_by_option) + if ($options['show_client'] || 'client' == $group_by_option) array_push($fields, 'c.name as client'); // Add project name if it is selected. - if ($report['show_project'] || 'project' == $group_by_option) + if ($options['show_project'] || 'project' == $group_by_option) array_push($fields, 'p.name as project'); - if ($report['show_task'] || 'task' == $group_by_option) + if ($options['show_task'] || 'task' == $group_by_option) array_push($fields, 'null'); // null for task name. We need to match column count for union. - if ($report['show_custom_field_1'] || 'cf_1' == $group_by_option) + if ($options['show_custom_field_1'] || 'cf_1' == $group_by_option) array_push($fields, 'null'); // null for cf_1. - if ($report['show_start']) { + if ($options['show_start']) { array_push($fields, 'null'); // null for unformatted_start. array_push($fields, 'null'); // null for start. } - if ($report['show_end']) + if ($options['show_end']) array_push($fields, 'null'); // null for finish. - if ($report['show_duration']) + if ($options['show_duration']) array_push($fields, 'null'); // null for duration. - if ($report['show_work_units']) + if ($options['show_work_units']) array_push($fields, 'null as units'); // null for work units. // Use the note field to print item name. - if ($report['show_note']) + if ($options['show_note']) array_push($fields, 'ei.name as note'); array_push($fields, 'ei.cost as cost'); array_push($fields, 'ei.cost as expense'); // Add paid status. - if ($canViewReports && $report['show_paid']) + if ($canViewReports && $options['show_paid']) array_push($fields, 'ei.paid as paid'); // Add IP address. - if ($canViewReports && $report['show_ip']) { + if ($canViewReports && $options['show_ip']) { array_push($fields, 'ei.created as created'); array_push($fields, 'ei.created_ip as created_ip'); array_push($fields, 'ei.modified as modified'); array_push($fields, 'ei.modified_ip as modified_ip'); } // Add invoice name if it is selected. - if (($canViewReports || $isClient) && $report['show_invoice']) + if (($canViewReports || $isClient) && $options['show_invoice']) array_push($fields, 'i.name as invoice'); // Prepare sql query part for left joins. $left_joins = null; if ($canViewReports || $isClient) $left_joins .= " left join tt_users u on (u.id = ei.user_id)"; - if ($report['show_client'] || 'client' == $group_by_option) + if ($options['show_client'] || 'client' == $group_by_option) $left_joins .= " left join tt_clients c on (c.id = ei.client_id)"; - if ($report['show_project'] || 'project' == $group_by_option) + if ($options['show_project'] || 'project' == $group_by_option) $left_joins .= " left join tt_projects p on (p.id = ei.project_id)"; - if (($canViewReports || $isClient) && $report['show_invoice']) + if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; - $where = ttReportHelper::getFavExpenseWhere($report); + $where = ttReportHelper::getFavExpenseWhere($options); // Construct sql query for expense items. $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $where"; @@ -692,7 +692,7 @@ static function getFavItems($report) { $sort_part .= $group_by_option.', date'; if (($canViewReports || $isClient) /*&& is_array($bean->getAttribute('users'))*/ && 'user' != $group_by_option) $sort_part .= ', user, type'; - if ($report['show_start']) + if ($options['show_start']) $sort_part .= ', unformatted_start'; $sort_part .= ', id'; @@ -894,10 +894,10 @@ static function getSubtotals($bean, $options) { // getFavSubtotals calculates report items subtotals when a favorite report is grouped by. // Without expenses, it's a simple select with group by. // With expenses, it becomes a select with group by from a combined set of records obtained with "union all". - static function getFavSubtotals($report) { + static function getFavSubtotals($options) { global $user; - $group_by_option = $report['group_by']; + $group_by_option = $options['group_by']; if ('no_grouping' == $group_by_option) return null; $mdb2 = getConnection(); @@ -936,13 +936,13 @@ static function getFavSubtotals($report) { break; } - $where = ttReportHelper::getFavWhere($report); - if ($report['show_cost']) { + $where = ttReportHelper::getFavWhere($options); + if ($options['show_cost']) { if (MODE_TIME == $user->tracking_mode) { if ($group_by_option != 'user') $left_join = 'left join tt_users u on (l.user_id = u.id)'; $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; - if ($report['show_work_units']) { + if ($options['show_work_units']) { if ($user->unit_totals_only) $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; else @@ -955,7 +955,7 @@ static function getFavSubtotals($report) { } else { // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; - if ($report['show_work_units']) { + if ($options['show_work_units']) { if ($user->unit_totals_only) $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; else @@ -968,7 +968,7 @@ static function getFavSubtotals($report) { } } else { $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; - if ($report['show_work_units']) { + if ($options['show_work_units']) { if ($user->unit_totals_only) $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; else @@ -980,7 +980,7 @@ static function getFavSubtotals($report) { // By now we have sql for time items. // However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table. - if ($report['show_cost'] && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled + if ($options['show_cost'] && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled // Determine group by field and a required join. $group_join = null; @@ -1004,16 +1004,16 @@ static function getFavSubtotals($report) { break; } - $where = ttReportHelper::getFavExpenseWhere($report); + $where = ttReportHelper::getFavExpenseWhere($options); $sql_for_expenses = "select $group_field as group_field, null as time"; - if ($report['show_work_units']) $sql_for_expenses .= ", null as units"; + if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $group_join $where"; // Add a "group by" clause if we are grouping. if ('null' != $group_field) $sql_for_expenses .= " group by $group_field"; // Create a combined query. $combined = "select group_field, sum(time) as time"; - if ($report['show_work_units']) $combined .= ", sum(units) as units"; + if ($options['show_work_units']) $combined .= ", sum(units) as units"; $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; $sql = $combined; } @@ -1030,7 +1030,7 @@ static function getFavSubtotals($report) { unset($o_date); } $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; - if ($report['show_cost']) { + if ($options['show_cost']) { if ('.' != $user->decimal_mark) { $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']); @@ -1126,20 +1126,20 @@ static function getTotals($bean, $options) } // getFavTotals calculates total hours and cost for all favorite report items. - static function getFavTotals($report) + static function getFavTotals($options) { global $user; $mdb2 = getConnection(); - $where = ttReportHelper::getFavWhere($report); + $where = ttReportHelper::getFavWhere($options); // Prepare parts. $time_part = "sum(time_to_sec(l.duration)) as time"; - if ($report['show_work_units']) { + if ($options['show_work_units']) { $units_part = $user->unit_totals_only ? ", null as units" : ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; } - if ($report['show_cost']) { + if ($options['show_cost']) { if (MODE_TIME == $user->tracking_mode) $cost_part = ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses"; else @@ -1147,7 +1147,7 @@ static function getFavTotals($report) } else { $cost_part = ", null as cost, null as expenses"; } - if ($report['show_cost']) { + if ($options['show_cost']) { if (MODE_TIME == $user->tracking_mode) { $left_joins = "left join tt_users u on (l.user_id = u.id)"; } else { @@ -1158,15 +1158,15 @@ static function getFavTotals($report) $sql = "select $time_part $units_part $cost_part from tt_log l $left_joins $where"; // If we have expenses, query becomes a bit more complex. - if ($report['show_cost'] && $user->isPluginEnabled('ex')) { - $where = ttReportHelper::getFavExpenseWhere($report); + if ($options['show_cost'] && $user->isPluginEnabled('ex')) { + $where = ttReportHelper::getFavExpenseWhere($options); $sql_for_expenses = "select null as time"; - if ($report['show_work_units']) $sql_for_expenses .= ", null as units"; + if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; // Create a combined query. $combined = "select sum(time) as time"; - if ($report['show_work_units']) $combined .= ", sum(units) as units"; + if ($options['show_work_units']) $combined .= ", sum(units) as units"; $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t"; $sql = $combined; } @@ -1177,7 +1177,7 @@ static function getFavTotals($report) $val = $res->fetchRow(); $total_time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; - if ($report['show_cost']) { + if ($options['show_cost']) { $total_cost = $val['cost']; if (!$total_cost) $total_cost = '0.00'; if ('.' != $user->decimal_mark) @@ -1188,13 +1188,13 @@ static function getFavTotals($report) $total_expenses = str_replace('.', $user->decimal_mark, $total_expenses); } - if ($report['period']) - $period = new Period($report['period'], new DateAndTime($user->date_format)); + if ($options['period']) + $period = new Period($options['period'], new DateAndTime($user->date_format)); else { $period = new Period(); $period->setPeriod( - new DateAndTime($user->date_format, $report['period_start']), - new DateAndTime($user->date_format, $report['period_end'])); + new DateAndTime($user->date_format, $options['period_start']), + new DateAndTime($user->date_format, $options['period_end'])); } $totals['start_date'] = $period->getStartDate(); @@ -1545,9 +1545,9 @@ static function prepareReportBody($bean, $comment) } // checkFavReportCondition - checks whether it is okay to send fav report. - static function checkFavReportCondition($report, $condition) + static function checkFavReportCondition($options, $condition) { - $items = ttReportHelper::getFavItems($report); + $items = ttReportHelper::getFavItems($options); $condition = str_replace('count', '', $condition); $count_required = (int) trim(str_replace('>', '', $condition)); @@ -1559,7 +1559,7 @@ static function checkFavReportCondition($report, $condition) } // prepareFavReportBody - prepares an email body for a favorite report. - static function prepareFavReportBody($report) + static function prepareFavReportBody($options) { global $user; global $i18n; @@ -1568,11 +1568,11 @@ static function prepareFavReportBody($report) $canViewReports = $user->can('view_reports'); $isClient = $user->isClient(); - $items = ttReportHelper::getFavItems($report); - $group_by = $report['group_by']; + $items = ttReportHelper::getFavItems($options); + $group_by = $options['group_by']; if ($group_by && 'no_grouping' != $group_by) - $subtotals = ttReportHelper::getFavSubtotals($report); - $totals = ttReportHelper::getFavTotals($report); + $subtotals = ttReportHelper::getFavSubtotals($options); + $totals = ttReportHelper::getFavTotals($options); // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) @@ -1601,7 +1601,7 @@ static function prepareFavReportBody($report) // Output comment. // if ($comment) $body .= '

'.htmlspecialchars($comment).'

'; // No comment for fav. reports. - if ($report['show_totals_only']) { + if ($options['show_totals_only']) { // Totals only report. Output subtotals. // Determine group_by header. @@ -1615,27 +1615,27 @@ static function prepareFavReportBody($report) $body .= ''; $body .= ''; $body .= ''; - if ($report['show_duration']) + if ($options['show_duration']) $body .= ''; - if ($report['show_work_units']) + if ($options['show_work_units']) $body .= ''; - if ($report['show_cost']) + if ($options['show_cost']) $body .= ''; $body .= ''; foreach($subtotals as $subtotal) { $body .= ''; $body .= ''; - if ($report['show_duration']) { + if ($options['show_duration']) { $body .= ''; } - if ($report['show_work_units']) { + if ($options['show_work_units']) { $body .= ''; } - if ($report['show_cost']) { + if ($options['show_cost']) { $body .= ''; @@ -1647,17 +1647,17 @@ static function prepareFavReportBody($report) $body .= ''; $body .= ''; $body .= ''; - if ($report['show_duration']) { + if ($options['show_duration']) { $body .= ''; } - if ($report['show_work_units']) { + if ($options['show_work_units']) { $body .= ''; } - if ($report['show_cost']) { + if ($options['show_cost']) { $body .= ''; @@ -1674,31 +1674,31 @@ static function prepareFavReportBody($report) $body .= ''; if ($canViewReports || $isClient) $body .= ''; - if ($report['show_client']) + if ($options['show_client']) $body .= ''; - if ($report['show_project']) + if ($options['show_project']) $body .= ''; - if ($report['show_task']) + if ($options['show_task']) $body .= ''; - if ($report['show_custom_field_1']) + if ($options['show_custom_field_1']) $body .= ''; - if ($report['show_start']) + if ($options['show_start']) $body .= ''; - if ($report['show_end']) + if ($options['show_end']) $body .= ''; - if ($report['show_duration']) + if ($options['show_duration']) $body .= ''; - if ($report['show_work_units']) + if ($options['show_work_units']) $body .= ''; - if ($report['show_note']) + if ($options['show_note']) $body .= ''; - if ($report['show_cost']) + if ($options['show_cost']) $body .= ''; - if ($report['show_paid']) + if ($options['show_paid']) $body .= ''; - if ($report['show_ip']) + if ($options['show_ip']) $body .= ''; - if ($report['show_invoice']) + if ($options['show_invoice']) $body .= ''; $body .= ''; @@ -1726,23 +1726,23 @@ static function prepareFavReportBody($report) $body .= ''; $subtotal_name = htmlspecialchars($subtotals[$prev_grouped_by]['name']); if ($canViewReports || $isClient) $body .= ''; - if ($report['show_client']) $body .= ''; - if ($report['show_project']) $body .= ''; - if ($report['show_task']) $body .= ''; - if ($report['show_custom_field_1']) $body .= ''; - if ($report['show_start']) $body .= ''; - if ($report['show_end']) $body .= ''; - if ($report['show_duration']) $body .= ''; - if ($report['show_work_units']) $body .= ''; - if ($report['show_note']) $body .= ''; - if ($report['show_cost']) { + if ($options['show_client']) $body .= ''; + if ($options['show_project']) $body .= ''; + if ($options['show_task']) $body .= ''; + if ($options['show_custom_field_1']) $body .= ''; + if ($options['show_start']) $body .= ''; + if ($options['show_end']) $body .= ''; + if ($options['show_duration']) $body .= ''; + if ($options['show_work_units']) $body .= ''; + if ($options['show_note']) $body .= ''; + if ($options['show_cost']) { $body .= ''; } - if ($report['show_paid']) $body .= ''; - if ($report['show_ip']) $body .= ''; - if ($report['show_invoice']) $body .= ''; + if ($options['show_paid']) $body .= ''; + if ($options['show_ip']) $body .= ''; + if ($options['show_invoice']) $body .= ''; $body .= ''; $body .= ''; } @@ -1756,37 +1756,37 @@ static function prepareFavReportBody($report) $body .= ''; if ($canViewReports || $isClient) $body .= ''; - if ($report['show_client']) + if ($options['show_client']) $body .= ''; - if ($report['show_project']) + if ($options['show_project']) $body .= ''; - if ($report['show_task']) + if ($options['show_task']) $body .= ''; - if ($report['show_custom_field_1']) + if ($options['show_custom_field_1']) $body .= ''; - if ($report['show_start']) + if ($options['show_start']) $body .= ''; - if ($report['show_end']) + if ($options['show_end']) $body .= ''; - if ($report['show_duration']) + if ($options['show_duration']) $body .= ''; - if ($report['show_work_units']) + if ($options['show_work_units']) $body .= ''; - if ($report['show_note']) + if ($options['show_note']) $body .= ''; - if ($report['show_cost']) + if ($options['show_cost']) $body .= ''; - if ($report['show_paid']) { + if ($options['show_paid']) { $body .= ''; } - if ($report['show_ip']) { + if ($options['show_ip']) { $body .= ''; } - if ($report['show_invoice']) + if ($options['show_invoice']) $body .= ''; $body .= ''; @@ -1802,23 +1802,23 @@ static function prepareFavReportBody($report) $body .= ''; $subtotal_name = htmlspecialchars($subtotals[$cur_grouped_by]['name']); if ($canViewReports || $isClient) $body .= ''; - if ($report['show_client']) $body .= ''; - if ($report['show_project']) $body .= ''; - if ($report['show_task']) $body .= ''; - if ($report['show_custom_field_1']) $body .= ''; - if ($report['show_start']) $body .= ''; - if ($report['show_end']) $body .= ''; - if ($report['show_duration']) $body .= ''; - if ($report['show_work_units']) $body .= ''; - if ($report['show_note']) $body .= ''; - if ($report['show_cost']) { + if ($options['show_client']) $body .= ''; + if ($options['show_project']) $body .= ''; + if ($options['show_task']) $body .= ''; + if ($options['show_custom_field_1']) $body .= ''; + if ($options['show_start']) $body .= ''; + if ($options['show_end']) $body .= ''; + if ($options['show_duration']) $body .= ''; + if ($options['show_work_units']) $body .= ''; + if ($options['show_note']) $body .= ''; + if ($options['show_cost']) { $body .= ''; } - if ($report['show_paid']) $body .= ''; - if ($report['show_ip']) $body .= ''; - if ($report['show_invoice']) $body .= ''; + if ($options['show_paid']) $body .= ''; + if ($options['show_ip']) $body .= ''; + if ($options['show_invoice']) $body .= ''; $body .= ''; } @@ -1827,23 +1827,23 @@ static function prepareFavReportBody($report) $body .= ''; $body .= ''; if ($canViewReports || $isClient) $body .= ''; - if ($report['show_client']) $body .= ''; - if ($report['show_project']) $body .= ''; - if ($report['show_task']) $body .= ''; - if ($report['show_custom_field_1']) $body .= ''; - if ($report['show_start']) $body .= ''; - if ($report['show_end']) $body .= ''; - if ($report['show_duration']) $body .= ''; - if ($report['show_work_units']) $body .= ''; - if ($report['show_note']) $body .= ''; - if ($report['show_cost']) { + if ($options['show_client']) $body .= ''; + if ($options['show_project']) $body .= ''; + if ($options['show_task']) $body .= ''; + if ($options['show_custom_field_1']) $body .= ''; + if ($options['show_start']) $body .= ''; + if ($options['show_end']) $body .= ''; + if ($options['show_duration']) $body .= ''; + if ($options['show_work_units']) $body .= ''; + if ($options['show_note']) $body .= ''; + if ($options['show_cost']) { $body .= ''; } - if ($report['show_paid']) $body .= ''; - if ($report['show_ip']) $body .= ''; - if ($report['show_invoice']) $body .= ''; + if ($options['show_paid']) $body .= ''; + if ($options['show_ip']) $body .= ''; + if ($options['show_invoice']) $body .= ''; $body .= ''; $body .= '
'.$group_by_header.''.$i18n->get('label.duration').''.$i18n->get('label.work_units_short').''.$i18n->get('label.cost').'
'.($subtotal['name'] ? htmlspecialchars($subtotal['name']) : ' ').''; if ($subtotal['time'] <> '0:00') $body .= $subtotal['time']; $body .= ''; $body .= $subtotal['units']; $body .= ''; $body .= ($canViewReports || $isClient) ? $subtotal['cost'] : $subtotal['expenses']; $body .= '
 
'.$i18n->get('label.total').''; if ($totals['time'] <> '0:00') $body .= $totals['time']; $body .= ''; $body .= $totals['units']; $body .= ''.htmlspecialchars($user->currency).' '; $body .= ($canViewReports || $isClient) ? $totals['cost'] : $totals['expenses']; $body .= ''.$i18n->get('label.date').''.$i18n->get('label.user').''.$i18n->get('label.client').''.$i18n->get('label.project').''.$i18n->get('label.task').''.htmlspecialchars($custom_fields->fields[0]['label']).''.$i18n->get('label.start').''.$i18n->get('label.finish').''.$i18n->get('label.duration').''.$i18n->get('label.work_units_short').''.$i18n->get('label.note').''.$i18n->get('label.cost').''.$i18n->get('label.paid').''.$i18n->get('label.ip').''.$i18n->get('label.invoice').'
'.$i18n->get('label.subtotal').''.($group_by == 'user' ? $subtotal_name : '').''.($group_by == 'client' ? $subtotal_name : '').''.($group_by == 'project' ? $subtotal_name : '').''.($group_by == 'task' ? $subtotal_name : '').''.($group_by == 'cf_1' ? $subtotal_name : '').''.$subtotals[$prev_grouped_by]['time'].''.$subtotals[$prev_grouped_by]['units'].''.($group_by == 'client' ? $subtotal_name : '').''.($group_by == 'project' ? $subtotal_name : '').''.($group_by == 'task' ? $subtotal_name : '').''.($group_by == 'cf_1' ? $subtotal_name : '').''.$subtotals[$prev_grouped_by]['time'].''.$subtotals[$prev_grouped_by]['units'].''; $body .= ($canViewReports || $isClient) ? $subtotals[$prev_grouped_by]['cost'] : $subtotals[$prev_grouped_by]['expenses']; $body .= '
 
'.$record['date'].''.htmlspecialchars($record['user']).''.htmlspecialchars($record['client']).''.htmlspecialchars($record['project']).''.htmlspecialchars($record['task']).''.htmlspecialchars($record['cf_1']).''.$record['start'].''.$record['finish'].''.$record['duration'].''.$record['units'].''.htmlspecialchars($record['note']).''.$record['cost'].''; $body .= $record['paid'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); $body .= ''; $body .= $record['modified'] ? $record['modified_ip'].' '.$record['modified'] : $record['created_ip'].' '.$record['created']; $body .= ''.htmlspecialchars($record['invoice']).'
'.$i18n->get('label.subtotal').''.($group_by == 'user' ? $subtotal_name : '').''.($group_by == 'client' ? $subtotal_name : '').''.($group_by == 'project' ? $subtotal_name : '').''.($group_by == 'task' ? $subtotal_name : '').''.($group_by == 'cf_1' ? $subtotal_name : '').''.$subtotals[$cur_grouped_by]['time'].''.$subtotals[$cur_grouped_by]['units'].''.($group_by == 'client' ? $subtotal_name : '').''.($group_by == 'project' ? $subtotal_name : '').''.($group_by == 'task' ? $subtotal_name : '').''.($group_by == 'cf_1' ? $subtotal_name : '').''.$subtotals[$cur_grouped_by]['time'].''.$subtotals[$cur_grouped_by]['units'].''; $body .= ($canViewReports || $isClient) ? $subtotals[$cur_grouped_by]['cost'] : $subtotals[$cur_grouped_by]['expenses']; $body .= '
'.$i18n->get('label.total').''.$totals['time'].''.$totals['units'].''.$totals['time'].''.$totals['units'].''.htmlspecialchars($user->currency).' '; $body .= ($canViewReports || $isClient) ? $totals['cost'] : $totals['expenses']; $body .= '
'; @@ -1860,14 +1860,14 @@ static function prepareFavReportBody($report) } // sendFavReport - sends a favorite report to a specified email, called from cron.php - static function sendFavReport($report, $subject, $email, $cc) { + static function sendFavReport($options, $subject, $email, $cc) { // We are called from cron.php, we have no $bean in session. // cron.php sets global $user and $i18n objects to match our favorite report user. global $user; global $i18n; // Prepare report body. - $body = ttReportHelper::prepareFavReportBody($report); + $body = ttReportHelper::prepareFavReportBody($options); import('mail.Mailer'); $mailer = new Mailer(); @@ -1880,7 +1880,7 @@ static function sendFavReport($report, $subject, $email, $cc) { $mailer->setReceiverBCC($user->bcc_email); $mailer->setReceiver($email); $mailer->setMailMode(MAIL_MODE); - if (empty($subject)) $subject = $report['name']; + if (empty($subject)) $subject = $options['name']; if (!$mailer->send($subject, $body)) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bbef7b8d3..654f80442 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.93.4288 | Copyright © Anuko | +  Anuko Time Tracker 1.17.93.4289 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cron.php b/cron.php index 262cafe54..50d5d7cfb 100644 --- a/cron.php +++ b/cron.php @@ -59,11 +59,11 @@ // We have jobs to execute in user language. // Get favorite report details. - $report = ttFavReportHelper::getReportOptions($val['report_id']); - if (!$report) continue; // Skip not found report. + $options = ttFavReportHelper::getReportOptions($val['report_id']); + if (!$options) continue; // Skip not found report. // Recycle global $user object, as user settings are specific for each report. - $user = new ttUser(null, $report['user_id']); + $user = new ttUser(null, $options['user_id']); if (!$user->id) continue; // Skip not found user. // Recycle $i18n object because language is user-specific. $i18n->load($user->lang); @@ -71,11 +71,11 @@ // Check condition on a report. $condition_ok = true; if ($val['report_condition']) - $condition_ok = ttReportHelper::checkFavReportCondition($report, $val['report_condition']); + $condition_ok = ttReportHelper::checkFavReportCondition($options, $val['report_condition']); // Email report if condition is okay. if ($condition_ok) { - if (ttReportHelper::sendFavReport($report, $val['subject'], $val['email'], $val['cc'])) + if (ttReportHelper::sendFavReport($options, $val['subject'], $val['email'], $val['cc'])) echo "Report ".$val['report_id']. " sent.
"; else echo "Error while emailing report...
"; From 3c959f0cd6c32bcfa962480ebd87e7ee4ae6d5c1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Jul 2018 16:57:36 +0000 Subject: [PATCH 0186/1848] A bit more progress on report refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 15 +++++++-------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index ae5698d2c..624ea8f3d 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -47,9 +47,9 @@ static function getWhere($bean, $options) { $dropdown_parts .= ' and l.client_id = '.$options['client_id']; elseif ($user->isClient() && $user->client_id) $dropdown_parts .= ' and l.client_id = '.$user->client_id; - if ($bean->getAttribute('option')) $dropdown_parts .= ' and l.id in(select log_id from tt_custom_field_log where status = 1 and option_id = '.$bean->getAttribute('option').')'; - if ($bean->getAttribute('project')) $dropdown_parts .= ' and l.project_id = '.$bean->getAttribute('project'); - if ($bean->getAttribute('task')) $dropdown_parts .= ' and l.task_id = '.$bean->getAttribute('task'); + if ($options['cf_1_option_id']) $dropdown_parts .= ' and l.id in(select log_id from tt_custom_field_log where status = 1 and option_id = '.$options['cf_1_option_id'].')'; + if ($options['project_id']) $dropdown_parts .= ' and l.project_id = '.$options['project_id']; + if ($options['task_id']) $dropdown_parts .= ' and l.task_id = '.$options['task_id']; if ($bean->getAttribute('include_records')=='1') $dropdown_parts .= ' and l.billable = 1'; if ($bean->getAttribute('include_records')=='2') $dropdown_parts .= ' and l.billable = 0'; if ($bean->getAttribute('invoice')=='1') $dropdown_parts .= ' and l.invoice_id is not NULL'; @@ -145,7 +145,7 @@ static function getExpenseWhere($bean, $options) { $dropdown_parts .= ' and l.client_id = '.$options['client_id']; elseif ($user->isClient() && $user->client_id) $dropdown_parts .= ' and ei.client_id = '.$user->client_id; - if ($bean->getAttribute('project')) $dropdown_parts .= ' and ei.project_id = '.$bean->getAttribute('project'); + if ($options['project_id']) $dropdown_parts .= ' and ei.project_id = '.$options['project_id']; if ($bean->getAttribute('invoice')=='1') $dropdown_parts .= ' and ei.invoice_id is not NULL'; if ($bean->getAttribute('invoice')=='2') $dropdown_parts .= ' and ei.invoice_id is NULL'; if ($bean->getAttribute('paid_status')=='1') $dropdown_parts .= ' and ei.paid = 1'; @@ -1903,13 +1903,12 @@ static function getReportOptions($bean) { $options['name'] = null; // No name required. $options['user_id'] = $user->id; // Not sure if we need user_id here. Fav reports use it to recycle $user object in cron.php. $options['client_id'] = $bean->getAttribute('client'); + $options['cf_1_option_id'] = $bean->getAttribute('option'); + $options['project_id'] = $bean->getAttribute('project'); + $options['task_id'] = $bean->getAttribute('task'); /* * TODO: remaining fields to fill in... - `client_id` int(11) default NULL, # client id (if selected) - `cf_1_option_id` int(11) default NULL, # custom field 1 option id (if selected) - `project_id` int(11) default NULL, # project id (if selected) - `task_id` int(11) default NULL, # task id (if selected) `billable` tinyint(4) default NULL, # whether to include billable, not billable, or all records `invoice` tinyint(4) default NULL, # whether to include invoiced, not invoiced, or all records `paid_status` tinyint(4) default NULL, # whether to include paid, not paid, or all records diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 654f80442..49a8ee805 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.93.4289 | Copyright © Anuko | +  Anuko Time Tracker 1.17.93.4290 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 0861ff3430ddb8ae58b0399ca3b6eced35cdb360 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Jul 2018 17:22:58 +0000 Subject: [PATCH 0187/1848] More refactoring in reports. --- WEB-INF/lib/ttReportHelper.class.php | 26 +++++++++++++------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 624ea8f3d..b33ded870 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -50,12 +50,12 @@ static function getWhere($bean, $options) { if ($options['cf_1_option_id']) $dropdown_parts .= ' and l.id in(select log_id from tt_custom_field_log where status = 1 and option_id = '.$options['cf_1_option_id'].')'; if ($options['project_id']) $dropdown_parts .= ' and l.project_id = '.$options['project_id']; if ($options['task_id']) $dropdown_parts .= ' and l.task_id = '.$options['task_id']; - if ($bean->getAttribute('include_records')=='1') $dropdown_parts .= ' and l.billable = 1'; - if ($bean->getAttribute('include_records')=='2') $dropdown_parts .= ' and l.billable = 0'; - if ($bean->getAttribute('invoice')=='1') $dropdown_parts .= ' and l.invoice_id is not NULL'; - if ($bean->getAttribute('invoice')=='2') $dropdown_parts .= ' and l.invoice_id is NULL'; - if ($bean->getAttribute('paid_status')=='1') $dropdown_parts .= ' and l.paid = 1'; - if ($bean->getAttribute('paid_status')=='2') $dropdown_parts .= ' and l.paid = 0'; + if ($options['billable']=='1') $dropdown_parts .= ' and l.billable = 1'; + if ($options['billable']=='2') $dropdown_parts .= ' and l.billable = 0'; + if ($options['invoice']=='1') $dropdown_parts .= ' and l.invoice_id is not NULL'; + if ($options['invoice']=='2') $dropdown_parts .= ' and l.invoice_id is NULL'; + if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; + if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; // Prepare user list part. $userlist = -1; @@ -146,10 +146,10 @@ static function getExpenseWhere($bean, $options) { elseif ($user->isClient() && $user->client_id) $dropdown_parts .= ' and ei.client_id = '.$user->client_id; if ($options['project_id']) $dropdown_parts .= ' and ei.project_id = '.$options['project_id']; - if ($bean->getAttribute('invoice')=='1') $dropdown_parts .= ' and ei.invoice_id is not NULL'; - if ($bean->getAttribute('invoice')=='2') $dropdown_parts .= ' and ei.invoice_id is NULL'; - if ($bean->getAttribute('paid_status')=='1') $dropdown_parts .= ' and ei.paid = 1'; - if ($bean->getAttribute('paid_status')=='2') $dropdown_parts .= ' and ei.paid = 0'; + if ($options['invoice']=='1') $dropdown_parts .= ' and ei.invoice_id is not NULL'; + if ($options['invoice']=='2') $dropdown_parts .= ' and ei.invoice_id is NULL'; + if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; + if ($options['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; // Prepare user list part. $userlist = -1; @@ -1906,12 +1906,12 @@ static function getReportOptions($bean) { $options['cf_1_option_id'] = $bean->getAttribute('option'); $options['project_id'] = $bean->getAttribute('project'); $options['task_id'] = $bean->getAttribute('task'); + $options['billable'] = $bean->getAttribute('include_records'); + $options['invoice'] = $bean->getAttribute('invoice'); + $options['paid_status'] = $bean->getAttribute('paid_status'); /* * TODO: remaining fields to fill in... - `billable` tinyint(4) default NULL, # whether to include billable, not billable, or all records - `invoice` tinyint(4) default NULL, # whether to include invoiced, not invoiced, or all records - `paid_status` tinyint(4) default NULL, # whether to include paid, not paid, or all records `users` text default NULL, # Comma-separated list of user ids. Nothing here means "all" users. `period` tinyint(4) default NULL, # selected period type for report `period_start` date default NULL, # period start diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 49a8ee805..48c12a76f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.93.4290 | Copyright © Anuko | +  Anuko Time Tracker 1.17.93.4291 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6072ff00f2f58e59e2e1138771038b42bc9f32aa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Jul 2018 19:18:19 +0000 Subject: [PATCH 0188/1848] More refactoring in reports. --- WEB-INF/lib/ttReportHelper.class.php | 43 ++++++++++++++-------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index b33ded870..74ddd5828 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -57,25 +57,27 @@ static function getWhere($bean, $options) { if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; - // Prepare user list part. - $userlist = -1; - if (($user->can('view_reports') || $user->isClient()) && is_array($bean->getAttribute('users'))) - $userlist = join(',', $bean->getAttribute('users')); + // Note: "Prepare sql query part for user list" is different in getFavWhere because of + // special meaning of NULL value (all "active" users). + // + // If we are merging into one function, one needs to take care of this, perhaps, with redesign. + // Prepare sql query part for user list. + $userlist = $options['users'] ? $options['users'] : '-1'; $user_list_part = null; - if ($user->can('view_reports') || $user->isClient()) + if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and l.user_id in ($userlist)"; else $user_list_part = " and l.user_id = ".$user->id; // Prepare sql query part for where. - if ($bean->getAttribute('period')) - $period = new Period($bean->getAttribute('period'), new DateAndTime($user->date_format)); + if ($options['period']) + $period = new Period($options['period'], new DateAndTime($user->date_format)); else { $period = new Period(); $period->setPeriod( - new DateAndTime($user->date_format, $bean->getAttribute('start_date')), - new DateAndTime($user->date_format, $bean->getAttribute('end_date'))); + new DateAndTime($user->date_format, $options['period_start']), + new DateAndTime($user->date_format, $options['period_end'])); } $where = " where l.status = 1 and l.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". " $user_list_part $dropdown_parts"; @@ -151,25 +153,22 @@ static function getExpenseWhere($bean, $options) { if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; - // Prepare user list part. - $userlist = -1; - if (($user->can('view_reports') || $user->isClient()) && is_array($bean->getAttribute('users'))) - $userlist = join(',', $bean->getAttribute('users')); // Prepare sql query part for user list. + $userlist = $options['users'] ? $options['users'] : '-1'; $user_list_part = null; - if ($user->can('view_reports') || $user->isClient()) + if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and ei.user_id in ($userlist)"; else $user_list_part = " and ei.user_id = ".$user->id; // Prepare sql query part for where. - if ($bean->getAttribute('period')) - $period = new Period($bean->getAttribute('period'), new DateAndTime($user->date_format)); + if ($options['period']) + $period = new Period($options['period'], new DateAndTime($user->date_format)); else { $period = new Period(); $period->setPeriod( - new DateAndTime($user->date_format, $bean->getAttribute('start_date')), - new DateAndTime($user->date_format, $bean->getAttribute('end_date'))); + new DateAndTime($user->date_format, $options['period_start']), + new DateAndTime($user->date_format, $options['period_end'])); } $where = " where ei.status = 1 and ei.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and ei.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". " $user_list_part $dropdown_parts"; @@ -1909,13 +1908,13 @@ static function getReportOptions($bean) { $options['billable'] = $bean->getAttribute('include_records'); $options['invoice'] = $bean->getAttribute('invoice'); $options['paid_status'] = $bean->getAttribute('paid_status'); + if (is_array($bean->getAttribute('users'))) $options['users'] = join(',', $bean->getAttribute('users')); + $options['period'] = $bean->getAttribute('period'); + $options['period_start'] = $bean->getAttribute('start_date'); + $options['period_end'] = $bean->getAttribute('end_date'); /* * TODO: remaining fields to fill in... - `users` text default NULL, # Comma-separated list of user ids. Nothing here means "all" users. - `period` tinyint(4) default NULL, # selected period type for report - `period_start` date default NULL, # period start - `period_end` date default NULL, # period end `show_client` tinyint(4) NOT NULL default 0, # whether to show client column `show_invoice` tinyint(4) NOT NULL default 0, # whether to show invoice column `show_paid` tinyint(4) NOT NULL default 0, # whether to show paid column diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 48c12a76f..33aba4ff5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.93.4291 | Copyright © Anuko | +  Anuko Time Tracker 1.17.93.4292 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 3d9beabc77b40f26d2ae76269d03ca1c379f0bd0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Jul 2018 20:29:50 +0000 Subject: [PATCH 0189/1848] Security fix for reports. --- WEB-INF/lib/ttReportHelper.class.php | 22 ++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- reports.php | 4 ++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 74ddd5828..acf33681d 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1936,4 +1936,26 @@ static function getReportOptions($bean) { */ return $options; } + + // verifyBean is a security function to make sure data in bean makes sense for a group. + static function verifyBean($bean) { + global $user; + + // Check users. + $users_in_bean = $bean->getAttribute('users'); + if (is_array($users_in_bean)) { + $users_in_group = ttTeamHelper::getUsers(); + foreach ($users_in_group as $user_in_group) { + $valid_ids[] = $user_in_group['id']; + } + foreach ($users_in_bean as $user_in_bean) { + if (!in_array($user_in_bean, $valid_ids)) { + return false; + } + } + } + + // TODO: add additional checks here. Perhaps do it before saving the bean for consistency. + return true; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 33aba4ff5..5b3bf4e75 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.93.4292 | Copyright © Anuko | +  Anuko Time Tracker 1.17.94.4293 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 0565cf71d..79c011f98 100644 --- a/reports.php +++ b/reports.php @@ -35,6 +35,7 @@ import('ttProjectHelper'); import('ttFavReportHelper'); import('ttClientHelper'); +import('ttReportHelper'); // Access check. if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports'))) { @@ -334,6 +335,9 @@ } $bean->saveBean(); + // Check some more values. TODO: Perhaps it's not a good place to check values, re-evaluate this. + // Also make sure other post variations are sane. + if (!ttReportHelper::verifyBean($bean)) $err->add($i18n->get('error.sys')); if ($err->no()) { // Now we can go ahead and create a report. From 7f94d3c91c405b7c5324b8b07cc8c66fabc40b77 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Jul 2018 14:13:15 +0000 Subject: [PATCH 0190/1848] Fixed a bug when reports where still sent with disabled Notifications. --- WEB-INF/templates/footer.tpl | 2 +- cron.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5b3bf4e75..028380aa6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.94.4293 | Copyright © Anuko | +  Anuko Time Tracker 1.17.95.4294 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cron.php b/cron.php index 50d5d7cfb..94a20ddad 100644 --- a/cron.php +++ b/cron.php @@ -65,6 +65,10 @@ // Recycle global $user object, as user settings are specific for each report. $user = new ttUser(null, $options['user_id']); if (!$user->id) continue; // Skip not found user. + + // Skip users with disabled Notifications plugin. + if (!$user->isPluginEnabled('no')) continue; + // Recycle $i18n object because language is user-specific. $i18n->load($user->lang); From eb39786a6d545fab4e795ce42f3cc5504ec69551 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Jul 2018 16:08:21 +0000 Subject: [PATCH 0191/1848] Resumed refactoring of reports. --- WEB-INF/templates/footer.tpl | 2 +- reports.php | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 028380aa6..5dd885172 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.95.4294 | Copyright © Anuko | +  Anuko Time Tracker 1.17.95.4295 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 79c011f98..a2825329e 100644 --- a/reports.php +++ b/reports.php @@ -333,13 +333,11 @@ if ($start_date->compare($end_date) > 0) $err->add($i18n->get('error.interval'), $i18n->get('label.end_date'), $i18n->get('label.start_date')); } - - $bean->saveBean(); - // Check some more values. TODO: Perhaps it's not a good place to check values, re-evaluate this. - // Also make sure other post variations are sane. + // Check remaining values. if (!ttReportHelper::verifyBean($bean)) $err->add($i18n->get('error.sys')); if ($err->no()) { + $bean->saveBean(); // Now we can go ahead and create a report. header('Location: report.php'); exit(); From 09da35919c86360c09fe365fd22c0be34df1c71f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Jul 2018 16:55:24 +0000 Subject: [PATCH 0192/1848] Added group_id field to tt_log and tt_expense_items tables. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 4 +++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5dd885172..c0fe9a67d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.95.4295 | Copyright © Anuko | +  Anuko Time Tracker 1.17.96.4296 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index b49824987..51b01ede9 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11792"]) { + if ($_POST["convert11744to11796"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -901,6 +901,9 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.17.88', modified = now() where param_name = 'version_db' and param_value = '1.17.87'"); setChange("ALTER TABLE `tt_fav_reports` ADD `show_work_units` tinyint(4) NOT NULL DEFAULT '0' AFTER `show_custom_field_1`"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.92', modified = now() where param_name = 'version_db' and param_value = '1.17.88'"); + setChange("ALTER TABLE `tt_log` ADD `group_id` int(11) default NULL AFTER `user_id`"); + setChange("ALTER TABLE `tt_expense_items` ADD `group_id` int(11) default NULL AFTER `user_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.96', modified = now() where param_name = 'version_db' and param_value = '1.17.92'"); } if ($_POST["cleanup"]) { @@ -946,7 +949,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.92) + Create database structure (v1.17.96)
(applies only to new installations, do not execute when updating)
@@ -986,8 +989,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.92)Update database structure (v1.17.44 to v1.17.96)
diff --git a/mysql.sql b/mysql.sql index 267d842dc..796176688 100644 --- a/mysql.sql +++ b/mysql.sql @@ -178,6 +178,7 @@ create index task_idx on tt_project_task_binds(task_id); CREATE TABLE `tt_log` ( `id` bigint NOT NULL auto_increment, # time record id `user_id` int(11) NOT NULL, # user id + `group_id` int(11) default NULL, # group id `date` date NOT NULL, # date the record is for `start` time default NULL, # record start time (for example, 09:00) `duration` time default NULL, # record duration (for example, 1 hour) @@ -387,6 +388,7 @@ CREATE TABLE `tt_expense_items` ( `id` bigint NOT NULL auto_increment, # expense item id `date` date NOT NULL, # date the record is for `user_id` int(11) NOT NULL, # user id the expense item is reported by + `group_id` int(11) default NULL, # group id `client_id` int(11) default NULL, # client id `project_id` int(11) default NULL, # project id `name` text NOT NULL, # expense item name (what is an expense for) @@ -450,4 +452,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.92', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.96', now()); # TODO: change when structure changes. From d086ba7f82e14dd22cc606a2e9f59870811196ed Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Jul 2018 18:15:05 +0000 Subject: [PATCH 0193/1848] Started to populate group_id on new time entry inserts. --- WEB-INF/lib/ttTimeHelper.class.php | 11 ++++++----- WEB-INF/lib/ttUser.class.php | 14 +++++++++++++- WEB-INF/templates/footer.tpl | 2 +- mobile/time.php | 1 + mobile/timer.php | 1 + time.php | 1 + 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index bfb81cc32..5ad07e18f 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -383,13 +383,14 @@ static function isValidInterval($start, $finish) { return false; } - // insert - inserts a time record into log table. Does not deal with custom fields. + // insert - inserts a time record into tt_log table. Does not deal with custom fields. static function insert($fields) { global $user; $mdb2 = getConnection(); $user_id = $fields['user_id']; + $group_id = $fields['group_id']; $date = $fields['date']; $start = $fields['start']; $finish = $fields['finish']; @@ -422,8 +423,8 @@ static function insert($fields) if (!$paid) $paid = 0; if ($duration) { - $sql = "insert into tt_log (user_id, date, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by $status_f) ". - "values ($user_id, ".$mdb2->quote($date).", '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; + $sql = "insert into tt_log (user_id, group_id, date, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by $status_f) ". + "values ($user_id, ".$mdb2->quote($group_id).", ".$mdb2->quote($date).", '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -432,8 +433,8 @@ static function insert($fields) if ($duration === false) $duration = 0; if (!$duration && ttTimeHelper::getUncompleted($user_id)) return false; - $sql = "insert into tt_log (user_id, date, start, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by $status_f) ". - "values ($user_id, ".$mdb2->quote($date).", '$start', '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; + $sql = "insert into tt_log (user_id, group_id, date, start, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by $status_f) ". + "values ($user_id, ".$mdb2->quote($group_id).", ".$mdb2->quote($date).", '$start', '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index e498cde0e..65a1f5962 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -38,7 +38,9 @@ class ttUser { var $rank = null; // User role rank. var $client_id = null; // Client id for client user role. var $behalf_id = null; // User id, on behalf of whom we are working. + var $behalf_group_id = null; // Group id, on behalf of which we are working. var $behalf_name = null; // User name, on behalf of whom we are working. + var $behalf_group = null; // Group name, on behalf of which we are working. var $email = null; // User email. var $lang = null; // Language. var $decimal_mark = null; // Decimal separator. @@ -143,11 +145,16 @@ function __construct($login, $id = null) { $this->unit_totals_only = $config->getDefinedValue('unit_totals_only'); } - // Set "on behalf" id and name. + // Set "on behalf" id and name (user). if (isset($_SESSION['behalf_id'])) { $this->behalf_id = $_SESSION['behalf_id']; $this->behalf_name = $_SESSION['behalf_name']; } + // Set "on behalf" id and name (group). + if (isset($_SESSION['behalf_group_id'])) { + $this->behalf_group_id = $_SESSION['behalf_group_id']; + $this->behalf_group = $_SESSION['behalf_group']; + } } } @@ -156,6 +163,11 @@ function getActiveUser() { return ($this->behalf_id ? $this->behalf_id : $this->id); } + // The getActiveGroup returns group id on behalf of which the current user is operating. + function getActiveGroup() { + return ($this->behalf_group_id ? $this->behalf_group_id : $this->group_id); + } + // can - determines whether user has a right to do something. function can($do_something) { return in_array($do_something, $this->rights); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c0fe9a67d..e20ac62df 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.96.4296 | Copyright © Anuko | +  Anuko Time Tracker 1.17.96.4297 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/time.php b/mobile/time.php index 2649ff279..76296f64b 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -252,6 +252,7 @@ $id = ttTimeHelper::insert(array( 'date' => $cl_date, 'user_id' => $user->getActiveUser(), + 'group_id' => $user->getActiveGroup(), 'client' => $cl_client, 'project' => $cl_project, 'task' => $cl_task, diff --git a/mobile/timer.php b/mobile/timer.php index e547c256d..09500bd22 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -225,6 +225,7 @@ $id = ttTimeHelper::insert(array( 'date' => $cl_date, 'user_id' => $user->getActiveUser(), + 'group_id' => $user->getActiveGroup(), 'client' => $cl_client, 'project' => $cl_project, 'task' => $cl_task, diff --git a/time.php b/time.php index d4caad2b1..98f6bbaf6 100644 --- a/time.php +++ b/time.php @@ -293,6 +293,7 @@ $id = ttTimeHelper::insert(array( 'date' => $cl_date, 'user_id' => $user->getActiveUser(), + 'group_id' => $user->getActiveGroup(), 'client' => $cl_client, 'project' => $cl_project, 'task' => $cl_task, From bcfe9680fdb90d26de543b2c43feabefdcac3c20 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Jul 2018 18:50:15 +0000 Subject: [PATCH 0194/1848] More progress on storing group_id on new inserts. --- WEB-INF/lib/ttExpenseHelper.class.php | 5 +++-- WEB-INF/lib/ttImportHelper.class.php | 2 ++ WEB-INF/lib/ttTimeHelper.class.php | 8 ++++---- WEB-INF/lib/ttWeekViewHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- expense_edit.php | 2 +- expenses.php | 2 +- mobile/expense_edit.php | 2 +- mobile/expenses.php | 2 +- time_edit.php | 1 + 10 files changed, 16 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/ttExpenseHelper.class.php b/WEB-INF/lib/ttExpenseHelper.class.php index 8a4b17153..6d3128fd4 100644 --- a/WEB-INF/lib/ttExpenseHelper.class.php +++ b/WEB-INF/lib/ttExpenseHelper.class.php @@ -36,6 +36,7 @@ static function insert($fields) $date = $fields['date']; $user_id = (int) $fields['user_id']; + $group_id = (int) $fields['group_id']; $client_id = $fields['client_id']; $project_id = $fields['project_id']; $name = $fields['name']; @@ -45,8 +46,8 @@ static function insert($fields) $paid = (int) $fields['paid']; $created = ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); - $sql = "insert into tt_expense_items (date, user_id, client_id, project_id, name, cost, invoice_id, paid, created, created_ip, created_by, status) ". - "values (".$mdb2->quote($date).", $user_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($project_id). + $sql = "insert into tt_expense_items (date, user_id, group_id, client_id, project_id, name, cost, invoice_id, paid, created, created_ip, created_by, status) ". + "values (".$mdb2->quote($date).", $user_id, $group_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($project_id). ", ".$mdb2->quote($name).", ".$mdb2->quote($cost).", ".$mdb2->quote($invoice_id).", $paid $created, ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 7b68ba7ce..8be7a8310 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -248,6 +248,7 @@ function endElement($parser, $name) { $this->logMap[$this->currentElement['ID']] = ttTimeHelper::insert(array( 'user_id' => $this->userMap[$this->currentElement['USER_ID']], + 'group_id' => $this->group_id, 'date' => $this->currentElement['DATE'], 'start' => $this->currentElement['START'], 'finish' => $this->currentElement['FINISH'], @@ -292,6 +293,7 @@ function endElement($parser, $name) { ttExpenseHelper::insert(array( 'date' => $this->currentElement['DATE'], 'user_id' => $this->userMap[$this->currentElement['USER_ID']], + 'group_id' => $this->group_id, 'client_id' => $this->clientMap[$this->currentElement['CLIENT_ID']], 'project_id' => $this->projectMap[$this->currentElement['PROJECT_ID']], 'name' => $this->currentElement['NAME'], diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 5ad07e18f..e30203540 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -389,8 +389,8 @@ static function insert($fields) global $user; $mdb2 = getConnection(); - $user_id = $fields['user_id']; - $group_id = $fields['group_id']; + $user_id = (int) $fields['user_id']; + $group_id = (int) $fields['group_id']; $date = $fields['date']; $start = $fields['start']; $finish = $fields['finish']; @@ -424,7 +424,7 @@ static function insert($fields) if ($duration) { $sql = "insert into tt_log (user_id, group_id, date, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by $status_f) ". - "values ($user_id, ".$mdb2->quote($group_id).", ".$mdb2->quote($date).", '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; + "values ($user_id, $group_id, ".$mdb2->quote($date).", '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -434,7 +434,7 @@ static function insert($fields) if (!$duration && ttTimeHelper::getUncompleted($user_id)) return false; $sql = "insert into tt_log (user_id, group_id, date, start, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by $status_f) ". - "values ($user_id, ".$mdb2->quote($group_id).", ".$mdb2->quote($date).", '$start', '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; + "values ($user_id, $group_id, ".$mdb2->quote($date).", '$start', '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index 27a1bbcf5..dcb39af63 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -493,6 +493,7 @@ static function insertDurationFromWeekView($fields, $custom_fields, $err) { // Prepare an array of fields for regular insert function. $fields4insert = array(); $fields4insert['user_id'] = $user->getActiveUser(); + $fields4insert['group_id'] = $user->getActiveGroup(); $fields4insert['date'] = $entry_date; $fields4insert['duration'] = $fields['duration']; $fields4insert['client'] = ttWeekViewHelper::parseFromWeekViewRow($fields['row_id'], 'cl'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e20ac62df..df6d91d31 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.96.4297 | Copyright © Anuko | +  Anuko Time Tracker 1.17.96.4298 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expense_edit.php b/expense_edit.php index 26cf3bba1..353f5ce53 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -205,7 +205,7 @@ // Now, a new insert. if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'user_id'=>$user->getActiveUser(), + if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'user_id'=>$user->getActiveUser(),'group_id'=>$user->getActiveGroup(), 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); exit(); diff --git a/expenses.php b/expenses.php index 7d7295d29..fa45ad444 100644 --- a/expenses.php +++ b/expenses.php @@ -188,7 +188,7 @@ // Insert record. if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$cl_date,'user_id'=>$user->getActiveUser(), + if (ttExpenseHelper::insert(array('date'=>$cl_date,'user_id'=>$user->getActiveUser(),'group_id'=>$user->getActiveGroup(), 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { header('Location: expenses.php'); exit(); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index f560f5574..338e6c778 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -200,7 +200,7 @@ // Now, a new insert. if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'user_id'=>$user->getActiveUser(), + if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'user_id'=>$user->getActiveUser(),'group_id'=>$user->getActiveGroup(), 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); exit(); diff --git a/mobile/expenses.php b/mobile/expenses.php index c853a2cae..25a1c6025 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -192,7 +192,7 @@ // Insert record. if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$cl_date,'user_id'=>$user->getActiveUser(), + if (ttExpenseHelper::insert(array('date'=>$cl_date,'user_id'=>$user->getActiveUser(),'group_id'=>$user->getActiveGroup(), 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { header('Location: expenses.php'); exit(); diff --git a/time_edit.php b/time_edit.php index fd1851dc3..5f4068829 100644 --- a/time_edit.php +++ b/time_edit.php @@ -365,6 +365,7 @@ $id = ttTimeHelper::insert(array( 'date'=>$new_date->toString(DB_DATEFORMAT), 'user_id'=>$user->getActiveUser(), + 'group_id'=>$user->getActiveGroup(), 'client'=>$cl_client, 'project'=>$cl_project, 'task'=>$cl_task, From d23d7bcb0be0840de0aa847c75e1673dba9302a8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Jul 2018 20:58:10 +0000 Subject: [PATCH 0195/1848] Wrote code to update group_id in 2 tables. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 49 +++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index df6d91d31..a261f3e71 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - +
 Anuko Time Tracker 1.17.96.4298 | Copyright © Anuko | +  Anuko Time Tracker 1.17.96.4299 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 51b01ede9..09c8d02e3 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -906,6 +906,53 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.17.96', modified = now() where param_name = 'version_db' and param_value = '1.17.92'"); } + // The update_group_id function updates group_id field in tt_log and tt_expense_items tables. + if ($_POST["update_group_id"]) { + $mdb2 = getConnection(); + + $sql = "(select distinct user_id from tt_log where group_id is null) union distinct (select distinct user_id from tt_expense_items where group_id is null)"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) { + die($res->getMessage()); + } + $users_updated = 0; + $tt_log_records_updated = 0; + $tt_expense_items_updated = 0; + + // Iterate through result set. + while ($val = $res->fetchRow()) { + $user_id = $val['user_id']; + $sql = "select group_id from tt_users where id = $user_id"; + $result = $mdb2->query($sql); + if (is_a($result, 'PEAR_Error')) { + die($res->getMessage()); + } + $value = $result->fetchRow(); + $group_id = $value['group_id']; + + if ($group_id) { + $sql = "update tt_log set group_id = $group_id where user_id = $user_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) { + die($affected->getMessage()); + } + $tt_log_records_updated += $affected; + + $sql = "update tt_expense_items set group_id = $group_id where user_id = $user_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) { + die($affected->getMessage()); + } + $tt_expense_items_updated += $affected; + $users_updated++; + } else { + print "Error: Could not find group for user $user_id...
\n"; + } + } + print "Updated $tt_log_records_updated tt_log records...
\n"; + print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; + } + if ($_POST["cleanup"]) { $mdb2 = getConnection(); @@ -990,7 +1037,7 @@ function setChange($sql) {
Update database structure (v1.17.44 to v1.17.96)
From 1c55e1b9d6da2173f7e946011908c02dd80df26d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Jul 2018 21:48:56 +0000 Subject: [PATCH 0196/1848] Added group_id to getWhere parts as additional protection. --- WEB-INF/lib/ttReportHelper.class.php | 18 +++++++++--------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index acf33681d..d46e783f7 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -64,11 +64,11 @@ static function getWhere($bean, $options) { // Prepare sql query part for user list. $userlist = $options['users'] ? $options['users'] : '-1'; - $user_list_part = null; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and l.user_id in ($userlist)"; else $user_list_part = " and l.user_id = ".$user->id; + $user_list_part .= " and l.group_id = ".$user->getActiveGroup(); // Prepare sql query part for where. if ($options['period']) @@ -106,22 +106,22 @@ static function getFavWhere($options) { // Prepare user list part. $userlist = -1; - if (($user->can('view_reports') || $user->isClient())) { + if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { if ($options['users']) $userlist = $options['users']; else { - $active_users = ttTeamHelper::getActiveUsers(); - foreach ($active_users as $single_user) + $group_users = ttTeamHelper::getUsers(); // active and inactive users + foreach ($group_users as $single_user) $users[] = $single_user['id']; $userlist = join(',', $users); } } // Prepare sql query part for user list. - $user_list_part = null; - if ($user->can('view_reports') || $user->isClient()) + if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and l.user_id in ($userlist)"; else $user_list_part = " and l.user_id = ".$user->id; + $user_list_part .= " and l.group_id = ".$user->getActiveGroup(); // Prepare sql query part for where. if ($options['period']) @@ -155,11 +155,11 @@ static function getExpenseWhere($bean, $options) { // Prepare sql query part for user list. $userlist = $options['users'] ? $options['users'] : '-1'; - $user_list_part = null; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and ei.user_id in ($userlist)"; else $user_list_part = " and ei.user_id = ".$user->id; + $user_list_part .= " and ei.group_id = ".$user->getActiveGroup(); // Prepare sql query part for where. if ($options['period']) @@ -204,11 +204,11 @@ static function getFavExpenseWhere($options) { } } // Prepare sql query part for user list. - $user_list_part = null; - if ($user->can('view_reports') || $user->isClient()) + if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and ei.user_id in ($userlist)"; else $user_list_part = " and ei.user_id = ".$user->id; + $user_list_part .= " and ei.group_id = ".$user->getActiveGroup(); // Prepare sql query part for where. if ($options['period']) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a261f3e71..d36605b65 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.96.4299 | Copyright © Anuko | +  Anuko Time Tracker 1.17.96.4300 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 0d76b58c818306b35261dd21fd998b9f5fb0a903 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 29 Jul 2018 16:53:01 +0000 Subject: [PATCH 0197/1848] Added indexes on group_id to speed up searches by group_id. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 4 +++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d36605b65..88eb10ac8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.17.96.4300 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4301 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 09c8d02e3..5144d1962 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -805,7 +805,7 @@ function setChange($sql) { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11796"]) { + if ($_POST["convert11744to11797"]) { setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); @@ -904,6 +904,9 @@ function setChange($sql) { setChange("ALTER TABLE `tt_log` ADD `group_id` int(11) default NULL AFTER `user_id`"); setChange("ALTER TABLE `tt_expense_items` ADD `group_id` int(11) default NULL AFTER `user_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.17.96', modified = now() where param_name = 'version_db' and param_value = '1.17.92'"); + setChange("create index group_idx on tt_log(group_id)"); + setChange("create index group_idx on tt_expense_items(group_id)"); + setChange("UPDATE `tt_site_config` SET param_value = '1.17.97', modified = now() where param_name = 'version_db' and param_value = '1.17.96'"); } // The update_group_id function updates group_id field in tt_log and tt_expense_items tables. @@ -996,7 +999,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.96) + Create database structure (v1.17.97)
(applies only to new installations, do not execute when updating)
@@ -1036,8 +1039,8 @@ function setChange($sql) {

Update database structure (v1.17.44 to v1.17.96)
Update database structure (v1.17.44 to v1.17.97)
diff --git a/mysql.sql b/mysql.sql index 796176688..62c1d7c48 100644 --- a/mysql.sql +++ b/mysql.sql @@ -202,6 +202,7 @@ CREATE TABLE `tt_log` ( # Create indexes on tt_log for performance. create index date_idx on tt_log(date); create index user_idx on tt_log(user_id); +create index group_idx on tt_log(group_id); create index client_idx on tt_log(client_id); create index invoice_idx on tt_log(invoice_id); create index project_idx on tt_log(project_id); @@ -408,6 +409,7 @@ CREATE TABLE `tt_expense_items` ( # Create indexes on tt_expense_items for performance. create index date_idx on tt_expense_items(date); create index user_idx on tt_expense_items(user_id); +create index group_idx on tt_expense_items(group_id); create index client_idx on tt_expense_items(client_id); create index project_idx on tt_expense_items(project_id); create index invoice_idx on tt_expense_items(invoice_id); @@ -452,4 +454,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.96', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.97', now()); # TODO: change when structure changes. From 92300e99d757a271d46126193a8cb1f133447294 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 29 Jul 2018 17:42:28 +0000 Subject: [PATCH 0198/1848] Optimized determining inactive groups. --- WEB-INF/lib/ttTeamHelper.class.php | 20 ++++---------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 631d21202..eafc9167c 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -664,9 +664,8 @@ static function getInactiveGroups() { $inactive_groups = array(); $mdb2 = getConnection(); - // Get all group ids for groups created or modified more than 9 months ago. - // $ts = date('Y-m-d', strtotime('-1 year')); - $ts = $mdb2->quote(date('Y-m-d', strtotime('-9 month'))); + // Get all group ids for groups created or modified more than 1 year ago. + $ts = $mdb2->quote(date('Y-m-d', strtotime('-1 year'))); $sql = "select id from tt_groups where created < $ts and (modified is null or modified < $ts) order by id"; $res = $mdb2->query($sql); @@ -688,22 +687,11 @@ static function getInactiveGroups() { // The isGroupActive determines if a group is using Time Tracker or abandoned it. static function isGroupActive($group_id) { - $users = array(); - $mdb2 = getConnection(); - $sql = "select id from tt_users where group_id = $group_id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) die($res->getMessage()); - while ($val = $res->fetchRow()) { - $users[] = $val['id']; - } - $user_list = implode(',', $users); // This is a comma-separated list of user ids. - if (!$user_list) - return false; // No users in group. $count = 0; $ts = date('Y-m-d', strtotime('-2 years')); - $sql = "select count(*) as cnt from tt_log where user_id in ($user_list) and created > '$ts'"; + $sql = "select count(*) as cnt from tt_log where group_id = $group_id and created > '$ts'"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) { @@ -718,7 +706,7 @@ static function isGroupActive($group_id) { // We will consider a group inactive if it has 5 or less time entries made more than 1 year ago. $count_last_year = 0; $ts = date('Y-m-d', strtotime('-1 year')); - $sql = "select count(*) as cnt from tt_log where user_id in ($user_list) and created > '$ts'"; + $sql = "select count(*) as cnt from tt_log where group_id = $group_id and created > '$ts'"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 88eb10ac8..c8f66d4f0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4301 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4302 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 22f23eb8f2f79853e18a4e4e5ded5c4db66cc5f8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 29 Jul 2018 23:30:38 +0000 Subject: [PATCH 0199/1848] Merged getWhere and getFavWhere into one function. --- WEB-INF/lib/ttFavReportHelper.class.php | 36 ++----- WEB-INF/lib/ttReportHelper.class.php | 138 +++--------------------- WEB-INF/templates/footer.tpl | 2 +- cron.php | 23 ++++ 4 files changed, 45 insertions(+), 154 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 88a1338d6..0a21f7c94 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -170,24 +170,9 @@ static function saveReport($user_id, $bean) { if (!$bean->getAttribute('chunits')) $bean->setAttribute('chunits', 0); if (!$bean->getAttribute('chtotalsonly')) $bean->setAttribute('chtotalsonly', 0); - if ($bean->getAttribute('users') && is_array($bean->getAttribute('users'))) { - $users_in_bean = $bean->getAttribute('users'); - - // If all users are selected - use a null value (which means "all users"). - $all_users_selected = true; - if ($user->can('view_reports')) { - $all = ttTeamHelper::getActiveUsers(); - foreach ($all as $one) { - if (!in_array($one['id'], $users_in_bean)) { - $all_users_selected = false; - break; - } - } - } - if ($all_users_selected) - $users = null; - else - $users = join(',', $users_in_bean); + $users_in_bean = $bean->getAttribute('users'); + if ($users_in_bean && is_array($users_in_bean)) { + $users = join(',', $users_in_bean); } if ($bean->getAttribute('start_date')) { $dt = new DateAndTime($user->date_format, $bean->getAttribute('start_date')); @@ -262,18 +247,7 @@ static function loadReport($user_id, &$bean) { $bean->setAttribute('include_records', $val['billable']); $bean->setAttribute('invoice', $val['invoice']); $bean->setAttribute('paid_status', $val['paid_status']); - if ($val['users']) - $bean->setAttribute('users', explode(',', $val['users'])); - else { - // Null users value means "all users". Add them to the bean. - if ($user->can('view_reports')) { - $all = ttTeamHelper::getActiveUsers(); - foreach ($all as $one) { - $all_user_ids[] = $one['id']; - } - $bean->setAttribute('users', $all_user_ids); - } - } + $bean->setAttribute('users', explode(',', $val['users'])); $bean->setAttribute('period', $val['period']); if ($val['period_start']) { $dt = new DateAndTime(DB_DATEFORMAT, $val['period_start']); @@ -346,6 +320,8 @@ static function getReportOptions($id) { unset($options['report_spec']); // Currently not used. unset($options['status']); + // Note: special handling for NULL users field is done in cron.php + // $options now is a subset of db fields from tt_fav_reports table. return $options; } diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index d46e783f7..d76b027ad 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -37,8 +37,7 @@ class ttReportHelper { // getWhere prepares a WHERE clause for a report query. - // Note: $options is a future replacement of $bean, which is work in progress. - static function getWhere($bean, $options) { + static function getWhere($options) { global $user; // Prepare dropdown parts. @@ -57,11 +56,6 @@ static function getWhere($bean, $options) { if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; - // Note: "Prepare sql query part for user list" is different in getFavWhere because of - // special meaning of NULL value (all "active" users). - // - // If we are merging into one function, one needs to take care of this, perhaps, with redesign. - // Prepare sql query part for user list. $userlist = $options['users'] ? $options['users'] : '-1'; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) @@ -84,99 +78,8 @@ static function getWhere($bean, $options) { return $where; } - // getFavWhere prepares a WHERE clause for a favorite report query. - static function getFavWhere($options) { - global $user; - - // Prepare dropdown parts. - $dropdown_parts = ''; - if ($options['client_id']) - $dropdown_parts .= ' and l.client_id = '.$options['client_id']; - elseif ($user->isClient() && $user->client_id) - $dropdown_parts .= ' and l.client_id = '.$user->client_id; - if ($options['cf_1_option_id']) $dropdown_parts .= ' and l.id in(select log_id from tt_custom_field_log where status = 1 and option_id = '.$options['cf_1_option_id'].')'; - if ($options['project_id']) $dropdown_parts .= ' and l.project_id = '.$options['project_id']; - if ($options['task_id']) $dropdown_parts .= ' and l.task_id = '.$options['task_id']; - if ($options['billable']=='1') $dropdown_parts .= ' and l.billable = 1'; - if ($options['billable']=='2') $dropdown_parts .= ' and l.billable = 0'; - if ($options['invoice']=='1') $dropdown_parts .= ' and l.invoice_id is not NULL'; - if ($options['invoice']=='2') $dropdown_parts .= ' and l.invoice_id is NULL'; - if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; - if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; - - // Prepare user list part. - $userlist = -1; - if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { - if ($options['users']) - $userlist = $options['users']; - else { - $group_users = ttTeamHelper::getUsers(); // active and inactive users - foreach ($group_users as $single_user) - $users[] = $single_user['id']; - $userlist = join(',', $users); - } - } - // Prepare sql query part for user list. - if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) - $user_list_part = " and l.user_id in ($userlist)"; - else - $user_list_part = " and l.user_id = ".$user->id; - $user_list_part .= " and l.group_id = ".$user->getActiveGroup(); - - // Prepare sql query part for where. - if ($options['period']) - $period = new Period($options['period'], new DateAndTime($user->date_format)); - else { - $period = new Period(); - $period->setPeriod( - new DateAndTime($user->date_format, $options['period_start']), - new DateAndTime($user->date_format, $options['period_end'])); - } - $where = " where l.status = 1 and l.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". - " $user_list_part $dropdown_parts"; - return $where; - } - // getExpenseWhere prepares WHERE clause for expenses query in a report. - static function getExpenseWhere($bean, $options) { - global $user; - - // Prepare dropdown parts. - $dropdown_parts = ''; - if ($options['client_id']) - $dropdown_parts .= ' and l.client_id = '.$options['client_id']; - elseif ($user->isClient() && $user->client_id) - $dropdown_parts .= ' and ei.client_id = '.$user->client_id; - if ($options['project_id']) $dropdown_parts .= ' and ei.project_id = '.$options['project_id']; - if ($options['invoice']=='1') $dropdown_parts .= ' and ei.invoice_id is not NULL'; - if ($options['invoice']=='2') $dropdown_parts .= ' and ei.invoice_id is NULL'; - if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; - if ($options['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; - - // Prepare sql query part for user list. - $userlist = $options['users'] ? $options['users'] : '-1'; - if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) - $user_list_part = " and ei.user_id in ($userlist)"; - else - $user_list_part = " and ei.user_id = ".$user->id; - $user_list_part .= " and ei.group_id = ".$user->getActiveGroup(); - - // Prepare sql query part for where. - if ($options['period']) - $period = new Period($options['period'], new DateAndTime($user->date_format)); - else { - $period = new Period(); - $period->setPeriod( - new DateAndTime($user->date_format, $options['period_start']), - new DateAndTime($user->date_format, $options['period_end'])); - } - $where = " where ei.status = 1 and ei.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and ei.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". - " $user_list_part $dropdown_parts"; - return $where; - } - - // getFavExpenseWhere prepares a WHERE clause for expenses query in a favorite report. - static function getFavExpenseWhere($options) { + static function getExpenseWhere($options) { global $user; // Prepare dropdown parts. @@ -191,19 +94,8 @@ static function getFavExpenseWhere($options) { if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; - // Prepare user list part. - $userlist = -1; - if (($user->can('view_reports') || $user->isClient())) { - if ($options['users']) - $userlist = $options['users']; - else { - $active_users = ttTeamHelper::getActiveUsers(); - foreach ($active_users as $single_user) - $users[] = $single_user['id']; - $userlist = join(',', $users); - } - } // Prepare sql query part for user list. + $userlist = $options['users'] ? $options['users'] : '-1'; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and ei.user_id in ($userlist)"; else @@ -333,7 +225,7 @@ static function getItems($bean, $options) { if ($includeCost && MODE_TIME != $user->tracking_mode) $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; - $where = ttReportHelper::getWhere($bean, $options); + $where = ttReportHelper::getWhere($options); // Construct sql query for tt_log items. $sql = "select ".join(', ', $fields)." from tt_log l $left_joins $where"; @@ -401,7 +293,7 @@ static function getItems($bean, $options) { if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice')) $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; - $where = ttReportHelper::getExpenseWhere($bean, $options); + $where = ttReportHelper::getExpenseWhere($options); // Construct sql query for expense items. $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $where"; @@ -608,7 +500,7 @@ static function getFavItems($options) { if ($includeCost && MODE_TIME != $user->tracking_mode) $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; - $where = ttReportHelper::getFavWhere($options); + $where = ttReportHelper::getWhere($options); // Construct sql query for tt_log items. $sql = "select ".join(', ', $fields)." from tt_log l $left_joins $where"; @@ -674,7 +566,7 @@ static function getFavItems($options) { if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; - $where = ttReportHelper::getFavExpenseWhere($options); + $where = ttReportHelper::getExpenseWhere($options); // Construct sql query for expense items. $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $where"; @@ -784,7 +676,7 @@ static function getSubtotals($bean, $options) { break; } - $where = ttReportHelper::getWhere($bean, $options); + $where = ttReportHelper::getWhere($options); if ($bean->getAttribute('chcost')) { if (MODE_TIME == $user->tracking_mode) { if ($group_by_option != 'user') @@ -851,7 +743,7 @@ static function getSubtotals($bean, $options) { break; } - $where = ttReportHelper::getExpenseWhere($bean, $options); + $where = ttReportHelper::getExpenseWhere($options); $sql_for_expenses = "select $group_field as group_field, null as time"; if ($bean->getAttribute('chunits')) $sql_for_expenses .= ", null as units"; $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $group_join $where"; @@ -935,7 +827,7 @@ static function getFavSubtotals($options) { break; } - $where = ttReportHelper::getFavWhere($options); + $where = ttReportHelper::getWhere($options); if ($options['show_cost']) { if (MODE_TIME == $user->tracking_mode) { if ($group_by_option != 'user') @@ -1003,7 +895,7 @@ static function getFavSubtotals($options) { break; } - $where = ttReportHelper::getFavExpenseWhere($options); + $where = ttReportHelper::getExpenseWhere($options); $sql_for_expenses = "select $group_field as group_field, null as time"; if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $group_join $where"; @@ -1049,7 +941,7 @@ static function getTotals($bean, $options) $mdb2 = getConnection(); - $where = ttReportHelper::getWhere($bean, $options); + $where = ttReportHelper::getWhere($options); // Prepare parts. $time_part = "sum(time_to_sec(l.duration)) as time"; @@ -1076,7 +968,7 @@ static function getTotals($bean, $options) // If we have expenses, query becomes a bit more complex. if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) { - $where = ttReportHelper::getExpenseWhere($bean, $options); + $where = ttReportHelper::getExpenseWhere($options); $sql_for_expenses = "select null as time"; if ($bean->getAttribute('chunits')) $sql_for_expenses .= ", null as units"; $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; @@ -1131,7 +1023,7 @@ static function getFavTotals($options) $mdb2 = getConnection(); - $where = ttReportHelper::getFavWhere($options); + $where = ttReportHelper::getWhere($options); // Prepare parts. $time_part = "sum(time_to_sec(l.duration)) as time"; @@ -1158,7 +1050,7 @@ static function getFavTotals($options) // If we have expenses, query becomes a bit more complex. if ($options['show_cost'] && $user->isPluginEnabled('ex')) { - $where = ttReportHelper::getFavExpenseWhere($options); + $where = ttReportHelper::getExpenseWhere($options); $sql_for_expenses = "select null as time"; if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c8f66d4f0..fc683d0cc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4302 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4303 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cron.php b/cron.php index 94a20ddad..473f27eff 100644 --- a/cron.php +++ b/cron.php @@ -66,6 +66,29 @@ $user = new ttUser(null, $options['user_id']); if (!$user->id) continue; // Skip not found user. + // Special handling of the NULL $options['users'] field (this used to mean "all users"). + if (!$options['users']) { + if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { + if ($user->can('view_reports') || $user->can('view_all_reports')) { + $max_rank = $user->rank-1; + if ($user->can('view_all_reports')) $max_rank = 512; + if ($user->can('view_own_reports')) + $user_options = array('max_rank'=>$max_rank,'include_self'=>true); + else + $user_options = array('max_rank'=>$max_rank); + $users = $user->getUsers($user_options); // Active and inactive users. + } elseif ($user->isClient()) { + $users = ttTeamHelper::getUsersForClient(); // Active and inactive users for clients. + } + foreach ($users as $single_user) { + $user_ids[] = $single_user['id']; + } + $options['users'] = implode(',', $user_ids); + } + } else { + // TODO: add checking the existing user list for potentially changed access rights for user. + } + // Skip users with disabled Notifications plugin. if (!$user->isPluginEnabled('no')) continue; From 5970acff895c6773c700d7e218ad4a932040789d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 31 Jul 2018 23:11:54 +0000 Subject: [PATCH 0200/1848] Some more work on refactoring reports. --- WEB-INF/lib/ttReportHelper.class.php | 20 ++++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index d76b027ad..be472df0e 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -127,8 +127,8 @@ static function getItems($bean, $options) { $canViewReports = $user->can('view_reports'); $isClient = $user->isClient(); - $group_by_option = $bean->getAttribute('group_by'); - $convertTo12Hour = ('%I:%M %p' == $user->time_format) && ($bean->getAttribute('chstart') || $bean->getAttribute('chfinish')); + $group_by_option = $options['group_by']; + $convertTo12Hour = ('%I:%M %p' == $user->time_format) && ($options['show_start'] || $options['show_end']); // Prepare a query for time items in tt_log table. $fields = array(); // An array of fields for database query. @@ -138,9 +138,11 @@ static function getItems($bean, $options) { if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. - if ($bean->getAttribute('chclient') || 'client' == $group_by_option) + if ($options['show_client'] || 'client' == $group_by_option) array_push($fields, 'c.name as client'); // Add project name if it is selected. + +// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. if ($bean->getAttribute('chproject') || 'project' == $group_by_option) array_push($fields, 'p.name as project'); // Add task name if it is selected. @@ -1804,23 +1806,33 @@ static function getReportOptions($bean) { $options['period'] = $bean->getAttribute('period'); $options['period_start'] = $bean->getAttribute('start_date'); $options['period_end'] = $bean->getAttribute('end_date'); + $options['show_client'] = $bean->getAttribute('chclient'); /* * TODO: remaining fields to fill in... - `show_client` tinyint(4) NOT NULL default 0, # whether to show client column `show_invoice` tinyint(4) NOT NULL default 0, # whether to show invoice column `show_paid` tinyint(4) NOT NULL default 0, # whether to show paid column `show_ip` tinyint(4) NOT NULL default 0, # whether to show ip column `show_project` tinyint(4) NOT NULL default 0, # whether to show project column + */ + $options['show_start'] = $bean->getAttribute('chstart'); +/* `show_start` tinyint(4) NOT NULL default 0, # whether to show start field `show_duration` tinyint(4) NOT NULL default 0, # whether to show duration field `show_cost` tinyint(4) NOT NULL default 0, # whether to show cost field `show_task` tinyint(4) NOT NULL default 0, # whether to show task column + */ + $options['show_end'] = $bean->getAttribute('chfinish'); + /* `show_end` tinyint(4) NOT NULL default 0, # whether to show end field `show_note` tinyint(4) NOT NULL default 0, # whether to show note column `show_custom_field_1` tinyint(4) NOT NULL default 0, # whether to show custom field 1 `show_work_units` tinyint(4) NOT NULL default 0, # whether to show work units `show_totals_only` tinyint(4) NOT NULL default 0, # whether to show totals only + **/ + $options['group_by'] = $bean->getAttribute('group_by'); +/* + * TODO: remaining fields to fill in... `group_by` varchar(20) default NULL, # group by field `status` tinyint(4) default 1, # favorite report status PRIMARY KEY (`id`) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fc683d0cc..90e9c5a95 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4303 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4304 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9e5dbe1bb51fef6af2a8e3a1dc0160086d723cfb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 31 Jul 2018 23:25:50 +0000 Subject: [PATCH 0201/1848] More refactoring in reports. --- WEB-INF/lib/ttReportHelper.class.php | 24 ++++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index be472df0e..1b1adf90e 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -141,15 +141,13 @@ static function getItems($bean, $options) { if ($options['show_client'] || 'client' == $group_by_option) array_push($fields, 'c.name as client'); // Add project name if it is selected. - -// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. - if ($bean->getAttribute('chproject') || 'project' == $group_by_option) + if ($options['show_project'] || 'project' == $group_by_option) array_push($fields, 'p.name as project'); // Add task name if it is selected. - if ($bean->getAttribute('chtask') || 'task' == $group_by_option) + if ($options['show_task'] || 'task' == $group_by_option) array_push($fields, 't.name as task'); // Add custom field. - $include_cf_1 = $bean->getAttribute('chcf_1') || 'cf_1' == $group_by_option; + $include_cf_1 = $options['show_custom_field_1'] || 'cf_1' == $group_by_option; if ($include_cf_1) { $custom_fields = new CustomFields($user->group_id); $cf_1_type = $custom_fields->fields[0]['type']; @@ -159,6 +157,8 @@ static function getItems($bean, $options) { array_push($fields, 'cfo.value as cf_1'); } } + +// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. // Add start time. if ($bean->getAttribute('chstart')) { array_push($fields, "l.start as unformatted_start"); @@ -1813,27 +1813,27 @@ static function getReportOptions($bean) { `show_invoice` tinyint(4) NOT NULL default 0, # whether to show invoice column `show_paid` tinyint(4) NOT NULL default 0, # whether to show paid column `show_ip` tinyint(4) NOT NULL default 0, # whether to show ip column - `show_project` tinyint(4) NOT NULL default 0, # whether to show project column */ + $options['show_project'] = $bean->getAttribute('chproject'); $options['show_start'] = $bean->getAttribute('chstart'); /* - `show_start` tinyint(4) NOT NULL default 0, # whether to show start field `show_duration` tinyint(4) NOT NULL default 0, # whether to show duration field `show_cost` tinyint(4) NOT NULL default 0, # whether to show cost field - `show_task` tinyint(4) NOT NULL default 0, # whether to show task column */ + $options['show_task'] = $bean->getAttribute('chtask'); $options['show_end'] = $bean->getAttribute('chfinish'); - /* - `show_end` tinyint(4) NOT NULL default 0, # whether to show end field +/* `show_note` tinyint(4) NOT NULL default 0, # whether to show note column `show_custom_field_1` tinyint(4) NOT NULL default 0, # whether to show custom field 1 + */ + $options['show_custom_field_1'] = $bean->getAttribute('chcf_1'); + /* `show_work_units` tinyint(4) NOT NULL default 0, # whether to show work units `show_totals_only` tinyint(4) NOT NULL default 0, # whether to show totals only **/ - $options['group_by'] = $bean->getAttribute('group_by'); + $options['group_by'] = $bean->getAttribute('group_by'); /* * TODO: remaining fields to fill in... - `group_by` varchar(20) default NULL, # group by field `status` tinyint(4) default 1, # favorite report status PRIMARY KEY (`id`) ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 90e9c5a95..4711f9317 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4304 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4305 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 47676f16efdde0b36a4ed09d2ab0476584aeb2a6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 31 Jul 2018 23:32:49 +0000 Subject: [PATCH 0202/1848] A little bit more refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 12 ++++++------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 1b1adf90e..42463d08a 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -157,19 +157,19 @@ static function getItems($bean, $options) { array_push($fields, 'cfo.value as cf_1'); } } - -// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. // Add start time. - if ($bean->getAttribute('chstart')) { + if ($options['show_start']) { array_push($fields, "l.start as unformatted_start"); array_push($fields, "TIME_FORMAT(l.start, '%k:%i') as start"); } // Add finish time. - if ($bean->getAttribute('chfinish')) + if ($options['show_end']) array_push($fields, "TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), '%k:%i') as finish"); // Add duration. - if ($bean->getAttribute('chduration')) + if ($options['show_duration']) array_push($fields, "TIME_FORMAT(l.duration, '%k:%i') as duration"); + +// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. // Add work units. if ($bean->getAttribute('chunits')) { if ($user->unit_totals_only) @@ -1816,8 +1816,8 @@ static function getReportOptions($bean) { */ $options['show_project'] = $bean->getAttribute('chproject'); $options['show_start'] = $bean->getAttribute('chstart'); + $options['show_duration'] = $bean->getAttribute('chduration'); /* - `show_duration` tinyint(4) NOT NULL default 0, # whether to show duration field `show_cost` tinyint(4) NOT NULL default 0, # whether to show cost field */ $options['show_task'] = $bean->getAttribute('chtask'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4711f9317..bcbfab0ee 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4305 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4306 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 7b3aad0973b1e581f32539cf96380f57e9f829ae Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 31 Jul 2018 23:54:08 +0000 Subject: [PATCH 0203/1848] More refactoring in reports. --- WEB-INF/lib/ttReportHelper.class.php | 38 +++++++++++++--------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 42463d08a..71fcb08f7 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -168,20 +168,18 @@ static function getItems($bean, $options) { // Add duration. if ($options['show_duration']) array_push($fields, "TIME_FORMAT(l.duration, '%k:%i') as duration"); - -// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. // Add work units. - if ($bean->getAttribute('chunits')) { + if ($options['show_work_units']) { if ($user->unit_totals_only) array_push($fields, "null as units"); else - array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); + array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); } // Add note. - if ($bean->getAttribute('chnote')) + if ($options['show_note']) array_push($fields, 'l.comment as note'); // Handle cost. - $includeCost = $bean->getAttribute('chcost'); + $includeCost = $options['show_cost']; if ($includeCost) { if (MODE_TIME == $user->tracking_mode) array_push($fields, "cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use default user rate. @@ -190,8 +188,10 @@ static function getItems($bean, $options) { array_push($fields, "null as expense"); } // Add paid status. - if ($canViewReports && $bean->getAttribute('chpaid')) + if ($canViewReports && $options['show_paid']) array_push($fields, 'l.paid as paid'); + +// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. // Add IP address. if ($canViewReports && $bean->getAttribute('chip')) { array_push($fields, 'l.created as created'); @@ -452,7 +452,6 @@ static function getFavItems($options) { else array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); } - // Add note. if ($options['show_note']) array_push($fields, 'l.comment as note'); @@ -1811,33 +1810,30 @@ static function getReportOptions($bean) { /* * TODO: remaining fields to fill in... `show_invoice` tinyint(4) NOT NULL default 0, # whether to show invoice column - `show_paid` tinyint(4) NOT NULL default 0, # whether to show paid column +*/ + $options['show_paid'] = $bean->getAttribute('chpaid'); +/* `show_ip` tinyint(4) NOT NULL default 0, # whether to show ip column - */ +*/ $options['show_project'] = $bean->getAttribute('chproject'); $options['show_start'] = $bean->getAttribute('chstart'); $options['show_duration'] = $bean->getAttribute('chduration'); -/* - `show_cost` tinyint(4) NOT NULL default 0, # whether to show cost field - */ + $options['show_cost'] = $bean->getAttribute('chcost'); $options['show_task'] = $bean->getAttribute('chtask'); $options['show_end'] = $bean->getAttribute('chfinish'); -/* - `show_note` tinyint(4) NOT NULL default 0, # whether to show note column - `show_custom_field_1` tinyint(4) NOT NULL default 0, # whether to show custom field 1 - */ + $options['show_note'] = $bean->getAttribute('chnote'); $options['show_custom_field_1'] = $bean->getAttribute('chcf_1'); - /* - `show_work_units` tinyint(4) NOT NULL default 0, # whether to show work units + $options['show_work_units'] = $bean->getAttribute('chunits'); +/* `show_totals_only` tinyint(4) NOT NULL default 0, # whether to show totals only - **/ +*/ $options['group_by'] = $bean->getAttribute('group_by'); /* * TODO: remaining fields to fill in... `status` tinyint(4) default 1, # favorite report status PRIMARY KEY (`id`) ); - */ +*/ return $options; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bcbfab0ee..14d389b67 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4306 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4307 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 0092d0f0e70b66795f5ab0fcff4bfcef89842f3d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 1 Aug 2018 00:06:10 +0000 Subject: [PATCH 0204/1848] A bit more refactoring... --- WEB-INF/lib/ttReportHelper.class.php | 27 ++++++++++----------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 71fcb08f7..612180a94 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -190,31 +190,28 @@ static function getItems($bean, $options) { // Add paid status. if ($canViewReports && $options['show_paid']) array_push($fields, 'l.paid as paid'); - -// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. // Add IP address. - if ($canViewReports && $bean->getAttribute('chip')) { + if ($canViewReports && $options['show_ip']) { array_push($fields, 'l.created as created'); array_push($fields, 'l.created_ip as created_ip'); array_push($fields, 'l.modified as modified'); array_push($fields, 'l.modified_ip as modified_ip'); } - // Add invoice name if it is selected. - if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice')) + if (($canViewReports || $isClient) && $options['show_invoice']) array_push($fields, 'i.name as invoice'); // Prepare sql query part for left joins. $left_joins = null; - if ($bean->getAttribute('chclient') || 'client' == $group_by_option) + if ($options['show_client'] || 'client' == $group_by_option) $left_joins .= " left join tt_clients c on (c.id = l.client_id)"; - if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice')) + if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = l.invoice_id and i.status = 1)"; if ($canViewReports || $isClient || $user->isPluginEnabled('ex')) $left_joins .= " left join tt_users u on (u.id = l.user_id)"; - if ($bean->getAttribute('chproject') || 'project' == $group_by_option) + if ($options['show_project'] || 'project' == $group_by_option) $left_joins .= " left join tt_projects p on (p.id = l.project_id)"; - if ($bean->getAttribute('chtask') || 'task' == $group_by_option) + if ($options['show_task'] || 'task' == $group_by_option) $left_joins .= " left join tt_tasks t on (t.id = l.task_id)"; if ($include_cf_1) { if ($cf_1_type == CustomFields::TYPE_TEXT) @@ -234,6 +231,8 @@ static function getItems($bean, $options) { // If we don't have expense items (such as when the Expenses plugin is desabled), the above is all sql we need, // with an exception of sorting part, that is added in the end. +// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. + // However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table. if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled @@ -1806,15 +1805,9 @@ static function getReportOptions($bean) { $options['period_start'] = $bean->getAttribute('start_date'); $options['period_end'] = $bean->getAttribute('end_date'); $options['show_client'] = $bean->getAttribute('chclient'); - -/* - * TODO: remaining fields to fill in... - `show_invoice` tinyint(4) NOT NULL default 0, # whether to show invoice column -*/ + $options['show_invoice'] = $bean->getAttribute('chinvoice'); $options['show_paid'] = $bean->getAttribute('chpaid'); -/* - `show_ip` tinyint(4) NOT NULL default 0, # whether to show ip column -*/ + $options['show_ip'] = $bean->getAttribute('chip'); $options['show_project'] = $bean->getAttribute('chproject'); $options['show_start'] = $bean->getAttribute('chstart'); $options['show_duration'] = $bean->getAttribute('chduration'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 14d389b67..f620d8508 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4307 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4308 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 520f98abdb50f3ec9d0c0b27c7502b1c2a84034a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 1 Aug 2018 00:17:18 +0000 Subject: [PATCH 0205/1848] Some more refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 31 +++++++++++++--------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 612180a94..bc60fb804 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -231,10 +231,8 @@ static function getItems($bean, $options) { // If we don't have expense items (such as when the Expenses plugin is desabled), the above is all sql we need, // with an exception of sorting part, that is added in the end. -// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. - // However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table. - if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled + if ($options['show_cost'] && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled $fields = array(); // An array of fields for database query. array_push($fields, 'ei.id'); @@ -243,46 +241,45 @@ static function getItems($bean, $options) { if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. - if ($bean->getAttribute('chclient') || 'client' == $group_by_option) + if ($options['show_client'] || 'client' == $group_by_option) array_push($fields, 'c.name as client'); // Add project name if it is selected. - if ($bean->getAttribute('chproject') || 'project' == $group_by_option) + if ($options['show_project'] || 'project' == $group_by_option) array_push($fields, 'p.name as project'); - if ($bean->getAttribute('chtask') || 'task' == $group_by_option) + if ($options['show_task'] || 'task' == $group_by_option) array_push($fields, 'null'); // null for task name. We need to match column count for union. - if ($bean->getAttribute('chcf_1') || 'cf_1' == $group_by_option) + if ($options['show_custom_field_1'] || 'cf_1' == $group_by_option) array_push($fields, 'null'); // null for cf_1. - if ($bean->getAttribute('chstart')) { + if ($options['show_start']) { array_push($fields, 'null'); // null for unformatted_start. array_push($fields, 'null'); // null for start. } - if ($bean->getAttribute('chfinish')) + if ($options['show_end']) array_push($fields, 'null'); // null for finish. - if ($bean->getAttribute('chduration')) + if ($options['show_duration']) array_push($fields, 'null'); // null for duration. - // Add work units. - if ($bean->getAttribute('chunits')) + if ($options['show_work_units']) array_push($fields, 'null as units'); // null for work units. // Use the note field to print item name. - if ($bean->getAttribute('chnote')) + if ($options['show_note']) array_push($fields, 'ei.name as note'); array_push($fields, 'ei.cost as cost'); array_push($fields, 'ei.cost as expense'); // Add paid status. - if ($canViewReports && $bean->getAttribute('chpaid')) + if ($canViewReports && $options['show_paid']) array_push($fields, 'ei.paid as paid'); // Add IP address. - if ($canViewReports && $bean->getAttribute('chip')) { + if ($canViewReports && $options['show_ip']) { array_push($fields, 'ei.created as created'); array_push($fields, 'ei.created_ip as created_ip'); array_push($fields, 'ei.modified as modified'); array_push($fields, 'ei.modified_ip as modified_ip'); } - // Add invoice name if it is selected. - if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice')) + if (($canViewReports || $isClient) && $options['show_invoice']) array_push($fields, 'i.name as invoice'); +// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. // Prepare sql query part for left joins. $left_joins = null; if ($canViewReports || $isClient) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f620d8508..833f43748 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4308 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4309 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e4ddcc8ecb86ac997048d648ed82402eff2cbb4a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 1 Aug 2018 00:36:03 +0000 Subject: [PATCH 0206/1848] More refactoring in reports. --- WEB-INF/lib/ttReportHelper.class.php | 20 +++++++------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index bc60fb804..a3b0b0d80 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -279,16 +279,15 @@ static function getItems($bean, $options) { if (($canViewReports || $isClient) && $options['show_invoice']) array_push($fields, 'i.name as invoice'); -// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. // Prepare sql query part for left joins. $left_joins = null; if ($canViewReports || $isClient) $left_joins .= " left join tt_users u on (u.id = ei.user_id)"; - if ($bean->getAttribute('chclient') || 'client' == $group_by_option) + if ($options['show_client'] || 'client' == $group_by_option) $left_joins .= " left join tt_clients c on (c.id = ei.client_id)"; - if ($bean->getAttribute('chproject') || 'project' == $group_by_option) + if ($options['show_project'] || 'project' == $group_by_option) $left_joins .= " left join tt_projects p on (p.id = ei.project_id)"; - if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice')) + if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; $where = ttReportHelper::getExpenseWhere($options); @@ -300,6 +299,9 @@ static function getItems($bean, $options) { $sql = "($sql) union all ($sql_for_expense_items)"; } +// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. +// Note: this sort part below is different in getFavItems. Need to figure out why and fix properly. + // Determine sort part. $sort_part = ' order by '; if ('no_grouping' == $group_by_option || 'date' == $group_by_option) @@ -1814,16 +1816,8 @@ static function getReportOptions($bean) { $options['show_note'] = $bean->getAttribute('chnote'); $options['show_custom_field_1'] = $bean->getAttribute('chcf_1'); $options['show_work_units'] = $bean->getAttribute('chunits'); -/* - `show_totals_only` tinyint(4) NOT NULL default 0, # whether to show totals only -*/ + $options['show_totals_only'] = $bean->getAttribute('chtotalsonly'); $options['group_by'] = $bean->getAttribute('group_by'); -/* - * TODO: remaining fields to fill in... - `status` tinyint(4) default 1, # favorite report status - PRIMARY KEY (`id`) -); -*/ return $options; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 833f43748..56a708306 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4309 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4310 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 69f1f97814697d70aa31902ef35add23536baa60 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 4 Aug 2018 16:30:38 +0000 Subject: [PATCH 0207/1848] Resuming refactoring reports. --- WEB-INF/lib/ttReportHelper.class.php | 10 +++++----- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index a3b0b0d80..811312aef 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -299,15 +299,15 @@ static function getItems($bean, $options) { $sql = "($sql) union all ($sql_for_expense_items)"; } -// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. -// Note: this sort part below is different in getFavItems. Need to figure out why and fix properly. - // Determine sort part. $sort_part = ' order by '; - if ('no_grouping' == $group_by_option || 'date' == $group_by_option) + if ($group_by_option == null || 'no_grouping' == $group_by_option || 'date' == $group_by_option) $sort_part .= 'date'; else $sort_part .= $group_by_option.', date'; + +// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. +// Note: this sort part below is different in getFavItems. Need to figure out why and fix properly. if (($canViewReports || $isClient) && is_array($bean->getAttribute('users')) && 'user' != $group_by_option) $sort_part .= ', user, type'; if ($bean->getAttribute('chstart')) @@ -576,7 +576,7 @@ static function getFavItems($options) { // Determine sort part. $sort_part = ' order by '; - if ($group_by_option == null || 'no_grouping' == $group_by_option || 'date' == $group_by_option) // TODO: fix DB for NULL values in group_by field. + if ($group_by_option == null || 'no_grouping' == $group_by_option || 'date' == $group_by_option) $sort_part .= 'date'; else $sort_part .= $group_by_option.', date'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 56a708306..4d4cdf90d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4310 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4311 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 85d475278111ea1ed81fcd0dd5eef7140d1cd493 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 4 Aug 2018 16:57:45 +0000 Subject: [PATCH 0208/1848] Some more refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 13 +++++-------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 811312aef..641282758 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -124,7 +124,7 @@ static function getItems($bean, $options) { $mdb2 = getConnection(); // Determine these once as they are used in multiple places in this function. - $canViewReports = $user->can('view_reports'); + $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); $group_by_option = $options['group_by']; @@ -305,12 +305,9 @@ static function getItems($bean, $options) { $sort_part .= 'date'; else $sort_part .= $group_by_option.', date'; - -// TODO: refactoring in progress down from here... The above is identical to getFavItems and is ready to merge. -// Note: this sort part below is different in getFavItems. Need to figure out why and fix properly. - if (($canViewReports || $isClient) && is_array($bean->getAttribute('users')) && 'user' != $group_by_option) + if (($canViewReports || $isClient) && $options['users'] && 'user' != $group_by_option) $sort_part .= ', user, type'; - if ($bean->getAttribute('chstart')) + if ($options['show_start']) $sort_part .= ', unformatted_start'; $sort_part .= ', id'; @@ -399,7 +396,7 @@ static function getFavItems($options) { $mdb2 = getConnection(); // Determine these once as they are used in multiple places in this function. - $canViewReports = $user->can('view_reports'); + $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); $group_by_option = $options['group_by']; @@ -580,7 +577,7 @@ static function getFavItems($options) { $sort_part .= 'date'; else $sort_part .= $group_by_option.', date'; - if (($canViewReports || $isClient) /*&& is_array($bean->getAttribute('users'))*/ && 'user' != $group_by_option) + if (($canViewReports || $isClient) && $options['users'] && 'user' != $group_by_option) $sort_part .= ', user, type'; if ($options['show_start']) $sort_part .= ', unformatted_start'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4d4cdf90d..edaf0900f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4311 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4312 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 756657a71e251b65d8191636e33e5e4ea32767af Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 4 Aug 2018 17:08:23 +0000 Subject: [PATCH 0209/1848] Merged getItems and getFavItems into one function. --- WEB-INF/lib/ttReportHelper.class.php | 251 +-------------------------- WEB-INF/templates/footer.tpl | 2 +- report.php | 2 +- tofile.php | 2 +- topdf.php | 2 +- 5 files changed, 10 insertions(+), 249 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 641282758..85078db3b 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -119,7 +119,7 @@ static function getExpenseWhere($options) { // getItems retrieves all items associated with a report. // It combines tt_log and tt_expense_items in one array for presentation in one table using mysql union all. // Expense items use the "note" field for item name. - static function getItems($bean, $options) { + static function getItems($options) { global $user; $mdb2 = getConnection(); @@ -388,245 +388,6 @@ static function getFromSession() { return $items; } - // getFavItems retrieves all items associated with a favorite report. - // It combines tt_log and tt_expense_items in one array for presentation in one table using mysql union all. - // Expense items use the "note" field for item name. - static function getFavItems($options) { - global $user; - $mdb2 = getConnection(); - - // Determine these once as they are used in multiple places in this function. - $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); - $isClient = $user->isClient(); - - $group_by_option = $options['group_by']; - $convertTo12Hour = ('%I:%M %p' == $user->time_format) && ($options['show_start'] || $options['show_end']); - - // Prepare a query for time items in tt_log table. - $fields = array(); // An array of fields for database query. - array_push($fields, 'l.id as id'); - array_push($fields, '1 as type'); // Type 1 is for tt_log entries. - array_push($fields, 'l.date as date'); - if($canViewReports || $isClient) - array_push($fields, 'u.name as user'); - // Add client name if it is selected. - if ($options['show_client'] || 'client' == $group_by_option) - array_push($fields, 'c.name as client'); - // Add project name if it is selected. - if ($options['show_project'] || 'project' == $group_by_option) - array_push($fields, 'p.name as project'); - // Add task name if it is selected. - if ($options['show_task'] || 'task' == $group_by_option) - array_push($fields, 't.name as task'); - // Add custom field. - $include_cf_1 = $options['show_custom_field_1'] || 'cf_1' == $group_by_option; - if ($include_cf_1) { - $custom_fields = new CustomFields($user->group_id); - $cf_1_type = $custom_fields->fields[0]['type']; - if ($cf_1_type == CustomFields::TYPE_TEXT) { - array_push($fields, 'cfl.value as cf_1'); - } elseif ($cf_1_type == CustomFields::TYPE_DROPDOWN) { - array_push($fields, 'cfo.value as cf_1'); - } - } - // Add start time. - if ($options['show_start']) { - array_push($fields, "l.start as unformatted_start"); - array_push($fields, "TIME_FORMAT(l.start, '%k:%i') as start"); - } - // Add finish time. - if ($options['show_end']) - array_push($fields, "TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), '%k:%i') as finish"); - // Add duration. - if ($options['show_duration']) - array_push($fields, "TIME_FORMAT(l.duration, '%k:%i') as duration"); - // Add work units. - if ($options['show_work_units']) { - if ($user->unit_totals_only) - array_push($fields, "null as units"); - else - array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); - } - // Add note. - if ($options['show_note']) - array_push($fields, 'l.comment as note'); - // Handle cost. - $includeCost = $options['show_cost']; - if ($includeCost) { - if (MODE_TIME == $user->tracking_mode) - array_push($fields, "cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use default user rate. - else - array_push($fields, "cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use project rate for user. - array_push($fields, "null as expense"); - } - // Add paid status. - if ($canViewReports && $options['show_paid']) - array_push($fields, 'l.paid as paid'); - // Add IP address. - if ($canViewReports && $options['show_ip']) { - array_push($fields, 'l.created as created'); - array_push($fields, 'l.created_ip as created_ip'); - array_push($fields, 'l.modified as modified'); - array_push($fields, 'l.modified_ip as modified_ip'); - } - // Add invoice name if it is selected. - if (($canViewReports || $isClient) && $options['show_invoice']) - array_push($fields, 'i.name as invoice'); - - // Prepare sql query part for left joins. - $left_joins = null; - if ($options['show_client'] || 'client' == $group_by_option) - $left_joins .= " left join tt_clients c on (c.id = l.client_id)"; - if (($canViewReports || $isClient) && $options['show_invoice']) - $left_joins .= " left join tt_invoices i on (i.id = l.invoice_id and i.status = 1)"; - if ($canViewReports || $isClient || $user->isPluginEnabled('ex')) - $left_joins .= " left join tt_users u on (u.id = l.user_id)"; - if ($options['show_project'] || 'project' == $group_by_option) - $left_joins .= " left join tt_projects p on (p.id = l.project_id)"; - if ($options['show_task'] || 'task' == $group_by_option) - $left_joins .= " left join tt_tasks t on (t.id = l.task_id)"; - if ($include_cf_1) { - if ($cf_1_type == CustomFields::TYPE_TEXT) - $left_joins .= " left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1)"; - elseif ($cf_1_type == CustomFields::TYPE_DROPDOWN) { - $left_joins .= " left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1)". - " left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)"; - } - } - if ($includeCost && MODE_TIME != $user->tracking_mode) - $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; - - $where = ttReportHelper::getWhere($options); - - // Construct sql query for tt_log items. - $sql = "select ".join(', ', $fields)." from tt_log l $left_joins $where"; - // If we don't have expense items (such as when the Expenses plugin is desabled), the above is all sql we need, - // with an exception of sorting part, that is added in the end. - - // However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table. - if ($options['show_cost'] && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled - - $fields = array(); // An array of fields for database query. - array_push($fields, 'ei.id'); - array_push($fields, '2 as type'); // Type 2 is for tt_expense_items entries. - array_push($fields, 'ei.date'); - if($canViewReports || $isClient) - array_push($fields, 'u.name as user'); - // Add client name if it is selected. - if ($options['show_client'] || 'client' == $group_by_option) - array_push($fields, 'c.name as client'); - // Add project name if it is selected. - if ($options['show_project'] || 'project' == $group_by_option) - array_push($fields, 'p.name as project'); - if ($options['show_task'] || 'task' == $group_by_option) - array_push($fields, 'null'); // null for task name. We need to match column count for union. - if ($options['show_custom_field_1'] || 'cf_1' == $group_by_option) - array_push($fields, 'null'); // null for cf_1. - if ($options['show_start']) { - array_push($fields, 'null'); // null for unformatted_start. - array_push($fields, 'null'); // null for start. - } - if ($options['show_end']) - array_push($fields, 'null'); // null for finish. - if ($options['show_duration']) - array_push($fields, 'null'); // null for duration. - if ($options['show_work_units']) - array_push($fields, 'null as units'); // null for work units. - // Use the note field to print item name. - if ($options['show_note']) - array_push($fields, 'ei.name as note'); - array_push($fields, 'ei.cost as cost'); - array_push($fields, 'ei.cost as expense'); - // Add paid status. - if ($canViewReports && $options['show_paid']) - array_push($fields, 'ei.paid as paid'); - // Add IP address. - if ($canViewReports && $options['show_ip']) { - array_push($fields, 'ei.created as created'); - array_push($fields, 'ei.created_ip as created_ip'); - array_push($fields, 'ei.modified as modified'); - array_push($fields, 'ei.modified_ip as modified_ip'); - } - // Add invoice name if it is selected. - if (($canViewReports || $isClient) && $options['show_invoice']) - array_push($fields, 'i.name as invoice'); - - // Prepare sql query part for left joins. - $left_joins = null; - if ($canViewReports || $isClient) - $left_joins .= " left join tt_users u on (u.id = ei.user_id)"; - if ($options['show_client'] || 'client' == $group_by_option) - $left_joins .= " left join tt_clients c on (c.id = ei.client_id)"; - if ($options['show_project'] || 'project' == $group_by_option) - $left_joins .= " left join tt_projects p on (p.id = ei.project_id)"; - if (($canViewReports || $isClient) && $options['show_invoice']) - $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; - - $where = ttReportHelper::getExpenseWhere($options); - - // Construct sql query for expense items. - $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $where"; - - // Construct a union. - $sql = "($sql) union all ($sql_for_expense_items)"; - } - - // Determine sort part. - $sort_part = ' order by '; - if ($group_by_option == null || 'no_grouping' == $group_by_option || 'date' == $group_by_option) - $sort_part .= 'date'; - else - $sort_part .= $group_by_option.', date'; - if (($canViewReports || $isClient) && $options['users'] && 'user' != $group_by_option) - $sort_part .= ', user, type'; - if ($options['show_start']) - $sort_part .= ', unformatted_start'; - $sort_part .= ', id'; - - $sql .= $sort_part; - // By now we are ready with sql. - - // Obtain items for report. - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) die($res->getMessage()); - - while ($val = $res->fetchRow()) { - if ($convertTo12Hour) { - if($val['start'] != '') - $val['start'] = ttTimeHelper::to12HourFormat($val['start']); - if($val['finish'] != '') - $val['finish'] = ttTimeHelper::to12HourFormat($val['finish']); - } - if (isset($val['cost'])) { - if ('.' != $user->decimal_mark) - $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); - } - if (isset($val['expense'])) { - if ('.' != $user->decimal_mark) - $val['expense'] = str_replace('.', $user->decimal_mark, $val['expense']); - } - if ('no_grouping' != $group_by_option) { - $val['grouped_by'] = $val[$group_by_option]; - if ('date' == $group_by_option) { - // This is needed to get the date in user date format. - $o_date = new DateAndTime(DB_DATEFORMAT, $val['grouped_by']); - $val['grouped_by'] = $o_date->toString($user->date_format); - unset($o_date); - } - } - - // This is needed to get the date in user date format. - $o_date = new DateAndTime(DB_DATEFORMAT, $val['date']); - $val['date'] = $o_date->toString($user->date_format); - unset($o_date); - - $row = $val; - $report_items[] = $row; - } - - return $report_items; - } - // getSubtotals calculates report items subtotals when a report is grouped by. // Without expenses, it's a simple select with group by. // With expenses, it becomes a select with group by from a combined set of records obtained with "union all". @@ -1136,11 +897,11 @@ static function prepareReportBody($bean, $comment) global $i18n; // Determine these once as they are used in multiple places in this function. - $canViewReports = $user->can('view_reports'); + $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); $options = ttReportHelper::getReportOptions($bean); - $items = ttReportHelper::getItems($bean, $options); + $items = ttReportHelper::getItems($options); $group_by = $bean->getAttribute('group_by'); if ($group_by && 'no_grouping' != $group_by) $subtotals = ttReportHelper::getSubtotals($bean, $options); @@ -1434,7 +1195,7 @@ static function prepareReportBody($bean, $comment) // checkFavReportCondition - checks whether it is okay to send fav report. static function checkFavReportCondition($options, $condition) { - $items = ttReportHelper::getFavItems($options); + $items = ttReportHelper::getItems($options); $condition = str_replace('count', '', $condition); $count_required = (int) trim(str_replace('>', '', $condition)); @@ -1452,10 +1213,10 @@ static function prepareFavReportBody($options) global $i18n; // Determine these once as they are used in multiple places in this function. - $canViewReports = $user->can('view_reports'); + $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); - $items = ttReportHelper::getFavItems($options); + $items = ttReportHelper::getItems($options); $group_by = $options['group_by']; if ($group_by && 'no_grouping' != $group_by) $subtotals = ttReportHelper::getFavSubtotals($options); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index edaf0900f..8817aedd6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4312 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4313 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index 61b3587ff..1423706a4 100644 --- a/report.php +++ b/report.php @@ -173,7 +173,7 @@ $group_by = $bean->getAttribute('group_by'); $options = ttReportHelper::getReportOptions($bean); -$report_items = ttReportHelper::getItems($bean, $options); +$report_items = ttReportHelper::getItems($options); // Store record ids in session in case user wants to act on records such as marking them all paid. if ($request->isGet() && $user->isPluginEnabled('ps')) ttReportHelper::putInSession($report_items); diff --git a/tofile.php b/tofile.php index 5a190f4bb..36bd7e1c9 100644 --- a/tofile.php +++ b/tofile.php @@ -62,7 +62,7 @@ if ($totals_only) $subtotals = ttReportHelper::getSubtotals($bean, $options); else - $items = ttReportHelper::getItems($bean, $options); + $items = ttReportHelper::getItems($options); // Build a string to use as filename for the files being downloaded. $filename = strtolower($i18n->get('title.report')).'_'.$bean->mValues['start_date'].'_'.$bean->mValues['end_date']; diff --git a/topdf.php b/topdf.php index 9d3164af1..b415f50de 100644 --- a/topdf.php +++ b/topdf.php @@ -76,7 +76,7 @@ // Obtain items for report. $options = ttReportHelper::getReportOptions($bean); if (!$totals_only) - $items = ttReportHelper::getItems($bean, $options); // Individual entries. + $items = ttReportHelper::getItems($options); // Individual entries. if ($totals_only || 'no_grouping' != $group_by) $subtotals = ttReportHelper::getSubtotals($bean, $options); // Subtotals for groups of items. $totals = ttReportHelper::getTotals($bean, $options); // Totals for the entire report. From 8009bd2e92e46bb3756ba69132dbca5e9e6d9895 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 4 Aug 2018 17:36:41 +0000 Subject: [PATCH 0210/1848] Merged getTotals and getFavTotals into one function. --- WEB-INF/lib/ttReportHelper.class.php | 88 +--------------------------- WEB-INF/templates/footer.tpl | 2 +- report.php | 2 +- topdf.php | 2 +- 4 files changed, 6 insertions(+), 88 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 85078db3b..28a0bc548 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -692,89 +692,7 @@ static function getFavSubtotals($options) { } // getTotals calculates total hours and cost for all report items. - static function getTotals($bean, $options) - { - global $user; - - $mdb2 = getConnection(); - - $where = ttReportHelper::getWhere($options); - - // Prepare parts. - $time_part = "sum(time_to_sec(l.duration)) as time"; - if ($bean->getAttribute('chunits')) { - $units_part = $user->unit_totals_only ? ", null as units" : ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; - } - if ($bean->getAttribute('chcost')) { - if (MODE_TIME == $user->tracking_mode) - $cost_part = ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses"; - else - $cost_part = ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses"; - } else { - $cost_part = ", null as cost, null as expenses"; - } - if ($bean->getAttribute('chcost')) { - if (MODE_TIME == $user->tracking_mode) { - $left_joins = "left join tt_users u on (l.user_id = u.id)"; - } else { - $left_joins = "left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; - } - } - // Prepare a query for time items. - $sql = "select $time_part $units_part $cost_part from tt_log l $left_joins $where"; - - // If we have expenses, query becomes a bit more complex. - if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) { - $where = ttReportHelper::getExpenseWhere($options); - $sql_for_expenses = "select null as time"; - if ($bean->getAttribute('chunits')) $sql_for_expenses .= ", null as units"; - $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; - - // Create a combined query. - $combined = "select sum(time) as time"; - if ($bean->getAttribute('chunits')) $combined .= ", sum(units) as units"; - $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t"; - $sql = $combined; - } - - // Execute query. - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) die($res->getMessage()); - - $val = $res->fetchRow(); - $total_time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; - if ($bean->getAttribute('chcost')) { - $total_cost = $val['cost']; - if (!$total_cost) $total_cost = '0.00'; - if ('.' != $user->decimal_mark) - $total_cost = str_replace('.', $user->decimal_mark, $total_cost); - $total_expenses = $val['expenses']; - if (!$total_expenses) $total_expenses = '0.00'; - if ('.' != $user->decimal_mark) - $total_expenses = str_replace('.', $user->decimal_mark, $total_expenses); - } - - if ($bean->getAttribute('period')) - $period = new Period($bean->getAttribute('period'), new DateAndTime($user->date_format)); - else { - $period = new Period(); - $period->setPeriod( - new DateAndTime($user->date_format, $bean->getAttribute('start_date')), - new DateAndTime($user->date_format, $bean->getAttribute('end_date'))); - } - - $totals['start_date'] = $period->getStartDate(); - $totals['end_date'] = $period->getEndDate(); - $totals['time'] = $total_time; - $totals['units'] = $val['units']; - $totals['cost'] = $total_cost; - $totals['expenses'] = $total_expenses; - - return $totals; - } - - // getFavTotals calculates total hours and cost for all favorite report items. - static function getFavTotals($options) + static function getTotals($options) { global $user; @@ -905,7 +823,7 @@ static function prepareReportBody($bean, $comment) $group_by = $bean->getAttribute('group_by'); if ($group_by && 'no_grouping' != $group_by) $subtotals = ttReportHelper::getSubtotals($bean, $options); - $totals = ttReportHelper::getTotals($bean, $options); + $totals = ttReportHelper::getTotals($options); // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) @@ -1220,7 +1138,7 @@ static function prepareFavReportBody($options) $group_by = $options['group_by']; if ($group_by && 'no_grouping' != $group_by) $subtotals = ttReportHelper::getFavSubtotals($options); - $totals = ttReportHelper::getFavTotals($options); + $totals = ttReportHelper::getTotals($options); // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8817aedd6..27bbebd33 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4313 | Copyright © Anuko | +  Anuko Time Tracker 1.17.97.4314 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index 1423706a4..e59c759cf 100644 --- a/report.php +++ b/report.php @@ -180,7 +180,7 @@ if ('no_grouping' != $group_by) $subtotals = ttReportHelper::getSubtotals($bean, $options); -$totals = ttReportHelper::getTotals($bean, $options); +$totals = ttReportHelper::getTotals($options); // Assign variables that are used to print subtotals. if ($report_items && 'no_grouping' != $group_by) { diff --git a/topdf.php b/topdf.php index b415f50de..fdcbf683e 100644 --- a/topdf.php +++ b/topdf.php @@ -79,7 +79,7 @@ $items = ttReportHelper::getItems($options); // Individual entries. if ($totals_only || 'no_grouping' != $group_by) $subtotals = ttReportHelper::getSubtotals($bean, $options); // Subtotals for groups of items. -$totals = ttReportHelper::getTotals($bean, $options); // Totals for the entire report. +$totals = ttReportHelper::getTotals($options); // Totals for the entire report. // Assign variables that are used to print subtotals. if ($items && 'no_grouping' != $group_by) { From 02649cd1c0f39d44fd21e0ddc9f5e5eb428409c8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 4 Aug 2018 18:58:36 +0000 Subject: [PATCH 0211/1848] Fixed a bug in sql query for work units calculation. --- WEB-INF/lib/ttReportHelper.class.php | 23 +++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 28a0bc548..4fb5ca1f0 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -394,7 +394,7 @@ static function getFromSession() { static function getSubtotals($bean, $options) { global $user; - $group_by_option = $bean->getAttribute('group_by'); + $group_by_option = $options['group_by']; if ('no_grouping' == $group_by_option) return null; $mdb2 = getConnection(); @@ -434,12 +434,12 @@ static function getSubtotals($bean, $options) { } $where = ttReportHelper::getWhere($options); - if ($bean->getAttribute('chcost')) { + if ($options['show_cost']) { if (MODE_TIME == $user->tracking_mode) { if ($group_by_option != 'user') $left_join = 'left join tt_users u on (l.user_id = u.id)'; $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; - if ($bean->getAttribute('chunits')) { + if ($options['show_work_units']) { if ($user->unit_totals_only) $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; else @@ -589,15 +589,14 @@ static function getFavSubtotals($options) { if (MODE_TIME == $user->tracking_mode) { if ($group_by_option != 'user') $left_join = 'left join tt_users u on (l.user_id = u.id)'; - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; - if ($options['show_work_units']) { - if ($user->unit_totals_only) - $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; - else - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; - } - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; - $sql .= ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, + $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + if ($options['show_work_units']) { + if ($user->unit_totals_only) + $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + else + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + } + $sql .= ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, null as expenses from tt_log l $group_join $left_join $where group by $group_field"; } else { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 27bbebd33..766f8737a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.97.4314 | Copyright © Anuko | +  Anuko Time Tracker 1.17.98.4315 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a58bca2afc5d6457d07c886c7c20fb10c941752a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 4 Aug 2018 19:45:02 +0000 Subject: [PATCH 0212/1848] Merged getSubtotals and getFavSubtotals into one function. --- WEB-INF/lib/ttReportHelper.class.php | 157 +-------------------------- WEB-INF/templates/footer.tpl | 2 +- cron.php | 6 + report.php | 2 +- tofile.php | 2 +- topdf.php | 2 +- 6 files changed, 13 insertions(+), 158 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 4fb5ca1f0..4d510bbb2 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -391,158 +391,7 @@ static function getFromSession() { // getSubtotals calculates report items subtotals when a report is grouped by. // Without expenses, it's a simple select with group by. // With expenses, it becomes a select with group by from a combined set of records obtained with "union all". - static function getSubtotals($bean, $options) { - global $user; - - $group_by_option = $options['group_by']; - if ('no_grouping' == $group_by_option) return null; - - $mdb2 = getConnection(); - - // Start with sql to obtain subtotals for time items. This simple sql will be used when we have no expenses. - - // Determine group by field and a required join. - switch ($group_by_option) { - case 'date': - $group_field = 'l.date'; - $group_join = ''; - break; - case 'user': - $group_field = 'u.name'; - $group_join = 'left join tt_users u on (l.user_id = u.id) '; - break; - case 'client': - $group_field = 'c.name'; - $group_join = 'left join tt_clients c on (l.client_id = c.id) '; - break; - case 'project': - $group_field = 'p.name'; - $group_join = 'left join tt_projects p on (l.project_id = p.id) '; - break; - case 'task': - $group_field = 't.name'; - $group_join = 'left join tt_tasks t on (l.task_id = t.id) '; - break; - case 'cf_1': - $group_field = 'cfo.value'; - $custom_fields = new CustomFields($user->group_id); - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $group_join = 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id) '; - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $group_join = 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.option_id = cfo.id) '; - break; - } - - $where = ttReportHelper::getWhere($options); - if ($options['show_cost']) { - if (MODE_TIME == $user->tracking_mode) { - if ($group_by_option != 'user') - $left_join = 'left join tt_users u on (l.user_id = u.id)'; - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; - if ($options['show_work_units']) { - if ($user->unit_totals_only) - $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; - else - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; - } - $sql .= ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, - null as expenses from tt_log l - $group_join $left_join $where group by $group_field"; - } else { - // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; - if ($bean->getAttribute('chunits')) { - if ($user->unit_totals_only) - $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; - else - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; - } - $sql .= ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, - null as expenses from tt_log l - $group_join - left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where group by $group_field"; - } - } else { - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; - if ($bean->getAttribute('chunits')) { - if ($user->unit_totals_only) - $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; - else - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; - } - $sql .= ", null as expenses from tt_log l - $group_join $where group by $group_field"; - } - // By now we have sql for time items. - - // However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table. - if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled - - // Determine group by field and a required join. - $group_join = null; - $group_field = 'null'; - switch ($group_by_option) { - case 'date': - $group_field = 'ei.date'; - $group_join = ''; - break; - case 'user': - $group_field = 'u.name'; - $group_join = 'left join tt_users u on (ei.user_id = u.id) '; - break; - case 'client': - $group_field = 'c.name'; - $group_join = 'left join tt_clients c on (ei.client_id = c.id) '; - break; - case 'project': - $group_field = 'p.name'; - $group_join = 'left join tt_projects p on (ei.project_id = p.id) '; - break; - } - - $where = ttReportHelper::getExpenseWhere($options); - $sql_for_expenses = "select $group_field as group_field, null as time"; - if ($bean->getAttribute('chunits')) $sql_for_expenses .= ", null as units"; - $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $group_join $where"; - // Add a "group by" clause if we are grouping. - if ('null' != $group_field) $sql_for_expenses .= " group by $group_field"; - - // Create a combined query. - $combined = "select group_field, sum(time) as time"; - if ($bean->getAttribute('chunits')) $combined .= ", sum(units) as units"; - $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; - $sql = $combined; - } - - // Execute query. - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) die($res->getMessage()); - - while ($val = $res->fetchRow()) { - if ('date' == $group_by_option) { - // This is needed to get the date in user date format. - $o_date = new DateAndTime(DB_DATEFORMAT, $val['group_field']); - $val['group_field'] = $o_date->toString($user->date_format); - unset($o_date); - } - $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; - if ($bean->getAttribute('chcost')) { - if ('.' != $user->decimal_mark) { - $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); - $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']); - } - $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time, 'units'=> $val['units'],'cost'=>$val['cost'],'expenses'=>$val['expenses']); - } else - $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time, 'units'=> $val['units']); - } - - return $subtotals; - } - - // getFavSubtotals calculates report items subtotals when a favorite report is grouped by. - // Without expenses, it's a simple select with group by. - // With expenses, it becomes a select with group by from a combined set of records obtained with "union all". - static function getFavSubtotals($options) { + static function getSubtotals($options) { global $user; $group_by_option = $options['group_by']; @@ -821,7 +670,7 @@ static function prepareReportBody($bean, $comment) $items = ttReportHelper::getItems($options); $group_by = $bean->getAttribute('group_by'); if ($group_by && 'no_grouping' != $group_by) - $subtotals = ttReportHelper::getSubtotals($bean, $options); + $subtotals = ttReportHelper::getSubtotals($options); $totals = ttReportHelper::getTotals($options); // Use custom fields plugin if it is enabled. @@ -1136,7 +985,7 @@ static function prepareFavReportBody($options) $items = ttReportHelper::getItems($options); $group_by = $options['group_by']; if ($group_by && 'no_grouping' != $group_by) - $subtotals = ttReportHelper::getFavSubtotals($options); + $subtotals = ttReportHelper::getSubtotals($options); $totals = ttReportHelper::getTotals($options); // Use custom fields plugin if it is enabled. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 766f8737a..856333383 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.98.4315 | Copyright © Anuko | +  Anuko Time Tracker 1.17.98.4316 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cron.php b/cron.php index 473f27eff..1b586cf0f 100644 --- a/cron.php +++ b/cron.php @@ -66,6 +66,12 @@ $user = new ttUser(null, $options['user_id']); if (!$user->id) continue; // Skip not found user. + // TODO: write a new function ttFavReportHelper::adjustReportOptions that will use + // a $user objected recycled above. Put user handling below into it. + // Also adjust all other options for potentially changed user access rights and group properties. + // For example, tracking mode may have changed, but fav report options are still old... + // This needs to be fixed. + // Special handling of the NULL $options['users'] field (this used to mean "all users"). if (!$options['users']) { if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { diff --git a/report.php b/report.php index e59c759cf..cd093e40b 100644 --- a/report.php +++ b/report.php @@ -179,7 +179,7 @@ ttReportHelper::putInSession($report_items); if ('no_grouping' != $group_by) - $subtotals = ttReportHelper::getSubtotals($bean, $options); + $subtotals = ttReportHelper::getSubtotals($options); $totals = ttReportHelper::getTotals($options); // Assign variables that are used to print subtotals. diff --git a/tofile.php b/tofile.php index 36bd7e1c9..a40dbf0ac 100644 --- a/tofile.php +++ b/tofile.php @@ -60,7 +60,7 @@ // Obtain items. $options = ttReportHelper::getReportOptions($bean); if ($totals_only) - $subtotals = ttReportHelper::getSubtotals($bean, $options); + $subtotals = ttReportHelper::getSubtotals($options); else $items = ttReportHelper::getItems($options); diff --git a/topdf.php b/topdf.php index fdcbf683e..69f5816d8 100644 --- a/topdf.php +++ b/topdf.php @@ -78,7 +78,7 @@ if (!$totals_only) $items = ttReportHelper::getItems($options); // Individual entries. if ($totals_only || 'no_grouping' != $group_by) - $subtotals = ttReportHelper::getSubtotals($bean, $options); // Subtotals for groups of items. + $subtotals = ttReportHelper::getSubtotals($options); // Subtotals for groups of items. $totals = ttReportHelper::getTotals($options); // Totals for the entire report. // Assign variables that are used to print subtotals. From f43392d109df8f4b04d623bd933f7a98089fb210 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 6 Aug 2018 13:49:19 +0000 Subject: [PATCH 0213/1848] Resuming refactoring report related functions. --- WEB-INF/lib/ttReportHelper.class.php | 11 ++++++----- WEB-INF/templates/footer.tpl | 2 +- cron.php | 6 +++--- report_send.php | 4 +++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 4d510bbb2..46ce3f856 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -657,7 +657,7 @@ static function markPaid($time_log_ids, $expense_item_ids, $paid = true) } // prepareReportBody - prepares an email body for report. - static function prepareReportBody($bean, $comment) + static function prepareReportBody($bean, $options, $comment) { global $user; global $i18n; @@ -665,10 +665,9 @@ static function prepareReportBody($bean, $comment) // Determine these once as they are used in multiple places in this function. $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); - $options = ttReportHelper::getReportOptions($bean); $items = ttReportHelper::getItems($options); - $group_by = $bean->getAttribute('group_by'); + $group_by = $options['group_by']; if ($group_by && 'no_grouping' != $group_by) $subtotals = ttReportHelper::getSubtotals($options); $totals = ttReportHelper::getTotals($options); @@ -700,6 +699,8 @@ static function prepareReportBody($bean, $comment) // Output comment. if ($comment) $body .= '

'.htmlspecialchars($comment).'

'; +// TODO: refactoring ongoing down from here... + if ($bean->getAttribute('chtotalsonly')) { // Totals only report. Output subtotals. @@ -973,7 +974,7 @@ static function checkFavReportCondition($options, $condition) } // prepareFavReportBody - prepares an email body for a favorite report. - static function prepareFavReportBody($options) + static function prepareFavReportBody($options, $comment = null) { global $user; global $i18n; @@ -1013,7 +1014,7 @@ static function prepareFavReportBody($options) $body .= '

'.$i18n->get('form.mail.report_subject').': '.$totals['start_date'].' - '.$totals['end_date'].'

'; // Output comment. - // if ($comment) $body .= '

'.htmlspecialchars($comment).'

'; // No comment for fav. reports. + if ($comment) $body .= '

'.htmlspecialchars($comment).'

'; if ($options['show_totals_only']) { // Totals only report. Output subtotals. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 856333383..c8a4919c9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.98.4316 | Copyright © Anuko | +  Anuko Time Tracker 1.17.98.4317 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cron.php b/cron.php index 1b586cf0f..7d766992c 100644 --- a/cron.php +++ b/cron.php @@ -66,9 +66,9 @@ $user = new ttUser(null, $options['user_id']); if (!$user->id) continue; // Skip not found user. - // TODO: write a new function ttFavReportHelper::adjustReportOptions that will use - // a $user objected recycled above. Put user handling below into it. - // Also adjust all other options for potentially changed user access rights and group properties. + // TODO: write a new function ttFavReportHelper::adjustOptions that will use + // a $user objecte recycled above. Put user handling below into it. + // Also adjust remaining options for potentially changed user access rights and group properties. // For example, tracking mode may have changed, but fav report options are still old... // This needs to be fixed. diff --git a/report_send.php b/report_send.php index d7c031fd7..ea6c555b5 100644 --- a/report_send.php +++ b/report_send.php @@ -72,8 +72,10 @@ // Obtain session bean with report attributes. $bean = new ActionForm('reportBean', new Form('reportForm')); + $options = ttReportHelper::getReportOptions($bean); + // Prepare report body. - $body = ttReportHelper::prepareReportBody($bean, $cl_comment); + $body = ttReportHelper::prepareReportBody($bean, $options, $cl_comment); import('mail.Mailer'); $mailer = new Mailer(); From bd92aeb3404ed8625272abccc9a8766f13ab75e6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 6 Aug 2018 14:02:29 +0000 Subject: [PATCH 0214/1848] A bit of refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 21 ++++++++++++--------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 46ce3f856..1f1654782 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -699,9 +699,7 @@ static function prepareReportBody($bean, $options, $comment) // Output comment. if ($comment) $body .= '

'.htmlspecialchars($comment).'

'; -// TODO: refactoring ongoing down from here... - - if ($bean->getAttribute('chtotalsonly')) { + if ($options['show_totals_only']) { // Totals only report. Output subtotals. // Determine group_by header. @@ -715,27 +713,27 @@ static function prepareReportBody($bean, $options, $comment) $body .= ''; $body .= ''; $body .= ''; - if ($bean->getAttribute('chduration')) + if ($options['show_duration']) $body .= ''; - if ($bean->getAttribute('chunits')) + if ($options['show_work_units']) $body .= ''; - if ($bean->getAttribute('chcost')) + if ($options['show_cost']) $body .= ''; $body .= ''; foreach($subtotals as $subtotal) { $body .= ''; $body .= ''; - if ($bean->getAttribute('chduration')) { + if ($options['show_duration']) { $body .= ''; } - if ($bean->getAttribute('chunits')) { + if ($options['show_work_units']) { $body .= ''; } - if ($bean->getAttribute('chcost')) { + if ($options['show_cost']) { $body .= ''; @@ -743,6 +741,11 @@ static function prepareReportBody($bean, $options, $comment) $body .= ''; } +// TODO: refactoring ongoing down from here... + + + + // Print totals. $body .= ''; $body .= ''; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c8a4919c9..cdbd8cbbe 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
'.$group_by_header.''.$i18n->get('label.duration').''.$i18n->get('label.work_units_short').''.$i18n->get('label.cost').'
'.($subtotal['name'] ? htmlspecialchars($subtotal['name']) : ' ').''; if ($subtotal['time'] <> '0:00') $body .= $subtotal['time']; $body .= ''; $body .= $subtotal['units']; $body .= ''; $body .= ($canViewReports || $isClient) ? $subtotal['cost'] : $subtotal['expenses']; $body .= '
 
-
 Anuko Time Tracker 1.17.98.4317 | Copyright © Anuko | +  Anuko Time Tracker 1.17.98.4318 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6e023fcc8768de908976357682d951d9f9a42226 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 6 Aug 2018 14:41:50 +0000 Subject: [PATCH 0215/1848] Merged prepareReportBody and prepareFavReportBody into one function. --- WEB-INF/lib/ttReportHelper.class.php | 338 ++------------------------- WEB-INF/templates/footer.tpl | 2 +- report_send.php | 2 +- 3 files changed, 18 insertions(+), 324 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 1f1654782..019293207 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -657,327 +657,7 @@ static function markPaid($time_log_ids, $expense_item_ids, $paid = true) } // prepareReportBody - prepares an email body for report. - static function prepareReportBody($bean, $options, $comment) - { - global $user; - global $i18n; - - // Determine these once as they are used in multiple places in this function. - $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); - $isClient = $user->isClient(); - - $items = ttReportHelper::getItems($options); - $group_by = $options['group_by']; - if ($group_by && 'no_grouping' != $group_by) - $subtotals = ttReportHelper::getSubtotals($options); - $totals = ttReportHelper::getTotals($options); - - // Use custom fields plugin if it is enabled. - if ($user->isPluginEnabled('cf')) - $custom_fields = new CustomFields($user->group_id); - - // Define some styles to use in email. - $style_title = 'text-align: center; font-size: 15pt; font-family: Arial, Helvetica, sans-serif;'; - $tableHeader = 'font-weight: bold; background-color: #a6ccf7; text-align: left;'; - $tableHeaderCentered = 'font-weight: bold; background-color: #a6ccf7; text-align: center;'; - $rowItem = 'background-color: #ffffff;'; - $rowItemAlt = 'background-color: #f5f5f5;'; - $rowSubtotal = 'background-color: #e0e0e0;'; - $cellLeftAligned = 'text-align: left; vertical-align: top;'; - $cellRightAligned = 'text-align: right; vertical-align: top;'; - $cellLeftAlignedSubtotal = 'font-weight: bold; text-align: left; vertical-align: top;'; - $cellRightAlignedSubtotal = 'font-weight: bold; text-align: right; vertical-align: top;'; - - // Start creating email body. - $body = ''; - $body .= ''; - $body .= ''; - - // Output title. - $body .= '

'.$i18n->get('form.mail.report_subject').': '.$totals['start_date'].' - '.$totals['end_date'].'

'; - - // Output comment. - if ($comment) $body .= '

'.htmlspecialchars($comment).'

'; - - if ($options['show_totals_only']) { - // Totals only report. Output subtotals. - - // Determine group_by header. - if ('cf_1' == $group_by) - $group_by_header = htmlspecialchars($custom_fields->fields[0]['label']); - else { - $key = 'label.'.$group_by; - $group_by_header = $i18n->get($key); - } - - $body .= ''; - $body .= ''; - $body .= ''; - if ($options['show_duration']) - $body .= ''; - if ($options['show_work_units']) - $body .= ''; - if ($options['show_cost']) - $body .= ''; - $body .= ''; - foreach($subtotals as $subtotal) { - $body .= ''; - $body .= ''; - if ($options['show_duration']) { - $body .= ''; - } - if ($options['show_work_units']) { - $body .= ''; - } - if ($options['show_cost']) { - $body .= ''; - } - $body .= ''; - } - -// TODO: refactoring ongoing down from here... - - - - - // Print totals. - $body .= ''; - $body .= ''; - $body .= ''; - if ($bean->getAttribute('chduration')) { - $body .= ''; - } - if ($bean->getAttribute('chunits')) { - $body .= ''; - } - if ($bean->getAttribute('chcost')) { - $body .= ''; - } - $body .= ''; - - $body .= '
'.$group_by_header.''.$i18n->get('label.duration').''.$i18n->get('label.work_units_short').''.$i18n->get('label.cost').'
'.($subtotal['name'] ? htmlspecialchars($subtotal['name']) : ' ').''; - if ($subtotal['time'] <> '0:00') $body .= $subtotal['time']; - $body .= ''; - $body .= $subtotal['units']; - $body .= ''; - $body .= ($canViewReports || $isClient) ? $subtotal['cost'] : $subtotal['expenses']; - $body .= '
 
'.$i18n->get('label.total').''; - if ($totals['time'] <> '0:00') $body .= $totals['time']; - $body .= ''; - $body .= $totals['units']; - $body .= ''.htmlspecialchars($user->currency).' '; - $body .= ($canViewReports || $isClient) ? $totals['cost'] : $totals['expenses']; - $body .= '
'; - } else { - // Regular report. - - // Print table header. - $body .= ''; - $body .= ''; - $body .= ''; - if ($canViewReports || $isClient) - $body .= ''; - if ($bean->getAttribute('chclient')) - $body .= ''; - if ($bean->getAttribute('chproject')) - $body .= ''; - if ($bean->getAttribute('chtask')) - $body .= ''; - if ($bean->getAttribute('chcf_1')) - $body .= ''; - if ($bean->getAttribute('chstart')) - $body .= ''; - if ($bean->getAttribute('chfinish')) - $body .= ''; - if ($bean->getAttribute('chduration')) - $body .= ''; - if ($bean->getAttribute('chunits')) - $body .= ''; - if ($bean->getAttribute('chnote')) - $body .= ''; - if ($bean->getAttribute('chcost')) - $body .= ''; - if ($bean->getAttribute('chpaid')) - $body .= ''; - if ($bean->getAttribute('chip')) - $body .= ''; - if ($bean->getAttribute('chinvoice')) - $body .= ''; - $body .= ''; - - // Initialize variables to print subtotals. - if ($items && 'no_grouping' != $group_by) { - $print_subtotals = true; - $first_pass = true; - $prev_grouped_by = ''; - $cur_grouped_by = ''; - } - // Initialize variables to alternate color of rows for different dates. - $prev_date = ''; - $cur_date = ''; - $row_style = $rowItem; - - // Print report items. - if (is_array($items)) { - foreach ($items as $record) { - $cur_date = $record['date']; - // Print a subtotal row after a block of grouped items. - if ($print_subtotals) { - $cur_grouped_by = $record['grouped_by']; - if ($cur_grouped_by != $prev_grouped_by && !$first_pass) { - $body .= ''; - $body .= ''; - $subtotal_name = htmlspecialchars($subtotals[$prev_grouped_by]['name']); - if ($canViewReports || $isClient) $body .= ''; - if ($bean->getAttribute('chclient')) $body .= ''; - if ($bean->getAttribute('chproject')) $body .= ''; - if ($bean->getAttribute('chtask')) $body .= ''; - if ($bean->getAttribute('chcf_1')) $body .= ''; - if ($bean->getAttribute('chstart')) $body .= ''; - if ($bean->getAttribute('chfinish')) $body .= ''; - if ($bean->getAttribute('chduration')) $body .= ''; - if ($bean->getAttribute('chunits')) $body .= ''; - if ($bean->getAttribute('chnote')) $body .= ''; - if ($bean->getAttribute('chcost')) { - $body .= ''; - } - if ($bean->getAttribute('chpaid')) $body .= ''; - if ($bean->getAttribute('chip')) $body .= ''; - if ($bean->getAttribute('chinvoice')) $body .= ''; - $body .= ''; - $body .= ''; - } - $first_pass = false; - } - - // Print a regular row. - if ($cur_date != $prev_date) - $row_style = ($row_style == $rowItem) ? $rowItemAlt : $rowItem; - $body .= ''; - $body .= ''; - if ($canViewReports || $isClient) - $body .= ''; - if ($bean->getAttribute('chclient')) - $body .= ''; - if ($bean->getAttribute('chproject')) - $body .= ''; - if ($bean->getAttribute('chtask')) - $body .= ''; - if ($bean->getAttribute('chcf_1')) - $body .= ''; - if ($bean->getAttribute('chstart')) - $body .= ''; - if ($bean->getAttribute('chfinish')) - $body .= ''; - if ($bean->getAttribute('chduration')) - $body .= ''; - if ($bean->getAttribute('chunits')) - $body .= ''; - if ($bean->getAttribute('chnote')) - $body .= ''; - if ($bean->getAttribute('chcost')) - $body .= ''; - if ($bean->getAttribute('chpaid')) { - $body .= ''; - } - if ($bean->getAttribute('chip')) { - $body .= ''; - } - if ($bean->getAttribute('chinvoice')) - $body .= ''; - $body .= ''; - - $prev_date = $record['date']; - if ($print_subtotals) - $prev_grouped_by = $record['grouped_by']; - } - } - - // Print a terminating subtotal. - if ($print_subtotals) { - $body .= ''; - $body .= ''; - $subtotal_name = htmlspecialchars($subtotals[$cur_grouped_by]['name']); - if ($canViewReports || $isClient) $body .= ''; - if ($bean->getAttribute('chclient')) $body .= ''; - if ($bean->getAttribute('chproject')) $body .= ''; - if ($bean->getAttribute('chtask')) $body .= ''; - if ($bean->getAttribute('chcf_1')) $body .= ''; - if ($bean->getAttribute('chstart')) $body .= ''; - if ($bean->getAttribute('chfinish')) $body .= ''; - if ($bean->getAttribute('chduration')) $body .= ''; - if ($bean->getAttribute('chunits')) $body .= ''; - if ($bean->getAttribute('chnote')) $body .= ''; - if ($bean->getAttribute('chcost')) { - $body .= ''; - } - if ($bean->getAttribute('chpaid')) $body .= ''; - if ($bean->getAttribute('chip')) $body .= ''; - if ($bean->getAttribute('chinvoice')) $body .= ''; - $body .= ''; - } - - // Print totals. - $body .= ''; - $body .= ''; - $body .= ''; - if ($canViewReports || $isClient) $body .= ''; - if ($bean->getAttribute('chclient')) $body .= ''; - if ($bean->getAttribute('chproject')) $body .= ''; - if ($bean->getAttribute('chtask')) $body .= ''; - if ($bean->getAttribute('chcf_1')) $body .= ''; - if ($bean->getAttribute('chstart')) $body .= ''; - if ($bean->getAttribute('chfinish')) $body .= ''; - if ($bean->getAttribute('chduration')) $body .= ''; - if ($bean->getAttribute('chunits')) $body .= ''; - if ($bean->getAttribute('chnote')) $body .= ''; - if ($bean->getAttribute('chcost')) { - $body .= ''; - } - if ($bean->getAttribute('chpaid')) $body .= ''; - if ($bean->getAttribute('chip')) $body .= ''; - if ($bean->getAttribute('chinvoice')) $body .= ''; - $body .= ''; - - $body .= '
'.$i18n->get('label.date').''.$i18n->get('label.user').''.$i18n->get('label.client').''.$i18n->get('label.project').''.$i18n->get('label.task').''.htmlspecialchars($custom_fields->fields[0]['label']).''.$i18n->get('label.start').''.$i18n->get('label.finish').''.$i18n->get('label.duration').''.$i18n->get('label.work_units_short').''.$i18n->get('label.note').''.$i18n->get('label.cost').''.$i18n->get('label.paid').''.$i18n->get('label.ip').''.$i18n->get('label.invoice').'
'.$i18n->get('label.subtotal').''.($group_by == 'user' ? $subtotal_name : '').''.($group_by == 'client' ? $subtotal_name : '').''.($group_by == 'project' ? $subtotal_name : '').''.($group_by == 'task' ? $subtotal_name : '').''.($group_by == 'cf_1' ? $subtotal_name : '').''.$subtotals[$prev_grouped_by]['time'].''.$subtotals[$prev_grouped_by]['units'].''; - $body .= ($canViewReports || $isClient) ? $subtotals[$prev_grouped_by]['cost'] : $subtotals[$prev_grouped_by]['expenses']; - $body .= '
 
'.$record['date'].''.htmlspecialchars($record['user']).''.htmlspecialchars($record['client']).''.htmlspecialchars($record['project']).''.htmlspecialchars($record['task']).''.htmlspecialchars($record['cf_1']).''.$record['start'].''.$record['finish'].''.$record['duration'].''.$record['units'].''.htmlspecialchars($record['note']).''.$record['cost'].''; - $body .= $record['paid'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); - $body .= ''; - $body .= $record['modified'] ? $record['modified_ip'].' '.$record['modified'] : $record['created_ip'].' '.$record['created']; - $body .= ''.htmlspecialchars($record['invoice']).'
'.$i18n->get('label.subtotal').''.($group_by == 'user' ? $subtotal_name : '').''.($group_by == 'client' ? $subtotal_name : '').''.($group_by == 'project' ? $subtotal_name : '').''.($group_by == 'task' ? $subtotal_name : '').''.($group_by == 'cf_1' ? $subtotal_name : '').''.$subtotals[$cur_grouped_by]['time'].''.$subtotals[$cur_grouped_by]['units'].''; - $body .= ($canViewReports || $isClient) ? $subtotals[$cur_grouped_by]['cost'] : $subtotals[$cur_grouped_by]['expenses']; - $body .= '
 
'.$i18n->get('label.total').''.$totals['time'].''.$totals['units'].''.htmlspecialchars($user->currency).' '; - $body .= ($canViewReports || $isClient) ? $totals['cost'] : $totals['expenses']; - $body .= '
'; - } - - // Output footer. - if (!defined('REPORT_FOOTER') || !(REPORT_FOOTER == false)) - $body .= '

'.$i18n->get('form.mail.footer').'

'; - - // Finish creating email body. - $body .= ''; - - return $body; - } - - // checkFavReportCondition - checks whether it is okay to send fav report. - static function checkFavReportCondition($options, $condition) - { - $items = ttReportHelper::getItems($options); - - $condition = str_replace('count', '', $condition); - $count_required = (int) trim(str_replace('>', '', $condition)); - - if (count($items) > $count_required) - return true; // Condition ok. - - return false; - } - - // prepareFavReportBody - prepares an email body for a favorite report. - static function prepareFavReportBody($options, $comment = null) + static function prepareReportBody($options, $comment = null) { global $user; global $i18n; @@ -1277,6 +957,20 @@ static function prepareFavReportBody($options, $comment = null) return $body; } + // checkFavReportCondition - checks whether it is okay to send fav report. + static function checkFavReportCondition($options, $condition) + { + $items = ttReportHelper::getItems($options); + + $condition = str_replace('count', '', $condition); + $count_required = (int) trim(str_replace('>', '', $condition)); + + if (count($items) > $count_required) + return true; // Condition ok. + + return false; + } + // sendFavReport - sends a favorite report to a specified email, called from cron.php static function sendFavReport($options, $subject, $email, $cc) { // We are called from cron.php, we have no $bean in session. @@ -1285,7 +979,7 @@ static function sendFavReport($options, $subject, $email, $cc) { global $i18n; // Prepare report body. - $body = ttReportHelper::prepareFavReportBody($options); + $body = ttReportHelper::prepareReportBody($options); import('mail.Mailer'); $mailer = new Mailer(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index cdbd8cbbe..1b7d29ce0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.98.4318 | Copyright © Anuko | +  Anuko Time Tracker 1.17.98.4319 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report_send.php b/report_send.php index ea6c555b5..9bbf9f51c 100644 --- a/report_send.php +++ b/report_send.php @@ -75,7 +75,7 @@ $options = ttReportHelper::getReportOptions($bean); // Prepare report body. - $body = ttReportHelper::prepareReportBody($bean, $options, $cl_comment); + $body = ttReportHelper::prepareReportBody($options, $cl_comment); import('mail.Mailer'); $mailer = new Mailer(); From 2ba240f9b321e7d2ccb9e7f9cf90a3be9d304a8d Mon Sep 17 00:00:00 2001 From: Stefan Date: Sat, 11 Aug 2018 19:13:06 +0200 Subject: [PATCH 0216/1848] German (formal) translation (#66) * Update de.lang.php * Update de.lang.php Translated missing strings --- WEB-INF/resources/de.lang.php | 177 ++++++++++++++-------------------- 1 file changed, 72 insertions(+), 105 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index ac6423de6..40e083fe8 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -44,11 +44,9 @@ 'menu.logout' => 'Abmelden', 'menu.forum' => 'Forum', 'menu.help' => 'Hilfe', -// TODO: translate the following. -// 'menu.create_group' => 'Create Group', +'menu.create_group' => 'Erstelle Gruppe', 'menu.profile' => 'Profil', -// TODO: translate the following. -// 'menu.group' => 'Group', +'menu.group' => 'Gruppe', 'menu.time' => 'Zeiten', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Berichte', @@ -56,8 +54,7 @@ 'menu.projects' => 'Projekte', 'menu.tasks' => 'Aufgaben', 'menu.users' => 'Personen', -// TODO: translate the following. -// 'menu.groups' => 'Groups', +'menu.groups' => 'Gruppen', 'menu.export' => 'Exportieren', 'menu.clients' => 'Kunden', 'menu.options' => 'Optionen', @@ -72,8 +69,7 @@ 'error.access_denied' => 'Zugriff verweigert.', 'error.sys' => 'Systemfehler.', 'error.db' => 'Datenbankfehler.', -// TODO: translate the following. -// 'error.feature_disabled' => 'Feature is disabled.', +'error.feature_disabled' => 'Funktion ist deaktiviert.', 'error.field' => 'Ungültige "{0}" Daten.', 'error.empty' => 'Feld "{0}" ist leer.', 'error.not_equal' => 'Feld "{0}" ist nicht gleich Feld "{1}".', @@ -82,18 +78,15 @@ 'error.task' => 'Aufgabe auswählen.', 'error.client' => 'Kunde auswählen.', 'error.report' => 'Bericht auswählen.', -// TODO: translate the following. -// 'error.record' => 'Select record.', +'error.record' => 'Eintrag auswählen.', 'error.auth' => 'Benutzername oder Passwort ungültig.', 'error.user_exists' => 'Benutzer mit diesem Konto ist bereits vorhanden.', -// TODO: translate the following. -// 'error.object_exists' => 'Object with this name already exists.', +'error.object_exists' => 'Objekt mit diesem Namen ist bereits vorhanden.', 'error.project_exists' => 'Es gibt bereits ein Projekt mit diesem Namen.', 'error.task_exists' => 'Task mit diesem Namen existiert bereits.', 'error.client_exists' => 'Der Kunde mit dem Namen existiert schon.', 'error.invoice_exists' => 'Rechnung mit dieser Nummer existiert bereits.', -// TODO: translate the following. -// 'error.role_exists' => 'Role with this rank already exists.', +'error.role_exists' => 'Rolle mit diesem Rang existiert bereits.', 'error.no_invoiceable_items' => 'Keine Einträge zur Rechnungsstellung gefunden.', 'error.no_login' => 'Benutzer mit diesen Anmeldedaten nicht vorhanden.', 'error.no_groups' => 'Die Datenbank ist leer. Als Administrator anmelden und ein neues Team erzeugen.', // TODO: replace "team" with "group". @@ -126,7 +119,7 @@ 'button.stop' => 'Stop', // Labels for controls on forms. Labels in this section are used on multiple forms. -'label.group_name' => 'Teamname', // TODO: replace "team" with "group". +'label.group_name' => 'Gruppenname', 'label.address' => 'Adresse', 'label.currency' => 'Währung', 'label.manager_name' => 'Manager Name', @@ -145,8 +138,7 @@ 'label.end_date' => 'Enddatum', 'label.user' => 'Benutzer', 'label.users' => 'Personen', -// TODO: translate the following. -// 'label.roles' => 'Roles', +'label.roles' => 'Rollen', 'label.client' => 'Kunde', 'label.clients' => 'Kunden', 'label.option' => 'Option', @@ -163,8 +155,7 @@ 'label.notes' => 'Beschreibungen', 'label.item' => 'Position', 'label.cost' => 'Kosten', -// TODO: translate the following. -// 'label.ip' => 'IP', +'label.ip' => 'IP', 'label.day_total' => 'Summe (Tag)', 'label.week_total' => 'Summe (Woche)', 'label.month_total' => 'Summe (Monat)', @@ -218,10 +209,10 @@ 'label.paid' => 'Bezahlt', 'label.mark_paid' => 'Als bezahlt setzen', // TODO: translate the following. -// 'label.week_note' => 'Week note', -// 'label.week_list' => 'Week list', -// 'label.work_units' => 'Work units', -// 'label.work_units_short' => 'Units', +'label.week_note' => 'Wochennotiz', +'label.week_list' => 'Wochenliste', +'label.work_units' => 'Arbeitseinheiten', +'label.work_units_short' => 'Einheiten', 'label.totals_only' => 'Nur Gesamtstunden', // Form titles. @@ -256,11 +247,10 @@ 'title.add_user' => 'Benutzerkonto erstellen', 'title.edit_user' => 'Benutzerdaten bearbeiten', 'title.delete_user' => 'Benutzer löschen', -// TODO: translate the following. -// 'title.roles' => 'Roles', -// 'title.add_role' => 'Adding Role', -// 'title.edit_role' => 'Editing Role', -// 'title.delete_role' => 'Deleting Role', +'title.roles' => 'Rolle', +'title.add_role' => 'Rolle hinzufügen', +'title.edit_role' => 'Rolle bearbeiten', +'title.delete_role' => 'Rolle löschen', 'title.clients' => 'Kunden', 'title.add_client' => 'Kunden hinzufügen', 'title.edit_client' => 'Kunden bearbeiten', @@ -278,8 +268,7 @@ 'title.import' => 'Daten importieren', 'title.options' => 'Optionen', 'title.profile' => 'Profil', -// TODO: translate the following. -// 'title.group' => 'Group Settings', +'title.group' => 'Gruppeneinstellungen', 'title.cf_custom_fields' => 'Benutzerfelder', 'title.cf_add_custom_field' => 'Benutzerfeld hinzufügen', 'title.cf_edit_custom_field' => 'Benutzerfeld bearbeiten', @@ -289,10 +278,9 @@ 'title.cf_edit_dropdown_option' => 'Auswahlmöglichkeit bearbeiten', 'title.cf_delete_dropdown_option' => 'Auswahlmöglichkeit löschen', 'title.locking' => 'Sperren', -// TODO: translate the following. -// 'title.week_view' => 'Week View', -// 'title.swap_roles' => 'Swapping Roles', -// 'title.work_units' => 'Work Units', +'title.week_view' => 'Wochenansicht', +'title.swap_roles' => 'Tausche Rollen', +'title.work_units' => 'Arbeitseinheiten', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. @@ -335,10 +323,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Anfrage zur Zurücksetzung des Passwortes wurde per E-mail gesendet.', 'form.reset_password.email_subject' => 'Anuko Time Tracker Anfrage zur Zurücksetzung des Passwortes', -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", -// "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Sehr geehrter Nutzer,\n\nJemand, IP %s, sendete die Aufforderung Ihr Anuko Time Tracker Passwort zurückzusetzen. Bitte rufen Sie diesen Link auf wenn Sie Ihr Passwort zurücksetzen möchten.\n\n%s\n\nAnuko Time Tracker ist ein einfaches, leicht zu bedienendes, Open-Source Zeiterfassungs-System. Besuchen Sie https://www.anuko.com für weitere Informationen.\n\n", +'form.reset_password.email_body' => "Sehr geehrte(r) Nutzer(in),\n\nEin Benutzer mit der IP %s hat vor Kurzem die Zurücksetzung Ihres Passworts für Anuko Time Tracker Passwort angefordert. Bitte rufen Sie diesen Link auf wenn Sie Ihr Passwort zurücksetzen möchten.\n\n%s\n\nAnuko Time Tracker ist ein einfaches, leicht zu bedienendes, Open-Source Zeiterfassungs-System. Besuchen Sie https://www.anuko.com für weitere Informationen.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Um das Passwort zurückzusetzen, geben Sie ein Neues ein und klicken dann auf Speichern.', @@ -377,8 +362,7 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportiere', -// TODO: translate the following. -// 'form.report.assign_to_invoice' => 'Assign to invoice', +'form.report.assign_to_invoice' => 'Zu Rechnung hinzufügen', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). @@ -388,13 +372,7 @@ // Deleting Invoice form. See example at https://timetracker.anuko.com/invoice_delete.php 'form.invoice.invoice_to_delete' => 'Zu löschende Rechnung', 'form.invoice.invoice_entries' => 'Rechnungseintrag', -'form.invoice.confirm_deleting_entries' => 'Bitte die Löschung von Rechnungseinträgen bestätigen.', -// TODO: consider improving translation of form.invoice.confirm_deleting_entries -// This is a warning to user when they are deleting invoice entries. -// They may believe they delete entries from the invoice only but keep the Time Tracker (reports, etc.). -// What is really happening we delete entries from the system, so that they are no longer in reports, etc. -// Original English wording is as follows. -// 'form.invoice.confirm_deleting_entries' => 'Please confirm deleting invoice entries from Time Tracker.', +'form.invoice.confirm_deleting_entries' => 'Bitte bestätigen Sie, dass die Einträge der Rechnung aus dem gesamten System gelöscht werden sollen.', // Charts form. See example at https://timetracker.anuko.com/charts.php 'form.charts.interval' => 'Zeitraum', @@ -419,17 +397,15 @@ 'form.users.default_rate' => 'Normaler Stundensatz', // Editing User form. See example at https://timetracker.anuko.com/user_edit.php -// TODO: translate the following. -// 'form.user_edit.swap_roles' => 'Swap roles', +'form.user_edit.swap_roles' => 'Rollen tauschen', // Roles form. See example at https://timetracker.anuko.com/roles.php -// TODO: translate the following. -// 'form.roles.active_roles' => 'Active Roles', -// 'form.roles.inactive_roles' => 'Inactive Roles', -// 'form.roles.rank' => 'Rank', -// 'form.roles.rights' => 'Rights', -// 'form.roles.assigned' => 'Assigned', -// 'form.roles.not_assigned' => 'Not assigned', +'form.roles.active_roles' => 'Aktive Rollen', +'form.roles.inactive_roles' => 'Inaktive Rollen', +'form.roles.rank' => 'Rang', +'form.roles.rights' => 'Rechte', +'form.roles.assigned' => 'Zugewiesen', +'form.roles.not_assigned' => 'Nicht zugewiesen', // Clients form. See example at https://timetracker.anuko.com/clients.php 'form.clients.active_clients' => 'Aktive Kunden', @@ -440,26 +416,23 @@ 'form.client.client_entries' => 'Kundeneintrag', // Exporting Group Data form. See example at https://timetracker.anuko.com/export.php -// TODO: replace "team" with "group" in the string below. -'form.export.hint' => 'Sie können alle Teamdaten in eine XML-Datei exportieren. Diese können in andere Zeiterfassungs-Programme importiert werden.', +'form.export.hint' => 'Sie können alle Gruppendaten in eine XML-Datei exportieren. Diese können in andere Zeiterfassungs-Programme importiert werden.', 'form.export.compression' => 'Kompression', 'form.export.compression_none' => 'Keine', 'form.export.compression_bzip' => 'bzip', // Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). -'form.import.hint' => 'Teamdaten von einer XML-Datei importieren.', // TODO: replace "team" with "group". +'form.import.hint' => 'Gruppendaten von einer XML-Datei importieren.', 'form.import.file' => 'Datei auswählen', 'form.import.success' => 'Import erfolgreich abgeschlossen.', // Groups form. See example at https://timetracker.anuko.com/admin_groups.php (login as admin first). -// TODO: replace "team" with "group" in the string below. -'form.groups.hint' => 'Das Erzeugen eines neuen Manager Kontos, erzeugt eine neues Team.
Diese Teams können auch von XML-Dateien importiert werden.', +'form.groups.hint' => 'Das Erzeugen eines neuen Manager Kontos, erzeugt eine neue Gruppe.
Diese Gruppen können auch von XML-Dateien importiert werden.', // Group Settings form. See example at https://timetracker.anuko.com/group_edit.php. 'form.group_edit.12_hours' => '12 Stunden', 'form.group_edit.24_hours' => '24 Stunden', -// TODO: translate the following. -// 'form.group_edit.show_holidays' => 'Show holidays', +'form.group_edit.show_holidays' => 'Zeige Feiertage', 'form.group_edit.tracking_mode' => 'Nachverfolgung', 'form.group_edit.mode_time' => 'Zeit', 'form.group_edit.mode_projects' => 'Projekte', @@ -468,17 +441,15 @@ 'form.group_edit.type_all' => 'alle', 'form.group_edit.type_start_finish' => 'Start und Ende', 'form.group_edit.type_duration' => 'Dauer', -// TODO: translate the following. -// 'form.group_edit.punch_mode' => 'Punch mode', -// 'form.group_edit.allow_overlap' => 'Allow overlap', -// 'form.group_edit.future_entries' => 'Future entries', -// 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.allow_ip' => 'Allow IP', +'form.group_edit.punch_mode' => 'Stechuhr-Modus', +'form.group_edit.allow_overlap' => 'Erlaube Überschneidung', +'form.group_edit.future_entries' => 'Einträge in der Zukunft', +'form.group_edit.uncompleted_indicators' => 'Zeige unfertige Einträge', +'form.group_edit.allow_ip' => 'Erlaube IP', 'form.group_edit.plugins' => 'Erweiterungen', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php -// TODO: translate the following. -// 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', +'form.group_delete.hint' => 'Sind Sie sicher, dass Sie die gesamte Gruppe löschen möchten?', // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.from' => 'Von', @@ -489,44 +460,40 @@ 'form.mail.invoice_sent' => 'Die Rechnung wurde gesendet.', // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. -// TODO: translate the following. -// 'form.quota.year' => 'Year', -// 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', -// 'form.quota.workday_hours' => 'Hours in work day', -// 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', +'form.quota.year' => 'Jahr', +'form.quota.month' => 'Monat', +'form.quota.quota' => 'Quote', +'form.quota.workday_hours' => 'Arbeitsstunden pro Tag', +'form.quota.hint' => 'Wenn leergelassen wird die Quote automatisch berechnet (Basierend auf Arbeitsstunden pro Tag und Feiertagen)', // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. -// TODO: translate the following. -// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', -// 'form.swap.swap_with' => 'Swap roles with', +'form.swap.hint' => 'Stufen Sie ihre Rolle auf eine niedrigere indem Sie mit jemadem die Rollen tauschen. Dies kann nicht rückgängig gemacht werden.', +'form.swap.swap_with' => 'Tausche Rolle mit', // Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. -// TODO: translate the following. -// 'form.work_units.minutes_in_unit' => 'Minutes in unit', -// 'form.work_units.1st_unit_threshold' => '1st unit threshold', +'form.work_units.minutes_in_unit' => 'Minuten in einer Arbeitseinheit', +'form.work_units.1st_unit_threshold' => 'Schwellenwert für erste Arbeitseinheit', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. -// TODO: translate the following. -// 'role.user.label' => 'User', -// 'role.user.low_case_label' => 'user', -// 'role.user.description' => 'A regular member without management rights.', -// 'role.client.label' => 'Client', -// 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', -// 'role.supervisor.label' => 'Supervisor', -// 'role.supervisor.low_case_label' => 'supervisor', -// 'role.supervisor.description' => 'A person with a small set of management rights.', -// 'role.comanager.label' => 'Co-manager', -// 'role.comanager.low_case_label' => 'co-manager', -// 'role.comanager.description' => 'A person with a big set of management functions.', -// 'role.manager.label' => 'Manager', -// 'role.manager.low_case_label' => 'manager', -// 'role.manager.description' => 'Group manager. Can do most of things for a group.', -// 'role.top_manager.label' => 'Top manager', -// 'role.top_manager.low_case_label' => 'top manager', -// 'role.top_manager.description' => 'Top group manager. Can do everything in a tree of groups.', -// 'role.admin.label' => 'Administrator', -// 'role.admin.low_case_label' => 'administrator', -// 'role.admin.description' => 'Site adminsitrator.', +'role.user.label' => 'Benutzer', +'role.user.low_case_label' => 'Benutzer', +'role.user.description' => 'Ein normaler Benutzer ohne Administrationsrechte.', +'role.client.label' => 'Kunde', +'role.client.low_case_label' => 'Kunde', +'role.client.description' => 'Ein Kunde kann zu ihm gehörende Berichte, Diagramme und Rechnungen ansehen.', +'role.supervisor.label' => 'Dienstvorgesetzter', +'role.supervisor.low_case_label' => 'Dienstvorgesetzter', +'role.supervisor.description' => 'Eine Person mit ein paar Administrationsrechten.', +'role.comanager.label' => 'Co-Manager', +'role.comanager.low_case_label' => 'Co-Manager', +'role.comanager.description' => 'Ein Person mit vielen Administrationsrechten.', +'role.manager.label' => 'Manager', +'role.manager.low_case_label' => 'Manager', +'role.manager.description' => 'Gruppen-Manager. Kann fast alles innerhalb einer Gruppe administrieren.', +'role.top_manager.label' => 'Top-Manager', +'role.top_manager.low_case_label' => 'Top-Manager', +'role.top_manager.description' => 'Top Gruppen-Manager. Kann alles innerhalb eines Gruppenbaums administrieren', +'role.admin.label' => 'Administrator', +'role.admin.low_case_label' => 'Administrator', +'role.admin.description' => 'Aadminsitrator der Seite.', ); From 3a44195498f8f70c67f7122909c7977cad0351f0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Aug 2018 17:19:28 +0000 Subject: [PATCH 0217/1848] Cosmetic changes in the German file. --- WEB-INF/resources/de.lang.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 40e083fe8..42c7c8aa9 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -89,7 +89,7 @@ 'error.role_exists' => 'Rolle mit diesem Rang existiert bereits.', 'error.no_invoiceable_items' => 'Keine Einträge zur Rechnungsstellung gefunden.', 'error.no_login' => 'Benutzer mit diesen Anmeldedaten nicht vorhanden.', -'error.no_groups' => 'Die Datenbank ist leer. Als Administrator anmelden und ein neues Team erzeugen.', // TODO: replace "team" with "group". +'error.no_groups' => 'Die Datenbank ist leer. Als Administrator anmelden und ein neues Gruppe erzeugen.', 'error.upload' => 'Fehler beim hochladen einer Datei.', 'error.range_locked' => 'Zeitinterval ist gesperrt.', 'error.mail_send' => 'Fehler beim versenden einer E-Mail.', @@ -208,7 +208,6 @@ 'label.paid_status' => 'Bezahlstatus', 'label.paid' => 'Bezahlt', 'label.mark_paid' => 'Als bezahlt setzen', -// TODO: translate the following. 'label.week_note' => 'Wochennotiz', 'label.week_list' => 'Wochenliste', 'label.work_units' => 'Arbeitseinheiten', @@ -323,7 +322,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Anfrage zur Zurücksetzung des Passwortes wurde per E-mail gesendet.', 'form.reset_password.email_subject' => 'Anuko Time Tracker Anfrage zur Zurücksetzung des Passwortes', -'form.reset_password.email_body' => "Sehr geehrte(r) Nutzer(in),\n\nEin Benutzer mit der IP %s hat vor Kurzem die Zurücksetzung Ihres Passworts für Anuko Time Tracker Passwort angefordert. Bitte rufen Sie diesen Link auf wenn Sie Ihr Passwort zurücksetzen möchten.\n\n%s\n\nAnuko Time Tracker ist ein einfaches, leicht zu bedienendes, Open-Source Zeiterfassungs-System. Besuchen Sie https://www.anuko.com für weitere Informationen.\n\n", +'form.reset_password.email_body' => "Sehr geehrter Nutzer,\n\nEin Benutzer mit der IP %s hat vor Kurzem die Zurücksetzung Ihres Passworts für Anuko Time Tracker Passwort angefordert. Bitte rufen Sie diesen Link auf wenn Sie Ihr Passwort zurücksetzen möchten.\n\n%s\n\nAnuko Time Tracker ist ein einfaches, leicht zu bedienendes, Open-Source Zeiterfassungs-System. Besuchen Sie https://www.anuko.com für weitere Informationen.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Um das Passwort zurückzusetzen, geben Sie ein Neues ein und klicken dann auf Speichern.', From 98dfff814b103b57c450173804f92a255909a3ba Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 14 Aug 2018 21:16:29 +0000 Subject: [PATCH 0218/1848] Improved access check for cf_custom_field_add.php. --- WEB-INF/templates/footer.tpl | 2 +- cf_custom_field_add.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1b7d29ce0..99c9b21cb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.98.4319 | Copyright © Anuko | +  Anuko Time Tracker 1.17.98.4320 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index 922d83b7c..8227d2541 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -39,6 +39,12 @@ header('Location: feature_disabled.php'); exit(); } +$fields = CustomFields::getFields(); +// Deny access when max number of custom fields is already set. +if (count($fields) >= 1) { + header('Location: access_denied.php'); + exit(); +} if ($request->isPost()) { $cl_field_name = trim($request->getParameter('name')); From d2fa5b1566bf9834fd19e24231941a9a62e2164a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 Sep 2018 18:04:49 +0000 Subject: [PATCH 0219/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 907b4a496..2e63e8436 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -210,9 +210,8 @@ 'label.mark_paid' => 'Markeer als betaald', 'label.week_note' => 'Week aantekening', 'label.week_list' => 'Week overzicht', -// TODO: translate the following. -// 'label.work_units' => 'Work units', -// 'label.work_units_short' => 'Units', +'label.work_units' => 'Werk eenheid', +'label.work_units_short' => 'Eenheid', 'label.totals_only' => 'Alleen totalen', // Form titles. @@ -284,8 +283,7 @@ 'title.locking' => 'Blokkeren', 'title.week_view' => 'Week overzicht', 'title.swap_roles' => 'Rollen verruilen', -// TODO: translate the following. -// 'title.work_units' => 'Work Units', +'title.work_units' => 'Werk eenheid', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. @@ -476,9 +474,8 @@ 'form.swap.swap_with' => 'Verruil rol met', // Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. -// TODO: translate the following. -// 'form.work_units.minutes_in_unit' => 'Minutes in unit', -// 'form.work_units.1st_unit_threshold' => '1st unit threshold', +'form.work_units.minutes_in_unit' => 'Minuten per eenheid', +'form.work_units.1st_unit_threshold' => 'Drempel eerste eenheid', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. 'role.user.label' => 'Gebruiker', From 34627c08c23651305a94e9e533249cc1d3472685 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Sep 2018 17:09:19 +0000 Subject: [PATCH 0220/1848] Added adjustOptions function to ttFavRepportHelper class and started to use it in cron.php. --- WEB-INF/lib/ttFavReportHelper.class.php | 46 +++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- cron.php | 26 ++------------ 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 0a21f7c94..069ecbb5f 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -325,4 +325,50 @@ static function getReportOptions($id) { // $options now is a subset of db fields from tt_fav_reports table. return $options; } + + // adjustOptions takes and array or report options and adjusts them for current user + // (and group) settings. This is needed in situations when a fav report is stored in db + // long ago, but user or group attributes are now changed, so we have to adjust. + static function adjustOptions($options) { + global $user; + + // Check and optionally adjust users. + // Special handling of the NULL $options['users'] field (this used to mean "all users"). + if (!$options['users']) { + if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { + if ($user->can('view_reports') || $user->can('view_all_reports')) { + $max_rank = $user->rank-1; + if ($user->can('view_all_reports')) $max_rank = 512; + if ($user->can('view_own_reports')) + $user_options = array('max_rank'=>$max_rank,'include_self'=>true); + else + $user_options = array('max_rank'=>$max_rank); + $users = $user->getUsers($user_options); // Active and inactive users. + } elseif ($user->isClient()) { + $users = ttTeamHelper::getUsersForClient(); // Active and inactive users for clients. + } + foreach ($users as $single_user) { + $user_ids[] = $single_user['id']; + } + $options['users'] = implode(',', $user_ids); + } + } else { + $users_to_adjust = explode(',', $options['users']); // Users to adjust. + if ($user->isClient()) { + $users = ttTeamHelper::getUsersForClient(); // Active and inactive users for clients. + foreach ($users as $single_user) { + $user_ids[] = $single_user['id']; + } + foreach ($users_to_adjust as $user_to_adjust) { + if (in_array($user_to_adjust['id'], $user_ids)) { + $adjusted_user_ids[] = $user_to_adjust['id']; + } + } + $options['users'] = implode(',', $adjusted_user_ids); + } + // TODO: add checking the existing user list for potentially changed access rights for user. + } + + return $options; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 99c9b21cb..2c74b1ec1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + diff --git a/plugins.php b/plugins.php index fce36a7e4..60b86fede 100644 --- a/plugins.php +++ b/plugins.php @@ -146,6 +146,6 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="handlePluginCheckboxes();"'); -$smarty->assign('title', $i18n->get('form.group_edit.plugins')); // TODO: fix this in transl;ation files. +$smarty->assign('title', $i18n->get('title.plugins')); $smarty->assign('content_page_name', 'plugins.tpl'); $smarty->display('index.tpl'); From 9b51878cb6636d768f5938615090c67f397a6558 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Sep 2018 18:42:53 +0000 Subject: [PATCH 0225/1848] Moved plugins config out to a separate plugins.php page. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 140 ------------------------------- WEB-INF/templates/header.tpl | 3 + group_edit.php | 86 ------------------- 4 files changed, 4 insertions(+), 227 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2c74b1ec1..bfb6356cd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.17.98.4320 | Copyright © Anuko | +  Anuko Time Tracker 1.17.98.4321 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cron.php b/cron.php index 7d766992c..eabcaa05c 100644 --- a/cron.php +++ b/cron.php @@ -67,33 +67,11 @@ if (!$user->id) continue; // Skip not found user. // TODO: write a new function ttFavReportHelper::adjustOptions that will use - // a $user objecte recycled above. Put user handling below into it. + // a $user object recycled above. Put user handling below into it. // Also adjust remaining options for potentially changed user access rights and group properties. // For example, tracking mode may have changed, but fav report options are still old... // This needs to be fixed. - - // Special handling of the NULL $options['users'] field (this used to mean "all users"). - if (!$options['users']) { - if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { - if ($user->can('view_reports') || $user->can('view_all_reports')) { - $max_rank = $user->rank-1; - if ($user->can('view_all_reports')) $max_rank = 512; - if ($user->can('view_own_reports')) - $user_options = array('max_rank'=>$max_rank,'include_self'=>true); - else - $user_options = array('max_rank'=>$max_rank); - $users = $user->getUsers($user_options); // Active and inactive users. - } elseif ($user->isClient()) { - $users = ttTeamHelper::getUsersForClient(); // Active and inactive users for clients. - } - foreach ($users as $single_user) { - $user_ids[] = $single_user['id']; - } - $options['users'] = implode(',', $user_ids); - } - } else { - // TODO: add checking the existing user list for potentially changed access rights for user. - } + $options = ttFavReportHelper::adjustOptions($options); // Skip users with disabled Notifications plugin. if (!$user->isPluginEnabled('no')) continue; From 873cee05ecd24aa9066b467b2c90132ee08a99a1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Sep 2018 17:46:27 +0000 Subject: [PATCH 0221/1848] Work in progress on separate page for plugins config. --- WEB-INF/templates/group_edit.tpl | 2 +- WEB-INF/templates/plugins.tpl | 147 ++++++++++++++++++++++++++++++ plugins.php | 151 +++++++++++++++++++++++++++++++ 3 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/templates/plugins.tpl create mode 100644 plugins.php diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index db66201c5..d2a9476ad 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -16,7 +16,7 @@ function handleTaskRequiredCheckbox() { } -// handleControls - controls visibility of controls. +// handlePluginCheckboxes - controls visibility of controls. function handlePluginCheckboxes() { var clientsCheckbox = document.getElementById("clients"); var invoicesCheckbox = document.getElementById("invoices"); diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl new file mode 100644 index 000000000..f72d5699a --- /dev/null +++ b/WEB-INF/templates/plugins.tpl @@ -0,0 +1,147 @@ + + +{$forms.pluginsForm.open} + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$forms.pluginsForm.charts.control}
{$forms.pluginsForm.clients.control} {$forms.pluginsForm.client_required.control}
{$forms.pluginsForm.invoices.control}
{$forms.pluginsForm.paid_status.control}
{$forms.pluginsForm.custom_fields.control} {$i18n.label.configure}
{$forms.pluginsForm.expenses.control} {$forms.pluginsForm.tax_expenses.control} {$i18n.label.configure}
{$forms.pluginsForm.notifications.control} {$i18n.label.configure}
{$forms.pluginsForm.locking.control} {$i18n.label.configure}
{$forms.pluginsForm.quotas.control} {$i18n.label.configure}
{$forms.pluginsForm.week_view.control} {$i18n.label.configure}
{$forms.pluginsForm.work_units.control} {$i18n.label.configure}
 
{$forms.pluginsForm.btn_save.control}
+
+{$forms.pluginsForm.close} diff --git a/plugins.php b/plugins.php new file mode 100644 index 000000000..fce36a7e4 --- /dev/null +++ b/plugins.php @@ -0,0 +1,151 @@ +config); + + +if ($request->isPost()) { + // Plugin checkboxes. + $cl_charts = $request->getParameter('charts'); + $cl_clients = $request->getParameter('clients'); + $cl_client_required = $request->getParameter('client_required'); + $cl_invoices = $request->getParameter('invoices'); + $cl_paid_status = $request->getParameter('paid_status'); + $cl_custom_fields = $request->getParameter('custom_fields'); + $cl_expenses = $request->getParameter('expenses'); + $cl_tax_expenses = $request->getParameter('tax_expenses'); + $cl_notifications = $request->getParameter('notifications'); + $cl_locking = $request->getParameter('locking'); + $cl_quotas = $request->getParameter('quotas'); + $cl_week_view = $request->getParameter('week_view'); + $cl_work_units = $request->getParameter('work_units'); +} else { + // Which plugins do we have enabled? + $plugins = explode(',', $user->plugins); + $cl_charts = in_array('ch', $plugins); + $cl_clients = in_array('cl', $plugins); + $cl_client_required = in_array('cm', $plugins); + $cl_invoices = in_array('iv', $plugins); + $cl_paid_status = in_array('ps', $plugins); + $cl_custom_fields = in_array('cf', $plugins); + $cl_expenses = in_array('ex', $plugins); + $cl_tax_expenses = in_array('et', $plugins); + $cl_notifications = in_array('no', $plugins); + $cl_locking = in_array('lk', $plugins); + $cl_quotas = in_array('mq', $plugins); + $cl_week_view = in_array('wv', $plugins); + $cl_work_units = in_array('wu', $plugins); +} + +$form = new Form('pluginsForm'); + +// Plugin checkboxes. +$form->addInput(array('type'=>'checkbox','name'=>'charts','value'=>$cl_charts)); +$form->addInput(array('type'=>'checkbox','name'=>'clients','value'=>$cl_clients,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'client_required','value'=>$cl_client_required)); +$form->addInput(array('type'=>'checkbox','name'=>'invoices','value'=>$cl_invoices)); +$form->addInput(array('type'=>'checkbox','name'=>'paid_status','value'=>$cl_paid_status)); +$form->addInput(array('type'=>'checkbox','name'=>'custom_fields','value'=>$cl_custom_fields,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'expenses','value'=>$cl_expenses,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'tax_expenses','value'=>$cl_tax_expenses)); +$form->addInput(array('type'=>'checkbox','name'=>'notifications','value'=>$cl_notifications,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'locking','value'=>$cl_locking,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'quotas','value'=>$cl_quotas,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'week_view','value'=>$cl_week_view,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'work_units','value'=>$cl_work_units,'onchange'=>'handlePluginCheckboxes()')); + +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()) { + + // Validate user input. Do we have to? + + if ($err->no()) { + // Prepare plugins string. + if ($cl_charts) + $plugins .= ',ch'; + if ($cl_clients) + $plugins .= ',cl'; + if ($cl_client_required) + $plugins .= ',cm'; + if ($cl_invoices) + $plugins .= ',iv'; + if ($cl_paid_status) + $plugins .= ',ps'; + if ($cl_custom_fields) + $plugins .= ',cf'; + if ($cl_expenses) + $plugins .= ',ex'; + if ($cl_tax_expenses) + $plugins .= ',et'; + if ($cl_notifications) + $plugins .= ',no'; + if ($cl_locking) + $plugins .= ',lk'; + if ($cl_quotas) + $plugins .= ',mq'; + if ($cl_week_view) + $plugins .= ',wv'; + if ($cl_work_units) + $plugins .= ',wu'; + + // Recycle week view plugin options as they are not configured on this page. + $existing_plugins = explode(',', $user->plugins); + if (in_array('wvn', $existing_plugins)) + $plugins .= ',wvn'; + if (in_array('wvl', $existing_plugins)) + $plugins .= ',wvl'; + if (in_array('wvns', $existing_plugins)) + $plugins .= ',wvns'; + + $plugins = trim($plugins, ','); + + if ($user->updateGroup(array( + 'plugins' => $plugins))) { + header('Location: time.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="handlePluginCheckboxes();"'); +$smarty->assign('title', $i18n->get('form.group_edit.plugins')); // TODO: fix this in transl;ation files. +$smarty->assign('content_page_name', 'plugins.tpl'); +$smarty->display('index.tpl'); From 92dd94c462e142e8a5f7aae9594dd75b5b5a7afa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Sep 2018 17:59:02 +0000 Subject: [PATCH 0222/1848] A bit more work on separate page for plugins config. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + 30 files changed, 36 insertions(+) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 9d446f2a4..59330487b 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -50,6 +50,7 @@ 'menu.profile' => 'Perfil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Temps', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index fccc92b51..88f3fc08a 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -52,6 +52,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', // 'menu.time' => 'Time', // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Sestavy', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 4390e22bb..85e6e3924 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -49,6 +49,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Tid', 'menu.expenses' => 'Udgifter', 'menu.reports' => 'Rapporter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 42c7c8aa9..0200660b0 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -47,6 +47,8 @@ 'menu.create_group' => 'Erstelle Gruppe', 'menu.profile' => 'Profil', 'menu.group' => 'Gruppe', +// TODO: translate the following. +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Zeiten', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Berichte', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 50180602a..40c21d77a 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -47,6 +47,7 @@ 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profile', 'menu.group' => 'Group', +'menu.plugins' => 'Plugins', 'menu.time' => 'Time', 'menu.expenses' => 'Expenses', 'menu.reports' => 'Reports', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index f03a331b1..661cd3d61 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -49,6 +49,7 @@ 'menu.profile' => 'Perfil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Tiempo', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index f59da5646..0a82fbe02 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -52,6 +52,7 @@ 'menu.profile' => 'Profiili', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Aeg', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f2a033312..ec2ff9658 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -50,6 +50,7 @@ 'menu.profile' => 'پروفايل', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'زمان', 'menu.expenses' => 'هزينه ها', 'menu.reports' => 'گزارشات', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index f06429daa..661a0ba89 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -49,6 +49,7 @@ 'menu.profile' => 'Profiili', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Tunnit', 'menu.expenses' => 'Kulut', 'menu.reports' => 'Raportit', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 49825603c..111aa811f 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -49,6 +49,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Temps', 'menu.expenses' => 'Dépenses', 'menu.reports' => 'Rapports', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 3c6d78a2e..342adde0c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -47,6 +47,8 @@ 'menu.create_group' => 'Δημιουργία ομάδας', 'menu.profile' => 'Προφίλ', 'menu.group' => 'Ομάδα', +// TODO: translate the following. +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Χρόνος', 'menu.expenses' => 'Έξοδα', 'menu.reports' => 'Αναφορές', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index cd61af660..9e5c0d18a 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -50,6 +50,7 @@ 'menu.profile' => 'פרופיל', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'זמן', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index f0dacf13e..372dd9437 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -49,6 +49,8 @@ 'menu.create_group' => 'Csoport létrehozása', 'menu.profile' => 'Profil', 'menu.group' => 'Csoport', +// TODO: translate the following. +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Munkaidő', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ceedf9f52..2392815f6 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -49,6 +49,8 @@ 'menu.create_group' => 'Crea gruppo', 'menu.profile' => 'Profilo', 'menu.group' => 'Gruppo', +// TODO: translate the following. +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Tempo', 'menu.expenses' => 'Spese', 'menu.reports' => 'Rapporti', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 07dc50b9f..e5f933d07 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -50,6 +50,7 @@ 'menu.profile' => 'プロファイル', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => '時間', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 21c34a561..36d888718 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -50,6 +50,7 @@ 'menu.profile' => '프로필', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => '시간', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 2e63e8436..9c21e1201 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -47,6 +47,8 @@ 'menu.create_group' => 'Maak groep', 'menu.profile' => 'Profiel', 'menu.group' => 'Groep', +// TODO: translate the following. +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Tijden', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Rapporten', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 436f59016..e135b8d3c 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -51,6 +51,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Tid', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 6b262c22d..9e8e4c761 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -49,6 +49,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Czas', 'menu.expenses' => 'Wydatki', 'menu.reports' => 'Raporty', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index afdd8eb94..f658e4a2e 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -49,6 +49,7 @@ 'menu.profile' => 'Perfil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Tempo', 'menu.expenses' => 'Gastos', 'menu.reports' => 'Relatórios', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 834aaaf56..a6c48693c 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -52,6 +52,7 @@ 'menu.profile' => 'Perfil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Tempo', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index f00956294..e7fdbd35a 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -52,6 +52,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Timpul', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 85155b423..ad71ecc5b 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -47,6 +47,7 @@ 'menu.create_group' => 'Создать группу', 'menu.profile' => 'Профиль', 'menu.group' => 'Группа', +'menu.plugins' => 'Плагины', 'menu.time' => 'Время', 'menu.expenses' => 'Расходы', 'menu.reports' => 'Отчёты', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index f79f4abd5..ed66a67bb 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -49,6 +49,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Časový záznam', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 3e24c2541..5812629dd 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -52,6 +52,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', // 'menu.time' => 'Time', // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Poročila', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 7e7d7f4d1..8702df928 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -49,6 +49,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Vreme', 'menu.expenses' => 'Troškovi', 'menu.reports' => 'Izveštaji', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index c2159bb1a..f6b2b1bdb 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -47,6 +47,8 @@ 'menu.create_group' => 'Skapa grupp', 'menu.profile' => 'Profil', 'menu.group' => 'Grupp', +// TODO: translate the following. +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Tider', 'menu.expenses' => 'Kostnader', 'menu.reports' => 'Rapporter', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 0159c7a9c..a2707fd92 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -52,6 +52,7 @@ 'menu.profile' => 'Profili', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => 'Zaman', // TODO: translate the following. // 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 4265532fd..3255dc211 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -49,6 +49,7 @@ 'menu.profile' => '简介', // TODO: translate the following. // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', 'menu.time' => '时间记录', 'menu.expenses' => '费用', 'menu.reports' => '报告', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 09712f483..45ca0eeb3 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -49,6 +49,7 @@ // 'menu.create_group' => 'Create Group', // 'menu.profile' => 'Profile', // 'menu.group' => 'Group', +// 'menu.plugins' => 'Plugins', // 'menu.time' => 'Time', // 'menu.expenses' => 'Expenses', 'menu.reports' => '報告', From f12ceba49cb845be385e6b7c7786fc7e5393e802 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Sep 2018 18:09:03 +0000 Subject: [PATCH 0223/1848] More work in progress on separate page for plugins config. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + 30 files changed, 32 insertions(+) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 59330487b..4d647f791 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -319,6 +319,7 @@ 'title.profile' => 'Perfil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 88f3fc08a..a0de85099 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -330,6 +330,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 85e6e3924..079750a58 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -289,6 +289,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Brugerdefineret Felt', 'title.cf_add_custom_field' => 'Tilføj Brugerdefineret Felt', 'title.cf_edit_custom_field' => 'Redigér Brugerdefineret Felt', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 0200660b0..cf5e9757b 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -270,6 +270,8 @@ 'title.options' => 'Optionen', 'title.profile' => 'Profil', 'title.group' => 'Gruppeneinstellungen', +// TODO: translate the followwing. +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Benutzerfelder', 'title.cf_add_custom_field' => 'Benutzerfeld hinzufügen', 'title.cf_edit_custom_field' => 'Benutzerfeld bearbeiten', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 40c21d77a..98fc58982 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -274,6 +274,7 @@ 'title.options' => 'Options', 'title.profile' => 'Profile', 'title.group' => 'Group Settings', +'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Custom Fields', 'title.cf_add_custom_field' => 'Adding Custom Field', 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 661cd3d61..eed4d9e3b 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -318,6 +318,7 @@ 'title.profile' => 'Perfil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 0a82fbe02..f30157f9e 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -325,6 +325,7 @@ 'title.profile' => 'Profiili', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index ec2ff9658..0a2ee38e0 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -299,6 +299,7 @@ 'title.profile' => 'پروفایل', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'فیلدهای سفارشی', 'title.cf_add_custom_field' => 'درج فیلد سفارشی', 'title.cf_edit_custom_field' => 'ویرایش فیلد سفارشی', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 661a0ba89..9f54aa171 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -290,6 +290,7 @@ 'title.profile' => 'Profiili', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Omat kentät', 'title.cf_add_custom_field' => 'Oman kentän lisäys', 'title.cf_edit_custom_field' => 'Oman kentän muokkaus', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 111aa811f..85d52a337 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -283,6 +283,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Champs personalisés', 'title.cf_add_custom_field' => 'Ajout d\\\'un champ', 'title.cf_edit_custom_field' => 'Édition d\\\'un champ', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 342adde0c..73ed6f74e 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -278,6 +278,7 @@ 'title.profile' => 'Προφίλ', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Προσαρμοσμένα πεδία', 'title.cf_add_custom_field' => 'Προσθήκη προσαρμοσμένου πεδίου', 'title.cf_edit_custom_field' => 'Επεξεργασία προσαρμοσμένου πεδίου', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 9e5c0d18a..f1df92975 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -310,6 +310,7 @@ 'title.profile' => 'פרופיל', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'שדות אישיים', 'title.cf_add_custom_field' => 'הוספת שדה אישי', 'title.cf_edit_custom_field' => 'עריכת שדה אישי', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 372dd9437..2a4eab273 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -317,6 +317,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 2392815f6..47157dbc1 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -288,6 +288,7 @@ 'title.profile' => 'Profilo', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Campi personalizzati', 'title.cf_add_custom_field' => 'Aggiunta campo personalizzato', 'title.cf_edit_custom_field' => 'Modifica campo personalizzato', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index e5f933d07..3f8d25cd9 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -323,6 +323,7 @@ 'title.profile' => 'プロファイル', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 36d888718..ff8012b8e 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -324,6 +324,7 @@ 'title.profile' => '프로필', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 9c21e1201..474552604 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -274,6 +274,8 @@ 'title.options' => 'Opties', 'title.profile' => 'Profiel', 'title.group' => 'Groep instelling', +// TODO: translate the following. +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Eigen velden', 'title.cf_add_custom_field' => 'Eigen veld toevoegen', 'title.cf_edit_custom_field' => 'Eigen veld bewerken', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index e135b8d3c..22e6edefb 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -320,6 +320,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 9e8e4c761..f60c8394d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -290,6 +290,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Pola niestandardowe', 'title.cf_add_custom_field' => 'Dodawanie pola niestandardowego', 'title.cf_edit_custom_field' => 'Edytowanie pola niestandardowego', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index f658e4a2e..55e8a7fa0 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -287,6 +287,7 @@ 'title.profile' => 'Perfil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Campos personalizados', 'title.cf_add_custom_field' => 'Adicionando campo personalizado', 'title.cf_edit_custom_field' => 'Editando campo personalizado', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index a6c48693c..8e98496e8 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -306,6 +306,7 @@ 'title.profile' => 'Perfil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index e7fdbd35a..6d41d6626 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -325,6 +325,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index ad71ecc5b..8f4b5b063 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -273,6 +273,7 @@ 'title.options' => 'Опции', 'title.profile' => 'Профиль', 'title.group' => 'Настройки группы', +'title.plugins' => 'Плагины', 'title.cf_custom_fields' => 'Дополнительные поля', 'title.cf_add_custom_field' => 'Добавление поля', 'title.cf_edit_custom_field' => 'Редактирование поля', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index ed66a67bb..d8f2cdd1a 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -300,6 +300,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Vlastné polia', 'title.cf_add_custom_field' => 'Pridávanie vlastného poľa', 'title.cf_edit_custom_field' => 'Upravovanie vlastného poľa', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 5812629dd..1e2e11c1a 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -300,6 +300,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 8702df928..1c7c1929e 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -288,6 +288,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Dodatna polja', 'title.cf_add_custom_field' => 'Dodavanje dodatnih polja', 'title.cf_edit_custom_field' => 'Izmena dodatnih polja', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index f6b2b1bdb..c362381e4 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -288,6 +288,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Egna fält', 'title.cf_add_custom_field' => 'Lägg till fält', 'title.cf_edit_custom_field' => 'Redigera fält', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index a2707fd92..9ba985f67 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -334,6 +334,7 @@ 'title.profile' => 'Profili', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 3255dc211..2ed62dd76 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -312,6 +312,7 @@ 'title.profile' => '简介', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 45ca0eeb3..a7ce7c58e 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -319,6 +319,7 @@ // TODO: translate the following. // 'title.profile' => 'Profile', // 'title.group' => 'Group Settings', +// 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', // 'title.cf_edit_custom_field' => 'Editing Custom Field', From ea7a43edbe96f9741b734dc4ee5efc16b6c48244 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Sep 2018 18:29:00 +0000 Subject: [PATCH 0224/1848] Some recycling in translation files. --- WEB-INF/resources/ca.lang.php | 1 - WEB-INF/resources/cs.lang.php | 1 - WEB-INF/resources/da.lang.php | 5 ++--- WEB-INF/resources/de.lang.php | 7 ++----- WEB-INF/resources/en.lang.php | 1 - WEB-INF/resources/es.lang.php | 1 - WEB-INF/resources/et.lang.php | 1 - WEB-INF/resources/fa.lang.php | 5 ++--- WEB-INF/resources/fi.lang.php | 5 ++--- WEB-INF/resources/fr.lang.php | 5 ++--- WEB-INF/resources/gr.lang.php | 6 ++---- WEB-INF/resources/he.lang.php | 5 ++--- WEB-INF/resources/hu.lang.php | 1 - WEB-INF/resources/it.lang.php | 6 ++---- WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 7 ++----- WEB-INF/resources/no.lang.php | 1 - WEB-INF/resources/pl.lang.php | 5 ++--- WEB-INF/resources/pt-br.lang.php | 5 ++--- WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 1 - WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 5 ++--- WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 5 ++--- WEB-INF/resources/sv.lang.php | 6 ++---- WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 1 - WEB-INF/resources/zh-tw.lang.php | 1 - WEB-INF/templates/group_edit.tpl | 2 +- plugins.php | 2 +- 32 files changed, 30 insertions(+), 67 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 4d647f791..f778db81e 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -519,7 +519,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index a0de85099..99531a5ee 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -533,7 +533,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 079750a58..7cff4bdde 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -49,7 +49,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Plugins', 'menu.time' => 'Tid', 'menu.expenses' => 'Udgifter', 'menu.reports' => 'Rapporter', @@ -289,7 +289,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Brugerdefineret Felt', 'title.cf_add_custom_field' => 'Tilføj Brugerdefineret Felt', 'title.cf_edit_custom_field' => 'Redigér Brugerdefineret Felt', @@ -479,7 +479,6 @@ 'form.group_edit.uncompleted_indicators' => 'Uafsluttede indikatore', // TODO: translate the following. // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index cf5e9757b..51520a2af 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -47,8 +47,7 @@ 'menu.create_group' => 'Erstelle Gruppe', 'menu.profile' => 'Profil', 'menu.group' => 'Gruppe', -// TODO: translate the following. -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Erweiterungen', 'menu.time' => 'Zeiten', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Berichte', @@ -270,8 +269,7 @@ 'title.options' => 'Optionen', 'title.profile' => 'Profil', 'title.group' => 'Gruppeneinstellungen', -// TODO: translate the followwing. -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Erweiterungen', 'title.cf_custom_fields' => 'Benutzerfelder', 'title.cf_add_custom_field' => 'Benutzerfeld hinzufügen', 'title.cf_edit_custom_field' => 'Benutzerfeld bearbeiten', @@ -449,7 +447,6 @@ 'form.group_edit.future_entries' => 'Einträge in der Zukunft', 'form.group_edit.uncompleted_indicators' => 'Zeige unfertige Einträge', 'form.group_edit.allow_ip' => 'Erlaube IP', -'form.group_edit.plugins' => 'Erweiterungen', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Sind Sie sicher, dass Sie die gesamte Gruppe löschen möchten?', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 98fc58982..1fe0874ef 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -454,7 +454,6 @@ 'form.group_edit.future_entries' => 'Future entries', 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index eed4d9e3b..58355a85c 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -533,7 +533,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index f30157f9e..a9f535f99 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -529,7 +529,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 0a2ee38e0..bf82096f3 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -50,7 +50,7 @@ 'menu.profile' => 'پروفايل', // TODO: translate the following. // 'menu.group' => 'Group', -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'پلاگین ها', 'menu.time' => 'زمان', 'menu.expenses' => 'هزينه ها', 'menu.reports' => 'گزارشات', @@ -299,7 +299,7 @@ 'title.profile' => 'پروفایل', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'پلاگین ها', 'title.cf_custom_fields' => 'فیلدهای سفارشی', 'title.cf_add_custom_field' => 'درج فیلد سفارشی', 'title.cf_edit_custom_field' => 'ویرایش فیلد سفارشی', @@ -503,7 +503,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'پلاگین ها', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 9f54aa171..65234876f 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -49,7 +49,7 @@ 'menu.profile' => 'Profiili', // TODO: translate the following. // 'menu.group' => 'Group', -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Lisäosat', 'menu.time' => 'Tunnit', 'menu.expenses' => 'Kulut', 'menu.reports' => 'Raportit', @@ -290,7 +290,7 @@ 'title.profile' => 'Profiili', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Lisäosat', 'title.cf_custom_fields' => 'Omat kentät', 'title.cf_add_custom_field' => 'Oman kentän lisäys', 'title.cf_edit_custom_field' => 'Oman kentän muokkaus', @@ -486,7 +486,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Lisäosat', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 85d52a337..1ae8176d3 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -49,7 +49,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Plugins', 'menu.time' => 'Temps', 'menu.expenses' => 'Dépenses', 'menu.reports' => 'Rapports', @@ -283,7 +283,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Champs personalisés', 'title.cf_add_custom_field' => 'Ajout d\\\'un champ', 'title.cf_edit_custom_field' => 'Édition d\\\'un champ', @@ -475,7 +475,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 73ed6f74e..c5aea9e85 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -47,8 +47,7 @@ 'menu.create_group' => 'Δημιουργία ομάδας', 'menu.profile' => 'Προφίλ', 'menu.group' => 'Ομάδα', -// TODO: translate the following. -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Πρόσθετα', 'menu.time' => 'Χρόνος', 'menu.expenses' => 'Έξοδα', 'menu.reports' => 'Αναφορές', @@ -278,7 +277,7 @@ 'title.profile' => 'Προφίλ', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Πρόσθετα', 'title.cf_custom_fields' => 'Προσαρμοσμένα πεδία', 'title.cf_add_custom_field' => 'Προσθήκη προσαρμοσμένου πεδίου', 'title.cf_edit_custom_field' => 'Επεξεργασία προσαρμοσμένου πεδίου', @@ -459,7 +458,6 @@ 'form.group_edit.uncompleted_indicators' => 'Μη ολοκληρωμένες ενδείξεις', // TODO: translate the following. // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Πρόσθετα', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index f1df92975..355e2ee79 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -50,7 +50,7 @@ 'menu.profile' => 'פרופיל', // TODO: translate the following. // 'menu.group' => 'Group', -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'תוספים', 'menu.time' => 'זמן', // TODO: translate the following. // 'menu.expenses' => 'Expenses', @@ -310,7 +310,7 @@ 'title.profile' => 'פרופיל', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'תוספים', 'title.cf_custom_fields' => 'שדות אישיים', 'title.cf_add_custom_field' => 'הוספת שדה אישי', 'title.cf_edit_custom_field' => 'עריכת שדה אישי', @@ -512,7 +512,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'תוספים', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 2a4eab273..9f64eb2fb 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -523,7 +523,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 47157dbc1..d20853596 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -49,8 +49,7 @@ 'menu.create_group' => 'Crea gruppo', 'menu.profile' => 'Profilo', 'menu.group' => 'Gruppo', -// TODO: translate the following. -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Plugin', 'menu.time' => 'Tempo', 'menu.expenses' => 'Spese', 'menu.reports' => 'Rapporti', @@ -288,7 +287,7 @@ 'title.profile' => 'Profilo', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Plugin', 'title.cf_custom_fields' => 'Campi personalizzati', 'title.cf_add_custom_field' => 'Aggiunta campo personalizzato', 'title.cf_edit_custom_field' => 'Modifica campo personalizzato', @@ -475,7 +474,6 @@ 'form.group_edit.uncompleted_indicators' => 'Indicatori incompleti', // TODO: translate the following. // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Plugin', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 3f8d25cd9..cb15bea93 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -525,7 +525,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index ff8012b8e..5cd609360 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -523,7 +523,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 474552604..6eb372fe1 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -47,8 +47,7 @@ 'menu.create_group' => 'Maak groep', 'menu.profile' => 'Profiel', 'menu.group' => 'Groep', -// TODO: translate the following. -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Plugins', 'menu.time' => 'Tijden', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Rapporten', @@ -274,8 +273,7 @@ 'title.options' => 'Opties', 'title.profile' => 'Profiel', 'title.group' => 'Groep instelling', -// TODO: translate the following. -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Eigen velden', 'title.cf_add_custom_field' => 'Eigen veld toevoegen', 'title.cf_edit_custom_field' => 'Eigen veld bewerken', @@ -453,7 +451,6 @@ 'form.group_edit.future_entries' => 'Toevoegingen toestaan in de toekomst', 'form.group_edit.uncompleted_indicators' => 'Onvolledige indicatoren', 'form.group_edit.allow_ip' => 'Toegestane IP adressen', -'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Bent u er zeker van dat u de hele groep wilt verwijderen?', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 22e6edefb..241d112a6 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -522,7 +522,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index f60c8394d..606adf937 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -49,7 +49,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Moduły', 'menu.time' => 'Czas', 'menu.expenses' => 'Wydatki', 'menu.reports' => 'Raporty', @@ -290,7 +290,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Dodatkowe moduły', 'title.cf_custom_fields' => 'Pola niestandardowe', 'title.cf_add_custom_field' => 'Dodawanie pola niestandardowego', 'title.cf_edit_custom_field' => 'Edytowanie pola niestandardowego', @@ -488,7 +488,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Dodatkowe moduły', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 55e8a7fa0..41d406cf2 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -49,7 +49,7 @@ 'menu.profile' => 'Perfil', // TODO: translate the following. // 'menu.group' => 'Group', -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Plugins', 'menu.time' => 'Tempo', 'menu.expenses' => 'Gastos', 'menu.reports' => 'Relatórios', @@ -287,7 +287,7 @@ 'title.profile' => 'Perfil', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Campos personalizados', 'title.cf_add_custom_field' => 'Adicionando campo personalizado', 'title.cf_edit_custom_field' => 'Editando campo personalizado', @@ -483,7 +483,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 8e98496e8..8e55e7a92 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -506,7 +506,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 6d41d6626..ce0e22eb0 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -528,7 +528,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 8f4b5b063..4b49fabf0 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -451,7 +451,6 @@ 'form.group_edit.future_entries' => 'Будущие записи', 'form.group_edit.uncompleted_indicators' => 'Индикаторы незавершения', 'form.group_edit.allow_ip' => 'Разрешить доступ с IP', -'form.group_edit.plugins' => 'Плагины', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Вы уверены, что хотите удалить всю группу?', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d8f2cdd1a..339083457 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -49,7 +49,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Moduly', 'menu.time' => 'Časový záznam', // TODO: translate the following. // 'menu.expenses' => 'Expenses', @@ -300,7 +300,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Doplnkové moduly', 'title.cf_custom_fields' => 'Vlastné polia', 'title.cf_add_custom_field' => 'Pridávanie vlastného poľa', 'title.cf_edit_custom_field' => 'Upravovanie vlastného poľa', @@ -503,7 +503,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Doplnkové moduly', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 1e2e11c1a..14a1b1ad8 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -502,7 +502,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 1c7c1929e..7a4306518 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -49,7 +49,7 @@ 'menu.profile' => 'Profil', // TODO: translate the following. // 'menu.group' => 'Group', -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Dodaci', 'menu.time' => 'Vreme', 'menu.expenses' => 'Troškovi', 'menu.reports' => 'Izveštaji', @@ -288,7 +288,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Dodaci', 'title.cf_custom_fields' => 'Dodatna polja', 'title.cf_add_custom_field' => 'Dodavanje dodatnih polja', 'title.cf_edit_custom_field' => 'Izmena dodatnih polja', @@ -486,7 +486,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Dodaci', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index c362381e4..dccb0f484 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -47,8 +47,7 @@ 'menu.create_group' => 'Skapa grupp', 'menu.profile' => 'Profil', 'menu.group' => 'Grupp', -// TODO: translate the following. -// 'menu.plugins' => 'Plugins', +'menu.plugins' => 'Tillägg', 'menu.time' => 'Tider', 'menu.expenses' => 'Kostnader', 'menu.reports' => 'Rapporter', @@ -288,7 +287,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', -// 'title.plugins' => 'Plugins', +'title.plugins' => 'Tillägg', 'title.cf_custom_fields' => 'Egna fält', 'title.cf_add_custom_field' => 'Lägg till fält', 'title.cf_edit_custom_field' => 'Redigera fält', @@ -483,7 +482,6 @@ 'form.group_edit.uncompleted_indicators' => 'Indikatorer för oavslutad registrering', // TODO: translate the following. // 'form.group_edit.allow_ip' => 'Allow IP', -'form.group_edit.plugins' => 'Tillägg', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 9ba985f67..a0f43fc75 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -541,7 +541,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 2ed62dd76..13d570e08 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -509,7 +509,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index a7ce7c58e..6750d90a6 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -517,7 +517,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.plugins' => 'Plugins', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index d2a9476ad..3e34054e1 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -204,7 +204,7 @@ function handlePluginCheckboxes() {
{$i18n.form.group_edit.plugins}{$i18n.title.plugins}
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {/if} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index aa59d3fff..c7c445a79 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -88,6 +88,9 @@ {/if} {if $user->can('manage_basic_settings')} {$i18n.menu.group} · + {/if} + {if $user->can('manage_features')} + {$i18n.menu.plugins} · {/if} {$i18n.menu.forum} · {$i18n.menu.help} diff --git a/group_edit.php b/group_edit.php index 01d2ecdc4..9c4cf3692 100644 --- a/group_edit.php +++ b/group_edit.php @@ -64,21 +64,6 @@ $cl_uncompleted_indicators = $request->getParameter('uncompleted_indicators'); $cl_bcc_email = trim($request->getParameter('bcc_email')); $cl_allow_ip = trim($request->getParameter('allow_ip')); - - // Plugin checkboxes. - $cl_charts = $request->getParameter('charts'); - $cl_clients = $request->getParameter('clients'); - $cl_client_required = $request->getParameter('client_required'); - $cl_invoices = $request->getParameter('invoices'); - $cl_paid_status = $request->getParameter('paid_status'); - $cl_custom_fields = $request->getParameter('custom_fields'); - $cl_expenses = $request->getParameter('expenses'); - $cl_tax_expenses = $request->getParameter('tax_expenses'); - $cl_notifications = $request->getParameter('notifications'); - $cl_locking = $request->getParameter('locking'); - $cl_quotas = $request->getParameter('quotas'); - $cl_week_view = $request->getParameter('week_view'); - $cl_work_units = $request->getParameter('work_units'); } else { $cl_group = $user->group; $cl_currency = ($user->currency == ''? CURRENCY_DEFAULT : $user->currency); @@ -98,22 +83,6 @@ $cl_uncompleted_indicators = $user->uncompleted_indicators; $cl_bcc_email = $user->bcc_email; $cl_allow_ip = $user->allow_ip; - - // Which plugins do we have enabled? - $plugins = explode(',', $user->plugins); - $cl_charts = in_array('ch', $plugins); - $cl_clients = in_array('cl', $plugins); - $cl_client_required = in_array('cm', $plugins); - $cl_invoices = in_array('iv', $plugins); - $cl_paid_status = in_array('ps', $plugins); - $cl_custom_fields = in_array('cf', $plugins); - $cl_expenses = in_array('ex', $plugins); - $cl_tax_expenses = in_array('et', $plugins); - $cl_notifications = in_array('no', $plugins); - $cl_locking = in_array('lk', $plugins); - $cl_quotas = in_array('mq', $plugins); - $cl_week_view = in_array('wv', $plugins); - $cl_work_units = in_array('wu', $plugins); } $form = new Form('groupForm'); @@ -199,21 +168,6 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'allow_ip','value'=>$cl_allow_ip)); } -// Plugin checkboxes. -$form->addInput(array('type'=>'checkbox','name'=>'charts','value'=>$cl_charts)); -$form->addInput(array('type'=>'checkbox','name'=>'clients','value'=>$cl_clients,'onchange'=>'handlePluginCheckboxes()')); -$form->addInput(array('type'=>'checkbox','name'=>'client_required','value'=>$cl_client_required)); -$form->addInput(array('type'=>'checkbox','name'=>'invoices','value'=>$cl_invoices)); -$form->addInput(array('type'=>'checkbox','name'=>'paid_status','value'=>$cl_paid_status)); -$form->addInput(array('type'=>'checkbox','name'=>'custom_fields','value'=>$cl_custom_fields,'onchange'=>'handlePluginCheckboxes()')); -$form->addInput(array('type'=>'checkbox','name'=>'expenses','value'=>$cl_expenses,'onchange'=>'handlePluginCheckboxes()')); -$form->addInput(array('type'=>'checkbox','name'=>'tax_expenses','value'=>$cl_tax_expenses)); -$form->addInput(array('type'=>'checkbox','name'=>'notifications','value'=>$cl_notifications,'onchange'=>'handlePluginCheckboxes()')); -$form->addInput(array('type'=>'checkbox','name'=>'locking','value'=>$cl_locking,'onchange'=>'handlePluginCheckboxes()')); -$form->addInput(array('type'=>'checkbox','name'=>'quotas','value'=>$cl_quotas,'onchange'=>'handlePluginCheckboxes()')); -$form->addInput(array('type'=>'checkbox','name'=>'week_view','value'=>$cl_week_view,'onchange'=>'handlePluginCheckboxes()')); -$form->addInput(array('type'=>'checkbox','name'=>'work_units','value'=>$cl_work_units,'onchange'=>'handlePluginCheckboxes()')); - $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($user->can('delete_group')) $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('button.delete'))); @@ -235,45 +189,6 @@ // Finished validating user input. if ($err->no()) { - // Prepare plugins string. - if ($cl_charts) - $plugins .= ',ch'; - if ($cl_clients) - $plugins .= ',cl'; - if ($cl_client_required) - $plugins .= ',cm'; - if ($cl_invoices) - $plugins .= ',iv'; - if ($cl_paid_status) - $plugins .= ',ps'; - if ($cl_custom_fields) - $plugins .= ',cf'; - if ($cl_expenses) - $plugins .= ',ex'; - if ($cl_tax_expenses) - $plugins .= ',et'; - if ($cl_notifications) - $plugins .= ',no'; - if ($cl_locking) - $plugins .= ',lk'; - if ($cl_quotas) - $plugins .= ',mq'; - if ($cl_week_view) - $plugins .= ',wv'; - if ($cl_work_units) - $plugins .= ',wu'; - - // Recycle week view plugin options as they are not configured on this page. - $existing_plugins = explode(',', $user->plugins); - if (in_array('wvn', $existing_plugins)) - $plugins .= ',wvn'; - if (in_array('wvl', $existing_plugins)) - $plugins .= ',wvl'; - if (in_array('wvns', $existing_plugins)) - $plugins .= ',wvns'; - - $plugins = trim($plugins, ','); - // Update config. $config->setDefinedValue('show_holidays', $cl_show_holidays); $config->setDefinedValue('punch_mode', $cl_punch_mode); @@ -296,7 +211,6 @@ 'uncompleted_indicators' => $cl_uncompleted_indicators, 'bcc_email' => $cl_bcc_email, 'allow_ip' => $cl_allow_ip, - 'plugins' => $plugins, 'config' => $config->getConfig()))) { header('Location: time.php'); exit(); From 93472f16bca36138fb4f227b262fe0a96a246776 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 25 Oct 2018 17:00:09 +0000 Subject: [PATCH 0226/1848] Extended conditions to include >=, <, <=, and = situations. --- WEB-INF/lib/common.lib.php | 9 ++++++++- WEB-INF/lib/ttReportHelper.class.php | 27 +++++++++++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 325ae73b4..d1ad384f5 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -319,7 +319,7 @@ function ttValidCondition($val, $emptyValid = true) if (stristr($val, ' @@ -304,7 +307,7 @@ function handleCheckboxes() { - +
 Anuko Time Tracker 1.17.98.4321 | Copyright © Anuko | +  Anuko Time Tracker 1.17.99.4322 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index 3e34054e1..ef00ca4db 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -14,92 +14,6 @@ function handleTaskRequiredCheckbox() { taskRequiredLabel.style.visibility = "hidden"; } } - - -// handlePluginCheckboxes - controls visibility of controls. -function handlePluginCheckboxes() { - var clientsCheckbox = document.getElementById("clients"); - var invoicesCheckbox = document.getElementById("invoices"); - var requiredCheckbox = document.getElementById("client_required"); - var requiredLabel = document.getElementById("client_required_label"); - if (clientsCheckbox.checked) { - requiredCheckbox.style.visibility = "visible"; - requiredLabel.style.visibility = "visible"; - invoicesCheckbox.disabled = false; - } else { - requiredCheckbox.checked = false; - requiredCheckbox.style.visibility = "hidden"; - requiredLabel.style.visibility = "hidden"; - invoicesCheckbox.checked = false; - invoicesCheckbox.disabled = true; - } - - var expensesCheckbox = document.getElementById("expenses"); - var taxCheckbox = document.getElementById("tax_expenses"); - var taxLabel = document.getElementById("tax_label"); - if (expensesCheckbox.checked) { - taxCheckbox.style.visibility = "visible"; - taxLabel.style.visibility = "visible"; - } else { - taxCheckbox.checked = false; - taxCheckbox.style.visibility = "hidden"; - taxLabel.style.visibility = "hidden"; - } - var configureLabel = document.getElementById("expenses_config"); - if (expensesCheckbox.checked) { - configureLabel.style.visibility = "visible"; - } else { - configureLabel.style.visibility = "hidden"; - } - - var customFieldsCheckbox = document.getElementById("custom_fields"); - configureLabel = document.getElementById("cf_config"); - if (customFieldsCheckbox.checked) { - configureLabel.style.visibility = "visible"; - } else { - configureLabel.style.visibility = "hidden"; - } - - var notificationsCheckbox = document.getElementById("notifications"); - configureLabel = document.getElementById("notifications_config"); - if (notificationsCheckbox.checked) { - configureLabel.style.visibility = "visible"; - } else { - configureLabel.style.visibility = "hidden"; - } - - var lockingCheckbox = document.getElementById("locking"); - configureLabel = document.getElementById("locking_config"); - if (lockingCheckbox.checked) { - configureLabel.style.visibility = "visible"; - } else { - configureLabel.style.visibility = "hidden"; - } - - var quotasCheckbox = document.getElementById("quotas"); - configureLabel = document.getElementById("quotas_config"); - if (quotasCheckbox.checked){ - configureLabel.style.visibility = "visible"; - } else { - configureLabel.style.visibility = "hidden"; - } - - var weekViewCheckbox = document.getElementById("week_view"); - configureLabel = document.getElementById("week_view_config"); - if (weekViewCheckbox.checked){ - configureLabel.style.visibility = "visible"; - } else { - configureLabel.style.visibility = "hidden"; - } - - var workUnitsCheckbox = document.getElementById("work_units"); - configureLabel = document.getElementById("work_units_config"); - if (workUnitsCheckbox.checked){ - configureLabel.style.visibility = "visible"; - } else { - configureLabel.style.visibility = "hidden"; - } -} {$forms.groupForm.open} @@ -197,60 +111,6 @@ function handlePluginCheckboxes() { } adjustDecimalPreview(); - -
  
{$i18n.title.plugins}
 
{$forms.groupForm.charts.control}
{$forms.groupForm.clients.control} {$forms.groupForm.client_required.control}
{$forms.groupForm.invoices.control}
{$forms.groupForm.paid_status.control}
{$forms.groupForm.custom_fields.control} {$i18n.label.configure}
{$forms.groupForm.expenses.control} {$forms.groupForm.tax_expenses.control} {$i18n.label.configure}
{$forms.groupForm.notifications.control} {$i18n.label.configure}
{$forms.groupForm.locking.control} {$i18n.label.configure}
{$forms.groupForm.quotas.control} {$i18n.label.configure}
{$forms.groupForm.week_view.control} {$i18n.label.configure}
{$forms.groupForm.work_units.control} {$i18n.label.configure}
{$forms.reportForm.group_by3.control}
diff --git a/reports.php b/reports.php index ae5c9371b..dae0c180b 100644 --- a/reports.php +++ b/reports.php @@ -235,8 +235,8 @@ $group_by_options_size = sizeof($group_by_options); $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by','data'=>$group_by_options)); if (defined('MULTIPLE_GROUP_BY_DEBUG') && isTrue(MULTIPLE_GROUP_BY_DEBUG)) { - if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by2','data'=>$group_by_options)); - if ($group_by_options_size > 3) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by3','data'=>$group_by_options)); + if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','name'=>'group_by2','data'=>$group_by_options)); + if ($group_by_options_size > 3) $form->addInput(array('type'=>'combobox','name'=>'group_by3','data'=>$group_by_options)); } $form->addInput(array('type'=>'checkbox','name'=>'chtotalsonly')); From 85329fe7459e5892082de3bd40459e7dfdb36f11 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 28 Oct 2018 17:56:59 +0000 Subject: [PATCH 0233/1848] Added 2 additional group by fields in database as part of ongoing work on multiple level grouping. --- WEB-INF/lib/ttFavReportHelper.class.php | 6 +++--- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 16 ++++++++++++++-- mysql.sql | 6 ++++-- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 069ecbb5f..adc6e2ebb 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -84,7 +84,7 @@ static function insertReport($fields) { show_client, show_invoice, show_paid, show_ip, show_project, show_start, show_duration, show_cost, show_task, show_end, show_note, show_custom_field_1, show_work_units, - group_by, show_totals_only) + group_by1, show_totals_only) values(". $mdb2->quote($fields['name']).", ".$fields['user_id'].", ". $mdb2->quote($fields['client']).", ".$mdb2->quote($fields['option']).", ". @@ -139,7 +139,7 @@ function updateReport($fields) { "show_note = ".$fields['chnote'].", ". "show_custom_field_1 = ".$fields['chcf_1'].", ". "show_work_units = ".$fields['chunits'].", ". - "group_by = ".$mdb2->quote($fields['group_by']).", ". + "group_by1 = ".$mdb2->quote($fields['group_by']).", ". "show_totals_only = ".$fields['chtotalsonly']. " where id = ".$fields['id']; $affected = $mdb2->exec($sql); @@ -270,7 +270,7 @@ static function loadReport($user_id, &$bean) { $bean->setAttribute('chnote', $val['show_note']); $bean->setAttribute('chcf_1', $val['show_custom_field_1']); $bean->setAttribute('chunits', $val['show_work_units']); - $bean->setAttribute('group_by', $val['group_by']); + $bean->setAttribute('group_by', $val['group_by1']); $bean->setAttribute('chtotalsonly', $val['show_totals_only']); $bean->setAttribute('new_fav_report', $val['name']); } else { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7167ac7f4..52a5e8081 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + + + + + +
 Anuko Time Tracker 1.17.100.4324 | Copyright © Anuko | +  Anuko Time Tracker 1.18.00.4325 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 5144d1962..097d2abe5 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -956,6 +956,13 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } + if ($_POST["convert11797to11800"]) { + setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); + setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); + setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.00', modified = now() where param_name = 'version_db' and param_value = '1.17.97'"); + } + if ($_POST["cleanup"]) { $mdb2 = getConnection(); @@ -999,7 +1006,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.17.97) + Create database structure (v1.18.00)
(applies only to new installations, do not execute when updating)
@@ -1040,7 +1047,12 @@ function setChange($sql) {
Update database structure (v1.17.44 to v1.17.97)

Update database structure (v1.17.97 to v1.18.00)
diff --git a/mysql.sql b/mysql.sql index 62c1d7c48..07a2323a1 100644 --- a/mysql.sql +++ b/mysql.sql @@ -269,7 +269,9 @@ CREATE TABLE `tt_fav_reports` ( `show_custom_field_1` tinyint(4) NOT NULL default 0, # whether to show custom field 1 `show_work_units` tinyint(4) NOT NULL default 0, # whether to show work units `show_totals_only` tinyint(4) NOT NULL default 0, # whether to show totals only - `group_by` varchar(20) default NULL, # group by field + `group_by1` varchar(20) default NULL, # group by field 1 + `group_by2` varchar(20) default NULL, # group by field 2 + `group_by3` varchar(20) default NULL, # group by field 3 `status` tinyint(4) default 1, # favorite report status PRIMARY KEY (`id`) ); @@ -454,4 +456,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.97', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.00', now()); # TODO: change when structure changes. From 47b6c704a5375b9f98376bf4eb727d4ee49fe3e2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 28 Oct 2018 18:43:40 +0000 Subject: [PATCH 0234/1848] Some fixes associated with renaming the group_by field. --- WEB-INF/lib/ttFavReportHelper.class.php | 10 +++++----- WEB-INF/lib/ttReportHelper.class.php | 8 ++++---- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 4 ++-- report.php | 10 +++++----- reports.php | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index adc6e2ebb..96188f22b 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -96,7 +96,7 @@ static function insertReport($fields) { $fields['chclient'].", ".$fields['chinvoice'].", ".$fields['chpaid'].", ".$fields['chip'].", ". $fields['chproject'].", ".$fields['chstart'].", ".$fields['chduration'].", ".$fields['chcost'].", ". $fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ".$fields['chcf_1'].", ".$fields['chunits'].", ". - $mdb2->quote($fields['group_by']).", ".$fields['chtotalsonly'].")"; + $mdb2->quote($fields['group_by1']).", ".$fields['chtotalsonly'].")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -139,7 +139,7 @@ function updateReport($fields) { "show_note = ".$fields['chnote'].", ". "show_custom_field_1 = ".$fields['chcf_1'].", ". "show_work_units = ".$fields['chunits'].", ". - "group_by1 = ".$mdb2->quote($fields['group_by']).", ". + "group_by1 = ".$mdb2->quote($fields['group_by1']).", ". "show_totals_only = ".$fields['chtotalsonly']. " where id = ".$fields['id']; $affected = $mdb2->exec($sql); @@ -209,7 +209,7 @@ static function saveReport($user_id, $bean) { 'chnote'=>$bean->getAttribute('chnote'), 'chcf_1'=>$bean->getAttribute('chcf_1'), 'chunits'=>$bean->getAttribute('chunits'), - 'group_by'=>$bean->getAttribute('group_by'), + 'group_by1'=>$bean->getAttribute('group_by1'), 'chtotalsonly'=>$bean->getAttribute('chtotalsonly')); $id = false; @@ -270,7 +270,7 @@ static function loadReport($user_id, &$bean) { $bean->setAttribute('chnote', $val['show_note']); $bean->setAttribute('chcf_1', $val['show_custom_field_1']); $bean->setAttribute('chunits', $val['show_work_units']); - $bean->setAttribute('group_by', $val['group_by1']); + $bean->setAttribute('group_by1', $val['group_by1']); $bean->setAttribute('chtotalsonly', $val['show_totals_only']); $bean->setAttribute('new_fav_report', $val['name']); } else { @@ -295,7 +295,7 @@ static function loadReport($user_id, &$bean) { 'chnote'=>'1', 'chcf_1'=>'', 'chunits'=>'', - 'group_by'=>'', + 'group_by1'=>'', 'chtotalsonly'=>'', 'new_fav_report'=>'')); $bean->setAttributes($attrs); diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index e2bb8ddba..538830c3c 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -127,7 +127,7 @@ static function getItems($options) { $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); - $group_by_option = $options['group_by']; + $group_by_option = $options['group_by1']; $convertTo12Hour = ('%I:%M %p' == $user->time_format) && ($options['show_start'] || $options['show_end']); // Prepare a query for time items in tt_log table. @@ -394,7 +394,7 @@ static function getFromSession() { static function getSubtotals($options) { global $user; - $group_by_option = $options['group_by']; + $group_by_option = $options['group_by1']; if ('no_grouping' == $group_by_option) return null; $mdb2 = getConnection(); @@ -667,7 +667,7 @@ static function prepareReportBody($options, $comment = null) $isClient = $user->isClient(); $items = ttReportHelper::getItems($options); - $group_by = $options['group_by']; + $group_by = $options['group_by1']; if ($group_by && 'no_grouping' != $group_by) $subtotals = ttReportHelper::getSubtotals($options); $totals = ttReportHelper::getTotals($options); @@ -1062,7 +1062,7 @@ static function getReportOptions($bean) { $options['show_custom_field_1'] = $bean->getAttribute('chcf_1'); $options['show_work_units'] = $bean->getAttribute('chunits'); $options['show_totals_only'] = $bean->getAttribute('chtotalsonly'); - $options['group_by'] = $bean->getAttribute('group_by'); + $options['group_by1'] = $bean->getAttribute('group_by1'); return $options; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 52a5e8081..a54d6aa67 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + diff --git a/report.php b/report.php index cd093e40b..efbaccea8 100644 --- a/report.php +++ b/report.php @@ -69,7 +69,7 @@ // Do we need to show checkboxes? if ($bean->getAttribute('chpaid') || - ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by')) && !$user->isClient())) { + ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by1')) && !$user->isClient())) { if ($user->can('manage_invoices')) $smarty->assign('use_checkboxes', true); } @@ -92,7 +92,7 @@ // Controls for "Assign to invoice" block. if ($user->can('manage_invoices') && - ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by')) && !$user->isClient())) { + ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by1')) && !$user->isClient())) { // Client is selected and we are displaying the invoice column. $recent_invoices = ttTeamHelper::getRecentInvoices($user->group_id, $client_id); if ($recent_invoices) { @@ -170,7 +170,7 @@ } } // isPost -$group_by = $bean->getAttribute('group_by'); +$group_by = $bean->getAttribute('group_by1'); $options = ttReportHelper::getReportOptions($bean); $report_items = ttReportHelper::getItems($options); @@ -183,10 +183,10 @@ $totals = ttReportHelper::getTotals($options); // Assign variables that are used to print subtotals. -if ($report_items && 'no_grouping' != $group_by) { +if ($report_items && 'no_grouping' != $group_by1) { $smarty->assign('print_subtotals', true); $smarty->assign('first_pass', true); - $smarty->assign('group_by', $group_by); + $smarty->assign('group_by1', $group_by1); $smarty->assign('prev_grouped_by', ''); $smarty->assign('cur_grouped_by', ''); } diff --git a/reports.php b/reports.php index dae0c180b..39f09c0b4 100644 --- a/reports.php +++ b/reports.php @@ -233,7 +233,7 @@ $group_by_options['cf_1'] = $custom_fields->fields[0]['label']; } $group_by_options_size = sizeof($group_by_options); -$form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by','data'=>$group_by_options)); +$form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by1','data'=>$group_by_options)); if (defined('MULTIPLE_GROUP_BY_DEBUG') && isTrue(MULTIPLE_GROUP_BY_DEBUG)) { if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','name'=>'group_by2','data'=>$group_by_options)); if ($group_by_options_size > 3) $form->addInput(array('type'=>'combobox','name'=>'group_by3','data'=>$group_by_options)); From 9e3d2ed2e3128245418e5cf5aff39f8695958d9a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 28 Oct 2018 20:35:40 +0000 Subject: [PATCH 0235/1848] Fixed export-import for renamed field. --- WEB-INF/lib/ttExportHelper.class.php | 2 +- WEB-INF/lib/ttImportHelper.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttExportHelper.class.php b/WEB-INF/lib/ttExportHelper.class.php index d0b533952..0c30b2f76 100644 --- a/WEB-INF/lib/ttExportHelper.class.php +++ b/WEB-INF/lib/ttExportHelper.class.php @@ -304,7 +304,7 @@ function createDataFile($compress = false) { " show_note=\"".$fav_report['show_note']."\"". " show_custom_field_1=\"".$fav_report['show_custom_field_1']."\"". " show_work_units=\"".$fav_report['show_work_units']."\"". - " group_by=\"".$fav_report['group_by']."\"". + " group_by1=\"".$fav_report['group_by1']."\"". " show_totals_only=\"".$fav_report['show_totals_only']."\">\n"); fwrite($file, " \n"); fwrite($file, " \n"); diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 8be7a8310..c59f5e3f0 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -335,7 +335,7 @@ function endElement($parser, $name) { 'chnote' => (int) $this->currentElement['SHOW_NOTE'], 'chcf_1' => (int) $this->currentElement['SHOW_CUSTOM_FIELD_1'], 'chunits' => (int) $this->currentElement['SHOW_WORK_UNITS'], - 'group_by' => $this->currentElement['GROUP_BY'], + 'group_by1' => $this->currentElement['GROUP_BY1'], 'chtotalsonly' => (int) $this->currentElement['SHOW_TOTALS_ONLY'])); } $this->currentTag = ''; From e6463e1944221a524f49668b3b23032c3b9335f3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 28 Oct 2018 20:46:08 +0000 Subject: [PATCH 0236/1848] Fixed report exports to files for a renamed field. --- WEB-INF/templates/footer.tpl | 2 +- tofile.php | 10 +++++----- topdf.php | 32 ++++++++++++++++---------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a54d6aa67..5d3d36a61 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.00.4325 | Copyright © Anuko | +  Anuko Time Tracker 1.18.01.4326 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 9c8221ade..feb5800fe 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -138,7 +138,7 @@ function selectAssignedUsers(project_id) { function handleCheckboxes() { var totalsOnlyCheckbox = document.getElementById("chtotalsonly"); var totalsOnlyLabel = document.getElementById("totals_only_label"); - if ("no_grouping" == document.getElementById("group_by").value) { + if ("no_grouping" == document.getElementById("group_by1").value) { // Unmark and disable the "Totals only" checkbox. totalsOnlyCheckbox.checked = false; totalsOnlyCheckbox.style.visibility = "hidden"; @@ -302,7 +302,7 @@ function handleCheckboxes() { {$i18n.form.reports.group_by}
{$forms.reportForm.group_by.control}{$forms.reportForm.group_by1.control} {$forms.reportForm.group_by2.control} {$forms.reportForm.group_by3.control}
- '; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { $html .= ''; } if ($bean->getAttribute('chclient')) { $html .= ''; } if ($bean->getAttribute('chproject')) { $html .= ''; } if ($bean->getAttribute('chtask')) { $html .= ''; } if ($bean->getAttribute('chcf_1')) { $html .= ''; } if ($bean->getAttribute('chstart')) $html .= ''; @@ -270,27 +270,27 @@ $html .= ''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { $html .= ''; } if ($bean->getAttribute('chclient')) { $html .= ''; } if ($bean->getAttribute('chproject')) { $html .= ''; } if ($bean->getAttribute('chtask')) { $html .= ''; } if ($bean->getAttribute('chcf_1')) { $html .= ''; } if ($bean->getAttribute('chstart')) $html .= ''; From 5f56885676a5004de82919add3d309575514be1b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 28 Oct 2018 21:21:49 +0000 Subject: [PATCH 0237/1848] A bit more work in progress on multiple levels of grouping by in reports. --- WEB-INF/lib/ttExportHelper.class.php | 2 ++ WEB-INF/lib/ttFavReportHelper.class.php | 13 +++++++++++-- WEB-INF/lib/ttImportHelper.class.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttExportHelper.class.php b/WEB-INF/lib/ttExportHelper.class.php index 0c30b2f76..d40ce4528 100644 --- a/WEB-INF/lib/ttExportHelper.class.php +++ b/WEB-INF/lib/ttExportHelper.class.php @@ -305,6 +305,8 @@ function createDataFile($compress = false) { " show_custom_field_1=\"".$fav_report['show_custom_field_1']."\"". " show_work_units=\"".$fav_report['show_work_units']."\"". " group_by1=\"".$fav_report['group_by1']."\"". + " group_by2=\"".$fav_report['group_by2']."\"". + " group_by3=\"".$fav_report['group_by3']."\"". " show_totals_only=\"".$fav_report['show_totals_only']."\">\n"); fwrite($file, " \n"); fwrite($file, " \n"); diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 96188f22b..305a4fc8c 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -84,7 +84,7 @@ static function insertReport($fields) { show_client, show_invoice, show_paid, show_ip, show_project, show_start, show_duration, show_cost, show_task, show_end, show_note, show_custom_field_1, show_work_units, - group_by1, show_totals_only) + group_by1, group_by2, group_by3, show_totals_only) values(". $mdb2->quote($fields['name']).", ".$fields['user_id'].", ". $mdb2->quote($fields['client']).", ".$mdb2->quote($fields['option']).", ". @@ -96,7 +96,8 @@ static function insertReport($fields) { $fields['chclient'].", ".$fields['chinvoice'].", ".$fields['chpaid'].", ".$fields['chip'].", ". $fields['chproject'].", ".$fields['chstart'].", ".$fields['chduration'].", ".$fields['chcost'].", ". $fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ".$fields['chcf_1'].", ".$fields['chunits'].", ". - $mdb2->quote($fields['group_by1']).", ".$fields['chtotalsonly'].")"; + $mdb2->quote($fields['group_by1']).", ".$mdb2->quote($fields['group_by2']).", ". + $mdb2->quote($fields['group_by3']).", ".$fields['chtotalsonly'].")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -140,6 +141,8 @@ function updateReport($fields) { "show_custom_field_1 = ".$fields['chcf_1'].", ". "show_work_units = ".$fields['chunits'].", ". "group_by1 = ".$mdb2->quote($fields['group_by1']).", ". + "group_by2 = ".$mdb2->quote($fields['group_by2']).", ". + "group_by3 = ".$mdb2->quote($fields['group_by3']).", ". "show_totals_only = ".$fields['chtotalsonly']. " where id = ".$fields['id']; $affected = $mdb2->exec($sql); @@ -210,6 +213,8 @@ static function saveReport($user_id, $bean) { 'chcf_1'=>$bean->getAttribute('chcf_1'), 'chunits'=>$bean->getAttribute('chunits'), 'group_by1'=>$bean->getAttribute('group_by1'), + 'group_by2'=>$bean->getAttribute('group_by2'), + 'group_by3'=>$bean->getAttribute('group_by3'), 'chtotalsonly'=>$bean->getAttribute('chtotalsonly')); $id = false; @@ -271,6 +276,8 @@ static function loadReport($user_id, &$bean) { $bean->setAttribute('chcf_1', $val['show_custom_field_1']); $bean->setAttribute('chunits', $val['show_work_units']); $bean->setAttribute('group_by1', $val['group_by1']); + $bean->setAttribute('group_by2', $val['group_by2']); + $bean->setAttribute('group_by3', $val['group_by3']); $bean->setAttribute('chtotalsonly', $val['show_totals_only']); $bean->setAttribute('new_fav_report', $val['name']); } else { @@ -296,6 +303,8 @@ static function loadReport($user_id, &$bean) { 'chcf_1'=>'', 'chunits'=>'', 'group_by1'=>'', + 'group_by2'=>'', + 'group_by3'=>'', 'chtotalsonly'=>'', 'new_fav_report'=>'')); $bean->setAttributes($attrs); diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index c59f5e3f0..d966f8963 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -336,6 +336,8 @@ function endElement($parser, $name) { 'chcf_1' => (int) $this->currentElement['SHOW_CUSTOM_FIELD_1'], 'chunits' => (int) $this->currentElement['SHOW_WORK_UNITS'], 'group_by1' => $this->currentElement['GROUP_BY1'], + 'group_by2' => $this->currentElement['GROUP_BY2'], + 'group_by3' => $this->currentElement['GROUP_BY3'], 'chtotalsonly' => (int) $this->currentElement['SHOW_TOTALS_ONLY'])); } $this->currentTag = ''; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5d3d36a61..818b42753 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.01.4326 | Copyright © Anuko | +  Anuko Time Tracker 1.18.01.4327 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/tofile.php b/tofile.php index a40dbf0ac..42b734338 100644 --- a/tofile.php +++ b/tofile.php @@ -84,12 +84,12 @@ print "\n"; print "\n"; - $group_by = $bean->getAttribute('group_by'); + $group_by1 = $bean->getAttribute('group_by1'); if ($totals_only) { // Totals only report. Print subtotals. foreach ($subtotals as $subtotal) { print "\n"; - print "\t<".$group_by.">\n"; + print "\t<".$group_by1.">\n"; if ($bean->getAttribute('chduration')) { $val = $subtotal['time']; if($val && defined('EXPORT_DECIMAL_DURATION') && isTrue(EXPORT_DECIMAL_DURATION)) @@ -161,15 +161,15 @@ $bom = chr(239).chr(187).chr(191); // 0xEF 0xBB 0xBF in the beginning of the file is UTF8 BOM. print $bom; // Without this Excel does not display UTF8 characters properly. - $group_by = $bean->getAttribute('group_by'); + $group_by1 = $bean->getAttribute('group_by1'); if ($totals_only) { // Totals only report. // Determine group_by header. - if ('cf_1' == $group_by) + if ('cf_1' == $group_by1) $group_by_header = $custom_fields->fields[0]['label']; else { - $key = 'label.'.$group_by; + $key = 'label.'.$group_by1; $group_by_header = $i18n->get($key); } diff --git a/topdf.php b/topdf.php index 69f5816d8..7d3fa0096 100644 --- a/topdf.php +++ b/topdf.php @@ -63,12 +63,12 @@ $totals_only = ($bean->getAttribute('chtotalsonly') == '1'); // Determine group by header. -$group_by = $bean->getAttribute('group_by'); -if ('no_grouping' != $group_by) { - if ('cf_1' == $group_by) +$group_by1 = $bean->getAttribute('group_by1'); +if ('no_grouping' != $group_by1) { + if ('cf_1' == $group_by1) $group_by_header = $custom_fields->fields[0]['label']; else { - $key = 'label.'.$group_by; + $key = 'label.'.$group_by1; $group_by_header = $i18n->get($key); } } @@ -77,12 +77,12 @@ $options = ttReportHelper::getReportOptions($bean); if (!$totals_only) $items = ttReportHelper::getItems($options); // Individual entries. -if ($totals_only || 'no_grouping' != $group_by) +if ($totals_only || 'no_grouping' != $group_by1) $subtotals = ttReportHelper::getSubtotals($options); // Subtotals for groups of items. $totals = ttReportHelper::getTotals($options); // Totals for the entire report. // Assign variables that are used to print subtotals. -if ($items && 'no_grouping' != $group_by) { +if ($items && 'no_grouping' != $group_by1) { $print_subtotals = true; $first_pass = true; $prev_grouped_by = ''; @@ -181,27 +181,27 @@ $html .= ''.$i18n->get('label.subtotal').''; - if ($group_by == 'user') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + if ($group_by1 == 'user') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); $html .= ''; - if ($group_by == 'client') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + if ($group_by1 == 'client') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); $html .= ''; - if ($group_by == 'project') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + if ($group_by1 == 'project') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); $html .= ''; - if ($group_by == 'task') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + if ($group_by1 == 'task') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); $html .= ''; - if ($group_by == 'cf_1') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + if ($group_by1 == 'cf_1') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); $html .= ''.$i18n->get('label.subtotal').''; - if ($group_by == 'user') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + if ($group_by1 == 'user') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); $html .= ''; - if ($group_by == 'client') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + if ($group_by1 == 'client') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); $html .= ''; - if ($group_by == 'project') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + if ($group_by1 == 'project') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); $html .= ''; - if ($group_by == 'task') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + if ($group_by1 == 'task') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); $html .= ''; - if ($group_by == 'cf_1') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + if ($group_by1 == 'cf_1') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); $html .= '
-
 Anuko Time Tracker 1.18.01.4327 | Copyright © Anuko | +  Anuko Time Tracker 1.18.01.4328 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b027028b5322fcbfb6de53e7a74529cbac7931de Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 29 Oct 2018 13:03:03 +0000 Subject: [PATCH 0238/1848] Some more work in progress on multiple grouping by. --- WEB-INF/lib/common.lib.php | 8 ++++ WEB-INF/lib/ttReportHelper.class.php | 62 ++++++++++++++++++---------- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 43377103a..d29ba1a12 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -390,3 +390,11 @@ function ttStartsWith($string, $startString) $len = strlen($startString); return (substr($string, 0, $len) === $startString); } + +// ttDateToUserFormat converts a date from database format to user format. +function ttDateToUserFormat($date) +{ + global $user; + $o_date = new DateAndTime(DB_DATEFORMAT, $date); + return $o_date->toString($user->date_format); +} diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 538830c3c..280b70dbe 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -127,6 +127,16 @@ static function getItems($options) { $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); + $no_grouping = ($options['group_by1'] == null || $options['group_by1'] == 'no_grouping') && + ($options['group_by2'] == null || $options['group_by2'] == 'no_grouping') && + ($options['group_by3'] == null || $options['group_by3'] == 'no_grouping'); + $grouping_by_date = ($options['group_by1'] == 'date'|| $options['group_by2'] == 'date' || $options['group_by3'] == 'date'); + $grouping_by_client = ($options['group_by1'] == 'client'|| $options['group_by2'] == 'client' || $options['group_by3'] == 'client'); + $grouping_by_project = ($options['group_by1'] == 'project'|| $options['group_by2'] == 'project' || $options['group_by3'] == 'project'); + $grouping_by_task = ($options['group_by1'] == 'task'|| $options['group_by2'] == 'task' || $options['group_by3'] == 'task'); + $grouping_by_user = ($options['group_by1'] == 'user'|| $options['group_by2'] == 'user' || $options['group_by3'] == 'user'); + $grouping_by_cf_1 = ($options['group_by1'] == 'cf_1'|| $options['group_by2'] == 'cf_1' || $options['group_by3'] == 'cf_1'); + $group_by_option = $options['group_by1']; $convertTo12Hour = ('%I:%M %p' == $user->time_format) && ($options['show_start'] || $options['show_end']); @@ -138,16 +148,16 @@ static function getItems($options) { if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. - if ($options['show_client'] || 'client' == $group_by_option) + if ($options['show_client'] || $grouping_by_client) array_push($fields, 'c.name as client'); // Add project name if it is selected. - if ($options['show_project'] || 'project' == $group_by_option) + if ($options['show_project'] || $grouping_by_project) array_push($fields, 'p.name as project'); // Add task name if it is selected. - if ($options['show_task'] || 'task' == $group_by_option) + if ($options['show_task'] || $grouping_by_task) array_push($fields, 't.name as task'); // Add custom field. - $include_cf_1 = $options['show_custom_field_1'] || 'cf_1' == $group_by_option; + $include_cf_1 = $options['show_custom_field_1'] || $grouping_by_cf_1; if ($include_cf_1) { $custom_fields = new CustomFields($user->group_id); $cf_1_type = $custom_fields->fields[0]['type']; @@ -203,15 +213,15 @@ static function getItems($options) { // Prepare sql query part for left joins. $left_joins = null; - if ($options['show_client'] || 'client' == $group_by_option) + if ($options['show_client'] || $grouping_by_client) $left_joins .= " left join tt_clients c on (c.id = l.client_id)"; if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = l.invoice_id and i.status = 1)"; if ($canViewReports || $isClient || $user->isPluginEnabled('ex')) $left_joins .= " left join tt_users u on (u.id = l.user_id)"; - if ($options['show_project'] || 'project' == $group_by_option) + if ($options['show_project'] || $grouping_by_project) $left_joins .= " left join tt_projects p on (p.id = l.project_id)"; - if ($options['show_task'] || 'task' == $group_by_option) + if ($options['show_task'] || $grouping_by_task) $left_joins .= " left join tt_tasks t on (t.id = l.task_id)"; if ($include_cf_1) { if ($cf_1_type == CustomFields::TYPE_TEXT) @@ -228,7 +238,7 @@ static function getItems($options) { // Construct sql query for tt_log items. $sql = "select ".join(', ', $fields)." from tt_log l $left_joins $where"; - // If we don't have expense items (such as when the Expenses plugin is desabled), the above is all sql we need, + // If we don't have expense items (such as when the Expenses plugin is disabled), the above is all sql we need, // with an exception of sorting part, that is added in the end. // However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table. @@ -241,14 +251,14 @@ static function getItems($options) { if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. - if ($options['show_client'] || 'client' == $group_by_option) + if ($options['show_client'] || $grouping_by_client) array_push($fields, 'c.name as client'); // Add project name if it is selected. - if ($options['show_project'] || 'project' == $group_by_option) + if ($options['show_project'] || $grouping_by_project) array_push($fields, 'p.name as project'); - if ($options['show_task'] || 'task' == $group_by_option) + if ($options['show_task'] || $grouping_by_task) array_push($fields, 'null'); // null for task name. We need to match column count for union. - if ($options['show_custom_field_1'] || 'cf_1' == $group_by_option) + if ($options['show_custom_field_1'] || $grouping_by_cf_1) array_push($fields, 'null'); // null for cf_1. if ($options['show_start']) { array_push($fields, 'null'); // null for unformatted_start. @@ -283,9 +293,9 @@ static function getItems($options) { $left_joins = null; if ($canViewReports || $isClient) $left_joins .= " left join tt_users u on (u.id = ei.user_id)"; - if ($options['show_client'] || 'client' == $group_by_option) + if ($options['show_client'] || $grouping_by_client) $left_joins .= " left join tt_clients c on (c.id = ei.client_id)"; - if ($options['show_project'] || 'project' == $group_by_option) + if ($options['show_project'] || $grouping_by_project) $left_joins .= " left join tt_projects p on (p.id = ei.project_id)"; if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; @@ -301,11 +311,16 @@ static function getItems($options) { // Determine sort part. $sort_part = ' order by '; - if ($group_by_option == null || 'no_grouping' == $group_by_option || 'date' == $group_by_option) + if ($no_grouping) $sort_part .= 'date'; - else - $sort_part .= $group_by_option.', date'; - if (($canViewReports || $isClient) && $options['users'] && 'user' != $group_by_option) + else { + $sort_part2 .= ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') ? ', '.$options['group_by1'] : ''; + $sort_part2 .= ($options['group_by2'] != null && $options['group_by2'] != 'no_grouping') ? ', '.$options['group_by2'] : ''; + $sort_part2 .= ($options['group_by3'] != null && $options['group_by3'] != 'no_grouping') ? ', '.$options['group_by3'] : ''; + if (!$grouping_by_date) $sort_part2 .= ', date'; + $sort_part .= ltrim($sort_part2, ', '); // Remove leading comma and space. + } + if (($canViewReports || $isClient) && $options['users'] && !$grouping_by_user) $sort_part .= ', user, type'; if ($options['show_start']) $sort_part .= ', unformatted_start'; @@ -333,13 +348,16 @@ static function getItems($options) { if ('.' != $user->decimal_mark) $val['expense'] = str_replace('.', $user->decimal_mark, $val['expense']); } +// CODING STOPPED RIGHT HERE replace with a combined key... if ('no_grouping' != $group_by_option) { $val['grouped_by'] = $val[$group_by_option]; if ('date' == $group_by_option) { // This is needed to get the date in user date format. - $o_date = new DateAndTime(DB_DATEFORMAT, $val['grouped_by']); - $val['grouped_by'] = $o_date->toString($user->date_format); - unset($o_date); + //$o_date = new DateAndTime(DB_DATEFORMAT, $val['grouped_by']); + //$val['grouped_by'] = $o_date->toString($user->date_format); + //unset($o_date); + + $val['grouped_by'] = ttDateToUserFormat($val['grouped_by']); } } @@ -1063,6 +1081,8 @@ static function getReportOptions($bean) { $options['show_work_units'] = $bean->getAttribute('chunits'); $options['show_totals_only'] = $bean->getAttribute('chtotalsonly'); $options['group_by1'] = $bean->getAttribute('group_by1'); + $options['group_by2'] = $bean->getAttribute('group_by2'); + $options['group_by3'] = $bean->getAttribute('group_by3'); return $options; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 818b42753..54df5f942 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.01.4328 | Copyright © Anuko | +  Anuko Time Tracker 1.18.01.4329 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a2c9be17652110a021c2a6ab867ad78ecd1bcc2d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 29 Oct 2018 13:14:09 +0000 Subject: [PATCH 0239/1848] A bit of refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 15 ++------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 280b70dbe..0b8dc83cd 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -352,19 +352,11 @@ static function getItems($options) { if ('no_grouping' != $group_by_option) { $val['grouped_by'] = $val[$group_by_option]; if ('date' == $group_by_option) { - // This is needed to get the date in user date format. - //$o_date = new DateAndTime(DB_DATEFORMAT, $val['grouped_by']); - //$val['grouped_by'] = $o_date->toString($user->date_format); - //unset($o_date); - $val['grouped_by'] = ttDateToUserFormat($val['grouped_by']); } } - // This is needed to get the date in user date format. - $o_date = new DateAndTime(DB_DATEFORMAT, $val['date']); - $val['date'] = $o_date->toString($user->date_format); - unset($o_date); + $val['date'] = ttDateToUserFormat($val['date']); $row = $val; $report_items[] = $row; @@ -538,10 +530,7 @@ static function getSubtotals($options) { while ($val = $res->fetchRow()) { if ('date' == $group_by_option) { - // This is needed to get the date in user date format. - $o_date = new DateAndTime(DB_DATEFORMAT, $val['group_field']); - $val['group_field'] = $o_date->toString($user->date_format); - unset($o_date); + $val['group_field'] = ttDateToUserFormat($val['group_field']); } $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; if ($options['show_cost']) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 54df5f942..5fe882778 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.01.4329 | Copyright © Anuko | +  Anuko Time Tracker 1.18.01.4330 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 75f676a0c24fc8593c94ba3fedd366a99fe45a93 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 29 Oct 2018 14:19:52 +0000 Subject: [PATCH 0240/1848] Refactored ttReportHelper::getItems for multiple group by condition. --- WEB-INF/lib/ttReportHelper.class.php | 39 +++++++++++++++++++++------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 0b8dc83cd..e80e7d03c 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -348,18 +348,11 @@ static function getItems($options) { if ('.' != $user->decimal_mark) $val['expense'] = str_replace('.', $user->decimal_mark, $val['expense']); } -// CODING STOPPED RIGHT HERE replace with a combined key... - if ('no_grouping' != $group_by_option) { - $val['grouped_by'] = $val[$group_by_option]; - if ('date' == $group_by_option) { - $val['grouped_by'] = ttDateToUserFormat($val['grouped_by']); - } - } + if (!$no_grouping) $val['grouped_by'] = ttReportHelper::makeGroupByKey($options, $val); $val['date'] = ttDateToUserFormat($val['date']); - $row = $val; - $report_items[] = $row; + $report_items[] = $val; } return $report_items; @@ -1096,4 +1089,32 @@ static function verifyBean($bean) { // TODO: add additional checks here. Perhaps do it before saving the bean for consistency. return true; } + + // makeGroupByKey - builds a combined group by key from group_by1, group_by2 and group_by3 values + // (passed in $options) and a row of data ($row obtained from a db query). + static function makeGroupByKey($options, $row) { + if ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') { + // We have group_by1. + $group_by1 = $options['group_by1']; + $group_by1_value = $row[$group_by1]; + if ($group_by1 == 'date') $group_by1_value = ttDateToUserFormat($group_by1_value); + $group_by_key .= ' - '.$group_by1_value; + } + if ($options['group_by2'] != null && $options['group_by2'] != 'no_grouping') { + // We have group_by2. + $group_by2 = $options['group_by2']; + $group_by2_value = $row[$group_by2]; + if ($group_by2 == 'date') $group_by2_value = ttDateToUserFormat($group_by2_value); + $group_by_key .= ' - '.$group_by2_value; + } + if ($options['group_by3'] != null && $options['group_by3'] != 'no_grouping') { + // We have group_by3. + $group_by3 = $options['group_by3']; + $group_by3_value = $row[$group_by3]; + if ($group_by3 == 'date') $group_by3_value = ttDateToUserFormat($group_by3_value); + $group_by_key .= ' - '.$group_by3_value; + } + $group_by_key = trim($group_by_key, ' -'); + return $group_by_key; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5fe882778..81f2623ed 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.01.4330 | Copyright © Anuko | +  Anuko Time Tracker 1.18.01.4331 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e99d8df6059bacd85be829c9a369f6a1e2994882 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 29 Oct 2018 14:51:31 +0000 Subject: [PATCH 0241/1848] Added user input check for multiple group by. --- WEB-INF/templates/footer.tpl | 2 +- reports.php | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 81f2623ed..d261f0815 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.01.4331 | Copyright © Anuko | +  Anuko Time Tracker 1.18.01.4332 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 39f09c0b4..cba099160 100644 --- a/reports.php +++ b/reports.php @@ -338,6 +338,13 @@ if ($start_date->compare($end_date) > 0) $err->add($i18n->get('error.interval'), $i18n->get('label.end_date'), $i18n->get('label.start_date')); } + $group_by1 = $bean->getAttribute('group_by1'); + $group_by2 = $bean->getAttribute('group_by2'); + $group_by3 = $bean->getAttribute('group_by3'); + if (($group_by3 != null && $group_by3 != 'no_grouping') && ($group_by3 == $group_by1 || $group_by3 == $group_by2)) + $err->add($i18n->get('error.field'), $i18n->get('form.reports.group_by')); + if (($group_by2 != null && $group_by2 != 'no_grouping') && ($group_by2 == $group_by1 || $group_by3 == $group_by2)) + $err->add($i18n->get('error.field'), $i18n->get('form.reports.group_by')); // Check remaining values. if (!ttReportHelper::verifyBean($bean)) $err->add($i18n->get('error.sys')); From 405a3dc75eaf770313b2da57bc25088e5c6e76bd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 30 Oct 2018 16:13:22 +0000 Subject: [PATCH 0242/1848] Initial attempt to refactor ttReportHelper::getSubtotals to use multiple group by. --- WEB-INF/lib/ttReportHelper.class.php | 503 ++++++++++++++++++++++----- WEB-INF/templates/footer.tpl | 2 +- report.php | 4 +- tofile.php | 9 +- topdf.php | 12 +- 5 files changed, 430 insertions(+), 100 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index e80e7d03c..454b437df 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -397,51 +397,20 @@ static function getFromSession() { static function getSubtotals($options) { global $user; - $group_by_option = $options['group_by1']; - if ('no_grouping' == $group_by_option) return null; + $group_fields = ttReportHelper::makeGroupByFieldsPart($options); + if (!$group_fields) return null; $mdb2 = getConnection(); - // Start with sql to obtain subtotals for time items. This simple sql will be used when we have no expenses. - - // Determine group by field and a required join. - switch ($group_by_option) { - case 'date': - $group_field = 'l.date'; - $group_join = ''; - break; - case 'user': - $group_field = 'u.name'; - $group_join = 'left join tt_users u on (l.user_id = u.id) '; - break; - case 'client': - $group_field = 'c.name'; - $group_join = 'left join tt_clients c on (l.client_id = c.id) '; - break; - case 'project': - $group_field = 'p.name'; - $group_join = 'left join tt_projects p on (l.project_id = p.id) '; - break; - case 'task': - $group_field = 't.name'; - $group_join = 'left join tt_tasks t on (l.task_id = t.id) '; - break; - case 'cf_1': - $group_field = 'cfo.value'; - $custom_fields = new CustomFields($user->group_id); - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $group_join = 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id) '; - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $group_join = 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.option_id = cfo.id) '; - break; - } - + $concat_part = ttReportHelper::makeConcatPart($options); + $join_part = ttReportHelper::makeJoinPart($options); $where = ttReportHelper::getWhere($options); + $group_by_part = ttReportHelper::makeGroupByPart($options); if ($options['show_cost']) { if (MODE_TIME == $user->tracking_mode) { - if ($group_by_option != 'user') + if (!ttReportHelper::groupingByUser($options)) $left_join = 'left join tt_users u on (l.user_id = u.id)'; - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time"; if ($options['show_work_units']) { if ($user->unit_totals_only) $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; @@ -450,10 +419,10 @@ static function getSubtotals($options) { } $sql .= ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, null as expenses from tt_log l - $group_join $left_join $where group by $group_field"; + $join_part $left_join $where $group_by_part"; } else { // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time"; if ($options['show_work_units']) { if ($user->unit_totals_only) $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; @@ -462,11 +431,12 @@ static function getSubtotals($options) { } $sql .= ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l - $group_join - left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where group by $group_field"; + $join_part + left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where $group_by_part"; } - } else { - $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + } else { + // $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; + $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time"; if ($options['show_work_units']) { if ($user->unit_totals_only) $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; @@ -474,41 +444,20 @@ static function getSubtotals($options) { $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; } $sql .= ", null as expenses from tt_log l - $group_join $where group by $group_field"; + $join_part $where $group_by_part"; } // By now we have sql for time items. // However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table. if ($options['show_cost'] && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled - // Determine group by field and a required join. - $group_join = null; - $group_field = 'null'; - switch ($group_by_option) { - case 'date': - $group_field = 'ei.date'; - $group_join = ''; - break; - case 'user': - $group_field = 'u.name'; - $group_join = 'left join tt_users u on (ei.user_id = u.id) '; - break; - case 'client': - $group_field = 'c.name'; - $group_join = 'left join tt_clients c on (ei.client_id = c.id) '; - break; - case 'project': - $group_field = 'p.name'; - $group_join = 'left join tt_projects p on (ei.project_id = p.id) '; - break; - } - + $concat_part = ttReportHelper::makeConcatExpensesPart($options); + $join_part = ttReportHelper::makeJoinExpensesPart($options); $where = ttReportHelper::getExpenseWhere($options); - $sql_for_expenses = "select $group_field as group_field, null as time"; + $group_by_part = ttReportHelper::makeGroupByExpensesPart($options); + $sql_for_expenses = "select $concat_part, null as time"; if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; - $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $group_join $where"; - // Add a "group by" clause if we are grouping. - if ('null' != $group_field) $sql_for_expenses .= " group by $group_field"; + $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $join_part $where $group_by_part"; // Create a combined query. $combined = "select group_field, sum(time) as time"; @@ -520,11 +469,12 @@ static function getSubtotals($options) { // Execute query. $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die($res->getMessage()); - while ($val = $res->fetchRow()) { - if ('date' == $group_by_option) { - $val['group_field'] = ttDateToUserFormat($val['group_field']); - } +// TODO: consider writing a function that properly formats a date part in a multi-part key. +// +// if ('date' == $group_by_option) { +// $val['group_field'] = ttDateToUserFormat($val['group_field']); +// } $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; if ($options['show_cost']) { if ('.' != $user->decimal_mark) { @@ -1090,31 +1040,426 @@ static function verifyBean($bean) { return true; } - // makeGroupByKey - builds a combined group by key from group_by1, group_by2 and group_by3 values + // makeGroupByKey builds a combined group by key from group_by1, group_by2 and group_by3 values // (passed in $options) and a row of data ($row obtained from a db query). static function makeGroupByKey($options, $row) { if ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') { // We have group_by1. $group_by1 = $options['group_by1']; $group_by1_value = $row[$group_by1]; - if ($group_by1 == 'date') $group_by1_value = ttDateToUserFormat($group_by1_value); + //if ($group_by1 == 'date') $group_by1_value = ttDateToUserFormat($group_by1_value); + if (empty($group_by1_value)) $group_by1_value = 'Null'; // To match what comes out of makeConcatPart. $group_by_key .= ' - '.$group_by1_value; } if ($options['group_by2'] != null && $options['group_by2'] != 'no_grouping') { // We have group_by2. $group_by2 = $options['group_by2']; $group_by2_value = $row[$group_by2]; - if ($group_by2 == 'date') $group_by2_value = ttDateToUserFormat($group_by2_value); + //if ($group_by2 == 'date') $group_by2_value = ttDateToUserFormat($group_by2_value); + if (empty($group_by2_value)) $group_by2_value = 'Null'; // To match what comes out of makeConcatPart. $group_by_key .= ' - '.$group_by2_value; } if ($options['group_by3'] != null && $options['group_by3'] != 'no_grouping') { // We have group_by3. $group_by3 = $options['group_by3']; $group_by3_value = $row[$group_by3]; - if ($group_by3 == 'date') $group_by3_value = ttDateToUserFormat($group_by3_value); + //if ($group_by3 == 'date') $group_by3_value = ttDateToUserFormat($group_by3_value); + if (empty($group_by3_value)) $group_by3_value = 'Null'; // To match what comes out of makeConcatPart. $group_by_key .= ' - '.$group_by3_value; } $group_by_key = trim($group_by_key, ' -'); return $group_by_key; } + + // makeGroupByPart builds a combined group by part for sql query for time items using group_by1, + // group_by2, and group_by3 values passed in $options. + static function makeGroupByPart($options) { + $no_grouping = ($options['group_by1'] == null || $options['group_by1'] == 'no_grouping') && + ($options['group_by2'] == null || $options['group_by2'] == 'no_grouping') && + ($options['group_by3'] == null || $options['group_by3'] == 'no_grouping'); + if ($no_grouping) return null; + + $group_by1 = $options['group_by1']; + $group_by2 = $options['group_by2']; + $group_by3 = $options['group_by3']; + + switch ($group_by1) { + case 'date': + $group_by_parts .= ', l.date'; + break; + case 'user': + $group_by_parts .= ', u.name'; + break; + case 'client': + $group_by_parts .= ', c.name'; + break; + case 'project': + $group_by_parts .= ', p.name'; + break; + case 'task': + $group_by_parts .= ', t.name'; + break; + case 'cf_1': + $group_by_parts .= ', cfo.value'; + break; + } + switch ($group_by2) { + case 'date': + $group_by_parts .= ', l.date'; + break; + case 'user': + $group_by_parts .= ', u.name'; + break; + case 'client': + $group_by_parts .= ', c.name'; + break; + case 'project': + $group_by_parts .= ', p.name'; + break; + case 'task': + $group_by_parts .= ', t.name'; + break; + case 'cf_1': + $group_by_parts .= ', cfo.value'; + break; + } + switch ($group_by3) { + case 'date': + $group_by_parts .= ', l.date'; + break; + case 'user': + $group_by_parts .= ', u.name'; + break; + case 'client': + $group_by_parts .= ', c.name'; + break; + case 'project': + $group_by_parts .= ', p.name'; + break; + case 'task': + $group_by_parts .= ', t.name'; + break; + case 'cf_1': + $group_by_parts .= ', cfo.value'; + break; + } + // Remove garbage from the beginning. + $group_by_parts = ltrim($group_by_parts, ', '); + $group_by_part = "group by $group_by_parts"; + return $group_by_part; + } + + // makeGroupByExpensesPart builds a combined group by part for sql query for expense items using + // group_by1, group_by2, and group_by3 values passed in $options. + static function makeGroupByExpensesPart($options) { + $no_grouping = ($options['group_by1'] == null || $options['group_by1'] == 'no_grouping') && + ($options['group_by2'] == null || $options['group_by2'] == 'no_grouping') && + ($options['group_by3'] == null || $options['group_by3'] == 'no_grouping'); + if ($no_grouping) return null; + + $group_by1 = $options['group_by1']; + $group_by2 = $options['group_by2']; + $group_by3 = $options['group_by3']; + + switch ($group_by1) { + case 'date': + $group_by_parts .= ', ei.date'; + break; + case 'user': + $group_by_parts .= ', u.name'; + break; + case 'client': + $group_by_parts .= ', c.name'; + break; + case 'project': + $group_by_parts .= ', p.name'; + break; + } + switch ($group_by2) { + case 'date': + $group_by_parts .= ', ei.date'; + break; + case 'user': + $group_by_parts .= ', u.name'; + break; + case 'client': + $group_by_parts .= ', c.name'; + break; + case 'project': + $group_by_parts .= ', p.name'; + break; + } + switch ($group_by3) { + case 'date': + $group_by_parts .= ', ei.date'; + break; + case 'user': + $group_by_parts .= ', u.name'; + break; + case 'client': + $group_by_parts .= ', c.name'; + break; + case 'project': + $group_by_parts .= ', p.name'; + break; + } + // Remove garbage from the beginning. + $group_by_parts = ltrim($group_by_parts, ', '); + $group_by_part = "group by $group_by_parts"; + return $group_by_part; + } + + // makeConcatPart builds a concatenation part for getSubtotals query (for time items). + static function makeConcatPart($options) { + $group_by1 = $options['group_by1']; + $group_by2 = $options['group_by2']; + $group_by3 = $options['group_by3']; + + switch ($group_by1) { + case 'date': + $what_to_concat .= ", ' - ', l.date"; + break; + case 'user': + $what_to_concat .= ", ' - ', u.name"; + break; + case 'client': + $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + break; + case 'project': + $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + break; + case 'task': + $what_to_concat .= ", ' - ', coalesce(t.name, 'Null')"; + break; + case 'cf_1': + $what_to_concat .= ", ' - ', coalesce(cfo.value, 'Null')"; + break; + } + switch ($group_by2) { + case 'date': + $what_to_concat .= ", ' - ', l.date"; + break; + case 'user': + $what_to_concat .= ", ' - ', u.name"; + break; + case 'client': + $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + break; + case 'project': + $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + break; + case 'task': + $what_to_concat .= ", ' - ', coalesce(t.name, 'Null')"; + break; + case 'cf_1': + $what_to_concat .= ", ' - ', coalesce(cfo.value, 'Null')"; + break; + } + switch ($group_by3) { + case 'date': + $what_to_concat .= ", ' - ', l.date"; + break; + case 'user': + $what_to_concat .= ", ' - ', u.name"; + break; + case 'client': + $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + break; + case 'project': + $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + break; + case 'task': + $what_to_concat .= ", ' - ', coalesce(t.name, 'Null')"; + break; + case 'cf_1': + $what_to_concat .= ", ' - ', coalesce(cfo.value, 'Null')"; + break; + } + // Remove garbage from both ends. + $what_to_concat = trim($what_to_concat, "', -"); + $concat_part = "concat($what_to_concat) as group_field"; + $concat_part = trim($concat_part, ' -'); + return $concat_part; + } + + // makeConcatPart builds a concatenation part for getSubtotals query (for expense items). + static function makeConcatExpensesPart($options) { + $group_by1 = $options['group_by1']; + $group_by2 = $options['group_by2']; + $group_by3 = $options['group_by3']; + + switch ($group_by1) { + case 'date': + $what_to_concat .= ", ' - ', ei.date"; + break; + case 'user': + $what_to_concat .= ", ' - ', u.name"; + break; + case 'client': + $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + break; + case 'project': + $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + break; + } + switch ($group_by2) { + case 'date': + $what_to_concat .= ", ' - ', ei.date"; + break; + case 'user': + $what_to_concat .= ", ' - ', u.name"; + break; + case 'client': + $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + break; + case 'project': + $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + break; + } + switch ($group_by3) { + case 'date': + $what_to_concat .= ", ' - ', ei.date"; + break; + case 'user': + $what_to_concat .= ", ' - ', u.name"; + break; + case 'client': + $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + break; + case 'project': + $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + break; + } + // Remove garbage from both ends. + $what_to_concat = trim($what_to_concat, "', -"); + $concat_part = "concat($what_to_concat) as group_field"; + $concat_part = trim($concat_part, ' -'); + return $concat_part; + } + + // makeJoinPart builds a left join part for getSubtotals query (for time items). + static function makeJoinPart($options) { + global $custom_fields; // TODO: is it safe to assume the object is there when needed? + + $group_by_fields = ttReportHelper::makeGroupByFieldsPart($options); // TODO: refactor this, perhaps? + if (strpos($group_by_fields, 'user') !== false) { + // Grouping by user, add a join on tt_users table. + $join .= ' left join tt_users u on (l.user_id = u.id)'; + } + if (strpos($group_by_fields, 'client') !== false) { + // Grouping by client, add a join on tt_clients table. + $join .= ' left join tt_clients c on (l.client_id = c.id)'; + } + if (strpos($group_by_fields, 'project') !== false) { + // Grouping by project, add a join on tt_projects table. + $join .= ' left join tt_projects p on (l.project_id = p.id)'; + } + if (strpos($group_by_fields, 'task') !== false) { + // Grouping by task, add a join on tt_tasks table. + $join .= ' left join tt_tasks t on (l.task_id = t.id)'; + } + if (strpos($group_by_fields, 'cf_1') !== false) { + // Grouping by custom field 1, add a join for it. + // $custom_fields = new CustomFields($user->group_id); + if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) + $join .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id)'; + elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) + $join .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)'; + } + return $join; + } + + // makeJoinExpensesPart builds a left join part for getSubtotals query for expense items. + static function makeJoinExpensesPart($options) { + $group_by_fields = ttReportHelper::makeGroupByFieldsPart($options); // TODO: refactor this, perhaps? + if (strpos($group_by_fields, 'user') !== false) { + // Grouping by user, add a join on tt_users table. + $join .= ' left join tt_users u on (ei.user_id = u.id)'; + } + if (strpos($group_by_fields, 'client') !== false) { + // Grouping by client, add a join on tt_clients table. + $join .= ' left join tt_clients c on (ei.client_id = c.id)'; + } + if (strpos($group_by_fields, 'project') !== false) { + // Grouping by project, add a join on tt_projects table. + $join .= ' left join tt_projects p on (ei.project_id = p.id)'; + } + return $join; + } + + // makeGroupByFieldsPart builds a commma-separated list of fields for sql query using group_by1, + // group_by2, and group_by3 values passed in $options. + static function makeGroupByFieldsPart($options) { + $no_grouping = ($options['group_by1'] == null || $options['group_by1'] == 'no_grouping') && + ($options['group_by2'] == null || $options['group_by2'] == 'no_grouping') && + ($options['group_by3'] == null || $options['group_by3'] == 'no_grouping'); + if ($no_grouping) return null; + + if ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') { + // We have group_by1. + $group_by_fields .= ', '.$options['group_by1']; + } + if ($options['group_by2'] != null && $options['group_by2'] != 'no_grouping') { + // We have group_by2. + $group_by_fields .= ', '.$options['group_by2']; + } + if ($options['group_by3'] != null && $options['group_by3'] != 'no_grouping') { + // We have group_by3. + $group_by_fields .= ', '.$options['group_by3']; + } + $group_by_fields = ltrim($group_by_fields, ', '); + return $group_by_fields; + } + + // groupingByUser determines if we are grouping a report by user. + static function groupingByUser($options) { + if ($options['group_by1'] == 'user' || $options['group_by2'] == 'user' || $options['group_by3'] == 'user') return true; + + return false; + } + + // makeGroupByHeader builds a column header for a totals-only report using group_by1, + // group_by2, and group_by3 values passed in $options. + static function makeGroupByHeader($options) { + global $i18n; + global $custom_fields; + + $no_grouping = ($options['group_by1'] == null || $options['group_by1'] == 'no_grouping') && + ($options['group_by2'] == null || $options['group_by2'] == 'no_grouping') && + ($options['group_by3'] == null || $options['group_by3'] == 'no_grouping'); + if ($no_grouping) return null; + + if ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') { + // We have group_by1. + $group_by1 = $options['group_by1']; + if ('cf_1' == $group_by1) + $group_by_header .= ' - '.$custom_fields->fields[0]['label']; + else { + $key = 'label.'.$group_by1; + $group_by_header .= ' - '.$i18n->get($key); + } + } + if ($options['group_by2'] != null && $options['group_by2'] != 'no_grouping') { + // We have group_by2. + $group_by2 = $options['group_by2']; + if ('cf_1' == $group_by2) + $group_by_header .= ' - '.$custom_fields->fields[0]['label']; + else { + $key = 'label.'.$group_by2; + $group_by_header .= ' - '.$i18n->get($key); + } + } + if ($options['group_by3'] != null && $options['group_by3'] != 'no_grouping') { + // We have group_by3. + $group_by3 = $options['group_by3']; + if ('cf_1' == $group_by3) + $group_by_header .= ' - '.$custom_fields->fields[0]['label']; + else { + $key = 'label.'.$group_by3; + $group_by_header .= ' - '.$i18n->get($key); + } + } + $group_by_header = ltrim($group_by_header, ' -'); + return $group_by_header; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d261f0815..7b0a56e40 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- '; From 3be2bc61911ea52fb39774f7e569f7f9f2552b58 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 30 Oct 2018 16:17:54 +0000 Subject: [PATCH 0243/1848] Initial release of multiple group by in reports. --- WEB-INF/config.php.dist | 3 --- WEB-INF/templates/footer.tpl | 2 +- reports.php | 6 ++---- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 1fd74cce8..1218f7f65 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -207,6 +207,3 @@ define('AUTH_MODULE', 'db'); // Height in pixels for the note input field in time.php. Defaults to 40. // define('NOTE_INPUT_HEIGHT', 100); - -// A temporary config option while development on multiple grouping in reports is ongoing. To be removed when done. -// define('MULTIPLE_GROUP_BY_DEBUG', false); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7b0a56e40..f2bf5b5e5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.01.4332 | Copyright © Anuko | +  Anuko Time Tracker 1.18.02.4333 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index efbaccea8..5f7e687bf 100644 --- a/report.php +++ b/report.php @@ -192,12 +192,14 @@ } // Determine group by header. if ('no_grouping' != $group_by) { + /* if ('cf_1' == $group_by) $smarty->assign('group_by_header', $custom_fields->fields[0]['label']); else { $key = 'label.'.$group_by; $smarty->assign('group_by_header', $i18n->get($key)); - } + } */ + $smarty->assign('group_by_header', ttReportHelper::makeGroupByHeader($options)); } // Assign variables that are used to alternate color of rows for different dates. $smarty->assign('prev_date', ''); diff --git a/tofile.php b/tofile.php index 42b734338..d996098b7 100644 --- a/tofile.php +++ b/tofile.php @@ -164,14 +164,7 @@ $group_by1 = $bean->getAttribute('group_by1'); if ($totals_only) { // Totals only report. - - // Determine group_by header. - if ('cf_1' == $group_by1) - $group_by_header = $custom_fields->fields[0]['label']; - else { - $key = 'label.'.$group_by1; - $group_by_header = $i18n->get($key); - } + $group_by_header = ttReportHelper::makeGroupByHeader($options); // Print headers. print '"'.$group_by_header.'"'; diff --git a/topdf.php b/topdf.php index 7d3fa0096..0040c7be9 100644 --- a/topdf.php +++ b/topdf.php @@ -62,17 +62,6 @@ // is grouped by either date, user, client, project, task or cf_1 and user only needs to see subtotals by group. $totals_only = ($bean->getAttribute('chtotalsonly') == '1'); -// Determine group by header. -$group_by1 = $bean->getAttribute('group_by1'); -if ('no_grouping' != $group_by1) { - if ('cf_1' == $group_by1) - $group_by_header = $custom_fields->fields[0]['label']; - else { - $key = 'label.'.$group_by1; - $group_by_header = $i18n->get($key); - } -} - // Obtain items for report. $options = ttReportHelper::getReportOptions($bean); if (!$totals_only) @@ -104,6 +93,7 @@ if ($totals_only) { // We are building a "totals only" report with only subtotals and total. + $group_by_header = ttReportHelper::makeGroupByHeader($options); $colspan = 1; // Column span for an empty row. // Table header. $html .= '
-
 Anuko Time Tracker 1.18.02.4333 | Copyright © Anuko | +  Anuko Time Tracker 1.18.03.4334 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index cba099160..ae7f552cb 100644 --- a/reports.php +++ b/reports.php @@ -234,10 +234,8 @@ } $group_by_options_size = sizeof($group_by_options); $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by1','data'=>$group_by_options)); -if (defined('MULTIPLE_GROUP_BY_DEBUG') && isTrue(MULTIPLE_GROUP_BY_DEBUG)) { - if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','name'=>'group_by2','data'=>$group_by_options)); - if ($group_by_options_size > 3) $form->addInput(array('type'=>'combobox','name'=>'group_by3','data'=>$group_by_options)); -} +if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','name'=>'group_by2','data'=>$group_by_options)); +if ($group_by_options_size > 3) $form->addInput(array('type'=>'combobox','name'=>'group_by3','data'=>$group_by_options)); $form->addInput(array('type'=>'checkbox','name'=>'chtotalsonly')); // Add text field for a new favorite report name. From 7562c5b6d68929eb4787749f8c10dc032ee9a1c7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 31 Oct 2018 01:22:43 +0000 Subject: [PATCH 0244/1848] Fixed a condition that determines grouping for getting subtotals. --- WEB-INF/lib/ttReportHelper.class.php | 9 +++++++++ WEB-INF/templates/footer.tpl | 2 +- report.php | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 454b437df..3940a51b7 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1411,6 +1411,15 @@ static function makeGroupByFieldsPart($options) { return $group_by_fields; } + // grouping determines if we are grooping the project by either group_by1, + // group_by2, or group_by3 values passed in $options. + static function grouping($options) { + $grouping = ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') || + ($options['group_by2'] != null && $options['group_by2'] != 'no_grouping') || + ($options['group_by3'] != null && $options['group_by3'] != 'no_grouping'); + return $grouping; + } + // groupingByUser determines if we are grouping a report by user. static function groupingByUser($options) { if ($options['group_by1'] == 'user' || $options['group_by2'] == 'user' || $options['group_by3'] == 'user') return true; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f2bf5b5e5..be04ad962 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.03.4334 | Copyright © Anuko | +  Anuko Time Tracker 1.18.03.4335 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index 5f7e687bf..f6abcc4c6 100644 --- a/report.php +++ b/report.php @@ -178,7 +178,7 @@ if ($request->isGet() && $user->isPluginEnabled('ps')) ttReportHelper::putInSession($report_items); -if ('no_grouping' != $group_by) +if (ttReportHelper::grouping($options)) $subtotals = ttReportHelper::getSubtotals($options); $totals = ttReportHelper::getTotals($options); From 5403806f9c5e87add5a1594835018125a5ed0b0b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 31 Oct 2018 12:40:28 +0000 Subject: [PATCH 0245/1848] Improved visibility of Totals only checkbox on reports.php for multiple group by. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 6 ++++-- reports.php | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index be04ad962..1a52dda6e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.03.4335 | Copyright © Anuko | +  Anuko Time Tracker 1.18.03.4336 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index feb5800fe..418c172a3 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -138,8 +138,10 @@ function selectAssignedUsers(project_id) { function handleCheckboxes() { var totalsOnlyCheckbox = document.getElementById("chtotalsonly"); var totalsOnlyLabel = document.getElementById("totals_only_label"); - if ("no_grouping" == document.getElementById("group_by1").value) { - // Unmark and disable the "Totals only" checkbox. + if ("no_grouping" == document.getElementById("group_by1").value + && "no_grouping" == document.getElementById("group_by2").value + && "no_grouping" == document.getElementById("group_by3").value) { + // Unmark and hide the "Totals only" checkbox. totalsOnlyCheckbox.checked = false; totalsOnlyCheckbox.style.visibility = "hidden"; totalsOnlyLabel.style.visibility = "hidden"; diff --git a/reports.php b/reports.php index ae7f552cb..31028f2f2 100644 --- a/reports.php +++ b/reports.php @@ -234,8 +234,8 @@ } $group_by_options_size = sizeof($group_by_options); $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by1','data'=>$group_by_options)); -if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','name'=>'group_by2','data'=>$group_by_options)); -if ($group_by_options_size > 3) $form->addInput(array('type'=>'combobox','name'=>'group_by3','data'=>$group_by_options)); +if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by2','data'=>$group_by_options)); +if ($group_by_options_size > 3) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by3','data'=>$group_by_options)); $form->addInput(array('type'=>'checkbox','name'=>'chtotalsonly')); // Add text field for a new favorite report name. From f9e704d00a2d21b1a94332e088f78c22da03d37c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 31 Oct 2018 13:35:35 +0000 Subject: [PATCH 0246/1848] Improved the script that shows the Totals only checkbox. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1a52dda6e..bc3b468e3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.03.4336 | Copyright © Anuko | +  Anuko Time Tracker 1.18.03.4337 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 418c172a3..95b4a4364 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -134,20 +134,28 @@ function selectAssignedUsers(project_id) { } // handleCheckboxes - unmarks and hides the "Totals only" checkbox when -// "no grouping" is selected in the associated dropdown. +// "no grouping" is selected in the associated group by dropdowns. function handleCheckboxes() { var totalsOnlyCheckbox = document.getElementById("chtotalsonly"); var totalsOnlyLabel = document.getElementById("totals_only_label"); - if ("no_grouping" == document.getElementById("group_by1").value - && "no_grouping" == document.getElementById("group_by2").value - && "no_grouping" == document.getElementById("group_by3").value) { + var groupBy1 = document.getElementById("group_by1"); + var groupBy2 = document.getElementById("group_by2"); + var groupBy3 = document.getElementById("group_by3"); + var grouping = false; + if ((groupBy1 != null && "no_grouping" != groupBy1.value) || + (groupBy2 != null && "no_grouping" != groupBy2.value) || + (groupBy3 != null && "no_grouping" != groupBy3.value)) { + grouping = true; + } + if (grouping) { + // Show the "Totals only" checkbox. + totalsOnlyCheckbox.style.visibility = "visible"; + totalsOnlyLabel.style.visibility = "visible"; + } else { // Unmark and hide the "Totals only" checkbox. totalsOnlyCheckbox.checked = false; totalsOnlyCheckbox.style.visibility = "hidden"; totalsOnlyLabel.style.visibility = "hidden"; - } else { - totalsOnlyCheckbox.style.visibility = "visible"; - totalsOnlyLabel.style.visibility = "visible"; } } From 913eba1427598741fcfb8d1e53746923c1f9e0e4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 31 Oct 2018 17:08:48 +0000 Subject: [PATCH 0247/1848] Fixed date format in Totals only reports. --- WEB-INF/lib/ttReportHelper.class.php | 54 ++++++++++++++++++++-------- WEB-INF/templates/footer.tpl | 2 +- topdf.php | 2 +- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 3940a51b7..7a4ba2664 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -127,9 +127,7 @@ static function getItems($options) { $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); - $no_grouping = ($options['group_by1'] == null || $options['group_by1'] == 'no_grouping') && - ($options['group_by2'] == null || $options['group_by2'] == 'no_grouping') && - ($options['group_by3'] == null || $options['group_by3'] == 'no_grouping'); + $grouping = ttReportHelper::grouping($options); $grouping_by_date = ($options['group_by1'] == 'date'|| $options['group_by2'] == 'date' || $options['group_by3'] == 'date'); $grouping_by_client = ($options['group_by1'] == 'client'|| $options['group_by2'] == 'client' || $options['group_by3'] == 'client'); $grouping_by_project = ($options['group_by1'] == 'project'|| $options['group_by2'] == 'project' || $options['group_by3'] == 'project'); @@ -311,14 +309,14 @@ static function getItems($options) { // Determine sort part. $sort_part = ' order by '; - if ($no_grouping) - $sort_part .= 'date'; - else { + if ($grouping) { $sort_part2 .= ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') ? ', '.$options['group_by1'] : ''; $sort_part2 .= ($options['group_by2'] != null && $options['group_by2'] != 'no_grouping') ? ', '.$options['group_by2'] : ''; $sort_part2 .= ($options['group_by3'] != null && $options['group_by3'] != 'no_grouping') ? ', '.$options['group_by3'] : ''; if (!$grouping_by_date) $sort_part2 .= ', date'; $sort_part .= ltrim($sort_part2, ', '); // Remove leading comma and space. + } else { + $sort_part .= 'date'; } if (($canViewReports || $isClient) && $options['users'] && !$grouping_by_user) $sort_part .= ', user, type'; @@ -349,7 +347,7 @@ static function getItems($options) { $val['expense'] = str_replace('.', $user->decimal_mark, $val['expense']); } - if (!$no_grouping) $val['grouped_by'] = ttReportHelper::makeGroupByKey($options, $val); + if ($grouping) $val['grouped_by'] = ttReportHelper::makeGroupByKey($options, $val); $val['date'] = ttDateToUserFormat($val['date']); $report_items[] = $val; @@ -476,14 +474,15 @@ static function getSubtotals($options) { // $val['group_field'] = ttDateToUserFormat($val['group_field']); // } $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; + $rowLabel = ttReportHelper::makeGroupByLabel($val['group_field'], $options); if ($options['show_cost']) { if ('.' != $user->decimal_mark) { $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']); } - $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time, 'units'=> $val['units'], 'cost'=>$val['cost'],'expenses'=>$val['expenses']); + $subtotals[$val['group_field']] = array('name'=>$rowLabel,'time'=>$time, 'units'=> $val['units'], 'cost'=>$val['cost'],'expenses'=>$val['expenses']); } else - $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time, 'units'=> $val['units']); + $subtotals[$val['group_field']] = array('name'=>$rowLabel,'time'=>$time, 'units'=> $val['units']); } return $subtotals; @@ -1074,10 +1073,7 @@ static function makeGroupByKey($options, $row) { // makeGroupByPart builds a combined group by part for sql query for time items using group_by1, // group_by2, and group_by3 values passed in $options. static function makeGroupByPart($options) { - $no_grouping = ($options['group_by1'] == null || $options['group_by1'] == 'no_grouping') && - ($options['group_by2'] == null || $options['group_by2'] == 'no_grouping') && - ($options['group_by3'] == null || $options['group_by3'] == 'no_grouping'); - if ($no_grouping) return null; + if (!ttReportHelper::grouping($options)) return null; $group_by1 = $options['group_by1']; $group_by2 = $options['group_by2']; @@ -1411,7 +1407,7 @@ static function makeGroupByFieldsPart($options) { return $group_by_fields; } - // grouping determines if we are grooping the project by either group_by1, + // grouping determines if we are grouping the report by either group_by1, // group_by2, or group_by3 values passed in $options. static function grouping($options) { $grouping = ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') || @@ -1426,6 +1422,16 @@ static function groupingByUser($options) { return false; } + + // groupingBy determines if we are grouping a report by a value of $what + // ('user', 'project', etc.) by checking group_by1, group_by2, and group_by3 + // values passed in $options. + static function groupingBy($what, $options) { + $grouping = ($options['group_by1'] != null && $options['group_by1'] != $what) || + ($options['group_by2'] != null && $options['group_by2'] != $what) || + ($options['group_by3'] != null && $options['group_by3'] != $what); + return $grouping; + } // makeGroupByHeader builds a column header for a totals-only report using group_by1, // group_by2, and group_by3 values passed in $options. @@ -1471,4 +1477,24 @@ static function makeGroupByHeader($options) { $group_by_header = ltrim($group_by_header, ' -'); return $group_by_header; } + + // makeGroupByLabel builds a label for one row in a "Totals only" report of grouped by items. + // It does one thing: if we are grouping by date, the date format is converted for user. + static function makeGroupByLabel($key, $options) { + if (!ttReportHelper::groupingBy('date', $options)) + return $key; // No need to format. + + global $user; + if ($user->date_format == DB_DATEFORMAT) + return $key; // No need to format. + + $label = $key; + if (preg_match('/\d\d\d\d-\d\d-\d\d/', $key, $matches)) { + // Replace the first found match of a date in DB_DATEFORMAT. + // This is not entirely clean but better than nothing for a label in a row. + $userDate = ttDateToUserFormat($matches[0]); + $label = str_replace($matches[0], $userDate, $key); + } + return $label; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bc3b468e3..d8a4447fc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.03.4337 | Copyright © Anuko | +  Anuko Time Tracker 1.18.04.4338 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/topdf.php b/topdf.php index 0040c7be9..23f29d508 100644 --- a/topdf.php +++ b/topdf.php @@ -66,7 +66,7 @@ $options = ttReportHelper::getReportOptions($bean); if (!$totals_only) $items = ttReportHelper::getItems($options); // Individual entries. -if ($totals_only || 'no_grouping' != $group_by1) +if ($totals_only || ttReportHelper::grouping($options)) $subtotals = ttReportHelper::getSubtotals($options); // Subtotals for groups of items. $totals = ttReportHelper::getTotals($options); // Totals for the entire report. From 3297bc03f58074f5b688d867f3477e6af47d73de Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 31 Oct 2018 18:31:50 +0000 Subject: [PATCH 0248/1848] Fixed creation of group by tag for XML report export. --- WEB-INF/lib/ttReportHelper.class.php | 24 +++++++++++++++++++----- WEB-INF/templates/footer.tpl | 2 +- tofile.php | 9 +++++---- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 7a4ba2664..60cac0790 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -468,11 +468,6 @@ static function getSubtotals($options) { $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die($res->getMessage()); while ($val = $res->fetchRow()) { -// TODO: consider writing a function that properly formats a date part in a multi-part key. -// -// if ('date' == $group_by_option) { -// $val['group_field'] = ttDateToUserFormat($val['group_field']); -// } $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; $rowLabel = ttReportHelper::makeGroupByLabel($val['group_field'], $options); if ($options['show_cost']) { @@ -1478,6 +1473,25 @@ static function makeGroupByHeader($options) { return $group_by_header; } + // makeGroupByXmlTag creates an xml tag for a totals only report using group_by1, + // group_by2, and group_by3 values passed in $options. + static function makeGroupByXmlTag($options) { + if ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') { + // We have group_by1. + $tag .= '_'.$options['group_by1']; + } + if ($options['group_by2'] != null && $options['group_by2'] != 'no_grouping') { + // We have group_by2. + $tag .= '_'.$options['group_by2']; + } + if ($options['group_by3'] != null && $options['group_by3'] != 'no_grouping') { + // We have group_by3. + $tag .= '_'.$options['group_by3']; + } + $tag = ltrim($tag, '_'); + return $tag; + } + // makeGroupByLabel builds a label for one row in a "Totals only" report of grouped by items. // It does one thing: if we are grouping by date, the date format is converted for user. static function makeGroupByLabel($key, $options) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d8a4447fc..996c8dfce 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.04.4338 | Copyright © Anuko | +  Anuko Time Tracker 1.18.04.4339 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/tofile.php b/tofile.php index d996098b7..07bbc11a6 100644 --- a/tofile.php +++ b/tofile.php @@ -84,12 +84,14 @@ print "\n"; print "\n"; - $group_by1 = $bean->getAttribute('group_by1'); if ($totals_only) { - // Totals only report. Print subtotals. + // Totals only report. + $group_by_tag = ttReportHelper::makeGroupByXmlTag($options); + + // Print subtotals. foreach ($subtotals as $subtotal) { print "\n"; - print "\t<".$group_by1.">\n"; + print "\t<".$group_by_tag.">\n"; if ($bean->getAttribute('chduration')) { $val = $subtotal['time']; if($val && defined('EXPORT_DECIMAL_DURATION') && isTrue(EXPORT_DECIMAL_DURATION)) @@ -161,7 +163,6 @@ $bom = chr(239).chr(187).chr(191); // 0xEF 0xBB 0xBF in the beginning of the file is UTF8 BOM. print $bom; // Without this Excel does not display UTF8 characters properly. - $group_by1 = $bean->getAttribute('group_by1'); if ($totals_only) { // Totals only report. $group_by_header = ttReportHelper::makeGroupByHeader($options); From 3b4f6b89a71f50d89d816129b27ee819a314620e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 31 Oct 2018 22:06:44 +0000 Subject: [PATCH 0249/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 4 +--- WEB-INF/templates/footer.tpl | 2 +- topdf.php | 5 +++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 78dc1a206..5225d6763 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -93,9 +93,7 @@ 'error.no_groups' => 'Uw database is leeg. Meld je aan als admin en maak een nieuw groep.', 'error.upload' => 'Fout bij het uploaden van het bestand.', 'error.range_locked' => 'Datums zijn geblokkeerd.', -'error.mail_send' => 'Fout bij het versturen van een e-mailbericht.', -// TODO: improve the translation above by adding MAIL_SMTP_DEBUG part. -// 'error.mail_send' => 'Error sending mail. Use MAIL_SMTP_DEBUG for diagnostics.', +'error.mail_send' => 'Fout bij het versturen van een e-mailbericht. Gebruik MAIL_SMTP_DEBUG om het probleem te diagnosticeren', 'error.no_email' => 'Geen e-mailadres bekend voor dit account.', 'error.uncompleted_exists' => 'Niet afgeronde invoer bestaat al. Sluit of verwijder deze.', 'error.goto_uncompleted' => 'Ga naar onvolledige invoer.', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 996c8dfce..c92fd1a92 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.04.4339 | Copyright © Anuko | +  Anuko Time Tracker 1.18.04.4340 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/topdf.php b/topdf.php index 23f29d508..15ac1ee92 100644 --- a/topdf.php +++ b/topdf.php @@ -64,14 +64,15 @@ // Obtain items for report. $options = ttReportHelper::getReportOptions($bean); +$grouping = ttReportHelper::grouping($options); if (!$totals_only) $items = ttReportHelper::getItems($options); // Individual entries. -if ($totals_only || ttReportHelper::grouping($options)) +if ($totals_only || $grouping) $subtotals = ttReportHelper::getSubtotals($options); // Subtotals for groups of items. $totals = ttReportHelper::getTotals($options); // Totals for the entire report. // Assign variables that are used to print subtotals. -if ($items && 'no_grouping' != $group_by1) { +if ($items && $grouping) { $print_subtotals = true; $first_pass = true; $prev_grouped_by = ''; From 6d706063e2f1c0555844c381ee98bd5a4a457d4e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 1 Nov 2018 18:13:07 +0000 Subject: [PATCH 0250/1848] Added an index on tt_custom_field_log for faster reporting, a few fixes. --- WEB-INF/lib/ttReportHelper.class.php | 82 +++++++++++++++++++++++----- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 20 +++---- dbinstall.php | 10 ++-- mysql.sql | 4 +- report.php | 5 ++ 6 files changed, 92 insertions(+), 31 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 60cac0790..85b2c8e9e 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -395,9 +395,6 @@ static function getFromSession() { static function getSubtotals($options) { global $user; - $group_fields = ttReportHelper::makeGroupByFieldsPart($options); - if (!$group_fields) return null; - $mdb2 = getConnection(); $concat_part = ttReportHelper::makeConcatPart($options); @@ -452,18 +449,18 @@ static function getSubtotals($options) { $concat_part = ttReportHelper::makeConcatExpensesPart($options); $join_part = ttReportHelper::makeJoinExpensesPart($options); $where = ttReportHelper::getExpenseWhere($options); - $group_by_part = ttReportHelper::makeGroupByExpensesPart($options); + $group_by_expenses_part = ttReportHelper::makeGroupByExpensesPart($options); $sql_for_expenses = "select $concat_part, null as time"; if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; - $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $join_part $where $group_by_part"; - + $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $join_part $where $group_by_expenses_part"; +//die($sql_for_expenses); // Create a combined query. $combined = "select group_field, sum(time) as time"; if ($options['show_work_units']) $combined .= ", sum(units) as units"; $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; $sql = $combined; } - +//die($sql); // Execute query. $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die($res->getMessage()); @@ -475,9 +472,9 @@ static function getSubtotals($options) { $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']); } - $subtotals[$val['group_field']] = array('name'=>$rowLabel,'time'=>$time, 'units'=> $val['units'], 'cost'=>$val['cost'],'expenses'=>$val['expenses']); + $subtotals[$val['group_field']] = array('name'=>$rowLabel,'user'=>$val['user'],'project'=>$val['project'],'task'=>$val['task'],'client'=>$val['client'],'cf_1'=>$val['cf_1'],'time'=>$time,'units'=> $val['units'],'cost'=>$val['cost'],'expenses'=>$val['expenses']); } else - $subtotals[$val['group_field']] = array('name'=>$rowLabel,'time'=>$time, 'units'=> $val['units']); + $subtotals[$val['group_field']] = array('name'=>$rowLabel,'user'=>$val['user'],'project'=>$val['project'],'task'=>$val['task'],'client'=>$val['client'],'cf_1'=>$val['cf_1'],'time'=>$time, 'units'=> $val['units']); } return $subtotals; @@ -1196,7 +1193,8 @@ static function makeGroupByExpensesPart($options) { } // Remove garbage from the beginning. $group_by_parts = ltrim($group_by_parts, ', '); - $group_by_part = "group by $group_by_parts"; + if ($group_by_parts) + $group_by_part = "group by $group_by_parts"; return $group_by_part; } @@ -1212,18 +1210,23 @@ static function makeConcatPart($options) { break; case 'user': $what_to_concat .= ", ' - ', u.name"; + $fields_part .= ', u.name as user'; break; case 'client': $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + $fields_part .= ', c.name as client'; break; case 'project': $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + $fields_part .= ', p.name as project'; break; case 'task': $what_to_concat .= ", ' - ', coalesce(t.name, 'Null')"; + $fields_part .= ', t.name as task'; break; case 'cf_1': $what_to_concat .= ", ' - ', coalesce(cfo.value, 'Null')"; + $fields_part .= ', cfo.value as cf_1'; break; } switch ($group_by2) { @@ -1232,18 +1235,23 @@ static function makeConcatPart($options) { break; case 'user': $what_to_concat .= ", ' - ', u.name"; + $fields_part .= ', u.name as user'; break; case 'client': $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + $fields_part .= ', c.name as client'; break; case 'project': $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + $fields_part .= ', p.name as project'; break; case 'task': $what_to_concat .= ", ' - ', coalesce(t.name, 'Null')"; + $fields_part .= ', t.name as task'; break; case 'cf_1': $what_to_concat .= ", ' - ', coalesce(cfo.value, 'Null')"; + $fields_part .= ', cfo.value as cf_1'; break; } switch ($group_by3) { @@ -1252,25 +1260,30 @@ static function makeConcatPart($options) { break; case 'user': $what_to_concat .= ", ' - ', u.name"; + $fields_part .= ', u.name as user'; break; case 'client': $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + $fields_part .= ', c.name as client'; break; case 'project': $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + $fields_part .= ', p.name as project'; break; case 'task': $what_to_concat .= ", ' - ', coalesce(t.name, 'Null')"; + $fields_part .= ', t.name as task'; break; case 'cf_1': $what_to_concat .= ", ' - ', coalesce(cfo.value, 'Null')"; + $fields_part .= ', cfo.value as cf_1'; break; } // Remove garbage from both ends. $what_to_concat = trim($what_to_concat, "', -"); $concat_part = "concat($what_to_concat) as group_field"; $concat_part = trim($concat_part, ' -'); - return $concat_part; + return "$concat_part $fields_part"; } // makeConcatPart builds a concatenation part for getSubtotals query (for expense items). @@ -1285,12 +1298,25 @@ static function makeConcatExpensesPart($options) { break; case 'user': $what_to_concat .= ", ' - ', u.name"; + $fields_part .= ', u.name as user'; break; case 'client': $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + $fields_part .= ', c.name as client'; break; case 'project': $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + $fields_part .= ', p.name as project'; + break; + + case 'task': + $what_to_concat .= ", ' - ', 'Null'"; + $fields_part .= ', null as task'; + break; + + case 'cf_1': + $what_to_concat .= ", ' - ', 'Null'"; + $fields_part .= ', null as cf_1'; break; } switch ($group_by2) { @@ -1299,12 +1325,25 @@ static function makeConcatExpensesPart($options) { break; case 'user': $what_to_concat .= ", ' - ', u.name"; + $fields_part .= ', u.name as user'; break; case 'client': $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + $fields_part .= ', c.name as client'; break; case 'project': $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + $fields_part .= ', p.name as project'; + break; + + case 'task': + $what_to_concat .= ", ' - ', 'Null'"; + $fields_part .= ', null as task'; + break; + + case 'cf_1': + $what_to_concat .= ", ' - ', 'Null'"; + $fields_part .= ', null as cf_1'; break; } switch ($group_by3) { @@ -1313,19 +1352,32 @@ static function makeConcatExpensesPart($options) { break; case 'user': $what_to_concat .= ", ' - ', u.name"; + $fields_part .= ', u.name as user'; break; case 'client': $what_to_concat .= ", ' - ', coalesce(c.name, 'Null')"; + $fields_part .= ', c.name as client'; break; case 'project': $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; + $fields_part .= ', p.name as project'; + break; + + case 'task': + $what_to_concat .= ", ' - ', 'Null'"; + $fields_part .= ', null as task'; + break; + + case 'cf_1': + $what_to_concat .= ", ' - ', 'Null'"; + $fields_part .= ', null as cf_1'; break; } - // Remove garbage from both ends. - $what_to_concat = trim($what_to_concat, "', -"); + // Remove garbage from the beginning. + if ($what_to_concat) + $what_to_concat = substr($what_to_concat, 8); $concat_part = "concat($what_to_concat) as group_field"; - $concat_part = trim($concat_part, ' -'); - return $concat_part; + return "$concat_part $fields_part"; } // makeJoinPart builds a left join part for getSubtotals query (for time items). diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c92fd1a92..3cf6d4ae9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if}{/if} - {if $bean->getAttribute('chclient')}{/if}{/if} - {if $bean->getAttribute('chproject')}{/if}{/if} - {if $bean->getAttribute('chtask')}{/if}{/if} - {if $bean->getAttribute('chcf_1')}{/if}{/if} + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + {if $bean->getAttribute('chcf_1')}{/if} {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} @@ -114,11 +114,11 @@ {if $print_subtotals} {/if}{/if} - {if $bean->getAttribute('chclient')}{/if}{/if} - {if $bean->getAttribute('chproject')}{/if}{/if} - {if $bean->getAttribute('chtask')}{/if}{/if} - {if $bean->getAttribute('chcf_1')}{/if}{/if} + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + {if $bean->getAttribute('chcf_1')}{/if} {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} diff --git a/dbinstall.php b/dbinstall.php index 097d2abe5..f6fd0c1b5 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -956,11 +956,13 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11800"]) { + if ($_POST["convert11797to11805"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.00', modified = now() where param_name = 'version_db' and param_value = '1.17.97'"); + setChange("create index log_idx on tt_custom_field_log(log_id)"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.05', modified = now() where param_name = 'version_db' and param_value = '1.18.00'"); } if ($_POST["cleanup"]) { @@ -1006,7 +1008,7 @@ function setChange($sql) {

DB Install

 Anuko Time Tracker 1.18.04.4340 | Copyright © Anuko | +  Anuko Time Tracker 1.18.05.4341 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 55438428c..0c98951f7 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -62,11 +62,11 @@ {if $cur_grouped_by != $prev_grouped_by && !$first_pass}
{$i18n.label.subtotal} - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{if $group_by == 'user'}{$subtotals[$prev_grouped_by]['name']|escape}{if $group_by == 'client'}{$subtotals[$prev_grouped_by]['name']|escape}{if $group_by == 'project'}{$subtotals[$prev_grouped_by]['name']|escape}{if $group_by == 'task'}{$subtotals[$prev_grouped_by]['name']|escape}{if $group_by == 'cf_1'}{$subtotals[$prev_grouped_by]['name']|escape}{$subtotals[$prev_grouped_by]['user']|escape}{$subtotals[$prev_grouped_by]['client']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$subtotals[$prev_grouped_by]['cf_1']|escape}{$subtotals[$prev_grouped_by]['time']}
{$i18n.label.subtotal} - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{if $group_by == 'user'}{$subtotals[$cur_grouped_by]['name']|escape}{if $group_by == 'client'}{$subtotals[$cur_grouped_by]['name']|escape}{if $group_by == 'project'}{$subtotals[$cur_grouped_by]['name']|escape}{if $group_by == 'task'}{$subtotals[$cur_grouped_by]['name']|escape}{if $group_by == 'cf_1'}{$subtotals[$cur_grouped_by]['name']|escape}{$subtotals[$cur_grouped_by]['user']|escape}{$subtotals[$cur_grouped_by]['client']|escape}{$subtotals[$cur_grouped_by]['project']|escape}{$subtotals[$cur_grouped_by]['task']|escape}{$subtotals[$cur_grouped_by]['cf_1']|escape}{$subtotals[$cur_grouped_by]['time']}
-
Create database structure (v1.18.00) + Create database structure (v1.18.05)
(applies only to new installations, do not execute when updating)
@@ -1051,8 +1053,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.00)Update database structure (v1.17.97 to v1.18.05)
diff --git a/mysql.sql b/mysql.sql index 07a2323a1..955f1b29c 100644 --- a/mysql.sql +++ b/mysql.sql @@ -382,6 +382,8 @@ CREATE TABLE `tt_custom_field_log` ( PRIMARY KEY (`id`) ); +create index log_idx on tt_custom_field_log(log_id); + # # Structure for table tt_expense_items. @@ -456,4 +458,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.00', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.05', now()); # TODO: change when structure changes. diff --git a/report.php b/report.php index f6abcc4c6..28e086c4d 100644 --- a/report.php +++ b/report.php @@ -173,6 +173,8 @@ $group_by = $bean->getAttribute('group_by1'); $options = ttReportHelper::getReportOptions($bean); + +$group_by_tag = ttReportHelper::makeGroupByXmlTag($options); $report_items = ttReportHelper::getItems($options); // Store record ids in session in case user wants to act on records such as marking them all paid. if ($request->isGet() && $user->isPluginEnabled('ps')) @@ -201,6 +203,9 @@ } */ $smarty->assign('group_by_header', ttReportHelper::makeGroupByHeader($options)); } + +$smarty->assign('group_by', $group_by_tag); + // Assign variables that are used to alternate color of rows for different dates. $smarty->assign('prev_date', ''); $smarty->assign('cur_date', ''); From 03c03896828d818303c12dfe2e368f5bd9e7dbae Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 1 Nov 2018 19:15:48 +0000 Subject: [PATCH 0251/1848] Improved output of grouped subtotals on reports by including grouped values. --- WEB-INF/lib/ttReportHelper.class.php | 78 ++++++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 85b2c8e9e..11f8841fe 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -453,14 +453,15 @@ static function getSubtotals($options) { $sql_for_expenses = "select $concat_part, null as time"; if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; $sql_for_expenses .= ", sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei $join_part $where $group_by_expenses_part"; -//die($sql_for_expenses); + // Create a combined query. - $combined = "select group_field, sum(time) as time"; + $fields = ttReportHelper::makeCombinedSelectPart($options); + $combined = "select $fields, sum(time) as time"; if ($options['show_work_units']) $combined .= ", sum(units) as units"; - $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field"; + $combined .= ", sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by $fields"; $sql = $combined; } -//die($sql); + // Execute query. $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die($res->getMessage()); @@ -1380,6 +1381,75 @@ static function makeConcatExpensesPart($options) { return "$concat_part $fields_part"; } + // makeCombinedSelectPart builds a list of fields for a combined select on a union for getSubtotals. + // This is used when we include expenses. + static function makeCombinedSelectPart($options) { + $group_by1 = $options['group_by1']; + $group_by2 = $options['group_by2']; + $group_by3 = $options['group_by3']; + + $fields = "group_field"; + + switch ($group_by1) { + case 'user': + $fields .= ', user'; + break; + case 'client': + $fields_part .= ', client'; + break; + case 'project': + $fields .= ', project'; + break; + + case 'task': + $fields .= ', task'; + break; + + case 'cf_1': + $fields .= ', cf_1'; + break; + } + switch ($group_by2) { + case 'user': + $fields .= ', user'; + break; + case 'client': + $fields_part .= ', client'; + break; + case 'project': + $fields .= ', project'; + break; + + case 'task': + $fields .= ', task'; + break; + + case 'cf_1': + $fields .= ', cf_1'; + break; + } + switch ($group_by3) { + case 'user': + $fields .= ', user'; + break; + case 'client': + $fields_part .= ', client'; + break; + case 'project': + $fields .= ', project'; + break; + + case 'task': + $fields .= ', task'; + break; + + case 'cf_1': + $fields .= ', cf_1'; + break; + } + return $fields; + } + // makeJoinPart builds a left join part for getSubtotals query (for time items). static function makeJoinPart($options) { global $custom_fields; // TODO: is it safe to assume the object is there when needed? diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3cf6d4ae9..af9a278a0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.05.4341 | Copyright © Anuko | +  Anuko Time Tracker 1.18.05.4342 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 2fb29ce0672acc8828496861db80f3cac32a49a1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 1 Nov 2018 19:46:45 +0000 Subject: [PATCH 0252/1848] Improved output of pdf reports by including grouped values in subtotals. --- WEB-INF/templates/footer.tpl | 2 +- topdf.php | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index af9a278a0..90e8b3c53 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- '; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { $html .= ''; } if ($bean->getAttribute('chclient')) { $html .= ''; } if ($bean->getAttribute('chproject')) { $html .= ''; } if ($bean->getAttribute('chtask')) { $html .= ''; } if ($bean->getAttribute('chcf_1')) { $html .= ''; } if ($bean->getAttribute('chstart')) $html .= ''; @@ -261,27 +261,27 @@ $html .= ''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { $html .= ''; } if ($bean->getAttribute('chclient')) { $html .= ''; } if ($bean->getAttribute('chproject')) { $html .= ''; } if ($bean->getAttribute('chtask')) { $html .= ''; } if ($bean->getAttribute('chcf_1')) { $html .= ''; } if ($bean->getAttribute('chstart')) $html .= ''; From d31bcc34081a36b3f45c080f3a5cd231ec417fa9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 1 Nov 2018 20:02:24 +0000 Subject: [PATCH 0253/1848] Improved emailed reports by including grouped vaalues in subtotals. --- WEB-INF/lib/ttReportHelper.class.php | 35 +++++++++++----------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 11f8841fe..5dafe95be 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -609,8 +609,8 @@ static function prepareReportBody($options, $comment = null) $isClient = $user->isClient(); $items = ttReportHelper::getItems($options); - $group_by = $options['group_by1']; - if ($group_by && 'no_grouping' != $group_by) + $grouping = ttReportHelper::grouping($options); + if ($grouping) $subtotals = ttReportHelper::getSubtotals($options); $totals = ttReportHelper::getTotals($options); @@ -643,14 +643,7 @@ static function prepareReportBody($options, $comment = null) if ($options['show_totals_only']) { // Totals only report. Output subtotals. - - // Determine group_by header. - if ('cf_1' == $group_by) - $group_by_header = htmlspecialchars($custom_fields->fields[0]['label']); - else { - $key = 'label.'.$group_by; - $group_by_header = $i18n->get($key); - } + $group_by_header = ttReportHelper::makeGroupByHeader($options); $body .= '
 Anuko Time Tracker 1.18.05.4342 | Copyright © Anuko | +  Anuko Time Tracker 1.18.05.4343 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/topdf.php b/topdf.php index 15ac1ee92..e3801d273 100644 --- a/topdf.php +++ b/topdf.php @@ -172,27 +172,27 @@ $html .= ''.$i18n->get('label.subtotal').''; - if ($group_by1 == 'user') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + $html .= htmlspecialchars($subtotals[$prev_grouped_by]['user']); $html .= ''; - if ($group_by1 == 'client') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + $html .= htmlspecialchars($subtotals[$prev_grouped_by]['client']); $html .= ''; - if ($group_by1 == 'project') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + $html .= htmlspecialchars($subtotals[$prev_grouped_by]['project']); $html .= ''; - if ($group_by1 == 'task') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + $html .= htmlspecialchars($subtotals[$prev_grouped_by]['task']); $html .= ''; - if ($group_by1 == 'cf_1') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + $html .= htmlspecialchars($subtotals[$prev_grouped_by]['cf_1']); $html .= ''.$i18n->get('label.subtotal').''; - if ($group_by1 == 'user') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + $html .= htmlspecialchars($subtotals[$prev_grouped_by]['user']); $html .= ''; - if ($group_by1 == 'client') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + $html .= htmlspecialchars($subtotals[$prev_grouped_by]['client']); $html .= ''; - if ($group_by1 == 'project') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + $html .= htmlspecialchars($subtotals[$prev_grouped_by]['project']); $html .= ''; - if ($group_by1 == 'task') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + $html .= htmlspecialchars($subtotals[$prev_grouped_by]['task']); $html .= ''; - if ($group_by1 == 'cf_1') $html .= htmlspecialchars($subtotals[$prev_grouped_by]['name']); + $html .= htmlspecialchars($subtotals[$prev_grouped_by]['cf_1']); $html .= '
'; $body .= ''; @@ -743,7 +736,7 @@ static function prepareReportBody($options, $comment = null) $body .= ''; // Initialize variables to print subtotals. - if ($items && 'no_grouping' != $group_by) { + if ($items && $grouping) { $print_subtotals = true; $first_pass = true; $prev_grouped_by = ''; @@ -765,11 +758,11 @@ static function prepareReportBody($options, $comment = null) $body .= ''; $body .= ''; $subtotal_name = htmlspecialchars($subtotals[$prev_grouped_by]['name']); - if ($canViewReports || $isClient) $body .= ''; - if ($options['show_client']) $body .= ''; - if ($options['show_project']) $body .= ''; - if ($options['show_task']) $body .= ''; - if ($options['show_custom_field_1']) $body .= ''; + if ($canViewReports || $isClient) $body .= ''; + if ($options['show_client']) $body .= ''; + if ($options['show_project']) $body .= ''; + if ($options['show_task']) $body .= ''; + if ($options['show_custom_field_1']) $body .= ''; if ($options['show_start']) $body .= ''; if ($options['show_end']) $body .= ''; if ($options['show_duration']) $body .= ''; @@ -841,11 +834,11 @@ static function prepareReportBody($options, $comment = null) $body .= ''; $body .= ''; $subtotal_name = htmlspecialchars($subtotals[$cur_grouped_by]['name']); - if ($canViewReports || $isClient) $body .= ''; - if ($options['show_client']) $body .= ''; - if ($options['show_project']) $body .= ''; - if ($options['show_task']) $body .= ''; - if ($options['show_custom_field_1']) $body .= ''; + if ($canViewReports || $isClient) $body .= ''; + if ($options['show_client']) $body .= ''; + if ($options['show_project']) $body .= ''; + if ($options['show_task']) $body .= ''; + if ($options['show_custom_field_1']) $body .= ''; if ($options['show_start']) $body .= ''; if ($options['show_end']) $body .= ''; if ($options['show_duration']) $body .= ''; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 90e8b3c53..0b1969132 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
'.$i18n->get('label.subtotal').''.($group_by == 'user' ? $subtotal_name : '').''.($group_by == 'client' ? $subtotal_name : '').''.($group_by == 'project' ? $subtotal_name : '').''.($group_by == 'task' ? $subtotal_name : '').''.($group_by == 'cf_1' ? $subtotal_name : '').''.$subtotals[$prev_grouped_by]['user'].''.$subtotals[$prev_grouped_by]['client'].''.$subtotals[$prev_grouped_by]['project'].''.$subtotals[$prev_grouped_by]['task'].''.$subtotals[$prev_grouped_by]['cf_1'].''.$subtotals[$prev_grouped_by]['time'].'
'.$i18n->get('label.subtotal').''.($group_by == 'user' ? $subtotal_name : '').''.($group_by == 'client' ? $subtotal_name : '').''.($group_by == 'project' ? $subtotal_name : '').''.($group_by == 'task' ? $subtotal_name : '').''.($group_by == 'cf_1' ? $subtotal_name : '').''.$subtotals[$prev_grouped_by]['user'].''.$subtotals[$prev_grouped_by]['client'].''.$subtotals[$prev_grouped_by]['project'].''.$subtotals[$prev_grouped_by]['task'].''.$subtotals[$prev_grouped_by]['cf_1'].''.$subtotals[$cur_grouped_by]['time'].'
-
 Anuko Time Tracker 1.18.05.4343 | Copyright © Anuko | +  Anuko Time Tracker 1.18.05.4344 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a48e5ff4ad629b551f6a94143a5e9d0f235b1953 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 1 Nov 2018 20:48:16 +0000 Subject: [PATCH 0254/1848] Fixed emailing reports grouped by custom field, hopefully. --- WEB-INF/lib/ttReportHelper.class.php | 5 ++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 5dafe95be..3a6a09608 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1445,7 +1445,10 @@ static function makeCombinedSelectPart($options) { // makeJoinPart builds a left join part for getSubtotals query (for time items). static function makeJoinPart($options) { - global $custom_fields; // TODO: is it safe to assume the object is there when needed? + global $user; + if (ttReportHelper::groupingBy('cf_1', $options)) { + $custom_fields = new CustomFields($user->group_id); + } $group_by_fields = ttReportHelper::makeGroupByFieldsPart($options); // TODO: refactor this, perhaps? if (strpos($group_by_fields, 'user') !== false) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0b1969132..ffb9e9c93 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.05.4344 | Copyright © Anuko | +  Anuko Time Tracker 1.18.05.4345 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6a2fb5042be34b6a15a2b57816aadefa661ee2c7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 2 Nov 2018 07:31:22 +0000 Subject: [PATCH 0255/1848] Starting work on subgroups. --- WEB-INF/config.php.dist | 3 +++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 1218f7f65..3f6fdaf33 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -207,3 +207,6 @@ define('AUTH_MODULE', 'db'); // Height in pixels for the note input field in time.php. Defaults to 40. // define('NOTE_INPUT_HEIGHT', 100); + +// A temporary config option while development of subgroup support is ongoing. To be removed later. +// define('SUBGROUP_DEBUG', false); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ffb9e9c93..a14235f23 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.05.4345 | Copyright © Anuko | +  Anuko Time Tracker 1.18.05.4346 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9def341e72ae78b8d0cb96ce425cdfb6824b00b6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 2 Nov 2018 08:34:18 +0000 Subject: [PATCH 0256/1848] Some work in progress on subgroups. --- WEB-INF/lib/ttUser.class.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 65a1f5962..9ce67ac09 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -70,7 +70,7 @@ class ttUser { var $is_client = false; // Whether user is a client as determined by missing 'track_own_time' right. var $minutes_in_unit = 15; // Number of minutes in unit for Work units plugin. var $first_unit_threshold = 0;// Threshold for 1st unit for Work units plugin. - var $unit_totals_only = 0; // Totlas only option for the Work units plugin. + var $unit_totals_only = 0; // Totals only option for the Work units plugin. // Constructor. function __construct($login, $id = null) { @@ -361,6 +361,22 @@ function getUsers($options) { return $user_list; } + // getGroups obtains an array consisting of: + // - A parent group (..) of a currently selected group, if available. + // - A currently selected group (.) represented by $behalf_group_id. + // - All subgroups (only immediate children) of a currently selected group. + function getGroups($options) { + $mdb2 = getConnection(); + + // $sql = 'select id, parent_id, name from tt_groups where org_id = $this->org_id ...'; // TODO: parent_id is now NULL in db, fix this. + // Step 1: Get parent group (sql query). + // Step 2: Get current group from the class. + // Step 3: Get immediate subgroups (sql query). + // Populate an array and return it, + + return false; // Work in progress here... + } + // getUser function is used to manage users in group and returns user details. // At the moment, the function is used for user edits and deletes. function getUser($user_id) { From f066e7ba4d1141bad2f50e802c0911e5f76e8ef0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 2 Nov 2018 12:36:58 +0000 Subject: [PATCH 0257/1848] Started to populate org_id upon group creation. --- WEB-INF/lib/ttGroupHelper.class.php | 2 +- WEB-INF/lib/ttRegistrator.class.php | 14 +++++++++----- WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 6ffa6b21a..d28c30670 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -36,7 +36,7 @@ static function getTopGroups() { $mdb2 = getConnection(); $sql = "select id, name, created, lang from tt_groups". - " where status = 1 and org_id is NULL order by id desc"; + " where status = 1 and org_id is NULL or org_id = id order by id desc"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 6a2142b56..48f4b0aa0 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -137,12 +137,16 @@ function createGroup() { $sql = "insert into tt_groups (name, currency, lang, created, created_ip) values($name, $currency, $lang, $created, $created_ip)"; $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; - if (!is_a($affected, 'PEAR_Error')) { - $group_id = $mdb2->lastInsertID('tt_groups', 'id'); - return $group_id; - } - return false; + $group_id = $mdb2->lastInsertID('tt_groups', 'id'); + + // Update org_id with group_id. + $sql = "update tt_groups set org_id = $group_id where org_id is NULL and id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + return $group_id; } // The createUser creates a user in database as part of registration process. diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 9ce67ac09..3085a0d56 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -365,7 +365,7 @@ function getUsers($options) { // - A parent group (..) of a currently selected group, if available. // - A currently selected group (.) represented by $behalf_group_id. // - All subgroups (only immediate children) of a currently selected group. - function getGroups($options) { + function getGroups() { $mdb2 = getConnection(); // $sql = 'select id, parent_id, name from tt_groups where org_id = $this->org_id ...'; // TODO: parent_id is now NULL in db, fix this. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a14235f23..80c891058 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.05.4346 | Copyright © Anuko | +  Anuko Time Tracker 1.18.06.4347 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 8a0ec8135a1bb4f42c0ae89b7d97e3dfd500aba5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 2 Nov 2018 12:55:44 +0000 Subject: [PATCH 0258/1848] Fixing org_id for existing groups. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 2 ++ mysql.sql | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 80c891058..74ea3c29b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.06.4347 | Copyright © Anuko | +  Anuko Time Tracker 1.18.06.4348 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index f6fd0c1b5..9e71651ef 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -963,6 +963,8 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.18.00', modified = now() where param_name = 'version_db' and param_value = '1.17.97'"); setChange("create index log_idx on tt_custom_field_log(log_id)"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.05', modified = now() where param_name = 'version_db' and param_value = '1.18.00'"); + setChange("update `tt_groups` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.05') set org_id = id where org_id is null"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.06', modified = now() where param_name = 'version_db' and param_value = '1.18.05'"); } if ($_POST["cleanup"]) { diff --git a/mysql.sql b/mysql.sql index 955f1b29c..3c2b786a3 100644 --- a/mysql.sql +++ b/mysql.sql @@ -458,4 +458,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.05', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.06', now()); # TODO: change when structure changes. From 5d2849f60950348fd2b862f40ae98e9fce837528 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 2 Nov 2018 13:23:35 +0000 Subject: [PATCH 0259/1848] Updated ttImportHelper class to populate org_id in newly imported groups. --- WEB-INF/lib/ttImportHelper.class.php | 17 ++++++++++++----- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index d966f8963..6686d40f6 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -474,11 +474,18 @@ private function createGroup($fields) { $sql = 'insert into tt_groups '.$columns.$values; $affected = $mdb2->exec($sql); - if (!is_a($affected, 'PEAR_Error')) { - $group_id = $mdb2->lastInsertID('tt_groups', 'id'); - return $group_id; - } - return false; + if (is_a($affected, 'PEAR_Error')) return false; + + $group_id = $mdb2->lastInsertID('tt_groups', 'id'); + + // Update org_id with group_id. + // NOTE: Both export and import need an additional effort to properly operate on subgroups. + // Currently we are importing one group only, which becomes a top level group. + $sql = "update tt_groups set org_id = $group_id where org_id is NULL and id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + return $group_id; } // insertMonthlyQuota - a helper function to insert a monthly quota. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 74ea3c29b..878b85eea 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.06.4348 | Copyright © Anuko | +  Anuko Time Tracker 1.18.06.4349 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 2ced7cd9d8dc6bb3225b9f2ec957cbfb1d7af285 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 2 Nov 2018 14:42:01 +0000 Subject: [PATCH 0260/1848] Wrote getGroups function for ttUser class. --- WEB-INF/lib/ttUser.class.php | 47 ++++++++++++++++++++++++++++++------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 3085a0d56..e7fa3fa0b 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -32,6 +32,7 @@ class ttUser { var $login = null; // User login. var $name = null; // User name. var $id = null; // User id. + var $org_id = null; // Organization id. var $group_id = null; // Group id. var $role_id = null; // Role id. var $role_name = null; // Role name. @@ -81,8 +82,8 @@ function __construct($login, $id = null) { $mdb2 = getConnection(); - $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id, u.email, g.name as group_name, - g.currency, g.lang, g.decimal_mark, g.date_format, g.time_format, g.week_start, + $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id, u.email, + g.org_id, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format, g.time_format, g.week_start, g.tracking_mode, g.project_required, g.task_required, g.record_type, g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.workday_minutes, g.custom_logo FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; @@ -102,6 +103,7 @@ function __construct($login, $id = null) { $this->login = $val['login']; $this->name = $val['name']; $this->id = $val['id']; + $this->org_id = $val['org_id']; $this->group_id = $val['group_id']; $this->role_id = $val['role_id']; $this->role_name = $val['role_name']; @@ -368,13 +370,42 @@ function getUsers($options) { function getGroups() { $mdb2 = getConnection(); - // $sql = 'select id, parent_id, name from tt_groups where org_id = $this->org_id ...'; // TODO: parent_id is now NULL in db, fix this. - // Step 1: Get parent group (sql query). - // Step 2: Get current group from the class. - // Step 3: Get immediate subgroups (sql query). - // Populate an array and return it, + $selected_group_id = ($this->behalf_group_id ? $this->behalf_group_id : $this->group_id); + + // Start with parent group. + if ($selected_group_id != $this->org_id) { + // We are in one of the subgroups, and a parent exists. + // Get parent group info. + $sql = "select parent_id from tt_groups where org_id = $this->org_id and id = $selected_group_id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + $parent_id = $val['parent_id']; + if ($parent_id) { + // Get parent group name. + $sql = "select name from tt_groups where org_id = $this->org_id and id = $parent_id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + $groups[] = array('id'=>$parent_id,'name'=>$val['name']); + } + } + } + } - return false; // Work in progress here... + // Add current group. + $selected_group_name = ($this->behalf_group_id ? $this->behalf_group : $this->group); + $groups[] = array('id'=>$selected_group_id,'name'=>$selected_group_name); + + // Add subgroups. + $sql = "select id, name from tt_groups where org_id = $this->org_id and parent_id = $selected_group_id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $groups[] = array('id'=>$val['id'],'name'=>$val['name']); + } + } + return $groups; } // getUser function is used to manage users in group and returns user details. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 878b85eea..e635a9777 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.06.4349 | Copyright © Anuko | +  Anuko Time Tracker 1.18.06.4350 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9045840bac7c2e7132555c199495b0477d07bc61 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 2 Nov 2018 15:17:34 +0000 Subject: [PATCH 0261/1848] Added label.group string into translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + 30 files changed, 33 insertions(+) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 42a9ea858..64a3b86a6 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -163,6 +163,7 @@ 'label.user' => 'Usuari', 'label.users' => 'Usuaris', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Client', 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 112538618..1cc0734d1 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -167,6 +167,7 @@ 'label.user' => 'Uživatel', 'label.users' => 'Uživatelů', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Zákazník', 'label.clients' => 'Zákazníci', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 8f6e8f4bb..280c9945c 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -150,6 +150,7 @@ 'label.user' => 'Bruger', 'label.users' => 'Brugere', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Klient', 'label.clients' => 'Klienter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index e51ec1248..48d5dcfaa 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -141,6 +141,8 @@ 'label.end_date' => 'Enddatum', 'label.user' => 'Benutzer', 'label.users' => 'Personen', +// TODO: translate the following. +// 'label.group' => 'Group', 'label.roles' => 'Rollen', 'label.client' => 'Kunde', 'label.clients' => 'Kunden', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 3c04d5d74..a28c87cfa 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -140,6 +140,7 @@ 'label.end_date' => 'End date', 'label.user' => 'User', 'label.users' => 'Users', +'label.group' => 'Group', 'label.roles' => 'Roles', 'label.client' => 'Client', 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 72ef4fdf4..28dbb500b 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -162,6 +162,7 @@ 'label.user' => 'Usuario', // TODO: translate the following. // 'label.users' => 'Users', +// 'label.group' => 'Group', // 'label.roles' => 'Roles', // 'label.client' => 'Client', // 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 68b238001..854021632 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -165,6 +165,7 @@ 'label.user' => 'Kasutaja', 'label.users' => 'Kasutajad', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Klient', 'label.clients' => 'Kliendid', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index a728ba862..d220c13d8 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -158,6 +158,7 @@ 'label.user' => 'کاربر', 'label.users' => 'کاربران', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'مشتری', 'label.clients' => 'مشتریان', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index f9299b205..1e4b86a63 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -152,6 +152,7 @@ 'label.user' => 'Käyttäjä', 'label.users' => 'Käyttäjät', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Asiakas', 'label.clients' => 'Asiakkaat', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 5213715ea..1e64e96d2 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -149,6 +149,7 @@ 'label.user' => 'Utilisateur', 'label.users' => 'Utilisateurs', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Client', 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 604456708..180401534 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -142,6 +142,8 @@ 'label.end_date' => 'Ημερομηνία λήξης', 'label.user' => 'Χρήστης', 'label.users' => 'Χρήστες', +// TODO: translate the following. +// 'label.group' => 'Group', 'label.roles' => 'Ρόλους', 'label.client' => 'Πελάτης', 'label.clients' => 'Πελάτες', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index ea42550d7..a44d82e50 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -168,6 +168,7 @@ 'label.user' => 'משתמש', 'label.users' => 'משתמשים', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'לקוח', 'label.clients' => 'לקוחות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 5712426cd..9e59b544c 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -165,6 +165,7 @@ // TODO: translate the following. // 'label.user' => 'User', // 'label.users' => 'Users', +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Ügyfél', 'label.clients' => 'Ügyfelek', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index d7b44f8ac..ea2b25140 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -147,6 +147,7 @@ 'label.user' => 'Utente', 'label.users' => 'Utenti', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Cliente', 'label.clients' => 'Clienti', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 7f9ee0587..23afc5d99 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -168,6 +168,7 @@ 'label.user' => 'ユーザー', 'label.users' => 'ユーザー', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'クライアント', 'label.clients' => 'クライアント', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 862384d37..6e0f59bdd 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -167,6 +167,7 @@ 'label.user' => '사용자', 'label.users' => '사용자', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => '클라이언트', 'label.clients' => '클라이언트', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 5225d6763..b1f76af77 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -139,6 +139,8 @@ 'label.end_date' => 'Einddatum', 'label.user' => 'Medewerker', 'label.users' => 'Medewerkers', +// TODO: translate the following. +// 'label.group' => 'Group', 'label.roles' => 'Rollen', 'label.client' => 'Klant', 'label.clients' => 'Klanten', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index e24f3470b..07026ae57 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -168,6 +168,7 @@ 'label.user' => 'Bruker', 'label.users' => 'Brukere', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Klient', 'label.clients' => 'Klienter', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 1e77cfbb7..f88888fc3 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -154,6 +154,7 @@ 'label.user' => 'Użytkownik', 'label.users' => 'Użytkownicy', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Klient', 'label.clients' => 'Klienci', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index ba5d6f826..79370ec62 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -151,6 +151,7 @@ 'label.user' => 'Usuário', 'label.users' => 'Usuários', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Cliente', 'label.clients' => 'Clientes', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index c5c906923..c9b24b347 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -159,6 +159,7 @@ 'label.user' => 'Usuário', 'label.users' => 'Usuários', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', // 'label.client' => 'Client', // 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index bbc412fb5..223415522 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -168,6 +168,7 @@ 'label.user' => 'Utilizator', 'label.users' => 'Utilizatori', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Client', 'label.clients' => 'Clienti', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3a79929dc..4a5dbd629 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -139,6 +139,7 @@ 'label.end_date' => 'Конечная дата', 'label.user' => 'Пользователь', 'label.users' => 'Сотрудники', +'label.group' => 'Группа', 'label.roles' => 'Роли', 'label.client' => 'Клиент', 'label.clients' => 'Клиенты', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d48987320..13992fe8b 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -159,6 +159,7 @@ 'label.user' => 'Používateľ', 'label.users' => 'Používatelia', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Klient', 'label.clients' => 'Klienti', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 8985874c7..df5ddf52a 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -157,6 +157,7 @@ // 'label.end_date' => 'End date', // 'label.user' => 'User', // 'label.users' => 'Users', +// 'label.group' => 'Group', // 'label.roles' => 'Roles', // 'label.client' => 'Client', // 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 19027adda..a35014c01 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -151,6 +151,7 @@ 'label.user' => 'Korisnik', 'label.users' => 'Korisnici', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Klijent', 'label.clients' => 'Klijenti', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 9472db288..fb4289a81 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -147,6 +147,7 @@ 'label.user' => 'Användare', 'label.users' => 'Användare', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Kund', 'label.clients' => 'Kunder', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 9dab38b1b..4b167e882 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -173,6 +173,7 @@ 'label.user' => 'Kullanıcı', 'label.users' => 'Kullanıcılar', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => 'Müşteri', 'label.clients' => 'Müşteriler', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 60fdeed1e..2d55378f9 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -158,6 +158,7 @@ 'label.user' => '用户', 'label.users' => '用户', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => '客户', 'label.clients' => '客户', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 1c794d38b..74d379fc3 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -165,6 +165,7 @@ 'label.user' => '用戶', 'label.users' => '用戶', // TODO: translate the following. +// 'label.group' => 'Group', // 'label.roles' => 'Roles', 'label.client' => '客戶', 'label.clients' => '客戶', From 948617a6a0f129ba4090934ee8f544009dbcd935 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 2 Nov 2018 17:36:47 +0000 Subject: [PATCH 0262/1848] A bit more work in progress on subgroups. --- WEB-INF/lib/ttGroupHelper.class.php | 14 +++++++++++++ WEB-INF/lib/ttUser.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time.tpl | 6 ++++++ time.php | 31 +++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index d28c30670..22362b5b9 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -48,4 +48,18 @@ static function getTopGroups() { } return false; } + + // The getGroupName function returns group name. + static function getGroupName($group_id) { + $mdb2 = getConnection(); + + $sql = "select name from tt_groups where id = $group_id and (status = 1 or status = 0)"; + $res = $mdb2->query($sql); + + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + return $val['name']; + } + return false; + } } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index e7fa3fa0b..21cd19aa7 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -155,7 +155,7 @@ function __construct($login, $id = null) { // Set "on behalf" id and name (group). if (isset($_SESSION['behalf_group_id'])) { $this->behalf_group_id = $_SESSION['behalf_group_id']; - $this->behalf_group = $_SESSION['behalf_group']; + $this->behalf_group = $_SESSION['behalf_group_name']; } } } @@ -371,6 +371,7 @@ function getGroups() { $mdb2 = getConnection(); $selected_group_id = ($this->behalf_group_id ? $this->behalf_group_id : $this->group_id); + $selected_group_name = ($this->behalf_group_id ? $this->behalf_group : $this->group); // Start with parent group. if ($selected_group_id != $this->org_id) { @@ -394,7 +395,6 @@ function getGroups() { } // Add current group. - $selected_group_name = ($this->behalf_group_id ? $this->behalf_group : $this->group); $groups[] = array('id'=>$selected_group_id,'name'=>$selected_group_name); // Add subgroups. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e635a9777..3f32ac037 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.06.4350 | Copyright © Anuko | +  Anuko Time Tracker 1.18.06.4351 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index f532be424..0e05f05bc 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -18,6 +18,12 @@
+{if $on_behalf_group_control} + + + + +{/if} {if $on_behalf_control} diff --git a/time.php b/time.php index 98f6bbaf6..5307d8b2a 100644 --- a/time.php +++ b/time.php @@ -29,6 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('ttUserHelper'); +import('ttGroupHelper'); import('ttTeamHelper'); import('ttClientHelper'); import('ttTimeHelper'); @@ -95,6 +96,7 @@ $cl_billable = $_SESSION['billable']; } $on_behalf_id = $request->getParameter('onBehalfUser', (isset($_SESSION['behalf_id'])? $_SESSION['behalf_id'] : $user->id)); +$on_behalf_group_id = $request->getParameter('onBehalfGroup', (isset($_SESSION['behalf_group_id'])? $_SESSION['behalf_group_id'] : $user->group_id)); $cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); $_SESSION['client'] = $cl_client; $cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); @@ -105,6 +107,22 @@ // Elements of timeRecordForm. $form = new Form('timeRecordForm'); +if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { +if ($user->can('manage_subgroups')) { + $groups = $user->getGroups(); + if (count($groups) > 1) { + $form->addInput(array('type'=>'combobox', + 'onchange'=>'this.form.submit();', + 'name'=>'onBehalfGroup', + 'style'=>'width: 250px;', + 'value'=>$on_behalf_group_id, + 'data'=>$groups, + 'datakeys'=>array('id','name'))); + $smarty->assign('on_behalf_group_control', 1); + } +} +} // SUBGROUP_DEBUG + if ($user->can('track_time')) { if ($user->can('track_own_time')) $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_self'=>true,'self_first'=>true); @@ -347,6 +365,19 @@ exit(); } } + elseif ($request->getParameter('onBehalfGroup')) { + if($user->can('manage_subgroups')) { + unset($_SESSION['behalf_group_id']); + unset($_SESSION['behalf_group_name']); + + if($on_behalf_group_id != $user->group_id) { + $_SESSION['behalf_group_id'] = $on_behalf_group_id; + $_SESSION['behalf_group_name'] = ttGroupHelper::getGroupName($on_behalf_group_id); + } + header('Location: time.php'); + exit(); + } + } elseif ($request->getParameter('onBehalfUser')) { if($user->can('track_time')) { unset($_SESSION['behalf_id']); From b4be5795ddbcef63b4b6fffb200c3dfc3ffcb530 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 2 Nov 2018 21:47:41 +0000 Subject: [PATCH 0263/1848] More work in progress on subgroups. --- WEB-INF/lib/ttRegistrator.class.php | 4 ++-- WEB-INF/lib/ttUserHelper.class.php | 5 +++-- dbinstall.php | 5 ++++- mysql.sql | 5 +++-- user_add.php | 3 ++- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 48f4b0aa0..b3551dad6 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -159,9 +159,9 @@ function createUser() { $email = $mdb2->quote($this->email); $created = 'now()'; $created_ip = $mdb2->quote($_SERVER['REMOTE_ADDR']); - $values = "values($login, $password, $name, $this->group_id, $this->role_id, $email, $created, $created_ip)"; + $values = "values($login, $password, $name, $this->group_id, $this->group_id, $this->role_id, $email, $created, $created_ip)"; - $sql = 'insert into tt_users (login, password, name, group_id, role_id, email, created, created_ip) '.$values; + $sql = 'insert into tt_users (login, password, name, group_id, org_id, role_id, email, created, created_ip) '.$values; $affected = $mdb2->exec($sql); if (!is_a($affected, 'PEAR_Error')) { $user_id = $mdb2->lastInsertID('tt_users', 'id'); diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 521bc8b7a..28175080f 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -102,6 +102,7 @@ static function insert($fields, $hash = true) { $password = 'md5('.$password.')'; $email = isset($fields['email']) ? $fields['email'] : ''; $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; $rate = str_replace(',', '.', isset($fields['rate']) ? $fields['rate'] : 0); if($rate == '') $rate = 0; @@ -112,9 +113,9 @@ static function insert($fields, $hash = true) { $created_ip_v = ', '.$mdb2->quote($_SERVER['REMOTE_ADDR']); $created_by_v = ', '.$mdb2->quote($user->id); - $sql = "insert into tt_users (name, login, password, group_id, role_id, client_id, rate, email, created, created_ip, created_by $status_f) values (". + $sql = "insert into tt_users (name, login, password, group_id, org_id, role_id, client_id, rate, email, created, created_ip, created_by $status_f) values (". $mdb2->quote($fields['name']).", ".$mdb2->quote($fields['login']). - ", $password, $group_id, ".$mdb2->quote($fields['role_id']).", ".$mdb2->quote($fields['client_id']).", $rate, ".$mdb2->quote($email).", now() $created_ip_v $created_by_v $status_v)"; + ", $password, $group_id, $org_id, ".$mdb2->quote($fields['role_id']).", ".$mdb2->quote($fields['client_id']).", $rate, ".$mdb2->quote($email).", now() $created_ip_v $created_by_v $status_v)"; $affected = $mdb2->exec($sql); // Now deal with project assignment. diff --git a/dbinstall.php b/dbinstall.php index 9e71651ef..5baff57e6 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -963,8 +963,11 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.18.00', modified = now() where param_name = 'version_db' and param_value = '1.17.97'"); setChange("create index log_idx on tt_custom_field_log(log_id)"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.05', modified = now() where param_name = 'version_db' and param_value = '1.18.00'"); - setChange("update `tt_groups` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.05') set org_id = id where org_id is null"); + setChange("UPDATE `tt_groups` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.05') set org_id = id where org_id is null"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.06', modified = now() where param_name = 'version_db' and param_value = '1.18.05'"); + setChange("ALTER TABLE `tt_users` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.06') set org_id = group_id where org_id is null"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.07', modified = now() where param_name = 'version_db' and param_value = '1.18.06'"); } if ($_POST["cleanup"]) { diff --git a/mysql.sql b/mysql.sql index 3c2b786a3..bfa26a0da 100644 --- a/mysql.sql +++ b/mysql.sql @@ -85,6 +85,7 @@ CREATE TABLE `tt_users` ( `password` varchar(50) default NULL, # password hash `name` varchar(100) default NULL, # user name `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id `role_id` int(11) default NULL, # role id `client_id` int(11) default NULL, # client id for "client" user role `rate` float(6,2) NOT NULL default '0.00', # default hourly rate @@ -104,7 +105,7 @@ CREATE TABLE `tt_users` ( # Create an index that guarantees unique active and inactive logins. create unique index login_idx on tt_users(login, status); -# Create admin account with password 'secret'. Admin is a superuser, who can create groupd. +# Create admin account with password 'secret'. Admin is a superuser who can create groups. DELETE from `tt_users` WHERE login = 'admin'; INSERT INTO `tt_users` (`login`, `password`, `name`, `group_id`, `role_id`) VALUES ('admin', md5('secret'), 'Admin', '0', (select id from tt_roles where rank = 1024)); @@ -458,4 +459,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.06', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.07', now()); # TODO: change when structure changes. diff --git a/user_add.php b/user_add.php index 1ed0cb725..ac2d8c4e4 100644 --- a/user_add.php +++ b/user_add.php @@ -150,7 +150,8 @@ function render(&$table, $value, $row, $column, $selected = false) { 'login' => $cl_login, 'password' => $cl_password1, 'rate' => $cl_rate, - 'group_id' => $user->group_id, + 'group_id' => $user->group_id, // TODO: this needs to be fixed for on-behalf group work. + 'org_id' => $user->org_id, 'role_id' => $cl_role_id, 'client_id' => $cl_client_id, 'projects' => $assigned_projects, From 0bf91be4d6ee52adaf09a74d729c7a34cf012de7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 3 Nov 2018 12:15:12 +0000 Subject: [PATCH 0264/1848] Some more work in progress on subgroups. --- WEB-INF/lib/ttUser.class.php | 17 +++++++++-------- WEB-INF/templates/footer.tpl | 2 +- time.php | 6 ++++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 21cd19aa7..003cf0fe3 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -41,7 +41,8 @@ class ttUser { var $behalf_id = null; // User id, on behalf of whom we are working. var $behalf_group_id = null; // Group id, on behalf of which we are working. var $behalf_name = null; // User name, on behalf of whom we are working. - var $behalf_group = null; // Group name, on behalf of which we are working. + var $group_name = null; // Group name. + var $behalf_group_name = null;// Group name, on behalf of which we are working. var $email = null; // User email. var $lang = null; // Language. var $decimal_mark = null; // Decimal separator. @@ -63,7 +64,6 @@ class ttUser { var $currency = null; // Currency. var $plugins = null; // Comma-separated list of enabled plugins. var $config = null; // Comma-separated list of miscellaneous config options. - var $group = null; // Group name. var $custom_logo = 0; // Whether to use a custom logo for group. var $lock_spec = null; // Cron specification for record locking. var $workday_minutes = 480; // Number of work minutes in a regular day. @@ -124,7 +124,7 @@ function __construct($login, $id = null) { $this->bcc_email = $val['bcc_email']; $this->allow_ip = $val['allow_ip']; $this->password_complexity = $val['password_complexity']; - $this->group = $val['group_name']; + $this->group_name = $val['group_name']; $this->currency = $val['currency']; $this->plugins = $val['plugins']; $this->lock_spec = $val['lock_spec']; @@ -155,7 +155,7 @@ function __construct($login, $id = null) { // Set "on behalf" id and name (group). if (isset($_SESSION['behalf_group_id'])) { $this->behalf_group_id = $_SESSION['behalf_group_id']; - $this->behalf_group = $_SESSION['behalf_group_name']; + $this->behalf_group_name = $_SESSION['behalf_group_name']; } } } @@ -309,6 +309,7 @@ function getUsers($options) { $skipClients = !isset($options['include_clients']); $includeSelf = isset($options['include_self']); + $group_id = isset($options['group_id']) ? $options['group_id'] : $this->group_id; $select_part = 'select u.id, u.name'; if (isset($options['include_login'])) $select_part .= ', u.login'; @@ -321,7 +322,7 @@ function getUsers($options) { if (isset($options['max_rank']) || $skipClients || isset($options['include_role'])) $left_joins .= ' left join tt_roles r on (u.role_id = r.id)'; - $where_part = " where u.group_id = $this->group_id"; + $where_part = " where u.org_id = $this->org_id and u.group_id = $group_id"; if (isset($options['status'])) $where_part .= ' and u.status = '.(int)$options['status']; else @@ -371,11 +372,11 @@ function getGroups() { $mdb2 = getConnection(); $selected_group_id = ($this->behalf_group_id ? $this->behalf_group_id : $this->group_id); - $selected_group_name = ($this->behalf_group_id ? $this->behalf_group : $this->group); + $selected_group_name = ($this->behalf_group_id ? $this->behalf_group_name : $this->group_name); // Start with parent group. - if ($selected_group_id != $this->org_id) { - // We are in one of the subgroups, and a parent exists. + if ($selected_group_id != $this->group_id) { + // We are in one of subgroups, and a parent exists. // Get parent group info. $sql = "select parent_id from tt_groups where org_id = $this->org_id and id = $selected_group_id"; $res = $mdb2->query($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3f32ac037..d9c3e334e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.group}:{$forms.timeRecordForm.onBehalfGroup.control}
{$i18n.label.user}:
-
 Anuko Time Tracker 1.18.06.4351 | Copyright © Anuko | +  Anuko Time Tracker 1.18.06.4352 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/time.php b/time.php index 5307d8b2a..da816362d 100644 --- a/time.php +++ b/time.php @@ -124,10 +124,12 @@ } // SUBGROUP_DEBUG if ($user->can('track_time')) { + // Determine max rank. + $max_rank = $on_behalf_group_id == $user->group_id ? $user->rank-1 : 512; // TODO: stop using magic numbers. if ($user->can('track_own_time')) - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_self'=>true,'self_first'=>true); + $options = array('group_id'=>$on_behalf_group_id,'status'=>ACTIVE,'max_rank'=>$max_rank,'include_self'=>true,'self_first'=>true); else - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1); + $options = array('group_id'=>$on_behalf_group_id,'status'=>ACTIVE,'max_rank'=>$max_rank); $user_list = $user->getUsers($options); if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', From b134135b685422ddcdc2d6856972c60ea15f661f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 3 Nov 2018 15:34:15 +0000 Subject: [PATCH 0265/1848] Work in progress on subgroups. Made user list population more robust. --- WEB-INF/lib/ttGroupHelper.class.php | 16 +++++++++++++ WEB-INF/lib/ttUser.class.php | 35 +++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- initialize.php | 1 + time.php | 7 +++--- 5 files changed, 56 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 22362b5b9..3fb01c604 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -62,4 +62,20 @@ static function getGroupName($group_id) { } return false; } + + // The getParentGroup determines a parent group for a given group. + static function getParentGroup($group_id) { + global $user; + + $mdb2 = getConnection(); + + $sql = "select parent_id from tt_groups where id = $group_id and org_id = $user->org_id and status = 1"; + $res = $mdb2->query($sql); + + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + return $val['parent_id']; + } + return false; + } } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 003cf0fe3..b7ea34f07 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -559,4 +559,39 @@ function enablePlugin($plugin, $enable = true) return true; } + + // isSubgroupValid determines if a subgroup is valid for user. + // A subgroup is valid if: + // - user can manage_subgroups; + // - subgroup is either a direct child of user group, or "on the path" + // to it (grand-child, etc.). + function isSubgroupValid($subgroup_id) { + if (!$this->can('manage_subgroups')) return false; // User cannot manage subgroups. + + $current_group_id = $subgroup_id; + while ($parent_group_id = ttGroupHelper::getParentGroup($current_group_id)) { + if ($parent_group_id == $this->group_id) { + return true; // Found it. + } + $current_group_id = $parent_group_id; + } + return false; + } + + // getMaxRankForGroup determines effective user rank for a user in a given group. + // For home group it is the existing user rank (as per role) minus 1. + // For subgroups, if user can "manage_subgroups", it is MAX_RANK. + function getMaxRankForGroup($group_id) { + + $max_rank = 0; // Start safely. + if ($this->group_id == $group_id) { + $max_rank = $this->rank - 1; + return $max_rank; + } + + if ($this->isSubgroupValid($group_id)) + $max_rank = MAX_RANK; + + return $max_rank; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d9c3e334e..fda4c01ad 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.06.4352 | Copyright © Anuko | +  Anuko Time Tracker 1.18.06.4353 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/initialize.php b/initialize.php index 795408507..241d72334 100644 --- a/initialize.php +++ b/initialize.php @@ -42,6 +42,7 @@ define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); // Date format for database and URI parameters. define('DB_DATEFORMAT', '%Y-%m-%d'); +define('MAX_RANK', 512); // Max user rank. require_once(LIBRARY_DIR.'/common.lib.php'); diff --git a/time.php b/time.php index da816362d..6d62fb691 100644 --- a/time.php +++ b/time.php @@ -124,12 +124,11 @@ } // SUBGROUP_DEBUG if ($user->can('track_time')) { - // Determine max rank. - $max_rank = $on_behalf_group_id == $user->group_id ? $user->rank-1 : 512; // TODO: stop using magic numbers. + $rank = $user->getMaxRankForGroup($on_behalf_group_id); if ($user->can('track_own_time')) - $options = array('group_id'=>$on_behalf_group_id,'status'=>ACTIVE,'max_rank'=>$max_rank,'include_self'=>true,'self_first'=>true); + $options = array('group_id'=>$on_behalf_group_id,'status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); else - $options = array('group_id'=>$on_behalf_group_id,'status'=>ACTIVE,'max_rank'=>$max_rank); + $options = array('group_id'=>$on_behalf_group_id,'status'=>ACTIVE,'max_rank'=>$rank); $user_list = $user->getUsers($options); if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', From 5e861d92d6d758ba4888e35109cc6df4ab5e2df1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 3 Nov 2018 20:56:08 +0000 Subject: [PATCH 0266/1848] More progress on subgroups, mostly about setting on behalf values properly. --- WEB-INF/lib/ttUser.class.php | 38 +++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- reports.php | 2 +- time.php | 72 +++++++++++++++++++++++++----------- 4 files changed, 84 insertions(+), 30 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index b7ea34f07..469345b75 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -429,13 +429,32 @@ function getUser($user_id) { } // checkBehalfId checks whether behalf_id is appropriate. - // On behalf user must be active and have lower rank. + // On behalf user must be active and have lower rank if the user is from home group, + // otherwise: + // - subgroup must ve valid; + // - user should be a member of it. function checkBehalfId() { - $options = array('status'=>ACTIVE,'max_rank'=>$this->rank-1); - $users = $this->getUsers($options); - foreach($users as $one_user) { - if ($one_user['id'] == $this->behalf_id) - return true; + if (!$this->behalf_group_id) { + // Checking user from home group. + $options = array('status'=>ACTIVE,'max_rank'=>$this->rank-1); + $users = $this->getUsers($options); + foreach($users as $one_user) { + if ($one_user['id'] == $this->behalf_id) + return true; + } + } else { + // Checking user from a subgroup. + $group_id = $this->behalf_group_id; + if (!$this->isSubgroupValid($group_id)) + return false; + + // So far, so good. Check user now. + $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>MAX_RANK); + $users = $this->getUsers($options); + foreach($users as $one_user) { + if ($one_user['id'] == $this->behalf_id) + return true; + } } return false; } @@ -446,8 +465,13 @@ function checkBehalfId() { // Needed for situations when user does not have do_own_something right. // Example: has view_charts but does not have view_own_charts. // In this case we still allow access to charts, but set behalf_id to someone else. + // Another example: working in a subgroup on behalf of someone else. function adjustBehalfId() { - $options = array('status'=>ACTIVE,'max_rank'=>$this->rank-1); + $group_id = $this->behalf_group_id ? $this->behalf_group_id : $this->group_id; + $rank = $this->getMaxRankForGroup($group_id); + + // Adjust to first found user in group. + $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank); $users = $this->getUsers($options); foreach($users as $one_user) { // Fake loop to access first element. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fda4c01ad..f29129e59 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.06.4353 | Copyright © Anuko | +  Anuko Time Tracker 1.18.06.4354 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 31028f2f2..6a0687e60 100644 --- a/reports.php +++ b/reports.php @@ -149,7 +149,7 @@ // Prepare user and assigned projects arrays. if ($user->can('view_reports') || $user->can('view_all_reports')) { $max_rank = $user->rank-1; - if ($user->can('view_all_reports')) $max_rank = 512; + if ($user->can('view_all_reports')) $max_rank = MAX_RANK; if ($user->can('view_own_reports')) $options = array('max_rank'=>$max_rank,'include_self'=>true); else diff --git a/time.php b/time.php index 6d62fb691..258f15c19 100644 --- a/time.php +++ b/time.php @@ -366,31 +366,61 @@ exit(); } } - elseif ($request->getParameter('onBehalfGroup')) { - if($user->can('manage_subgroups')) { - unset($_SESSION['behalf_group_id']); - unset($_SESSION['behalf_group_name']); - - if($on_behalf_group_id != $user->group_id) { - $_SESSION['behalf_group_id'] = $on_behalf_group_id; - $_SESSION['behalf_group_name'] = ttGroupHelper::getGroupName($on_behalf_group_id); + elseif ($request->getParameter('onBehalfUser') || $request->getParameter('onBehalfGroup')) { + // User changed either on behalf user or group. + // TODO: Organize this code into a separate function. + + // We get here if one of the dropdowns changed. Handle these 2 situations differently. + // 1) User changed. Determine if user changed. Then do exactly as before. + // + // Group changed. Determine if group changed. + // Adjust group info. + // Adjust user info to first user in group (or self if we are in home group now). + // + // Determine if user was changed. + if ($request->getParameter('onBehalfUser')) { + $request_user_id = $request->getParameter('onBehalfUser'); + $session_user_id = $_SESSION['behalf_id']; + $user_changed = !(($session_user_id == null && ($user->id == $request_user_id)) + || ($session_user_id != null && ($request_user_id == $session_user_id))); + if ($user_changed && $user->can('track_time')) { + unset($_SESSION['behalf_id']); + unset($_SESSION['behalf_name']); + + if($request_user_id != $user->id) { + $_SESSION['behalf_id'] = $request_user_id; + $_SESSION['behalf_name'] = ttUserHelper::getUserName($request_user_id); + } } - header('Location: time.php'); - exit(); } - } - elseif ($request->getParameter('onBehalfUser')) { - if($user->can('track_time')) { - unset($_SESSION['behalf_id']); - unset($_SESSION['behalf_name']); - - if($on_behalf_id != $user->id) { - $_SESSION['behalf_id'] = $on_behalf_id; - $_SESSION['behalf_name'] = ttUserHelper::getUserName($on_behalf_id); + + if ($request->getParameter('onBehalfGroup')) { + // Determine if group was changed. + $request_group_id = $request->getParameter('onBehalfGroup'); + $session_group_id = $_SESSION['behalf_group_id']; + $group_changed = !(($session_group_id == null && ($user->group_id == $request_group_id)) + || ($session_group_id != null && ($request_group_id == $session_group_id))); + + if ($group_changed && $user->can('manage_subgroups')) { + unset($_SESSION['behalf_group_id']); + unset($_SESSION['behalf_group_name']); + if ($request_group_id == $user->group_id) + $user->behalf_group_id = null; + + if (($request_group_id != $user->group_id) && $user->isSubgroupValid($request_group_id)) { + $_SESSION['behalf_group_id'] = $request_group_id; + $_SESSION['behalf_group_name'] = ttGroupHelper::getGroupName($request_group_id); + $user->behalf_group_id = $request_group_id; + } + + unset($_SESSION['behalf_id']); + unset($_SESSION['behalf_name']); + if ($request_group_id != $user->group_id) + $user->adjustBehalfId(); } - header('Location: time.php'); - exit(); } + header('Location: time.php'); + exit(); } } // isPost From 2d4eeda71b7c65a7af5359cb1ec2f29537d43d3a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 3 Nov 2018 22:10:35 +0000 Subject: [PATCH 0267/1848] Fixed ttUser::getAssignedProjects to obtain projects in subgroups. --- WEB-INF/lib/ttUser.class.php | 3 ++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 469345b75..6bac7cb46 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -192,10 +192,11 @@ function getAssignedProjects() $result = array(); $mdb2 = getConnection(); + $group_id = $this->behalf_group_id ? $this->behalf_group_id : $this->group_id; // Do a query with inner join to get assigned projects. $sql = "select p.id, p.name, p.description, p.tasks, upb.rate from tt_projects p inner join tt_user_project_binds upb on (upb.user_id = ".$this->getActiveUser()." and upb.project_id = p.id and upb.status = 1) - where p.group_id = $this->group_id and p.status = 1 order by p.name"; + where p.group_id = $group_id and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f29129e59..438d7d5c4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.06.4354 | Copyright © Anuko | +  Anuko Time Tracker 1.18.06.4355 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6b65ed469a258f8ece8bafa26379fdf546c23bc7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 4 Nov 2018 12:13:01 +0000 Subject: [PATCH 0268/1848] Fixed ttReportHelper::groupingBy function. --- WEB-INF/lib/ttReportHelper.class.php | 20 +++++++++----------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 3a6a09608..d1de3af8b 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -128,14 +128,14 @@ static function getItems($options) { $isClient = $user->isClient(); $grouping = ttReportHelper::grouping($options); - $grouping_by_date = ($options['group_by1'] == 'date'|| $options['group_by2'] == 'date' || $options['group_by3'] == 'date'); - $grouping_by_client = ($options['group_by1'] == 'client'|| $options['group_by2'] == 'client' || $options['group_by3'] == 'client'); - $grouping_by_project = ($options['group_by1'] == 'project'|| $options['group_by2'] == 'project' || $options['group_by3'] == 'project'); - $grouping_by_task = ($options['group_by1'] == 'task'|| $options['group_by2'] == 'task' || $options['group_by3'] == 'task'); - $grouping_by_user = ($options['group_by1'] == 'user'|| $options['group_by2'] == 'user' || $options['group_by3'] == 'user'); - $grouping_by_cf_1 = ($options['group_by1'] == 'cf_1'|| $options['group_by2'] == 'cf_1' || $options['group_by3'] == 'cf_1'); - - $group_by_option = $options['group_by1']; + if ($grouping) { + $grouping_by_date = ttReportHelper::groupingBy('date', $options); + $grouping_by_client = ttReportHelper::groupingBy('client', $options); + $grouping_by_project = ttReportHelper::groupingBy('project', $options); + $grouping_by_task = ttReportHelper::groupingBy('task', $options); + $grouping_by_user = ttReportHelper::groupingBy('user', $options); + $grouping_by_cf_1 = ttReportHelper::groupingBy('cf_1', $options); + } $convertTo12Hour = ('%I:%M %p' == $user->time_format) && ($options['show_start'] || $options['show_end']); // Prepare a query for time items in tt_log table. @@ -1540,9 +1540,7 @@ static function groupingByUser($options) { // ('user', 'project', etc.) by checking group_by1, group_by2, and group_by3 // values passed in $options. static function groupingBy($what, $options) { - $grouping = ($options['group_by1'] != null && $options['group_by1'] != $what) || - ($options['group_by2'] != null && $options['group_by2'] != $what) || - ($options['group_by3'] != null && $options['group_by3'] != $what); + $grouping = ($options['group_by1'] == $what) || ($options['group_by2'] == $what) || ($options['group_by3'] == $what); return $grouping; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 438d7d5c4..e22100338 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.06.4355 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4356 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From aa93160fd2b4cccce4e14c96cc1c3e5e43218e4c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 4 Nov 2018 12:50:08 +0000 Subject: [PATCH 0269/1848] A bit of refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 68 +++++----------------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 13 insertions(+), 57 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index d1de3af8b..744ef97b0 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -403,7 +403,7 @@ static function getSubtotals($options) { $group_by_part = ttReportHelper::makeGroupByPart($options); if ($options['show_cost']) { if (MODE_TIME == $user->tracking_mode) { - if (!ttReportHelper::groupingByUser($options)) + if (!ttReportHelper::groupingBy('user', $options)) $left_join = 'left join tt_users u on (l.user_id = u.id)'; $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time"; if ($options['show_work_units']) { @@ -1446,30 +1446,21 @@ static function makeCombinedSelectPart($options) { // makeJoinPart builds a left join part for getSubtotals query (for time items). static function makeJoinPart($options) { global $user; - if (ttReportHelper::groupingBy('cf_1', $options)) { - $custom_fields = new CustomFields($user->group_id); - } - $group_by_fields = ttReportHelper::makeGroupByFieldsPart($options); // TODO: refactor this, perhaps? - if (strpos($group_by_fields, 'user') !== false) { - // Grouping by user, add a join on tt_users table. + if (ttReportHelper::groupingBy('user', $options)) { $join .= ' left join tt_users u on (l.user_id = u.id)'; } - if (strpos($group_by_fields, 'client') !== false) { - // Grouping by client, add a join on tt_clients table. + if (ttReportHelper::groupingBy('client', $options)) { $join .= ' left join tt_clients c on (l.client_id = c.id)'; } - if (strpos($group_by_fields, 'project') !== false) { - // Grouping by project, add a join on tt_projects table. + if (ttReportHelper::groupingBy('project', $options)) { $join .= ' left join tt_projects p on (l.project_id = p.id)'; } - if (strpos($group_by_fields, 'task') !== false) { - // Grouping by task, add a join on tt_tasks table. + if (ttReportHelper::groupingBy('task', $options)) { $join .= ' left join tt_tasks t on (l.task_id = t.id)'; } - if (strpos($group_by_fields, 'cf_1') !== false) { - // Grouping by custom field 1, add a join for it. - // $custom_fields = new CustomFields($user->group_id); + if (ttReportHelper::groupingBy('cf_1', $options)) { + $custom_fields = new CustomFields($user->group_id); if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) $join .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id)'; elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) @@ -1480,45 +1471,17 @@ static function makeJoinPart($options) { // makeJoinExpensesPart builds a left join part for getSubtotals query for expense items. static function makeJoinExpensesPart($options) { - $group_by_fields = ttReportHelper::makeGroupByFieldsPart($options); // TODO: refactor this, perhaps? - if (strpos($group_by_fields, 'user') !== false) { - // Grouping by user, add a join on tt_users table. + if (ttReportHelper::groupingBy('user', $options)) { $join .= ' left join tt_users u on (ei.user_id = u.id)'; } - if (strpos($group_by_fields, 'client') !== false) { - // Grouping by client, add a join on tt_clients table. + if (ttReportHelper::groupingBy('client', $options)) { $join .= ' left join tt_clients c on (ei.client_id = c.id)'; } - if (strpos($group_by_fields, 'project') !== false) { - // Grouping by project, add a join on tt_projects table. + if (ttReportHelper::groupingBy('project', $options)) { $join .= ' left join tt_projects p on (ei.project_id = p.id)'; } return $join; } - - // makeGroupByFieldsPart builds a commma-separated list of fields for sql query using group_by1, - // group_by2, and group_by3 values passed in $options. - static function makeGroupByFieldsPart($options) { - $no_grouping = ($options['group_by1'] == null || $options['group_by1'] == 'no_grouping') && - ($options['group_by2'] == null || $options['group_by2'] == 'no_grouping') && - ($options['group_by3'] == null || $options['group_by3'] == 'no_grouping'); - if ($no_grouping) return null; - - if ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') { - // We have group_by1. - $group_by_fields .= ', '.$options['group_by1']; - } - if ($options['group_by2'] != null && $options['group_by2'] != 'no_grouping') { - // We have group_by2. - $group_by_fields .= ', '.$options['group_by2']; - } - if ($options['group_by3'] != null && $options['group_by3'] != 'no_grouping') { - // We have group_by3. - $group_by_fields .= ', '.$options['group_by3']; - } - $group_by_fields = ltrim($group_by_fields, ', '); - return $group_by_fields; - } // grouping determines if we are grouping the report by either group_by1, // group_by2, or group_by3 values passed in $options. @@ -1529,16 +1492,9 @@ static function grouping($options) { return $grouping; } - // groupingByUser determines if we are grouping a report by user. - static function groupingByUser($options) { - if ($options['group_by1'] == 'user' || $options['group_by2'] == 'user' || $options['group_by3'] == 'user') return true; - - return false; - } - // groupingBy determines if we are grouping a report by a value of $what - // ('user', 'project', etc.) by checking group_by1, group_by2, and group_by3 - // values passed in $options. + // ('date', 'user', 'project', etc.) by checking group_by1, group_by2, + // and group_by3 values passed in $options. static function groupingBy($what, $options) { $grouping = ($options['group_by1'] == $what) || ($options['group_by2'] == $what) || ($options['group_by3'] == $what); return $grouping; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e22100338..1d02b7d73 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4356 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4357 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 39646912fc3018f2a6922ba6716be22a91da14e9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 4 Nov 2018 13:28:51 +0000 Subject: [PATCH 0270/1848] Fixed changed name in a couple of places. --- WEB-INF/templates/footer.tpl | 2 +- group_edit.php | 2 +- invoice_send.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1d02b7d73..c10f48c9c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4357 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4358 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_edit.php b/group_edit.php index 9c4cf3692..e9d5189a1 100644 --- a/group_edit.php +++ b/group_edit.php @@ -65,7 +65,7 @@ $cl_bcc_email = trim($request->getParameter('bcc_email')); $cl_allow_ip = trim($request->getParameter('allow_ip')); } else { - $cl_group = $user->group; + $cl_group = $user->group_name; $cl_currency = ($user->currency == ''? CURRENCY_DEFAULT : $user->currency); $cl_lang = $user->lang; $cl_decimal_mark = $user->decimal_mark; diff --git a/invoice_send.php b/invoice_send.php index ca76f34bb..135453b53 100644 --- a/invoice_send.php +++ b/invoice_send.php @@ -58,7 +58,7 @@ } else { $cl_receiver = $sc->getValue(SYSC_LAST_INVOICE_EMAIL); $cl_cc = $sc->getValue(SYSC_LAST_INVOICE_CC); - $cl_subject = $i18n->get('title.invoice').' '.$invoice['name'].', '.$user->group; + $cl_subject = $i18n->get('title.invoice').' '.$invoice['name'].', '.$user->group_name; } $form = new Form('mailForm'); From c83e33b75d24c71b29df94a061e79a3079f7fe12 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 4 Nov 2018 13:50:15 +0000 Subject: [PATCH 0271/1848] Fixed export of group name - broken during refactoring. --- WEB-INF/lib/ttExportHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttExportHelper.class.php b/WEB-INF/lib/ttExportHelper.class.php index d40ce4528..26c801d48 100644 --- a/WEB-INF/lib/ttExportHelper.class.php +++ b/WEB-INF/lib/ttExportHelper.class.php @@ -69,7 +69,7 @@ function createDataFile($compress = false) { "\" plugins=\"".$user->plugins."\" lock_spec=\"".$user->lock_spec."\" workday_minutes=\"".$user->workday_minutes. "\" config=\"".$user->config. "\">\n"); - fwrite($file, " group."]]>\n"); + fwrite($file, " group_name."]]>\n"); fwrite($file, " allow_ip."]]>\n"); fwrite($file, " password_complexity."]]>\n"); fwrite($file, "\n"); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c10f48c9c..087433288 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4358 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4359 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index c7c445a79..430c1c2b0 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -161,7 +161,7 @@ {if $user->name} - + {else} {/if} From 0098044d9aa84b16c0a2fc6a028844b078a21ca0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 4 Nov 2018 14:05:55 +0000 Subject: [PATCH 0272/1848] Fixed ttGroupHelper::getTopGroups to not display deleted groups. --- WEB-INF/lib/ttGroupHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 3fb01c604..44dc3e1b1 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -36,7 +36,7 @@ static function getTopGroups() { $mdb2 = getConnection(); $sql = "select id, name, created, lang from tt_groups". - " where status = 1 and org_id is NULL or org_id = id order by id desc"; + " where status = 1 and (org_id is NULL or org_id = id) order by id desc"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 087433288..abee8d919 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$title}{if $timestring}: {$timestring}{/if}
{$user->name|escape} - {$user->role_name|escape}{if $user->behalf_id > 0} {$i18n.label.on_behalf} {$user->behalf_name|escape}{/if}{if $user->group}, {$user->group|escape}{/if}
{$user->name|escape} - {$user->role_name|escape}{if $user->behalf_id > 0} {$i18n.label.on_behalf} {$user->behalf_name|escape}{/if}{if $user->group_name}, {$user->group_name|escape}{/if}
 
-
 Anuko Time Tracker 1.18.07.4359 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4360 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 41db697346ee4c6ca08d0c6891c7764ff5ce59b4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 4 Nov 2018 14:37:55 +0000 Subject: [PATCH 0273/1848] Fixed creating org_id for newly imported users. --- WEB-INF/lib/ttImportHelper.class.php | 3 +++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 6686d40f6..69af9e12c 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -47,6 +47,7 @@ class ttImportHelper { var $canImport = true; // False if we cannot import data due to a login collision. var $groupData = array(); // Array of group data such as group name, etc. + var $org_id = null; // New organization id we are importing. It is created during the import operation. var $group_id = null; // New group id we are importing. It is created during the import operation. var $roles = array(); // Array of arrays of role properties. var $users = array(); // Array of arrays of user properties. @@ -144,6 +145,7 @@ function endElement($parser, $name) { 'workday_minutes' => $this->groupData['WORKDAY_MINUTES'], 'config' => $this->groupData['CONFIG'])); if ($group_id) { + $this->org_id = $group_id; $this->group_id = $group_id; // Create roles. @@ -161,6 +163,7 @@ function endElement($parser, $name) { $role_id = $user_item['ROLE_ID'] === '0' ? $this->top_role_id : $this->roleMap[$user_item['ROLE_ID']]; // 0 (not null) means top manager role. $user_id = ttUserHelper::insert(array( 'group_id' => $this->group_id, + 'org_id' => $this->org_id, 'role_id' => $role_id, 'client_id' => $user_item['CLIENT_ID'], // Note: NOT mapped value, replaced in CLIENT handler. 'name' => $user_item['NAME'], diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index abee8d919..6f69b349a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4360 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4361 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a0656da39249cd92f75f9794ae08dd3a009bf7a1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 4 Nov 2018 17:26:29 +0000 Subject: [PATCH 0274/1848] Starting redoing import for subgroup support. --- WEB-INF/lib/ttImportHelper2.class.php | 503 ++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- import.php | 8 +- 3 files changed, 510 insertions(+), 3 deletions(-) create mode 100644 WEB-INF/lib/ttImportHelper2.class.php diff --git a/WEB-INF/lib/ttImportHelper2.class.php b/WEB-INF/lib/ttImportHelper2.class.php new file mode 100644 index 000000000..c646b97e0 --- /dev/null +++ b/WEB-INF/lib/ttImportHelper2.class.php @@ -0,0 +1,503 @@ +errors = &$errors; + } + + // startElement - callback handler for opening tag of an XML element. + // In this function we assign passed in attributes to currentElement. + function startElement($parser, $name, $attrs) { + if ($name == 'GROUP' + || $name == 'USER' + || $name == 'TASK' + || $name == 'PROJECT' + || $name == 'CLIENT' + || $name == 'INVOICE' + || $name == 'MONTHLY_QUOTA' + || $name == 'LOG_ITEM' + || $name == 'CUSTOM_FIELD' + || $name == 'CUSTOM_FIELD_OPTION' + || $name == 'CUSTOM_FIELD_LOG_ENTRY' + || $name == 'INVOICE_HEADER' + || $name == 'USER_PROJECT_BIND' + || $name == 'EXPENSE_ITEM' + || $name == 'FAV_REPORT' + || $name == 'ROLE') { + $this->currentElement = $attrs; + } + $this->currentTag = $name; + } + + // endElement - callback handler for the closing tag of an XML element. + // When we are here, currentElement is an array of the element attributes (as set in startElement). + // Here we do the actual import of data into the database. + function endElement($parser, $name) { + if ($name == 'GROUP') { + $this->groupData = $this->currentElement; + // Now groupData is an array of group properties. We'll use it later to create a group. + // Cannot create the group here. Need to determine whether logins collide with existing logins. + $this->currentElement = array(); + } + if ($name == 'ROLE') { + $this->roles[$this->currentElement['ID']] = $this->currentElement; + $this->currentElement = array(); + } + if ($name == 'USER') { + $this->users[$this->currentElement['ID']] = $this->currentElement; + $this->currentElement = array(); + } + if ($name == 'USERS') { + foreach ($this->users as $user_item) { + if (('' != $user_item['STATUS']) && ttUserHelper::getUserByLogin($user_item['LOGIN'])) { + // We have a login collision, cannot import any data. + $this->canImport = false; + break; + } + } + + // Now we can create a group. + if ($this->canImport) { + $this->top_role_id = ttRoleHelper::getRoleByRank(512, 0); + $group_id = $this->createGroup(array( + 'name' => $this->groupData['NAME'], + 'currency' => $this->groupData['CURRENCY'], + 'decimal_mark' => $this->groupData['DECIMAL_MARK'], + 'lang' => $this->groupData['LANG'], + 'date_format' => $this->groupData['DATE_FORMAT'], + 'time_format' => $this->groupData['TIME_FORMAT'], + 'week_start' => $this->groupData['WEEK_START'], + 'tracking_mode' => $this->groupData['TRACKING_MODE'], + 'project_required' => $this->groupData['PROJECT_REQUIRED'], + 'task_required' => $this->groupData['TASK_REQUIRED'], + 'record_type' => $this->groupData['RECORD_TYPE'], + 'bcc_email' => $this->groupData['BCC_EMAIL'], + 'allow_ip' => $this->groupData['ALLOW_IP'], + 'password_complexity' => $this->groupData['PASSWORD_COMPLEXITY'], + 'plugins' => $this->groupData['PLUGINS'], + 'lock_spec' => $this->groupData['LOCK_SPEC'], + 'workday_minutes' => $this->groupData['WORKDAY_MINUTES'], + 'config' => $this->groupData['CONFIG'])); + if ($group_id) { + $this->org_id = $group_id; + $this->group_id = $group_id; + + // Create roles. + foreach ($this->roles as $key=>$role_item) { + $role_id = ttRoleHelper::insert(array( + 'group_id' => $this->group_id, + 'name' => $role_item['NAME'], + 'rank' => $role_item['RANK'], + 'rights' => $role_item['RIGHTS'], + 'status' => $role_item['STATUS'])); + $this->roleMap[$role_item['ID']] = $role_id; + } + + foreach ($this->users as $key=>$user_item) { + $role_id = $user_item['ROLE_ID'] === '0' ? $this->top_role_id : $this->roleMap[$user_item['ROLE_ID']]; // 0 (not null) means top manager role. + $user_id = ttUserHelper::insert(array( + 'group_id' => $this->group_id, + 'org_id' => $this->org_id, + 'role_id' => $role_id, + 'client_id' => $user_item['CLIENT_ID'], // Note: NOT mapped value, replaced in CLIENT handler. + 'name' => $user_item['NAME'], + 'login' => $user_item['LOGIN'], + 'password' => $user_item['PASSWORD'], + 'rate' => $user_item['RATE'], + 'email' => $user_item['EMAIL'], + 'status' => $user_item['STATUS']), false); + $this->userMap[$key] = $user_id; + } + } + } + } + + if ($name == 'TASK' && $this->canImport) { + $this->taskMap[$this->currentElement['ID']] = + ttTaskHelper::insert(array( + 'group_id' => $this->group_id, + 'name' => $this->currentElement['NAME'], + 'description' => $this->currentElement['DESCRIPTION'], + 'status' => $this->currentElement['STATUS'])); + } + if ($name == 'PROJECT' && $this->canImport) { + // Prepare a list of task ids. + $tasks = explode(',', $this->currentElement['TASKS']); + foreach ($tasks as $id) + $mapped_tasks[] = $this->taskMap[$id]; + + // Add a new project. + $this->projectMap[$this->currentElement['ID']] = + ttProjectHelper::insert(array( + 'group_id' => $this->group_id, + 'name' => $this->currentElement['NAME'], + 'description' => $this->currentElement['DESCRIPTION'], + 'tasks' => $mapped_tasks, + 'status' => $this->currentElement['STATUS'])); + } + if ($name == 'USER_PROJECT_BIND' && $this->canImport) { + ttUserHelper::insertBind( + $this->userMap[$this->currentElement['USER_ID']], + $this->projectMap[$this->currentElement['PROJECT_ID']], + $this->currentElement['RATE'], + $this->currentElement['STATUS']); + } + + if ($name == 'CLIENT' && $this->canImport) { + // Prepare a list of project ids. + if ($this->currentElement['PROJECTS']) { + $projects = explode(',', $this->currentElement['PROJECTS']); + foreach ($projects as $id) + $mapped_projects[] = $this->projectMap[$id]; + } + + $this->clientMap[$this->currentElement['ID']] = + ttClientHelper::insert(array( + 'group_id' => $this->group_id, + 'name' => $this->currentElement['NAME'], + 'address' => $this->currentElement['ADDRESS'], + 'tax' => $this->currentElement['TAX'], + 'projects' => $mapped_projects, + 'status' => $this->currentElement['STATUS'])); + + // Update client_id for tt_users to a mapped value. + // We did not do it during user insertion because clientMap was not ready then. + if ($this->currentElement['ID'] != $this->clientMap[$this->currentElement['ID']]) + ttClientHelper::setMappedClient($this->group_id, $this->currentElement['ID'], $this->clientMap[$this->currentElement['ID']]); + } + + if ($name == 'INVOICE' && $this->canImport) { + $this->invoiceMap[$this->currentElement['ID']] = + ttInvoiceHelper::insert(array( + 'group_id' => $this->group_id, + 'name' => $this->currentElement['NAME'], + 'date' => $this->currentElement['DATE'], + 'client_id' => $this->clientMap[$this->currentElement['CLIENT_ID']], + 'discount' => $this->currentElement['DISCOUNT'], + 'status' => $this->currentElement['STATUS'])); + } + + if ($name == 'MONTHLY_QUOTA' && $this->canImport) { + $this->insertMonthlyQuota($this->group_id, $this->currentElement['YEAR'], $this->currentElement['MONTH'], $this->currentElement['MINUTES']); + } + + if ($name == 'LOG_ITEM' && $this->canImport) { + $this->logMap[$this->currentElement['ID']] = + ttTimeHelper::insert(array( + 'user_id' => $this->userMap[$this->currentElement['USER_ID']], + 'group_id' => $this->group_id, + 'date' => $this->currentElement['DATE'], + 'start' => $this->currentElement['START'], + 'finish' => $this->currentElement['FINISH'], + 'duration' => $this->currentElement['DURATION'], + 'client' => $this->clientMap[$this->currentElement['CLIENT_ID']], + 'project' => $this->projectMap[$this->currentElement['PROJECT_ID']], + 'task' => $this->taskMap[$this->currentElement['TASK_ID']], + 'invoice' => $this->invoiceMap[$this->currentElement['INVOICE_ID']], + 'note' => (isset($this->currentElement['COMMENT']) ? $this->currentElement['COMMENT'] : ''), + 'billable' => $this->currentElement['BILLABLE'], + 'paid' => $this->currentElement['PAID'], + 'status' => $this->currentElement['STATUS'])); + } + + if ($name == 'CUSTOM_FIELD' && $this->canImport) { + $this->customFieldMap[$this->currentElement['ID']] = + ttCustomFieldHelper::insertField(array( + 'group_id' => $this->group_id, + 'type' => $this->currentElement['TYPE'], + 'label' => $this->currentElement['LABEL'], + 'required' => $this->currentElement['REQUIRED'], + 'status' => $this->currentElement['STATUS'])); + } + + if ($name == 'CUSTOM_FIELD_OPTION' && $this->canImport) { + $this->customFieldOptionMap[$this->currentElement['ID']] = + ttCustomFieldHelper::insertOption(array( + 'field_id' => $this->customFieldMap[$this->currentElement['FIELD_ID']], + 'value' => $this->currentElement['VALUE'])); + } + + if ($name == 'CUSTOM_FIELD_LOG_ENTRY' && $this->canImport) { + ttCustomFieldHelper::insertLogEntry(array( + 'log_id' => $this->logMap[$this->currentElement['LOG_ID']], + 'field_id' => $this->customFieldMap[$this->currentElement['FIELD_ID']], + 'option_id' => $this->customFieldOptionMap[$this->currentElement['OPTION_ID']], + 'value' => $this->currentElement['VALUE'], + 'status' => $this->currentElement['STATUS'])); + } + + if ($name == 'EXPENSE_ITEM' && $this->canImport) { + ttExpenseHelper::insert(array( + 'date' => $this->currentElement['DATE'], + 'user_id' => $this->userMap[$this->currentElement['USER_ID']], + 'group_id' => $this->group_id, + 'client_id' => $this->clientMap[$this->currentElement['CLIENT_ID']], + 'project_id' => $this->projectMap[$this->currentElement['PROJECT_ID']], + 'name' => $this->currentElement['NAME'], + 'cost' => $this->currentElement['COST'], + 'invoice_id' => $this->invoiceMap[$this->currentElement['INVOICE_ID']], + 'paid' => $this->currentElement['PAID'], + 'status' => $this->currentElement['STATUS'])); + } + + if ($name == 'FAV_REPORT' && $this->canImport) { + $user_list = ''; + if (strlen($this->currentElement['USERS']) > 0) { + $arr = explode(',', $this->currentElement['USERS']); + foreach ($arr as $v) + $user_list .= (strlen($user_list) == 0 ? '' : ',').$this->userMap[$v]; + } + ttFavReportHelper::insertReport(array( + 'name' => $this->currentElement['NAME'], + 'user_id' => $this->userMap[$this->currentElement['USER_ID']], + 'client' => $this->clientMap[$this->currentElement['CLIENT_ID']], + 'option' => $this->customFieldOptionMap[$this->currentElement['CF_1_OPTION_ID']], + 'project' => $this->projectMap[$this->currentElement['PROJECT_ID']], + 'task' => $this->taskMap[$this->currentElement['TASK_ID']], + 'billable' => $this->currentElement['BILLABLE'], + 'users' => $user_list, + 'period' => $this->currentElement['PERIOD'], + 'from' => $this->currentElement['PERIOD_START'], + 'to' => $this->currentElement['PERIOD_END'], + 'chclient' => (int) $this->currentElement['SHOW_CLIENT'], + 'chinvoice' => (int) $this->currentElement['SHOW_INVOICE'], + 'chpaid' => (int) $this->currentElement['SHOW_PAID'], + 'chip' => (int) $this->currentElement['SHOW_IP'], + 'chproject' => (int) $this->currentElement['SHOW_PROJECT'], + 'chstart' => (int) $this->currentElement['SHOW_START'], + 'chduration' => (int) $this->currentElement['SHOW_DURATION'], + 'chcost' => (int) $this->currentElement['SHOW_COST'], + 'chtask' => (int) $this->currentElement['SHOW_TASK'], + 'chfinish' => (int) $this->currentElement['SHOW_END'], + 'chnote' => (int) $this->currentElement['SHOW_NOTE'], + 'chcf_1' => (int) $this->currentElement['SHOW_CUSTOM_FIELD_1'], + 'chunits' => (int) $this->currentElement['SHOW_WORK_UNITS'], + 'group_by1' => $this->currentElement['GROUP_BY1'], + 'group_by2' => $this->currentElement['GROUP_BY2'], + 'group_by3' => $this->currentElement['GROUP_BY3'], + 'chtotalsonly' => (int) $this->currentElement['SHOW_TOTALS_ONLY'])); + } + $this->currentTag = ''; + } + + // dataElement - callback handler for text data fragments. It builds up currentElement array with text pieces from XML. + function dataElement($parser, $data) { + if ($this->currentTag == 'NAME' + || $this->currentTag == 'DESCRIPTION' + || $this->currentTag == 'LABEL' + || $this->currentTag == 'VALUE' + || $this->currentTag == 'COMMENT' + || $this->currentTag == 'ADDRESS' + || $this->currentTag == 'ALLOW_IP' + || $this->currentTag == 'PASSWORD_COMPLEXITY') { + if (isset($this->currentElement[$this->currentTag])) + $this->currentElement[$this->currentTag] .= trim($data); + else + $this->currentElement[$this->currentTag] = trim($data); + } + } + + // importXml - uncompresses the file, reads and parses its content. During parsing, + // startElement, endElement, and dataElement functions are called as many times as necessary. + // Actual import occurs in the endElement handler. + function importXml() { + global $i18n; + + // Do we have a compressed file? + $compressed = false; + $file_ext = substr($_FILES['xmlfile']['name'], strrpos($_FILES['xmlfile']['name'], '.') + 1); + if (in_array($file_ext, array('bz','tbz','bz2','tbz2'))) { + $compressed = true; + } + + // Create a temporary file. + $dirName = dirname(TEMPLATE_DIR . '_c/.'); + $filename = tempnam($dirName, 'import_'); + + // If the file is compressed - uncompress it. + if ($compressed) { + if (!$this->uncompress($_FILES['xmlfile']['tmp_name'], $filename)) { + $this->errors->add($i18n->get('error.sys')); + return; + } + unlink($_FILES['xmlfile']['tmp_name']); + } else { + if (!move_uploaded_file($_FILES['xmlfile']['tmp_name'], $filename)) { + $this->errors->add($i18n->get('error.upload')); + return; + } + } + + // Initialize XML parser. + $parser = xml_parser_create(); + xml_set_object($parser, $this); + xml_set_element_handler($parser, 'startElement', 'endElement'); + xml_set_character_data_handler($parser, 'dataElement'); + + // Read and parse the content of the file. During parsing, startElement, endElement, and dataElement functions are called. + $file = fopen($filename, 'r'); + while ($data = fread($file, 4096)) { + if (!xml_parse($parser, $data, feof($file))) { + $this->errors->add(sprintf("XML error: %s at line %d", + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser))); + } + if (!$this->canImport) { + $this->errors->add($i18n->get('error.user_exists')); + break; + } + } + xml_parser_free($parser); + if ($file) fclose($file); + unlink($filename); + } + + // uncompress - uncompresses the content of the $in file into the $out file. + function uncompress($in, $out) { + // Do we have the uncompress function? + if (!function_exists('bzopen')) + return false; + + // Initial checks of file names and permissions. + if (!file_exists($in) || !is_readable ($in)) + return false; + if ((!file_exists($out) && !is_writable(dirname($out))) || (file_exists($out) && !is_writable($out))) + return false; + + if (!$out_file = fopen($out, 'wb')) + return false; + if (!$in_file = bzopen ($in, 'r')) + return false; + + while (!feof($in_file)) { + $buffer = bzread($in_file, 4096); + fwrite($out_file, $buffer, 4096); + } + bzclose($in_file); + fclose ($out_file); + return true; + } + + // createGroup function creates a new group. + private function createGroup($fields) { + + global $user; + $mdb2 = getConnection(); + + $columns = '(name, currency, decimal_mark, lang, date_format, time_format, week_start, tracking_mode'. + ', project_required, task_required, record_type, bcc_email, allow_ip, password_complexity, plugins'. + ', lock_spec, workday_minutes, config, created, created_ip, created_by)'; + + $values = ' values ('.$mdb2->quote(trim($fields['name'])); + $values .= ', '.$mdb2->quote(trim($fields['currency'])); + $values .= ', '.$mdb2->quote($fields['decimal_mark']); + $values .= ', '.$mdb2->quote($fields['lang']); + $values .= ', '.$mdb2->quote($fields['date_format']); + $values .= ', '.$mdb2->quote($fields['time_format']); + $values .= ', '.(int)$fields['week_start']; + $values .= ', '.(int)$fields['tracking_mode']; + $values .= ', '.(int)$fields['project_required']; + $values .= ', '.(int)$fields['task_required']; + $values .= ', '.(int)$fields['record_type']; + $values .= ', '.$mdb2->quote($fields['bcc_email']); + $values .= ', '.$mdb2->quote($fields['allow_ip']); + $values .= ', '.$mdb2->quote($fields['password_complexity']); + $values .= ', '.$mdb2->quote($fields['plugins']); + $values .= ', '.$mdb2->quote($fields['lock_spec']); + $values .= ', '.(int)$fields['workday_minutes']; + $values .= ', '.$mdb2->quote($fields['config']); + $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); + $values .= ')'; + + $sql = 'insert into tt_groups '.$columns.$values; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + $group_id = $mdb2->lastInsertID('tt_groups', 'id'); + + // Update org_id with group_id. + // NOTE: Both export and import need an additional effort to properly operate on subgroups. + // Currently we are importing one group only, which becomes a top level group. + $sql = "update tt_groups set org_id = $group_id where org_id is NULL and id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + return $group_id; + } + + // insertMonthlyQuota - a helper function to insert a monthly quota. + private function insertMonthlyQuota($group_id, $year, $month, $minutes) { + $mdb2 = getConnection(); + $sql = "INSERT INTO tt_monthly_quotas (group_id, year, month, minutes) values ($group_id, $year, $month, $minutes)"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } +} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6f69b349a..04c4015fd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4361 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4362 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/import.php b/import.php index f822cb793..3e375c981 100644 --- a/import.php +++ b/import.php @@ -28,6 +28,7 @@ require_once('initialize.php'); import('ttImportHelper'); +import('ttImportHelper2'); import('form.Form'); // Access check. @@ -42,8 +43,11 @@ $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.import'))); if ($request->isPost()) { - - $import = new ttImportHelper($err); + if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { + $import = new ttImportHelper2($err); + } else { + $import = new ttImportHelper($err); + } $import->importXml(); if ($err->no()) $msg->add($i18n->get('form.import.success')); } // isPost From de9b34758cdcbc54e7100c260591143445c3c5cf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 4 Nov 2018 20:20:17 +0000 Subject: [PATCH 0275/1848] More work on new import. Implemented 2-pass approach. --- WEB-INF/lib/ttImportHelper2.class.php | 369 +++----------------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 42 insertions(+), 329 deletions(-) diff --git a/WEB-INF/lib/ttImportHelper2.class.php b/WEB-INF/lib/ttImportHelper2.class.php index c646b97e0..58bfa8866 100644 --- a/WEB-INF/lib/ttImportHelper2.class.php +++ b/WEB-INF/lib/ttImportHelper2.class.php @@ -48,28 +48,10 @@ class ttImportHelper2 { var $currentTag = ''; // XML tag of the current element. var $canImport = true; // False if we cannot import data due to a login collision. - var $groupData = array(); // Array of group data such as group name, etc. - var $org_id = null; // New organization id we are importing. It is created during the import operation. - var $group_id = null; // New group id we are importing. It is created during the import operation. - var $roles = array(); // Array of arrays of role properties. - var $users = array(); // Array of arrays of user properties. - var $top_role_id = null; // Top manager role id on the new server. - - // The following arrays are maps between entity ids in the file versus the database. - // In the file they are sequential (1,2,3...) while in the database the entities have different ids. - var $roleMap = array(); // Role ids. - var $userMap = array(); // User ids. - var $projectMap = array(); // Project ids. - var $taskMap = array(); // Task ids. - var $clientMap = array(); // Client ids. - var $invoiceMap = array(); // Invoice ids. - - var $customFieldMap = array(); // Custom field ids. - var $customFieldOptionMap = array(); // Custop field option ids. - var $logMap = array(); // Time log ids. + var $firstPass = true; // True during first pass through the file. // Constructor. - function ttImportHelper(&$errors) { + function ttImportHelper2(&$errors) { $this->errors = &$errors; } @@ -77,21 +59,7 @@ function ttImportHelper(&$errors) { // In this function we assign passed in attributes to currentElement. function startElement($parser, $name, $attrs) { if ($name == 'GROUP' - || $name == 'USER' - || $name == 'TASK' - || $name == 'PROJECT' - || $name == 'CLIENT' - || $name == 'INVOICE' - || $name == 'MONTHLY_QUOTA' - || $name == 'LOG_ITEM' - || $name == 'CUSTOM_FIELD' - || $name == 'CUSTOM_FIELD_OPTION' - || $name == 'CUSTOM_FIELD_LOG_ENTRY' - || $name == 'INVOICE_HEADER' - || $name == 'USER_PROJECT_BIND' - || $name == 'EXPENSE_ITEM' - || $name == 'FAV_REPORT' - || $name == 'ROLE') { + || $name == 'USER') { $this->currentElement = $attrs; } $this->currentTag = $name; @@ -101,251 +69,21 @@ function startElement($parser, $name, $attrs) { // When we are here, currentElement is an array of the element attributes (as set in startElement). // Here we do the actual import of data into the database. function endElement($parser, $name) { - if ($name == 'GROUP') { - $this->groupData = $this->currentElement; - // Now groupData is an array of group properties. We'll use it later to create a group. - // Cannot create the group here. Need to determine whether logins collide with existing logins. - $this->currentElement = array(); - } - if ($name == 'ROLE') { - $this->roles[$this->currentElement['ID']] = $this->currentElement; - $this->currentElement = array(); - } - if ($name == 'USER') { - $this->users[$this->currentElement['ID']] = $this->currentElement; - $this->currentElement = array(); - } - if ($name == 'USERS') { - foreach ($this->users as $user_item) { - if (('' != $user_item['STATUS']) && ttUserHelper::getUserByLogin($user_item['LOGIN'])) { + // During first pass we only check user logins. + if ($this->firstPass) { + if ($name == 'USER' && $this->canImport) { + if ('' != $this->currentElement['STATUS'] && ttUserHelper::getUserByLogin($this->currentElement['LOGIN'])) { // We have a login collision, cannot import any data. $this->canImport = false; - break; } } - - // Now we can create a group. - if ($this->canImport) { - $this->top_role_id = ttRoleHelper::getRoleByRank(512, 0); - $group_id = $this->createGroup(array( - 'name' => $this->groupData['NAME'], - 'currency' => $this->groupData['CURRENCY'], - 'decimal_mark' => $this->groupData['DECIMAL_MARK'], - 'lang' => $this->groupData['LANG'], - 'date_format' => $this->groupData['DATE_FORMAT'], - 'time_format' => $this->groupData['TIME_FORMAT'], - 'week_start' => $this->groupData['WEEK_START'], - 'tracking_mode' => $this->groupData['TRACKING_MODE'], - 'project_required' => $this->groupData['PROJECT_REQUIRED'], - 'task_required' => $this->groupData['TASK_REQUIRED'], - 'record_type' => $this->groupData['RECORD_TYPE'], - 'bcc_email' => $this->groupData['BCC_EMAIL'], - 'allow_ip' => $this->groupData['ALLOW_IP'], - 'password_complexity' => $this->groupData['PASSWORD_COMPLEXITY'], - 'plugins' => $this->groupData['PLUGINS'], - 'lock_spec' => $this->groupData['LOCK_SPEC'], - 'workday_minutes' => $this->groupData['WORKDAY_MINUTES'], - 'config' => $this->groupData['CONFIG'])); - if ($group_id) { - $this->org_id = $group_id; - $this->group_id = $group_id; - - // Create roles. - foreach ($this->roles as $key=>$role_item) { - $role_id = ttRoleHelper::insert(array( - 'group_id' => $this->group_id, - 'name' => $role_item['NAME'], - 'rank' => $role_item['RANK'], - 'rights' => $role_item['RIGHTS'], - 'status' => $role_item['STATUS'])); - $this->roleMap[$role_item['ID']] = $role_id; - } - - foreach ($this->users as $key=>$user_item) { - $role_id = $user_item['ROLE_ID'] === '0' ? $this->top_role_id : $this->roleMap[$user_item['ROLE_ID']]; // 0 (not null) means top manager role. - $user_id = ttUserHelper::insert(array( - 'group_id' => $this->group_id, - 'org_id' => $this->org_id, - 'role_id' => $role_id, - 'client_id' => $user_item['CLIENT_ID'], // Note: NOT mapped value, replaced in CLIENT handler. - 'name' => $user_item['NAME'], - 'login' => $user_item['LOGIN'], - 'password' => $user_item['PASSWORD'], - 'rate' => $user_item['RATE'], - 'email' => $user_item['EMAIL'], - 'status' => $user_item['STATUS']), false); - $this->userMap[$key] = $user_id; - } - } - } - } - - if ($name == 'TASK' && $this->canImport) { - $this->taskMap[$this->currentElement['ID']] = - ttTaskHelper::insert(array( - 'group_id' => $this->group_id, - 'name' => $this->currentElement['NAME'], - 'description' => $this->currentElement['DESCRIPTION'], - 'status' => $this->currentElement['STATUS'])); + $this->currentTag = ''; } - if ($name == 'PROJECT' && $this->canImport) { - // Prepare a list of task ids. - $tasks = explode(',', $this->currentElement['TASKS']); - foreach ($tasks as $id) - $mapped_tasks[] = $this->taskMap[$id]; - // Add a new project. - $this->projectMap[$this->currentElement['ID']] = - ttProjectHelper::insert(array( - 'group_id' => $this->group_id, - 'name' => $this->currentElement['NAME'], - 'description' => $this->currentElement['DESCRIPTION'], - 'tasks' => $mapped_tasks, - 'status' => $this->currentElement['STATUS'])); - } - if ($name == 'USER_PROJECT_BIND' && $this->canImport) { - ttUserHelper::insertBind( - $this->userMap[$this->currentElement['USER_ID']], - $this->projectMap[$this->currentElement['PROJECT_ID']], - $this->currentElement['RATE'], - $this->currentElement['STATUS']); + // During second pass we import data. + if (!$this->firstPass && $this->canImport) { + // TODO: write code here. } - - if ($name == 'CLIENT' && $this->canImport) { - // Prepare a list of project ids. - if ($this->currentElement['PROJECTS']) { - $projects = explode(',', $this->currentElement['PROJECTS']); - foreach ($projects as $id) - $mapped_projects[] = $this->projectMap[$id]; - } - - $this->clientMap[$this->currentElement['ID']] = - ttClientHelper::insert(array( - 'group_id' => $this->group_id, - 'name' => $this->currentElement['NAME'], - 'address' => $this->currentElement['ADDRESS'], - 'tax' => $this->currentElement['TAX'], - 'projects' => $mapped_projects, - 'status' => $this->currentElement['STATUS'])); - - // Update client_id for tt_users to a mapped value. - // We did not do it during user insertion because clientMap was not ready then. - if ($this->currentElement['ID'] != $this->clientMap[$this->currentElement['ID']]) - ttClientHelper::setMappedClient($this->group_id, $this->currentElement['ID'], $this->clientMap[$this->currentElement['ID']]); - } - - if ($name == 'INVOICE' && $this->canImport) { - $this->invoiceMap[$this->currentElement['ID']] = - ttInvoiceHelper::insert(array( - 'group_id' => $this->group_id, - 'name' => $this->currentElement['NAME'], - 'date' => $this->currentElement['DATE'], - 'client_id' => $this->clientMap[$this->currentElement['CLIENT_ID']], - 'discount' => $this->currentElement['DISCOUNT'], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'MONTHLY_QUOTA' && $this->canImport) { - $this->insertMonthlyQuota($this->group_id, $this->currentElement['YEAR'], $this->currentElement['MONTH'], $this->currentElement['MINUTES']); - } - - if ($name == 'LOG_ITEM' && $this->canImport) { - $this->logMap[$this->currentElement['ID']] = - ttTimeHelper::insert(array( - 'user_id' => $this->userMap[$this->currentElement['USER_ID']], - 'group_id' => $this->group_id, - 'date' => $this->currentElement['DATE'], - 'start' => $this->currentElement['START'], - 'finish' => $this->currentElement['FINISH'], - 'duration' => $this->currentElement['DURATION'], - 'client' => $this->clientMap[$this->currentElement['CLIENT_ID']], - 'project' => $this->projectMap[$this->currentElement['PROJECT_ID']], - 'task' => $this->taskMap[$this->currentElement['TASK_ID']], - 'invoice' => $this->invoiceMap[$this->currentElement['INVOICE_ID']], - 'note' => (isset($this->currentElement['COMMENT']) ? $this->currentElement['COMMENT'] : ''), - 'billable' => $this->currentElement['BILLABLE'], - 'paid' => $this->currentElement['PAID'], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'CUSTOM_FIELD' && $this->canImport) { - $this->customFieldMap[$this->currentElement['ID']] = - ttCustomFieldHelper::insertField(array( - 'group_id' => $this->group_id, - 'type' => $this->currentElement['TYPE'], - 'label' => $this->currentElement['LABEL'], - 'required' => $this->currentElement['REQUIRED'], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'CUSTOM_FIELD_OPTION' && $this->canImport) { - $this->customFieldOptionMap[$this->currentElement['ID']] = - ttCustomFieldHelper::insertOption(array( - 'field_id' => $this->customFieldMap[$this->currentElement['FIELD_ID']], - 'value' => $this->currentElement['VALUE'])); - } - - if ($name == 'CUSTOM_FIELD_LOG_ENTRY' && $this->canImport) { - ttCustomFieldHelper::insertLogEntry(array( - 'log_id' => $this->logMap[$this->currentElement['LOG_ID']], - 'field_id' => $this->customFieldMap[$this->currentElement['FIELD_ID']], - 'option_id' => $this->customFieldOptionMap[$this->currentElement['OPTION_ID']], - 'value' => $this->currentElement['VALUE'], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'EXPENSE_ITEM' && $this->canImport) { - ttExpenseHelper::insert(array( - 'date' => $this->currentElement['DATE'], - 'user_id' => $this->userMap[$this->currentElement['USER_ID']], - 'group_id' => $this->group_id, - 'client_id' => $this->clientMap[$this->currentElement['CLIENT_ID']], - 'project_id' => $this->projectMap[$this->currentElement['PROJECT_ID']], - 'name' => $this->currentElement['NAME'], - 'cost' => $this->currentElement['COST'], - 'invoice_id' => $this->invoiceMap[$this->currentElement['INVOICE_ID']], - 'paid' => $this->currentElement['PAID'], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'FAV_REPORT' && $this->canImport) { - $user_list = ''; - if (strlen($this->currentElement['USERS']) > 0) { - $arr = explode(',', $this->currentElement['USERS']); - foreach ($arr as $v) - $user_list .= (strlen($user_list) == 0 ? '' : ',').$this->userMap[$v]; - } - ttFavReportHelper::insertReport(array( - 'name' => $this->currentElement['NAME'], - 'user_id' => $this->userMap[$this->currentElement['USER_ID']], - 'client' => $this->clientMap[$this->currentElement['CLIENT_ID']], - 'option' => $this->customFieldOptionMap[$this->currentElement['CF_1_OPTION_ID']], - 'project' => $this->projectMap[$this->currentElement['PROJECT_ID']], - 'task' => $this->taskMap[$this->currentElement['TASK_ID']], - 'billable' => $this->currentElement['BILLABLE'], - 'users' => $user_list, - 'period' => $this->currentElement['PERIOD'], - 'from' => $this->currentElement['PERIOD_START'], - 'to' => $this->currentElement['PERIOD_END'], - 'chclient' => (int) $this->currentElement['SHOW_CLIENT'], - 'chinvoice' => (int) $this->currentElement['SHOW_INVOICE'], - 'chpaid' => (int) $this->currentElement['SHOW_PAID'], - 'chip' => (int) $this->currentElement['SHOW_IP'], - 'chproject' => (int) $this->currentElement['SHOW_PROJECT'], - 'chstart' => (int) $this->currentElement['SHOW_START'], - 'chduration' => (int) $this->currentElement['SHOW_DURATION'], - 'chcost' => (int) $this->currentElement['SHOW_COST'], - 'chtask' => (int) $this->currentElement['SHOW_TASK'], - 'chfinish' => (int) $this->currentElement['SHOW_END'], - 'chnote' => (int) $this->currentElement['SHOW_NOTE'], - 'chcf_1' => (int) $this->currentElement['SHOW_CUSTOM_FIELD_1'], - 'chunits' => (int) $this->currentElement['SHOW_WORK_UNITS'], - 'group_by1' => $this->currentElement['GROUP_BY1'], - 'group_by2' => $this->currentElement['GROUP_BY2'], - 'group_by3' => $this->currentElement['GROUP_BY3'], - 'chtotalsonly' => (int) $this->currentElement['SHOW_TOTALS_ONLY'])); - } - $this->currentTag = ''; } // dataElement - callback handler for text data fragments. It builds up currentElement array with text pieces from XML. @@ -402,6 +140,13 @@ function importXml() { xml_set_element_handler($parser, 'startElement', 'endElement'); xml_set_character_data_handler($parser, 'dataElement'); + // We need to parse the file 2 times: + // 1) First pass: determine if import is possible - there must be no login collisions. + // 2) Second pass: if we can import, then do import in a second pass. + // This is different from earlier approach for single group import, where we could + // do both things in one pass because user info was in the beginning of XML file. + // Now, with subgroups, users can be located anywhere in the file. + // Read and parse the content of the file. During parsing, startElement, endElement, and dataElement functions are called. $file = fopen($filename, 'r'); while ($data = fread($file, 4096)) { @@ -415,6 +160,29 @@ function importXml() { break; } } + $this->firstPass = false; // We are done with 1st pass. + xml_parser_free($parser); + if ($file) fclose($file); + if (!$this->canImport) { + unlink($filename); + return; + } + + // Now we can do a second pass, where real work is done. + $parser = xml_parser_create(); + xml_set_object($parser, $this); + xml_set_element_handler($parser, 'startElement', 'endElement'); + xml_set_character_data_handler($parser, 'dataElement'); + + // Read and parse the content of the file. During parsing, startElement, endElement, and dataElement functions are called. + $file = fopen($filename, 'r'); + while ($data = fread($file, 4096)) { + if (!xml_parse($parser, $data, feof($file))) { + $this->errors->add(sprintf("XML error: %s at line %d", + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser))); + } + } xml_parser_free($parser); if ($file) fclose($file); unlink($filename); @@ -445,59 +213,4 @@ function uncompress($in, $out) { fclose ($out_file); return true; } - - // createGroup function creates a new group. - private function createGroup($fields) { - - global $user; - $mdb2 = getConnection(); - - $columns = '(name, currency, decimal_mark, lang, date_format, time_format, week_start, tracking_mode'. - ', project_required, task_required, record_type, bcc_email, allow_ip, password_complexity, plugins'. - ', lock_spec, workday_minutes, config, created, created_ip, created_by)'; - - $values = ' values ('.$mdb2->quote(trim($fields['name'])); - $values .= ', '.$mdb2->quote(trim($fields['currency'])); - $values .= ', '.$mdb2->quote($fields['decimal_mark']); - $values .= ', '.$mdb2->quote($fields['lang']); - $values .= ', '.$mdb2->quote($fields['date_format']); - $values .= ', '.$mdb2->quote($fields['time_format']); - $values .= ', '.(int)$fields['week_start']; - $values .= ', '.(int)$fields['tracking_mode']; - $values .= ', '.(int)$fields['project_required']; - $values .= ', '.(int)$fields['task_required']; - $values .= ', '.(int)$fields['record_type']; - $values .= ', '.$mdb2->quote($fields['bcc_email']); - $values .= ', '.$mdb2->quote($fields['allow_ip']); - $values .= ', '.$mdb2->quote($fields['password_complexity']); - $values .= ', '.$mdb2->quote($fields['plugins']); - $values .= ', '.$mdb2->quote($fields['lock_spec']); - $values .= ', '.(int)$fields['workday_minutes']; - $values .= ', '.$mdb2->quote($fields['config']); - $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); - $values .= ')'; - - $sql = 'insert into tt_groups '.$columns.$values; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; - - $group_id = $mdb2->lastInsertID('tt_groups', 'id'); - - // Update org_id with group_id. - // NOTE: Both export and import need an additional effort to properly operate on subgroups. - // Currently we are importing one group only, which becomes a top level group. - $sql = "update tt_groups set org_id = $group_id where org_id is NULL and id = $group_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; - - return $group_id; - } - - // insertMonthlyQuota - a helper function to insert a monthly quota. - private function insertMonthlyQuota($group_id, $year, $month, $minutes) { - $mdb2 = getConnection(); - $sql = "INSERT INTO tt_monthly_quotas (group_id, year, month, minutes) values ($group_id, $year, $month, $minutes)"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 04c4015fd..5f015a501 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4362 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4363 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 5210e7673369389701814dab3bf646b7a0d98437 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 4 Nov 2018 20:36:55 +0000 Subject: [PATCH 0276/1848] Starting to work on ttExportHelper2 class as part of subgroup support. --- WEB-INF/lib/ttExportHelper2.class.php | 420 ++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- export.php | 7 +- 3 files changed, 427 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/lib/ttExportHelper2.class.php diff --git a/WEB-INF/lib/ttExportHelper2.class.php b/WEB-INF/lib/ttExportHelper2.class.php new file mode 100644 index 000000000..a34c66fa6 --- /dev/null +++ b/WEB-INF/lib/ttExportHelper2.class.php @@ -0,0 +1,420 @@ +\n"); + fwrite($file, "\n"); + + // Write group info. + fwrite($file, "currency."\" decimal_mark=\"".$user->decimal_mark."\" lang=\"".$user->lang. + "\" date_format=\"".$user->date_format."\" time_format=\"".$user->time_format."\" week_start=\"".$user->week_start. + "\" tracking_mode=\"".$user->tracking_mode."\" project_required=\"".$user->project_required."\" task_required=\"".$user->task_required. + "\" record_type=\"".$user->record_type."\" bcc_email=\"".$user->bcc_email. + "\" plugins=\"".$user->plugins."\" lock_spec=\"".$user->lock_spec."\" workday_minutes=\"".$user->workday_minutes. + "\" config=\"".$user->config. + "\">\n"); + fwrite($file, " group_name."]]>\n"); + fwrite($file, " allow_ip."]]>\n"); + fwrite($file, " password_complexity."]]>\n"); + fwrite($file, "\n"); + + // Prepare role map. + $roles = $this->getRoles(); + foreach ($roles as $key=>$role_item) + $this->roleMap[$role_item['id']] = $key + 1; + + // Prepare user map. + $users = $this->getUsers(); + foreach ($users as $key=>$user_item) + $this->userMap[$user_item['id']] = $key + 1; + + // Prepare project map. + $projects = ttTeamHelper::getAllProjects($user->group_id, true); + foreach ($projects as $key=>$project_item) + $this->projectMap[$project_item['id']] = $key + 1; + + // Prepare task map. + $tasks = ttTeamHelper::getAllTasks($user->group_id, true); + foreach ($tasks as $key=>$task_item) + $this->taskMap[$task_item['id']] = $key + 1; + + // Prepare client map. + $clients = ttTeamHelper::getAllClients($user->group_id, true); + foreach ($clients as $key=>$client_item) + $this->clientMap[$client_item['id']] = $key + 1; + + // Prepare invoice map. + $invoices = ttTeamHelper::getAllInvoices(); + foreach ($invoices as $key=>$invoice_item) + $this->invoiceMap[$invoice_item['id']] = $key + 1; + + // Prepare custom fields map. + $custom_fields = ttTeamHelper::getAllCustomFields($user->group_id); + foreach ($custom_fields as $key=>$custom_field) + $this->customFieldMap[$custom_field['id']] = $key + 1; + + // Prepare custom field options map. + $custom_field_options = ttTeamHelper::getAllCustomFieldOptions($user->group_id); + foreach ($custom_field_options as $key=>$option) + $this->customFieldOptionMap[$option['id']] = $key + 1; + + // Write roles. + fwrite($file, "\n"); + foreach ($roles as $role) { + fwrite($file, " roleMap[$role['id']]."\" rank=\"".$role['rank']."\"". + " rights=\"".$role['rights']."\" status=\"".$role['status']."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + fwrite($file, "\n"); + unset($roles); + + // Write users. + fwrite($file, "\n"); + foreach ($users as $user_item) { + $role_id = $user_item['rank'] == 512 ? 0 : $this->roleMap[$user_item['role_id']]; // Special role_id 0 (not null) for top manager. + fwrite($file, " userMap[$user_item['id']]."\" login=\"".htmlentities($user_item['login'])."\" password=\"".$user_item['password']."\" role_id=\"".$role_id."\" client_id=\"".$this->clientMap[$user_item['client_id']]."\" rate=\"".$user_item['rate']."\" email=\"".$user_item['email']."\" status=\"".$user_item['status']."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + fwrite($file, "\n"); + + // Write tasks. + fwrite($file, "\n"); + foreach ($tasks as $task_item) { + fwrite($file, " taskMap[$task_item['id']]."\" status=\"".$task_item['status']."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + fwrite($file, "\n"); + unset($tasks); + + // Write projects. + fwrite($file, "\n"); + foreach ($projects as $project_item) { + if($project_item['tasks']){ + $tasks = explode(',', $project_item['tasks']); + $tasks_mapped = array(); + foreach ($tasks as $item) + $tasks_mapped[] = $this->taskMap[$item]; + $tasks_str = implode(',', $tasks_mapped); + } + fwrite($file, " projectMap[$project_item['id']]."\" tasks=\"".$tasks_str."\" status=\"".$project_item['status']."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + fwrite($file, "\n"); + unset($projects); + + // Write user to project binds. + fwrite($file, "\n"); + $user_binds = ttTeamHelper::getUserToProjectBinds($user->group_id); + foreach ($user_binds as $bind) { + $user_id = $this->userMap[$bind['user_id']]; + $project_id = $this->projectMap[$bind['project_id']]; + fwrite($file, " \n"); + } + fwrite($file, "\n"); + unset($user_binds); + + // Write clients. + fwrite($file, "\n"); + foreach ($clients as $client_item) { + if($client_item['projects']){ + $projects = explode(',', $client_item['projects']); + $projects_mapped = array(); + foreach ($projects as $item) + $projects_mapped[] = $this->projectMap[$item]; + $projects_str = implode(',', $projects_mapped); + } + fwrite($file, " clientMap[$client_item['id']]."\" tax=\"".$client_item['tax']."\" projects=\"".$projects_str."\" status=\"".$client_item['status']."\">\n"); + fwrite($file, " \n"); + fwrite($file, "
\n"); + fwrite($file, "
\n"); + } + fwrite($file, "
\n"); + unset($clients); + + // Write invoices. + fwrite($file, "\n"); + foreach ($invoices as $invoice_item) { + fwrite($file, " invoiceMap[$invoice_item['id']]."\" date=\"".$invoice_item['date']."\" client_id=\"".$this->clientMap[$invoice_item['client_id']]."\" status=\"".$invoice_item['status']."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + fwrite($file, "\n"); + unset($invoices); + + // Write custom fields. + fwrite($file, "\n"); + foreach ($custom_fields as $custom_field) { + fwrite($file, " customFieldMap[$custom_field['id']]."\" type=\"".$custom_field['type']."\" required=\"".$custom_field['required']."\" status=\"".$custom_field['status']."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + fwrite($file, "\n"); + unset($custom_fields); + + // Write custom field options. + fwrite($file, "\n"); + foreach ($custom_field_options as $option) { + fwrite($file, " customFieldOptionMap[$option['id']]."\" field_id=\"".$this->customFieldMap[$option['field_id']]."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + fwrite($file, "\n"); + unset($custom_field_options); + + // Write monthly quotas. + $quotas = ttTeamHelper::getMonthlyQuotas($user->group_id); + fwrite($file, "\n"); + foreach ($quotas as $quota) { + fwrite($file, " \n"); + } + fwrite($file, "\n"); + + // Write time log entries. + fwrite($file, "\n"); + $key = 0; + foreach ($users as $user_item) { + $records = ttTimeHelper::getAllRecords($user_item['id']); + foreach ($records as $record) { + $key++; + $this->logMap[$record['id']] = $key; + fwrite($file, " userMap[$record['user_id']]."\" date=\"".$record['date']."\" start=\"".$record['start']."\" finish=\"".$record['finish']."\" duration=\"".($record['start']?"":$record['duration'])."\" client_id=\"".$this->clientMap[$record['client_id']]."\" project_id=\"".$this->projectMap[$record['project_id']]."\" task_id=\"".$this->taskMap[$record['task_id']]."\" invoice_id=\"".$this->invoiceMap[$record['invoice_id']]."\" billable=\"".$record['billable']."\" paid=\"".$record['paid']."\" status=\"".$record['status']."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + } + fwrite($file, "\n"); + unset($records); + + // Write custom field log. + $custom_field_log = ttTeamHelper::getCustomFieldLog($user->group_id); + fwrite($file, "\n"); + foreach ($custom_field_log as $entry) { + fwrite($file, " logMap[$entry['log_id']]."\" field_id=\"".$this->customFieldMap[$entry['field_id']]."\" option_id=\"".$this->customFieldOptionMap[$entry['option_id']]."\" status=\"".$entry['status']."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + fwrite($file, "\n"); + unset($custom_field_log); + + // Write expense items. + $expense_items = ttTeamHelper::getExpenseItems($user->group_id); + fwrite($file, "\n"); + foreach ($expense_items as $expense_item) { + fwrite($file, " userMap[$expense_item['user_id']]."\" client_id=\"".$this->clientMap[$expense_item['client_id']]."\" project_id=\"".$this->projectMap[$expense_item['project_id']]."\" cost=\"".$expense_item['cost']."\" invoice_id=\"".$this->invoiceMap[$expense_item['invoice_id']]."\" paid=\"".$expense_item['paid']."\" status=\"".$expense_item['status']."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + fwrite($file, "\n"); + unset($expense_items); + + // Write fav reports. + fwrite($file, "\n"); + $fav_reports = ttTeamHelper::getFavReports($user->group_id); + foreach ($fav_reports as $fav_report) { + $user_list = ''; + if (strlen($fav_report['users']) > 0) { + $arr = explode(',', $fav_report['users']); + foreach ($arr as $k=>$v) { + if (array_key_exists($arr[$k], $this->userMap)) + $user_list .= (strlen($user_list) == 0? '' : ',').$this->userMap[$v]; + } + } + fwrite($file, " userMap[$fav_report['user_id']]."\"". + " client_id=\"".$this->clientMap[$fav_report['client_id']]."\"". + " cf_1_option_id=\"".$this->customFieldOptionMap[$fav_report['cf_1_option_id']]."\"". + " project_id=\"".$this->projectMap[$fav_report['project_id']]."\"". + " task_id=\"".$this->taskMap[$fav_report['task_id']]."\"". + " billable=\"".$fav_report['billable']."\"". + " users=\"".$user_list."\"". + " period=\"".$fav_report['period']."\"". + " period_start=\"".$fav_report['period_start']."\"". + " period_end=\"".$fav_report['period_end']."\"". + " show_client=\"".$fav_report['show_client']."\"". + " show_invoice=\"".$fav_report['show_invoice']."\"". + " show_paid=\"".$fav_report['show_paid']."\"". + " show_ip=\"".$fav_report['show_ip']."\"". + " show_project=\"".$fav_report['show_project']."\"". + " show_start=\"".$fav_report['show_start']."\"". + " show_duration=\"".$fav_report['show_duration']."\"". + " show_cost=\"".$fav_report['show_cost']."\"". + " show_task=\"".$fav_report['show_task']."\"". + " show_end=\"".$fav_report['show_end']."\"". + " show_note=\"".$fav_report['show_note']."\"". + " show_custom_field_1=\"".$fav_report['show_custom_field_1']."\"". + " show_work_units=\"".$fav_report['show_work_units']."\"". + " group_by1=\"".$fav_report['group_by1']."\"". + " group_by2=\"".$fav_report['group_by2']."\"". + " group_by3=\"".$fav_report['group_by3']."\"". + " show_totals_only=\"".$fav_report['show_totals_only']."\">\n"); + fwrite($file, " \n"); + fwrite($file, " \n"); + } + fwrite($file, "\n"); + unset($fav_reports); + + // Cleanup. + unset($users); + $this->roleMap = array(); + $this->userMap = array(); + $this->projectMap = array(); + $this->taskMap = array(); + + fwrite($file, "
\n"); + fclose($file); + + if ($compress) { + $this->fileName = tempnam($dirName, 'tt'); + $this->compress($tmp_file, $this->fileName); + unlink($tmp_file); + } else + $this->fileName = $tmp_file; + + return true; + } + + // getFileName - returns file name. + function getFileName() { + return $this->fileName; + } + + // compress - compresses the content of the $in file into $out file. + function compress($in, $out) { + // Initial checks of file names and permissions. + if (!file_exists($in) || !is_readable ($in)) + return false; + if ((!file_exists($out) && !is_writable(dirname($out))) || (file_exists($out) && !is_writable($out))) + return false; + + $in_file = fopen($in, 'rb'); + + if (function_exists('bzopen')) { + if (!$out_file = bzopen($out, 'w')) + return false; + + while (!feof ($in_file)) { + $buffer = fread($in_file, 4096); + bzwrite($out_file, $buffer, 4096); + } + bzclose($out_file); + } + fclose ($in_file); + return true; + } + + /* + * Note about the utility functions below. + * We have roughly 4 groups of operations: + * 1) Regular system usage for tracking time, etc. + * 2) Registration process - used infrequently. + * 3) Admin usage - used infrequently. + * 4) Export - used infrequently. + * + * It is tempting to have a generic function to get things done for + * all situations. However, as registration, export and admin access are one-off + * operations, while regular system usage is daily and must be efficient, + * the current approach is to have SEPARATE functions for each mode. + * + * This is because each mode requires a slightly different approach, + * and we don't want to over-complicate things. + */ + + // getRoles - obtains all roles defined for group. + function getRoles() { + global $user; + $mdb2 = getConnection(); + + $result = array(); + $sql = "select * from tt_roles where group_id = $user->group_id"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + + // The getUsers obtains all users in group for the purpose of export. + function getUsers() { + global $user; + $mdb2 = getConnection(); + + $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $user->group_id order by upper(u.name)"; // Note: deleted users are included. + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } +} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5f015a501..45a12a655 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4363 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4364 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/export.php b/export.php index 5f7bd02d4..b194adfb3 100644 --- a/export.php +++ b/export.php @@ -28,6 +28,7 @@ require_once('initialize.php'); import('ttExportHelper'); +import('ttExportHelper2'); import('form.Form'); // Access check. @@ -56,7 +57,11 @@ $mime_type = 'application/x-bzip2'; } - $exportHelper = new ttExportHelper(); + if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { + $exportHelper = new ttExportHelper2(); + } else { + $exportHelper = new ttExportHelper(); + } if ($exportHelper->createDataFile($compress)) { header('Pragma: public'); // This is needed for IE8 to download files over https. header('Content-Type: '.$mime_type); From 51818601ad6bd5fafcbc93e171b51f9eaf98486c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 12:43:27 +0000 Subject: [PATCH 0277/1848] Renamed pack tag to org for clarity. --- WEB-INF/lib/ttExportHelper.class.php | 4 ++-- WEB-INF/lib/ttExportHelper2.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttExportHelper.class.php b/WEB-INF/lib/ttExportHelper.class.php index 26c801d48..c5e7802d8 100644 --- a/WEB-INF/lib/ttExportHelper.class.php +++ b/WEB-INF/lib/ttExportHelper.class.php @@ -59,7 +59,7 @@ function createDataFile($compress = false) { // Write XML to the file. fwrite($file, "\n"); - fwrite($file, "\n"); + fwrite($file, "\n"); // Write group info. fwrite($file, "currency."\" decimal_mark=\"".$user->decimal_mark."\" lang=\"".$user->lang. @@ -321,7 +321,7 @@ function createDataFile($compress = false) { $this->projectMap = array(); $this->taskMap = array(); - fwrite($file, "\n"); + fwrite($file, "\n"); fclose($file); if ($compress) { diff --git a/WEB-INF/lib/ttExportHelper2.class.php b/WEB-INF/lib/ttExportHelper2.class.php index a34c66fa6..a179769eb 100644 --- a/WEB-INF/lib/ttExportHelper2.class.php +++ b/WEB-INF/lib/ttExportHelper2.class.php @@ -62,7 +62,7 @@ function createDataFile($compress = false) { // Write XML to the file. fwrite($file, "\n"); - fwrite($file, "\n"); + fwrite($file, "\n"); // Write group info. fwrite($file, "currency."\" decimal_mark=\"".$user->decimal_mark."\" lang=\"".$user->lang. @@ -324,7 +324,7 @@ function createDataFile($compress = false) { $this->projectMap = array(); $this->taskMap = array(); - fwrite($file, "\n"); + fwrite($file, "\n"); fclose($file); if ($compress) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 45a12a655..9581fdb9a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4364 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4365 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 2b02e65a452b9ab911d3a3c3072302f6e39dfec7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 13:00:46 +0000 Subject: [PATCH 0278/1848] Renamed ttExportHelper2 class to ttOrgExportHelper. --- ...tExportHelper2.class.php => ttOrgExportHelper.class.php} | 6 +++--- export.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) rename WEB-INF/lib/{ttExportHelper2.class.php => ttOrgExportHelper.class.php} (99%) diff --git a/WEB-INF/lib/ttExportHelper2.class.php b/WEB-INF/lib/ttOrgExportHelper.class.php similarity index 99% rename from WEB-INF/lib/ttExportHelper2.class.php rename to WEB-INF/lib/ttOrgExportHelper.class.php index a179769eb..a6eb6af8f 100644 --- a/WEB-INF/lib/ttExportHelper2.class.php +++ b/WEB-INF/lib/ttOrgExportHelper.class.php @@ -29,10 +29,10 @@ import('ttTeamHelper'); import('ttTimeHelper'); -// ttExportHelper2 - this class is a future replacement for ttExportHelper. +// ttOrgExportHelper - this class is a future replacement for ttExportHelper. // Currently, it is work in progress. -// When done, it should handle exporting of complex groups containing other groups. -class ttExportHelper2 { +// When done, it should handle export of organizations containing multiple groups. +class ttOrgExportHelper { // TODO: we need a constructor... var $fileName = null; // Name of the file with data. diff --git a/export.php b/export.php index b194adfb3..3d6178148 100644 --- a/export.php +++ b/export.php @@ -28,7 +28,7 @@ require_once('initialize.php'); import('ttExportHelper'); -import('ttExportHelper2'); +import('ttOrgExportHelper'); import('form.Form'); // Access check. @@ -58,7 +58,7 @@ } if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { - $exportHelper = new ttExportHelper2(); + $exportHelper = new ttOrgExportHelper(); } else { $exportHelper = new ttExportHelper(); } From ee95ed0e72258b76ed0280f04d6846d802aefa12 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 13:17:29 +0000 Subject: [PATCH 0279/1848] Renamed constructor function. --- WEB-INF/lib/ttImportHelper.class.php | 2 +- WEB-INF/lib/ttImportHelper2.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 69af9e12c..42c7102be 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -67,7 +67,7 @@ class ttImportHelper { var $logMap = array(); // Time log ids. // Constructor. - function ttImportHelper(&$errors) { + function __construct(&$errors) { $this->errors = &$errors; } diff --git a/WEB-INF/lib/ttImportHelper2.class.php b/WEB-INF/lib/ttImportHelper2.class.php index 58bfa8866..5de6d8c59 100644 --- a/WEB-INF/lib/ttImportHelper2.class.php +++ b/WEB-INF/lib/ttImportHelper2.class.php @@ -51,7 +51,7 @@ class ttImportHelper2 { var $firstPass = true; // True during first pass through the file. // Constructor. - function ttImportHelper2(&$errors) { + function __construct(&$errors) { $this->errors = &$errors; } From abfd3bbc6a72c55b30d48466b2719804ebee6733 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 14:01:29 +0000 Subject: [PATCH 0280/1848] Started work on ttGroupExportHelper class for exporting single groups. --- WEB-INF/lib/ttGroupExportHelper.class.php | 56 +++++++++++++++++++++++ WEB-INF/lib/ttOrgExportHelper.class.php | 1 + 2 files changed, 57 insertions(+) create mode 100644 WEB-INF/lib/ttGroupExportHelper.class.php diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php new file mode 100644 index 000000000..9ac4464aa --- /dev/null +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -0,0 +1,56 @@ +group_id = $group_id; + $this->file = $file; + $this->indentation = $indentation; + + // TODO: Build a list of subgroups here. + } + + // writeData writes group data into file. + function writeData() { + // TODO: write code here. + // + // Call itself recursively for all subgroups. + } +} diff --git a/WEB-INF/lib/ttOrgExportHelper.class.php b/WEB-INF/lib/ttOrgExportHelper.class.php index a6eb6af8f..07ad7488b 100644 --- a/WEB-INF/lib/ttOrgExportHelper.class.php +++ b/WEB-INF/lib/ttOrgExportHelper.class.php @@ -28,6 +28,7 @@ import('ttTeamHelper'); import('ttTimeHelper'); +import('ttGroupExportHelper'); // ttOrgExportHelper - this class is a future replacement for ttExportHelper. // Currently, it is work in progress. From 46e93b281cb1460848b14c9e6109789b7949072b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 14:29:21 +0000 Subject: [PATCH 0281/1848] A bit more work in progress on new export. --- WEB-INF/lib/ttGroupExportHelper.class.php | 5 + WEB-INF/lib/ttOrgExportHelper.class.php | 330 +--------------------- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 11 insertions(+), 326 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 9ac4464aa..331385469 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -50,6 +50,11 @@ function __construct($group_id, $file, $indentation) { // writeData writes group data into file. function writeData() { // TODO: write code here. + + // Write group info. Something dummy for now to test... + fwrite($this->file, $this->indentation."\n"); + fwrite($this->file, $this->indentation."\n"); + // // // Call itself recursively for all subgroups. } diff --git a/WEB-INF/lib/ttOrgExportHelper.class.php b/WEB-INF/lib/ttOrgExportHelper.class.php index 07ad7488b..aa9c9051d 100644 --- a/WEB-INF/lib/ttOrgExportHelper.class.php +++ b/WEB-INF/lib/ttOrgExportHelper.class.php @@ -34,22 +34,10 @@ // Currently, it is work in progress. // When done, it should handle export of organizations containing multiple groups. class ttOrgExportHelper { - // TODO: we need a constructor... - var $fileName = null; // Name of the file with data. - // The following arrays are maps between entity ids in the file versus the database. - // We write to the file sequentially (1,2,3...) while in the database the entities have different ids. - var $userMap = array(); // User ids. - var $roleMap = array(); // Role ids. - var $projectMap = array(); // Project ids. - var $taskMap = array(); // Task ids. - var $clientMap = array(); // Client ids. - var $invoiceMap = array(); // Invoice ids. - var $customFieldMap = array(); // Custom field ids. - var $customFieldOptionMap = array(); // Custop field option ids. - var $logMap = array(); // Time log ids. + var $fileName = null; // Name of file with data. - // createDataFile creates a file with all data for a given group. + // createDataFile creates a file with all data for the entire organization. function createDataFile($compress = false) { global $user; @@ -65,265 +53,9 @@ function createDataFile($compress = false) { fwrite($file, "\n"); fwrite($file, "\n"); - // Write group info. - fwrite($file, "currency."\" decimal_mark=\"".$user->decimal_mark."\" lang=\"".$user->lang. - "\" date_format=\"".$user->date_format."\" time_format=\"".$user->time_format."\" week_start=\"".$user->week_start. - "\" tracking_mode=\"".$user->tracking_mode."\" project_required=\"".$user->project_required."\" task_required=\"".$user->task_required. - "\" record_type=\"".$user->record_type."\" bcc_email=\"".$user->bcc_email. - "\" plugins=\"".$user->plugins."\" lock_spec=\"".$user->lock_spec."\" workday_minutes=\"".$user->workday_minutes. - "\" config=\"".$user->config. - "\">\n"); - fwrite($file, " group_name."]]>\n"); - fwrite($file, " allow_ip."]]>\n"); - fwrite($file, " password_complexity."]]>\n"); - fwrite($file, "\n"); - - // Prepare role map. - $roles = $this->getRoles(); - foreach ($roles as $key=>$role_item) - $this->roleMap[$role_item['id']] = $key + 1; - - // Prepare user map. - $users = $this->getUsers(); - foreach ($users as $key=>$user_item) - $this->userMap[$user_item['id']] = $key + 1; - - // Prepare project map. - $projects = ttTeamHelper::getAllProjects($user->group_id, true); - foreach ($projects as $key=>$project_item) - $this->projectMap[$project_item['id']] = $key + 1; - - // Prepare task map. - $tasks = ttTeamHelper::getAllTasks($user->group_id, true); - foreach ($tasks as $key=>$task_item) - $this->taskMap[$task_item['id']] = $key + 1; - - // Prepare client map. - $clients = ttTeamHelper::getAllClients($user->group_id, true); - foreach ($clients as $key=>$client_item) - $this->clientMap[$client_item['id']] = $key + 1; - - // Prepare invoice map. - $invoices = ttTeamHelper::getAllInvoices(); - foreach ($invoices as $key=>$invoice_item) - $this->invoiceMap[$invoice_item['id']] = $key + 1; - - // Prepare custom fields map. - $custom_fields = ttTeamHelper::getAllCustomFields($user->group_id); - foreach ($custom_fields as $key=>$custom_field) - $this->customFieldMap[$custom_field['id']] = $key + 1; - - // Prepare custom field options map. - $custom_field_options = ttTeamHelper::getAllCustomFieldOptions($user->group_id); - foreach ($custom_field_options as $key=>$option) - $this->customFieldOptionMap[$option['id']] = $key + 1; - - // Write roles. - fwrite($file, "\n"); - foreach ($roles as $role) { - fwrite($file, " roleMap[$role['id']]."\" rank=\"".$role['rank']."\"". - " rights=\"".$role['rights']."\" status=\"".$role['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($roles); - - // Write users. - fwrite($file, "\n"); - foreach ($users as $user_item) { - $role_id = $user_item['rank'] == 512 ? 0 : $this->roleMap[$user_item['role_id']]; // Special role_id 0 (not null) for top manager. - fwrite($file, " userMap[$user_item['id']]."\" login=\"".htmlentities($user_item['login'])."\" password=\"".$user_item['password']."\" role_id=\"".$role_id."\" client_id=\"".$this->clientMap[$user_item['client_id']]."\" rate=\"".$user_item['rate']."\" email=\"".$user_item['email']."\" status=\"".$user_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - - // Write tasks. - fwrite($file, "\n"); - foreach ($tasks as $task_item) { - fwrite($file, " taskMap[$task_item['id']]."\" status=\"".$task_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($tasks); - - // Write projects. - fwrite($file, "\n"); - foreach ($projects as $project_item) { - if($project_item['tasks']){ - $tasks = explode(',', $project_item['tasks']); - $tasks_mapped = array(); - foreach ($tasks as $item) - $tasks_mapped[] = $this->taskMap[$item]; - $tasks_str = implode(',', $tasks_mapped); - } - fwrite($file, " projectMap[$project_item['id']]."\" tasks=\"".$tasks_str."\" status=\"".$project_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($projects); - - // Write user to project binds. - fwrite($file, "\n"); - $user_binds = ttTeamHelper::getUserToProjectBinds($user->group_id); - foreach ($user_binds as $bind) { - $user_id = $this->userMap[$bind['user_id']]; - $project_id = $this->projectMap[$bind['project_id']]; - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($user_binds); - - // Write clients. - fwrite($file, "\n"); - foreach ($clients as $client_item) { - if($client_item['projects']){ - $projects = explode(',', $client_item['projects']); - $projects_mapped = array(); - foreach ($projects as $item) - $projects_mapped[] = $this->projectMap[$item]; - $projects_str = implode(',', $projects_mapped); - } - fwrite($file, " clientMap[$client_item['id']]."\" tax=\"".$client_item['tax']."\" projects=\"".$projects_str."\" status=\"".$client_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, "
\n"); - fwrite($file, "
\n"); - } - fwrite($file, "
\n"); - unset($clients); - - // Write invoices. - fwrite($file, "\n"); - foreach ($invoices as $invoice_item) { - fwrite($file, " invoiceMap[$invoice_item['id']]."\" date=\"".$invoice_item['date']."\" client_id=\"".$this->clientMap[$invoice_item['client_id']]."\" status=\"".$invoice_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($invoices); - - // Write custom fields. - fwrite($file, "\n"); - foreach ($custom_fields as $custom_field) { - fwrite($file, " customFieldMap[$custom_field['id']]."\" type=\"".$custom_field['type']."\" required=\"".$custom_field['required']."\" status=\"".$custom_field['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($custom_fields); - - // Write custom field options. - fwrite($file, "\n"); - foreach ($custom_field_options as $option) { - fwrite($file, " customFieldOptionMap[$option['id']]."\" field_id=\"".$this->customFieldMap[$option['field_id']]."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($custom_field_options); - - // Write monthly quotas. - $quotas = ttTeamHelper::getMonthlyQuotas($user->group_id); - fwrite($file, "\n"); - foreach ($quotas as $quota) { - fwrite($file, " \n"); - } - fwrite($file, "\n"); - - // Write time log entries. - fwrite($file, "\n"); - $key = 0; - foreach ($users as $user_item) { - $records = ttTimeHelper::getAllRecords($user_item['id']); - foreach ($records as $record) { - $key++; - $this->logMap[$record['id']] = $key; - fwrite($file, " userMap[$record['user_id']]."\" date=\"".$record['date']."\" start=\"".$record['start']."\" finish=\"".$record['finish']."\" duration=\"".($record['start']?"":$record['duration'])."\" client_id=\"".$this->clientMap[$record['client_id']]."\" project_id=\"".$this->projectMap[$record['project_id']]."\" task_id=\"".$this->taskMap[$record['task_id']]."\" invoice_id=\"".$this->invoiceMap[$record['invoice_id']]."\" billable=\"".$record['billable']."\" paid=\"".$record['paid']."\" status=\"".$record['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - } - fwrite($file, "\n"); - unset($records); - - // Write custom field log. - $custom_field_log = ttTeamHelper::getCustomFieldLog($user->group_id); - fwrite($file, "\n"); - foreach ($custom_field_log as $entry) { - fwrite($file, " logMap[$entry['log_id']]."\" field_id=\"".$this->customFieldMap[$entry['field_id']]."\" option_id=\"".$this->customFieldOptionMap[$entry['option_id']]."\" status=\"".$entry['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($custom_field_log); - - // Write expense items. - $expense_items = ttTeamHelper::getExpenseItems($user->group_id); - fwrite($file, "\n"); - foreach ($expense_items as $expense_item) { - fwrite($file, " userMap[$expense_item['user_id']]."\" client_id=\"".$this->clientMap[$expense_item['client_id']]."\" project_id=\"".$this->projectMap[$expense_item['project_id']]."\" cost=\"".$expense_item['cost']."\" invoice_id=\"".$this->invoiceMap[$expense_item['invoice_id']]."\" paid=\"".$expense_item['paid']."\" status=\"".$expense_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($expense_items); - - // Write fav reports. - fwrite($file, "\n"); - $fav_reports = ttTeamHelper::getFavReports($user->group_id); - foreach ($fav_reports as $fav_report) { - $user_list = ''; - if (strlen($fav_report['users']) > 0) { - $arr = explode(',', $fav_report['users']); - foreach ($arr as $k=>$v) { - if (array_key_exists($arr[$k], $this->userMap)) - $user_list .= (strlen($user_list) == 0? '' : ',').$this->userMap[$v]; - } - } - fwrite($file, " userMap[$fav_report['user_id']]."\"". - " client_id=\"".$this->clientMap[$fav_report['client_id']]."\"". - " cf_1_option_id=\"".$this->customFieldOptionMap[$fav_report['cf_1_option_id']]."\"". - " project_id=\"".$this->projectMap[$fav_report['project_id']]."\"". - " task_id=\"".$this->taskMap[$fav_report['task_id']]."\"". - " billable=\"".$fav_report['billable']."\"". - " users=\"".$user_list."\"". - " period=\"".$fav_report['period']."\"". - " period_start=\"".$fav_report['period_start']."\"". - " period_end=\"".$fav_report['period_end']."\"". - " show_client=\"".$fav_report['show_client']."\"". - " show_invoice=\"".$fav_report['show_invoice']."\"". - " show_paid=\"".$fav_report['show_paid']."\"". - " show_ip=\"".$fav_report['show_ip']."\"". - " show_project=\"".$fav_report['show_project']."\"". - " show_start=\"".$fav_report['show_start']."\"". - " show_duration=\"".$fav_report['show_duration']."\"". - " show_cost=\"".$fav_report['show_cost']."\"". - " show_task=\"".$fav_report['show_task']."\"". - " show_end=\"".$fav_report['show_end']."\"". - " show_note=\"".$fav_report['show_note']."\"". - " show_custom_field_1=\"".$fav_report['show_custom_field_1']."\"". - " show_work_units=\"".$fav_report['show_work_units']."\"". - " group_by1=\"".$fav_report['group_by1']."\"". - " group_by2=\"".$fav_report['group_by2']."\"". - " group_by3=\"".$fav_report['group_by3']."\"". - " show_totals_only=\"".$fav_report['show_totals_only']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($fav_reports); - - // Cleanup. - unset($users); - $this->roleMap = array(); - $this->userMap = array(); - $this->projectMap = array(); - $this->taskMap = array(); + // Use ttGroupExportHelper to export all groups. + $groupExportHelper = new ttGroupExportHelper($user->group_id, $file, ' '); // 2 spaces indentation for home group. + $groupExportHelper->writeData(); fwrite($file, "
\n"); fclose($file); @@ -366,56 +98,4 @@ function compress($in, $out) { fclose ($in_file); return true; } - - /* - * Note about the utility functions below. - * We have roughly 4 groups of operations: - * 1) Regular system usage for tracking time, etc. - * 2) Registration process - used infrequently. - * 3) Admin usage - used infrequently. - * 4) Export - used infrequently. - * - * It is tempting to have a generic function to get things done for - * all situations. However, as registration, export and admin access are one-off - * operations, while regular system usage is daily and must be efficient, - * the current approach is to have SEPARATE functions for each mode. - * - * This is because each mode requires a slightly different approach, - * and we don't want to over-complicate things. - */ - - // getRoles - obtains all roles defined for group. - function getRoles() { - global $user; - $mdb2 = getConnection(); - - $result = array(); - $sql = "select * from tt_roles where group_id = $user->group_id"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - - // The getUsers obtains all users in group for the purpose of export. - function getUsers() { - global $user; - $mdb2 = getConnection(); - - $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $user->group_id order by upper(u.name)"; // Note: deleted users are included. - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9581fdb9a..af3f176f6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4365 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4366 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9d9131123acc4790f51cf844144ca144bbef9a28 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 15:40:55 +0000 Subject: [PATCH 0282/1848] A bit more progress on new export. --- WEB-INF/lib/ttGroupExportHelper.class.php | 29 +++++++++++++++++------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 331385469..59a19be29 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -33,18 +33,29 @@ // When done, it should handle export of organizations containing multiple groups. class ttGroupExportHelper { - var $group_id = null; // Group we are exporting. - var $file = null; // File to write to. - var $indentation = null; // A string consisting of a number of spaces. + var $group_id = null; // Group we are exporting. + var $file = null; // File to write to. + var $indentation = null; // A string consisting of a number of spaces. + var $subgroups = array(); // Immediate subgroups. // Constructor. function __construct($group_id, $file, $indentation) { + global $user; $this->group_id = $group_id; $this->file = $file; $this->indentation = $indentation; - // TODO: Build a list of subgroups here. + // Build a list of subgroups. + $mdb2 = getConnection(); + $sql = "select id from tt_groups". + " where status = 1 and parent_id = $this->group_id and org_id = $user->org_id order by id desc"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $this->subgroups[] = $val; + } + } } // writeData writes group data into file. @@ -53,9 +64,13 @@ function writeData() { // Write group info. Something dummy for now to test... fwrite($this->file, $this->indentation."\n"); - fwrite($this->file, $this->indentation."\n"); - // - // + // Call itself recursively for all subgroups. + foreach ($this->subgroups as $subgroup) { + $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); + $subgroup_helper->writeData(); + } + + fwrite($this->file, $this->indentation."\n"); } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index af3f176f6..5b275168d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4366 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4367 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 60c61508f8586f489fc8795c93d9bd45e41467c1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 16:53:55 +0000 Subject: [PATCH 0283/1848] Another small iteration for new export. --- WEB-INF/lib/ttGroupExportHelper.class.php | 31 +++++++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 59a19be29..364f984dc 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -49,7 +49,7 @@ function __construct($group_id, $file, $indentation) { // Build a list of subgroups. $mdb2 = getConnection(); $sql = "select id from tt_groups". - " where status = 1 and parent_id = $this->group_id and org_id = $user->org_id order by id desc"; + " where status = 1 and parent_id = $this->group_id and org_id = $user->org_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -58,14 +58,35 @@ function __construct($group_id, $file, $indentation) { } } + // getGroupData obtains group attributes for export. + function getGroupData() { + global $user; + + $mdb2 = getConnection(); + $sql = "select name, currency, lang from tt_groups". + " where status = 1 and id = $this->group_id and org_id = $user->org_id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + } + return $val; + } + // writeData writes group data into file. function writeData() { - // TODO: write code here. - // Write group info. Something dummy for now to test... - fwrite($this->file, $this->indentation."\n"); + // Write group info. + $group = $this->getGroupData(); + $group_part = "file, $this->indentation.$group_part); - // Call itself recursively for all subgroups. + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); $subgroup_helper->writeData(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5b275168d..058c96fe2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4367 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4368 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 40263b0f447ad572e5ba029bbaf9e5c47c4329bb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 18:39:12 +0000 Subject: [PATCH 0284/1848] More progress on new export, adding users to output. --- WEB-INF/lib/ttGroupExportHelper.class.php | 77 ++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 364f984dc..56533e10d 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -38,6 +38,12 @@ class ttGroupExportHelper { var $indentation = null; // A string consisting of a number of spaces. var $subgroups = array(); // Immediate subgroups. + // The following arrays are maps between entity ids in the file versus the database. + // We write to the file sequentially (1,2,3...) while in the database the entities have different ids. + var $userMap = array(); // User ids. + var $roleMap = array(); // Role ids. + var $clientMap = array(); // Client ids. + // Constructor. function __construct($group_id, $file, $indentation) { global $user; @@ -61,8 +67,8 @@ function __construct($group_id, $file, $indentation) { // getGroupData obtains group attributes for export. function getGroupData() { global $user; - $mdb2 = getConnection(); + $sql = "select name, currency, lang from tt_groups". " where status = 1 and id = $this->group_id and org_id = $user->org_id"; $res = $mdb2->query($sql); @@ -72,6 +78,42 @@ function getGroupData() { return $val; } + // The getUsers obtains all users in group for the purpose of export. + function getUsers() { + global $user; + $mdb2 = getConnection(); + + $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id)". + " where u.group_id = $this->group_id and u.org_id = $user->org_id order by upper(u.name)"; // Note: deleted users are included. + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + + // getRoles - obtains all roles defined for group. + function getRoles() { + global $user; + $mdb2 = getConnection(); + + $result = array(); + $sql = "select * from tt_roles where group_id = $this->group_id"; // and org_id = $user->org_id <-- add this when possible + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + // writeData writes group data into file. function writeData() { @@ -86,6 +128,39 @@ function writeData() { // Write group info. fwrite($this->file, $this->indentation.$group_part); + // Prepare user map. + $users = $this->getUsers(); + foreach ($users as $key=>$user_item) + $this->userMap[$user_item['id']] = $key + 1; + + // Prepare role map. + $roles = $this->getRoles(); + foreach ($roles as $key=>$role_item) + $this->roleMap[$role_item['id']] = $key + 1; + + // Prepare client map. + $clients = ttTeamHelper::getAllClients($this->group_id, true); + foreach ($clients as $key=>$client_item) + $this->clientMap[$client_item['id']] = $key + 1; + + // Write users. + fwrite($this->file, $this->indentation."\n"); + foreach ($users as $user_item) { + $role_id = $user_item['rank'] == 512 ? 0 : $this->roleMap[$user_item['role_id']]; // Special role_id 0 (not null) for top manager. + $user_part = $this->indentation.' '."userMap[$user_item['id']]."\""; + $user_part .= " name=\"".htmlentities($user_item['name'])."\""; + $user_part .= " login=\"".htmlentities($user_item['login'])."\""; + $user_part .= " password=\"".$user_item['password']."\""; + $user_part .= " role_id=\"".$role_id."\""; + $user_part .= " client_id=\"".$this->clientMap[$user_item['client_id']]."\""; + $user_part .= " rate=\"".$user_item['rate']."\""; + $user_part .= " email=\"".$user_item['email']."\""; + $user_part .= " status=\"".$user_item['status']."\""; + $user_part .= ">\n"; + fwrite($this->file, $user_part); + } + fwrite($this->file, $this->indentation."\n"); + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 058c96fe2..959fe31d3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.07.4368 | Copyright © Anuko | +  Anuko Time Tracker 1.18.07.4369 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 87b3867d52dbaf6c3db44cbcbe4d96a4def12dd2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 18:59:19 +0000 Subject: [PATCH 0285/1848] Introduced org_id in tt_roles table for better security and maintenance. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 959fe31d3..fe0ad54f6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.07.4369 | Copyright © Anuko | +  Anuko Time Tracker 1.18.08.4370 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 5baff57e6..b57f157cc 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -956,7 +956,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11805"]) { + if ($_POST["convert11797to11808"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -968,6 +968,9 @@ function setChange($sql) { setChange("ALTER TABLE `tt_users` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.06') set org_id = group_id where org_id is null"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.07', modified = now() where param_name = 'version_db' and param_value = '1.18.06'"); + setChange("ALTER TABLE `tt_roles` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.07') set org_id = group_id where org_id is null"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.08', modified = now() where param_name = 'version_db' and param_value = '1.18.07'"); } if ($_POST["cleanup"]) { @@ -1013,7 +1016,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.05) + Create database structure (v1.18.08)
(applies only to new installations, do not execute when updating)
@@ -1058,8 +1061,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.05)Update database structure (v1.17.97 to v1.18.08)
diff --git a/mysql.sql b/mysql.sql index bfa26a0da..79e2b3ff3 100644 --- a/mysql.sql +++ b/mysql.sql @@ -53,6 +53,7 @@ CREATE TABLE `tt_groups` ( CREATE TABLE `tt_roles` ( `id` int(11) NOT NULL auto_increment, # Role id. Identifies roles for all groups on the server. `group_id` int(11) NOT NULL, # Group id the role is defined for. + `org_id` int(11) default NULL, # Organization id. `name` varchar(80) default NULL, # Role name - custom role name. In case we are editing a # predefined role (USER, etc.), we can rename the role here. `description` varchar(255) default NULL, # Role description. @@ -459,4 +460,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.07', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.08', now()); # TODO: change when structure changes. From 207eb3b5bf14dcfeefead3a894c4056d06a102ea Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 20:36:24 +0000 Subject: [PATCH 0286/1848] Started to populate org_id furing creation of pre-defined roles. --- WEB-INF/lib/ttRoleHelper.class.php | 10 +++++----- WEB-INF/lib/ttTeamHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 958f034fc..51c95b1d1 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -193,7 +193,7 @@ static function createPredefinedRoles($group_id, $lang) $name = $mdb2->quote($i18n->get('role.user.label')); $description = $mdb2->quote($i18n->get('role.user.description')); $rights = $mdb2->quote($rights_user); - $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($group_id, $name, $description, 4, $rights, 1)"; + $sql = "insert into tt_roles (group_id, org_id, name, description, rank, rights, status) values($group_id, $group_id, $name, $description, 4, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -201,7 +201,7 @@ static function createPredefinedRoles($group_id, $lang) $name = $mdb2->quote($i18n->get('role.client.label')); $description = $mdb2->quote($i18n->get('role.client.description')); $rights = $mdb2->quote($rights_client); - $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($group_id, $name, $description, 16, $rights, 1)"; + $sql = "insert into tt_roles (group_id, org_id, name, description, rank, rights, status) values($group_id, $group_id, $name, $description, 16, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -209,7 +209,7 @@ static function createPredefinedRoles($group_id, $lang) $name = $mdb2->quote($i18n->get('role.comanager.label')); $description = $mdb2->quote($i18n->get('role.comanager.description')); $rights = $mdb2->quote($rights_comanager); - $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($group_id, $name, $description, 68, $rights, 1)"; + $sql = "insert into tt_roles (group_id, org_id, name, description, rank, rights, status) values($group_id, $group_id, $name, $description, 68, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -217,7 +217,7 @@ static function createPredefinedRoles($group_id, $lang) $name = $mdb2->quote($i18n->get('role.manager.label')); $description = $mdb2->quote($i18n->get('role.manager.description')); $rights = $mdb2->quote($rights_manager); - $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($group_id, $name, $description, 324, $rights, 1)"; + $sql = "insert into tt_roles (group_id, org_id, name, description, rank, rights, status) values($group_id, $group_id, $name, $description, 324, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -226,7 +226,7 @@ static function createPredefinedRoles($group_id, $lang) $name = $mdb2->quote($i18n->get('role.supervisor.label')); $description = $mdb2->quote($i18n->get('role.supervisor.description')); $rights = $mdb2->quote($rights_supervisor); - $sql = "insert into tt_roles (group_id, name, description, rank, rights, status) values($group_id, $name, $description, 12, $rights, 0)"; + $sql = "insert into tt_roles (group_id, org_id, name, description, rank, rights, status) values($group_id, $group_id, $name, $description, 12, $rights, 0)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index eafc9167c..8b9d7ed66 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -290,7 +290,7 @@ static function getActiveRolesForUser() $result = array(); $mdb2 = getConnection(); - $sql = "select id, name, description, rank, rights from tt_roles where group_id = $user->group_id and rank < $user->rank and status = 1 order by rank"; + $sql = "select id, name, description, rank, rights from tt_roles where group_id = $user->group_id and org_id = $user->org_id and rank < $user->rank and status = 1 order by rank"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -348,7 +348,7 @@ static function getInactiveRolesForUser() $result = array(); $mdb2 = getConnection(); - $sql = "select id, name, description, rank, rights from tt_roles where group_id = $user->group_id and rank < $user->rank and status = 0 order by rank"; + $sql = "select id, name, description, rank, rights from tt_roles where group_id = $user->group_id and org_id = $user->org_id and rank < $user->rank and status = 0 order by rank"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fe0ad54f6..90828c1b6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.08.4370 | Copyright © Anuko | +  Anuko Time Tracker 1.18.08.4371 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 96dd4d9712381a9c2d9df96961f96dc4c2dcc6f2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 21:49:07 +0000 Subject: [PATCH 0287/1848] Fixed adding custom role with org_id field population. --- WEB-INF/lib/ttImportHelper.class.php | 1 + WEB-INF/lib/ttRoleHelper.class.php | 5 +++-- WEB-INF/templates/footer.tpl | 2 +- role_add.php | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 42c7102be..e250a4fca 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -152,6 +152,7 @@ function endElement($parser, $name) { foreach ($this->roles as $key=>$role_item) { $role_id = ttRoleHelper::insert(array( 'group_id' => $this->group_id, + 'org_id' => $this->org_id, 'name' => $role_item['NAME'], 'rank' => $role_item['RANK'], 'rights' => $role_item['RIGHTS'], diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 51c95b1d1..e5bf6a7dc 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -154,14 +154,15 @@ static function insert($fields) $mdb2 = getConnection(); $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; $name = $fields['name']; $rank = (int) $fields['rank']; $description = $fields['description']; $rights = $fields['rights']; $status = $fields['status']; - $sql = "insert into tt_roles (group_id, name, rank, description, rights, status) - values ($group_id, ".$mdb2->quote($name).", $rank, ".$mdb2->quote($description).", ".$mdb2->quote($rights).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_roles (group_id, org_id, name, rank, description, rights, status) + values ($group_id, $org_id, ".$mdb2->quote($name).", $rank, ".$mdb2->quote($description).", ".$mdb2->quote($rights).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 90828c1b6..6430f8a68 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.08.4371 | Copyright © Anuko | +  Anuko Time Tracker 1.18.08.4372 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/role_add.php b/role_add.php index c8df24c73..cb3d6f407 100644 --- a/role_add.php +++ b/role_add.php @@ -63,6 +63,7 @@ // Insert a role with default user rights. if (ttRoleHelper::insert(array( 'group_id' => $user->group_id, + 'org_id' => $user->org_id, 'name' => $cl_name, 'rank' => $cl_rank, 'description' => $cl_description, From 566bd317d329af1fe9935edfcefafee7f07ebc2b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 5 Nov 2018 22:18:37 +0000 Subject: [PATCH 0288/1848] Fixed import and export of role descriptions. --- WEB-INF/lib/ttExportHelper.class.php | 1 + WEB-INF/lib/ttImportHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttExportHelper.class.php b/WEB-INF/lib/ttExportHelper.class.php index c5e7802d8..310af9137 100644 --- a/WEB-INF/lib/ttExportHelper.class.php +++ b/WEB-INF/lib/ttExportHelper.class.php @@ -120,6 +120,7 @@ function createDataFile($compress = false) { fwrite($file, " roleMap[$role['id']]."\" rank=\"".$role['rank']."\"". " rights=\"".$role['rights']."\" status=\"".$role['status']."\">\n"); fwrite($file, " \n"); + fwrite($file, " \n"); fwrite($file, " \n"); } fwrite($file, "\n"); diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index e250a4fca..8c6fd0c08 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -154,6 +154,7 @@ function endElement($parser, $name) { 'group_id' => $this->group_id, 'org_id' => $this->org_id, 'name' => $role_item['NAME'], + 'description' => $role_item['DESCRIPTION'], 'rank' => $role_item['RANK'], 'rights' => $role_item['RIGHTS'], 'status' => $role_item['STATUS'])); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6430f8a68..bd83dd666 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.08.4372 | Copyright © Anuko | +  Anuko Time Tracker 1.18.08.4373 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From cc89430b244535c67dbb7d1f8813a4ba56b1ffc0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 6 Nov 2018 15:25:31 +0000 Subject: [PATCH 0289/1848] More use of getActiveGroup as part of ongoing subgroup support. --- WEB-INF/lib/ttClientHelper.class.php | 15 +++++++-------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index afa7afbd1..855458987 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -41,8 +41,8 @@ static function getClient($client_id, $all_fields = false) { else $sql .= 'name '; - $sql .= "from tt_clients where group_id = $user->group_id - and id = $client_id and (status = 1 or status = 0)"; + $sql .= "from tt_clients where group_id = ".$user->getActiveGroup(). + " and id = $client_id and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -59,8 +59,7 @@ static function getClients() $result = array(); $mdb2 = getConnection(); - $sql = "select id, name from tt_clients - where group_id = $user->group_id and (status = 0 or status = 1) order by upper(name)"; + $sql = "select id, name from tt_clients where group_id = ".$user->getActiveGroup()." and (status = 0 or status = 1) order by upper(name)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -76,8 +75,8 @@ static function getClientByName($client_name) { $mdb2 = getConnection(); global $user; - $sql = "select id from tt_clients where group_id = $user->group_id and name = ". - $mdb2->quote($client_name)." and (status = 1 or status = 0)"; + $sql = "select id from tt_clients where group_id = ".$user->getActiveGroup(). + " and name = ".$mdb2->quote($client_name)." and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -95,8 +94,8 @@ static function getDeletedClient($client_id) { $mdb2 = getConnection(); global $user; - $sql = "select name, address from tt_clients where group_id = $user->group_id - and id = $client_id and status is NULL"; + $sql = "select name, address from tt_clients where group_id = ".$user->getActiveGroup(). + " and id = $client_id and status is NULL"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bd83dd666..cca966e63 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.08.4373 | Copyright © Anuko | +  Anuko Time Tracker 1.18.08.4374 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e7152db9fac2662f92f2ea37723de3f1ec5f93f3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 6 Nov 2018 16:47:40 +0000 Subject: [PATCH 0290/1848] More refactoring as part of subgroup support. --- WEB-INF/lib/ttClientHelper.class.php | 38 ++++++---------------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 855458987..19409b905 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -137,7 +137,7 @@ static function delete($id, $delete_client_entries) { // Handle invoices. if ($delete_client_entries) { - $sql = "update tt_invoices set status = NULL where client_id = $id and group_id = $user->group_id"; + $sql = "update tt_invoices set status = NULL where client_id = $id and group_id = ".$user->getActiveGroup(); $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -150,13 +150,13 @@ static function delete($id, $delete_client_entries) { return false; // Handle users for client. - $sql = 'update tt_users set status = NULL'.$modified_part." where client_id = $id and group_id = $user->group_id"; + $sql = 'update tt_users set status = NULL'.$modified_part." where client_id = $id and group_id = ".$user->getActiveGroup(); $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark client deleted. - $sql = "update tt_clients set status = NULL where id = $id and group_id = $user->group_id"; + $sql = "update tt_clients set status = NULL where id = $id and group_id = ".$user->getActiveGroup(); $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -235,7 +235,8 @@ static function update($fields) // Update client properties in tt_clients table. $comma_separated = implode(",", $projects); // This is a comma-separated list of associated project ids. $sql = "update tt_clients set name = ".$mdb2->quote($name).", address = ".$mdb2->quote($address). - ", tax = $tax, projects = ".$mdb2->quote($comma_separated).", status = $status where group_id = ".$user->group_id." and id = ".$id; + ", tax = $tax, projects = ".$mdb2->quote($comma_separated).", status = $status". + " where group_id = ".$user->getActiveGroup()." and id = ".$id; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -269,9 +270,9 @@ static function getAssignedProjects($client_id) $mdb2 = getConnection(); // Do a query with inner join to get assigned projects. - $sql = "select p.id, p.name from tt_projects p - inner join tt_client_project_binds cpb on (cpb.client_id = $client_id and cpb.project_id = p.id) - where p.group_id = $user->group_id and p.status = 1 order by p.name"; + $sql = "select p.id, p.name from tt_projects p". + " inner join tt_client_project_binds cpb on (cpb.client_id = $client_id and cpb.project_id = p.id)". + " where p.group_id = ".$user->getActiveGroup()." and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -303,27 +304,4 @@ static function getClientsForUser() } return $result; } - - // getAssignedProjectsForUser - returns an array of projects assigned to a user and associatied with a client. - static function getAssignedProjectsForUser($client_id) - { - global $user; - $user_id = $user->getActiveUser(); - - $result = array(); - $mdb2 = getConnection(); - - // Do a query with inner join to get assigned projects. - $sql = "select p.id, p.name from tt_projects p - inner join tt_client_project_binds cpb on (cpb.client_id = $client_id and cpb.project_id = p.id) - inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id and upb.status = 1) - where p.group_id = $user->group_id and p.status = 1 order by p.name"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - } - return $result; - } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index cca966e63..bbff9a4c5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.08.4374 | Copyright © Anuko | +  Anuko Time Tracker 1.18.08.4375 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 5afa29dbbc20b43e3ae11cf8dfb6d535586b831a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 6 Nov 2018 17:10:30 +0000 Subject: [PATCH 0291/1848] A bit more refactoring. --- WEB-INF/lib/ttExportHelper.class.php | 26 ++++++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttExportHelper.class.php b/WEB-INF/lib/ttExportHelper.class.php index 310af9137..7072f2b73 100644 --- a/WEB-INF/lib/ttExportHelper.class.php +++ b/WEB-INF/lib/ttExportHelper.class.php @@ -48,6 +48,7 @@ class ttExportHelper { // createDataFile creates a file with all data for a given group. function createDataFile($compress = false) { global $user; + $group_id = $user->getActiveGroup(); // Create a temporary file. $dirName = dirname(TEMPLATE_DIR . '_c/.'); @@ -85,17 +86,17 @@ function createDataFile($compress = false) { $this->userMap[$user_item['id']] = $key + 1; // Prepare project map. - $projects = ttTeamHelper::getAllProjects($user->group_id, true); + $projects = ttTeamHelper::getAllProjects($group_id, true); foreach ($projects as $key=>$project_item) $this->projectMap[$project_item['id']] = $key + 1; // Prepare task map. - $tasks = ttTeamHelper::getAllTasks($user->group_id, true); + $tasks = ttTeamHelper::getAllTasks($group_id, true); foreach ($tasks as $key=>$task_item) $this->taskMap[$task_item['id']] = $key + 1; // Prepare client map. - $clients = ttTeamHelper::getAllClients($user->group_id, true); + $clients = ttTeamHelper::getAllClients($group_id, true); foreach ($clients as $key=>$client_item) $this->clientMap[$client_item['id']] = $key + 1; @@ -105,12 +106,12 @@ function createDataFile($compress = false) { $this->invoiceMap[$invoice_item['id']] = $key + 1; // Prepare custom fields map. - $custom_fields = ttTeamHelper::getAllCustomFields($user->group_id); + $custom_fields = ttTeamHelper::getAllCustomFields($group_id); foreach ($custom_fields as $key=>$custom_field) $this->customFieldMap[$custom_field['id']] = $key + 1; // Prepare custom field options map. - $custom_field_options = ttTeamHelper::getAllCustomFieldOptions($user->group_id); + $custom_field_options = ttTeamHelper::getAllCustomFieldOptions($group_id); foreach ($custom_field_options as $key=>$option) $this->customFieldOptionMap[$option['id']] = $key + 1; @@ -167,7 +168,7 @@ function createDataFile($compress = false) { // Write user to project binds. fwrite($file, "\n"); - $user_binds = ttTeamHelper::getUserToProjectBinds($user->group_id); + $user_binds = ttTeamHelper::getUserToProjectBinds($group_id); foreach ($user_binds as $bind) { $user_id = $this->userMap[$bind['user_id']]; $project_id = $this->projectMap[$bind['project_id']]; @@ -225,7 +226,7 @@ function createDataFile($compress = false) { unset($custom_field_options); // Write monthly quotas. - $quotas = ttTeamHelper::getMonthlyQuotas($user->group_id); + $quotas = ttTeamHelper::getMonthlyQuotas($group_id); fwrite($file, "\n"); foreach ($quotas as $quota) { fwrite($file, " \n"); @@ -249,7 +250,7 @@ function createDataFile($compress = false) { unset($records); // Write custom field log. - $custom_field_log = ttTeamHelper::getCustomFieldLog($user->group_id); + $custom_field_log = ttTeamHelper::getCustomFieldLog($group_id); fwrite($file, "\n"); foreach ($custom_field_log as $entry) { fwrite($file, " logMap[$entry['log_id']]."\" field_id=\"".$this->customFieldMap[$entry['field_id']]."\" option_id=\"".$this->customFieldOptionMap[$entry['option_id']]."\" status=\"".$entry['status']."\">\n"); @@ -260,7 +261,7 @@ function createDataFile($compress = false) { unset($custom_field_log); // Write expense items. - $expense_items = ttTeamHelper::getExpenseItems($user->group_id); + $expense_items = ttTeamHelper::getExpenseItems($group_id); fwrite($file, "\n"); foreach ($expense_items as $expense_item) { fwrite($file, " userMap[$expense_item['user_id']]."\" client_id=\"".$this->clientMap[$expense_item['client_id']]."\" project_id=\"".$this->projectMap[$expense_item['project_id']]."\" cost=\"".$expense_item['cost']."\" invoice_id=\"".$this->invoiceMap[$expense_item['invoice_id']]."\" paid=\"".$expense_item['paid']."\" status=\"".$expense_item['status']."\">\n"); @@ -272,7 +273,7 @@ function createDataFile($compress = false) { // Write fav reports. fwrite($file, "\n"); - $fav_reports = ttTeamHelper::getFavReports($user->group_id); + $fav_reports = ttTeamHelper::getFavReports($group_id); foreach ($fav_reports as $fav_report) { $user_list = ''; if (strlen($fav_report['users']) > 0) { @@ -387,7 +388,7 @@ function getRoles() { $mdb2 = getConnection(); $result = array(); - $sql = "select * from tt_roles where group_id = $user->group_id"; + $sql = "select * from tt_roles where group_id = ".$user->getActiveGroup(); $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -404,7 +405,8 @@ function getUsers() { global $user; $mdb2 = getConnection(); - $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $user->group_id order by upper(u.name)"; // Note: deleted users are included. + $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = ". + $user->getActiveGroup()." order by upper(u.name)"; // Note: deleted users are included. $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bbff9a4c5..53e4ad54b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.08.4375 | Copyright © Anuko | +  Anuko Time Tracker 1.18.08.4376 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e73ed25068a87e7a70f634aed888acafda5139aa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 6 Nov 2018 18:22:57 +0000 Subject: [PATCH 0292/1848] A bit more refactoring for subgroups. --- WEB-INF/lib/ttInvoiceHelper.class.php | 12 +++++++----- WEB-INF/lib/ttNotificationHelper.class.php | 4 ++-- WEB-INF/lib/ttPredefinedExpenseHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index d35aa3486..5c5d7141f 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -71,7 +71,8 @@ static function getInvoice($invoice_id) { if ($user->isClient()) $client_part = " and client_id = $user->client_id"; - $sql = "select * from tt_invoices where id = $invoice_id and group_id = $user->group_id $client_part and status = 1"; + $sql = "select * from tt_invoices where id = $invoice_id and group_id = ". + $user->getActiveGroup()."$client_part and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) @@ -86,7 +87,8 @@ static function getInvoiceByName($invoice_name) { $mdb2 = getConnection(); global $user; - $sql = "select id from tt_invoices where group_id = $user->group_id and name = ".$mdb2->quote($invoice_name)." and status = 1"; + $sql = "select id from tt_invoices where group_id = ". + $user->getActiveGroup()." and name = ".$mdb2->quote($invoice_name)." and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -233,7 +235,7 @@ static function delete($invoice_id, $delete_invoice_items) { $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $sql = "update tt_invoices set status = NULL where id = $invoice_id and group_id = $user->group_id"; + $sql = "update tt_invoices set status = NULL where id = $invoice_id and group_id = ".$user->getActiveGroup(); $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -328,8 +330,8 @@ static function createInvoice($fields) { if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; // Create a new invoice record. - $sql = "insert into tt_invoices (group_id, name, date, client_id) - values($user->group_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id)"; + $sql = "insert into tt_invoices (group_id, name, date, client_id) values(". + $user->getActiveGroup().", ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttNotificationHelper.class.php b/WEB-INF/lib/ttNotificationHelper.class.php index 35a96970e..af1bcd3c8 100644 --- a/WEB-INF/lib/ttNotificationHelper.class.php +++ b/WEB-INF/lib/ttNotificationHelper.class.php @@ -38,7 +38,7 @@ static function get($id) $sql = "select c.id, c.cron_spec, c.report_id, c.email, c.cc, c.subject, c.report_condition, c.status, fr.name from tt_cron c left join tt_fav_reports fr on (fr.id = c.report_id) - where c.id = $id and c.group_id = $user->group_id"; + where c.id = $id and c.group_id = ".$user->getActiveGroup(); $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -54,7 +54,7 @@ static function delete($id) { $mdb2 = getConnection(); - $sql = "delete from tt_cron where id = $id and group_id = $user->group_id"; + $sql = "delete from tt_cron where id = $id and group_id = ".$user->getActiveGroup(); $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php index c292870fb..2de4dfad3 100644 --- a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php +++ b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php @@ -39,7 +39,7 @@ static function get($id) $mdb2 = getConnection(); $sql = "select id, name, cost from tt_predefined_expenses - where id = $id and group_id = $user->group_id"; + where id = $id and group_id = ".$user->getActiveGroup(); $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -58,7 +58,7 @@ static function delete($id) { $mdb2 = getConnection(); - $sql = "delete from tt_predefined_expenses where id = $id and group_id = $user->group_id"; + $sql = "delete from tt_predefined_expenses where id = $id and group_id = ".$user->getActiveGroup(); $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 53e4ad54b..760672f71 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.08.4376 | Copyright © Anuko | +  Anuko Time Tracker 1.18.08.4377 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 3a835e437ea379fb2ddd6b532f4a61bc5d5bbf33 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 6 Nov 2018 19:42:21 +0000 Subject: [PATCH 0293/1848] More refactoring for subgroup support. --- WEB-INF/lib/ttProjectHelper.class.php | 34 ++++++++++++++------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 174a31cea..9203b5607 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -41,9 +41,9 @@ static function getAssignedProjects($user_id) $mdb2 = getConnection(); // Do a query with inner join to get assigned projects. - $sql = "select p.id, p.name, p.tasks, upb.rate from tt_projects p - inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id and upb.status = 1) - where p.group_id = $user->group_id and p.status = 1 order by p.name"; + $sql = "select p.id, p.name, p.tasks, upb.rate from tt_projects p". + " inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id and upb.status = 1)". + " where p.group_id = ".$user->getActiveGroup()." and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -61,9 +61,9 @@ static function getRates($user_id) $result = array(); $mdb2 = getConnection(); - $sql = "select p.id, upb.rate from tt_projects p - inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id) - where group_id = $user->group_id"; + $sql = "select p.id, upb.rate from tt_projects p". + " inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id)". + " where group_id = ".$user->getActiveGroup(); $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -83,7 +83,7 @@ static function getProjects() $mdb2 = getConnection(); $sql = "select id, name, tasks from tt_projects". - " where group_id = $user->group_id and (status = 0 or status = 1) order by name"; + " where group_id = ".$user->getActiveGroup()." and (status = 0 or status = 1) order by name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -104,7 +104,7 @@ static function getProjectsForClient() $sql = "select p.id, p.name, p.tasks from tt_projects p". " inner join tt_client_project_binds cpb on (cpb.client_id = $user->client_id and cpb.project_id = p.id)". - " where p.group_id = $user->group_id and (p.status = 0 or p.status = 1)". + " where p.group_id = ".$user->getActiveGroup()." and (p.status = 0 or p.status = 1)". " order by p.name"; $res = $mdb2->query($sql); @@ -124,7 +124,8 @@ static function get($id) $mdb2 = getConnection(); - $sql = "select id, name, description, status, tasks from tt_projects where id = $id and group_id = $user->group_id and (status = 0 or status = 1)"; + $sql = "select id, name, description, status, tasks from tt_projects where id = $id and group_id = ". + $user->getActiveGroup()." and (status = 0 or status = 1)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -140,12 +141,13 @@ static function getProjectByName($name) { $mdb2 = getConnection(); global $user; - $sql = "select id from tt_projects where group_id = $user->group_id and name = ". - $mdb2->quote($name)." and (status = 1 or status = 0)"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { + $sql = "select id from tt_projects where group_id = ". + $user->getActiveGroup()." and name = ".$mdb2->quote($name). + " and (status = 1 or status = 0)"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - if ($val && $val['id']) + if ($val && $val['id']) return $val; } return false; @@ -161,7 +163,7 @@ static function delete($id) { // we'll fail right here and don't damage any other data. // Mark project as deleted and remove associated tasks. - $sql = "update tt_projects set status = NULL, tasks = NULL where id = $id and group_id = $user->group_id"; + $sql = "update tt_projects set status = NULL, tasks = NULL where id = $id and group_id = ".$user->getActiveGroup(); $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error') || 0 == $affected) return false; // An error ocurred, or 0 rows updated. @@ -312,7 +314,7 @@ static function update($fields) { // Update project name, description, tasks and status in tt_projects table. $comma_separated = implode(",", $tasks_to_bind); // This is a comma-separated list of associated task ids. $sql = "update tt_projects set name = ".$mdb2->quote($name).", description = ".$mdb2->quote($description). - ", tasks = ".$mdb2->quote($comma_separated).", status = $status where id = $project_id and group_id = $user->group_id"; + ", tasks = ".$mdb2->quote($comma_separated).", status = $status where id = $project_id and group_id = ".$user->getActiveGroup(); $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 760672f71..d0d15732e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.08.4377 | Copyright © Anuko | +  Anuko Time Tracker 1.18.08.4378 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 085cb5b327f095bcd55f0764b8ab7b7fb3b6bcfa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 6 Nov 2018 21:57:37 +0000 Subject: [PATCH 0294/1848] Fixed role_add.php with a check for existing role name. --- WEB-INF/lib/ttReportHelper.class.php | 6 +++--- WEB-INF/lib/ttRoleHelper.class.php | 8 ++++---- WEB-INF/templates/footer.tpl | 2 +- role_add.php | 1 + 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 744ef97b0..76c1765e8 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -157,7 +157,7 @@ static function getItems($options) { // Add custom field. $include_cf_1 = $options['show_custom_field_1'] || $grouping_by_cf_1; if ($include_cf_1) { - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields($user->getActiveGroup()); $cf_1_type = $custom_fields->fields[0]['type']; if ($cf_1_type == CustomFields::TYPE_TEXT) { array_push($fields, 'cfl.value as cf_1'); @@ -616,7 +616,7 @@ static function prepareReportBody($options, $comment = null) // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields($user->getActiveGroup()); // Define some styles to use in email. $style_title = 'text-align: center; font-size: 15pt; font-family: Arial, Helvetica, sans-serif;'; @@ -1460,7 +1460,7 @@ static function makeJoinPart($options) { $join .= ' left join tt_tasks t on (l.task_id = t.id)'; } if (ttReportHelper::groupingBy('cf_1', $options)) { - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields($user->getActiveGroup()); if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) $join .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id)'; elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index e5bf6a7dc..2751756b7 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -37,7 +37,7 @@ static function get($id) $mdb2 = getConnection(); $sql = "select id, name, description, rank, rights, status from tt_roles - where id = $id and group_id = $user->group_id and (status = 0 or status = 1)"; + where id = $id and group_id = ".$user->getActiveGroup()." and (status = 0 or status = 1)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -56,8 +56,8 @@ static function getRoleByName($role_name) { $mdb2 = getConnection(); global $user; - $sql = "select id from tt_roles where group_id = $user->group_id and name = ". - $mdb2->quote($role_name)." and (status = 1 or status = 0)"; + $sql = "select id from tt_roles where group_id = ".$user->getActiveGroup(). + " and name = ".$mdb2->quote($role_name)." and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -89,7 +89,7 @@ static function isClientRole($role_id) { global $user; $mdb2 = getConnection(); - $sql = "select rights from tt_roles where group_id = $user->group_id and id = $role_id"; + $sql = "select rights from tt_roles where group_id = ".$user->getActiveGroup()." and id = $role_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d0d15732e..5e48388e4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.08.4378 | Copyright © Anuko | +  Anuko Time Tracker 1.18.08.4379 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/role_add.php b/role_add.php index cb3d6f407..e1e16cc77 100644 --- a/role_add.php +++ b/role_add.php @@ -56,6 +56,7 @@ if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($cl_rank >= $user->rank || $cl_rank < 0) $err->add($i18n->get('error.field'), $i18n->get('form.roles.rank')); + if ($err->no() && ttRoleHelper::getRoleByName($cl_name)) $err->add($i18n->get('error.object_exists')); if ($err->no()) { $existing_role = ttRoleHelper::getRoleByRank($cl_rank, $user->group_id); From 39988068b83854ecfd7f0a86ccfe4bfb8fc89644 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 7 Nov 2018 11:59:11 +0000 Subject: [PATCH 0295/1848] Introduced org_id field in tt_clients table. --- WEB-INF/lib/ttGroupExportHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 ++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 56533e10d..d643ed9d6 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -102,7 +102,7 @@ function getRoles() { $mdb2 = getConnection(); $result = array(); - $sql = "select * from tt_roles where group_id = $this->group_id"; // and org_id = $user->org_id <-- add this when possible + $sql = "select * from tt_roles where group_id = $this->group_id and org_id = $user->org_id"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5e48388e4..0148ae7b4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.08.4379 | Copyright © Anuko | +  Anuko Time Tracker 1.18.09.4380 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index b57f157cc..9ba804fd4 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -956,7 +956,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11808"]) { + if ($_POST["convert11797to11809"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -971,6 +971,8 @@ function setChange($sql) { setChange("ALTER TABLE `tt_roles` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.07') set org_id = group_id where org_id is null"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.08', modified = now() where param_name = 'version_db' and param_value = '1.18.07'"); + setChange("ALTER TABLE `tt_clients` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.09', modified = now() where param_name = 'version_db' and param_value = '1.18.08'"); } if ($_POST["cleanup"]) { @@ -1016,7 +1018,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.08) + Create database structure (v1.18.09)
(applies only to new installations, do not execute when updating)
@@ -1061,8 +1063,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.08)Update database structure (v1.17.97 to v1.18.09)
diff --git a/mysql.sql b/mysql.sql index 79e2b3ff3..b29d08dce 100644 --- a/mysql.sql +++ b/mysql.sql @@ -304,6 +304,7 @@ CREATE TABLE `tt_cron` ( CREATE TABLE `tt_clients` ( `id` int(11) NOT NULL AUTO_INCREMENT, # client id `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id `name` varchar(80) COLLATE utf8_bin NOT NULL, # client name `address` varchar(255) default NULL, # client address `tax` float(6,2) default '0.00', # applicable tax for this client @@ -460,4 +461,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.08', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.09', now()); # TODO: change when structure changes. From 0fdda830ba3e780c365c90e1fdfd5cfa7ed77244 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 7 Nov 2018 12:43:23 +0000 Subject: [PATCH 0296/1848] Started to populate org_id upon client creation. --- WEB-INF/lib/ttClientHelper.class.php | 5 +++-- WEB-INF/lib/ttImportHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- client_add.php | 3 ++- client_edit.php | 3 ++- mobile/client_add.php | 3 ++- mobile/client_edit.php | 3 ++- 7 files changed, 13 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 19409b905..0c12a9538 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -168,6 +168,7 @@ static function insert($fields) $mdb2 = getConnection(); $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; $name = $fields['name']; $address = $fields['address']; $tax = $fields['tax']; @@ -179,8 +180,8 @@ static function insert($fields) $tax = str_replace(',', '.', $tax); if ($tax == '') $tax = 0; - $sql = "insert into tt_clients (group_id, name, address, tax, projects, status)". - " values ($group_id, ".$mdb2->quote($name).", ".$mdb2->quote($address).", $tax, ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_clients (group_id, org_id, name, address, tax, projects, status)". + " values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($address).", $tax, ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 8c6fd0c08..e732b9890 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -222,6 +222,7 @@ function endElement($parser, $name) { $this->clientMap[$this->currentElement['ID']] = ttClientHelper::insert(array( 'group_id' => $this->group_id, + 'org_id' => $this->org_id, 'name' => $this->currentElement['NAME'], 'address' => $this->currentElement['ADDRESS'], 'tax' => $this->currentElement['TAX'], diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0148ae7b4..c94ea8584 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.09.4380 | Copyright © Anuko | +  Anuko Time Tracker 1.18.09.4381 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/client_add.php b/client_add.php index 3afcbc072..dc99e6c89 100644 --- a/client_add.php +++ b/client_add.php @@ -71,7 +71,8 @@ if ($err->no()) { if (!ttClientHelper::getClientByName($cl_name)) { if (ttClientHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, diff --git a/client_edit.php b/client_edit.php index 74062d06e..19aa5f893 100644 --- a/client_edit.php +++ b/client_edit.php @@ -103,7 +103,8 @@ if ($request->getParameter('btn_copy')) { if (!ttClientHelper::getClientByName($cl_name)) { if (ttClientHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, diff --git a/mobile/client_add.php b/mobile/client_add.php index f83c720ae..7a097b5ff 100644 --- a/mobile/client_add.php +++ b/mobile/client_add.php @@ -71,7 +71,8 @@ if ($err->no()) { if (!ttClientHelper::getClientByName($cl_name)) { if (ttClientHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, diff --git a/mobile/client_edit.php b/mobile/client_edit.php index 093e9668c..73d50cac2 100644 --- a/mobile/client_edit.php +++ b/mobile/client_edit.php @@ -104,7 +104,8 @@ if ($request->getParameter('btn_copy')) { if (!ttClientHelper::getClientByName($cl_name)) { if (ttClientHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, From 264ed2176f4d55449f4a329d6b85fcb48fd50fb4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 7 Nov 2018 13:16:41 +0000 Subject: [PATCH 0297/1848] Introduced org_id field in tt_projects and tt_tasks tables. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 12 ++++++++---- mysql.sql | 4 +++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c94ea8584..f36602e58 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.09.4381 | Copyright © Anuko | +  Anuko Time Tracker 1.18.10.4382 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 9ba804fd4..a4a6eba71 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -956,7 +956,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11809"]) { + if ($_POST["convert11797to11810"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -973,6 +973,10 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.18.08', modified = now() where param_name = 'version_db' and param_value = '1.18.07'"); setChange("ALTER TABLE `tt_clients` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.09', modified = now() where param_name = 'version_db' and param_value = '1.18.08'"); + setChange("UPDATE `tt_clients` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.09') set org_id = group_id where org_id is null"); + setChange("ALTER TABLE `tt_projects` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("ALTER TABLE `tt_tasks` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.10', modified = now() where param_name = 'version_db' and param_value = '1.18.09'"); } if ($_POST["cleanup"]) { @@ -1018,7 +1022,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.09) + Create database structure (v1.18.10)
(applies only to new installations, do not execute when updating)
@@ -1063,8 +1067,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.09)Update database structure (v1.17.97 to v1.18.10)
diff --git a/mysql.sql b/mysql.sql index b29d08dce..32ba202eb 100644 --- a/mysql.sql +++ b/mysql.sql @@ -117,6 +117,7 @@ INSERT INTO `tt_users` (`login`, `password`, `name`, `group_id`, `role_id`) VALU CREATE TABLE `tt_projects` ( `id` int(11) NOT NULL auto_increment, # project id `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id `name` varchar(80) COLLATE utf8_bin NOT NULL, # project name `description` varchar(255) default NULL, # project description `tasks` text default NULL, # comma-separated list of task ids associated with this project @@ -134,6 +135,7 @@ create unique index project_idx on tt_projects(group_id, name, status); CREATE TABLE `tt_tasks` ( `id` int(11) NOT NULL auto_increment, # task id `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id `name` varchar(80) COLLATE utf8_bin NOT NULL, # task name `description` varchar(255) default NULL, # task description `status` tinyint(4) default 1, # task status @@ -461,4 +463,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.09', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.10', now()); # TODO: change when structure changes. From a711e76851f29c7e0ac290a279eb4dd984ea7167 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 7 Nov 2018 14:12:04 +0000 Subject: [PATCH 0298/1848] Started populating org_id in projects and tasks. --- WEB-INF/lib/ttImportHelper.class.php | 2 ++ WEB-INF/lib/ttProjectHelper.class.php | 5 +++-- WEB-INF/lib/ttTaskHelper.class.php | 5 +++-- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 2 ++ mobile/project_add.php | 3 ++- mobile/project_edit.php | 3 ++- mobile/task_add.php | 3 ++- mobile/task_edit.php | 3 ++- project_add.php | 3 ++- project_edit.php | 3 ++- task_add.php | 3 ++- task_edit.php | 3 ++- 13 files changed, 27 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index e732b9890..350b0c1ff 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -184,6 +184,7 @@ function endElement($parser, $name) { $this->taskMap[$this->currentElement['ID']] = ttTaskHelper::insert(array( 'group_id' => $this->group_id, + 'org_id' => $this->org_id, 'name' => $this->currentElement['NAME'], 'description' => $this->currentElement['DESCRIPTION'], 'status' => $this->currentElement['STATUS'])); @@ -198,6 +199,7 @@ function endElement($parser, $name) { $this->projectMap[$this->currentElement['ID']] = ttProjectHelper::insert(array( 'group_id' => $this->group_id, + 'org_id' => $this->org_id, 'name' => $this->currentElement['NAME'], 'description' => $this->currentElement['DESCRIPTION'], 'tasks' => $mapped_tasks, diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 9203b5607..72b717117 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -189,6 +189,7 @@ static function insert($fields) $mdb2 = getConnection(); $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; $name = $fields['name']; $description = $fields['description']; @@ -197,8 +198,8 @@ static function insert($fields) $comma_separated = implode(',', $tasks); // This is a comma-separated list of associated task ids. $status = $fields['status']; - $sql = "insert into tt_projects (group_id, name, description, tasks, status) - values ($group_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_projects (group_id, org_id, name, description, tasks, status) + values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttTaskHelper.class.php b/WEB-INF/lib/ttTaskHelper.class.php index b02271b95..b4644d513 100644 --- a/WEB-INF/lib/ttTaskHelper.class.php +++ b/WEB-INF/lib/ttTaskHelper.class.php @@ -136,13 +136,14 @@ static function insert($fields) $mdb2 = getConnection(); $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; $name = $fields['name']; $description = $fields['description']; $projects = $fields['projects']; $status = $fields['status']; - $sql = "insert into tt_tasks (group_id, name, description, status) - values ($group_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_tasks (group_id, org_id, name, description, status) + values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); $last_id = 0; if (is_a($affected, 'PEAR_Error')) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f36602e58..8da3be0e6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.10.4382 | Copyright © Anuko | +  Anuko Time Tracker 1.18.10.4383 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index a4a6eba71..e77c24b91 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -977,6 +977,8 @@ function setChange($sql) { setChange("ALTER TABLE `tt_projects` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("ALTER TABLE `tt_tasks` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.10', modified = now() where param_name = 'version_db' and param_value = '1.18.09'"); + setChange("UPDATE `tt_projects` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.10') set org_id = group_id where org_id is null"); + setChange("UPDATE `tt_tasks` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.10') set org_id = group_id where org_id is null"); } if ($_POST["cleanup"]) { diff --git a/mobile/project_add.php b/mobile/project_add.php index b0d5394d4..6d68a178e 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -78,7 +78,8 @@ if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { if (ttProjectHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, diff --git a/mobile/project_edit.php b/mobile/project_edit.php index 94f3e514d..defec7add 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -119,7 +119,8 @@ if ($request->getParameter('btn_copy')) { if (!ttProjectHelper::getProjectByName($cl_name)) { if (ttProjectHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, diff --git a/mobile/task_add.php b/mobile/task_add.php index 4b257edc5..796c725c9 100644 --- a/mobile/task_add.php +++ b/mobile/task_add.php @@ -68,7 +68,8 @@ if ($err->no()) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => ACTIVE, diff --git a/mobile/task_edit.php b/mobile/task_edit.php index f1e256892..030cacd1b 100644 --- a/mobile/task_edit.php +++ b/mobile/task_edit.php @@ -103,7 +103,8 @@ if ($request->getParameter('btn_copy')) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => $cl_status, diff --git a/project_add.php b/project_add.php index 980870250..3b4c73d36 100644 --- a/project_add.php +++ b/project_add.php @@ -77,7 +77,8 @@ if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { if (ttProjectHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, diff --git a/project_edit.php b/project_edit.php index 14e8e7713..77312b0b2 100644 --- a/project_edit.php +++ b/project_edit.php @@ -118,7 +118,8 @@ if ($request->getParameter('btn_copy')) { if (!ttProjectHelper::getProjectByName($cl_name)) { if (ttProjectHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, diff --git a/task_add.php b/task_add.php index e25fa3908..383a3935a 100644 --- a/task_add.php +++ b/task_add.php @@ -68,7 +68,8 @@ if ($err->no()) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => ACTIVE, diff --git a/task_edit.php b/task_edit.php index feff4e52d..e63817313 100644 --- a/task_edit.php +++ b/task_edit.php @@ -101,7 +101,8 @@ if ($request->getParameter('btn_copy')) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'group_id' => $user->group_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => $cl_status, From c0ddf2c276ccbb7480ab690edfbd6c6e42a3ae39 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 7 Nov 2018 22:40:17 +0000 Subject: [PATCH 0299/1848] Added org_id to a couple more tables. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 3 +++ mysql.sql | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8da3be0e6..b56b168de 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.10.4383 | Copyright © Anuko | +  Anuko Time Tracker 1.18.11.4384 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index e77c24b91..9a87d38e3 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -979,6 +979,9 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.18.10', modified = now() where param_name = 'version_db' and param_value = '1.18.09'"); setChange("UPDATE `tt_projects` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.10') set org_id = group_id where org_id is null"); setChange("UPDATE `tt_tasks` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.10') set org_id = group_id where org_id is null"); + setChange("ALTER TABLE `tt_log` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("ALTER TABLE `tt_invoices` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.11', modified = now() where param_name = 'version_db' and param_value = '1.18.10'"); } if ($_POST["cleanup"]) { diff --git a/mysql.sql b/mysql.sql index 32ba202eb..396fd2d21 100644 --- a/mysql.sql +++ b/mysql.sql @@ -183,6 +183,7 @@ CREATE TABLE `tt_log` ( `id` bigint NOT NULL auto_increment, # time record id `user_id` int(11) NOT NULL, # user id `group_id` int(11) default NULL, # group id + `org_id` int(11) default NULL, # organization id `date` date NOT NULL, # date the record is for `start` time default NULL, # record start time (for example, 09:00) `duration` time default NULL, # record duration (for example, 1 hour) @@ -219,6 +220,7 @@ create index task_idx on tt_log(task_id); CREATE TABLE `tt_invoices` ( `id` int(11) NOT NULL auto_increment, # invoice id `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id `name` varchar(80) COLLATE utf8_bin NOT NULL, # invoice name `date` date NOT NULL, # invoice date `client_id` int(11) NOT NULL, # client id @@ -463,4 +465,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.10', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.11', now()); # TODO: change when structure changes. From 7f313df2fbc1b28531adccbf022d6fdde0d6fdc8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 7 Nov 2018 22:45:51 +0000 Subject: [PATCH 0300/1848] Cosmetic version fixes in dbinstall.php. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b56b168de..4f98ebca7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.11.4384 | Copyright © Anuko | +  Anuko Time Tracker 1.18.11.4385 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 9a87d38e3..a2ff4331c 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -956,7 +956,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11810"]) { + if ($_POST["convert11797to11811"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1027,7 +1027,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.10) + Create database structure (v1.18.11)
(applies only to new installations, do not execute when updating)
@@ -1072,8 +1072,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.10)Update database structure (v1.17.97 to v1.18.11)
From 3c5f822f90846e9a65866c9e33b7e1ff81b46b1f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 7 Nov 2018 23:38:00 +0000 Subject: [PATCH 0301/1848] Started to populate org_id in tt_log and tt_invoices tables. --- WEB-INF/lib/ttImportHelper.class.php | 2 ++ WEB-INF/lib/ttInvoiceHelper.class.php | 9 +++++---- WEB-INF/lib/ttTimeHelper.class.php | 9 +++++---- WEB-INF/lib/ttWeekViewHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 2 ++ mobile/time.php | 1 + mobile/timer.php | 1 + time.php | 1 + time_edit.php | 1 + 10 files changed, 20 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 350b0c1ff..64a32e0e6 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -241,6 +241,7 @@ function endElement($parser, $name) { $this->invoiceMap[$this->currentElement['ID']] = ttInvoiceHelper::insert(array( 'group_id' => $this->group_id, + 'org_id' => $this->org_id, 'name' => $this->currentElement['NAME'], 'date' => $this->currentElement['DATE'], 'client_id' => $this->clientMap[$this->currentElement['CLIENT_ID']], @@ -257,6 +258,7 @@ function endElement($parser, $name) { ttTimeHelper::insert(array( 'user_id' => $this->userMap[$this->currentElement['USER_ID']], 'group_id' => $this->group_id, + 'org_id' => $this->org_id, 'date' => $this->currentElement['DATE'], 'start' => $this->currentElement['START'], 'finish' => $this->currentElement['FINISH'], diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 5c5d7141f..3a8dbe27b 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -38,6 +38,7 @@ static function insert($fields) $mdb2 = getConnection(); $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; $name = $fields['name']; if (!$name) return false; @@ -49,8 +50,8 @@ static function insert($fields) } // Insert a new invoice record. - $sql = "insert into tt_invoices (group_id, name, date, client_id $status_f)". - " values($group_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id $status_v)"; + $sql = "insert into tt_invoices (group_id, org_id, name, date, client_id $status_f)". + " values($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id $status_v)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -330,8 +331,8 @@ static function createInvoice($fields) { if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; // Create a new invoice record. - $sql = "insert into tt_invoices (group_id, name, date, client_id) values(". - $user->getActiveGroup().", ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id)"; + $sql = "insert into tt_invoices (group_id, org_id, name, date, client_id) values(". + $user->getActiveGroup().", $user->org_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index e30203540..245067804 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -391,6 +391,7 @@ static function insert($fields) $user_id = (int) $fields['user_id']; $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; $date = $fields['date']; $start = $fields['start']; $finish = $fields['finish']; @@ -423,8 +424,8 @@ static function insert($fields) if (!$paid) $paid = 0; if ($duration) { - $sql = "insert into tt_log (user_id, group_id, date, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by $status_f) ". - "values ($user_id, $group_id, ".$mdb2->quote($date).", '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; + $sql = "insert into tt_log (user_id, group_id, org_id, date, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by $status_f) ". + "values ($user_id, $group_id, $org_id, ".$mdb2->quote($date).", '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -433,8 +434,8 @@ static function insert($fields) if ($duration === false) $duration = 0; if (!$duration && ttTimeHelper::getUncompleted($user_id)) return false; - $sql = "insert into tt_log (user_id, group_id, date, start, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by $status_f) ". - "values ($user_id, $group_id, ".$mdb2->quote($date).", '$start', '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; + $sql = "insert into tt_log (user_id, group_id, org_id, date, start, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by $status_f) ". + "values ($user_id, $group_id, $org_id, ".$mdb2->quote($date).", '$start', '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v $status_v)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index dcb39af63..53065d380 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -494,6 +494,7 @@ static function insertDurationFromWeekView($fields, $custom_fields, $err) { $fields4insert = array(); $fields4insert['user_id'] = $user->getActiveUser(); $fields4insert['group_id'] = $user->getActiveGroup(); + $fields4insert['org_id'] = $user->org_id; $fields4insert['date'] = $entry_date; $fields4insert['duration'] = $fields['duration']; $fields4insert['client'] = ttWeekViewHelper::parseFromWeekViewRow($fields['row_id'], 'cl'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4f98ebca7..98b2ad53f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.11.4385 | Copyright © Anuko | +  Anuko Time Tracker 1.18.11.4386 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index a2ff4331c..1c5fa9009 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -982,6 +982,8 @@ function setChange($sql) { setChange("ALTER TABLE `tt_log` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("ALTER TABLE `tt_invoices` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.11', modified = now() where param_name = 'version_db' and param_value = '1.18.10'"); + setChange("UPDATE `tt_log` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.11') set org_id = group_id where org_id is null"); + setChange("UPDATE `tt_invoices` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.11') set org_id = group_id where org_id is null"); } if ($_POST["cleanup"]) { diff --git a/mobile/time.php b/mobile/time.php index 76296f64b..a25cf90c8 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -253,6 +253,7 @@ 'date' => $cl_date, 'user_id' => $user->getActiveUser(), 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'client' => $cl_client, 'project' => $cl_project, 'task' => $cl_task, diff --git a/mobile/timer.php b/mobile/timer.php index 09500bd22..2f5dbad4c 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -226,6 +226,7 @@ 'date' => $cl_date, 'user_id' => $user->getActiveUser(), 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'client' => $cl_client, 'project' => $cl_project, 'task' => $cl_task, diff --git a/time.php b/time.php index 258f15c19..68aaf40e7 100644 --- a/time.php +++ b/time.php @@ -313,6 +313,7 @@ 'date' => $cl_date, 'user_id' => $user->getActiveUser(), 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, 'client' => $cl_client, 'project' => $cl_project, 'task' => $cl_task, diff --git a/time_edit.php b/time_edit.php index 5f4068829..21c3effa7 100644 --- a/time_edit.php +++ b/time_edit.php @@ -366,6 +366,7 @@ 'date'=>$new_date->toString(DB_DATEFORMAT), 'user_id'=>$user->getActiveUser(), 'group_id'=>$user->getActiveGroup(), + 'org_id' => $user->org_id, 'client'=>$cl_client, 'project'=>$cl_project, 'task'=>$cl_task, From eae8b284cbee2b8e78b311bfa3a94f731f5056ee Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 8 Nov 2018 08:55:16 +0000 Subject: [PATCH 0302/1848] A bit more progress with introducing org_id in tables. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 13 +++++++++---- mysql.sql | 10 +++++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 98b2ad53f..f807fe1c3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.11.4386 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4387 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 1c5fa9009..26f1a33aa 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -956,7 +956,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11811"]) { + if ($_POST["convert11797to11812"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -984,6 +984,11 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.18.11', modified = now() where param_name = 'version_db' and param_value = '1.18.10'"); setChange("UPDATE `tt_log` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.11') set org_id = group_id where org_id is null"); setChange("UPDATE `tt_invoices` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.11') set org_id = group_id where org_id is null"); + setChange("ALTER TABLE `tt_user_project_binds` ADD `group_id` int(11) default NULL AFTER `project_id`"); + setChange("ALTER TABLE `tt_user_project_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("ALTER TABLE `tt_project_task_binds` ADD `group_id` int(11) default NULL AFTER `task_id`"); + setChange("ALTER TABLE `tt_project_task_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.12', modified = now() where param_name = 'version_db' and param_value = '1.18.11'"); } if ($_POST["cleanup"]) { @@ -1029,7 +1034,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.11) + Create database structure (v1.18.12)
(applies only to new installations, do not execute when updating)
@@ -1074,8 +1079,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.11)Update database structure (v1.17.97 to v1.18.12)
diff --git a/mysql.sql b/mysql.sql index 396fd2d21..00abb462f 100644 --- a/mysql.sql +++ b/mysql.sql @@ -153,6 +153,8 @@ CREATE TABLE `tt_user_project_binds` ( `id` int(11) NOT NULL auto_increment, # bind id `user_id` int(11) NOT NULL, # user id `project_id` int(11) NOT NULL, # project id + `group_id` int(11) default NULL, # group id + `org_id` int(11) default NULL, # organization id `rate` float(6,2) default '0.00', # rate for this user when working on this project `status` tinyint(4) default 1, # bind status PRIMARY KEY (`id`) @@ -166,8 +168,10 @@ create unique index bind_idx on tt_user_project_binds(user_id, project_id); # Structure for table tt_project_task_binds. This table maps projects to assigned tasks. # CREATE TABLE `tt_project_task_binds` ( - `project_id` int(11) NOT NULL, # project id - `task_id` int(11) NOT NULL # task id + `project_id` int(11) NOT NULL, # project id + `task_id` int(11) NOT NULL # task id + `group_id` int(11) default NULL, # group id + `org_id` int(11) default NULL, # organization id ); # Indexes for tt_project_task_binds. @@ -465,4 +469,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.11', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.12', now()); # TODO: change when structure changes. From 8fc038ec7505483c193e290423623b6a66ee3797 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 8 Nov 2018 15:57:34 +0000 Subject: [PATCH 0303/1848] Started to populate group_id and org_id in tt_user_project_binds. --- WEB-INF/lib/ttImportHelper.class.php | 12 +++++++++-- WEB-INF/lib/ttProjectHelper.class.php | 9 +++++--- WEB-INF/lib/ttUserHelper.class.php | 30 ++++++++++++++++++++++++--- WEB-INF/templates/footer.tpl | 2 +- user_add.php | 2 +- 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 64a32e0e6..307be1677 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -206,11 +206,19 @@ function endElement($parser, $name) { 'status' => $this->currentElement['STATUS'])); } if ($name == 'USER_PROJECT_BIND' && $this->canImport) { - ttUserHelper::insertBind( +/* + ttUserHelper::insertBind( $this->userMap[$this->currentElement['USER_ID']], $this->projectMap[$this->currentElement['PROJECT_ID']], $this->currentElement['RATE'], - $this->currentElement['STATUS']); + $this->currentElement['STATUS']);*/ + ttUserHelper::insertBind2(array( + 'user_id' => $this->userMap[$this->currentElement['USER_ID']], + 'project_id' => $this->projectMap[$this->currentElement['PROJECT_ID']], + 'group_id' => $this->group_id, + 'org_id' => $this->org_id, + 'rate' => $this->currentElement['RATE'], + 'status' => $this->currentElement['STATUS'])); } if ($name == 'CLIENT' && $this->canImport) { diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 72b717117..47783d59d 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -214,8 +214,8 @@ static function insert($fields) $active_users = ttTeamHelper::getActiveUsers(array('getAllFields'=>true)); foreach ($active_users as $u) { if(in_array($u['id'], $users)) { - $sql = "insert into tt_user_project_binds (project_id, user_id, status, rate) values( - $last_id, ".$u['id'].", 1, ".$u['rate'].")"; + $sql = "insert into tt_user_project_binds (project_id, user_id, group_id, org_id, status, rate) values( + $last_id, ".$u['id'].", $group_id, $org_id, 1, ".$u['rate'].")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -271,8 +271,11 @@ static function update($fields) { while ($row = $res->fetchRow()) { $user_rate[$row['id']] = $row['rate']; } + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; foreach ($users_to_add as $id) { - $sql = "insert into tt_user_project_binds (user_id, project_id, rate, status) values($id, $project_id, ".$user_rate[$id].", 1)"; + $sql = "insert into tt_user_project_binds (user_id, project_id, group_id, org_id, rate, status)". + " values($id, $project_id, $group_id, $org_id, ".$user_rate[$id].", 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 28175080f..bd5e46b8f 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -134,7 +134,8 @@ static function insert($fields, $hash = true) { else $p['rate'] = str_replace(',', '.', $p['rate']); - $sql = "insert into tt_user_project_binds (project_id, user_id, rate, status) values(".$p['id'].",".$last_id.",".$p['rate'].", 1)"; + $sql = "insert into tt_user_project_binds (project_id, user_id, group_id, org_id, rate, status)". + " values(".$p['id'].", $last_id, $group_id, $org_id, ".$p['rate'].", 1)"; $affected = $mdb2->exec($sql); } } @@ -309,10 +310,33 @@ static function setPassword($user_id, $password) { // insertBind - inserts a user to project bind into tt_user_project_binds table. static function insertBind($user_id, $project_id, $rate, $status) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; + $sql = "insert into tt_user_project_binds (user_id, project_id, group_id, org_id, rate, status)". + " values($user_id, $project_id, $group_id, $org_id, ".$mdb2->quote($rate).", $status)"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // insertBind2 - inserts a user to project bind into tt_user_project_binds table. + static function insertBind2($fields) { + global $user; $mdb2 = getConnection(); - $sql = "insert into tt_user_project_binds (user_id, project_id, rate, status) - values($user_id, $project_id, ".$mdb2->quote($rate).", $status)"; + // This may be used during import. Use the following until we have import refactored. + $group_id = $fields['group_id'] ? (int) $fields['group_id'] : $user->getActiveGroup(); + $org_id = $fields['org_id'] ? (int) $fields['org_id'] : $user->org_id; + + $user_id = (int) $fields['user_id']; + $project_id = (int) $fields['project_id']; + $rate = $mdb2->quote($fields['rate']); + $status = $mdb2->quote($fields['status']); + + $sql = "insert into tt_user_project_binds (user_id, project_id, group_id, org_id, rate, status)". + " values($user_id, $project_id, $group_id, $org_id, $rate, $status)"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f807fe1c3..ee8659bf9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4387 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4388 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/user_add.php b/user_add.php index ac2d8c4e4..eb9391472 100644 --- a/user_add.php +++ b/user_add.php @@ -150,7 +150,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'login' => $cl_login, 'password' => $cl_password1, 'rate' => $cl_rate, - 'group_id' => $user->group_id, // TODO: this needs to be fixed for on-behalf group work. + 'group_id' => $user->getActiveGroup(), 'org_id' => $user->org_id, 'role_id' => $cl_role_id, 'client_id' => $cl_client_id, From 1cfc9f9452a2e397fca1886825fff29fad409e5c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 8 Nov 2018 17:04:02 +0000 Subject: [PATCH 0304/1848] A bit of refactoring. --- WEB-INF/lib/ttImportHelper.class.php | 8 +------- WEB-INF/lib/ttUserHelper.class.php | 25 +++++++++---------------- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 2 ++ 4 files changed, 13 insertions(+), 24 deletions(-) diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index 307be1677..ea899821a 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -206,13 +206,7 @@ function endElement($parser, $name) { 'status' => $this->currentElement['STATUS'])); } if ($name == 'USER_PROJECT_BIND' && $this->canImport) { -/* - ttUserHelper::insertBind( - $this->userMap[$this->currentElement['USER_ID']], - $this->projectMap[$this->currentElement['PROJECT_ID']], - $this->currentElement['RATE'], - $this->currentElement['STATUS']);*/ - ttUserHelper::insertBind2(array( + ttUserHelper::insertBind(array( 'user_id' => $this->userMap[$this->currentElement['USER_ID']], 'project_id' => $this->projectMap[$this->currentElement['PROJECT_ID']], 'group_id' => $this->group_id, diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index bd5e46b8f..222cfdaa4 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -229,8 +229,14 @@ static function update($user_id, $fields) { if (is_a($affected, 'PEAR_Error')) die ($affected->getMessage()); } else { // Record does not exist. Insert it. - ttUserHelper::insertBind($user_id, $project_id, $rate, 1); - } + ttUserHelper::insertBind(array( + 'user_id' => $user_id, + 'project_id' => $project_id, + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, + 'rate' => $rate, + 'status' => ACTIVE)); + } } } } @@ -309,20 +315,7 @@ static function setPassword($user_id, $password) { } // insertBind - inserts a user to project bind into tt_user_project_binds table. - static function insertBind($user_id, $project_id, $rate, $status) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getActiveGroup(); - $org_id = $user->org_id; - $sql = "insert into tt_user_project_binds (user_id, project_id, group_id, org_id, rate, status)". - " values($user_id, $project_id, $group_id, $org_id, ".$mdb2->quote($rate).", $status)"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } - - // insertBind2 - inserts a user to project bind into tt_user_project_binds table. - static function insertBind2($fields) { + static function insertBind($fields) { global $user; $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ee8659bf9..73feb65aa 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4388 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4389 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 26f1a33aa..d150e7350 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -989,6 +989,8 @@ function setChange($sql) { setChange("ALTER TABLE `tt_project_task_binds` ADD `group_id` int(11) default NULL AFTER `task_id`"); setChange("ALTER TABLE `tt_project_task_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.12', modified = now() where param_name = 'version_db' and param_value = '1.18.11'"); + // TODO: this does not work as we just introduced group_id and it is NULL. Same for tt_project_task_binds. Improve. + // setChange("UPDATE `tt_user_project_binds` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.12') set org_id = group_id where org_id is null"); } if ($_POST["cleanup"]) { From f54ca9d66b525ec1cd7076744c8a022e8b4b488d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 8 Nov 2018 19:01:42 +0000 Subject: [PATCH 0305/1848] Resuming work on new import - renamed a class. --- ...tImportHelper2.class.php => ttOrgImportHelper.class.php} | 6 +++--- WEB-INF/templates/footer.tpl | 2 +- import.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename WEB-INF/lib/{ttImportHelper2.class.php => ttOrgImportHelper.class.php} (97%) diff --git a/WEB-INF/lib/ttImportHelper2.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php similarity index 97% rename from WEB-INF/lib/ttImportHelper2.class.php rename to WEB-INF/lib/ttOrgImportHelper.class.php index 5de6d8c59..cce763da6 100644 --- a/WEB-INF/lib/ttImportHelper2.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -38,10 +38,10 @@ import('ttExpenseHelper'); import('ttRoleHelper'); -// ttImportHelper2 - this class is a future replacement for ttImportHelper. +// ttOrgImportHelper - this class is a future replacement for ttImportHelper. // Currently, it is work in progress. // When done, it should handle import of complex groups consisting of other groups. -class ttImportHelper2 { +class ttOrgImportHelper { var $errors = null; // Errors go here. Set in constructor by reference. var $currentElement = array(); // Current element of the XML file we are parsing. @@ -82,7 +82,7 @@ function endElement($parser, $name) { // During second pass we import data. if (!$this->firstPass && $this->canImport) { - // TODO: write code here. + // TODO: write code here. Nothing is imported currently. } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 73feb65aa..d459f13a1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4389 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4390 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/import.php b/import.php index 3e375c981..235924ac4 100644 --- a/import.php +++ b/import.php @@ -28,7 +28,7 @@ require_once('initialize.php'); import('ttImportHelper'); -import('ttImportHelper2'); +import('ttOrgImportHelper'); import('form.Form'); // Access check. @@ -44,7 +44,7 @@ if ($request->isPost()) { if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { - $import = new ttImportHelper2($err); + $import = new ttOrgImportHelper($err); } else { $import = new ttImportHelper($err); } From 7051fc8c0f68618bbaff5f8bb48d3478ce93836a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 8 Nov 2018 20:41:48 +0000 Subject: [PATCH 0306/1848] Some progress with writing new export. --- WEB-INF/lib/ttOrgImportHelper.class.php | 77 ++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index cce763da6..e64019154 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -50,6 +50,10 @@ class ttOrgImportHelper { var $canImport = true; // False if we cannot import data due to a login collision. var $firstPass = true; // True during first pass through the file. + var $org_id = null; // Organization id (same as top group_id). + var $current_parent_group_id = null; // Current parent group id as we parse the file. + // Set when we create a new group. + // Constructor. function __construct(&$errors) { $this->errors = &$errors; @@ -63,6 +67,32 @@ function startElement($parser, $name, $attrs) { $this->currentElement = $attrs; } $this->currentTag = $name; + + if (!$this->firstPass && $this->canImport) { + $mdb2 = getConnection(); + + // We are in second pass through the XML file and can import data. + if ($name == 'GROUP') { + // Create a new group. + $group_id = $this->createGroup(array( + 'parent_id' => $this->current_parent_group_id, + 'org_id' => $this->org_id, + 'name' => $this->currentElement['NAME'], + 'currency' => $this->currentElement['CURRENCY'], + 'lang' => $this->currentElement['LANG'])); + // We only have 3 properties in export at the moment, while work is ongoing... + + // Special handling for top group. + if (!$this->org_id) { + $this->org_id = $group_id; + $sql = "update tt_groups set org_id = $group_id where org_id is NULL and id = $group_id"; + $affected = $mdb2->exec($sql); + // TODO: design a better error handling approach for the entire import process. + } + // Set current parent group. + $this->current_parent_group_id = $group_id; + } + } } // endElement - callback handler for the closing tag of an XML element. @@ -82,7 +112,7 @@ function endElement($parser, $name) { // During second pass we import data. if (!$this->firstPass && $this->canImport) { - // TODO: write code here. Nothing is imported currently. + // Nothing is done here, see startElement for second pass. } } @@ -213,4 +243,49 @@ function uncompress($in, $out) { fclose ($out_file); return true; } + + // createGroup function creates a new group. + private function createGroup($fields) { + + global $user; + $mdb2 = getConnection(); + + $columns = '(parent_id, org_id, name, currency, lang)'; + +// $columns = '(name, currency, decimal_mark, lang, date_format, time_format, week_start, tracking_mode'. +// ', project_required, task_required, record_type, bcc_email, allow_ip, password_complexity, plugins'. +// ', lock_spec, workday_minutes, config, created, created_ip, created_by)'; + + $values = ' values ('; + $values .= $mdb2->quote($fields['parent_id']); + $values .= ', '.$mdb2->quote($fields['org_id']); + $values .= ', '.$mdb2->quote(trim($fields['name'])); + $values .= ', '.$mdb2->quote(trim($fields['currency'])); + //$values .= ', '.$mdb2->quote($fields['decimal_mark']); + $values .= ', '.$mdb2->quote($fields['lang']); +/* + $values .= ', '.$mdb2->quote($fields['date_format']); + $values .= ', '.$mdb2->quote($fields['time_format']); + $values .= ', '.(int)$fields['week_start']; + $values .= ', '.(int)$fields['tracking_mode']; + $values .= ', '.(int)$fields['project_required']; + $values .= ', '.(int)$fields['task_required']; + $values .= ', '.(int)$fields['record_type']; + $values .= ', '.$mdb2->quote($fields['bcc_email']); + $values .= ', '.$mdb2->quote($fields['allow_ip']); + $values .= ', '.$mdb2->quote($fields['password_complexity']); + $values .= ', '.$mdb2->quote($fields['plugins']); + $values .= ', '.$mdb2->quote($fields['lock_spec']); + $values .= ', '.(int)$fields['workday_minutes']; + $values .= ', '.$mdb2->quote($fields['config']); + $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); */ + $values .= ')'; + + $sql = 'insert into tt_groups '.$columns.$values; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + $group_id = $mdb2->lastInsertID('tt_groups', 'id'); + return $group_id; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d459f13a1..b0b2e53f0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4390 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4391 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a1d3d5c5d92eed842325de1c62295cb01d070228 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 8 Nov 2018 20:57:44 +0000 Subject: [PATCH 0307/1848] Improved new export to include roles in output. --- WEB-INF/lib/ttGroupExportHelper.class.php | 14 ++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index d643ed9d6..af49e19e6 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -143,6 +143,20 @@ function writeData() { foreach ($clients as $key=>$client_item) $this->clientMap[$client_item['id']] = $key + 1; + // Write roles. + fwrite($this->file, $this->indentation."\n"); + foreach ($roles as $role) { + $role_part = $this->indentation.' '."roleMap[$role['id']]."\""; + $role_part .= " name=\"".htmlentities($role['name'])."\""; + $role_part .= " description=\"".htmlentities($role['description'])."\""; + $role_part .= " rank=\"".$role['rank']."\""; + $role_part .= " rights=\"".htmlentities($role['rights'])."\""; + $role_part .= " status=\"".$role['status']."\""; + $role_part .= ">\n"; + fwrite($this->file, $role_part); + } + fwrite($this->file, $this->indentation."\n"); + // Write users. fwrite($this->file, $this->indentation."\n"); foreach ($users as $user_item) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b0b2e53f0..6e4cc7431 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4391 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4392 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From fb57263a487993f368478238d3f65d3495349b22 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 9 Nov 2018 12:39:23 +0000 Subject: [PATCH 0308/1848] A bit of refactoring in ttOrgImportHelper class. --- WEB-INF/lib/ttOrgImportHelper.class.php | 48 ++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index e64019154..f3a2d8eaa 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -53,6 +53,17 @@ class ttOrgImportHelper { var $org_id = null; // Organization id (same as top group_id). var $current_parent_group_id = null; // Current parent group id as we parse the file. // Set when we create a new group. + // Entities for current group. + var $currentGroupRoles = array(); // Array of arrays of role properties. + // var $currentGroupUsers = array(); // Array of arrays of user properties. + + // Entity maps for current group. They map XML ids with database ids. + var $currentGroupRoleMap = array(); // Maps role ids from XML to their database ids. + //var $userMap = array(); // User ids. + //var $projectMap = array(); // Project ids. + //var $taskMap = array(); // Task ids. + //var $clientMap = array(); // Client ids. + //var $invoiceMap = array(); // Invoice ids. // Constructor. function __construct(&$errors) { @@ -62,12 +73,25 @@ function __construct(&$errors) { // startElement - callback handler for opening tag of an XML element. // In this function we assign passed in attributes to currentElement. function startElement($parser, $name, $attrs) { +/* if ($name == 'GROUP' || $name == 'USER') { $this->currentElement = $attrs; } $this->currentTag = $name; +*/ + // First pass. We only check user logins for potential collisions with existing. + if ($this->firstPass) { + if ($name == 'USER' && $this->canImport) { + if ('' != $attrs['STATUS'] && ttUserHelper::getUserByLogin($attrs['LOGIN'])) { + // We have a login collision, cannot import any data. + $this->canImport = false; + } + } + //$this->currentTag = ''; + } + // Second pass processing. We import data here, one tag at a time. if (!$this->firstPass && $this->canImport) { $mdb2 = getConnection(); @@ -92,6 +116,23 @@ function startElement($parser, $name, $attrs) { // Set current parent group. $this->current_parent_group_id = $group_id; } + + if ($name == 'ROLES') { + // If we get here, we have to recycle both $currentGroupRoles and $currentGroupRoleMap. + unset($this->currentGroupRoles); + unset($this->currentGroupRoleMap); + $this->currentGroupRoles = array(); + $this->currentGroupRoleMap = array(); + // Both arrays are now empty. + // They will get reconstructed after processing of elements in XML. See below. + } + + if ($name == 'ROLE') { + // We get here when processing a tag for the current group. + // Add new role to $this->currentGroupRoles and a mapping to $this->currentGroupRoleMap. + $this->currentGroupRoles[$this->currentElement['ID']] = $this->currentElement; + $this->currentElement = array(); + } } } @@ -99,6 +140,8 @@ function startElement($parser, $name, $attrs) { // When we are here, currentElement is an array of the element attributes (as set in startElement). // Here we do the actual import of data into the database. function endElement($parser, $name) { + // Do nothing here. Everything is done in startElement to keep things simple. + /* // During first pass we only check user logins. if ($this->firstPass) { if ($name == 'USER' && $this->canImport) { @@ -113,11 +156,13 @@ function endElement($parser, $name) { // During second pass we import data. if (!$this->firstPass && $this->canImport) { // Nothing is done here, see startElement for second pass. - } + }*/ } // dataElement - callback handler for text data fragments. It builds up currentElement array with text pieces from XML. function dataElement($parser, $data) { + // New approach is to do nothing here. Everything is now done when processing start tag (startElement). + /* if ($this->currentTag == 'NAME' || $this->currentTag == 'DESCRIPTION' || $this->currentTag == 'LABEL' @@ -131,6 +176,7 @@ function dataElement($parser, $data) { else $this->currentElement[$this->currentTag] = trim($data); } + * */ } // importXml - uncompresses the file, reads and parses its content. During parsing, diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6e4cc7431..69cf517ed 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4392 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4393 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 7af7d601282b0ea3138d05c300163e18e121ec32 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 9 Nov 2018 13:08:04 +0000 Subject: [PATCH 0309/1848] A bit more work in progress in ttOrgImportHelper class. --- WEB-INF/lib/ttOrgImportHelper.class.php | 53 ++----------------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 4 insertions(+), 51 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index f3a2d8eaa..c70d25805 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -26,7 +26,6 @@ // | https://www.anuko.com/time_tracker/credits.htm // +----------------------------------------------------------------------+ -import('ttTeamHelper'); import('ttUserHelper'); import('ttProjectHelper'); import('ttTaskHelper'); @@ -70,8 +69,7 @@ function __construct(&$errors) { $this->errors = &$errors; } - // startElement - callback handler for opening tag of an XML element. - // In this function we assign passed in attributes to currentElement. + // startElement - callback handler for opening tag of an XML element in the file. function startElement($parser, $name, $attrs) { /* if ($name == 'GROUP' @@ -136,49 +134,6 @@ function startElement($parser, $name, $attrs) { } } - // endElement - callback handler for the closing tag of an XML element. - // When we are here, currentElement is an array of the element attributes (as set in startElement). - // Here we do the actual import of data into the database. - function endElement($parser, $name) { - // Do nothing here. Everything is done in startElement to keep things simple. - /* - // During first pass we only check user logins. - if ($this->firstPass) { - if ($name == 'USER' && $this->canImport) { - if ('' != $this->currentElement['STATUS'] && ttUserHelper::getUserByLogin($this->currentElement['LOGIN'])) { - // We have a login collision, cannot import any data. - $this->canImport = false; - } - } - $this->currentTag = ''; - } - - // During second pass we import data. - if (!$this->firstPass && $this->canImport) { - // Nothing is done here, see startElement for second pass. - }*/ - } - - // dataElement - callback handler for text data fragments. It builds up currentElement array with text pieces from XML. - function dataElement($parser, $data) { - // New approach is to do nothing here. Everything is now done when processing start tag (startElement). - /* - if ($this->currentTag == 'NAME' - || $this->currentTag == 'DESCRIPTION' - || $this->currentTag == 'LABEL' - || $this->currentTag == 'VALUE' - || $this->currentTag == 'COMMENT' - || $this->currentTag == 'ADDRESS' - || $this->currentTag == 'ALLOW_IP' - || $this->currentTag == 'PASSWORD_COMPLEXITY') { - if (isset($this->currentElement[$this->currentTag])) - $this->currentElement[$this->currentTag] .= trim($data); - else - $this->currentElement[$this->currentTag] = trim($data); - } - * */ - } - // importXml - uncompresses the file, reads and parses its content. During parsing, // startElement, endElement, and dataElement functions are called as many times as necessary. // Actual import occurs in the endElement handler. @@ -213,8 +168,7 @@ function importXml() { // Initialize XML parser. $parser = xml_parser_create(); xml_set_object($parser, $this); - xml_set_element_handler($parser, 'startElement', 'endElement'); - xml_set_character_data_handler($parser, 'dataElement'); + xml_set_element_handler($parser, 'startElement', false); // We need to parse the file 2 times: // 1) First pass: determine if import is possible - there must be no login collisions. @@ -247,8 +201,7 @@ function importXml() { // Now we can do a second pass, where real work is done. $parser = xml_parser_create(); xml_set_object($parser, $this); - xml_set_element_handler($parser, 'startElement', 'endElement'); - xml_set_character_data_handler($parser, 'dataElement'); + xml_set_element_handler($parser, 'startElement', false); // Read and parse the content of the file. During parsing, startElement, endElement, and dataElement functions are called. $file = fopen($filename, 'r'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 69cf517ed..ea363bc86 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4393 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4394 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 15ae2165165da813912300d223c50b74f44cc1e0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 9 Nov 2018 14:25:57 +0000 Subject: [PATCH 0310/1848] ttOrgImportHelper class impoved to output conflicting login names. --- WEB-INF/lib/ttOrgImportHelper.class.php | 54 +++++++++---------------- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 + WEB-INF/resources/de.lang.php | 2 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 2 + WEB-INF/resources/fr.lang.php | 2 + WEB-INF/resources/gr.lang.php | 2 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 2 + WEB-INF/resources/pt-br.lang.php | 2 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 + WEB-INF/resources/sv.lang.php | 2 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + 31 files changed, 61 insertions(+), 35 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index c70d25805..b22c4fe3d 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -27,28 +27,17 @@ // +----------------------------------------------------------------------+ import('ttUserHelper'); -import('ttProjectHelper'); -import('ttTaskHelper'); -import('ttInvoiceHelper'); -import('ttTimeHelper'); -import('ttClientHelper'); -import('ttCustomFieldHelper'); -import('ttFavReportHelper'); -import('ttExpenseHelper'); -import('ttRoleHelper'); // ttOrgImportHelper - this class is a future replacement for ttImportHelper. // Currently, it is work in progress. // When done, it should handle import of complex groups consisting of other groups. class ttOrgImportHelper { var $errors = null; // Errors go here. Set in constructor by reference. - - var $currentElement = array(); // Current element of the XML file we are parsing. - var $currentTag = ''; // XML tag of the current element. + var $cannotImport = null; // A comma-separated string of entity names that we cannot import. + // TODO: rename the above to something better. var $canImport = true; // False if we cannot import data due to a login collision. var $firstPass = true; // True during first pass through the file. - var $org_id = null; // Organization id (same as top group_id). var $current_parent_group_id = null; // Current parent group id as we parse the file. // Set when we create a new group. @@ -71,38 +60,32 @@ function __construct(&$errors) { // startElement - callback handler for opening tag of an XML element in the file. function startElement($parser, $name, $attrs) { -/* - if ($name == 'GROUP' - || $name == 'USER') { - $this->currentElement = $attrs; - } - $this->currentTag = $name; -*/ + // First pass. We only check user logins for potential collisions with existing. if ($this->firstPass) { if ($name == 'USER' && $this->canImport) { - if ('' != $attrs['STATUS'] && ttUserHelper::getUserByLogin($attrs['LOGIN'])) { - // We have a login collision, cannot import any data. - $this->canImport = false; + $login = $attrs['LOGIN']; + if ('' != $attrs['STATUS'] && ttUserHelper::getUserByLogin($login)) { + // We have a login collision. Append colliding login to a list of things we cannot import. + $this->cannotImport .= ($this->cannotImport ? ", $login" : $login); } } - //$this->currentTag = ''; } // Second pass processing. We import data here, one tag at a time. if (!$this->firstPass && $this->canImport) { $mdb2 = getConnection(); - // We are in second pass through the XML file and can import data. + // We are in second pass and can import data. if ($name == 'GROUP') { // Create a new group. $group_id = $this->createGroup(array( 'parent_id' => $this->current_parent_group_id, 'org_id' => $this->org_id, - 'name' => $this->currentElement['NAME'], - 'currency' => $this->currentElement['CURRENCY'], - 'lang' => $this->currentElement['LANG'])); - // We only have 3 properties in export at the moment, while work is ongoing... + 'name' => $attrs['NAME'], + 'currency' => $attrs['CURRENCY'], + 'lang' => $attrs['LANG'])); + // We only have 3 properties at the moment, while work is ongoing... // Special handling for top group. if (!$this->org_id) { @@ -128,8 +111,7 @@ function startElement($parser, $name, $attrs) { if ($name == 'ROLE') { // We get here when processing a tag for the current group. // Add new role to $this->currentGroupRoles and a mapping to $this->currentGroupRoleMap. - $this->currentGroupRoles[$this->currentElement['ID']] = $this->currentElement; - $this->currentElement = array(); + $this->currentGroupRoles[$attrs['ID']] = $attrs; } } } @@ -185,11 +167,13 @@ function importXml() { xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser))); } - if (!$this->canImport) { - $this->errors->add($i18n->get('error.user_exists')); - break; - } } + if ($this->cannotImport) { + $this->canImport = false; + $this->errors->add($i18n->get('error.user_exists')); + $this->errors->add(sprintf($i18n->get('error.cannot_import'), $this->cannotImport)); + } + $this->firstPass = false; // We are done with 1st pass. xml_parser_free($parser); if ($file) fclose($file); diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 64a3b86a6..2a74077ea 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -116,6 +116,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Iniciar sessió', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 1cc0734d1..4d5937494 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -118,6 +118,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Přihlásit', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 280c9945c..914bba6d9 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -108,6 +108,8 @@ 'error.goto_uncompleted' => 'Gå til uafsluttet registrering.', 'error.overlap' => 'Tidsinterval overlapper eksisterende poster.', 'error.future_date' => 'Datoen er ud i fremtiden.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Log ind', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 48d5dcfaa..9e118e4ac 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -101,6 +101,8 @@ 'error.goto_uncompleted' => 'Zum unvollständigen Eintrag gehen.', 'error.overlap' => 'Der Zeitinterval überschneidet sich mit vorhandenen Einträgen.', 'error.future_date' => 'Datum ist in der Zukunft.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Anmelden', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index a28c87cfa..16f61f22a 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -100,6 +100,7 @@ 'error.goto_uncompleted' => 'Go to uncompleted entry.', 'error.overlap' => 'Time interval overlaps with existing records.', 'error.future_date' => 'Date is in future.', +'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Login', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 28dbb500b..2ee7de8c3 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -114,6 +114,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Iniciar sesion', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 854021632..86cde2a33 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -118,6 +118,8 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Login', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index d220c13d8..55625a883 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -116,6 +116,7 @@ 'error.overlap' => 'بازه زمانی با سوابق موجود هم پوشانی دارد.', // TODO: translate the following. // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'ورود', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 1e4b86a63..36b4d0bd3 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -110,6 +110,8 @@ 'error.goto_uncompleted' => 'Siirry kesken olevaan syötteeseen.', 'error.overlap' => 'Aikavälillä on päällekkäisiä syötteitä.', 'error.future_date' => 'Aika on tulevaisuudessa.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Kirjaudu', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 1e64e96d2..6290479f2 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -108,6 +108,8 @@ 'error.goto_uncompleted' => 'Aller à l\\\'entrée non terminée.', 'error.overlap' => 'Les heures des projets ne peuvent se chevaucher.', 'error.future_date' => 'Date ultérieure.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Connexion', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 180401534..f2de6f519 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -102,6 +102,8 @@ 'error.goto_uncompleted' => 'Μεταβείτε στην μη ολοκληρωμένη καταχώρηση.', 'error.overlap' => 'Το χρονικό διάστημα επικαλύπτει υπάρχουσες καταχωρήσεις.', 'error.future_date' => 'Η ημερομηνία είναι στο μέλλον.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Σύνδεση', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index a44d82e50..66cbea766 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -126,6 +126,7 @@ 'error.overlap' => 'טווח הזמן מתנגש עם רישומים קיימים.', // TODO: translate the following. // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'היכנס', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 9e59b544c..b740fe356 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -115,6 +115,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Bejelentkezés', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ea2b25140..5d0600aa1 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -106,6 +106,8 @@ 'error.goto_uncompleted' => 'Vai alle voce incompleta.', 'error.overlap' => 'Intervallo temporale sovrapposto a voci esistenti.', 'error.future_date' => 'La data è nel futuro.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Login', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 23afc5d99..6149e7c4b 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -120,6 +120,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'ログイン', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 6e0f59bdd..fa41f2ca0 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -119,6 +119,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => '로그인', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index b1f76af77..8c4a5244c 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -99,6 +99,8 @@ 'error.goto_uncompleted' => 'Ga naar onvolledige invoer.', 'error.overlap' => 'De huidige registratie overlapt een reeds bestaande registratie.', 'error.future_date' => 'Datum ligt in de toekomst.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Aanmelden', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 07026ae57..044a6f338 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -120,6 +120,7 @@ // TODO: translate the following. // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Innlogging', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index f88888fc3..c94ae1c95 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -112,6 +112,8 @@ 'error.goto_uncompleted' => 'Przejdź do niedokończonego wpisu.', 'error.overlap' => 'Okres czasowy nakłada się z istniejącymi wpisami.', 'error.future_date' => 'Data jest w przyszłości.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons 'button.login' => 'Login', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 79370ec62..f40b5f017 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -109,6 +109,8 @@ 'error.goto_uncompleted' => 'Ir até a entrada incompleta.', 'error.overlap' => 'O intervalo se sobrepõe com entradas já existentes.', 'error.future_date' => 'Data é no futuro.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Login', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index c9b24b347..4f7d748b9 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -112,6 +112,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Login', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 223415522..82d5d3e6a 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -120,6 +120,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Autentifica', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 4a5dbd629..3974d1673 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -99,6 +99,7 @@ 'error.goto_uncompleted' => 'Посмотреть неоконченную запись.', 'error.overlap' => 'Интервал времени перекрывается с существующими записями.', 'error.future_date' => 'Дата в будущем.', +'error.cannot_import' => 'Невозможно импортировать: %s.', // Labels for buttons. 'button.login' => 'Войти', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 13992fe8b..cfca9b0a8 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -115,6 +115,7 @@ // TODO: translate the following. // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Prihlásiť', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index df5ddf52a..e07b20898 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -109,6 +109,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Prijava', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index a35014c01..6bc886a0a 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -109,6 +109,8 @@ 'error.goto_uncompleted' => 'Prikaži postojeći unos.', 'error.overlap' => 'Navedeni vremenski interval se podudara sa već unetim vremenom.', 'error.future_date' => 'Naveli ste budući datum.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Prijava', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index fb4289a81..a646aab5e 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -106,6 +106,8 @@ 'error.goto_uncompleted' => 'Visa registrering.', 'error.overlap' => 'Tidsintervallet överlappar med en redan existerande tidsregistrering.', 'error.future_date' => 'Det går inte att registrera tider framåt i tiden.', +// TODO: translate the following. +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Logga in', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 4b167e882..eb4887542 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -123,6 +123,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => 'Giriş', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 2d55378f9..e37138ba3 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -112,6 +112,7 @@ // TODO: translate the following. // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => '登录', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 74d379fc3..f46f45627 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -117,6 +117,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. 'button.login' => '登錄', From 6825261fd55ae8caf490fe52e5cad466cc6deb81 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 9 Nov 2018 14:47:05 +0000 Subject: [PATCH 0311/1848] Renamed a class member to avoid confusion. --- WEB-INF/lib/ttOrgImportHelper.class.php | 14 ++++++-------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index b22c4fe3d..ba1b120fe 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -32,11 +32,9 @@ // Currently, it is work in progress. // When done, it should handle import of complex groups consisting of other groups. class ttOrgImportHelper { - var $errors = null; // Errors go here. Set in constructor by reference. - var $cannotImport = null; // A comma-separated string of entity names that we cannot import. - // TODO: rename the above to something better. - - var $canImport = true; // False if we cannot import data due to a login collision. + var $errors = null; // Errors go here. Set in constructor by reference. + var $conflicting_entities = null; // A comma-separated list of entity names we cannot import. + var $canImport = true; // False if we cannot import data due to a conflict such as login collision. var $firstPass = true; // True during first pass through the file. var $org_id = null; // Organization id (same as top group_id). var $current_parent_group_id = null; // Current parent group id as we parse the file. @@ -67,7 +65,7 @@ function startElement($parser, $name, $attrs) { $login = $attrs['LOGIN']; if ('' != $attrs['STATUS'] && ttUserHelper::getUserByLogin($login)) { // We have a login collision. Append colliding login to a list of things we cannot import. - $this->cannotImport .= ($this->cannotImport ? ", $login" : $login); + $this->conflicting_entities .= ($this->conflicting_entities ? ", $login" : $login); } } } @@ -168,10 +166,10 @@ function importXml() { xml_get_current_line_number($parser))); } } - if ($this->cannotImport) { + if ($this->conflicting_entities) { $this->canImport = false; $this->errors->add($i18n->get('error.user_exists')); - $this->errors->add(sprintf($i18n->get('error.cannot_import'), $this->cannotImport)); + $this->errors->add(sprintf($i18n->get('error.cannot_import'), $this->conflicting_entities)); } $this->firstPass = false; // We are done with 1st pass. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ea363bc86..bb6e438b9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4394 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4395 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 94af2134f643b14c7f1a4838e88f7d6ed36aebcc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 9 Nov 2018 16:58:25 +0000 Subject: [PATCH 0312/1848] Disabled bot protection check for logged in site admin. --- WEB-INF/lib/ttRegistrator.class.php | 9 ++++++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index b3551dad6..44841f503 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -84,11 +84,14 @@ function register() { if ($this->err->yes()) return false; // There are errors, do not proceed. global $i18n; + global $user; // Protection fom too many recent bot registrations from user IP. - if ($this->registeredRecently()) { - $this->err->add($i18n->get('error.access_denied')); - return false; + if (!$user->can('administer_site')) { // No problems for site admin. + if ($this->registeredRecently()) { + $this->err->add($i18n->get('error.access_denied')); + return false; + } } import('ttUserHelper'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bb6e438b9..848425e0b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4395 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4396 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From ce2ddc553c3e30ffaa62d6e0f2e1220ca7f63f34 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 9 Nov 2018 17:36:29 +0000 Subject: [PATCH 0313/1848] Fixed populating created_by for user created by admin. --- WEB-INF/lib/ttRegistrator.class.php | 8 +++++--- WEB-INF/templates/footer.tpl | 2 +- admin_group_add.php | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 44841f503..c206881dc 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -86,7 +86,7 @@ function register() { global $i18n; global $user; - // Protection fom too many recent bot registrations from user IP. + // Protection from too many recent bot registrations from user IP. if (!$user->can('administer_site')) { // No problems for site admin. if ($this->registeredRecently()) { $this->err->add($i18n->get('error.access_denied')); @@ -121,7 +121,9 @@ function register() { return false; } - if (!$this->setCreatedBy($this->user_id)) + // Set created_by appropriately (admin or self). + $created_by = $user->can('administer_site') ? $user->id : $this->user_id; + if (!$this->setCreatedBy($created_by)) return false; return true; @@ -189,7 +191,7 @@ function setCreatedBy($user_id) { } // Update top manager. - $sql = "update tt_users set created_by = $user_id where id = $user_id and group_id = $this->group_id"; + $sql = "update tt_users set created_by = $user_id where id = $this->user_id and group_id = $this->group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) { $this->err->add($i18n->get('error.db')); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 848425e0b..67fbea434 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4396 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4397 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_group_add.php b/admin_group_add.php index 21570a967..71dde8a08 100644 --- a/admin_group_add.php +++ b/admin_group_add.php @@ -106,7 +106,8 @@ import('ttRegistrator'); $registrator = new ttRegistrator($fields, $err); $registrator->register(); - $registrator->setCreatedBy($user->id); // Override created_by to admin account. + // $registrator->setCreatedBy($user->id); // Override created_by to admin account. + // TODO: redo ttRegistrator class by passing in created_by_id in $fields to keep code straightforward. if ($err->no()) { header('Location: admin_groups.php'); exit(); From 725af06a89e5a7014dfdc9081222f313a58a6bb6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 9 Nov 2018 19:24:35 +0000 Subject: [PATCH 0314/1848] Some refactoring and cleanup in ttRegistrator class. --- WEB-INF/lib/ttRegistrator.class.php | 21 ++++++++++++++------- WEB-INF/templates/footer.tpl | 2 +- admin_group_add.php | 5 ++--- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index c206881dc..8e755837e 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -35,7 +35,12 @@ class ttRegistrator { var $group_name = null; // Group name. var $currency = null; // Currency. var $lang = null; // Language. + var $created_by_id = null; // User, who uses the instance. + // Currently, there are 2 possibilities: + // 1) Self-registration, or null here. + // 2) Registration by admin with a user_id. var $group_id = null; // Group id, set after we create a group. + var $org_id = null; // Organization id, the same as group_id (top group in org). var $role_id = null; // Role id for top managers. var $user_id = null; // User id after registration. var $err = null; // Error object, passed to us as reference. @@ -52,6 +57,7 @@ function __construct($fields, &$err) { $this->currency = $fields['currency']; $this->lang = $fields['lang']; if (!$this->lang) $this->lang = 'en'; + $this->created_by_id = (int) $fields['created_by_id']; $this->err = $err; // Validate passed in parameters. @@ -87,7 +93,7 @@ function register() { global $user; // Protection from too many recent bot registrations from user IP. - if (!$user->can('administer_site')) { // No problems for site admin. + if (!$this->created_by_id) { // No problems for logged in user (site admin). if ($this->registeredRecently()) { $this->err->add($i18n->get('error.access_denied')); return false; @@ -103,6 +109,7 @@ function register() { // Create a new group. $this->group_id = $this->createGroup(); + $this->org_id = $this->group_id; if (!$this->group_id) { $this->err->add($i18n->get('error.db')); return false; @@ -121,8 +128,8 @@ function register() { return false; } - // Set created_by appropriately (admin or self). - $created_by = $user->can('administer_site') ? $user->id : $this->user_id; + // Set created_by appropriately. + $created_by = $this->created_by_id ? $this->created_by_id : $this->user_id; if (!$this->setCreatedBy($created_by)) return false; @@ -164,7 +171,7 @@ function createUser() { $email = $mdb2->quote($this->email); $created = 'now()'; $created_ip = $mdb2->quote($_SERVER['REMOTE_ADDR']); - $values = "values($login, $password, $name, $this->group_id, $this->group_id, $this->role_id, $email, $created, $created_ip)"; + $values = "values($login, $password, $name, $this->group_id, $this->org_id, $this->role_id, $email, $created, $created_ip)"; $sql = 'insert into tt_users (login, password, name, group_id, org_id, role_id, email, created, created_ip) '.$values; $affected = $mdb2->exec($sql); @@ -176,14 +183,14 @@ function createUser() { } // The setCreatedBy sets created_by field for both group and user to passed in user_id. - function setCreatedBy($user_id) { + private function setCreatedBy($user_id) { if ($this->err->yes()) return false; // There are errors, do not proceed. global $i18n; $mdb2 = getConnection(); // Update group. - $sql = "update tt_groups set created_by = $user_id where id = $this->group_id"; + $sql = "update tt_groups set created_by = $user_id where id = $this->group_id and org_id = $this->org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) { $this->err->add($i18n->get('error.db')); @@ -191,7 +198,7 @@ function setCreatedBy($user_id) { } // Update top manager. - $sql = "update tt_users set created_by = $user_id where id = $this->user_id and group_id = $this->group_id"; + $sql = "update tt_users set created_by = $user_id where id = $this->user_id and group_id = $this->group_id and org_id = $this->org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) { $this->err->add($i18n->get('error.db')); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 67fbea434..fd5880c7d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4397 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4398 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_group_add.php b/admin_group_add.php index 71dde8a08..e40be98e4 100644 --- a/admin_group_add.php +++ b/admin_group_add.php @@ -100,14 +100,13 @@ 'email' => $cl_manager_email, 'group_name' => $cl_group_name, 'currency' => CURRENCY_DEFAULT, - 'lang' => $cl_lang); + 'lang' => $cl_lang, + 'created_by_id' => $user->id); // Create an instance of ttRegistrator class. import('ttRegistrator'); $registrator = new ttRegistrator($fields, $err); $registrator->register(); - // $registrator->setCreatedBy($user->id); // Override created_by to admin account. - // TODO: redo ttRegistrator class by passing in created_by_id in $fields to keep code straightforward. if ($err->no()) { header('Location: admin_groups.php'); exit(); From bf2399f1315130312cc513cdd4efbcffaeb617d0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 9 Nov 2018 22:18:20 +0000 Subject: [PATCH 0315/1848] Improved new export a bit by adding tasks to output. --- WEB-INF/lib/ttAdmin.class.php | 12 +++++- WEB-INF/lib/ttGroupExportHelper.class.php | 48 ++++++++++++++++++++--- WEB-INF/lib/ttOrgImportHelper.class.php | 28 ++++++++----- WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 73 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index 30c78f94b..23d8480d7 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -41,7 +41,17 @@ function __construct(&$err = null) { // getSubgroups rerurns an array of subgroups for a group. function getSubgroups($group_id) { - return array(); // TODO: not yet implemented. + $mdb2 = getConnection(); + + $subgroups = array(); + $sql = "select id from tt_groups where parent_id = $group_id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $subgroups[] = $val; + } + } + return $subgroups; } // getUsers obtains user ids in a group. diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index af49e19e6..5338d2d46 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -42,6 +42,7 @@ class ttGroupExportHelper { // We write to the file sequentially (1,2,3...) while in the database the entities have different ids. var $userMap = array(); // User ids. var $roleMap = array(); // Role ids. + var $taskMap = array(); // Task ids. var $clientMap = array(); // Client ids. // Constructor. @@ -114,6 +115,24 @@ function getRoles() { return false; } + // getTasks - obtains all tasks defined for group. + function getTasks() { + global $user; + $mdb2 = getConnection(); + + $result = array(); + $sql = "select * from tt_tasks where group_id = $this->group_id and org_id = $user->org_id"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + // writeData writes group data into file. function writeData() { @@ -138,15 +157,20 @@ function writeData() { foreach ($roles as $key=>$role_item) $this->roleMap[$role_item['id']] = $key + 1; + // Prepare task map. + $tasks = $this->getTasks(); + foreach ($tasks as $key=>$task_item) + $this->taskMap[$task_item['id']] = $key + 1; + // Prepare client map. $clients = ttTeamHelper::getAllClients($this->group_id, true); foreach ($clients as $key=>$client_item) $this->clientMap[$client_item['id']] = $key + 1; // Write roles. - fwrite($this->file, $this->indentation."\n"); + fwrite($this->file, $this->indentation." \n"); foreach ($roles as $role) { - $role_part = $this->indentation.' '."roleMap[$role['id']]."\""; + $role_part = $this->indentation.' '."roleMap[$role['id']]."\""; $role_part .= " name=\"".htmlentities($role['name'])."\""; $role_part .= " description=\"".htmlentities($role['description'])."\""; $role_part .= " rank=\"".$role['rank']."\""; @@ -155,13 +179,25 @@ function writeData() { $role_part .= ">\n"; fwrite($this->file, $role_part); } - fwrite($this->file, $this->indentation."\n"); + fwrite($this->file, $this->indentation." \n"); + + // Write tasks. + fwrite($this->file, $this->indentation." \n"); + foreach ($tasks as $task) { + $task_part = $this->indentation.' '."taskMap[$task['id']]."\""; + $task_part .= " name=\"".htmlentities($task['name'])."\""; + $task_part .= " description=\"".htmlentities($task['description'])."\""; + $task_part .= " status=\"".$task['status']."\""; + $task_part .= ">\n"; + fwrite($this->file, $task_part); + } + fwrite($this->file, $this->indentation." \n"); // Write users. - fwrite($this->file, $this->indentation."\n"); + fwrite($this->file, $this->indentation." \n"); foreach ($users as $user_item) { $role_id = $user_item['rank'] == 512 ? 0 : $this->roleMap[$user_item['role_id']]; // Special role_id 0 (not null) for top manager. - $user_part = $this->indentation.' '."userMap[$user_item['id']]."\""; + $user_part = $this->indentation.' '."userMap[$user_item['id']]."\""; $user_part .= " name=\"".htmlentities($user_item['name'])."\""; $user_part .= " login=\"".htmlentities($user_item['login'])."\""; $user_part .= " password=\"".$user_item['password']."\""; @@ -173,7 +209,7 @@ function writeData() { $user_part .= ">\n"; fwrite($this->file, $user_part); } - fwrite($this->file, $this->indentation."\n"); + fwrite($this->file, $this->indentation." \n"); // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index ba1b120fe..015579c00 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -27,6 +27,7 @@ // +----------------------------------------------------------------------+ import('ttUserHelper'); +import('ttRoleHelper'); // ttOrgImportHelper - this class is a future replacement for ttImportHelper. // Currently, it is work in progress. @@ -37,10 +38,11 @@ class ttOrgImportHelper { var $canImport = true; // False if we cannot import data due to a conflict such as login collision. var $firstPass = true; // True during first pass through the file. var $org_id = null; // Organization id (same as top group_id). - var $current_parent_group_id = null; // Current parent group id as we parse the file. + var $current_group_id = null; // Current group id during parsing. + var $current_parent_group_id = null; // Current parent group id during parsing. // Set when we create a new group. - // Entities for current group. - var $currentGroupRoles = array(); // Array of arrays of role properties. + // Entities for current group. -- Looks like they are not needed as we insert right away... + // var $currentGroupRoles = array(); // Array of arrays of role properties. // var $currentGroupUsers = array(); // Array of arrays of user properties. // Entity maps for current group. They map XML ids with database ids. @@ -77,7 +79,7 @@ function startElement($parser, $name, $attrs) { // We are in second pass and can import data. if ($name == 'GROUP') { // Create a new group. - $group_id = $this->createGroup(array( + $this->current_group_id = $this->createGroup(array( 'parent_id' => $this->current_parent_group_id, 'org_id' => $this->org_id, 'name' => $attrs['NAME'], @@ -87,13 +89,13 @@ function startElement($parser, $name, $attrs) { // Special handling for top group. if (!$this->org_id) { - $this->org_id = $group_id; - $sql = "update tt_groups set org_id = $group_id where org_id is NULL and id = $group_id"; + $this->org_id = $this->current_group_id; + $sql = "update tt_groups set org_id = $this->current_group_id where org_id is NULL and id = $this->current_group_id"; $affected = $mdb2->exec($sql); // TODO: design a better error handling approach for the entire import process. } // Set current parent group. - $this->current_parent_group_id = $group_id; + $this->current_parent_group_id = $this->current_group_id; } if ($name == 'ROLES') { @@ -108,8 +110,16 @@ function startElement($parser, $name, $attrs) { if ($name == 'ROLE') { // We get here when processing a tag for the current group. - // Add new role to $this->currentGroupRoles and a mapping to $this->currentGroupRoleMap. - $this->currentGroupRoles[$attrs['ID']] = $attrs; + $role_id = ttRoleHelper::insert(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'name' => $attrs['NAME'], + 'description' => $attrs['DESCRIPTION'], + 'rank' => $attrs['RANK'], + 'rights' => $attrs['RIGHTS'], + 'status' => $attrs['STATUS'])); + // Add a mapping. + $this->currentGroupRoleMap[$attrs['ID']] = $role_id; } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fd5880c7d..9e7af7c95 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4398 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4399 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From da1736600c488f35a9b900a79ed4fe9b53d909a5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 12:12:17 +0000 Subject: [PATCH 0316/1848] Localized xml parsing error string. --- WEB-INF/lib/ttOrgImportHelper.class.php | 12 ++++++------ WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 32 files changed, 37 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 015579c00..57f221082 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -171,9 +171,9 @@ function importXml() { $file = fopen($filename, 'r'); while ($data = fread($file, 4096)) { if (!xml_parse($parser, $data, feof($file))) { - $this->errors->add(sprintf("XML error: %s at line %d", - xml_error_string(xml_get_error_code($parser)), - xml_get_current_line_number($parser))); + $this->errors->add(sprintf($i18n->get('error.xml'), + xml_get_current_line_number($parser), + xml_error_string(xml_get_error_code($parser)))); } } if ($this->conflicting_entities) { @@ -199,9 +199,9 @@ function importXml() { $file = fopen($filename, 'r'); while ($data = fread($file, 4096)) { if (!xml_parse($parser, $data, feof($file))) { - $this->errors->add(sprintf("XML error: %s at line %d", - xml_error_string(xml_get_error_code($parser)), - xml_get_current_line_number($parser))); + $this->errors->add(sprintf($i18n->get('error.xml'), + xml_get_current_line_number($parser), + xml_error_string(xml_get_error_code($parser)))); } } xml_parser_free($parser); diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 2a74077ea..5bfd796e9 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -116,6 +116,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 4d5937494..d407dccf6 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -118,6 +118,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 914bba6d9..f475e06f1 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -109,6 +109,7 @@ 'error.overlap' => 'Tidsinterval overlapper eksisterende poster.', 'error.future_date' => 'Datoen er ud i fremtiden.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 9e118e4ac..ea58b9a4e 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -102,6 +102,7 @@ 'error.overlap' => 'Der Zeitinterval überschneidet sich mit vorhandenen Einträgen.', 'error.future_date' => 'Datum ist in der Zukunft.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 16f61f22a..82059051e 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -100,6 +100,7 @@ 'error.goto_uncompleted' => 'Go to uncompleted entry.', 'error.overlap' => 'Time interval overlaps with existing records.', 'error.future_date' => 'Date is in future.', +'error.xml' => 'Error in XML file at line %d: %s.', 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 2ee7de8c3..740be1230 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -114,6 +114,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 86cde2a33..b9f784f73 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -119,6 +119,7 @@ // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 55625a883..e6d54ee93 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -116,6 +116,7 @@ 'error.overlap' => 'بازه زمانی با سوابق موجود هم پوشانی دارد.', // TODO: translate the following. // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 36b4d0bd3..316b3f8f9 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -111,6 +111,7 @@ 'error.overlap' => 'Aikavälillä on päällekkäisiä syötteitä.', 'error.future_date' => 'Aika on tulevaisuudessa.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 6290479f2..529fc2da0 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -109,6 +109,7 @@ 'error.overlap' => 'Les heures des projets ne peuvent se chevaucher.', 'error.future_date' => 'Date ultérieure.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index f2de6f519..2b523141b 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -103,6 +103,7 @@ 'error.overlap' => 'Το χρονικό διάστημα επικαλύπτει υπάρχουσες καταχωρήσεις.', 'error.future_date' => 'Η ημερομηνία είναι στο μέλλον.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 66cbea766..878e5ba9d 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -126,6 +126,7 @@ 'error.overlap' => 'טווח הזמן מתנגש עם רישומים קיימים.', // TODO: translate the following. // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index b740fe356..f98dffa13 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -115,6 +115,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 5d0600aa1..07ed67c56 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -107,6 +107,7 @@ 'error.overlap' => 'Intervallo temporale sovrapposto a voci esistenti.', 'error.future_date' => 'La data è nel futuro.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 6149e7c4b..0d077507c 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -120,6 +120,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index fa41f2ca0..0bc21ee8a 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -119,6 +119,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 8c4a5244c..02e0ab326 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -100,6 +100,7 @@ 'error.overlap' => 'De huidige registratie overlapt een reeds bestaande registratie.', 'error.future_date' => 'Datum ligt in de toekomst.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 044a6f338..c7f0fe254 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -120,6 +120,7 @@ // TODO: translate the following. // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index c94ae1c95..ffc6d37bb 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -113,6 +113,7 @@ 'error.overlap' => 'Okres czasowy nakłada się z istniejącymi wpisami.', 'error.future_date' => 'Data jest w przyszłości.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index f40b5f017..9b5bf7594 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -110,6 +110,7 @@ 'error.overlap' => 'O intervalo se sobrepõe com entradas já existentes.', 'error.future_date' => 'Data é no futuro.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 4f7d748b9..e2e95a8a7 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -112,6 +112,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 82d5d3e6a..6840977e6 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -120,6 +120,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3974d1673..3354eaaae 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -99,6 +99,7 @@ 'error.goto_uncompleted' => 'Посмотреть неоконченную запись.', 'error.overlap' => 'Интервал времени перекрывается с существующими записями.', 'error.future_date' => 'Дата в будущем.', +'error.xml' => 'Ошибка в файле XML на строке %d: %s.', 'error.cannot_import' => 'Невозможно импортировать: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index cfca9b0a8..18fa470d1 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -115,6 +115,7 @@ // TODO: translate the following. // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index e07b20898..7f09aac45 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -109,6 +109,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 6bc886a0a..890b8ee95 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -110,6 +110,7 @@ 'error.overlap' => 'Navedeni vremenski interval se podudara sa već unetim vremenom.', 'error.future_date' => 'Naveli ste budući datum.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index a646aab5e..d2e227dc5 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -107,6 +107,7 @@ 'error.overlap' => 'Tidsintervallet överlappar med en redan existerande tidsregistrering.', 'error.future_date' => 'Det går inte att registrera tider framåt i tiden.', // TODO: translate the following. +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index eb4887542..7f34cb370 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -123,6 +123,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index e37138ba3..96e43164c 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -112,6 +112,7 @@ // TODO: translate the following. // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index f46f45627..8664f1934 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -117,6 +117,7 @@ // 'error.goto_uncompleted' => 'Go to uncompleted entry.', // 'error.overlap' => 'Time interval overlaps with existing records.', // 'error.future_date' => 'Date is in future.', +// 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // Labels for buttons. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9e7af7c95..3789b25cb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4399 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4400 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 310dc5d75dc9ee3edac18b362a71cee758376d53 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 13:08:22 +0000 Subject: [PATCH 0317/1848] Imporved error handling in new import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 31 ++++++++++++++----------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 57f221082..991424e61 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -60,6 +60,7 @@ function __construct(&$errors) { // startElement - callback handler for opening tag of an XML element in the file. function startElement($parser, $name, $attrs) { + global $i18n; // First pass. We only check user logins for potential collisions with existing. if ($this->firstPass) { @@ -73,7 +74,7 @@ function startElement($parser, $name, $attrs) { } // Second pass processing. We import data here, one tag at a time. - if (!$this->firstPass && $this->canImport) { + if (!$this->firstPass && $this->canImport && $this->errors->no()) { $mdb2 = getConnection(); // We are in second pass and can import data. @@ -88,28 +89,24 @@ function startElement($parser, $name, $attrs) { // We only have 3 properties at the moment, while work is ongoing... // Special handling for top group. - if (!$this->org_id) { + if (!$this->org_id && $this->current_group_id) { $this->org_id = $this->current_group_id; $sql = "update tt_groups set org_id = $this->current_group_id where org_id is NULL and id = $this->current_group_id"; $affected = $mdb2->exec($sql); - // TODO: design a better error handling approach for the entire import process. } - // Set current parent group. + // Set parent group to create subgroups with this group as parent at next entry here. $this->current_parent_group_id = $this->current_group_id; } if ($name == 'ROLES') { - // If we get here, we have to recycle both $currentGroupRoles and $currentGroupRoleMap. - unset($this->currentGroupRoles); + // If we get here, we have to recycle $currentGroupRoleMap. unset($this->currentGroupRoleMap); - $this->currentGroupRoles = array(); $this->currentGroupRoleMap = array(); - // Both arrays are now empty. - // They will get reconstructed after processing of elements in XML. See below. + // Role map is reconstructed after processing elements in XML. See below. } if ($name == 'ROLE') { - // We get here when processing a tag for the current group. + // We get here when processing tags for the current group. $role_id = ttRoleHelper::insert(array( 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, @@ -118,8 +115,10 @@ function startElement($parser, $name, $attrs) { 'rank' => $attrs['RANK'], 'rights' => $attrs['RIGHTS'], 'status' => $attrs['STATUS'])); - // Add a mapping. - $this->currentGroupRoleMap[$attrs['ID']] = $role_id; + if ($role_id) { + // Add a mapping. + $this->currentGroupRoleMap[$attrs['ID']] = $role_id; + } else $this->errors->add($i18n->get('error.db')); } } } @@ -189,6 +188,7 @@ function importXml() { unlink($filename); return; } + if ($this->errors->yes()) return; // Exit if we have errors. // Now we can do a second pass, where real work is done. $parser = xml_parser_create(); @@ -238,7 +238,7 @@ function uncompress($in, $out) { // createGroup function creates a new group. private function createGroup($fields) { - global $user; + global $i18n; $mdb2 = getConnection(); $columns = '(parent_id, org_id, name, currency, lang)'; @@ -274,7 +274,10 @@ private function createGroup($fields) { $sql = 'insert into tt_groups '.$columns.$values; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; + if (is_a($affected, 'PEAR_Error')) { + $this->errors->add($i18n->get('error.db')); + return false; + } $group_id = $mdb2->lastInsertID('tt_groups', 'id'); return $group_id; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3789b25cb..45cd36fd7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4400 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4401 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 3b5e01059ad07bfc7ef7c07ba235a73a92ddc3f3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 13:43:14 +0000 Subject: [PATCH 0318/1848] Added importing of tasks in new import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 25 ++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 991424e61..3ccd3a665 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -28,6 +28,7 @@ import('ttUserHelper'); import('ttRoleHelper'); +import('ttTaskHelper'); // ttOrgImportHelper - this class is a future replacement for ttImportHelper. // Currently, it is work in progress. @@ -46,7 +47,8 @@ class ttOrgImportHelper { // var $currentGroupUsers = array(); // Array of arrays of user properties. // Entity maps for current group. They map XML ids with database ids. - var $currentGroupRoleMap = array(); // Maps role ids from XML to their database ids. + var $currentGroupRoleMap = array(); + var $currentGroupTaskMap = array(); //var $userMap = array(); // User ids. //var $projectMap = array(); // Project ids. //var $taskMap = array(); // Task ids. @@ -120,6 +122,27 @@ function startElement($parser, $name, $attrs) { $this->currentGroupRoleMap[$attrs['ID']] = $role_id; } else $this->errors->add($i18n->get('error.db')); } + + if ($name == 'TASKS') { + // If we get here, we have to recycle $currentGroupTaskMap. + unset($this->currentGroupTaskMap); + $this->currentGroupTaskMap = array(); + // Task map is reconstructed after processing elements in XML. See below. + } + + if ($name == 'TASK') { + // We get here when processing tags for the current group. + $task_id = ttTaskHelper::insert(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'name' => $attrs['NAME'], + 'description' => $attrs['DESCRIPTION'], + 'status' => $attrs['STATUS'])); + if ($task_id) { + // Add a mapping. + $this->currentGroupTaskMap[$attrs['ID']] = $task_id; + } else $this->errors->add($i18n->get('error.db')); + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 45cd36fd7..92fda1f14 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4401 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4402 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From da106606ea1e1553b080bf4491188d92a436b990 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 14:07:30 +0000 Subject: [PATCH 0319/1848] Improved new export by adding projects in output. --- WEB-INF/lib/ttGroupExportHelper.class.php | 52 +++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 5338d2d46..215414f64 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -40,10 +40,11 @@ class ttGroupExportHelper { // The following arrays are maps between entity ids in the file versus the database. // We write to the file sequentially (1,2,3...) while in the database the entities have different ids. - var $userMap = array(); // User ids. - var $roleMap = array(); // Role ids. - var $taskMap = array(); // Task ids. - var $clientMap = array(); // Client ids. + var $userMap = array(); // User ids. + var $roleMap = array(); // Role ids. + var $taskMap = array(); // Task ids. + var $projectMap = array(); // Project ids. + var $clientMap = array(); // Client ids. // Constructor. function __construct($group_id, $file, $indentation) { @@ -133,6 +134,24 @@ function getTasks() { return false; } + // getProjects - obtains all projects defined for group. + function getProjects() { + global $user; + $mdb2 = getConnection(); + + $result = array(); + $sql = "select * from tt_projects where group_id = $this->group_id and org_id = $user->org_id"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + // writeData writes group data into file. function writeData() { @@ -162,6 +181,11 @@ function writeData() { foreach ($tasks as $key=>$task_item) $this->taskMap[$task_item['id']] = $key + 1; + // Prepare project map. + $projects = $this->getProjects(); + foreach ($projects as $key=>$project_item) + $this->projectMap[$project_item['id']] = $key + 1; + // Prepare client map. $clients = ttTeamHelper::getAllClients($this->group_id, true); foreach ($clients as $key=>$client_item) @@ -193,6 +217,26 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); + // Write projects. + fwrite($this->file, $this->indentation." \n"); + foreach ($projects as $project_item) { + if($project_item['tasks']){ + $tasks = explode(',', $project_item['tasks']); + $tasks_mapped = array(); + foreach ($tasks as $item) + $tasks_mapped[] = $this->taskMap[$item]; + $tasks_str = implode(',', $tasks_mapped); + } + $project_part = $this->indentation.' '."projectMap[$project_item['id']]."\""; + $project_part .= " name=\"".htmlentities($project_item['name'])."\""; + $project_part .= " description=\"".htmlentities($project_item['description'])."\""; + $project_part .= " tasks=\"".$tasks_str."\""; + $project_part .= " status=\"".$project_item['status']."\""; + $project_part .= ">\n"; + fwrite($this->file, $project_part); + } + fwrite($this->file, $this->indentation." \n"); + // Write users. fwrite($this->file, $this->indentation." \n"); foreach ($users as $user_item) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 92fda1f14..98575976c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4402 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4403 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6bbd7742c4daa1b3d16e14cfb7f64c2b651a5362 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 14:29:51 +0000 Subject: [PATCH 0320/1848] Improved new import by adding projects. --- WEB-INF/lib/ttOrgImportHelper.class.php | 34 +++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 3ccd3a665..f8dbc523b 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -29,6 +29,7 @@ import('ttUserHelper'); import('ttRoleHelper'); import('ttTaskHelper'); +import('ttProjectHelper'); // ttOrgImportHelper - this class is a future replacement for ttImportHelper. // Currently, it is work in progress. @@ -47,8 +48,9 @@ class ttOrgImportHelper { // var $currentGroupUsers = array(); // Array of arrays of user properties. // Entity maps for current group. They map XML ids with database ids. - var $currentGroupRoleMap = array(); - var $currentGroupTaskMap = array(); + var $currentGroupRoleMap = array(); + var $currentGroupTaskMap = array(); + var $currentGroupProjectMap = array(); //var $userMap = array(); // User ids. //var $projectMap = array(); // Project ids. //var $taskMap = array(); // Task ids. @@ -143,6 +145,34 @@ function startElement($parser, $name, $attrs) { $this->currentGroupTaskMap[$attrs['ID']] = $task_id; } else $this->errors->add($i18n->get('error.db')); } + + if ($name == 'PROJECTS') { + // If we get here, we have to recycle $currentGroupProjectMap. + unset($this->currentGroupProjectMap); + $this->currentGroupProjectMap = array(); + // Project map is reconstructed after processing elements in XML. See below. + } + + if ($name == 'PROJECT') { + // We get here when processing tags for the current group. + + // Prepare a list of task ids. + $tasks = explode(',', $attrs['TASKS']); + foreach ($tasks as $id) + $mapped_tasks[] = $this->currentGroupTaskMap[$id]; + + $project_id = ttProjectHelper::insert(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'name' => $attrs['NAME'], + 'description' => $attrs['DESCRIPTION'], + 'tasks' => $mapped_tasks, + 'status' => $attrs['STATUS'])); + if ($project_id) { + // Add a mapping. + $this->currentGroupProjectMap[$attrs['ID']] = $project_id; + } else $this->errors->add($i18n->get('error.db')); + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 98575976c..b09112d37 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4403 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4404 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From d79a4bb229f2ce666fdb8d663e51e55e39a91827 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 14:53:37 +0000 Subject: [PATCH 0321/1848] Improved new export by adding clients in output. --- WEB-INF/lib/ttGroupExportHelper.class.php | 41 ++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 215414f64..054c43546 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -152,6 +152,24 @@ function getProjects() { return false; } + // getClients - obtains all clients defined for group. + function getClients() { + global $user; + $mdb2 = getConnection(); + + $result = array(); + $sql = "select * from tt_clients where group_id = $this->group_id and org_id = $user->org_id"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + // writeData writes group data into file. function writeData() { @@ -187,7 +205,7 @@ function writeData() { $this->projectMap[$project_item['id']] = $key + 1; // Prepare client map. - $clients = ttTeamHelper::getAllClients($this->group_id, true); + $clients = $this->getClients(); foreach ($clients as $key=>$client_item) $this->clientMap[$client_item['id']] = $key + 1; @@ -237,6 +255,27 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); + // Write clients. + fwrite($this->file, $this->indentation." \n"); + foreach ($clients as $client_item) { + if($client_item['projects']){ + $projects_db = explode(',', $client_item['projects']); + $projects_mapped = array(); + foreach ($projects_db as $item) + $projects_mapped[] = $this->projectMap[$item]; + $projects_str = implode(',', $projects_mapped); + } + $client_part = $this->indentation.' '."clientMap[$client_item['id']]."\""; + $client_part .= " name=\"".htmlentities($client_item['name'])."\""; + $client_part .= " address=\"".htmlentities($client_item['address'])."\""; + $client_part .= " tax=\"".$client_item['tax']."\""; + $client_part .= " projects=\"".$projects_str."\""; + $client_part .= " status=\"".$client_item['status']."\""; + $client_part .= ">\n"; + fwrite($this->file, $client_part); + } + fwrite($this->file, $this->indentation." \n"); + // Write users. fwrite($this->file, $this->indentation." \n"); foreach ($users as $user_item) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b09112d37..4d6e74dad 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4404 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4405 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a9354220ac7de34e59172d112884acab96f37538 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 15:17:30 +0000 Subject: [PATCH 0322/1848] Improved new import with integrating clients. --- WEB-INF/lib/ttOrgImportHelper.class.php | 36 +++++++++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index f8dbc523b..7c00f2543 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -30,6 +30,7 @@ import('ttRoleHelper'); import('ttTaskHelper'); import('ttProjectHelper'); +import('ttClientHelper'); // ttOrgImportHelper - this class is a future replacement for ttImportHelper. // Currently, it is work in progress. @@ -51,11 +52,7 @@ class ttOrgImportHelper { var $currentGroupRoleMap = array(); var $currentGroupTaskMap = array(); var $currentGroupProjectMap = array(); - //var $userMap = array(); // User ids. - //var $projectMap = array(); // Project ids. - //var $taskMap = array(); // Task ids. - //var $clientMap = array(); // Client ids. - //var $invoiceMap = array(); // Invoice ids. + var $currentGroupClientMap = array(); // Constructor. function __construct(&$errors) { @@ -173,6 +170,35 @@ function startElement($parser, $name, $attrs) { $this->currentGroupProjectMap[$attrs['ID']] = $project_id; } else $this->errors->add($i18n->get('error.db')); } + + if ($name == 'CLIENTS') { + // If we get here, we have to recycle $currentGroupClientMap. + unset($this->currentGroupClientMap); + $this->currentGroupClientMap = array(); + // Client map is reconstructed after processing elements in XML. See below. + } + + if ($name == 'CLIENT') { + // We get here when processing tags for the current group. + + // Prepare a list of project ids. + $projects = explode(',', $attrs['PROJECTS']); + foreach ($projects as $id) + $mapped_projects[] = $this->currentGroupProjectMap[$id]; + + $client_id = ttClientHelper::insert(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'name' => $attrs['NAME'], + 'address' => $attrs['ADDRESS'], + 'tax' => $attrs['TAX'], + 'projects' => $mapped_projects, + 'status' => $attrs['STATUS'])); + if ($client_id) { + // Add a mapping. + $this->currentGroupClientMap[$attrs['ID']] = $client_id; + } else $this->errors->add($i18n->get('error.db')); + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4d6e74dad..d4275c187 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4405 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4406 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b0cd6a547ce6a16f0f26667016efce5b66211e54 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 15:57:09 +0000 Subject: [PATCH 0323/1848] Added users to new import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 36 ++++++++++++++++++++++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 7c00f2543..6519ffaee 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -44,19 +44,19 @@ class ttOrgImportHelper { var $current_group_id = null; // Current group id during parsing. var $current_parent_group_id = null; // Current parent group id during parsing. // Set when we create a new group. - // Entities for current group. -- Looks like they are not needed as we insert right away... - // var $currentGroupRoles = array(); // Array of arrays of role properties. - // var $currentGroupUsers = array(); // Array of arrays of user properties. + var $top_role_id = 0; // Top role id. // Entity maps for current group. They map XML ids with database ids. var $currentGroupRoleMap = array(); var $currentGroupTaskMap = array(); var $currentGroupProjectMap = array(); var $currentGroupClientMap = array(); + var $currentGroupUserMap = array(); // Constructor. function __construct(&$errors) { $this->errors = &$errors; + $this->top_role_id = ttRoleHelper::getRoleByRank(512, 0); } // startElement - callback handler for opening tag of an XML element in the file. @@ -199,6 +199,36 @@ function startElement($parser, $name, $attrs) { $this->currentGroupClientMap[$attrs['ID']] = $client_id; } else $this->errors->add($i18n->get('error.db')); } + + if ($name == 'USERS') { + // If we get here, we have to recycle $currentGroupUserMap. + unset($this->currentGroupUserMap); + $this->currentGroupUserMap = array(); + // User map is reconstructed after processing elements in XML. See below. + } + + if ($name == 'USER') { + // We get here when processing tags for the current group. + + $role_id = $attrs['ROLE_ID'] === '0' ? $this->top_role_id : $this->currentGroupRoleMap[$attrs['ROLE_ID']]; // 0 (not null) means top manager role. + + $user_id = ttUserHelper::insert(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'role_id' => $role_id, + 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'name' => $attrs['NAME'], // TODO: check if we need to decode all such things from htmlentities back. Refactor from the beginning if necessary. + 'login' => $attrs['LOGIN'], + 'password' => $attrs['PASSWORD'], + 'rate' => $attrs['RATE'], + 'email' => $attrs['EMAIL'], + 'status' => $attrs['STATUS']), false); + // TODO: what about created_by and other audit info? + if ($user_id) { + // Add a mapping. + $this->currentGroupUserMap[$attrs['ID']] = $user_id; + } else $this->errors->add($i18n->get('error.db')); + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d4275c187..f9a335067 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4406 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4407 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 414ac81236ce044edc1ee194e58238d3a216c934 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 18:15:11 +0000 Subject: [PATCH 0324/1848] Improved new export-import by including all group attributes. --- WEB-INF/lib/ttGroupExportHelper.class.php | 19 ++++++++++-- WEB-INF/lib/ttOrgImportHelper.class.php | 37 +++++++++++++++-------- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 054c43546..4a2eb7859 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -71,7 +71,7 @@ function getGroupData() { global $user; $mdb2 = getConnection(); - $sql = "select name, currency, lang from tt_groups". + $sql = "select * from tt_groups". " where status = 1 and id = $this->group_id and org_id = $user->org_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -177,8 +177,23 @@ function writeData() { $group = $this->getGroupData(); $group_part = " $this->org_id, 'name' => $attrs['NAME'], 'currency' => $attrs['CURRENCY'], - 'lang' => $attrs['LANG'])); - // We only have 3 properties at the moment, while work is ongoing... + 'decimal_mark' => $attrs['DECIMAL_MARK'], + 'lang' => $attrs['LANG'], + 'date_format' => $attrs['DATE_FORMAT'], + 'time_format' => $attrs['TIME_FORMAT'], + 'week_start' => $attrs['WEEK_START'], + 'tracking_mode' => $attrs['TRACKING_MODE'], + 'project_required' => $attrs['PROJECT_REQUIRED'], + 'task_required' => $attrs['TASK_REQUIRED'], + 'record_type' => $attrs['RECORD_TYPE'], + 'bcc_email' => $attrs['BCC_EMAIL'], + 'allow_ip' => $attrs['ALLOW_IP'], + 'password_complexity' => $attrs['PASSWORD_COMPLEXITY'], + 'plugins' => $attrs['PLUGINS'], + 'lock_spec' => $attrs['LOCK_SPEC'], + 'workday_minutes' => $attrs['WORKDAY_MINUTES'], + 'custom_logo' => $attrs['CUSTOM_LOGO'], + 'config' => $attrs['CONFIG'])); // Special handling for top group. if (!$this->org_id && $this->current_group_id) { @@ -217,7 +232,7 @@ function startElement($parser, $name, $attrs) { 'org_id' => $this->org_id, 'role_id' => $role_id, 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], - 'name' => $attrs['NAME'], // TODO: check if we need to decode all such things from htmlentities back. Refactor from the beginning if necessary. + 'name' => $attrs['NAME'], 'login' => $attrs['LOGIN'], 'password' => $attrs['PASSWORD'], 'rate' => $attrs['RATE'], @@ -346,24 +361,22 @@ function uncompress($in, $out) { // createGroup function creates a new group. private function createGroup($fields) { - + global $user; global $i18n; $mdb2 = getConnection(); - $columns = '(parent_id, org_id, name, currency, lang)'; - -// $columns = '(name, currency, decimal_mark, lang, date_format, time_format, week_start, tracking_mode'. -// ', project_required, task_required, record_type, bcc_email, allow_ip, password_complexity, plugins'. -// ', lock_spec, workday_minutes, config, created, created_ip, created_by)'; + $columns = '(parent_id, org_id, name, currency, decimal_mark, lang, date_format, time_format'. + ', week_start, tracking_mode, project_required, task_required, record_type, bcc_email'. + ', allow_ip, password_complexity, plugins, lock_spec'. + ', workday_minutes, config, created, created_ip, created_by)'; $values = ' values ('; $values .= $mdb2->quote($fields['parent_id']); $values .= ', '.$mdb2->quote($fields['org_id']); $values .= ', '.$mdb2->quote(trim($fields['name'])); $values .= ', '.$mdb2->quote(trim($fields['currency'])); - //$values .= ', '.$mdb2->quote($fields['decimal_mark']); + $values .= ', '.$mdb2->quote($fields['decimal_mark']); $values .= ', '.$mdb2->quote($fields['lang']); -/* $values .= ', '.$mdb2->quote($fields['date_format']); $values .= ', '.$mdb2->quote($fields['time_format']); $values .= ', '.(int)$fields['week_start']; @@ -378,7 +391,7 @@ private function createGroup($fields) { $values .= ', '.$mdb2->quote($fields['lock_spec']); $values .= ', '.(int)$fields['workday_minutes']; $values .= ', '.$mdb2->quote($fields['config']); - $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); */ + $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); $values .= ')'; $sql = 'insert into tt_groups '.$columns.$values; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f9a335067..931ae5f1d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4407 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4408 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b06601362567c117bdc889277d554c8c58f0efdc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 20:27:17 +0000 Subject: [PATCH 0325/1848] Improved new export-import by including user to project binds. --- WEB-INF/lib/ttGroupExportHelper.class.php | 15 +++++++++++++++ WEB-INF/lib/ttOrgImportHelper.class.php | 13 ++++++++++++- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 4a2eb7859..125df0ff0 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -309,6 +309,21 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); + // Write user to project binds. + fwrite($this->file, $this->indentation." \n"); + $user_binds = ttTeamHelper::getUserToProjectBinds($this->group_id); + foreach ($user_binds as $bind) { + $user_id = $this->userMap[$bind['user_id']]; + $project_id = $this->projectMap[$bind['project_id']]; + $bind_part = $this->indentation.' '."file, $bind_part); + } + fwrite($this->file, $this->indentation." \n"); + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 06d205e6a..ccdc05b20 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -238,12 +238,23 @@ function startElement($parser, $name, $attrs) { 'rate' => $attrs['RATE'], 'email' => $attrs['EMAIL'], 'status' => $attrs['STATUS']), false); - // TODO: what about created_by and other audit info? if ($user_id) { // Add a mapping. $this->currentGroupUserMap[$attrs['ID']] = $user_id; } else $this->errors->add($i18n->get('error.db')); } + + if ($name == 'USER_PROJECT_BIND') { + if (!ttUserHelper::insertBind(array( + 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], + 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'rate' => $attrs['RATE'], + 'status' => $attrs['STATUS']))) { + $this->errors->add($i18n->get('error.db')); + } + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 931ae5f1d..cff882273 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4408 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4409 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e88a31092d2dbcd535a1704ed4410e92ca3be914 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 21:20:54 +0000 Subject: [PATCH 0326/1848] Improved new export-import by adding invoices. --- WEB-INF/lib/ttGroupExportHelper.class.php | 19 ++++++++++++++++++ WEB-INF/lib/ttImportHelper.class.php | 1 - WEB-INF/lib/ttOrgImportHelper.class.php | 24 +++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 125df0ff0..91a36ce97 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -45,6 +45,7 @@ class ttGroupExportHelper { var $taskMap = array(); // Task ids. var $projectMap = array(); // Project ids. var $clientMap = array(); // Client ids. + var $invoiceMap = array(); // Invoice ids. // Constructor. function __construct($group_id, $file, $indentation) { @@ -224,6 +225,11 @@ function writeData() { foreach ($clients as $key=>$client_item) $this->clientMap[$client_item['id']] = $key + 1; + // Prepare invoice map. + $invoices = ttTeamHelper::getAllInvoices(); + foreach ($invoices as $key=>$invoice_item) + $this->invoiceMap[$invoice_item['id']] = $key + 1; + // Write roles. fwrite($this->file, $this->indentation." \n"); foreach ($roles as $role) { @@ -324,6 +330,19 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); + // Write invoices. + fwrite($this->file, $this->indentation." \n"); + foreach ($invoices as $invoice_item) { + $invoice_part = $this->indentation.' '."invoiceMap[$invoice_item['id']]."\""; + $invoice_part .= " name=\"".htmlentities($invoice_item['name'])."\""; + $invoice_part .= " date=\"".$invoice_item['date']."\""; + $invoice_part .= " client_id=\"".$this->clientMap[$invoice_item['client_id']]."\""; + $invoice_part .= " status=\"".$invoice_item['status']."\""; + $invoice_part .= ">\n"; + fwrite($this->file, $invoice_part); + } + fwrite($this->file, $this->indentation." \n"); + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php index ea899821a..7fa1e2830 100644 --- a/WEB-INF/lib/ttImportHelper.class.php +++ b/WEB-INF/lib/ttImportHelper.class.php @@ -247,7 +247,6 @@ function endElement($parser, $name) { 'name' => $this->currentElement['NAME'], 'date' => $this->currentElement['DATE'], 'client_id' => $this->clientMap[$this->currentElement['CLIENT_ID']], - 'discount' => $this->currentElement['DISCOUNT'], 'status' => $this->currentElement['STATUS'])); } diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index ccdc05b20..015668807 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -31,6 +31,7 @@ import('ttTaskHelper'); import('ttProjectHelper'); import('ttClientHelper'); +import('ttInvoiceHelper'); // ttOrgImportHelper - this class is a future replacement for ttImportHelper. // Currently, it is work in progress. @@ -52,6 +53,7 @@ class ttOrgImportHelper { var $currentGroupProjectMap = array(); var $currentGroupClientMap = array(); var $currentGroupUserMap = array(); + var $currentGroupInvoiceMap = array(); // Constructor. function __construct(&$errors) { @@ -255,6 +257,28 @@ function startElement($parser, $name, $attrs) { $this->errors->add($i18n->get('error.db')); } } + + if ($name == 'INVOICES') { + // If we get here, we have to recycle $currentGroupInvoiceMap. + unset($this->currentGroupInvoiceMap); + $this->currentGroupInvoiceMap = array(); + // Invoice map is reconstructed after processing elements in XML. See below. + } + + if ($name == 'INVOICE') { + // We get here when processing tags for the current group. + $invoice_id = ttInvoiceHelper::insert(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'name' => $attrs['NAME'], + 'date' => $attrs['DATE'], + 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'status' => $attrs['STATUS'])); + if ($invoice_id) { + // Add a mapping. + $this->currentGroupInvoiceMap[$attrs['ID']] = $invoice_id; + } else $this->errors->add($i18n->get('error.db')); + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index cff882273..8995b12b2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4409 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4410 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 56f1fd19f2c9c72878395b3275f03f192ccca082 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 10 Nov 2018 23:02:08 +0000 Subject: [PATCH 0327/1848] Improved new export-import by adding time log. --- WEB-INF/lib/ttGroupExportHelper.class.php | 30 +++++++++++++++++++++ WEB-INF/lib/ttOrgImportHelper.class.php | 32 +++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 91a36ce97..fecfba8a8 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -46,6 +46,7 @@ class ttGroupExportHelper { var $projectMap = array(); // Project ids. var $clientMap = array(); // Client ids. var $invoiceMap = array(); // Invoice ids. + var $logMap = array(); // Time log ids. // Constructor. function __construct($group_id, $file, $indentation) { @@ -343,6 +344,35 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); + // Write time log entries and build logMap at the same time. + fwrite($this->file, $this->indentation." \n"); + $key = 0; + foreach ($users as $user_item) { + $records = ttTimeHelper::getAllRecords($user_item['id']); + foreach ($records as $record) { + $key++; + $this->logMap[$record['id']] = $key; + $log_part = $this->indentation.' '."userMap[$record['user_id']]."\""; + $log_part .= " date=\"".$record['date']."\""; + $log_part .= " start=\"".$record['start']."\""; + $log_part .= " finish=\"".$record['finish']."\""; + $log_part .= " duration=\"".($record['start']?"":$record['duration'])."\""; + $log_part .= " client_id=\"".$this->clientMap[$record['client_id']]."\""; + $log_part .= " project_id=\"".$this->projectMap[$record['project_id']]."\""; + $log_part .= " task_id=\"".$this->taskMap[$record['task_id']]."\""; + $log_part .= " invoice_id=\"".$this->invoiceMap[$record['invoice_id']]."\""; + $log_part .= " comment=\"".htmlentities($record['comment'])."\""; + $log_part .= " billable=\"".$record['billable']."\""; + $log_part .= " paid=\"".$record['paid']."\""; + $log_part .= " status=\"".$record['status']."\""; + $log_part .= ">\n"; + fwrite($this->file, $log_part); + } + } + fwrite($this->file, $this->indentation." \n"); + unset($records); + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 015668807..622b3fec5 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -54,6 +54,7 @@ class ttOrgImportHelper { var $currentGroupClientMap = array(); var $currentGroupUserMap = array(); var $currentGroupInvoiceMap = array(); + var $currentGroupLogMap = array(); // Constructor. function __construct(&$errors) { @@ -279,6 +280,37 @@ function startElement($parser, $name, $attrs) { $this->currentGroupInvoiceMap[$attrs['ID']] = $invoice_id; } else $this->errors->add($i18n->get('error.db')); } + + if ($name == 'LOG') { + // If we get here, we have to recycle $currentGroupLogMap. + unset($this->currentGroupLogMap); + $this->currentGroupLogMap = array(); + // Log map is reconstructed after processing elements in XML. See below. + } + + if ($name == 'LOG_ITEM') { + // We get here when processing tags for the current group. + $log_item_id = ttTimeHelper::insert(array( + 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'date' => $attrs['DATE'], + 'start' => $attrs['START'], + 'finish' => $attrs['FINISH'], + 'duration' => $attrs['DURATION'], + 'client' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'project' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], + 'task' => $this->currentGroupTaskMap[$attrs['TASK_ID']], + 'invoice' => $this->currentGroupInvoiceMap[$attrs['INVOICE_ID']], + 'note' => (isset($attrs['COMMENT']) ? $attrs['COMMENT'] : ''), + 'billable' => $attrs['BILLABLE'], + 'paid' => $attrs['PAID'], + 'status' => $attrs['STATUS'])); + if ($log_item_id) { + // Add a mapping. + $this->currentGroupLogMap[$attrs['ID']] = $log_item_id; + } else $this->errors->add($i18n->get('error.db')); + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8995b12b2..a93f706aa 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4410 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4411 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From bf300dab88607ee209b83f16a6915bb9d61787bb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Nov 2018 12:15:22 +0000 Subject: [PATCH 0328/1848] Added custom fields to new export-import. --- WEB-INF/lib/ttGroupExportHelper.class.php | 40 +++++++++++++++++++---- WEB-INF/lib/ttOrgImportHelper.class.php | 25 ++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index fecfba8a8..1b7e74a75 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -40,13 +40,15 @@ class ttGroupExportHelper { // The following arrays are maps between entity ids in the file versus the database. // We write to the file sequentially (1,2,3...) while in the database the entities have different ids. - var $userMap = array(); // User ids. - var $roleMap = array(); // Role ids. - var $taskMap = array(); // Task ids. - var $projectMap = array(); // Project ids. - var $clientMap = array(); // Client ids. - var $invoiceMap = array(); // Invoice ids. - var $logMap = array(); // Time log ids. + var $userMap = array(); + var $roleMap = array(); + var $taskMap = array(); + var $projectMap = array(); + var $clientMap = array(); + var $invoiceMap = array(); + var $logMap = array(); + var $customFieldMap = array(); + var $customFieldOptionMap = array(); // Constructor. function __construct($group_id, $file, $indentation) { @@ -231,6 +233,16 @@ function writeData() { foreach ($invoices as $key=>$invoice_item) $this->invoiceMap[$invoice_item['id']] = $key + 1; + // Prepare custom fields map. + $custom_fields = ttTeamHelper::getAllCustomFields($this->group_id); + foreach ($custom_fields as $key=>$custom_field) + $this->customFieldMap[$custom_field['id']] = $key + 1; + + // Prepare custom field options map. + $custom_field_options = ttTeamHelper::getAllCustomFieldOptions($this->group_id); + foreach ($custom_field_options as $key=>$option) + $this->customFieldOptionMap[$option['id']] = $key + 1; + // Write roles. fwrite($this->file, $this->indentation." \n"); foreach ($roles as $role) { @@ -373,6 +385,20 @@ function writeData() { fwrite($this->file, $this->indentation." \n"); unset($records); + // Write custom fields. + fwrite($this->file, $this->indentation." \n"); + foreach ($custom_fields as $custom_field) { + $custom_field_part = $this->indentation.' '."customFieldMap[$custom_field['id']]."\""; + $custom_field_part .= " type=\"".$custom_field['type']."\""; + $custom_field_part .= " label=\"".htmlentities($custom_field['label'])."\""; + $custom_field_part .= " required=\"".$custom_field['required']."\""; + $custom_field_part .= " status=\"".$custom_field['status']."\""; + $custom_field_part .= ">\n"; + fwrite($this->file, $custom_field_part); + } + fwrite($this->file, $this->indentation." \n"); + unset($custom_fields); + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 622b3fec5..2cb693445 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -32,6 +32,7 @@ import('ttProjectHelper'); import('ttClientHelper'); import('ttInvoiceHelper'); +import('ttCustomFieldHelper'); // ttOrgImportHelper - this class is a future replacement for ttImportHelper. // Currently, it is work in progress. @@ -55,6 +56,8 @@ class ttOrgImportHelper { var $currentGroupUserMap = array(); var $currentGroupInvoiceMap = array(); var $currentGroupLogMap = array(); + var $currentGroupCustomFieldMap = array(); + var $currentGroupCustomFieldOptionMap = array(); // Constructor. function __construct(&$errors) { @@ -311,6 +314,28 @@ function startElement($parser, $name, $attrs) { $this->currentGroupLogMap[$attrs['ID']] = $log_item_id; } else $this->errors->add($i18n->get('error.db')); } + + if ($name == 'CUSTOM_FIELDS') { + // If we get here, we have to recycle $currentGroupCustomFieldMap. + unset($this->currentGroupCustomFieldMap); + $this->currentGroupCustomFieldMap = array(); + // Custom field map is reconstructed after processing elements in XML. See below. + } + + if ($name == 'CUSTOM_FIELD') { + // We get here when processing tags for the current group. + $custom_field_id = ttCustomFieldHelper::insertField(array( + 'group_id' => $this->current_group_id, + // 'org_id' => $this->org_id, TODO: add this when org_id field is added to the table. + 'type' => $attrs['TYPE'], + 'label' => $attrs['LABEL'], + 'required' => $attrs['REQUIRED'], + 'status' => $attrs['STATUS'])); + if ($custom_field_id) { + // Add a mapping. + $this->currentGroupCustomFieldMap[$attrs['ID']] = $custom_field_id; + } else $this->errors->add($i18n->get('error.db')); + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a93f706aa..4e17b95e5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4411 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4412 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 77f0fbc75930d7d2f9a3d3acadb64be44b871621 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Nov 2018 13:25:11 +0000 Subject: [PATCH 0329/1848] Improved new export-import by adding custom field options. --- .gitignore | 1 + WEB-INF/lib/ttGroupExportHelper.class.php | 12 ++++++++++++ WEB-INF/lib/ttOrgImportHelper.class.php | 20 ++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9bfa047e7..dc348cfac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ config.php WEB-INF/templates_c/*.* +WEB-INF/templates_c/import_* WEB-INF/lib/tcpdf/ nbproject/ upload/ diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 1b7e74a75..f1ea228d1 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -399,6 +399,18 @@ function writeData() { fwrite($this->file, $this->indentation." \n"); unset($custom_fields); + // Write custom field options. + fwrite($this->file, $this->indentation." \n"); + foreach ($custom_field_options as $option) { + $custom_field_option_part = $this->indentation.' '."customFieldOptionMap[$option['id']]."\""; + $custom_field_option_part .= " field_id=\"".$this->customFieldMap[$option['field_id']]."\""; + $custom_field_option_part .= " value=\"".htmlentities($option['value'])."\""; + $custom_field_option_part .= ">\n"; + fwrite($this->file, $custom_field_option_part); + } + fwrite($this->file, $this->indentation." \n"); + unset($custom_field_options); + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 2cb693445..9c39810f2 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -336,6 +336,26 @@ function startElement($parser, $name, $attrs) { $this->currentGroupCustomFieldMap[$attrs['ID']] = $custom_field_id; } else $this->errors->add($i18n->get('error.db')); } + + if ($name == 'CUSTOM_FIELD_OPTIONS') { + // If we get here, we have to recycle $currentGroupCustomFieldOptionMap. + unset($this->currentGroupCustomFieldOptionMap); + $this->currentGroupCustomFieldOptionMap = array(); + // Custom field option map is reconstructed after processing elements in XML. See below. + } + + if ($name == 'CUSTOM_FIELD_OPTION') { + // We get here when processing tags for the current group. + $custom_field_option_id = ttCustomFieldHelper::insertOption(array( + // 'group_id' => $this->current_group_id, TODO: add this when group_id field is added to the table. + // 'org_id' => $this->org_id, TODO: add this when org_id field is added to the table. + 'field_id' => $this->currentGroupCustomFieldMap[$attrs['FIELD_ID']], + 'value' => $attrs['VALUE'])); + if ($custom_field_option_id) { + // Add a mapping. + $this->currentGroupCustomFieldOptionMap[$attrs['ID']] = $custom_field_option_id; + } else $this->errors->add($i18n->get('error.db')); + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4e17b95e5..bd9cdf511 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4412 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4413 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6ede4ba89cf66620bd1c40d092b3518fd51ba69c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Nov 2018 13:58:21 +0000 Subject: [PATCH 0330/1848] Integrated custom field log in new export-import. --- WEB-INF/lib/ttGroupExportHelper.class.php | 15 +++++++++++++++ WEB-INF/lib/ttOrgImportHelper.class.php | 14 ++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index f1ea228d1..aba161f6c 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -411,6 +411,21 @@ function writeData() { fwrite($this->file, $this->indentation." \n"); unset($custom_field_options); + // Write custom field log. + $custom_field_log = ttTeamHelper::getCustomFieldLog($this->group_id); + fwrite($this->file, $this->indentation." \n"); + foreach ($custom_field_log as $entry) { + $custom_field_log_part = $this->indentation.' '."logMap[$entry['log_id']]."\""; + $custom_field_log_part .= " field_id=\"".$this->customFieldMap[$entry['field_id']]."\""; + $custom_field_log_part .= " option_id=\"".$this->customFieldOptionMap[$entry['option_id']]."\""; + $custom_field_log_part .= " value=\"".htmlentities($entry['value'])."\""; + $custom_field_log_part .= " status=\"".$entry['status']."\""; + $custom_field_log_part .= ">\n"; + fwrite($this->file, $custom_field_log_part); + } + fwrite($this->file, $this->indentation." \n"); + unset($custom_field_log); + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 9c39810f2..17827986c 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -356,6 +356,20 @@ function startElement($parser, $name, $attrs) { $this->currentGroupCustomFieldOptionMap[$attrs['ID']] = $custom_field_option_id; } else $this->errors->add($i18n->get('error.db')); } + + if ($name == 'CUSTOM_FIELD_LOG_ENTRY') { + // We get here when processing tags for the current group. + if (!ttCustomFieldHelper::insertLogEntry(array( + // 'group_id' => $this->current_group_id, TODO: add this when group_id field is added to the table. + // 'org_id' => $this->org_id, TODO: add this when org_id field is added to the table. + 'log_id' => $this->currentGroupLogMap[$attrs['LOG_ID']], + 'field_id' => $this->currentGroupCustomFieldMap[$attrs['FIELD_ID']], + 'option_id' => $this->currentGroupCustomFieldOptionMap[$attrs['OPTION_ID']], + 'value' => $attrs['VALUE'], + 'status' => $attrs['STATUS']))) { + $this->errors->add($i18n->get('error.db')); + } + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bd9cdf511..b8cedad7c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4413 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4414 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b5c16658c0a91c98bb4e41bb6c0e1cc254222a68 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Nov 2018 14:39:41 +0000 Subject: [PATCH 0331/1848] Integrated expense items in new export-import. --- WEB-INF/lib/ttGroupExportHelper.class.php | 19 +++++++++++++++++++ WEB-INF/lib/ttOrgImportHelper.class.php | 18 ++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index aba161f6c..e18f8c9f4 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -426,6 +426,25 @@ function writeData() { fwrite($this->file, $this->indentation." \n"); unset($custom_field_log); + // Write expense items. + $expense_items = ttTeamHelper::getExpenseItems($this->group_id); + fwrite($this->file, $this->indentation." \n"); + foreach ($expense_items as $expense_item) { + $expense_item_part = $this->indentation.' '."userMap[$expense_item['user_id']]."\""; + $expense_item_part .= " client_id=\"".$this->clientMap[$expense_item['client_id']]."\""; + $expense_item_part .= " project_id=\"".$this->projectMap[$expense_item['project_id']]."\""; + $expense_item_part .= " name=\"".htmlentities($expense_item['name'])."\""; + $expense_item_part .= " cost=\"".$expense_item['cost']."\""; + $expense_item_part .= " invoice_id=\"".$this->invoiceMap[$expense_item['invoice_id']]."\""; + $expense_item_part .= " paid=\"".$expense_item['paid']."\""; + $expense_item_part .= " status=\"".$expense_item['status']."\""; + $expense_item_part .= ">\n"; + fwrite($this->file, $expense_item_part); + } + fwrite($this->file, $this->indentation." \n"); + unset($expense_items); + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 17827986c..89428c4c9 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -33,6 +33,7 @@ import('ttClientHelper'); import('ttInvoiceHelper'); import('ttCustomFieldHelper'); +import('ttExpenseHelper'); // ttOrgImportHelper - this class is a future replacement for ttImportHelper. // Currently, it is work in progress. @@ -370,6 +371,23 @@ function startElement($parser, $name, $attrs) { $this->errors->add($i18n->get('error.db')); } } + + if ($name == 'EXPENSE_ITEM') { + // We get here when processing tags for the current group. + $expense_item_id = ttExpenseHelper::insert(array( + 'date' => $attrs['DATE'], + 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], + 'group_id' => $this->current_group_id, + // 'org_id' => $this->org_id, TODO: add this when org_id field is added to the table. + 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], + 'name' => $attrs['NAME'], + 'cost' => $attrs['COST'], + 'invoice_id' => $this->currentGroupInvoiceMap[$attrs['INVOICE_ID']], + 'paid' => $attrs['PAID'], + 'status' => $attrs['STATUS'])); + if (!$expense_item_id) $this->errors->add($i18n->get('error.db')); + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b8cedad7c..dbce25f8c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4414 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4415 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a4298d704504e90da27dfdae71aaf6cc2faa9844 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Nov 2018 15:09:54 +0000 Subject: [PATCH 0332/1848] Added monthly quotas to new export-import. --- WEB-INF/lib/ttGroupExportHelper.class.php | 12 ++++++++++++ WEB-INF/lib/ttOrgImportHelper.class.php | 18 ++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index e18f8c9f4..b1aa35c03 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -445,6 +445,18 @@ function writeData() { fwrite($this->file, $this->indentation." \n"); unset($expense_items); + // Write monthly quotas. + $quotas = ttTeamHelper::getMonthlyQuotas($this->group_id); + fwrite($this->file, $this->indentation." \n"); + foreach ($quotas as $quota) { + $quota_part = $this->indentation.' '."file, $quota_part); + } + fwrite($this->file, $this->indentation." \n"); + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 89428c4c9..cc632f180 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -388,6 +388,16 @@ function startElement($parser, $name, $attrs) { 'status' => $attrs['STATUS'])); if (!$expense_item_id) $this->errors->add($i18n->get('error.db')); } + + if ($name == 'MONTHLY_QUOTA') { + if (!$this->insertMonthlyQuota($this->current_group_id, + // 'org_id' => $this->org_id, TODO: add this when org_id field is added to the table. + $attrs['YEAR'], + $attrs['MONTH'], + $attrs['MINUTES'])) { + $this->errors->add($i18n->get('error.db')); + } + } } } @@ -548,4 +558,12 @@ private function createGroup($fields) { $group_id = $mdb2->lastInsertID('tt_groups', 'id'); return $group_id; } + + // insertMonthlyQuota - a helper function to insert a monthly quota. + private function insertMonthlyQuota($group_id, $year, $month, $minutes) { + $mdb2 = getConnection(); + $sql = "INSERT INTO tt_monthly_quotas (group_id, year, month, minutes) values ($group_id, $year, $month, $minutes)"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index dbce25f8c..338b37b45 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4415 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4416 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 67c8fa59139659b2da15c560dd10d18601ab311f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Nov 2018 15:56:52 +0000 Subject: [PATCH 0333/1848] Added fav reports to new export-import. --- WEB-INF/lib/ttGroupExportHelper.class.php | 46 +++++++++++++++++++++++ WEB-INF/lib/ttOrgImportHelper.class.php | 40 ++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index b1aa35c03..17d40435a 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -457,6 +457,52 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); + // Write fav reports. + $fav_reports = ttTeamHelper::getFavReports($this->group_id); + fwrite($this->file, $this->indentation." \n"); + foreach ($fav_reports as $fav_report) { + $user_list = ''; + if (strlen($fav_report['users']) > 0) { + $arr = explode(',', $fav_report['users']); + foreach ($arr as $k=>$v) { + if (array_key_exists($arr[$k], $this->userMap)) + $user_list .= (strlen($user_list) == 0? '' : ',').$this->userMap[$v]; + } + } + $fav_report_part = $this->indentation.' '."userMap[$fav_report['user_id']]."\""; + $fav_report_part .= " name=\"".htmlentities($fav_report['name'])."\""; + $fav_report_part .= " client_id=\"".$this->clientMap[$fav_report['client_id']]."\""; + $fav_report_part .= " cf_1_option_id=\"".$this->customFieldOptionMap[$fav_report['cf_1_option_id']]."\""; + $fav_report_part .= " project_id=\"".$this->projectMap[$fav_report['project_id']]."\""; + $fav_report_part .= " task_id=\"".$this->taskMap[$fav_report['task_id']]."\""; + $fav_report_part .= " billable=\"".$fav_report['billable']."\""; + $fav_report_part .= " users=\"".$user_list."\""; + $fav_report_part .= " period=\"".$fav_report['period']."\""; + $fav_report_part .= " period_start=\"".$fav_report['period_start']."\""; + $fav_report_part .= " period_end=\"".$fav_report['period_end']."\""; + $fav_report_part .= " show_client=\"".$fav_report['show_client']."\""; + $fav_report_part .= " show_invoice=\"".$fav_report['show_invoice']."\""; + $fav_report_part .= " show_paid=\"".$fav_report['show_paid']."\""; + $fav_report_part .= " show_ip=\"".$fav_report['show_ip']."\""; + $fav_report_part .= " show_project=\"".$fav_report['show_project']."\""; + $fav_report_part .= " show_start=\"".$fav_report['show_start']."\""; + $fav_report_part .= " show_duration=\"".$fav_report['show_duration']."\""; + $fav_report_part .= " show_cost=\"".$fav_report['show_cost']."\""; + $fav_report_part .= " show_task=\"".$fav_report['show_task']."\""; + $fav_report_part .= " show_end=\"".$fav_report['show_end']."\""; + $fav_report_part .= " show_note=\"".$fav_report['show_note']."\""; + $fav_report_part .= " show_custom_field_1=\"".$fav_report['show_custom_field_1']."\""; + $fav_report_part .= " show_work_units=\"".$fav_report['show_work_units']."\""; + $fav_report_part .= " group_by1=\"".$fav_report['group_by1']."\""; + $fav_report_part .= " group_by2=\"".$fav_report['group_by2']."\""; + $fav_report_part .= " group_by3=\"".$fav_report['group_by3']."\""; + $fav_report_part .= " show_totals_only=\"".$fav_report['show_totals_only']."\""; + $fav_report_part .= ">\n"; + fwrite($this->file, $fav_report_part); + } + fwrite($this->file, $this->indentation." \n"); + unset($fav_reports); + // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index cc632f180..80dc8a199 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -34,6 +34,7 @@ import('ttInvoiceHelper'); import('ttCustomFieldHelper'); import('ttExpenseHelper'); +import('ttFavReportHelper'); // ttOrgImportHelper - this class is a future replacement for ttImportHelper. // Currently, it is work in progress. @@ -398,6 +399,45 @@ function startElement($parser, $name, $attrs) { $this->errors->add($i18n->get('error.db')); } } + + if ($name == 'FAV_REPORT') { + $user_list = ''; + if (strlen($attrs['USERS']) > 0) { + $arr = explode(',', $attrs['USERS']); + foreach ($arr as $v) + $user_list .= (strlen($user_list) == 0 ? '' : ',').$this->currentGroupUserMap[$v]; + } + $fav_report_id = ttFavReportHelper::insertReport(array( + 'name' => $attrs['NAME'], + 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], + 'client' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'option' => $this->currentGroupCustomFieldOptionMap[$attrs['CF_1_OPTION_ID']], + 'project' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], + 'task' => $this->currentGroupTaskMap[$attrs['TASK_ID']], + 'billable' => $attrs['BILLABLE'], + 'users' => $user_list, + 'period' => $attrs['PERIOD'], + 'from' => $attrs['PERIOD_START'], + 'to' => $attrs['PERIOD_END'], + 'chclient' => (int) $attrs['SHOW_CLIENT'], + 'chinvoice' => (int) $attrs['SHOW_INVOICE'], + 'chpaid' => (int) $attrs['SHOW_PAID'], + 'chip' => (int) $attrs['SHOW_IP'], + 'chproject' => (int) $attrs['SHOW_PROJECT'], + 'chstart' => (int) $attrs['SHOW_START'], + 'chduration' => (int) $attrs['SHOW_DURATION'], + 'chcost' => (int) $attrs['SHOW_COST'], + 'chtask' => (int) $attrs['SHOW_TASK'], + 'chfinish' => (int) $attrs['SHOW_END'], + 'chnote' => (int) $attrs['SHOW_NOTE'], + 'chcf_1' => (int) $attrs['SHOW_CUSTOM_FIELD_1'], + 'chunits' => (int) $attrs['SHOW_WORK_UNITS'], + 'group_by1' => $attrs['GROUP_BY1'], + 'group_by2' => $attrs['GROUP_BY2'], + 'group_by3' => $attrs['GROUP_BY3'], + 'chtotalsonly' => (int) $attrs['SHOW_TOTALS_ONLY'])); + if (!$fav_report_id) $this->errors->add($i18n->get('error.db')); + } } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 338b37b45..38980481d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4416 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4417 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 4255418fd8d5a23ff005e4136a0b173b9ad62bd0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Nov 2018 16:56:06 +0000 Subject: [PATCH 0334/1848] Added database schema attribute to export files. --- WEB-INF/lib/ttOrgExportHelper.class.php | 15 ++++++++++++++- WEB-INF/lib/ttOrgImportHelper.class.php | 13 +++++++++++++ WEB-INF/resources/en.lang.php | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttOrgExportHelper.class.php b/WEB-INF/lib/ttOrgExportHelper.class.php index aa9c9051d..719c486b5 100644 --- a/WEB-INF/lib/ttOrgExportHelper.class.php +++ b/WEB-INF/lib/ttOrgExportHelper.class.php @@ -51,7 +51,8 @@ function createDataFile($compress = false) { // Write XML to the file. fwrite($file, "\n"); - fwrite($file, "\n"); + $org_part = "getVersion()."\">\n"; + fwrite($file, $org_part); // Use ttGroupExportHelper to export all groups. $groupExportHelper = new ttGroupExportHelper($user->group_id, $file, ' '); // 2 spaces indentation for home group. @@ -98,4 +99,16 @@ function compress($in, $out) { fclose ($in_file); return true; } + + private function getVersion() { + $mdb2 = getConnection(); + $sql = "select param_value from tt_site_config where param_name = 'version_db'"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + return $val['param_value']; + $result[] = $val; + } + return false; + } } diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 80dc8a199..ada232862 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -41,6 +41,7 @@ // When done, it should handle import of complex groups consisting of other groups. class ttOrgImportHelper { var $errors = null; // Errors go here. Set in constructor by reference. + var $schema_version = null; // Database schema version from XML file we import from. var $conflicting_entities = null; // A comma-separated list of entity names we cannot import. var $canImport = true; // False if we cannot import data due to a conflict such as login collision. var $firstPass = true; // True during first pass through the file. @@ -73,6 +74,18 @@ function startElement($parser, $name, $attrs) { // First pass. We only check user logins for potential collisions with existing. if ($this->firstPass) { + if ($name == 'ORG' && $this->canImport) { + if ($attrs['SCHEMA'] == null) { + // We need (database) schema attribute to be available for import to work. + // Old Time Tracker export files don't have this. + // Current import code does not work with old format because we had to + // restructure data in export files for subgroup support. + $this->canImport = false; + $this->errors->add($i18n->get('error.format')); + return; + } + } + if ($name == 'USER' && $this->canImport) { $login = $attrs['LOGIN']; if ('' != $attrs['STATUS'] && ttUserHelper::getUserByLogin($login)) { diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 82059051e..31f0ebb8e 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -102,6 +102,7 @@ 'error.future_date' => 'Date is in future.', 'error.xml' => 'Error in XML file at line %d: %s.', 'error.cannot_import' => 'Cannot import: %s.', +'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Login', From f6c7709e92252811cc6f9997b86ac14e3f0dc4f6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Nov 2018 17:03:50 +0000 Subject: [PATCH 0335/1848] Switched to new export-import with subgroup support. --- WEB-INF/templates/footer.tpl | 2 +- export.php | 8 ++++---- import.php | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 38980481d..e294c882e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4417 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4418 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/export.php b/export.php index 3d6178148..2b52acae0 100644 --- a/export.php +++ b/export.php @@ -57,11 +57,11 @@ $mime_type = 'application/x-bzip2'; } - if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { + //if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { $exportHelper = new ttOrgExportHelper(); - } else { - $exportHelper = new ttExportHelper(); - } + //} else { + // $exportHelper = new ttExportHelper(); + //} if ($exportHelper->createDataFile($compress)) { header('Pragma: public'); // This is needed for IE8 to download files over https. header('Content-Type: '.$mime_type); diff --git a/import.php b/import.php index 235924ac4..78630866b 100644 --- a/import.php +++ b/import.php @@ -43,11 +43,11 @@ $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.import'))); if ($request->isPost()) { - if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { +// if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { $import = new ttOrgImportHelper($err); - } else { - $import = new ttImportHelper($err); - } +// } else { +// $import = new ttImportHelper($err); +// } $import->importXml(); if ($err->no()) $msg->add($i18n->get('form.import.success')); } // isPost From 220824961aa7e1d0da738de5a1feacc3c5832b7c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Nov 2018 17:51:08 +0000 Subject: [PATCH 0336/1848] Introduced a new string in translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 30 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 5bfd796e9..1e5b6f3d2 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -118,6 +118,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Iniciar sessió', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d407dccf6..d8f647dd2 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -120,6 +120,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Přihlásit', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index f475e06f1..344bf05c3 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -111,6 +111,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Log ind', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index ea58b9a4e..9a778429c 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -104,6 +104,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Anmelden', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 740be1230..622c1d87a 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -116,6 +116,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Iniciar sesion', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index b9f784f73..ad3698003 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -121,6 +121,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Login', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index e6d54ee93..26b236393 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -118,6 +118,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'ورود', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 316b3f8f9..208c25598 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -113,6 +113,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Kirjaudu', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 529fc2da0..c164138c5 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -111,6 +111,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Connexion', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 2b523141b..925abcafc 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -105,6 +105,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Σύνδεση', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 878e5ba9d..0c6ad0bfb 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -128,6 +128,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'היכנס', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index f98dffa13..c7eb011a0 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -117,6 +117,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Bejelentkezés', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 07ed67c56..ac542965e 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -109,6 +109,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Login', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 0d077507c..7bc81789a 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -122,6 +122,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'ログイン', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 0bc21ee8a..6121b38fb 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -121,6 +121,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => '로그인', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 02e0ab326..9c036716a 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -102,6 +102,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Aanmelden', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index c7f0fe254..af6943cb6 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -122,6 +122,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Innlogging', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index ffc6d37bb..39e7c9f57 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -115,6 +115,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons 'button.login' => 'Login', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 9b5bf7594..4355f748d 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -112,6 +112,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Login', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index e2e95a8a7..9225d2bfc 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -114,6 +114,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Login', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 6840977e6..a3a91d752 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -122,6 +122,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Autentifica', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3354eaaae..f11fff5bc 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -101,6 +101,7 @@ 'error.future_date' => 'Дата в будущем.', 'error.xml' => 'Ошибка в файле XML на строке %d: %s.', 'error.cannot_import' => 'Невозможно импортировать: %s.', +'error.format' => 'Неверный формат файла.', // Labels for buttons. 'button.login' => 'Войти', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 18fa470d1..0bd2af038 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -117,6 +117,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Prihlásiť', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 7f09aac45..be971e790 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -111,6 +111,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Prijava', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 890b8ee95..aef73a45f 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -112,6 +112,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Prijava', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index d2e227dc5..fe4ab32db 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -109,6 +109,7 @@ // TODO: translate the following. // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Logga in', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 7f34cb370..a0916ba99 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -125,6 +125,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => 'Giriş', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 96e43164c..5cabb5fc1 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -114,6 +114,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => '登录', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 8664f1934..168a6d442 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -119,6 +119,7 @@ // 'error.future_date' => 'Date is in future.', // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', +// 'error.format' => 'Invalid file format.', // Labels for buttons. 'button.login' => '登錄', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e294c882e..81bfe05d0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4418 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4419 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 252197d9417610f49c555a454995e0949741a01e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 12 Nov 2018 12:43:36 +0000 Subject: [PATCH 0337/1848] More consistent cleanup in group export. --- .gitignore | 1 + WEB-INF/lib/ttGroupExportHelper.class.php | 41 +++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index dc348cfac..d73d85537 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ config.php WEB-INF/templates_c/*.* WEB-INF/templates_c/import_* +WEB-INF/templates_c/tt* WEB-INF/lib/tcpdf/ nbproject/ upload/ diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 17d40435a..ce3dbb672 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -202,6 +202,8 @@ function writeData() { // Write group info. fwrite($this->file, $this->indentation.$group_part); + unset($group); + unset($group_part); // Prepare user map. $users = $this->getUsers(); @@ -256,6 +258,8 @@ function writeData() { fwrite($this->file, $role_part); } fwrite($this->file, $this->indentation." \n"); + unset($roles); + unset($role_part); // Write tasks. fwrite($this->file, $this->indentation." \n"); @@ -268,6 +272,8 @@ function writeData() { fwrite($this->file, $task_part); } fwrite($this->file, $this->indentation." \n"); + unset($tasks); + unset($task_part); // Write projects. fwrite($this->file, $this->indentation." \n"); @@ -288,6 +294,8 @@ function writeData() { fwrite($this->file, $project_part); } fwrite($this->file, $this->indentation." \n"); + unset($projects); + unset($project_part); // Write clients. fwrite($this->file, $this->indentation." \n"); @@ -309,6 +317,8 @@ function writeData() { fwrite($this->file, $client_part); } fwrite($this->file, $this->indentation." \n"); + unset($clients); + unset($client_part); // Write users. fwrite($this->file, $this->indentation." \n"); @@ -327,6 +337,8 @@ function writeData() { fwrite($this->file, $user_part); } fwrite($this->file, $this->indentation." \n"); + unset($users); + unset($user_part); // Write user to project binds. fwrite($this->file, $this->indentation." \n"); @@ -342,6 +354,8 @@ function writeData() { fwrite($this->file, $bind_part); } fwrite($this->file, $this->indentation." \n"); + unset($user_binds); + unset($bind_part); // Write invoices. fwrite($this->file, $this->indentation." \n"); @@ -355,12 +369,15 @@ function writeData() { fwrite($this->file, $invoice_part); } fwrite($this->file, $this->indentation." \n"); + unset($invoices); + unset($invoice_part); // Write time log entries and build logMap at the same time. fwrite($this->file, $this->indentation." \n"); $key = 0; - foreach ($users as $user_item) { - $records = ttTimeHelper::getAllRecords($user_item['id']); + foreach ($this->userMap as $key => $value) { + $user_id = $key; + $records = ttTimeHelper::getAllRecords($user_id); foreach ($records as $record) { $key++; $this->logMap[$record['id']] = $key; @@ -384,6 +401,7 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); unset($records); + unset($log_part); // Write custom fields. fwrite($this->file, $this->indentation." \n"); @@ -398,6 +416,7 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); unset($custom_fields); + unset($custom_field_part); // Write custom field options. fwrite($this->file, $this->indentation." \n"); @@ -410,6 +429,7 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); unset($custom_field_options); + unset($custom_field_option_part); // Write custom field log. $custom_field_log = ttTeamHelper::getCustomFieldLog($this->group_id); @@ -425,6 +445,7 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); unset($custom_field_log); + unset($custom_field_log_part); // Write expense items. $expense_items = ttTeamHelper::getExpenseItems($this->group_id); @@ -444,6 +465,7 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); unset($expense_items); + unset($expense_item_part); // Write monthly quotas. $quotas = ttTeamHelper::getMonthlyQuotas($this->group_id); @@ -456,6 +478,8 @@ function writeData() { fwrite($this->file, $quota_part); } fwrite($this->file, $this->indentation." \n"); + unset($quotas); + unset($quota_part); // Write fav reports. $fav_reports = ttTeamHelper::getFavReports($this->group_id); @@ -502,12 +526,25 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); unset($fav_reports); + unset($fav_report_part); + + // We are mostly done with writing this group data, destroy all maps. + unset($this->roleMap); + unset($this->userMap); + unset($this->taskMap); + unset($this->projectMap); + unset($this->clientMap); + unset($this->invoiceMap); + unset($this->logMap); + unset($this->customFieldMap); + unset($this->customFieldOptionMap); // Call self recursively for all subgroups. foreach ($this->subgroups as $subgroup) { $subgroup_helper = new ttGroupExportHelper($subgroup['id'], $this->file, $this->indentation.' '); $subgroup_helper->writeData(); } + unset($this->subgroups); fwrite($this->file, $this->indentation."\n"); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 81bfe05d0..48b80bfae 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4419 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4420 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 89d113bd3f5ab38ee7ecd7166ce420cad0634fa3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 12 Nov 2018 13:43:38 +0000 Subject: [PATCH 0338/1848] Improved efficiency of ttOrgImportHelper a bit. --- WEB-INF/lib/ttOrgImportHelper.class.php | 72 ++++++++++++++++--------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index ada232862..73f1f09e2 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -36,19 +36,17 @@ import('ttExpenseHelper'); import('ttFavReportHelper'); -// ttOrgImportHelper - this class is a future replacement for ttImportHelper. -// Currently, it is work in progress. -// When done, it should handle import of complex groups consisting of other groups. +// ttOrgImportHelper class is used to import organization data from an XML file +// prepared by ttOrgExportHelper and consisting of nested groups with their info. class ttOrgImportHelper { var $errors = null; // Errors go here. Set in constructor by reference. var $schema_version = null; // Database schema version from XML file we import from. - var $conflicting_entities = null; // A comma-separated list of entity names we cannot import. + var $conflicting_logins = null; // A comma-separated list of logins we cannot import. var $canImport = true; // False if we cannot import data due to a conflict such as login collision. var $firstPass = true; // True during first pass through the file. var $org_id = null; // Organization id (same as top group_id). var $current_group_id = null; // Current group id during parsing. var $current_parent_group_id = null; // Current parent group id during parsing. - // Set when we create a new group. var $top_role_id = 0; // Top role id. // Entity maps for current group. They map XML ids with database ids. @@ -68,11 +66,14 @@ function __construct(&$errors) { $this->top_role_id = ttRoleHelper::getRoleByRank(512, 0); } - // startElement - callback handler for opening tag of an XML element in the file. + // startElement - callback handler for opening tags in XML. function startElement($parser, $name, $attrs) { global $i18n; - // First pass. We only check user logins for potential collisions with existing. + // First pass through the file determines if we can import data. + // We require 2 things: + // 1) Database schema version must be set. This ensures we have a compatible file. + // 2) No login coillisions are allowed. if ($this->firstPass) { if ($name == 'ORG' && $this->canImport) { if ($attrs['SCHEMA'] == null) { @@ -86,11 +87,13 @@ function startElement($parser, $name, $attrs) { } } + // In first pass we check user logins for potential collisions with existing. if ($name == 'USER' && $this->canImport) { $login = $attrs['LOGIN']; if ('' != $attrs['STATUS'] && ttUserHelper::getUserByLogin($login)) { // We have a login collision. Append colliding login to a list of things we cannot import. - $this->conflicting_entities .= ($this->conflicting_entities ? ", $login" : $login); + $this->conflicting_logins .= ($this->conflicting_logins ? ", $login" : $login); + // The above is printed in error message with all found colliding logins. } } } @@ -133,6 +136,7 @@ function startElement($parser, $name, $attrs) { } // Set parent group to create subgroups with this group as parent at next entry here. $this->current_parent_group_id = $this->current_group_id; + return; } if ($name == 'ROLES') { @@ -140,22 +144,24 @@ function startElement($parser, $name, $attrs) { unset($this->currentGroupRoleMap); $this->currentGroupRoleMap = array(); // Role map is reconstructed after processing elements in XML. See below. + return; } if ($name == 'ROLE') { // We get here when processing tags for the current group. $role_id = ttRoleHelper::insert(array( - 'group_id' => $this->current_group_id, - 'org_id' => $this->org_id, - 'name' => $attrs['NAME'], - 'description' => $attrs['DESCRIPTION'], - 'rank' => $attrs['RANK'], - 'rights' => $attrs['RIGHTS'], - 'status' => $attrs['STATUS'])); + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'name' => $attrs['NAME'], + 'description' => $attrs['DESCRIPTION'], + 'rank' => $attrs['RANK'], + 'rights' => $attrs['RIGHTS'], + 'status' => $attrs['STATUS'])); if ($role_id) { // Add a mapping. $this->currentGroupRoleMap[$attrs['ID']] = $role_id; } else $this->errors->add($i18n->get('error.db')); + return; } if ($name == 'TASKS') { @@ -163,6 +169,7 @@ function startElement($parser, $name, $attrs) { unset($this->currentGroupTaskMap); $this->currentGroupTaskMap = array(); // Task map is reconstructed after processing elements in XML. See below. + return; } if ($name == 'TASK') { @@ -177,6 +184,7 @@ function startElement($parser, $name, $attrs) { // Add a mapping. $this->currentGroupTaskMap[$attrs['ID']] = $task_id; } else $this->errors->add($i18n->get('error.db')); + return; } if ($name == 'PROJECTS') { @@ -184,6 +192,7 @@ function startElement($parser, $name, $attrs) { unset($this->currentGroupProjectMap); $this->currentGroupProjectMap = array(); // Project map is reconstructed after processing elements in XML. See below. + return; } if ($name == 'PROJECT') { @@ -205,6 +214,7 @@ function startElement($parser, $name, $attrs) { // Add a mapping. $this->currentGroupProjectMap[$attrs['ID']] = $project_id; } else $this->errors->add($i18n->get('error.db')); + return; } if ($name == 'CLIENTS') { @@ -212,6 +222,7 @@ function startElement($parser, $name, $attrs) { unset($this->currentGroupClientMap); $this->currentGroupClientMap = array(); // Client map is reconstructed after processing elements in XML. See below. + return; } if ($name == 'CLIENT') { @@ -234,6 +245,7 @@ function startElement($parser, $name, $attrs) { // Add a mapping. $this->currentGroupClientMap[$attrs['ID']] = $client_id; } else $this->errors->add($i18n->get('error.db')); + return; } if ($name == 'USERS') { @@ -241,6 +253,7 @@ function startElement($parser, $name, $attrs) { unset($this->currentGroupUserMap); $this->currentGroupUserMap = array(); // User map is reconstructed after processing elements in XML. See below. + return; } if ($name == 'USER') { @@ -263,6 +276,7 @@ function startElement($parser, $name, $attrs) { // Add a mapping. $this->currentGroupUserMap[$attrs['ID']] = $user_id; } else $this->errors->add($i18n->get('error.db')); + return; } if ($name == 'USER_PROJECT_BIND') { @@ -275,6 +289,7 @@ function startElement($parser, $name, $attrs) { 'status' => $attrs['STATUS']))) { $this->errors->add($i18n->get('error.db')); } + return; } if ($name == 'INVOICES') { @@ -282,6 +297,7 @@ function startElement($parser, $name, $attrs) { unset($this->currentGroupInvoiceMap); $this->currentGroupInvoiceMap = array(); // Invoice map is reconstructed after processing elements in XML. See below. + return; } if ($name == 'INVOICE') { @@ -297,6 +313,7 @@ function startElement($parser, $name, $attrs) { // Add a mapping. $this->currentGroupInvoiceMap[$attrs['ID']] = $invoice_id; } else $this->errors->add($i18n->get('error.db')); + return; } if ($name == 'LOG') { @@ -304,6 +321,7 @@ function startElement($parser, $name, $attrs) { unset($this->currentGroupLogMap); $this->currentGroupLogMap = array(); // Log map is reconstructed after processing elements in XML. See below. + return; } if ($name == 'LOG_ITEM') { @@ -328,6 +346,7 @@ function startElement($parser, $name, $attrs) { // Add a mapping. $this->currentGroupLogMap[$attrs['ID']] = $log_item_id; } else $this->errors->add($i18n->get('error.db')); + return; } if ($name == 'CUSTOM_FIELDS') { @@ -335,6 +354,7 @@ function startElement($parser, $name, $attrs) { unset($this->currentGroupCustomFieldMap); $this->currentGroupCustomFieldMap = array(); // Custom field map is reconstructed after processing elements in XML. See below. + return; } if ($name == 'CUSTOM_FIELD') { @@ -350,6 +370,7 @@ function startElement($parser, $name, $attrs) { // Add a mapping. $this->currentGroupCustomFieldMap[$attrs['ID']] = $custom_field_id; } else $this->errors->add($i18n->get('error.db')); + return; } if ($name == 'CUSTOM_FIELD_OPTIONS') { @@ -357,6 +378,7 @@ function startElement($parser, $name, $attrs) { unset($this->currentGroupCustomFieldOptionMap); $this->currentGroupCustomFieldOptionMap = array(); // Custom field option map is reconstructed after processing elements in XML. See below. + return; } if ($name == 'CUSTOM_FIELD_OPTION') { @@ -370,6 +392,7 @@ function startElement($parser, $name, $attrs) { // Add a mapping. $this->currentGroupCustomFieldOptionMap[$attrs['ID']] = $custom_field_option_id; } else $this->errors->add($i18n->get('error.db')); + return; } if ($name == 'CUSTOM_FIELD_LOG_ENTRY') { @@ -384,6 +407,7 @@ function startElement($parser, $name, $attrs) { 'status' => $attrs['STATUS']))) { $this->errors->add($i18n->get('error.db')); } + return; } if ($name == 'EXPENSE_ITEM') { @@ -401,6 +425,7 @@ function startElement($parser, $name, $attrs) { 'paid' => $attrs['PAID'], 'status' => $attrs['STATUS'])); if (!$expense_item_id) $this->errors->add($i18n->get('error.db')); + return; } if ($name == 'MONTHLY_QUOTA') { @@ -411,6 +436,7 @@ function startElement($parser, $name, $attrs) { $attrs['MINUTES'])) { $this->errors->add($i18n->get('error.db')); } + return; } if ($name == 'FAV_REPORT') { @@ -450,6 +476,7 @@ function startElement($parser, $name, $attrs) { 'group_by3' => $attrs['GROUP_BY3'], 'chtotalsonly' => (int) $attrs['SHOW_TOTALS_ONLY'])); if (!$fav_report_id) $this->errors->add($i18n->get('error.db')); + return; } } } @@ -491,13 +518,10 @@ function importXml() { xml_set_element_handler($parser, 'startElement', false); // We need to parse the file 2 times: - // 1) First pass: determine if import is possible - there must be no login collisions. - // 2) Second pass: if we can import, then do import in a second pass. - // This is different from earlier approach for single group import, where we could - // do both things in one pass because user info was in the beginning of XML file. - // Now, with subgroups, users can be located anywhere in the file. + // 1) First pass: determine if import is possible. + // 2) Second pass: import data, one tag at a time. - // Read and parse the content of the file. During parsing, startElement, endElement, and dataElement functions are called. + // Read and parse the content of the file. During parsing, startElement is called back for each tag. $file = fopen($filename, 'r'); while ($data = fread($file, 4096)) { if (!xml_parse($parser, $data, feof($file))) { @@ -506,10 +530,10 @@ function importXml() { xml_error_string(xml_get_error_code($parser)))); } } - if ($this->conflicting_entities) { + if ($this->conflicting_logins) { $this->canImport = false; $this->errors->add($i18n->get('error.user_exists')); - $this->errors->add(sprintf($i18n->get('error.cannot_import'), $this->conflicting_entities)); + $this->errors->add(sprintf($i18n->get('error.cannot_import'), $this->conflicting_logins)); } $this->firstPass = false; // We are done with 1st pass. @@ -526,7 +550,7 @@ function importXml() { xml_set_object($parser, $this); xml_set_element_handler($parser, 'startElement', false); - // Read and parse the content of the file. During parsing, startElement, endElement, and dataElement functions are called. + // Read and parse the content of the file. During parsing, startElement is called back for each tag. $file = fopen($filename, 'r'); while ($data = fread($file, 4096)) { if (!xml_parse($parser, $data, feof($file))) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 48b80bfae..c79767d2b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4420 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4421 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From bea65bba9873151a4d31f944d90d9b93c72727b0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 12 Nov 2018 14:42:20 +0000 Subject: [PATCH 0339/1848] Rolling back old import-export due to a problem with undeclared entities during XML parsing. --- WEB-INF/templates/footer.tpl | 2 +- export.php | 8 ++++---- import.php | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c79767d2b..218053a7a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4421 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4422 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/export.php b/export.php index 2b52acae0..cf3bccfa9 100644 --- a/export.php +++ b/export.php @@ -57,11 +57,11 @@ $mime_type = 'application/x-bzip2'; } - //if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { + if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { $exportHelper = new ttOrgExportHelper(); - //} else { - // $exportHelper = new ttExportHelper(); - //} + } else { + $exportHelper = new ttExportHelper(); + } if ($exportHelper->createDataFile($compress)) { header('Pragma: public'); // This is needed for IE8 to download files over https. header('Content-Type: '.$mime_type); diff --git a/import.php b/import.php index 78630866b..235924ac4 100644 --- a/import.php +++ b/import.php @@ -43,11 +43,11 @@ $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.import'))); if ($request->isPost()) { -// if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { + if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { $import = new ttOrgImportHelper($err); -// } else { -// $import = new ttImportHelper($err); -// } + } else { + $import = new ttImportHelper($err); + } $import->importXml(); if ($err->no()) $msg->add($i18n->get('form.import.success')); } // isPost From 50062ed6562d3588745bca1fbd12e6ff063d8d74 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 14 Nov 2018 16:30:19 +0000 Subject: [PATCH 0340/1848] Another try to start using new export-import. --- WEB-INF/lib/ttGroupExportHelper.class.php | 40 +++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- export.php | 8 ++--- import.php | 8 ++--- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index ce3dbb672..4e6daad26 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -179,8 +179,8 @@ function writeData() { // Write group info. $group = $this->getGroupData(); - $group_part = "file, $this->indentation." \n"); foreach ($roles as $role) { $role_part = $this->indentation.' '."roleMap[$role['id']]."\""; - $role_part .= " name=\"".htmlentities($role['name'])."\""; - $role_part .= " description=\"".htmlentities($role['description'])."\""; + $role_part .= " name=\"".htmlspecialchars($role['name'])."\""; + $role_part .= " description=\"".htmlspecialchars($role['description'])."\""; $role_part .= " rank=\"".$role['rank']."\""; - $role_part .= " rights=\"".htmlentities($role['rights'])."\""; + $role_part .= " rights=\"".htmlspecialchars($role['rights'])."\""; $role_part .= " status=\"".$role['status']."\""; $role_part .= ">\n"; fwrite($this->file, $role_part); @@ -265,8 +265,8 @@ function writeData() { fwrite($this->file, $this->indentation." \n"); foreach ($tasks as $task) { $task_part = $this->indentation.' '."taskMap[$task['id']]."\""; - $task_part .= " name=\"".htmlentities($task['name'])."\""; - $task_part .= " description=\"".htmlentities($task['description'])."\""; + $task_part .= " name=\"".htmlspecialchars($task['name'])."\""; + $task_part .= " description=\"".htmlspecialchars($task['description'])."\""; $task_part .= " status=\"".$task['status']."\""; $task_part .= ">\n"; fwrite($this->file, $task_part); @@ -286,8 +286,8 @@ function writeData() { $tasks_str = implode(',', $tasks_mapped); } $project_part = $this->indentation.' '."projectMap[$project_item['id']]."\""; - $project_part .= " name=\"".htmlentities($project_item['name'])."\""; - $project_part .= " description=\"".htmlentities($project_item['description'])."\""; + $project_part .= " name=\"".htmlspecialchars($project_item['name'])."\""; + $project_part .= " description=\"".htmlspecialchars($project_item['description'])."\""; $project_part .= " tasks=\"".$tasks_str."\""; $project_part .= " status=\"".$project_item['status']."\""; $project_part .= ">\n"; @@ -308,8 +308,8 @@ function writeData() { $projects_str = implode(',', $projects_mapped); } $client_part = $this->indentation.' '."clientMap[$client_item['id']]."\""; - $client_part .= " name=\"".htmlentities($client_item['name'])."\""; - $client_part .= " address=\"".htmlentities($client_item['address'])."\""; + $client_part .= " name=\"".htmlspecialchars($client_item['name'])."\""; + $client_part .= " address=\"".htmlspecialchars($client_item['address'])."\""; $client_part .= " tax=\"".$client_item['tax']."\""; $client_part .= " projects=\"".$projects_str."\""; $client_part .= " status=\"".$client_item['status']."\""; @@ -325,8 +325,8 @@ function writeData() { foreach ($users as $user_item) { $role_id = $user_item['rank'] == 512 ? 0 : $this->roleMap[$user_item['role_id']]; // Special role_id 0 (not null) for top manager. $user_part = $this->indentation.' '."userMap[$user_item['id']]."\""; - $user_part .= " name=\"".htmlentities($user_item['name'])."\""; - $user_part .= " login=\"".htmlentities($user_item['login'])."\""; + $user_part .= " name=\"".htmlspecialchars($user_item['name'])."\""; + $user_part .= " login=\"".htmlspecialchars($user_item['login'])."\""; $user_part .= " password=\"".$user_item['password']."\""; $user_part .= " role_id=\"".$role_id."\""; $user_part .= " client_id=\"".$this->clientMap[$user_item['client_id']]."\""; @@ -361,7 +361,7 @@ function writeData() { fwrite($this->file, $this->indentation." \n"); foreach ($invoices as $invoice_item) { $invoice_part = $this->indentation.' '."invoiceMap[$invoice_item['id']]."\""; - $invoice_part .= " name=\"".htmlentities($invoice_item['name'])."\""; + $invoice_part .= " name=\"".htmlspecialchars($invoice_item['name'])."\""; $invoice_part .= " date=\"".$invoice_item['date']."\""; $invoice_part .= " client_id=\"".$this->clientMap[$invoice_item['client_id']]."\""; $invoice_part .= " status=\"".$invoice_item['status']."\""; @@ -391,7 +391,7 @@ function writeData() { $log_part .= " project_id=\"".$this->projectMap[$record['project_id']]."\""; $log_part .= " task_id=\"".$this->taskMap[$record['task_id']]."\""; $log_part .= " invoice_id=\"".$this->invoiceMap[$record['invoice_id']]."\""; - $log_part .= " comment=\"".htmlentities($record['comment'])."\""; + $log_part .= " comment=\"".htmlspecialchars($record['comment'])."\""; $log_part .= " billable=\"".$record['billable']."\""; $log_part .= " paid=\"".$record['paid']."\""; $log_part .= " status=\"".$record['status']."\""; @@ -408,7 +408,7 @@ function writeData() { foreach ($custom_fields as $custom_field) { $custom_field_part = $this->indentation.' '."customFieldMap[$custom_field['id']]."\""; $custom_field_part .= " type=\"".$custom_field['type']."\""; - $custom_field_part .= " label=\"".htmlentities($custom_field['label'])."\""; + $custom_field_part .= " label=\"".htmlspecialchars($custom_field['label'])."\""; $custom_field_part .= " required=\"".$custom_field['required']."\""; $custom_field_part .= " status=\"".$custom_field['status']."\""; $custom_field_part .= ">\n"; @@ -423,7 +423,7 @@ function writeData() { foreach ($custom_field_options as $option) { $custom_field_option_part = $this->indentation.' '."customFieldOptionMap[$option['id']]."\""; $custom_field_option_part .= " field_id=\"".$this->customFieldMap[$option['field_id']]."\""; - $custom_field_option_part .= " value=\"".htmlentities($option['value'])."\""; + $custom_field_option_part .= " value=\"".htmlspecialchars($option['value'])."\""; $custom_field_option_part .= ">\n"; fwrite($this->file, $custom_field_option_part); } @@ -438,7 +438,7 @@ function writeData() { $custom_field_log_part = $this->indentation.' '."logMap[$entry['log_id']]."\""; $custom_field_log_part .= " field_id=\"".$this->customFieldMap[$entry['field_id']]."\""; $custom_field_log_part .= " option_id=\"".$this->customFieldOptionMap[$entry['option_id']]."\""; - $custom_field_log_part .= " value=\"".htmlentities($entry['value'])."\""; + $custom_field_log_part .= " value=\"".htmlspecialchars($entry['value'])."\""; $custom_field_log_part .= " status=\"".$entry['status']."\""; $custom_field_log_part .= ">\n"; fwrite($this->file, $custom_field_log_part); @@ -455,7 +455,7 @@ function writeData() { $expense_item_part .= " user_id=\"".$this->userMap[$expense_item['user_id']]."\""; $expense_item_part .= " client_id=\"".$this->clientMap[$expense_item['client_id']]."\""; $expense_item_part .= " project_id=\"".$this->projectMap[$expense_item['project_id']]."\""; - $expense_item_part .= " name=\"".htmlentities($expense_item['name'])."\""; + $expense_item_part .= " name=\"".htmlspecialchars($expense_item['name'])."\""; $expense_item_part .= " cost=\"".$expense_item['cost']."\""; $expense_item_part .= " invoice_id=\"".$this->invoiceMap[$expense_item['invoice_id']]."\""; $expense_item_part .= " paid=\"".$expense_item['paid']."\""; @@ -494,7 +494,7 @@ function writeData() { } } $fav_report_part = $this->indentation.' '."userMap[$fav_report['user_id']]."\""; - $fav_report_part .= " name=\"".htmlentities($fav_report['name'])."\""; + $fav_report_part .= " name=\"".htmlspecialchars($fav_report['name'])."\""; $fav_report_part .= " client_id=\"".$this->clientMap[$fav_report['client_id']]."\""; $fav_report_part .= " cf_1_option_id=\"".$this->customFieldOptionMap[$fav_report['cf_1_option_id']]."\""; $fav_report_part .= " project_id=\"".$this->projectMap[$fav_report['project_id']]."\""; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 218053a7a..e6132be19 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4422 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4423 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/export.php b/export.php index cf3bccfa9..f278b7c96 100644 --- a/export.php +++ b/export.php @@ -57,11 +57,11 @@ $mime_type = 'application/x-bzip2'; } - if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { +// if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { $exportHelper = new ttOrgExportHelper(); - } else { - $exportHelper = new ttExportHelper(); - } +// } else { +// $exportHelper = new ttExportHelper(); +// } if ($exportHelper->createDataFile($compress)) { header('Pragma: public'); // This is needed for IE8 to download files over https. header('Content-Type: '.$mime_type); diff --git a/import.php b/import.php index 235924ac4..78630866b 100644 --- a/import.php +++ b/import.php @@ -43,11 +43,11 @@ $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.import'))); if ($request->isPost()) { - if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { +// if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { $import = new ttOrgImportHelper($err); - } else { - $import = new ttImportHelper($err); - } +// } else { +// $import = new ttImportHelper($err); +// } $import->importXml(); if ($err->no()) $msg->add($i18n->get('form.import.success')); } // isPost From 509d1d70d0580e26a4467e123c06d2c8939f32cc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 14 Nov 2018 17:52:45 +0000 Subject: [PATCH 0341/1848] Fixed importing clients without projects in new import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 8 +++++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 73f1f09e2..77458cfaa 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -229,9 +229,11 @@ function startElement($parser, $name, $attrs) { // We get here when processing tags for the current group. // Prepare a list of project ids. - $projects = explode(',', $attrs['PROJECTS']); - foreach ($projects as $id) - $mapped_projects[] = $this->currentGroupProjectMap[$id]; + if ($attrs['PROJECTS']) { + $projects = explode(',', $attrs['PROJECTS']); + foreach ($projects as $id) + $mapped_projects[] = $this->currentGroupProjectMap[$id]; + } $client_id = ttClientHelper::insert(array( 'group_id' => $this->current_group_id, diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e6132be19..16196a606 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4423 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4424 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From af4d194c7beb4020c7aff5f8c9eb36156b9b407e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 14 Nov 2018 23:57:41 +0000 Subject: [PATCH 0342/1848] Improved new import so that it does not flood the output with multiple XML errors. --- WEB-INF/lib/ttOrgImportHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 77458cfaa..96ac5708c 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -525,7 +525,7 @@ function importXml() { // Read and parse the content of the file. During parsing, startElement is called back for each tag. $file = fopen($filename, 'r'); - while ($data = fread($file, 4096)) { + while (($data = fread($file, 4096)) && $this->errors->no()) { if (!xml_parse($parser, $data, feof($file))) { $this->errors->add(sprintf($i18n->get('error.xml'), xml_get_current_line_number($parser), @@ -554,7 +554,7 @@ function importXml() { // Read and parse the content of the file. During parsing, startElement is called back for each tag. $file = fopen($filename, 'r'); - while ($data = fread($file, 4096)) { + while (($data = fread($file, 4096)) && $this->errors->no()) { if (!xml_parse($parser, $data, feof($file))) { $this->errors->add(sprintf($i18n->get('error.xml'), xml_get_current_line_number($parser), diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 16196a606..1f8ef090b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4424 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4425 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e56ae75283e1ce89e9188184e950cc8e38e11f8e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 15 Nov 2018 11:39:38 +0000 Subject: [PATCH 0343/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 10 ++++------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 9c036716a..af118f147 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -99,10 +99,9 @@ 'error.goto_uncompleted' => 'Ga naar onvolledige invoer.', 'error.overlap' => 'De huidige registratie overlapt een reeds bestaande registratie.', 'error.future_date' => 'Datum ligt in de toekomst.', -// TODO: translate the following. -// 'error.xml' => 'Error in XML file at line %d: %s.', -// 'error.cannot_import' => 'Cannot import: %s.', -// 'error.format' => 'Invalid file format.', +'error.xml' => 'Fout in XML bestand in regel line %d: %s.', +'error.cannot_import' => 'Kan niet importeren: %s.', +'error.format' => 'Bestandsformaat niet valide.', // Labels for buttons. 'button.login' => 'Aanmelden', @@ -143,8 +142,7 @@ 'label.end_date' => 'Einddatum', 'label.user' => 'Medewerker', 'label.users' => 'Medewerkers', -// TODO: translate the following. -// 'label.group' => 'Group', +'label.group' => 'Groep', 'label.roles' => 'Rollen', 'label.client' => 'Klant', 'label.clients' => 'Klanten', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1f8ef090b..d9982336f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4425 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4426 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 5f1e536c60f1b70dae7253e7ce7256b5f030074c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 15 Nov 2018 15:31:17 +0000 Subject: [PATCH 0344/1848] Cosmetic improvements. --- WEB-INF/lib/ttGroupHelper.class.php | 2 +- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 44dc3e1b1..128650c62 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -36,7 +36,7 @@ static function getTopGroups() { $mdb2 = getConnection(); $sql = "select id, name, created, lang from tt_groups". - " where status = 1 and (org_id is NULL or org_id = id) order by id desc"; + " where status = 1 and org_id = id order by id desc"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index af118f147..fb2e9b420 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -100,7 +100,7 @@ 'error.overlap' => 'De huidige registratie overlapt een reeds bestaande registratie.', 'error.future_date' => 'Datum ligt in de toekomst.', 'error.xml' => 'Fout in XML bestand in regel line %d: %s.', -'error.cannot_import' => 'Kan niet importeren: %s.', +'error.cannot_import' => 'Kan het volgende niet importeren: %s.', 'error.format' => 'Bestandsformaat niet valide.', // Labels for buttons. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d9982336f..89261e30d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4426 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4427 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 4cf643dd179f2784af068a5bbfbc0168ab9ad591 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 15 Nov 2018 16:07:16 +0000 Subject: [PATCH 0345/1848] Added error output. --- WEB-INF/templates/footer.tpl | 2 +- admin_group_edit.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 89261e30d..b1b51b776 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4427 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4428 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_group_edit.php b/admin_group_edit.php index 6306bdd08..bb0fc4134 100644 --- a/admin_group_edit.php +++ b/admin_group_edit.php @@ -95,7 +95,8 @@ if ($result) { header('Location: admin_groups.php'); exit(); - } + } else + $err->add($i18n->get('error.db')); } if ($request->getParameter('btn_cancel')) { From 4da474b3fee7606ff8ce81b9e9c9d1fe82a82bdc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 15 Nov 2018 16:21:24 +0000 Subject: [PATCH 0346/1848] Switching from utf8 to utf8mb4 character set for full Unicode support (emoji, etc.). --- WEB-INF/config.php.dist | 2 +- WEB-INF/templates/footer.tpl | 2 +- mysql.sql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 3f6fdaf33..1d852c21a 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -37,7 +37,7 @@ set_include_path(realpath(dirname(__FILE__).'/lib/pear') . PATH_SEPARATOR . get_ // CHANGE 3 PARAMETERS HERE! // In this example: "root" is username, "no" is password, "dbname" is database name. // -define('DSN', 'mysqli://root:no@localhost/dbname?charset=utf8'); +define('DSN', 'mysqli://root:no@localhost/dbname?charset=utf8mb4'); // Do NOT change charset unless you upgraded from an older Time Tracker where charset was NOT specified // and now you see some corrupted characters. See http://dev.mysql.com/doc/refman/5.0/en/charset-mysql.html diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b1b51b776..c45141d05 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.12.4428 | Copyright © Anuko | +  Anuko Time Tracker 1.18.12.4429 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mysql.sql b/mysql.sql index 00abb462f..5237dfe31 100644 --- a/mysql.sql +++ b/mysql.sql @@ -3,7 +3,7 @@ # 2) Then, execute this script from command prompt with a command like this: # mysql -h host -u user -p -D db_name < mysql.sql -# create database timetracker character set = 'utf8'; +# create database timetracker character set = 'utf8mb4'; # use timetracker; From 1a7f5dda663493a6ea33a86a58b3caab7fd94062 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 16 Nov 2018 00:04:10 +0000 Subject: [PATCH 0347/1848] Fixed mysql.sql for new installs - one table was not being created. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 9 +++++---- mysql.sql | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c45141d05..cb9bed062 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.12.4429 | Copyright © Anuko | +  Anuko Time Tracker 1.18.13.4430 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index d150e7350..8a6d66fde 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -956,7 +956,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11812"]) { + if ($_POST["convert11797to11813"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -989,6 +989,7 @@ function setChange($sql) { setChange("ALTER TABLE `tt_project_task_binds` ADD `group_id` int(11) default NULL AFTER `task_id`"); setChange("ALTER TABLE `tt_project_task_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.12', modified = now() where param_name = 'version_db' and param_value = '1.18.11'"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.13', modified = now() where param_name = 'version_db' and param_value = '1.18.12'"); // TODO: this does not work as we just introduced group_id and it is NULL. Same for tt_project_task_binds. Improve. // setChange("UPDATE `tt_user_project_binds` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.12') set org_id = group_id where org_id is null"); } @@ -1036,7 +1037,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.12) + Create database structure (v1.18.13)
(applies only to new installations, do not execute when updating)
@@ -1081,8 +1082,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.12)Update database structure (v1.17.97 to v1.18.13)
diff --git a/mysql.sql b/mysql.sql index 5237dfe31..1b510a73d 100644 --- a/mysql.sql +++ b/mysql.sql @@ -169,9 +169,9 @@ create unique index bind_idx on tt_user_project_binds(user_id, project_id); # CREATE TABLE `tt_project_task_binds` ( `project_id` int(11) NOT NULL, # project id - `task_id` int(11) NOT NULL # task id + `task_id` int(11) NOT NULL, # task id `group_id` int(11) default NULL, # group id - `org_id` int(11) default NULL, # organization id + `org_id` int(11) default NULL # organization id ); # Indexes for tt_project_task_binds. @@ -469,4 +469,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.12', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.13', now()); # TODO: change when structure changes. From b36d1978a980173bae78818be6254041533a4d98 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 16 Nov 2018 01:21:24 +0000 Subject: [PATCH 0348/1848] Changed collation to utf8mb4_bin to support 4-byte UTF-8 characters. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 15 ++++++--- mysql.sql | 60 ++++++++++++++++++------------------ 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index cb9bed062..e6154271f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.13.4430 | Copyright © Anuko | +  Anuko Time Tracker 1.18.14.4431 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 8a6d66fde..f81e31f7e 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -956,7 +956,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11813"]) { + if ($_POST["convert11797to11814"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -990,6 +990,13 @@ function setChange($sql) { setChange("ALTER TABLE `tt_project_task_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.12', modified = now() where param_name = 'version_db' and param_value = '1.18.11'"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.13', modified = now() where param_name = 'version_db' and param_value = '1.18.12'"); + setChange("ALTER TABLE `tt_users` MODIFY `login` varchar(50) COLLATE utf8mb4_bin NOT NULL"); + setChange("ALTER TABLE `tt_projects` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); + setChange("ALTER TABLE `tt_tasks` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); + setChange("ALTER TABLE `tt_invoices` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); + setChange("ALTER TABLE `tt_clients` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.14', modified = now() where param_name = 'version_db' and param_value = '1.18.13'"); + // TODO: this does not work as we just introduced group_id and it is NULL. Same for tt_project_task_binds. Improve. // setChange("UPDATE `tt_user_project_binds` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.12') set org_id = group_id where org_id is null"); } @@ -1037,7 +1044,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.13) + Create database structure (v1.18.14)
(applies only to new installations, do not execute when updating)
@@ -1082,8 +1089,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.13)Update database structure (v1.17.97 to v1.18.14)
diff --git a/mysql.sql b/mysql.sql index 1b510a73d..14a8aa0f9 100644 --- a/mysql.sql +++ b/mysql.sql @@ -82,7 +82,7 @@ INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top ma # CREATE TABLE `tt_users` ( `id` int(11) NOT NULL auto_increment, # user id - `login` varchar(50) COLLATE utf8_bin NOT NULL, # user login + `login` varchar(50) COLLATE utf8mb4_bin NOT NULL,# user login `password` varchar(50) default NULL, # password hash `name` varchar(100) default NULL, # user name `group_id` int(11) NOT NULL, # group id @@ -115,13 +115,13 @@ INSERT INTO `tt_users` (`login`, `password`, `name`, `group_id`, `role_id`) VALU # Structure for table tt_projects. # CREATE TABLE `tt_projects` ( - `id` int(11) NOT NULL auto_increment, # project id - `group_id` int(11) NOT NULL, # group id - `org_id` int(11) default NULL, # organization id - `name` varchar(80) COLLATE utf8_bin NOT NULL, # project name - `description` varchar(255) default NULL, # project description - `tasks` text default NULL, # comma-separated list of task ids associated with this project - `status` tinyint(4) default 1, # project status + `id` int(11) NOT NULL auto_increment, # project id + `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id + `name` varchar(80) COLLATE utf8mb4_bin NOT NULL, # project name + `description` varchar(255) default NULL, # project description + `tasks` text default NULL, # comma-separated list of task ids associated with this project + `status` tinyint(4) default 1, # project status PRIMARY KEY (`id`) ); @@ -133,12 +133,12 @@ create unique index project_idx on tt_projects(group_id, name, status); # Structure for table tt_tasks. # CREATE TABLE `tt_tasks` ( - `id` int(11) NOT NULL auto_increment, # task id - `group_id` int(11) NOT NULL, # group id - `org_id` int(11) default NULL, # organization id - `name` varchar(80) COLLATE utf8_bin NOT NULL, # task name - `description` varchar(255) default NULL, # task description - `status` tinyint(4) default 1, # task status + `id` int(11) NOT NULL auto_increment, # task id + `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id + `name` varchar(80) COLLATE utf8mb4_bin NOT NULL, # task name + `description` varchar(255) default NULL, # task description + `status` tinyint(4) default 1, # task status PRIMARY KEY (`id`) ); @@ -222,13 +222,13 @@ create index task_idx on tt_log(task_id); # Structure for table tt_invoices. Invoices are issued to clients for billable work. # CREATE TABLE `tt_invoices` ( - `id` int(11) NOT NULL auto_increment, # invoice id - `group_id` int(11) NOT NULL, # group id - `org_id` int(11) default NULL, # organization id - `name` varchar(80) COLLATE utf8_bin NOT NULL, # invoice name - `date` date NOT NULL, # invoice date - `client_id` int(11) NOT NULL, # client id - `status` tinyint(4) default 1, # invoice status + `id` int(11) NOT NULL auto_increment, # invoice id + `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id + `name` varchar(80) COLLATE utf8mb4_bin NOT NULL, # invoice name + `date` date NOT NULL, # invoice date + `client_id` int(11) NOT NULL, # client id + `status` tinyint(4) default 1, # invoice status PRIMARY KEY (`id`) ); @@ -310,14 +310,14 @@ CREATE TABLE `tt_cron` ( # Structure for table tt_clients. A client is an entity for whom work is performed and who may be invoiced. # CREATE TABLE `tt_clients` ( - `id` int(11) NOT NULL AUTO_INCREMENT, # client id - `group_id` int(11) NOT NULL, # group id - `org_id` int(11) default NULL, # organization id - `name` varchar(80) COLLATE utf8_bin NOT NULL, # client name - `address` varchar(255) default NULL, # client address - `tax` float(6,2) default '0.00', # applicable tax for this client - `projects` text default NULL, # comma-separated list of project ids assigned to this client - `status` tinyint(4) default 1, # client status + `id` int(11) NOT NULL AUTO_INCREMENT, # client id + `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id + `name` varchar(80) COLLATE utf8mb4_bin NOT NULL, # client name + `address` varchar(255) default NULL, # client address + `tax` float(6,2) default '0.00', # applicable tax for this client + `projects` text default NULL, # comma-separated list of project ids assigned to this client + `status` tinyint(4) default 1, # client status PRIMARY KEY (`id`) ); @@ -469,4 +469,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.13', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.14', now()); # TODO: change when structure changes. From e61ac06c8cef6425af27ee29a0cd0ca908108eb2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 16 Nov 2018 16:10:25 +0000 Subject: [PATCH 0349/1848] Removed old import and export classes. --- WEB-INF/lib/ttExportHelper.class.php | 420 ------------------- WEB-INF/lib/ttImportHelper.class.php | 509 ------------------------ WEB-INF/lib/ttOrgExportHelper.class.php | 5 +- WEB-INF/lib/ttOrgImportHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- export.php | 7 +- import.php | 9 +- 7 files changed, 7 insertions(+), 946 deletions(-) delete mode 100644 WEB-INF/lib/ttExportHelper.class.php delete mode 100644 WEB-INF/lib/ttImportHelper.class.php diff --git a/WEB-INF/lib/ttExportHelper.class.php b/WEB-INF/lib/ttExportHelper.class.php deleted file mode 100644 index 7072f2b73..000000000 --- a/WEB-INF/lib/ttExportHelper.class.php +++ /dev/null @@ -1,420 +0,0 @@ -getActiveGroup(); - - // Create a temporary file. - $dirName = dirname(TEMPLATE_DIR . '_c/.'); - $tmp_file = tempnam($dirName, 'tt'); - - // Open the file for writing. - $file = fopen($tmp_file, 'wb'); - if (!$file) return false; - - // Write XML to the file. - fwrite($file, "\n"); - fwrite($file, "\n"); - - // Write group info. - fwrite($file, "currency."\" decimal_mark=\"".$user->decimal_mark."\" lang=\"".$user->lang. - "\" date_format=\"".$user->date_format."\" time_format=\"".$user->time_format."\" week_start=\"".$user->week_start. - "\" tracking_mode=\"".$user->tracking_mode."\" project_required=\"".$user->project_required."\" task_required=\"".$user->task_required. - "\" record_type=\"".$user->record_type."\" bcc_email=\"".$user->bcc_email. - "\" plugins=\"".$user->plugins."\" lock_spec=\"".$user->lock_spec."\" workday_minutes=\"".$user->workday_minutes. - "\" config=\"".$user->config. - "\">\n"); - fwrite($file, " group_name."]]>\n"); - fwrite($file, " allow_ip."]]>\n"); - fwrite($file, " password_complexity."]]>\n"); - fwrite($file, "\n"); - - // Prepare role map. - $roles = $this->getRoles(); - foreach ($roles as $key=>$role_item) - $this->roleMap[$role_item['id']] = $key + 1; - - // Prepare user map. - $users = $this->getUsers(); - foreach ($users as $key=>$user_item) - $this->userMap[$user_item['id']] = $key + 1; - - // Prepare project map. - $projects = ttTeamHelper::getAllProjects($group_id, true); - foreach ($projects as $key=>$project_item) - $this->projectMap[$project_item['id']] = $key + 1; - - // Prepare task map. - $tasks = ttTeamHelper::getAllTasks($group_id, true); - foreach ($tasks as $key=>$task_item) - $this->taskMap[$task_item['id']] = $key + 1; - - // Prepare client map. - $clients = ttTeamHelper::getAllClients($group_id, true); - foreach ($clients as $key=>$client_item) - $this->clientMap[$client_item['id']] = $key + 1; - - // Prepare invoice map. - $invoices = ttTeamHelper::getAllInvoices(); - foreach ($invoices as $key=>$invoice_item) - $this->invoiceMap[$invoice_item['id']] = $key + 1; - - // Prepare custom fields map. - $custom_fields = ttTeamHelper::getAllCustomFields($group_id); - foreach ($custom_fields as $key=>$custom_field) - $this->customFieldMap[$custom_field['id']] = $key + 1; - - // Prepare custom field options map. - $custom_field_options = ttTeamHelper::getAllCustomFieldOptions($group_id); - foreach ($custom_field_options as $key=>$option) - $this->customFieldOptionMap[$option['id']] = $key + 1; - - // Write roles. - fwrite($file, "\n"); - foreach ($roles as $role) { - fwrite($file, " roleMap[$role['id']]."\" rank=\"".$role['rank']."\"". - " rights=\"".$role['rights']."\" status=\"".$role['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($roles); - - // Write users. - fwrite($file, "\n"); - foreach ($users as $user_item) { - $role_id = $user_item['rank'] == 512 ? 0 : $this->roleMap[$user_item['role_id']]; // Special role_id 0 (not null) for top manager. - fwrite($file, " userMap[$user_item['id']]."\" login=\"".htmlentities($user_item['login'])."\" password=\"".$user_item['password']."\" role_id=\"".$role_id."\" client_id=\"".$this->clientMap[$user_item['client_id']]."\" rate=\"".$user_item['rate']."\" email=\"".$user_item['email']."\" status=\"".$user_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - - // Write tasks. - fwrite($file, "\n"); - foreach ($tasks as $task_item) { - fwrite($file, " taskMap[$task_item['id']]."\" status=\"".$task_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($tasks); - - // Write projects. - fwrite($file, "\n"); - foreach ($projects as $project_item) { - if($project_item['tasks']){ - $tasks = explode(',', $project_item['tasks']); - $tasks_mapped = array(); - foreach ($tasks as $item) - $tasks_mapped[] = $this->taskMap[$item]; - $tasks_str = implode(',', $tasks_mapped); - } - fwrite($file, " projectMap[$project_item['id']]."\" tasks=\"".$tasks_str."\" status=\"".$project_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($projects); - - // Write user to project binds. - fwrite($file, "\n"); - $user_binds = ttTeamHelper::getUserToProjectBinds($group_id); - foreach ($user_binds as $bind) { - $user_id = $this->userMap[$bind['user_id']]; - $project_id = $this->projectMap[$bind['project_id']]; - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($user_binds); - - // Write clients. - fwrite($file, "\n"); - foreach ($clients as $client_item) { - if($client_item['projects']){ - $projects = explode(',', $client_item['projects']); - $projects_mapped = array(); - foreach ($projects as $item) - $projects_mapped[] = $this->projectMap[$item]; - $projects_str = implode(',', $projects_mapped); - } - fwrite($file, " clientMap[$client_item['id']]."\" tax=\"".$client_item['tax']."\" projects=\"".$projects_str."\" status=\"".$client_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, "
\n"); - fwrite($file, "
\n"); - } - fwrite($file, "
\n"); - unset($clients); - - // Write invoices. - fwrite($file, "\n"); - foreach ($invoices as $invoice_item) { - fwrite($file, " invoiceMap[$invoice_item['id']]."\" date=\"".$invoice_item['date']."\" client_id=\"".$this->clientMap[$invoice_item['client_id']]."\" status=\"".$invoice_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($invoices); - - // Write custom fields. - fwrite($file, "\n"); - foreach ($custom_fields as $custom_field) { - fwrite($file, " customFieldMap[$custom_field['id']]."\" type=\"".$custom_field['type']."\" required=\"".$custom_field['required']."\" status=\"".$custom_field['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($custom_fields); - - // Write custom field options. - fwrite($file, "\n"); - foreach ($custom_field_options as $option) { - fwrite($file, " customFieldOptionMap[$option['id']]."\" field_id=\"".$this->customFieldMap[$option['field_id']]."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($custom_field_options); - - // Write monthly quotas. - $quotas = ttTeamHelper::getMonthlyQuotas($group_id); - fwrite($file, "\n"); - foreach ($quotas as $quota) { - fwrite($file, " \n"); - } - fwrite($file, "\n"); - - // Write time log entries. - fwrite($file, "\n"); - $key = 0; - foreach ($users as $user_item) { - $records = ttTimeHelper::getAllRecords($user_item['id']); - foreach ($records as $record) { - $key++; - $this->logMap[$record['id']] = $key; - fwrite($file, " userMap[$record['user_id']]."\" date=\"".$record['date']."\" start=\"".$record['start']."\" finish=\"".$record['finish']."\" duration=\"".($record['start']?"":$record['duration'])."\" client_id=\"".$this->clientMap[$record['client_id']]."\" project_id=\"".$this->projectMap[$record['project_id']]."\" task_id=\"".$this->taskMap[$record['task_id']]."\" invoice_id=\"".$this->invoiceMap[$record['invoice_id']]."\" billable=\"".$record['billable']."\" paid=\"".$record['paid']."\" status=\"".$record['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - } - fwrite($file, "\n"); - unset($records); - - // Write custom field log. - $custom_field_log = ttTeamHelper::getCustomFieldLog($group_id); - fwrite($file, "\n"); - foreach ($custom_field_log as $entry) { - fwrite($file, " logMap[$entry['log_id']]."\" field_id=\"".$this->customFieldMap[$entry['field_id']]."\" option_id=\"".$this->customFieldOptionMap[$entry['option_id']]."\" status=\"".$entry['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($custom_field_log); - - // Write expense items. - $expense_items = ttTeamHelper::getExpenseItems($group_id); - fwrite($file, "\n"); - foreach ($expense_items as $expense_item) { - fwrite($file, " userMap[$expense_item['user_id']]."\" client_id=\"".$this->clientMap[$expense_item['client_id']]."\" project_id=\"".$this->projectMap[$expense_item['project_id']]."\" cost=\"".$expense_item['cost']."\" invoice_id=\"".$this->invoiceMap[$expense_item['invoice_id']]."\" paid=\"".$expense_item['paid']."\" status=\"".$expense_item['status']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($expense_items); - - // Write fav reports. - fwrite($file, "\n"); - $fav_reports = ttTeamHelper::getFavReports($group_id); - foreach ($fav_reports as $fav_report) { - $user_list = ''; - if (strlen($fav_report['users']) > 0) { - $arr = explode(',', $fav_report['users']); - foreach ($arr as $k=>$v) { - if (array_key_exists($arr[$k], $this->userMap)) - $user_list .= (strlen($user_list) == 0? '' : ',').$this->userMap[$v]; - } - } - fwrite($file, " userMap[$fav_report['user_id']]."\"". - " client_id=\"".$this->clientMap[$fav_report['client_id']]."\"". - " cf_1_option_id=\"".$this->customFieldOptionMap[$fav_report['cf_1_option_id']]."\"". - " project_id=\"".$this->projectMap[$fav_report['project_id']]."\"". - " task_id=\"".$this->taskMap[$fav_report['task_id']]."\"". - " billable=\"".$fav_report['billable']."\"". - " users=\"".$user_list."\"". - " period=\"".$fav_report['period']."\"". - " period_start=\"".$fav_report['period_start']."\"". - " period_end=\"".$fav_report['period_end']."\"". - " show_client=\"".$fav_report['show_client']."\"". - " show_invoice=\"".$fav_report['show_invoice']."\"". - " show_paid=\"".$fav_report['show_paid']."\"". - " show_ip=\"".$fav_report['show_ip']."\"". - " show_project=\"".$fav_report['show_project']."\"". - " show_start=\"".$fav_report['show_start']."\"". - " show_duration=\"".$fav_report['show_duration']."\"". - " show_cost=\"".$fav_report['show_cost']."\"". - " show_task=\"".$fav_report['show_task']."\"". - " show_end=\"".$fav_report['show_end']."\"". - " show_note=\"".$fav_report['show_note']."\"". - " show_custom_field_1=\"".$fav_report['show_custom_field_1']."\"". - " show_work_units=\"".$fav_report['show_work_units']."\"". - " group_by1=\"".$fav_report['group_by1']."\"". - " group_by2=\"".$fav_report['group_by2']."\"". - " group_by3=\"".$fav_report['group_by3']."\"". - " show_totals_only=\"".$fav_report['show_totals_only']."\">\n"); - fwrite($file, " \n"); - fwrite($file, " \n"); - } - fwrite($file, "\n"); - unset($fav_reports); - - // Cleanup. - unset($users); - $this->roleMap = array(); - $this->userMap = array(); - $this->projectMap = array(); - $this->taskMap = array(); - - fwrite($file, "
\n"); - fclose($file); - - if ($compress) { - $this->fileName = tempnam($dirName, 'tt'); - $this->compress($tmp_file, $this->fileName); - unlink($tmp_file); - } else - $this->fileName = $tmp_file; - - return true; - } - - // getFileName - returns file name. - function getFileName() { - return $this->fileName; - } - - // compress - compresses the content of the $in file into $out file. - function compress($in, $out) { - // Initial checks of file names and permissions. - if (!file_exists($in) || !is_readable ($in)) - return false; - if ((!file_exists($out) && !is_writable(dirname($out))) || (file_exists($out) && !is_writable($out))) - return false; - - $in_file = fopen($in, 'rb'); - - if (function_exists('bzopen')) { - if (!$out_file = bzopen($out, 'w')) - return false; - - while (!feof ($in_file)) { - $buffer = fread($in_file, 4096); - bzwrite($out_file, $buffer, 4096); - } - bzclose($out_file); - } - fclose ($in_file); - return true; - } - - /* - * Note about the utility functions below. - * We have roughly 4 groups of operations: - * 1) Regular system usage for tracking time, etc. - * 2) Registration process - used infrequently. - * 3) Admin usage - used infrequently. - * 4) Export - used infrequently. - * - * It is tempting to have a generic function to get things done for - * all situations. However, as registration, export and admin access are one-off - * operations, while regular system usage is daily and must be efficient, - * the current approach is to have SEPARATE functions for each mode. - * - * This is because each mode requires a slightly different approach, - * and we don't want to over-complicate things. - */ - - // getRoles - obtains all roles defined for group. - function getRoles() { - global $user; - $mdb2 = getConnection(); - - $result = array(); - $sql = "select * from tt_roles where group_id = ".$user->getActiveGroup(); - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - - // The getUsers obtains all users in group for the purpose of export. - function getUsers() { - global $user; - $mdb2 = getConnection(); - - $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = ". - $user->getActiveGroup()." order by upper(u.name)"; // Note: deleted users are included. - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } -} diff --git a/WEB-INF/lib/ttImportHelper.class.php b/WEB-INF/lib/ttImportHelper.class.php deleted file mode 100644 index 7fa1e2830..000000000 --- a/WEB-INF/lib/ttImportHelper.class.php +++ /dev/null @@ -1,509 +0,0 @@ -errors = &$errors; - } - - // startElement - callback handler for opening tag of an XML element. - // In this function we assign passed in attributes to currentElement. - function startElement($parser, $name, $attrs) { - if ($name == 'GROUP' - || $name == 'USER' - || $name == 'TASK' - || $name == 'PROJECT' - || $name == 'CLIENT' - || $name == 'INVOICE' - || $name == 'MONTHLY_QUOTA' - || $name == 'LOG_ITEM' - || $name == 'CUSTOM_FIELD' - || $name == 'CUSTOM_FIELD_OPTION' - || $name == 'CUSTOM_FIELD_LOG_ENTRY' - || $name == 'INVOICE_HEADER' - || $name == 'USER_PROJECT_BIND' - || $name == 'EXPENSE_ITEM' - || $name == 'FAV_REPORT' - || $name == 'ROLE') { - $this->currentElement = $attrs; - } - $this->currentTag = $name; - } - - // endElement - callback handler for the closing tag of an XML element. - // When we are here, currentElement is an array of the element attributes (as set in startElement). - // Here we do the actual import of data into the database. - function endElement($parser, $name) { - if ($name == 'GROUP') { - $this->groupData = $this->currentElement; - // Now groupData is an array of group properties. We'll use it later to create a group. - // Cannot create the group here. Need to determine whether logins collide with existing logins. - $this->currentElement = array(); - } - if ($name == 'ROLE') { - $this->roles[$this->currentElement['ID']] = $this->currentElement; - $this->currentElement = array(); - } - if ($name == 'USER') { - $this->users[$this->currentElement['ID']] = $this->currentElement; - $this->currentElement = array(); - } - if ($name == 'USERS') { - foreach ($this->users as $user_item) { - if (('' != $user_item['STATUS']) && ttUserHelper::getUserByLogin($user_item['LOGIN'])) { - // We have a login collision, cannot import any data. - $this->canImport = false; - break; - } - } - - // Now we can create a group. - if ($this->canImport) { - $this->top_role_id = ttRoleHelper::getRoleByRank(512, 0); - $group_id = $this->createGroup(array( - 'name' => $this->groupData['NAME'], - 'currency' => $this->groupData['CURRENCY'], - 'decimal_mark' => $this->groupData['DECIMAL_MARK'], - 'lang' => $this->groupData['LANG'], - 'date_format' => $this->groupData['DATE_FORMAT'], - 'time_format' => $this->groupData['TIME_FORMAT'], - 'week_start' => $this->groupData['WEEK_START'], - 'tracking_mode' => $this->groupData['TRACKING_MODE'], - 'project_required' => $this->groupData['PROJECT_REQUIRED'], - 'task_required' => $this->groupData['TASK_REQUIRED'], - 'record_type' => $this->groupData['RECORD_TYPE'], - 'bcc_email' => $this->groupData['BCC_EMAIL'], - 'allow_ip' => $this->groupData['ALLOW_IP'], - 'password_complexity' => $this->groupData['PASSWORD_COMPLEXITY'], - 'plugins' => $this->groupData['PLUGINS'], - 'lock_spec' => $this->groupData['LOCK_SPEC'], - 'workday_minutes' => $this->groupData['WORKDAY_MINUTES'], - 'config' => $this->groupData['CONFIG'])); - if ($group_id) { - $this->org_id = $group_id; - $this->group_id = $group_id; - - // Create roles. - foreach ($this->roles as $key=>$role_item) { - $role_id = ttRoleHelper::insert(array( - 'group_id' => $this->group_id, - 'org_id' => $this->org_id, - 'name' => $role_item['NAME'], - 'description' => $role_item['DESCRIPTION'], - 'rank' => $role_item['RANK'], - 'rights' => $role_item['RIGHTS'], - 'status' => $role_item['STATUS'])); - $this->roleMap[$role_item['ID']] = $role_id; - } - - foreach ($this->users as $key=>$user_item) { - $role_id = $user_item['ROLE_ID'] === '0' ? $this->top_role_id : $this->roleMap[$user_item['ROLE_ID']]; // 0 (not null) means top manager role. - $user_id = ttUserHelper::insert(array( - 'group_id' => $this->group_id, - 'org_id' => $this->org_id, - 'role_id' => $role_id, - 'client_id' => $user_item['CLIENT_ID'], // Note: NOT mapped value, replaced in CLIENT handler. - 'name' => $user_item['NAME'], - 'login' => $user_item['LOGIN'], - 'password' => $user_item['PASSWORD'], - 'rate' => $user_item['RATE'], - 'email' => $user_item['EMAIL'], - 'status' => $user_item['STATUS']), false); - $this->userMap[$key] = $user_id; - } - } - } - } - - if ($name == 'TASK' && $this->canImport) { - $this->taskMap[$this->currentElement['ID']] = - ttTaskHelper::insert(array( - 'group_id' => $this->group_id, - 'org_id' => $this->org_id, - 'name' => $this->currentElement['NAME'], - 'description' => $this->currentElement['DESCRIPTION'], - 'status' => $this->currentElement['STATUS'])); - } - if ($name == 'PROJECT' && $this->canImport) { - // Prepare a list of task ids. - $tasks = explode(',', $this->currentElement['TASKS']); - foreach ($tasks as $id) - $mapped_tasks[] = $this->taskMap[$id]; - - // Add a new project. - $this->projectMap[$this->currentElement['ID']] = - ttProjectHelper::insert(array( - 'group_id' => $this->group_id, - 'org_id' => $this->org_id, - 'name' => $this->currentElement['NAME'], - 'description' => $this->currentElement['DESCRIPTION'], - 'tasks' => $mapped_tasks, - 'status' => $this->currentElement['STATUS'])); - } - if ($name == 'USER_PROJECT_BIND' && $this->canImport) { - ttUserHelper::insertBind(array( - 'user_id' => $this->userMap[$this->currentElement['USER_ID']], - 'project_id' => $this->projectMap[$this->currentElement['PROJECT_ID']], - 'group_id' => $this->group_id, - 'org_id' => $this->org_id, - 'rate' => $this->currentElement['RATE'], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'CLIENT' && $this->canImport) { - // Prepare a list of project ids. - if ($this->currentElement['PROJECTS']) { - $projects = explode(',', $this->currentElement['PROJECTS']); - foreach ($projects as $id) - $mapped_projects[] = $this->projectMap[$id]; - } - - $this->clientMap[$this->currentElement['ID']] = - ttClientHelper::insert(array( - 'group_id' => $this->group_id, - 'org_id' => $this->org_id, - 'name' => $this->currentElement['NAME'], - 'address' => $this->currentElement['ADDRESS'], - 'tax' => $this->currentElement['TAX'], - 'projects' => $mapped_projects, - 'status' => $this->currentElement['STATUS'])); - - // Update client_id for tt_users to a mapped value. - // We did not do it during user insertion because clientMap was not ready then. - if ($this->currentElement['ID'] != $this->clientMap[$this->currentElement['ID']]) - ttClientHelper::setMappedClient($this->group_id, $this->currentElement['ID'], $this->clientMap[$this->currentElement['ID']]); - } - - if ($name == 'INVOICE' && $this->canImport) { - $this->invoiceMap[$this->currentElement['ID']] = - ttInvoiceHelper::insert(array( - 'group_id' => $this->group_id, - 'org_id' => $this->org_id, - 'name' => $this->currentElement['NAME'], - 'date' => $this->currentElement['DATE'], - 'client_id' => $this->clientMap[$this->currentElement['CLIENT_ID']], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'MONTHLY_QUOTA' && $this->canImport) { - $this->insertMonthlyQuota($this->group_id, $this->currentElement['YEAR'], $this->currentElement['MONTH'], $this->currentElement['MINUTES']); - } - - if ($name == 'LOG_ITEM' && $this->canImport) { - $this->logMap[$this->currentElement['ID']] = - ttTimeHelper::insert(array( - 'user_id' => $this->userMap[$this->currentElement['USER_ID']], - 'group_id' => $this->group_id, - 'org_id' => $this->org_id, - 'date' => $this->currentElement['DATE'], - 'start' => $this->currentElement['START'], - 'finish' => $this->currentElement['FINISH'], - 'duration' => $this->currentElement['DURATION'], - 'client' => $this->clientMap[$this->currentElement['CLIENT_ID']], - 'project' => $this->projectMap[$this->currentElement['PROJECT_ID']], - 'task' => $this->taskMap[$this->currentElement['TASK_ID']], - 'invoice' => $this->invoiceMap[$this->currentElement['INVOICE_ID']], - 'note' => (isset($this->currentElement['COMMENT']) ? $this->currentElement['COMMENT'] : ''), - 'billable' => $this->currentElement['BILLABLE'], - 'paid' => $this->currentElement['PAID'], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'CUSTOM_FIELD' && $this->canImport) { - $this->customFieldMap[$this->currentElement['ID']] = - ttCustomFieldHelper::insertField(array( - 'group_id' => $this->group_id, - 'type' => $this->currentElement['TYPE'], - 'label' => $this->currentElement['LABEL'], - 'required' => $this->currentElement['REQUIRED'], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'CUSTOM_FIELD_OPTION' && $this->canImport) { - $this->customFieldOptionMap[$this->currentElement['ID']] = - ttCustomFieldHelper::insertOption(array( - 'field_id' => $this->customFieldMap[$this->currentElement['FIELD_ID']], - 'value' => $this->currentElement['VALUE'])); - } - - if ($name == 'CUSTOM_FIELD_LOG_ENTRY' && $this->canImport) { - ttCustomFieldHelper::insertLogEntry(array( - 'log_id' => $this->logMap[$this->currentElement['LOG_ID']], - 'field_id' => $this->customFieldMap[$this->currentElement['FIELD_ID']], - 'option_id' => $this->customFieldOptionMap[$this->currentElement['OPTION_ID']], - 'value' => $this->currentElement['VALUE'], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'EXPENSE_ITEM' && $this->canImport) { - ttExpenseHelper::insert(array( - 'date' => $this->currentElement['DATE'], - 'user_id' => $this->userMap[$this->currentElement['USER_ID']], - 'group_id' => $this->group_id, - 'client_id' => $this->clientMap[$this->currentElement['CLIENT_ID']], - 'project_id' => $this->projectMap[$this->currentElement['PROJECT_ID']], - 'name' => $this->currentElement['NAME'], - 'cost' => $this->currentElement['COST'], - 'invoice_id' => $this->invoiceMap[$this->currentElement['INVOICE_ID']], - 'paid' => $this->currentElement['PAID'], - 'status' => $this->currentElement['STATUS'])); - } - - if ($name == 'FAV_REPORT' && $this->canImport) { - $user_list = ''; - if (strlen($this->currentElement['USERS']) > 0) { - $arr = explode(',', $this->currentElement['USERS']); - foreach ($arr as $v) - $user_list .= (strlen($user_list) == 0 ? '' : ',').$this->userMap[$v]; - } - ttFavReportHelper::insertReport(array( - 'name' => $this->currentElement['NAME'], - 'user_id' => $this->userMap[$this->currentElement['USER_ID']], - 'client' => $this->clientMap[$this->currentElement['CLIENT_ID']], - 'option' => $this->customFieldOptionMap[$this->currentElement['CF_1_OPTION_ID']], - 'project' => $this->projectMap[$this->currentElement['PROJECT_ID']], - 'task' => $this->taskMap[$this->currentElement['TASK_ID']], - 'billable' => $this->currentElement['BILLABLE'], - 'users' => $user_list, - 'period' => $this->currentElement['PERIOD'], - 'from' => $this->currentElement['PERIOD_START'], - 'to' => $this->currentElement['PERIOD_END'], - 'chclient' => (int) $this->currentElement['SHOW_CLIENT'], - 'chinvoice' => (int) $this->currentElement['SHOW_INVOICE'], - 'chpaid' => (int) $this->currentElement['SHOW_PAID'], - 'chip' => (int) $this->currentElement['SHOW_IP'], - 'chproject' => (int) $this->currentElement['SHOW_PROJECT'], - 'chstart' => (int) $this->currentElement['SHOW_START'], - 'chduration' => (int) $this->currentElement['SHOW_DURATION'], - 'chcost' => (int) $this->currentElement['SHOW_COST'], - 'chtask' => (int) $this->currentElement['SHOW_TASK'], - 'chfinish' => (int) $this->currentElement['SHOW_END'], - 'chnote' => (int) $this->currentElement['SHOW_NOTE'], - 'chcf_1' => (int) $this->currentElement['SHOW_CUSTOM_FIELD_1'], - 'chunits' => (int) $this->currentElement['SHOW_WORK_UNITS'], - 'group_by1' => $this->currentElement['GROUP_BY1'], - 'group_by2' => $this->currentElement['GROUP_BY2'], - 'group_by3' => $this->currentElement['GROUP_BY3'], - 'chtotalsonly' => (int) $this->currentElement['SHOW_TOTALS_ONLY'])); - } - $this->currentTag = ''; - } - - // dataElement - callback handler for text data fragments. It builds up currentElement array with text pieces from XML. - function dataElement($parser, $data) { - if ($this->currentTag == 'NAME' - || $this->currentTag == 'DESCRIPTION' - || $this->currentTag == 'LABEL' - || $this->currentTag == 'VALUE' - || $this->currentTag == 'COMMENT' - || $this->currentTag == 'ADDRESS' - || $this->currentTag == 'ALLOW_IP' - || $this->currentTag == 'PASSWORD_COMPLEXITY') { - if (isset($this->currentElement[$this->currentTag])) - $this->currentElement[$this->currentTag] .= trim($data); - else - $this->currentElement[$this->currentTag] = trim($data); - } - } - - // importXml - uncompresses the file, reads and parses its content. During parsing, - // startElement, endElement, and dataElement functions are called as many times as necessary. - // Actual import occurs in the endElement handler. - function importXml() { - global $i18n; - - // Do we have a compressed file? - $compressed = false; - $file_ext = substr($_FILES['xmlfile']['name'], strrpos($_FILES['xmlfile']['name'], '.') + 1); - if (in_array($file_ext, array('bz','tbz','bz2','tbz2'))) { - $compressed = true; - } - - // Create a temporary file. - $dirName = dirname(TEMPLATE_DIR . '_c/.'); - $filename = tempnam($dirName, 'import_'); - - // If the file is compressed - uncompress it. - if ($compressed) { - if (!$this->uncompress($_FILES['xmlfile']['tmp_name'], $filename)) { - $this->errors->add($i18n->get('error.sys')); - return; - } - unlink($_FILES['xmlfile']['tmp_name']); - } else { - if (!move_uploaded_file($_FILES['xmlfile']['tmp_name'], $filename)) { - $this->errors->add($i18n->get('error.upload')); - return; - } - } - - // Initialize XML parser. - $parser = xml_parser_create(); - xml_set_object($parser, $this); - xml_set_element_handler($parser, 'startElement', 'endElement'); - xml_set_character_data_handler($parser, 'dataElement'); - - // Read and parse the content of the file. During parsing, startElement, endElement, and dataElement functions are called. - $file = fopen($filename, 'r'); - while ($data = fread($file, 4096)) { - if (!xml_parse($parser, $data, feof($file))) { - $this->errors->add(sprintf("XML error: %s at line %d", - xml_error_string(xml_get_error_code($parser)), - xml_get_current_line_number($parser))); - } - if (!$this->canImport) { - $this->errors->add($i18n->get('error.user_exists')); - break; - } - } - xml_parser_free($parser); - if ($file) fclose($file); - unlink($filename); - } - - // uncompress - uncompresses the content of the $in file into the $out file. - function uncompress($in, $out) { - // Do we have the uncompress function? - if (!function_exists('bzopen')) - return false; - - // Initial checks of file names and permissions. - if (!file_exists($in) || !is_readable ($in)) - return false; - if ((!file_exists($out) && !is_writable(dirname($out))) || (file_exists($out) && !is_writable($out))) - return false; - - if (!$out_file = fopen($out, 'wb')) - return false; - if (!$in_file = bzopen ($in, 'r')) - return false; - - while (!feof($in_file)) { - $buffer = bzread($in_file, 4096); - fwrite($out_file, $buffer, 4096); - } - bzclose($in_file); - fclose ($out_file); - return true; - } - - // createGroup function creates a new group. - private function createGroup($fields) { - - global $user; - $mdb2 = getConnection(); - - $columns = '(name, currency, decimal_mark, lang, date_format, time_format, week_start, tracking_mode'. - ', project_required, task_required, record_type, bcc_email, allow_ip, password_complexity, plugins'. - ', lock_spec, workday_minutes, config, created, created_ip, created_by)'; - - $values = ' values ('.$mdb2->quote(trim($fields['name'])); - $values .= ', '.$mdb2->quote(trim($fields['currency'])); - $values .= ', '.$mdb2->quote($fields['decimal_mark']); - $values .= ', '.$mdb2->quote($fields['lang']); - $values .= ', '.$mdb2->quote($fields['date_format']); - $values .= ', '.$mdb2->quote($fields['time_format']); - $values .= ', '.(int)$fields['week_start']; - $values .= ', '.(int)$fields['tracking_mode']; - $values .= ', '.(int)$fields['project_required']; - $values .= ', '.(int)$fields['task_required']; - $values .= ', '.(int)$fields['record_type']; - $values .= ', '.$mdb2->quote($fields['bcc_email']); - $values .= ', '.$mdb2->quote($fields['allow_ip']); - $values .= ', '.$mdb2->quote($fields['password_complexity']); - $values .= ', '.$mdb2->quote($fields['plugins']); - $values .= ', '.$mdb2->quote($fields['lock_spec']); - $values .= ', '.(int)$fields['workday_minutes']; - $values .= ', '.$mdb2->quote($fields['config']); - $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); - $values .= ')'; - - $sql = 'insert into tt_groups '.$columns.$values; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; - - $group_id = $mdb2->lastInsertID('tt_groups', 'id'); - - // Update org_id with group_id. - // NOTE: Both export and import need an additional effort to properly operate on subgroups. - // Currently we are importing one group only, which becomes a top level group. - $sql = "update tt_groups set org_id = $group_id where org_id is NULL and id = $group_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; - - return $group_id; - } - - // insertMonthlyQuota - a helper function to insert a monthly quota. - private function insertMonthlyQuota($group_id, $year, $month, $minutes) { - $mdb2 = getConnection(); - $sql = "INSERT INTO tt_monthly_quotas (group_id, year, month, minutes) values ($group_id, $year, $month, $minutes)"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } -} diff --git a/WEB-INF/lib/ttOrgExportHelper.class.php b/WEB-INF/lib/ttOrgExportHelper.class.php index 719c486b5..2dd54f1b3 100644 --- a/WEB-INF/lib/ttOrgExportHelper.class.php +++ b/WEB-INF/lib/ttOrgExportHelper.class.php @@ -30,9 +30,8 @@ import('ttTimeHelper'); import('ttGroupExportHelper'); -// ttOrgExportHelper - this class is a future replacement for ttExportHelper. -// Currently, it is work in progress. -// When done, it should handle export of organizations containing multiple groups. +// ttOrgExportHelper handles export of organizations consisting of multiple groups +// into XML file for import (migrating) to another server. class ttOrgExportHelper { var $fileName = null; // Name of file with data. diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 96ac5708c..3afe26948 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -32,6 +32,7 @@ import('ttProjectHelper'); import('ttClientHelper'); import('ttInvoiceHelper'); +import('ttTimeHelper'); import('ttCustomFieldHelper'); import('ttExpenseHelper'); import('ttFavReportHelper'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e6154271f..06e093932 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.14.4431 | Copyright © Anuko | +  Anuko Time Tracker 1.18.14.4432 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/export.php b/export.php index f278b7c96..2206def2d 100644 --- a/export.php +++ b/export.php @@ -27,7 +27,6 @@ // +----------------------------------------------------------------------+ require_once('initialize.php'); -import('ttExportHelper'); import('ttOrgExportHelper'); import('form.Form'); @@ -57,11 +56,7 @@ $mime_type = 'application/x-bzip2'; } -// if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { - $exportHelper = new ttOrgExportHelper(); -// } else { -// $exportHelper = new ttExportHelper(); -// } + $exportHelper = new ttOrgExportHelper(); if ($exportHelper->createDataFile($compress)) { header('Pragma: public'); // This is needed for IE8 to download files over https. header('Content-Type: '.$mime_type); diff --git a/import.php b/import.php index 78630866b..938fdb3dd 100644 --- a/import.php +++ b/import.php @@ -27,7 +27,6 @@ // +----------------------------------------------------------------------+ require_once('initialize.php'); -import('ttImportHelper'); import('ttOrgImportHelper'); import('form.Form'); @@ -43,12 +42,8 @@ $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.import'))); if ($request->isPost()) { -// if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { - $import = new ttOrgImportHelper($err); -// } else { -// $import = new ttImportHelper($err); -// } - $import->importXml(); + $importHelper = new ttOrgImportHelper($err); + $importHelper->importXml(); if ($err->no()) $msg->add($i18n->get('form.import.success')); } // isPost From 8492dc052ad85039e0bbe11c7c3e1b8554907f64 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 16 Nov 2018 18:54:40 +0000 Subject: [PATCH 0350/1848] Some refactoring for subgroup support. --- WEB-INF/lib/ttAdmin.class.php | 2 +- WEB-INF/lib/ttGroupHelper.class.php | 19 --------- WEB-INF/lib/ttOrgHelper.class.php | 65 +++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- admin_groups.php | 4 +- login.php | 4 +- mobile/login.php | 4 +- 7 files changed, 73 insertions(+), 27 deletions(-) create mode 100644 WEB-INF/lib/ttOrgHelper.class.php diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index 23d8480d7..ef55ae50b 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -176,7 +176,7 @@ function markGroupDeleted($group_id) { // // 1) Users may mark some of them deleted during their work. // If we mark all of them deleted here, we can't recover nicely - // as we'll lose track of what was deleted by user. + // as we'll lose track of what was accidentally deleted by user. // // 2) DB maintenance script (Clean up DB from inactive groups) should // get rid of these items permanently eventually. diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 128650c62..6ddffaa8c 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -30,25 +30,6 @@ // This is a planned replacement for ttTeamHelper as we move forward with subgroups. class ttGroupHelper { - // The getTopGroups function returns an array of all active top groups on the server. - static function getTopGroups() { - $result = array(); - $mdb2 = getConnection(); - - $sql = "select id, name, created, lang from tt_groups". - " where status = 1 and org_id = id order by id desc"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $val['date'] = substr($val['created'], 0, 10); // Strip the time. - $result[] = $val; - } - return $result; - } - return false; - } - // The getGroupName function returns group name. static function getGroupName($group_id) { $mdb2 = getConnection(); diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php new file mode 100644 index 000000000..2cf045060 --- /dev/null +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -0,0 +1,65 @@ +query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $val['date'] = substr($val['created'], 0, 10); // Strip the time. + $result[] = $val; + } + return $result; + } + return false; + } + + // The getName function returns organization name (which is a name of its top group). + static function getName($org_id) { + $mdb2 = getConnection(); + + $sql = "select name from tt_groups where id = $org_id and (status = 1 or status = 0) and parent_id is NULL"; + $res = $mdb2->query($sql); + + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + return $val['name']; + } + return false; + } +} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 06e093932..8529b53cd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.14.4432 | Copyright © Anuko | +  Anuko Time Tracker 1.18.14.4433 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_groups.php b/admin_groups.php index 78e083ca5..ae66d1501 100644 --- a/admin_groups.php +++ b/admin_groups.php @@ -27,7 +27,7 @@ // +----------------------------------------------------------------------+ require_once('initialize.php'); -import('ttGroupHelper'); +import('ttOrgHelper'); // Access checks. if (!ttAccessAllowed('administer_site')) { @@ -36,7 +36,7 @@ } // End of access checks. -$smarty->assign('groups', ttGroupHelper::getTopGroups()); +$smarty->assign('groups', ttOrgHelper::getOrgs()); $smarty->assign('title', $i18n->get('title.groups')); $smarty->assign('content_page_name', 'admin_groups.tpl'); $smarty->display('index.tpl'); diff --git a/login.php b/login.php index 3bfed9a4d..e7254152c 100644 --- a/login.php +++ b/login.php @@ -28,7 +28,7 @@ require_once('initialize.php'); import('form.Form'); -import('ttGroupHelper'); +import('ttOrgHelper'); import('ttUser'); $cl_login = $request->getParameter('login'); @@ -75,7 +75,7 @@ } } // isPost -if(!isTrue(MULTITEAM_MODE) && !ttGroupHelper::getTopGroups()) +if(!isTrue(MULTITEAM_MODE) && !ttOrgHelper::getOrgs()) $err->add($i18n->get('error.no_groups')); // Determine whether to show login hint. It is currently used only for Windows LDAP authentication. diff --git a/mobile/login.php b/mobile/login.php index d094dfbf1..243aa5781 100644 --- a/mobile/login.php +++ b/mobile/login.php @@ -28,7 +28,7 @@ require_once('../initialize.php'); import('form.Form'); -import('ttGroupHelper'); +import('ttOrgHelper'); import('ttUser'); if ($request->isPost()) { @@ -80,7 +80,7 @@ } } // isPost -if(!isTrue(MULTITEAM_MODE) && !ttGroupHelper::getTopGroups()) +if(!isTrue(MULTITEAM_MODE) && !ttOrgHelper::getOrgs()) $err->add($i18n->get('error.no_groups')); // Determine whether to show login hint. It is currently used only for Windows LDAP authentication. From 3adb3c8c419ca1a01edac5fa62d5f88898415bfa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 16 Nov 2018 21:18:43 +0000 Subject: [PATCH 0351/1848] More progress with db maintenance code to support subgroups. --- WEB-INF/lib/ttOrgHelper.class.php | 20 ++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 5 +++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index 2cf045060..d93e25916 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -62,4 +62,24 @@ static function getName($org_id) { } return false; } + + // The getInactiveOrgs is a maintenance function that returns an array of inactive organization ids (max 5 for now). + static function getInactiveOrgs() { + $inactive_orgs = array(); + $mdb2 = getConnection(); + + // Determine inactive organizations by querying the database for max access timestamp for its users. + $cutoff_timestamp = $mdb2->quote(date('Y-m-d', strtotime('-1 year'))); + $sql = "select org_id from". + " (select max(accessed) as last_access, org_id from tt_users group by org_id order by last_access, org_id) as t". + " where last_access is null or last_access < $cutoff_timestamp limit 5"; // Max 5 orgs at a time for now... + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $inactive_orgs[] = $val['org_id']; + } + return $inactive_orgs; + } + return false; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8529b53cd..626610856 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.14.4433 | Copyright © Anuko | +  Anuko Time Tracker 1.18.14.4434 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index f81e31f7e..f02e90215 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -32,6 +32,7 @@ import('ttUserHelper'); import('ttTaskHelper'); import('ttRoleHelper'); +import('ttOrgHelper'); // setChange - executes an sql statement. TODO: rename this function to something better. // Better yet, redo the entire thing and make an installer. @@ -1004,13 +1005,13 @@ function setChange($sql) { if ($_POST["cleanup"]) { $mdb2 = getConnection(); - $inactive_groups = ttTeamHelper::getInactiveGroups(); + $inactive_groups = ttOrgHelper::getInactiveOrgs(); $count = count($inactive_groups); print "$count inactive groups found...
\n"; for ($i = 0; $i < $count; $i++) { print " deleting group ".$inactive_groups[$i]."
\n"; - $res = ttTeamHelper::delete($inactive_groups[$i]); + $res = ttTeamHelper::delete($inactive_groups[$i]); // TODO: rewrite this to delete subgroups, too. } setChange("OPTIMIZE TABLE tt_client_project_binds"); From 32173f5d1d4c523d9f3223489651049cafad9a5e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 11:29:56 +0000 Subject: [PATCH 0352/1848] Removed no longer used maintenance code. --- WEB-INF/lib/ttOrgHelper.class.php | 9 +++++ WEB-INF/lib/ttTeamHelper.class.php | 60 ------------------------------ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 10 insertions(+), 61 deletions(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index d93e25916..4a322f07d 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -82,4 +82,13 @@ static function getInactiveOrgs() { } return false; } + + // deleteOrg deletes data for the entire organization from database permanently. + static function deleteOrg() { + return false; // Work in progress, currently not implemented. + + // We shall do it in a straightforward way by a delete operation from all tables by org_id. + // However, at this time not all tables have org_id. + // So, we need to add the field as we write code here. + } } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 8b9d7ed66..40da2720b 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -659,66 +659,6 @@ static function getMonthlyQuotas($group_id) { return false; } - // The getInactiveGroups is a maintenance function that returns an array of inactive group ids (max 100). - static function getInactiveGroups() { - $inactive_groups = array(); - $mdb2 = getConnection(); - - // Get all group ids for groups created or modified more than 1 year ago. - $ts = $mdb2->quote(date('Y-m-d', strtotime('-1 year'))); - $sql = "select id from tt_groups where created < $ts and (modified is null or modified < $ts) order by id"; - $res = $mdb2->query($sql); - - $count = 0; - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $group_id = $val['id']; - if (ttTeamHelper::isGroupActive($group_id) == false) { - $count++; - $inactive_groups[] = $group_id; - // Limit the array size for perfomance by allowing this operation on small chunks only. - if ($count >= 100) break; - } - } - return $inactive_groups; - } - return false; - } - - // The isGroupActive determines if a group is using Time Tracker or abandoned it. - static function isGroupActive($group_id) { - $mdb2 = getConnection(); - - $count = 0; - $ts = date('Y-m-d', strtotime('-2 years')); - $sql = "select count(*) as cnt from tt_log where group_id = $group_id and created > '$ts'"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - if ($val = $res->fetchRow()) { - $count = $val['cnt']; - } - } - - if ($count == 0) - return false; // No time entries for the last 2 years. - - if ($count <= 5) { - // We will consider a group inactive if it has 5 or less time entries made more than 1 year ago. - $count_last_year = 0; - $ts = date('Y-m-d', strtotime('-1 year')); - $sql = "select count(*) as cnt from tt_log where group_id = $group_id and created > '$ts'"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - if ($val = $res->fetchRow()) { - $count_last_year = $val['cnt']; - } - if ($count_last_year == 0) - return false; // No time entries for the last year and only a few entries before that. - } - } - return true; - } - // The delete function permanently deletes all data for a group. static function delete($group_id) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 626610856..ab54bf610 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.14.4434 | Copyright © Anuko | +  Anuko Time Tracker 1.18.14.4435 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 5db12e31e86ebd4cb4be29851c07139edcca5ac4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 12:04:20 +0000 Subject: [PATCH 0353/1848] Introduced org_id in tt_monthly_quotas table. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 3 ++- plugins/MonthlyQuota.class.php | 16 ++++++++-------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ab54bf610..a89ed9b30 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.14.4435 | Copyright © Anuko | +  Anuko Time Tracker 1.18.15.4436 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index f02e90215..0c26a4578 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11814"]) { + if ($_POST["convert11797to11815"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -997,6 +997,9 @@ function setChange($sql) { setChange("ALTER TABLE `tt_invoices` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); setChange("ALTER TABLE `tt_clients` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.14', modified = now() where param_name = 'version_db' and param_value = '1.18.13'"); + setChange("ALTER TABLE `tt_monthly_quotas` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_monthly_quotas` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.14') set org_id = group_id where org_id is null"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.15', modified = now() where param_name = 'version_db' and param_value = '1.18.14'"); // TODO: this does not work as we just introduced group_id and it is NULL. Same for tt_project_task_binds. Improve. // setChange("UPDATE `tt_user_project_binds` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.12') set org_id = group_id where org_id is null"); @@ -1045,7 +1048,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.14) + Create database structure (v1.18.15)
(applies only to new installations, do not execute when updating)
@@ -1090,8 +1093,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.14)Update database structure (v1.17.97 to v1.18.15)
diff --git a/mysql.sql b/mysql.sql index 14a8aa0f9..3652c5288 100644 --- a/mysql.sql +++ b/mysql.sql @@ -449,6 +449,7 @@ CREATE TABLE `tt_predefined_expenses` ( # CREATE TABLE `tt_monthly_quotas` ( `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL # organization id `year` smallint(5) UNSIGNED NOT NULL, # quota year `month` tinyint(3) UNSIGNED NOT NULL, # quota month `minutes` int(11) default NULL, # quota in minutes in specified month and year @@ -469,4 +470,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.14', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.15', now()); # TODO: change when structure changes. diff --git a/plugins/MonthlyQuota.class.php b/plugins/MonthlyQuota.class.php index 5a4e70798..6a047badd 100644 --- a/plugins/MonthlyQuota.class.php +++ b/plugins/MonthlyQuota.class.php @@ -33,20 +33,22 @@ class MonthlyQuota { var $db; // Database connection. var $group_id; // Group id. + var $org_id; // Organization id. function __construct() { $this->db = getConnection(); global $user; - $this->group_id = $user->group_id; + $this->group_id = $user->getActiveGroup(); + $this->org_id = $user->org_id; } // update - deletes a quota, then inserts a new one. public function update($year, $month, $minutes) { - $group_id = $this->group_id; - $deleteSql = "DELETE FROM tt_monthly_quotas WHERE year = $year AND month = $month AND group_id = $group_id"; + $deleteSql = "DELETE FROM tt_monthly_quotas WHERE year = $year AND month = $month AND group_id = $this->group_id"; $this->db->exec($deleteSql); if ($minutes){ - $insertSql = "INSERT INTO tt_monthly_quotas (group_id, year, month, minutes) values ($group_id, $year, $month, $minutes)"; + $insertSql = "INSERT INTO tt_monthly_quotas (group_id, org_id, year, month, minutes)". + " values ($this->group_id, $this->org_id, $year, $month, $minutes)"; $affected = $this->db->exec($insertSql); return (!is_a($affected, 'PEAR_Error')); } @@ -64,8 +66,7 @@ public function get($year, $month = null) { // getSingle - obtains a quota for a single month. private function getSingle($year, $month) { - $group_id = $this->group_id; - $sql = "SELECT minutes FROM tt_monthly_quotas WHERE year = $year AND month = $month AND group_id = $group_id"; + $sql = "SELECT minutes FROM tt_monthly_quotas WHERE year = $year AND month = $month AND group_id = $this->group_id"; $reader = $this->db->query($sql); if (is_a($reader, 'PEAR_Error')) { return false; @@ -83,8 +84,7 @@ private function getSingle($year, $month) { // getMany - returns an array of quotas for a given year for group. private function getMany($year){ - $group_id = $this->group_id; - $sql = "SELECT month, minutes FROM tt_monthly_quotas WHERE year = $year AND group_id = $group_id"; + $sql = "SELECT month, minutes FROM tt_monthly_quotas WHERE year = $year AND group_id = $this->group_id"; $result = array(); $res = $this->db->query($sql); if (is_a($res, 'PEAR_Error')) { From 871d0e2a62747b03609afc04e0ed84cfb0b1d776 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 12:45:02 +0000 Subject: [PATCH 0354/1848] Fixed db maintenance code to delete monthly qoutas. --- WEB-INF/lib/ttOrgHelper.class.php | 12 +++++++++--- WEB-INF/lib/ttTeamHelper.class.php | 5 +++++ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index 4a322f07d..81bfbcf70 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -84,11 +84,17 @@ static function getInactiveOrgs() { } // deleteOrg deletes data for the entire organization from database permanently. - static function deleteOrg() { - return false; // Work in progress, currently not implemented. - + // Work in progress, currently not fully implemented. + static function deleteOrg($org_id) { // We shall do it in a straightforward way by a delete operation from all tables by org_id. // However, at this time not all tables have org_id. // So, we need to add the field as we write code here. + + // Delete monthly quotas. + $sql = "delete from tt_monthly_quotas where org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + return true; // Work in progress, currently not fully implemented. } } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 40da2720b..2198c0a85 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -703,6 +703,11 @@ static function delete($group_id) { $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; + // Delete monthly quotas. + $sql = "delete from tt_monthly_quotas where group_id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + // Delete group. $sql = "delete from tt_groups where id = $group_id"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a89ed9b30..4239f5132 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.15.4436 | Copyright © Anuko | +  Anuko Time Tracker 1.18.15.4437 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 208b036ea536d9d0e96e008c524a52fa3626dcdb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 12:56:15 +0000 Subject: [PATCH 0355/1848] Fixed mysql.sql - broken at 2nd commit earlier. --- WEB-INF/templates/footer.tpl | 2 +- mysql.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4239f5132..4923429a5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.15.4437 | Copyright © Anuko | +  Anuko Time Tracker 1.18.15.4438 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mysql.sql b/mysql.sql index 3652c5288..14fa2aaba 100644 --- a/mysql.sql +++ b/mysql.sql @@ -449,7 +449,7 @@ CREATE TABLE `tt_predefined_expenses` ( # CREATE TABLE `tt_monthly_quotas` ( `group_id` int(11) NOT NULL, # group id - `org_id` int(11) default NULL # organization id + `org_id` int(11) default NULL, # organization id `year` smallint(5) UNSIGNED NOT NULL, # quota year `month` tinyint(3) UNSIGNED NOT NULL, # quota month `minutes` int(11) default NULL, # quota in minutes in specified month and year From b50c69326fc036816418d39d04ff58062421644d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 13:33:04 +0000 Subject: [PATCH 0356/1848] Introduced org_id in tt_predefined_expenses table. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4923429a5..a7e71cff2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.15.4438 | Copyright © Anuko | +  Anuko Time Tracker 1.18.16.4439 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 0c26a4578..23eac7308 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11815"]) { + if ($_POST["convert11797to11816"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1000,6 +1000,8 @@ function setChange($sql) { setChange("ALTER TABLE `tt_monthly_quotas` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_monthly_quotas` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.14') set org_id = group_id where org_id is null"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.15', modified = now() where param_name = 'version_db' and param_value = '1.18.14'"); + setChange("ALTER TABLE `tt_predefined_expenses` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.16', modified = now() where param_name = 'version_db' and param_value = '1.18.15'"); // TODO: this does not work as we just introduced group_id and it is NULL. Same for tt_project_task_binds. Improve. // setChange("UPDATE `tt_user_project_binds` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.12') set org_id = group_id where org_id is null"); @@ -1048,7 +1050,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.15) + Create database structure (v1.18.16)
(applies only to new installations, do not execute when updating)
@@ -1093,8 +1095,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.15)Update database structure (v1.17.97 to v1.18.16)
diff --git a/mysql.sql b/mysql.sql index 14fa2aaba..9a6030c10 100644 --- a/mysql.sql +++ b/mysql.sql @@ -437,6 +437,7 @@ create index invoice_idx on tt_expense_items(invoice_id); CREATE TABLE `tt_predefined_expenses` ( `id` int(11) NOT NULL auto_increment, # predefined expense id `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id `name` varchar(255) NOT NULL, # predefined expense name, such as mileage `cost` decimal(10,2) default '0.00', # cost for one unit PRIMARY KEY (`id`) @@ -470,4 +471,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.15', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.16', now()); # TODO: change when structure changes. From c13d7023d283bda30121b8c9be56f982feeed89c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 15:40:55 +0000 Subject: [PATCH 0357/1848] Added predefined expenses to export-import. --- WEB-INF/lib/ttGroupExportHelper.class.php | 31 +++++++++++++++ WEB-INF/lib/ttOrgImportHelper.class.php | 47 +++++++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 4e6daad26..0e4777a2c 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -174,6 +174,24 @@ function getClients() { return false; } + // getPredefinedExpenses - obtains all predefined expenses for group. + function getPredefinedExpenses() { + global $user; + $mdb2 = getConnection(); + + $result = array(); + $sql = "select * from tt_predefined_expenses where group_id = $this->group_id"; // TODO: add " and org_id = $user->org_id" when possible. + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + // writeData writes group data into file. function writeData() { @@ -467,6 +485,19 @@ function writeData() { unset($expense_items); unset($expense_item_part); + // Write predefined expenses. + $predefined_expenses = $this->getPredefinedExpenses(); + fwrite($this->file, $this->indentation." \n"); + foreach ($predefined_expenses as $predefined_expense) { + $predefined_expense_part = $this->indentation.' '."file, $predefined_expense_part); + } + fwrite($this->file, $this->indentation." \n"); + unset($predefined_expenses); + unset($predefined_expense_part); + // Write monthly quotas. $quotas = ttTeamHelper::getMonthlyQuotas($this->group_id); fwrite($this->file, $this->indentation." \n"); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 3afe26948..9f5dd7884 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -431,12 +431,24 @@ function startElement($parser, $name, $attrs) { return; } + if ($name == 'PREDEFINED_EXPENSE') { + if (!$this->insertPredefinedExpense(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'name' => $attrs['NAME'], + 'cost' => $attrs['COST']))) { + $this->errors->add($i18n->get('error.db')); + } + return; + } + if ($name == 'MONTHLY_QUOTA') { - if (!$this->insertMonthlyQuota($this->current_group_id, - // 'org_id' => $this->org_id, TODO: add this when org_id field is added to the table. - $attrs['YEAR'], - $attrs['MONTH'], - $attrs['MINUTES'])) { + if (!$this->insertMonthlyQuota(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'year' => $attrs['YEAR'], + 'month' => $attrs['MONTH'], + 'minutes' => $attrs['MINUTES']))) { $this->errors->add($i18n->get('error.db')); } return; @@ -640,9 +652,30 @@ private function createGroup($fields) { } // insertMonthlyQuota - a helper function to insert a monthly quota. - private function insertMonthlyQuota($group_id, $year, $month, $minutes) { + private function insertMonthlyQuota($fields) { + $mdb2 = getConnection(); + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $year = (int) $fields['year']; + $month = (int) $fields['month']; + $minutes = (int) $fields['minutes']; + + $sql = "INSERT INTO tt_monthly_quotas (group_id, org_id, year, month, minutes)". + " values ($group_id, $org_id, $year, $month, $minutes)"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // insertPredefinedExpense - a helper function to insert a predefined expense. + private function insertPredefinedExpense($fields) { $mdb2 = getConnection(); - $sql = "INSERT INTO tt_monthly_quotas (group_id, year, month, minutes) values ($group_id, $year, $month, $minutes)"; + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $name = $mdb2->quote($fields['name']); + $cost = $mdb2->quote($fields['cost']); + + $sql = "INSERT INTO tt_predefined_expenses (group_id, org_id, name, cost)". + " values ($group_id, $org_id, $name, $cost)"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a7e71cff2..60ca1c166 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.16.4439 | Copyright © Anuko | +  Anuko Time Tracker 1.18.16.4440 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 07ee49d8208cc8308a167487f010e4b919555e03 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 16:10:00 +0000 Subject: [PATCH 0358/1848] A bit more refactoring towards subgroup support. --- WEB-INF/lib/ttPredefinedExpenseHelper.class.php | 12 +++++++----- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + predefined_expense_add.php | 1 - predefined_expense_edit.php | 1 - 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php index 2de4dfad3..16826a9d7 100644 --- a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php +++ b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php @@ -73,14 +73,15 @@ static function insert($fields) $mdb2 = getConnection(); - $group_id = (int) $fields['group_id']; + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; $name = $fields['name']; $cost = $fields['cost']; if ('.' != $user->decimal_mark) $cost = str_replace($user->decimal_mark, '.', $cost); - $sql = "insert into tt_predefined_expenses (group_id, name, cost) - values ($group_id, ".$mdb2->quote($name).", ".$mdb2->quote($cost).")"; + $sql = "insert into tt_predefined_expenses (group_id, org_id, name, cost)". + " values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($cost).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -95,15 +96,16 @@ static function update($fields) $mdb2 = getConnection(); + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; $predefined_expense_id = (int) $fields['id']; - $group_id = (int) $fields['group_id']; $name = $fields['name']; $cost = $fields['cost']; if ('.' != $user->decimal_mark) $cost = str_replace($user->decimal_mark, '.', $cost); $sql = "update tt_predefined_expenses set name = ".$mdb2->quote($name).", cost = ".$mdb2->quote($cost). - " where id = $predefined_expense_id and group_id = $group_id"; + " where id = $predefined_expense_id and group_id = $group_id"; // TODO: add org_id when possible. $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 60ca1c166..f5c805742 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.16.4440 | Copyright © Anuko | +  Anuko Time Tracker 1.18.16.4441 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 23eac7308..8b7e8c5e1 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1002,6 +1002,7 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.18.15', modified = now() where param_name = 'version_db' and param_value = '1.18.14'"); setChange("ALTER TABLE `tt_predefined_expenses` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.16', modified = now() where param_name = 'version_db' and param_value = '1.18.15'"); + setChange("UPDATE `tt_predefined_expenses` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.16') set org_id = group_id where org_id is null"); // TODO: this does not work as we just introduced group_id and it is NULL. Same for tt_project_task_binds. Improve. // setChange("UPDATE `tt_user_project_binds` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.12') set org_id = group_id where org_id is null"); diff --git a/predefined_expense_add.php b/predefined_expense_add.php index e653192b8..0bff7e051 100644 --- a/predefined_expense_add.php +++ b/predefined_expense_add.php @@ -56,7 +56,6 @@ if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); if ($err->no()) { if (ttPredefinedExpenseHelper::insert(array( - 'group_id' => $user->group_id, 'name' => $cl_name, 'cost' => $cl_cost))) { header('Location: predefined_expenses.php'); diff --git a/predefined_expense_edit.php b/predefined_expense_edit.php index 9b3727bf1..ab2299c0a 100644 --- a/predefined_expense_edit.php +++ b/predefined_expense_edit.php @@ -64,7 +64,6 @@ if ($err->no()) { if (ttPredefinedExpenseHelper::update(array( 'id' => $predefined_expense_id, - 'group_id' => $user->group_id, 'name' => $cl_name, 'cost' => $cl_cost))) { header('Location: predefined_expenses.php'); From d906edf1ba6fe68dc39f811cbb6fd6b5e94d9d4c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 16:52:44 +0000 Subject: [PATCH 0359/1848] Fixed db cleanup script by including predefined expenses. --- WEB-INF/lib/ttOrgHelper.class.php | 5 +++++ WEB-INF/lib/ttTeamHelper.class.php | 5 +++++ WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index 81bfbcf70..369212391 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -90,6 +90,11 @@ static function deleteOrg($org_id) { // However, at this time not all tables have org_id. // So, we need to add the field as we write code here. + // Delete predefined expenses. + $sql = "delete from tt_predefined_expenses where org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + // Delete monthly quotas. $sql = "delete from tt_monthly_quotas where org_id = $org_id"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 2198c0a85..4203fdc61 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -703,6 +703,11 @@ static function delete($group_id) { $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; + // Delete predefined expenses. + $sql = "delete from tt_predefined_expenses where group_id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + // Delete monthly quotas. $sql = "delete from tt_monthly_quotas where group_id = $group_id"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f5c805742..232208f90 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.16.4441 | Copyright © Anuko | +  Anuko Time Tracker 1.18.16.4442 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 8b7e8c5e1..069016abe 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1031,6 +1031,7 @@ function setChange($sql) { setChange("OPTIMIZE TABLE tt_invoices"); setChange("OPTIMIZE TABLE tt_log"); setChange("OPTIMIZE TABLE tt_monthly_quotas"); + setChange("OPTIMIZE TABLE tt_predefined_expenses"); setChange("OPTIMIZE TABLE tt_project_task_binds"); setChange("OPTIMIZE TABLE tt_projects"); setChange("OPTIMIZE TABLE tt_tasks"); From 0f552019a1c58ff22df3e9f59b9efe22261931fa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 17:48:55 +0000 Subject: [PATCH 0360/1848] Introduced org_id in tt_expense_items table. --- WEB-INF/lib/ttPredefinedExpenseHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 ++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php index 16826a9d7..27a3a8332 100644 --- a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php +++ b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php @@ -105,7 +105,7 @@ static function update($fields) $cost = str_replace($user->decimal_mark, '.', $cost); $sql = "update tt_predefined_expenses set name = ".$mdb2->quote($name).", cost = ".$mdb2->quote($cost). - " where id = $predefined_expense_id and group_id = $group_id"; // TODO: add org_id when possible. + " where id = $predefined_expense_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 232208f90..091178955 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.16.4442 | Copyright © Anuko | +  Anuko Time Tracker 1.18.17.4443 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 069016abe..e8dc454bd 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11816"]) { + if ($_POST["convert11797to11817"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1003,6 +1003,8 @@ function setChange($sql) { setChange("ALTER TABLE `tt_predefined_expenses` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.16', modified = now() where param_name = 'version_db' and param_value = '1.18.15'"); setChange("UPDATE `tt_predefined_expenses` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.16') set org_id = group_id where org_id is null"); + setChange("ALTER TABLE `tt_expense_items` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.17', modified = now() where param_name = 'version_db' and param_value = '1.18.16'"); // TODO: this does not work as we just introduced group_id and it is NULL. Same for tt_project_task_binds. Improve. // setChange("UPDATE `tt_user_project_binds` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.12') set org_id = group_id where org_id is null"); @@ -1052,7 +1054,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.16) + Create database structure (v1.18.17)
(applies only to new installations, do not execute when updating)
@@ -1097,8 +1099,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.16)Update database structure (v1.17.97 to v1.18.17)
diff --git a/mysql.sql b/mysql.sql index 9a6030c10..5ffc79e43 100644 --- a/mysql.sql +++ b/mysql.sql @@ -405,6 +405,7 @@ CREATE TABLE `tt_expense_items` ( `date` date NOT NULL, # date the record is for `user_id` int(11) NOT NULL, # user id the expense item is reported by `group_id` int(11) default NULL, # group id + `org_id` int(11) default NULL, # organization id `client_id` int(11) default NULL, # client id `project_id` int(11) default NULL, # project id `name` text NOT NULL, # expense item name (what is an expense for) @@ -471,4 +472,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.16', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.17', now()); # TODO: change when structure changes. From 2352b1096ea3b8301f06d3e5b072022ae08a2f73 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 18:24:14 +0000 Subject: [PATCH 0361/1848] Started to populate org_id during import of expense items. --- WEB-INF/lib/ttOrgImportHelper.class.php | 30 +++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 9f5dd7884..6764ba53e 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -415,11 +415,11 @@ function startElement($parser, $name, $attrs) { if ($name == 'EXPENSE_ITEM') { // We get here when processing tags for the current group. - $expense_item_id = ttExpenseHelper::insert(array( + $expense_item_id = $this->insertExpense(array( 'date' => $attrs['DATE'], 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], 'group_id' => $this->current_group_id, - // 'org_id' => $this->org_id, TODO: add this when org_id field is added to the table. + 'org_id' => $this->org_id, 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], 'name' => $attrs['NAME'], @@ -679,4 +679,30 @@ private function insertPredefinedExpense($fields) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // insertExpense - a helper function to insert an expense item. + private function insertExpense($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $date = $fields['date']; + $user_id = (int) $fields['user_id']; + $client_id = $fields['client_id']; + $project_id = $fields['project_id']; + $name = $fields['name']; + $cost = str_replace(',', '.', $fields['cost']); + $invoice_id = $fields['invoice_id']; + $status = $fields['status']; + $paid = (int) $fields['paid']; + $created = ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); + + $sql = "insert into tt_expense_items". + " (date, user_id, group_id, org_id, client_id, project_id, name, cost, invoice_id, paid, created, created_ip, created_by, status)". + " values (".$mdb2->quote($date).", $user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($project_id). + ", ".$mdb2->quote($name).", ".$mdb2->quote($cost).", ".$mdb2->quote($invoice_id).", $paid $created, ".$mdb2->quote($status).")"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 091178955..58b036cad 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.17.4443 | Copyright © Anuko | +  Anuko Time Tracker 1.18.17.4444 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 1e49bbdab2c6d229a22ed10495b526ac703b0be8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 18:44:00 +0000 Subject: [PATCH 0362/1848] Started to populate org_id on creation of expense items. --- WEB-INF/lib/ttExpenseHelper.class.php | 28 ++++++++++----------------- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + expense_edit.php | 4 ++-- expenses.php | 4 ++-- mobile/expense_edit.php | 4 ++-- mobile/expenses.php | 4 ++-- 7 files changed, 20 insertions(+), 27 deletions(-) diff --git a/WEB-INF/lib/ttExpenseHelper.class.php b/WEB-INF/lib/ttExpenseHelper.class.php index 6d3128fd4..7c0d83ff3 100644 --- a/WEB-INF/lib/ttExpenseHelper.class.php +++ b/WEB-INF/lib/ttExpenseHelper.class.php @@ -34,9 +34,11 @@ static function insert($fields) global $user; $mdb2 = getConnection(); + $user_id = $user->getActiveUser(); + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; + $date = $fields['date']; - $user_id = (int) $fields['user_id']; - $group_id = (int) $fields['group_id']; $client_id = $fields['client_id']; $project_id = $fields['project_id']; $name = $fields['name']; @@ -46,15 +48,12 @@ static function insert($fields) $paid = (int) $fields['paid']; $created = ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$mdb2->quote($user->id); - $sql = "insert into tt_expense_items (date, user_id, group_id, client_id, project_id, name, cost, invoice_id, paid, created, created_ip, created_by, status) ". - "values (".$mdb2->quote($date).", $user_id, $group_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($project_id). + $sql = "insert into tt_expense_items". + " (date, user_id, group_id, org_id, client_id, project_id, name, cost, invoice_id, paid, created, created_ip, created_by, status)". + " values (".$mdb2->quote($date).", $user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($project_id). ", ".$mdb2->quote($name).", ".$mdb2->quote($cost).", ".$mdb2->quote($invoice_id).", $paid $created, ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - $id = $mdb2->lastInsertID('tt_expense_items', 'id'); - return $id; + return (!is_a($affected, 'PEAR_Error')); } // update - updates a record in tt_expense_items table. @@ -82,12 +81,8 @@ static function update($fields) ", project_id = ".$mdb2->quote($project_id).", name = ".$mdb2->quote($name). ", cost = ".$mdb2->quote($cost)."$paid_part $modified_part, invoice_id = ".$mdb2->quote($invoice_id). " WHERE id = $id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - return true; + return (!is_a($affected, 'PEAR_Error')); } // markDeleted - marks an item as deleted in tt_expense_items table. @@ -96,10 +91,7 @@ static function markDeleted($id, $user_id) { $sql = "update tt_expense_items set status = NULL where id = $id and user_id = $user_id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - return true; + return (!is_a($affected, 'PEAR_Error')); } // getTotalForDay - gets total expenses for a user for a specific date. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 58b036cad..0fa85daaf 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.17.4444 | Copyright © Anuko | +  Anuko Time Tracker 1.18.17.4445 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index e8dc454bd..437dac2e9 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1005,6 +1005,7 @@ function setChange($sql) { setChange("UPDATE `tt_predefined_expenses` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.16') set org_id = group_id where org_id is null"); setChange("ALTER TABLE `tt_expense_items` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.17', modified = now() where param_name = 'version_db' and param_value = '1.18.16'"); + setChange("UPDATE `tt_expense_items` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') set org_id = group_id where org_id is null"); // TODO: this does not work as we just introduced group_id and it is NULL. Same for tt_project_task_binds. Improve. // setChange("UPDATE `tt_user_project_binds` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.12') set org_id = group_id where org_id is null"); diff --git a/expense_edit.php b/expense_edit.php index 353f5ce53..0c7cee5cd 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -205,8 +205,8 @@ // Now, a new insert. if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'user_id'=>$user->getActiveUser(),'group_id'=>$user->getActiveGroup(), - 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { + if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'client_id'=>$cl_client, + 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); exit(); } else diff --git a/expenses.php b/expenses.php index fa45ad444..69d8ae72a 100644 --- a/expenses.php +++ b/expenses.php @@ -188,8 +188,8 @@ // Insert record. if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$cl_date,'user_id'=>$user->getActiveUser(),'group_id'=>$user->getActiveGroup(), - 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { + if (ttExpenseHelper::insert(array('date'=>$cl_date,'client_id'=>$cl_client, + 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { header('Location: expenses.php'); exit(); } else diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index 338e6c778..61edca261 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -200,8 +200,8 @@ // Now, a new insert. if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'user_id'=>$user->getActiveUser(),'group_id'=>$user->getActiveGroup(), - 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { + if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'client_id'=>$cl_client, + 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); exit(); } else diff --git a/mobile/expenses.php b/mobile/expenses.php index 25a1c6025..97232f70d 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -192,8 +192,8 @@ // Insert record. if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$cl_date,'user_id'=>$user->getActiveUser(),'group_id'=>$user->getActiveGroup(), - 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { + if (ttExpenseHelper::insert(array('date'=>$cl_date,'client_id'=>$cl_client, + 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { header('Location: expenses.php'); exit(); } else From 6bd6e0481ca4c22c47de758d53eef9db5e565e5c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 21:24:23 +0000 Subject: [PATCH 0363/1848] Populating tt_user_project_binds. --- WEB-INF/lib/ttOrgHelper.class.php | 5 +++++ WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 4 +--- mysql.sql | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index 369212391..c69fc7a7a 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -90,6 +90,11 @@ static function deleteOrg($org_id) { // However, at this time not all tables have org_id. // So, we need to add the field as we write code here. + // Delete expense items. + $sql = "delete from tt_expense_items where org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + // Delete predefined expenses. $sql = "delete from tt_predefined_expenses where org_id = $org_id"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0fa85daaf..433f5934b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.17.4445 | Copyright © Anuko | +  Anuko Time Tracker 1.18.17.4446 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 437dac2e9..eec023683 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1006,9 +1006,7 @@ function setChange($sql) { setChange("ALTER TABLE `tt_expense_items` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.17', modified = now() where param_name = 'version_db' and param_value = '1.18.16'"); setChange("UPDATE `tt_expense_items` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') set org_id = group_id where org_id is null"); - - // TODO: this does not work as we just introduced group_id and it is NULL. Same for tt_project_task_binds. Improve. - // setChange("UPDATE `tt_user_project_binds` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.12') set org_id = group_id where org_id is null"); + setChange("update `tt_user_project_binds` upb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_users` u on u.id = upb.user_id set upb.group_id = u.group_id, upb.org_id = u.org_id where upb.org_id is null"); } if ($_POST["cleanup"]) { diff --git a/mysql.sql b/mysql.sql index 5ffc79e43..5ee9ad4a3 100644 --- a/mysql.sql +++ b/mysql.sql @@ -384,7 +384,7 @@ CREATE TABLE `tt_custom_field_options` ( # This table supplements tt_log and contains custom field values for records. # CREATE TABLE `tt_custom_field_log` ( - `id` bigint NOT NULL auto_increment, # cutom field log id + `id` bigint NOT NULL auto_increment, # custom field log id `log_id` bigint NOT NULL, # id of a record in tt_log this record corresponds to `field_id` int(11) NOT NULL, # custom field id `option_id` int(11) default NULL, # Option id. Used for dropdown custom fields. From 280d6ea0ee096843551d7734b23377ec06d42e81 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 17 Nov 2018 22:38:52 +0000 Subject: [PATCH 0364/1848] Started to populate tt_project_task_binds with group_id and org_id. --- WEB-INF/lib/ttOrgImportHelper.class.php | 4 ++-- WEB-INF/lib/ttProjectHelper.class.php | 12 +++++----- WEB-INF/lib/ttTaskHelper.class.php | 29 ++++++++++++++----------- WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 6764ba53e..d95aabb46 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -204,8 +204,8 @@ function startElement($parser, $name, $attrs) { foreach ($tasks as $id) $mapped_tasks[] = $this->currentGroupTaskMap[$id]; - $project_id = ttProjectHelper::insert(array( - 'group_id' => $this->current_group_id, + $project_id = ttProjectHelper::insert(array( // TODO: continue refactoring, write a separate, simple function to import projects + 'group_id' => $this->current_group_id, // because ttProjectHelper::insert is complicated. 'org_id' => $this->org_id, 'name' => $attrs['NAME'], 'description' => $attrs['DESCRIPTION'], diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 47783d59d..240760df3 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -226,7 +226,8 @@ static function insert($fields) $all_tasks = ttTeamHelper::getAllTasks($group_id); foreach ($all_tasks as $task) { if(in_array($task['id'], $tasks)) { - $sql = "insert into tt_project_task_binds (project_id, task_id) values($last_id, ".$task['id'].")"; + $sql = "insert into tt_project_task_binds (project_id, task_id, group_id, org_id)". + " values($last_id, ".$task['id'].", $group_id, $org_id)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -240,7 +241,9 @@ static function insert($fields) static function update($fields) { global $user; $mdb2 = getConnection(); - + + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; $project_id = $fields['id']; // Project we are updating. $name = $fields['name']; // Project name. $description = $fields['description']; // Project description. @@ -271,8 +274,6 @@ static function update($fields) { while ($row = $res->fetchRow()) { $user_rate[$row['id']] = $row['rate']; } - $group_id = $user->getActiveGroup(); - $org_id = $user->org_id; foreach ($users_to_add as $id) { $sql = "insert into tt_user_project_binds (user_id, project_id, group_id, org_id, rate, status)". " values($id, $project_id, $group_id, $org_id, ".$user_rate[$id].", 1)"; @@ -308,7 +309,8 @@ static function update($fields) { return false; } foreach ($task_binds_to_add as $task_id) { - $sql = "insert into tt_project_task_binds (project_id, task_id) values($project_id, $task_id)"; + $sql = "insert into tt_project_task_binds (project_id, task_id, group_id, org_id)". + " values($project_id, $task_id, $group_id, $org_id)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttTaskHelper.class.php b/WEB-INF/lib/ttTaskHelper.class.php index b4644d513..2c0fbe1e1 100644 --- a/WEB-INF/lib/ttTaskHelper.class.php +++ b/WEB-INF/lib/ttTaskHelper.class.php @@ -157,12 +157,13 @@ static function insert($fields) if (is_array($projects)) { foreach ($projects as $p_id) { // Insert task binds into tt_project_task_binds table. - $sql = "insert into tt_project_task_binds (project_id, task_id) values($p_id, $last_id)"; + $sql = "insert into tt_project_task_binds (project_id, task_id, group_id, org_id)". + " values($p_id, $last_id, $group_id, $org_id)"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; + if (is_a($affected, 'PEAR_Error')) + return false; - // Add task bind to the tasks field of the tt_projects table. + // Add task bind to the tasks field of the tt_projects table. $sql = "select tasks from tt_projects where id = $p_id"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) @@ -171,16 +172,16 @@ static function insert($fields) $val = $res->fetchRow(); $task_ids = $val['tasks']; if ($task_ids) { - $task_ids .= ",$last_id"; - $task_ids = ttTaskHelper::sort($task_ids); - } else - $task_ids = $last_id; + $task_ids .= ",$last_id"; + $task_ids = ttTaskHelper::sort($task_ids); + } else + $task_ids = $last_id; $sql = "update tt_projects set tasks = ".$mdb2->quote($task_ids)." where id = $p_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - } + } } return $last_id; } @@ -189,9 +190,10 @@ static function insert($fields) static function update($fields) { global $user; - $mdb2 = getConnection(); + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; $task_id = (int)$fields['task_id']; $name = $fields['name']; $description = $fields['description']; @@ -199,7 +201,7 @@ static function update($fields) $projects = $fields['projects']; $sql = "update tt_tasks set name = ".$mdb2->quote($name).", description = ".$mdb2->quote($description). - ", status = $status where id = $task_id and group_id = $user->group_id"; + ", status = $status where id = $task_id and group_id = $group_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); @@ -211,7 +213,8 @@ static function update($fields) die($affected->getMessage()); if (count($projects) > 0) foreach ($projects as $p_id) { - $sql = "insert into tt_project_task_binds (project_id, task_id) values($p_id, $task_id)"; + $sql = "insert into tt_project_task_binds (project_id, task_id, group_id, org_id)". + " values($p_id, $task_id, $group_id, $org_id)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); @@ -221,7 +224,7 @@ static function update($fields) // We need to either delete or insert task id in all affected projects. // Get all not deleted projects for group. - $sql = "select id, tasks from tt_projects where group_id = $user->group_id and status is not NULL"; + $sql = "select id, tasks from tt_projects where group_id = $group_id and status is not NULL"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die($res->getMessage()); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 433f5934b..a01384ccc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.17.4446 | Copyright © Anuko | +  Anuko Time Tracker 1.18.17.4447 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 4dab570c0194d954b9b0a064c1d5249ffb19981d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 18 Nov 2018 16:19:35 +0000 Subject: [PATCH 0365/1848] Fixed export for project to task binds. --- WEB-INF/lib/ttGroupExportHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 0e4777a2c..0c56117e0 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -296,6 +296,7 @@ function writeData() { // Write projects. fwrite($this->file, $this->indentation." \n"); foreach ($projects as $project_item) { + $tasks_str = null; if($project_item['tasks']){ $tasks = explode(',', $project_item['tasks']); $tasks_mapped = array(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a01384ccc..22d4c5e10 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.17.4447 | Copyright © Anuko | +  Anuko Time Tracker 1.18.17.4448 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 61866da737a6cc06ae2c1e4ba766a0c46ab4fb8a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 18 Nov 2018 17:54:44 +0000 Subject: [PATCH 0366/1848] Populating group_id and org_id in tt_project_task_binds table. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 22d4c5e10..7eb704844 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.17.4448 | Copyright © Anuko | +  Anuko Time Tracker 1.18.17.4449 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index eec023683..ef895bdd3 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1007,6 +1007,7 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.18.17', modified = now() where param_name = 'version_db' and param_value = '1.18.16'"); setChange("UPDATE `tt_expense_items` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') set org_id = group_id where org_id is null"); setChange("update `tt_user_project_binds` upb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_users` u on u.id = upb.user_id set upb.group_id = u.group_id, upb.org_id = u.org_id where upb.org_id is null"); + setChange("update `tt_project_task_binds` ptb inner join tt_site_config sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_projects` p on p.id = ptb.project_id set ptb.group_id = p.group_id, ptb.org_id = p.org_id where ptb.org_id is null"); } if ($_POST["cleanup"]) { From 06b80cf38fc0268250fcca3b7270801b4991505f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 18 Nov 2018 18:14:03 +0000 Subject: [PATCH 0367/1848] Introduced an index in tt_project_task_binds to eliminate duplicates. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + mysql.sql | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7eb704844..f66ff9ba2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.17.4449 | Copyright © Anuko | +  Anuko Time Tracker 1.18.17.4450 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index ef895bdd3..e3561eddb 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1008,6 +1008,7 @@ function setChange($sql) { setChange("UPDATE `tt_expense_items` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') set org_id = group_id where org_id is null"); setChange("update `tt_user_project_binds` upb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_users` u on u.id = upb.user_id set upb.group_id = u.group_id, upb.org_id = u.org_id where upb.org_id is null"); setChange("update `tt_project_task_binds` ptb inner join tt_site_config sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_projects` p on p.id = ptb.project_id set ptb.group_id = p.group_id, ptb.org_id = p.org_id where ptb.org_id is null"); + setChange("create unique index project_task_idx on tt_project_task_binds(project_id, task_id)"); } if ($_POST["cleanup"]) { diff --git a/mysql.sql b/mysql.sql index 5ee9ad4a3..23dbb14ad 100644 --- a/mysql.sql +++ b/mysql.sql @@ -177,6 +177,7 @@ CREATE TABLE `tt_project_task_binds` ( # Indexes for tt_project_task_binds. create index project_idx on tt_project_task_binds(project_id); create index task_idx on tt_project_task_binds(task_id); +create unique index project_tax_idx on tt_project_task_binds(project_id, task_id); # @@ -472,4 +473,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.17', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.18', now()); # TODO: change when structure changes. From 8e10219e51dcb9c39d84fe792b6207227d12b46a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 18 Nov 2018 18:39:45 +0000 Subject: [PATCH 0368/1848] Version update. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f66ff9ba2..cf8c742be 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.17.4450 | Copyright © Anuko | +  Anuko Time Tracker 1.18.18.4451 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index e3561eddb..3dfcb9316 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11817"]) { + if ($_POST["convert11797to11818"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1009,6 +1009,7 @@ function setChange($sql) { setChange("update `tt_user_project_binds` upb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_users` u on u.id = upb.user_id set upb.group_id = u.group_id, upb.org_id = u.org_id where upb.org_id is null"); setChange("update `tt_project_task_binds` ptb inner join tt_site_config sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_projects` p on p.id = ptb.project_id set ptb.group_id = p.group_id, ptb.org_id = p.org_id where ptb.org_id is null"); setChange("create unique index project_task_idx on tt_project_task_binds(project_id, task_id)"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.18', modified = now() where param_name = 'version_db' and param_value = '1.18.17'"); } if ($_POST["cleanup"]) { @@ -1055,7 +1056,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.17) + Create database structure (v1.18.18)
(applies only to new installations, do not execute when updating)
@@ -1100,8 +1101,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.17)Update database structure (v1.17.97 to v1.18.18)
From b0e20fffa896966634ad3274225c317003331a04 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 18 Nov 2018 18:43:29 +0000 Subject: [PATCH 0369/1848] Fixed index name. --- mysql.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql.sql b/mysql.sql index 23dbb14ad..692a8d25c 100644 --- a/mysql.sql +++ b/mysql.sql @@ -177,7 +177,7 @@ CREATE TABLE `tt_project_task_binds` ( # Indexes for tt_project_task_binds. create index project_idx on tt_project_task_binds(project_id); create index task_idx on tt_project_task_binds(task_id); -create unique index project_tax_idx on tt_project_task_binds(project_id, task_id); +create unique index project_task_idx on tt_project_task_binds(project_id, task_id); # From c5742659a15a48bd5ddcba78d648a26cc6c520ee Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 18 Nov 2018 22:14:32 +0000 Subject: [PATCH 0370/1848] Refactored import a bit by writing a function to insert projects with binds. --- WEB-INF/lib/ttOrgImportHelper.class.php | 53 ++++++++++++++++++++++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index d95aabb46..4c57739b3 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -29,7 +29,6 @@ import('ttUserHelper'); import('ttRoleHelper'); import('ttTaskHelper'); -import('ttProjectHelper'); import('ttClientHelper'); import('ttInvoiceHelper'); import('ttTimeHelper'); @@ -200,12 +199,14 @@ function startElement($parser, $name, $attrs) { // We get here when processing tags for the current group. // Prepare a list of task ids. - $tasks = explode(',', $attrs['TASKS']); - foreach ($tasks as $id) - $mapped_tasks[] = $this->currentGroupTaskMap[$id]; + if ($attrs['TASKS']) { + $tasks = explode(',', $attrs['TASKS']); + foreach ($tasks as $id) + $mapped_tasks[] = $this->currentGroupTaskMap[$id]; + } - $project_id = ttProjectHelper::insert(array( // TODO: continue refactoring, write a separate, simple function to import projects - 'group_id' => $this->current_group_id, // because ttProjectHelper::insert is complicated. + $project_id = $this->insertProject(array( + 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, 'name' => $attrs['NAME'], 'description' => $attrs['DESCRIPTION'], @@ -705,4 +706,44 @@ private function insertExpense($fields) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // insertProject - a helper function to insert a project as well as project to task binds. + private function insertProject($fields) + { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + + $name = $fields['name']; + $description = $fields['description']; + $tasks = $fields['tasks']; + $comma_separated = implode(',', $tasks); // This is a comma-separated list of associated task ids. + $status = $fields['status']; + + $sql = "insert into tt_projects (group_id, org_id, name, description, tasks, status) + values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + $last_id = 0; + $sql = "select last_insert_id() as last_insert_id"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + $last_id = $val['last_insert_id']; + + // Insert binds into tt_project_task_binds table. + if (is_array($tasks)) { + foreach ($tasks as $task_id) { + $sql = "insert into tt_project_task_binds (project_id, task_id, group_id, org_id)". + " values($last_id, $task_id, $group_id, $org_id)"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + } + } + + return $last_id; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index cf8c742be..417439b12 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.18.4451 | Copyright © Anuko | +  Anuko Time Tracker 1.18.18.4453 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 3510da81df216bb117f197dc69366fc564902754 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 18 Nov 2018 22:30:56 +0000 Subject: [PATCH 0371/1848] Added group_id and org_id to tt_fav_reports table. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 4 +++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 417439b12..f7d31bb22 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.18.4453 | Copyright © Anuko | +  Anuko Time Tracker 1.18.19.4454 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 3dfcb9316..7dda42134 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11818"]) { + if ($_POST["convert11797to11819"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1010,6 +1010,9 @@ function setChange($sql) { setChange("update `tt_project_task_binds` ptb inner join tt_site_config sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_projects` p on p.id = ptb.project_id set ptb.group_id = p.group_id, ptb.org_id = p.org_id where ptb.org_id is null"); setChange("create unique index project_task_idx on tt_project_task_binds(project_id, task_id)"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.18', modified = now() where param_name = 'version_db' and param_value = '1.18.17'"); + setChange("ALTER TABLE `tt_fav_reports` ADD `group_id` int(11) default NULL AFTER `user_id`"); + setChange("ALTER TABLE `tt_fav_reports` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.19', modified = now() where param_name = 'version_db' and param_value = '1.18.18'"); } if ($_POST["cleanup"]) { @@ -1056,7 +1059,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.18) + Create database structure (v1.18.19)
(applies only to new installations, do not execute when updating)
@@ -1101,8 +1104,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.18)Update database structure (v1.17.97 to v1.18.19)
diff --git a/mysql.sql b/mysql.sql index 692a8d25c..d5dbe4100 100644 --- a/mysql.sql +++ b/mysql.sql @@ -254,6 +254,8 @@ CREATE TABLE `tt_fav_reports` ( `id` int(11) NOT NULL auto_increment, # favorite report id `name` varchar(200) NOT NULL, # favorite report name `user_id` int(11) NOT NULL, # user id favorite report belongs to + `group_id` int(11) default NULL, # group id + `org_id` int(11) default NULL, # organization id `report_spec` text default NULL, # future replacement field for all report settings `client_id` int(11) default NULL, # client id (if selected) `cf_1_option_id` int(11) default NULL, # custom field 1 option id (if selected) @@ -473,4 +475,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.18', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.19', now()); # TODO: change when structure changes. From f1025fe95f90cd8dc7fa3b3f75617e447ab33f2e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 09:05:24 +0000 Subject: [PATCH 0372/1848] Populated group_id and org_id in tt_fav_reports table. --- WEB-INF/lib/ttFavReportHelper.class.php | 21 ++++++++----- WEB-INF/lib/ttOrgImportHelper.class.php | 40 +++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + reports.php | 2 +- 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 305a4fc8c..ab9fa0e09 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -77,16 +77,21 @@ static function getReportByName($user_id, $report_name) { // insertReport - stores reports settings in database. static function insertReport($fields) { + global $user; $mdb2 = getConnection(); - $sql = "insert into tt_fav_reports (name, user_id, client_id, cf_1_option_id, project_id, task_id, - billable, invoice, paid_status, users, period, period_start, period_end, - show_client, show_invoice, show_paid, show_ip, - show_project, show_start, show_duration, show_cost, - show_task, show_end, show_note, show_custom_field_1, show_work_units, - group_by1, group_by2, group_by3, show_totals_only) - values(". - $mdb2->quote($fields['name']).", ".$fields['user_id'].", ". + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; + + $sql = "insert into tt_fav_reports". + " (name, user_id, group_id, org_id, client_id, cf_1_option_id, project_id, task_id,". + " billable, invoice, paid_status, users, period, period_start, period_end,". + " show_client, show_invoice, show_paid, show_ip,". + " show_project, show_start, show_duration, show_cost,". + " show_task, show_end, show_note, show_custom_field_1, show_work_units,". + " group_by1, group_by2, group_by3, show_totals_only)". + " values(". + $mdb2->quote($fields['name']).", ".$fields['user_id'].", $group_id, $org_id, ". $mdb2->quote($fields['client']).", ".$mdb2->quote($fields['option']).", ". $mdb2->quote($fields['project']).", ".$mdb2->quote($fields['task']).", ". $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['invoice']).", ". diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 4c57739b3..c57cc6405 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -462,9 +462,11 @@ function startElement($parser, $name, $attrs) { foreach ($arr as $v) $user_list .= (strlen($user_list) == 0 ? '' : ',').$this->currentGroupUserMap[$v]; } - $fav_report_id = ttFavReportHelper::insertReport(array( + if (!$this->insertFavReport(array( 'name' => $attrs['NAME'], 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, 'client' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], 'option' => $this->currentGroupCustomFieldOptionMap[$attrs['CF_1_OPTION_ID']], 'project' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], @@ -490,8 +492,9 @@ function startElement($parser, $name, $attrs) { 'group_by1' => $attrs['GROUP_BY1'], 'group_by2' => $attrs['GROUP_BY2'], 'group_by3' => $attrs['GROUP_BY3'], - 'chtotalsonly' => (int) $attrs['SHOW_TOTALS_ONLY'])); - if (!$fav_report_id) $this->errors->add($i18n->get('error.db')); + 'chtotalsonly' => (int) $attrs['SHOW_TOTALS_ONLY']))) { + $this->errors->add($i18n->get('error.db')); + } return; } } @@ -746,4 +749,35 @@ private function insertProject($fields) return $last_id; } + + // insertFavReport - inserts a favorite report in database. + private function insertFavReport($fields) { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + + $sql = "insert into tt_fav_reports". + " (name, user_id, group_id, org_id, client_id, cf_1_option_id, project_id, task_id,". + " billable, invoice, paid_status, users, period, period_start, period_end,". + " show_client, show_invoice, show_paid, show_ip,". + " show_project, show_start, show_duration, show_cost,". + " show_task, show_end, show_note, show_custom_field_1, show_work_units,". + " group_by1, group_by2, group_by3, show_totals_only)". + " values(". + $mdb2->quote($fields['name']).", ".$fields['user_id'].", $group_id, $org_id, ". + $mdb2->quote($fields['client']).", ".$mdb2->quote($fields['option']).", ". + $mdb2->quote($fields['project']).", ".$mdb2->quote($fields['task']).", ". + $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['invoice']).", ". + $mdb2->quote($fields['paid_status']).", ". + $mdb2->quote($fields['users']).", ".$mdb2->quote($fields['period']).", ". + $mdb2->quote($fields['from']).", ".$mdb2->quote($fields['to']).", ". + $fields['chclient'].", ".$fields['chinvoice'].", ".$fields['chpaid'].", ".$fields['chip'].", ". + $fields['chproject'].", ".$fields['chstart'].", ".$fields['chduration'].", ".$fields['chcost'].", ". + $fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ".$fields['chcf_1'].", ".$fields['chunits'].", ". + $mdb2->quote($fields['group_by1']).", ".$mdb2->quote($fields['group_by2']).", ". + $mdb2->quote($fields['group_by3']).", ".$fields['chtotalsonly'].")"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f7d31bb22..463340b76 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.19.4454 | Copyright © Anuko | +  Anuko Time Tracker 1.18.19.4455 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 7dda42134..0d8ea9a40 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1013,6 +1013,7 @@ function setChange($sql) { setChange("ALTER TABLE `tt_fav_reports` ADD `group_id` int(11) default NULL AFTER `user_id`"); setChange("ALTER TABLE `tt_fav_reports` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.19', modified = now() where param_name = 'version_db' and param_value = '1.18.18'"); + setChange("update `tt_fav_reports` fr inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.19') inner join `tt_users` u on u.id = fr.user_id set fr.group_id = u.group_id, fr.org_id = u.org_id where fr.org_id is null"); } if ($_POST["cleanup"]) { diff --git a/reports.php b/reports.php index 6a0687e60..efbf96421 100644 --- a/reports.php +++ b/reports.php @@ -298,7 +298,7 @@ if (!ttValidString($bean->getAttribute('new_fav_report'))) $err->add($i18n->get('error.field'), $i18n->get('form.reports.save_as_favorite')); if ($err->no()) { - $id = ttFavReportHelper::saveReport($user->id, $bean); + $id = ttFavReportHelper::saveReport($user->id, $bean); // TODO: review "on behalf" situations (both user and group), redesign if needed. if (!$id) $err->add($i18n->get('error.db')); if ($err->no()) { From 57babce3424b88837a797860b52b9546908d478f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 13:07:53 +0000 Subject: [PATCH 0373/1848] Introduced org_id in tt_cron table as part of subgroup support work. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 463340b76..397c66008 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.19.4455 | Copyright © Anuko | +  Anuko Time Tracker 1.18.20.4456 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 0d8ea9a40..6497dbbf7 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11819"]) { + if ($_POST["convert11797to11820"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1014,6 +1014,8 @@ function setChange($sql) { setChange("ALTER TABLE `tt_fav_reports` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.19', modified = now() where param_name = 'version_db' and param_value = '1.18.18'"); setChange("update `tt_fav_reports` fr inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.19') inner join `tt_users` u on u.id = fr.user_id set fr.group_id = u.group_id, fr.org_id = u.org_id where fr.org_id is null"); + setChange("ALTER TABLE `tt_cron` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.20', modified = now() where param_name = 'version_db' and param_value = '1.18.19'"); } if ($_POST["cleanup"]) { @@ -1060,7 +1062,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.19) + Create database structure (v1.18.20)
(applies only to new installations, do not execute when updating)
@@ -1105,8 +1107,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.19)Update database structure (v1.17.97 to v1.18.20)
diff --git a/mysql.sql b/mysql.sql index d5dbe4100..e3f0bd83c 100644 --- a/mysql.sql +++ b/mysql.sql @@ -296,6 +296,7 @@ CREATE TABLE `tt_fav_reports` ( CREATE TABLE `tt_cron` ( `id` int(11) NOT NULL auto_increment, # entry id `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id `cron_spec` varchar(255) NOT NULL, # cron specification, "0 1 * * *" for "daily at 01:00" `last` int(11) default NULL, # UNIX timestamp of when job was last run `next` int(11) default NULL, # UNIX timestamp of when to run next job @@ -475,4 +476,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.19', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.20', now()); # TODO: change when structure changes. From 118c3d9a6326a6b1ebc3c5a018047cec00ffbd62 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 13:32:15 +0000 Subject: [PATCH 0374/1848] Populating org_id in tt_cron table. --- WEB-INF/lib/ttNotificationHelper.class.php | 8 +++++--- WEB-INF/lib/ttTeamHelper.class.php | 5 +++++ WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttNotificationHelper.class.php b/WEB-INF/lib/ttNotificationHelper.class.php index af1bcd3c8..a4fa5e6dc 100644 --- a/WEB-INF/lib/ttNotificationHelper.class.php +++ b/WEB-INF/lib/ttNotificationHelper.class.php @@ -65,9 +65,11 @@ static function delete($id) { // insert function inserts a new notification into database. static function insert($fields) { + global $user; $mdb2 = getConnection(); - $group_id = (int) $fields['group_id']; + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; $cron_spec = $fields['cron_spec']; $next = (int) $fields['next']; $report_id = (int) $fields['report_id']; @@ -77,8 +79,8 @@ static function insert($fields) $report_condition = $fields['report_condition']; $status = $fields['status']; - $sql = "insert into tt_cron (group_id, cron_spec, next, report_id, email, cc, subject, report_condition, status) - values ($group_id, ".$mdb2->quote($cron_spec).", $next, $report_id, ".$mdb2->quote($email).", ".$mdb2->quote($cc).", ".$mdb2->quote($subject).", ".$mdb2->quote($report_condition).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_cron (group_id, org_id, cron_spec, next, report_id, email, cc, subject, report_condition, status)". + " values ($group_id, $org_id, ".$mdb2->quote($cron_spec).", $next, $report_id, ".$mdb2->quote($email).", ".$mdb2->quote($cc).", ".$mdb2->quote($subject).", ".$mdb2->quote($report_condition).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 4203fdc61..b861e669e 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -703,6 +703,11 @@ static function delete($group_id) { $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; + // Delete cron entries. + $sql = "delete from tt_cron where group_id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + // Delete predefined expenses. $sql = "delete from tt_predefined_expenses where group_id = $group_id"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 397c66008..a63402887 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.20.4456 | Copyright © Anuko | +  Anuko Time Tracker 1.18.20.4457 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 6497dbbf7..e31783a7e 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1016,6 +1016,7 @@ function setChange($sql) { setChange("update `tt_fav_reports` fr inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.19') inner join `tt_users` u on u.id = fr.user_id set fr.group_id = u.group_id, fr.org_id = u.org_id where fr.org_id is null"); setChange("ALTER TABLE `tt_cron` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.20', modified = now() where param_name = 'version_db' and param_value = '1.18.19'"); + setChange("UPDATE `tt_cron` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.20') set org_id = group_id where org_id is null"); } if ($_POST["cleanup"]) { From e8612865ad9644fad85cd0d6fef32ea07c8acdf9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 14:50:44 +0000 Subject: [PATCH 0375/1848] Added notifications to export. --- WEB-INF/lib/ttGroupExportHelper.class.php | 72 ++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 0c56117e0..cf64cede7 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -49,6 +49,7 @@ class ttGroupExportHelper { var $logMap = array(); var $customFieldMap = array(); var $customFieldOptionMap = array(); + var $favReportMap = array(); // Constructor. function __construct($group_id, $file, $indentation) { @@ -102,6 +103,9 @@ function getUsers() { return false; } + // TODO: write a generic (private?) get function for exclusive use in this class, that obtains + // all fields from a given table. + // getRoles - obtains all roles defined for group. function getRoles() { global $user; @@ -174,13 +178,49 @@ function getClients() { return false; } + // getFavReports - obtains all favorite reports defined for group. + function getFavReports() { + global $user; + $mdb2 = getConnection(); + + $result = array(); + $sql = "select * from tt_fav_reports where group_id = $this->group_id and org_id = $user->org_id"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + // getPredefinedExpenses - obtains all predefined expenses for group. function getPredefinedExpenses() { global $user; $mdb2 = getConnection(); $result = array(); - $sql = "select * from tt_predefined_expenses where group_id = $this->group_id"; // TODO: add " and org_id = $user->org_id" when possible. + $sql = "select * from tt_predefined_expenses where group_id = $this->group_id and org_id = $user->org_id"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + + // getNotifications - obtains all notifications defined for group. + function getNotifications() { + global $user; + $mdb2 = getConnection(); + + $result = array(); + $sql = "select * from tt_cron where group_id = $this->group_id and org_id = $user->org_id"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -263,6 +303,11 @@ function writeData() { foreach ($custom_field_options as $key=>$option) $this->customFieldOptionMap[$option['id']] = $key + 1; + // Prepare favorite report map. + $fav_reports = $this->getFavReports(); + foreach ($fav_reports as $key=>$fav_report) + $this->favReportMap[$fav_report['id']] = $key + 1; + // Write roles. fwrite($this->file, $this->indentation." \n"); foreach ($roles as $role) { @@ -514,7 +559,7 @@ function writeData() { unset($quota_part); // Write fav reports. - $fav_reports = ttTeamHelper::getFavReports($this->group_id); + $fav_reports = $this->getFavReports(); fwrite($this->file, $this->indentation." \n"); foreach ($fav_reports as $fav_report) { $user_list = ''; @@ -525,7 +570,8 @@ function writeData() { $user_list .= (strlen($user_list) == 0? '' : ',').$this->userMap[$v]; } } - $fav_report_part = $this->indentation.' '."userMap[$fav_report['user_id']]."\""; + $fav_report_part = $this->indentation.' '."favReportMap[$fav_report['id']]."\""; + $fav_report_part .= " user_id=\"".$this->userMap[$fav_report['user_id']]."\""; $fav_report_part .= " name=\"".htmlspecialchars($fav_report['name'])."\""; $fav_report_part .= " client_id=\"".$this->clientMap[$fav_report['client_id']]."\""; $fav_report_part .= " cf_1_option_id=\"".$this->customFieldOptionMap[$fav_report['cf_1_option_id']]."\""; @@ -560,6 +606,26 @@ function writeData() { unset($fav_reports); unset($fav_report_part); + // Write notifications. + $notifications = $this->getNotifications(); + fwrite($this->file, $this->indentation." \n"); + foreach ($notifications as $notification) { + $notification_part = $this->indentation.' '."favReportMap[$notification['report_id']]."\""; + $notification_part .= " email=\"".htmlspecialchars($notification['email'])."\""; + $notification_part .= " cc=\"".htmlspecialchars($notification['cc'])."\""; + $notification_part .= " subject=\"".htmlspecialchars($notification['subject'])."\""; + $notification_part .= " report_condition=\"".htmlspecialchars($notification['report_condition'])."\""; + $notification_part .= " status=\"".$notification['status']."\""; + $notification_part .= ">\n"; + fwrite($this->file, $notification_part); + } + fwrite($this->file, $this->indentation." \n"); + unset($notifications); + unset($notification_part); + // We are mostly done with writing this group data, destroy all maps. unset($this->roleMap); unset($this->userMap); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a63402887..855cc77ec 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.20.4457 | Copyright © Anuko | +  Anuko Time Tracker 1.18.20.4458 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 3fe430d82ad416d1766b9f0cd558e2e1f26900a9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 15:41:51 +0000 Subject: [PATCH 0376/1848] Added notifications to import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 72 +++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index c57cc6405..0da0a7eac 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -59,6 +59,7 @@ class ttOrgImportHelper { var $currentGroupLogMap = array(); var $currentGroupCustomFieldMap = array(); var $currentGroupCustomFieldOptionMap = array(); + var $currentGroupFavReportMap = array(); // Constructor. function __construct(&$errors) { @@ -455,6 +456,14 @@ function startElement($parser, $name, $attrs) { return; } + if ($name == 'FAV_REPORTS') { + // If we get here, we have to recycle $currentGroupFavReportMap. + unset($this->currentGroupFavReportMap); + $this->currentGroupFavReportMap = array(); + // Favorite report map is reconstructed after processing elements in XML. See below. + return; + } + if ($name == 'FAV_REPORT') { $user_list = ''; if (strlen($attrs['USERS']) > 0) { @@ -462,7 +471,7 @@ function startElement($parser, $name, $attrs) { foreach ($arr as $v) $user_list .= (strlen($user_list) == 0 ? '' : ',').$this->currentGroupUserMap[$v]; } - if (!$this->insertFavReport(array( + $fav_report_id = $this->insertFavReport(array( 'name' => $attrs['NAME'], 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], 'group_id' => $this->current_group_id, @@ -492,10 +501,30 @@ function startElement($parser, $name, $attrs) { 'group_by1' => $attrs['GROUP_BY1'], 'group_by2' => $attrs['GROUP_BY2'], 'group_by3' => $attrs['GROUP_BY3'], - 'chtotalsonly' => (int) $attrs['SHOW_TOTALS_ONLY']))) { - $this->errors->add($i18n->get('error.db')); - } - return; + 'chtotalsonly' => (int) $attrs['SHOW_TOTALS_ONLY'])); + if ($fav_report_id) { + // Add a mapping. + $this->currentGroupFavReportMap[$attrs['ID']] = $fav_report_id; + } else $this->errors->add($i18n->get('error.db')); + return; + } + + if ($name == 'NOTIFICATION') { + if (!$this->insertNotification(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'cron_spec' => $attrs['CRON_SPEC'], + 'last' => $attrs['LAST'], + 'next' => $attrs['NEXT'], + 'report_id' => $this->currentGroupFavReportMap[$attrs['REPORT_ID']], + 'email' => $attrs['EMAIL'], + 'cc' => $attrs['CC'], + 'subject' => $attrs['SUBJECT'], + 'report_condition' => $attrs['REPORT_CONDITION'], + 'status' => $attrs['STATUS']))) { + $this->errors->add($i18n->get('error.db')); + } + return; } } } @@ -778,6 +807,39 @@ private function insertFavReport($fields) { $mdb2->quote($fields['group_by1']).", ".$mdb2->quote($fields['group_by2']).", ". $mdb2->quote($fields['group_by3']).", ".$fields['chtotalsonly'].")"; $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + $sql = "select last_insert_id() as last_id"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) + return false; + + $val = $res->fetchRow(); + return $val['last_id']; + } + + // insertNotification function inserts a new notification into database. + static function insertNotification($fields) + { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $cron_spec = $fields['cron_spec']; + $last = (int) $fields['last']; + $next = (int) $fields['next']; + $report_id = (int) $fields['report_id']; + $email = $fields['email']; + $cc = $fields['cc']; + $subject = $fields['subject']; + $report_condition = $fields['report_condition']; + $status = $fields['status']; + + $sql = "insert into tt_cron". + " (group_id, org_id, cron_spec, last, next, report_id, email, cc, subject, report_condition, status)". + " values ($group_id, $org_id, ".$mdb2->quote($cron_spec).", $last, $next, $report_id, ".$mdb2->quote($email).", ".$mdb2->quote($cc).", ".$mdb2->quote($subject).", ".$mdb2->quote($report_condition).", ".$mdb2->quote($status).")"; + $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 855cc77ec..01941ccc8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.20.4458 | Copyright © Anuko | +  Anuko Time Tracker 1.18.20.4459 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e9ae98c2cb2bc7455aa52ec6efa557b051429281 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 16:08:36 +0000 Subject: [PATCH 0377/1848] Added group_id and org_id in tt_client_project_binds table. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 8 +++++--- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 01941ccc8..b9077c05e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.20.4459 | Copyright © Anuko | +  Anuko Time Tracker 1.18.21.4460 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index e31783a7e..63bfdc0bd 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11820"]) { + if ($_POST["convert11797to11821"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1017,6 +1017,8 @@ function setChange($sql) { setChange("ALTER TABLE `tt_cron` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.20', modified = now() where param_name = 'version_db' and param_value = '1.18.19'"); setChange("UPDATE `tt_cron` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.20') set org_id = group_id where org_id is null"); + setChange("ALTER TABLE `tt_client_project_binds` ADD `group_id` int(11) default NULL AFTER `project_id`"); + setChange("ALTER TABLE `tt_client_project_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); } if ($_POST["cleanup"]) { @@ -1034,6 +1036,7 @@ function setChange($sql) { setChange("OPTIMIZE TABLE tt_client_project_binds"); setChange("OPTIMIZE TABLE tt_clients"); setChange("OPTIMIZE TABLE tt_config"); + setChange("OPTIMIZE TABLE tt_cron"); setChange("OPTIMIZE TABLE tt_custom_field_log"); setChange("OPTIMIZE TABLE tt_custom_field_options"); setChange("OPTIMIZE TABLE tt_custom_fields"); @@ -1063,7 +1066,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.20) + Create database structure (v1.18.21)
(applies only to new installations, do not execute when updating)
@@ -1108,8 +1111,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.20)Update database structure (v1.17.97 to v1.18.21)
diff --git a/mysql.sql b/mysql.sql index e3f0bd83c..705e664f1 100644 --- a/mysql.sql +++ b/mysql.sql @@ -333,8 +333,10 @@ create unique index client_name_idx on tt_clients(group_id, name, status); # Structure for table tt_client_project_binds. This table maps clients to assigned projects. # CREATE TABLE `tt_client_project_binds` ( - `client_id` int(11) NOT NULL, # client id - `project_id` int(11) NOT NULL # project id + `client_id` int(11) NOT NULL, # client id + `project_id` int(11) NOT NULL, # project id + `group_id` int(11) default NULL, # group id + `org_id` int(11) default NULL # organization id ); # Indexes for tt_client_project_binds. @@ -476,4 +478,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.20', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.21', now()); # TODO: change when structure changes. From e5c2856600ec9c939f011226c78f39ae9a63d8b0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 16:47:54 +0000 Subject: [PATCH 0378/1848] Populating group_id and org_id in tt_client_project_binds. --- WEB-INF/lib/ttClientHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 0c12a9538..eeb77f77a 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -195,7 +195,7 @@ static function insert($fields) if (count($projects) > 0) foreach ($projects as $p_id) { - $sql = "insert into tt_client_project_binds (client_id, project_id) values($last_id, $p_id)"; + $sql = "insert into tt_client_project_binds (client_id, project_id, group_id, org_id) values($last_id, $p_id, $group_id, $org_id)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b9077c05e..8d292fc5d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.21.4460 | Copyright © Anuko | +  Anuko Time Tracker 1.18.21.4461 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 63bfdc0bd..bfbb5c2c1 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1019,6 +1019,8 @@ function setChange($sql) { setChange("UPDATE `tt_cron` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.20') set org_id = group_id where org_id is null"); setChange("ALTER TABLE `tt_client_project_binds` ADD `group_id` int(11) default NULL AFTER `project_id`"); setChange("ALTER TABLE `tt_client_project_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("update `tt_client_project_binds` cpb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.20') inner join `tt_clients` c on c.id = cpb.client_id set cpb.group_id = c.group_id, cpb.org_id = c.org_id where cpb.org_id is null"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.21', modified = now() where param_name = 'version_db' and param_value = '1.18.20'"); } if ($_POST["cleanup"]) { From ad495718373d61982d81c3eebd3bc9d2921186b1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 17:01:51 +0000 Subject: [PATCH 0379/1848] Added an index to tt_client_project_binds to guarantee uniqueness. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + mysql.sql | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8d292fc5d..cab56b71c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.21.4461 | Copyright © Anuko | +  Anuko Time Tracker 1.18.21.4462 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index bfbb5c2c1..602449145 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1021,6 +1021,7 @@ function setChange($sql) { setChange("ALTER TABLE `tt_client_project_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("update `tt_client_project_binds` cpb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.20') inner join `tt_clients` c on c.id = cpb.client_id set cpb.group_id = c.group_id, cpb.org_id = c.org_id where cpb.org_id is null"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.21', modified = now() where param_name = 'version_db' and param_value = '1.18.20'"); + setChange("create unique index client_project_idx on tt_client_project_binds(client_id, project_id)"); } if ($_POST["cleanup"]) { diff --git a/mysql.sql b/mysql.sql index 705e664f1..bc970f734 100644 --- a/mysql.sql +++ b/mysql.sql @@ -342,6 +342,7 @@ CREATE TABLE `tt_client_project_binds` ( # Indexes for tt_client_project_binds. create index client_idx on tt_client_project_binds(client_id); create index project_idx on tt_client_project_binds(project_id); +create unique index client_project_idx on tt_client_project_binds(client_id, project_id); # From dc298aa5a82fc2aa86a27a1c106cf42881376004 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 18:00:03 +0000 Subject: [PATCH 0380/1848] Refactoring - wrote insertClient for import, to separate import from other stuff. --- WEB-INF/lib/ttOrgImportHelper.class.php | 46 +++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 0da0a7eac..9907f6e71 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -238,7 +238,7 @@ function startElement($parser, $name, $attrs) { $mapped_projects[] = $this->currentGroupProjectMap[$id]; } - $client_id = ttClientHelper::insert(array( + $client_id = $this->insertClient(array( 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, 'name' => $attrs['NAME'], @@ -779,6 +779,48 @@ private function insertProject($fields) return $last_id; } + // The insertClient function inserts a new client as well as client to project binds. + private function insertClient($fields) + { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $name = $fields['name']; + $address = $fields['address']; + $tax = $fields['tax']; + $projects = $fields['projects']; + if ($projects) + $comma_separated = implode(',', $projects); // This is a comma-separated list of associated projects ids. + $status = $fields['status']; + + $tax = str_replace(',', '.', $tax); + if ($tax == '') $tax = 0; + + $sql = "insert into tt_clients (group_id, org_id, name, address, tax, projects, status)". + " values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($address).", $tax, ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; + + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + $last_id = 0; + $sql = "select last_insert_id() as last_insert_id"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + $last_id = $val['last_insert_id']; + + if (count($projects) > 0) + foreach ($projects as $p_id) { + $sql = "insert into tt_client_project_binds (client_id, project_id, group_id, org_id) values($last_id, $p_id, $group_id, $org_id)"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + } + + return $last_id; + } + // insertFavReport - inserts a favorite report in database. private function insertFavReport($fields) { $mdb2 = getConnection(); @@ -820,7 +862,7 @@ private function insertFavReport($fields) { } // insertNotification function inserts a new notification into database. - static function insertNotification($fields) + private function insertNotification($fields) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index cab56b71c..627f0acc2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.21.4462 | Copyright © Anuko | +  Anuko Time Tracker 1.18.21.4463 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From abc243a67d158977ad2400ae4c41c447448473b5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 18:14:05 +0000 Subject: [PATCH 0381/1848] Added group_id and org_id to tt_config table. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 4 +++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 627f0acc2..3315253f0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.21.4463 | Copyright © Anuko | +  Anuko Time Tracker 1.18.22.4464 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 602449145..5ee0337e3 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11821"]) { + if ($_POST["convert11797to11822"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1022,6 +1022,9 @@ function setChange($sql) { setChange("update `tt_client_project_binds` cpb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.20') inner join `tt_clients` c on c.id = cpb.client_id set cpb.group_id = c.group_id, cpb.org_id = c.org_id where cpb.org_id is null"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.21', modified = now() where param_name = 'version_db' and param_value = '1.18.20'"); setChange("create unique index client_project_idx on tt_client_project_binds(client_id, project_id)"); + setChange("ALTER TABLE `tt_config` ADD `group_id` int(11) default NULL AFTER `user_id`"); + setChange("ALTER TABLE `tt_config` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.22', modified = now() where param_name = 'version_db' and param_value = '1.18.21'"); } if ($_POST["cleanup"]) { @@ -1069,7 +1072,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.21) + Create database structure (v1.18.22)
(applies only to new installations, do not execute when updating)
@@ -1114,8 +1117,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.21)Update database structure (v1.17.97 to v1.18.22)
diff --git a/mysql.sql b/mysql.sql index bc970f734..e0c4145d5 100644 --- a/mysql.sql +++ b/mysql.sql @@ -351,6 +351,8 @@ create unique index client_project_idx on tt_client_project_binds(client_id, pro # CREATE TABLE `tt_config` ( `user_id` int(11) NOT NULL, # user id + `group_id` int(11) default NULL, # group id + `org_id` int(11) default NULL, # organization id `param_name` varchar(32) NOT NULL, # parameter name `param_value` varchar(80) default NULL # parameter value ); @@ -479,4 +481,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.21', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.22', now()); # TODO: change when structure changes. From cfc33172165a50572d74d808c3c523484f60800f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 19:40:18 +0000 Subject: [PATCH 0382/1848] Populating group_id and org_id in tt_config table. --- WEB-INF/lib/ttSysConfig.class.php | 21 ++++++++++++++------- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttSysConfig.class.php b/WEB-INF/lib/ttSysConfig.class.php index cb7637d15..fd9905210 100644 --- a/WEB-INF/lib/ttSysConfig.class.php +++ b/WEB-INF/lib/ttSysConfig.class.php @@ -35,18 +35,23 @@ // Class ttSysConfig is used for storing and retrieving named values associated with users. class ttSysConfig { - var $u_id = null; + var $user_id = null; + var $group_id = null; + var $org_id = null; var $mdb2 = null; // Constructor. - function __construct($u_id) { - $this->u_id = $u_id; + function __construct($user_id) { + global $user; + $this->user_id = $user_id; // TODO: review "on behalf" situation and refactor if necessary. + $this->group_id = $user->getActiveGroup(); + $this->org_id = $user->org_id; $this->mdb2 = getConnection(); } // The getValue retrieves a value identified by name. function getValue($name) { - $res = $this->mdb2->query("select param_value from tt_config where user_id = ".$this->u_id." and param_name=".$this->mdb2->quote($name)); + $res = $this->mdb2->query("select param_value from tt_config where user_id = ".$this->user_id." and param_name=".$this->mdb2->quote($name)); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); return $val['param_value']; @@ -57,13 +62,15 @@ function getValue($name) { // The setValue sets a value identified by name. function setValue($name, $value) { $rcnt = 0; - $res = $this->mdb2->query("select count(*) as rcnt from tt_config where user_id = ".$this->u_id." and param_name = ".$this->mdb2->quote($name)); + $res = $this->mdb2->query("select count(*) as rcnt from tt_config where user_id = ".$this->user_id." and param_name = ".$this->mdb2->quote($name)); if ($val = $res->fetchRow()) $rcnt = $val['rcnt']; if ($rcnt > 0) { - $affected = $this->mdb2->exec("update tt_config set param_value = ".$this->mdb2->quote($value)." where user_id = ".$this->u_id." and param_name=".$this->mdb2->quote($name)); + $affected = $this->mdb2->exec("update tt_config set param_value = ".$this->mdb2->quote($value)." where user_id = ".$this->user_id." and param_name=".$this->mdb2->quote($name)); } else { - $affected = $this->mdb2->exec("insert into tt_config set param_value = ".$this->mdb2->quote($value).", param_name = ".$this->mdb2->quote($name).", user_id = ".$this->u_id); + $sql = "insert into tt_config set param_value = ".$this->mdb2->quote($value). + ", param_name = ".$this->mdb2->quote($name).", user_id = ".$this->user_id.", group_id = ".$this->group_id.", org_id = ".$this->org_id; + $affected = $this->mdb2->exec($sql); } return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3315253f0..92095cf01 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.22.4464 | Copyright © Anuko | +  Anuko Time Tracker 1.18.22.4465 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 5ee0337e3..c65175d57 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1025,6 +1025,7 @@ function setChange($sql) { setChange("ALTER TABLE `tt_config` ADD `group_id` int(11) default NULL AFTER `user_id`"); setChange("ALTER TABLE `tt_config` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.22', modified = now() where param_name = 'version_db' and param_value = '1.18.21'"); + setChange("update `tt_config` c inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.22') inner join `tt_users` u on u.id = c.user_id set c.group_id = u.group_id, c.org_id = u.org_id where c.org_id is null"); } if ($_POST["cleanup"]) { From 191af95a641e560104be099de62ea45ac5cd6315 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 20:46:11 +0000 Subject: [PATCH 0383/1848] Added user config params to export. --- WEB-INF/lib/ttGroupExportHelper.class.php | 36 +++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index cf64cede7..c6e1d9a5d 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -72,7 +72,7 @@ function __construct($group_id, $file, $indentation) { } // getGroupData obtains group attributes for export. - function getGroupData() { + private function getGroupData() { global $user; $mdb2 = getConnection(); @@ -86,7 +86,7 @@ function getGroupData() { } // The getUsers obtains all users in group for the purpose of export. - function getUsers() { + private function getUsers() { global $user; $mdb2 = getConnection(); @@ -232,6 +232,24 @@ function getNotifications() { return false; } + // getRecordsFromTable - obtains all fields from a given table for a group. + function getRecordsFromTable($table_name) { + global $user; + $mdb2 = getConnection(); + + $result = array(); + $sql = "select * from $table_name where group_id = $this->group_id and org_id = $user->org_id"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + // writeData writes group data into file. function writeData() { @@ -626,6 +644,20 @@ function writeData() { unset($notifications); unset($notification_part); + // Write user config parameters. + $user_params = $this->getRecordsFromTable('tt_config'); + fwrite($this->file, $this->indentation." \n"); + foreach ($user_params as $user_param) { + $user_param_part = $this->indentation.' '."userMap[$user_param['user_id']]."\""; + $user_param_part .= " param_name=\"".htmlspecialchars($user_param['param_name'])."\""; + $user_param_part .= " param_value=\"".htmlspecialchars($user_param['param_value'])."\""; + $user_param_part .= ">\n"; + fwrite($this->file, $user_param_part); + } + fwrite($this->file, $this->indentation." \n"); + unset($user_params); + unset($user_param_part); + // We are mostly done with writing this group data, destroy all maps. unset($this->roleMap); unset($this->userMap); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 92095cf01..23cc0edb5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.22.4465 | Copyright © Anuko | +  Anuko Time Tracker 1.18.22.4466 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From f6afe28937ca24f05e0a4fc0f4b4054d1832f5a9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 21:01:53 +0000 Subject: [PATCH 0384/1848] Added user config params to import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 29 +++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 9907f6e71..dda7f75df 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -526,6 +526,18 @@ function startElement($parser, $name, $attrs) { } return; } + + if ($name == 'USER_PARAM') { + if (!$this->insertUserParam(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], + 'param_name' => $attrs['PARAM_NAME'], + 'param_value' => $attrs['PARAM_VALUE']))) { + $this->errors->add($i18n->get('error.db')); + } + return; + } } } @@ -884,4 +896,21 @@ private function insertNotification($fields) $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // insertUserParam - a helper function to insert a user parameter. + private function insertUserParam($fields) { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $user_id = (int) $fields['user_id']; + $param_name = $fields['param_name']; + $param_value = $fields['param_value']; + + $sql = "insert into tt_config". + " (user_id, group_id, org_id, param_name, param_value)". + " values ($user_id, $group_id, $org_id, ".$mdb2->quote($param_name).", ".$mdb2->quote($param_value).")"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 23cc0edb5..c6c6ed7d7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.22.4466 | Copyright © Anuko | +  Anuko Time Tracker 1.18.22.4467 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 0d139d09bd3304dd9666ea4a74d367ad16c85604 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 21:12:06 +0000 Subject: [PATCH 0385/1848] Adding group_id and org_id to last 3 remaining tables. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 6 ++++++ mysql.sql | 7 ++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c6c6ed7d7..9ace916c9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.22.4467 | Copyright © Anuko | +  Anuko Time Tracker 1.18.23.4468 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index c65175d57..90067399b 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1026,6 +1026,12 @@ function setChange($sql) { setChange("ALTER TABLE `tt_config` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.22', modified = now() where param_name = 'version_db' and param_value = '1.18.21'"); setChange("update `tt_config` c inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.22') inner join `tt_users` u on u.id = c.user_id set c.group_id = u.group_id, c.org_id = u.org_id where c.org_id is null"); + setChange("ALTER TABLE `tt_custom_fields` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("ALTER TABLE `tt_custom_field_options` ADD `group_id` int(11) default NULL AFTER `id`"); + setChange("ALTER TABLE `tt_custom_field_options` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("ALTER TABLE `tt_custom_field_log` ADD `group_id` int(11) default NULL AFTER `id`"); + setChange("ALTER TABLE `tt_custom_field_log` ADD `org_id` int(11) default NULL AFTER `group_id`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.23', modified = now() where param_name = 'version_db' and param_value = '1.18.22'"); } if ($_POST["cleanup"]) { diff --git a/mysql.sql b/mysql.sql index e0c4145d5..0bbf15d43 100644 --- a/mysql.sql +++ b/mysql.sql @@ -369,6 +369,7 @@ create unique index param_idx on tt_config(user_id, param_name); CREATE TABLE `tt_custom_fields` ( `id` int(11) NOT NULL auto_increment, # custom field id `group_id` int(11) NOT NULL, # group id + `org_id` int(11) default NULL, # organization id `type` tinyint(4) NOT NULL default 0, # custom field type (text or dropdown) `label` varchar(32) NOT NULL default '', # custom field label `required` tinyint(4) default 0, # whether this custom field is mandatory for time records @@ -382,6 +383,8 @@ CREATE TABLE `tt_custom_fields` ( # CREATE TABLE `tt_custom_field_options` ( `id` int(11) NOT NULL auto_increment, # option id + `group_id` int(11) default NULL, # group id + `org_id` int(11) default NULL, # organization id `field_id` int(11) NOT NULL, # custom field id `value` varchar(32) NOT NULL default '', # option value PRIMARY KEY (`id`) @@ -394,6 +397,8 @@ CREATE TABLE `tt_custom_field_options` ( # CREATE TABLE `tt_custom_field_log` ( `id` bigint NOT NULL auto_increment, # custom field log id + `group_id` int(11) default NULL, # group id + `org_id` int(11) default NULL, # organization id `log_id` bigint NOT NULL, # id of a record in tt_log this record corresponds to `field_id` int(11) NOT NULL, # custom field id `option_id` int(11) default NULL, # Option id. Used for dropdown custom fields. @@ -481,4 +486,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.22', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.23', now()); # TODO: change when structure changes. From cd0fdd6bdf0879f047732df3d0092a291b35ff6c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Nov 2018 23:11:58 +0000 Subject: [PATCH 0386/1848] Populating org_id in tt_custom_fields table. --- WEB-INF/lib/ttOrgImportHelper.class.php | 30 +++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + plugins/CustomFields.class.php | 5 ++++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index dda7f75df..2758ac21d 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -364,9 +364,9 @@ function startElement($parser, $name, $attrs) { if ($name == 'CUSTOM_FIELD') { // We get here when processing tags for the current group. - $custom_field_id = ttCustomFieldHelper::insertField(array( + $custom_field_id = $this->insertCustomField(array( 'group_id' => $this->current_group_id, - // 'org_id' => $this->org_id, TODO: add this when org_id field is added to the table. + 'org_id' => $this->org_id, 'type' => $attrs['TYPE'], 'label' => $attrs['LABEL'], 'required' => $attrs['REQUIRED'], @@ -913,4 +913,30 @@ private function insertUserParam($fields) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // insertCustomField - a helper function to insert a custom field. + private function insertCustomField($fields) { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $type = (int) $fields['type']; + $label = $fields['label']; + $required = (int) $fields['required']; + $status = $fields['status']; + + $sql = "insert into tt_custom_fields". + " (group_id, org_id, type, label, required, status)". + " values($group_id, $org_id, $type, ".$mdb2->quote($label).", $required, ".$mdb2->quote($status).")"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + $last_id = 0; + $sql = "select last_insert_id() as last_insert_id"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + $last_id = $val['last_insert_id']; + return $last_id; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9ace916c9..00b5047c9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.23.4468 | Copyright © Anuko | +  Anuko Time Tracker 1.18.23.4469 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 90067399b..a6c499bd2 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1032,6 +1032,7 @@ function setChange($sql) { setChange("ALTER TABLE `tt_custom_field_log` ADD `group_id` int(11) default NULL AFTER `id`"); setChange("ALTER TABLE `tt_custom_field_log` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.23', modified = now() where param_name = 'version_db' and param_value = '1.18.22'"); + setChange("UPDATE `tt_custom_fields` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') set org_id = group_id where org_id is null"); } if ($_POST["cleanup"]) { diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 00582e3e9..57f1d86c6 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -274,7 +274,10 @@ static function getFieldIdForOption($option_id) { static function insertField($field_name, $field_type, $required) { global $user; $mdb2 = getConnection(); - $sql = "insert into tt_custom_fields (group_id, type, label, required, status) values($user->group_id, $field_type, ".$mdb2->quote($field_name).", $required, 1)"; + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; + $sql = "insert into tt_custom_fields (group_id, org_id, type, label, required, status)". + " values($group_id, $org_id, $field_type, ".$mdb2->quote($field_name).", $required, 1)"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } From a4c1ced936fb1a1b71d4d34479a9c999aef4b338 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Nov 2018 08:02:25 +0000 Subject: [PATCH 0387/1848] Populating group_id and org_id in tt_custom_field_options table. --- WEB-INF/lib/ttOrgImportHelper.class.php | 29 ++++++++++++++++++++++--- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + plugins/CustomFields.class.php | 8 +++++-- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 2758ac21d..7ff3b5b6b 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -388,9 +388,9 @@ function startElement($parser, $name, $attrs) { if ($name == 'CUSTOM_FIELD_OPTION') { // We get here when processing tags for the current group. - $custom_field_option_id = ttCustomFieldHelper::insertOption(array( - // 'group_id' => $this->current_group_id, TODO: add this when group_id field is added to the table. - // 'org_id' => $this->org_id, TODO: add this when org_id field is added to the table. + $custom_field_option_id = $this->insertCustomFieldOption(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, 'field_id' => $this->currentGroupCustomFieldMap[$attrs['FIELD_ID']], 'value' => $attrs['VALUE'])); if ($custom_field_option_id) { @@ -939,4 +939,27 @@ private function insertCustomField($fields) { $last_id = $val['last_insert_id']; return $last_id; } + + // insertCustomFieldOption - a helper function to insert a custom field option. + private function insertCustomFieldOption($fields) { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $field_id = (int) $fields['field_id']; + $value = $fields['value']; + + $sql = "insert into tt_custom_field_options (group_id, org_id, field_id, value)". + " values ($group_id, $org_id, $field_id, ".$mdb2->quote($value).")"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + $last_id = 0; + $sql = "select last_insert_id() as last_insert_id"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + $last_id = $val['last_insert_id']; + return $last_id; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 00b5047c9..305fc79c2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.23.4469 | Copyright © Anuko | +  Anuko Time Tracker 1.18.23.4470 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index a6c499bd2..f7254ad63 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1033,6 +1033,7 @@ function setChange($sql) { setChange("ALTER TABLE `tt_custom_field_log` ADD `org_id` int(11) default NULL AFTER `group_id`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.23', modified = now() where param_name = 'version_db' and param_value = '1.18.22'"); setChange("UPDATE `tt_custom_fields` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') set org_id = group_id where org_id is null"); + setChange("update `tt_custom_field_options` cfo inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfo.field_id set cfo.group_id = cf.group_id, cfo.org_id = cf.org_id where cfo.org_id is null"); } if ($_POST["cleanup"]) { diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 57f1d86c6..306b5993d 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -110,9 +110,12 @@ function get($log_id) { // insertOption adds a new option to a custom field. static function insertOption($field_id, $option_name) { - + global $user; $mdb2 = getConnection(); + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; + // Check if the option exists. $id = 0; $sql = "select id from tt_custom_field_options where field_id = $field_id and value = ".$mdb2->quote($option_name); @@ -123,7 +126,8 @@ static function insertOption($field_id, $option_name) { // Insert option. if (!$id) { - $sql = "insert into tt_custom_field_options (field_id, value) values($field_id, ".$mdb2->quote($option_name).")"; + $sql = "insert into tt_custom_field_options (group_id, org_id, field_id, value)". + " values($group_id, $org_id, $field_id, ".$mdb2->quote($option_name).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; From 6ebd9b5c4aa66017858979cf00ac1db700f9d643 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Nov 2018 08:33:15 +0000 Subject: [PATCH 0388/1848] Populating group_id and org_id in tt_custom_field_log. --- WEB-INF/lib/ttOrgImportHelper.class.php | 25 +++++++++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + plugins/CustomFields.class.php | 9 +++++++-- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 7ff3b5b6b..a14d9714b 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -32,7 +32,6 @@ import('ttClientHelper'); import('ttInvoiceHelper'); import('ttTimeHelper'); -import('ttCustomFieldHelper'); import('ttExpenseHelper'); import('ttFavReportHelper'); @@ -402,9 +401,9 @@ function startElement($parser, $name, $attrs) { if ($name == 'CUSTOM_FIELD_LOG_ENTRY') { // We get here when processing tags for the current group. - if (!ttCustomFieldHelper::insertLogEntry(array( - // 'group_id' => $this->current_group_id, TODO: add this when group_id field is added to the table. - // 'org_id' => $this->org_id, TODO: add this when org_id field is added to the table. + if (!$this->insertCustomFieldLogEntry(array( + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, 'log_id' => $this->currentGroupLogMap[$attrs['LOG_ID']], 'field_id' => $this->currentGroupCustomFieldMap[$attrs['FIELD_ID']], 'option_id' => $this->currentGroupCustomFieldOptionMap[$attrs['OPTION_ID']], @@ -962,4 +961,22 @@ private function insertCustomFieldOption($fields) { $last_id = $val['last_insert_id']; return $last_id; } + + // insertCustomFieldLogEntry - a helper function to insert a custom field log entry. + private function insertCustomFieldLogEntry($fields) { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $log_id = (int) $fields['log_id']; + $field_id = (int) $fields['field_id']; + $option_id = $fields['option_id']; + $value = $fields['value']; + $status = $fields['status']; + + $sql = "insert into tt_custom_field_log (group_id, org_id, log_id, field_id, option_id, value, status)". + " values ($group_id, $org_id, $log_id, $field_id, ".$mdb2->quote($option_id).", ".$mdb2->quote($value).", ".$mdb2->quote($status).")"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 305fc79c2..405a939b8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.23.4470 | Copyright © Anuko | +  Anuko Time Tracker 1.18.23.4471 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index f7254ad63..d0ccbe335 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1034,6 +1034,7 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.18.23', modified = now() where param_name = 'version_db' and param_value = '1.18.22'"); setChange("UPDATE `tt_custom_fields` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') set org_id = group_id where org_id is null"); setChange("update `tt_custom_field_options` cfo inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfo.field_id set cfo.group_id = cf.group_id, cfo.org_id = cf.org_id where cfo.org_id is null"); + setChange("update `tt_custom_field_log` cfl inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfl.field_id set cfl.group_id = cf.group_id, cfl.org_id = cf.org_id where cfl.org_id is null"); } if ($_POST["cleanup"]) { diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 306b5993d..0e450b14d 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -63,9 +63,14 @@ function __construct($group_id) { } function insert($log_id, $field_id, $option_id, $value) { - + global $user; $mdb2 = getConnection(); - $sql = "insert into tt_custom_field_log (log_id, field_id, option_id, value) values($log_id, $field_id, ".$mdb2->quote($option_id).", ".$mdb2->quote($value).")"; + + $group_id = $user->getActiveGroup(); + $org_id = $user->org_id; + + $sql = "insert into tt_custom_field_log (group_id, org_id, log_id, field_id, option_id, value)". + " values($group_id, $org_id, $log_id, $field_id, ".$mdb2->quote($option_id).", ".$mdb2->quote($value).")"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } From 94081b97e54440c0d7b1b5b3f2faf0db4f0c4687 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Nov 2018 12:51:18 +0000 Subject: [PATCH 0389/1848] Introduced status field in tt_custom_field_options for consistency. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 9 +++++---- mysql.sql | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 405a939b8..02b735550 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.23.4471 | Copyright © Anuko | +  Anuko Time Tracker 1.18.24.4472 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index d0ccbe335..6818e0d3e 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11822"]) { + if ($_POST["convert11797to11824"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1035,6 +1035,7 @@ function setChange($sql) { setChange("UPDATE `tt_custom_fields` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') set org_id = group_id where org_id is null"); setChange("update `tt_custom_field_options` cfo inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfo.field_id set cfo.group_id = cf.group_id, cfo.org_id = cf.org_id where cfo.org_id is null"); setChange("update `tt_custom_field_log` cfl inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfl.field_id set cfl.group_id = cf.group_id, cfl.org_id = cf.org_id where cfl.org_id is null"); + setChange("ALTER TABLE `tt_custom_field_options` ADD `status` tinyint(4) default '1' after `value`"); } if ($_POST["cleanup"]) { @@ -1082,7 +1083,7 @@ function setChange($sql) {

DB Install

-
Create database structure (v1.18.22) + Create database structure (v1.18.24)
(applies only to new installations, do not execute when updating)
@@ -1127,8 +1128,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.22)Update database structure (v1.17.97 to v1.18.24)
diff --git a/mysql.sql b/mysql.sql index 0bbf15d43..0ddf3bfa9 100644 --- a/mysql.sql +++ b/mysql.sql @@ -387,6 +387,7 @@ CREATE TABLE `tt_custom_field_options` ( `org_id` int(11) default NULL, # organization id `field_id` int(11) NOT NULL, # custom field id `value` varchar(32) NOT NULL default '', # option value + `status` tinyint(4) default 1, # option status PRIMARY KEY (`id`) ); @@ -486,4 +487,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.23', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.24', now()); # TODO: change when structure changes. From f5a86ad6b1e247ff6bd83d12fb1f4cfdce581192 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Nov 2018 12:55:50 +0000 Subject: [PATCH 0390/1848] Version update. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 02b735550..0af745e7f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.24.4472 | Copyright © Anuko | +  Anuko Time Tracker 1.18.24.4473 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 6818e0d3e..0d50381dd 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1036,6 +1036,7 @@ function setChange($sql) { setChange("update `tt_custom_field_options` cfo inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfo.field_id set cfo.group_id = cf.group_id, cfo.org_id = cf.org_id where cfo.org_id is null"); setChange("update `tt_custom_field_log` cfl inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfl.field_id set cfl.group_id = cf.group_id, cfl.org_id = cf.org_id where cfl.org_id is null"); setChange("ALTER TABLE `tt_custom_field_options` ADD `status` tinyint(4) default '1' after `value`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.24', modified = now() where param_name = 'version_db' and param_value = '1.18.23'"); } if ($_POST["cleanup"]) { From 9e55571e568f9653c94860ab308cd781e20d13eb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Nov 2018 13:35:43 +0000 Subject: [PATCH 0391/1848] Reworked custom fields a bit to mark things deleted instead of deleting. --- WEB-INF/templates/footer.tpl | 2 +- plugins/CustomFields.class.php | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0af745e7f..412285de9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.24.4473 | Copyright © Anuko | +  Anuko Time Tracker 1.18.24.4474 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 0e450b14d..1517bf085 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -52,7 +52,7 @@ function __construct($group_id) { // If we have a dropdown obtain options for it. if ((count($this->fields) > 0) && ($this->fields[0]['type'] == CustomFields::TYPE_DROPDOWN)) { - $sql = "select id, value from tt_custom_field_options where field_id = ".$this->fields[0]['id']." order by value"; + $sql = "select id, value from tt_custom_field_options where field_id = ".$this->fields[0]['id']." and status = 1 order by value"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -173,7 +173,7 @@ static function deleteOption($id) { return false; // Delete the option. - $sql = "delete from tt_custom_field_options where id = $id"; + $sql = "update tt_custom_field_options set status = NULL where id = $id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -194,7 +194,7 @@ static function getOptions($field_id) { return false; // Get options. - $sql = "select id, value from tt_custom_field_options where field_id = $field_id order by value"; + $sql = "select id, value from tt_custom_field_options where field_id = $field_id and status = 1 order by value"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -303,10 +303,6 @@ static function updateField($id, $name, $type, $required) { // The deleteField deletes a custom field, its options and log entries for group. static function deleteField($field_id) { - // Our overall intention is to keep the code simple and manageable. - // If a user wishes to delete a field, we will delete all its options and log entries. - // Otherwise we have to do conditional queries depending on field status (this complicates things). - global $user; $mdb2 = getConnection(); @@ -325,14 +321,14 @@ static function deleteField($field_id) { if (is_a($affected, 'PEAR_Error')) return false; - // Delete field options. - $sql = "delete from tt_custom_field_options where field_id = $field_id"; + // Mark field options as deleted. + $sql = "update tt_custom_field_options set status = NULL where field_id = $field_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - // Delete the field. - $sql = "delete from tt_custom_fields where id = $field_id and group_id = $user->group_id"; + // Mark custom field as deleted. + $sql = "update tt_custom_fields set status = NULL where id = $field_id and group_id = $user->group_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } From c9ab657042ee613e3e2b896c8cf381fee7dd3ff5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Nov 2018 14:36:07 +0000 Subject: [PATCH 0392/1848] Redone db cleanup to support subgroups. --- WEB-INF/lib/ttOrgHelper.class.php | 56 +++++++++++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 +++--- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index c69fc7a7a..6d7ae678c 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -63,7 +63,7 @@ static function getName($org_id) { return false; } - // The getInactiveOrgs is a maintenance function that returns an array of inactive organization ids (max 5 for now). + // The getInactiveOrgs is a maintenance function that returns an array of inactive organization ids (max 1 for now). static function getInactiveOrgs() { $inactive_orgs = array(); $mdb2 = getConnection(); @@ -72,7 +72,7 @@ static function getInactiveOrgs() { $cutoff_timestamp = $mdb2->quote(date('Y-m-d', strtotime('-1 year'))); $sql = "select org_id from". " (select max(accessed) as last_access, org_id from tt_users group by org_id order by last_access, org_id) as t". - " where last_access is null or last_access < $cutoff_timestamp limit 5"; // Max 5 orgs at a time for now... + " where last_access is null or last_access < $cutoff_timestamp limit 1"; // Max 1 orgs at a time for now... $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -84,27 +84,39 @@ static function getInactiveOrgs() { } // deleteOrg deletes data for the entire organization from database permanently. - // Work in progress, currently not fully implemented. static function deleteOrg($org_id) { - // We shall do it in a straightforward way by a delete operation from all tables by org_id. - // However, at this time not all tables have org_id. - // So, we need to add the field as we write code here. - - // Delete expense items. - $sql = "delete from tt_expense_items where org_id = $org_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; - - // Delete predefined expenses. - $sql = "delete from tt_predefined_expenses where org_id = $org_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; - - // Delete monthly quotas. - $sql = "delete from tt_monthly_quotas where org_id = $org_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; + // Go one table at a time and remove all records with matching org_id. + // The order is backwards to import (see ttOrgImportHelper). Remove groups last. + // This leaves us with something partially working if an error occurs. + $mdb2 = getConnection(); - return true; // Work in progress, currently not fully implemented. + $tables = array( + 'tt_config', + 'tt_cron', + 'tt_fav_reports', + 'tt_monthly_quotas', + 'tt_predefined_expenses', + 'tt_expense_items', + 'tt_custom_field_log', + 'tt_custom_field_options', + 'tt_custom_fields', + 'tt_log', + 'tt_invoices', + 'tt_user_project_binds', + 'tt_users', + 'tt_client_project_binds', + 'tt_clients', + 'tt_project_task_binds', + 'tt_projects', + 'tt_tasks', + 'tt_roles', + 'tt_groups' + ); + foreach($tables as $table) { + $sql = "delete from $table where org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + } + return true; } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 412285de9..c74e2d020 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.24.4474 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4475 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 0d50381dd..264fc379d 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1042,13 +1042,13 @@ function setChange($sql) { if ($_POST["cleanup"]) { $mdb2 = getConnection(); - $inactive_groups = ttOrgHelper::getInactiveOrgs(); + $inactive_orgs = ttOrgHelper::getInactiveOrgs(); - $count = count($inactive_groups); - print "$count inactive groups found...
\n"; + $count = count($inactive_orgs); + print "$count inactive organizations found...
\n"; for ($i = 0; $i < $count; $i++) { - print " deleting group ".$inactive_groups[$i]."
\n"; - $res = ttTeamHelper::delete($inactive_groups[$i]); // TODO: rewrite this to delete subgroups, too. + print " deleting organization ".$inactive_orgs[$i]."
\n"; + $res = ttOrgHelper::deleteOrg($inactive_orgs[$i]); } setChange("OPTIMIZE TABLE tt_client_project_binds"); From 2eb17adc82261776d7bc3b19942e5e6da2778e11 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Nov 2018 14:53:15 +0000 Subject: [PATCH 0393/1848] Increased db cleanup scope to 5 orgs at a time. --- WEB-INF/lib/ttOrgHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index 6d7ae678c..8b3f95ff0 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -63,7 +63,7 @@ static function getName($org_id) { return false; } - // The getInactiveOrgs is a maintenance function that returns an array of inactive organization ids (max 1 for now). + // The getInactiveOrgs is a maintenance function that returns an array of inactive organization ids (max 5 for now). static function getInactiveOrgs() { $inactive_orgs = array(); $mdb2 = getConnection(); @@ -72,7 +72,7 @@ static function getInactiveOrgs() { $cutoff_timestamp = $mdb2->quote(date('Y-m-d', strtotime('-1 year'))); $sql = "select org_id from". " (select max(accessed) as last_access, org_id from tt_users group by org_id order by last_access, org_id) as t". - " where last_access is null or last_access < $cutoff_timestamp limit 1"; // Max 1 orgs at a time for now... + " where last_access is null or last_access < $cutoff_timestamp limit 5"; // Max 5 orgs at a time for now... $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c74e2d020..98ee48de8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.25.4475 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4476 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 78ef5f9b455fc04a3fe8535f234d98bddf4de6c9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Nov 2018 21:56:40 +0000 Subject: [PATCH 0394/1848] Started to work on group editor for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/groups.tpl | 31 +++++++++++++++++++++++++ groups.php | 45 ++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/templates/groups.tpl create mode 100644 groups.php diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 98ee48de8..9a9be2d06 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.25.4476 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4477 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/groups.tpl b/WEB-INF/templates/groups.tpl new file mode 100644 index 000000000..d9748bcbd --- /dev/null +++ b/WEB-INF/templates/groups.tpl @@ -0,0 +1,31 @@ + + + + + + + + +{if $groups} + {foreach $groups as $group} + + + + + + {/foreach} +{/if} +
{$i18n.label.thing_name}{$i18n.label.edit}{$i18n.label.delete}
{$group.name|escape}{$i18n.label.edit}{$i18n.label.delete}
+ + + + + +
+
+
+ +
+
diff --git a/groups.php b/groups.php new file mode 100644 index 000000000..5a612c130 --- /dev/null +++ b/groups.php @@ -0,0 +1,45 @@ +assign('groups', $user->getGroups()); +$smarty->assign('title', $i18n->get('title.groups')); +$smarty->assign('content_page_name', 'groups.tpl'); +$smarty->display('index.tpl'); From a4fd787ff4452eb1a7e3d0c0a24d8fcebd7b8b43 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 08:26:43 +0000 Subject: [PATCH 0395/1848] Added label.subgroups to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + 30 files changed, 31 insertions(+) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 1e5b6f3d2..c74d35a36 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -167,6 +167,7 @@ 'label.users' => 'Usuaris', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Client', 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d8f647dd2..dc118550f 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -171,6 +171,7 @@ 'label.users' => 'Uživatelů', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Zákazník', 'label.clients' => 'Zákazníci', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 344bf05c3..01a71f892 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -155,6 +155,7 @@ 'label.users' => 'Brugere', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Klient', 'label.clients' => 'Klienter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 9a778429c..aa828b220 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -147,6 +147,7 @@ 'label.users' => 'Personen', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', 'label.roles' => 'Rollen', 'label.client' => 'Kunde', 'label.clients' => 'Kunden', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 31f0ebb8e..31a243414 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -144,6 +144,7 @@ 'label.user' => 'User', 'label.users' => 'Users', 'label.group' => 'Group', +'label.subgroups' => 'Subgroups', 'label.roles' => 'Roles', 'label.client' => 'Client', 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 622c1d87a..f9139807c 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -166,6 +166,7 @@ // TODO: translate the following. // 'label.users' => 'Users', // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', // 'label.client' => 'Client', // 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index ad3698003..03d5c3603 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -170,6 +170,7 @@ 'label.users' => 'Kasutajad', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Klient', 'label.clients' => 'Kliendid', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 26b236393..e90fd976c 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -162,6 +162,7 @@ 'label.users' => 'کاربران', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'مشتری', 'label.clients' => 'مشتریان', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 208c25598..8ec0afc59 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -157,6 +157,7 @@ 'label.users' => 'Käyttäjät', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Asiakas', 'label.clients' => 'Asiakkaat', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index c164138c5..9805bfd4c 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -154,6 +154,7 @@ 'label.users' => 'Utilisateurs', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Client', 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 925abcafc..90a5fea85 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -148,6 +148,7 @@ 'label.users' => 'Χρήστες', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', 'label.roles' => 'Ρόλους', 'label.client' => 'Πελάτης', 'label.clients' => 'Πελάτες', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 0c6ad0bfb..615e40ada 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -172,6 +172,7 @@ 'label.users' => 'משתמשים', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'לקוח', 'label.clients' => 'לקוחות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index c7eb011a0..bcb236bc9 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -169,6 +169,7 @@ // 'label.user' => 'User', // 'label.users' => 'Users', // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Ügyfél', 'label.clients' => 'Ügyfelek', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ac542965e..fa488a65e 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -152,6 +152,7 @@ 'label.users' => 'Utenti', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Cliente', 'label.clients' => 'Clienti', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 7bc81789a..142e4c684 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -172,6 +172,7 @@ 'label.users' => 'ユーザー', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'クライアント', 'label.clients' => 'クライアント', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 6121b38fb..f30d279e4 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -171,6 +171,7 @@ 'label.users' => '사용자', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => '클라이언트', 'label.clients' => '클라이언트', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index fb2e9b420..c6786e0c7 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -143,6 +143,8 @@ 'label.user' => 'Medewerker', 'label.users' => 'Medewerkers', 'label.group' => 'Groep', +// TODO: translate the following. +// 'label.subgroups' => 'Subgroups', 'label.roles' => 'Rollen', 'label.client' => 'Klant', 'label.clients' => 'Klanten', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index af6943cb6..c14345d1b 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -172,6 +172,7 @@ 'label.users' => 'Brukere', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Klient', 'label.clients' => 'Klienter', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 39e7c9f57..92df49acb 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -159,6 +159,7 @@ 'label.users' => 'Użytkownicy', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Klient', 'label.clients' => 'Klienci', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 4355f748d..7a508d98d 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -156,6 +156,7 @@ 'label.users' => 'Usuários', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Cliente', 'label.clients' => 'Clientes', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9225d2bfc..2ec859189 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -163,6 +163,7 @@ 'label.users' => 'Usuários', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', // 'label.client' => 'Client', // 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index a3a91d752..978117524 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -172,6 +172,7 @@ 'label.users' => 'Utilizatori', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Client', 'label.clients' => 'Clienti', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index f11fff5bc..d026b2811 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -143,6 +143,7 @@ 'label.user' => 'Пользователь', 'label.users' => 'Сотрудники', 'label.group' => 'Группа', +'label.subgroups' => 'Подгруппы', 'label.roles' => 'Роли', 'label.client' => 'Клиент', 'label.clients' => 'Клиенты', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 0bd2af038..5f454d1a6 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -163,6 +163,7 @@ 'label.users' => 'Používatelia', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Klient', 'label.clients' => 'Klienti', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index be971e790..f980d69e3 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -161,6 +161,7 @@ // 'label.user' => 'User', // 'label.users' => 'Users', // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', // 'label.client' => 'Client', // 'label.clients' => 'Clients', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index aef73a45f..5165ca61b 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -156,6 +156,7 @@ 'label.users' => 'Korisnici', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Klijent', 'label.clients' => 'Klijenti', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index fe4ab32db..a8e793364 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -152,6 +152,7 @@ 'label.users' => 'Användare', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Kund', 'label.clients' => 'Kunder', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index a0916ba99..2600f1d40 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -177,6 +177,7 @@ 'label.users' => 'Kullanıcılar', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => 'Müşteri', 'label.clients' => 'Müşteriler', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5cabb5fc1..511963efb 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -162,6 +162,7 @@ 'label.users' => '用户', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => '客户', 'label.clients' => '客户', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 168a6d442..49fd53b6d 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -169,6 +169,7 @@ 'label.users' => '用戶', // TODO: translate the following. // 'label.group' => 'Group', +// 'label.subgroups' => 'Subgroups', // 'label.roles' => 'Roles', 'label.client' => '客戶', 'label.clients' => '客戶', From d6a5ffec0f76b9ab5b1ee4f8e69ecdb2afd7c0ff Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 08:49:12 +0000 Subject: [PATCH 0396/1848] A bit more progress on subgroups. --- WEB-INF/lib/ttUser.class.php | 14 ++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 8 ++++++++ groups.php | 4 ++-- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 6bac7cb46..86174547e 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -410,6 +410,20 @@ function getGroups() { return $groups; } + // getSubgroups obtains a list of immediate subgroups. + function getSubgroups() { + $mdb2 = getConnection(); + + $sql = "select id, name from tt_groups where org_id = $this->org_id and parent_id = ".$this->getActiveGroup();; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $groups[] = array('id'=>$val['id'],'name'=>$val['name']); + } + } + return $groups; + } + // getUser function is used to manage users in group and returns user details. // At the moment, the function is used for user edits and deletes. function getUser($user_id) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9a9be2d06..53f93aceb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} +{if $smarty.const.SUBGROUP_DEBUG == 'true'} + {if $user->can('manage_subgroups')} + + + + + {/if} +{/if} diff --git a/groups.php b/groups.php index 5a612c130..12e54da20 100644 --- a/groups.php +++ b/groups.php @@ -39,7 +39,7 @@ } // End of access checks. -$smarty->assign('groups', $user->getGroups()); -$smarty->assign('title', $i18n->get('title.groups')); +$smarty->assign('groups', $user->getSubgroups()); +$smarty->assign('title', $i18n->get('label.subgroups')); $smarty->assign('content_page_name', 'groups.tpl'); $smarty->display('index.tpl'); From d25b2051caf684cb847977474f03ee0d3c1046e4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 13:15:32 +0000 Subject: [PATCH 0397/1848] Introduced menu.subgroups in translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 37 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index c74d35a36..d42e37e6b 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -63,6 +63,7 @@ 'menu.users' => 'Usuaris', 'menu.groups' => 'Grups', // TODO: translate the following. +// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Clients', 'menu.options' => 'Opcions', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index dc118550f..526b2215d 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -64,6 +64,7 @@ 'menu.users' => 'Uživatelů', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Export', 'menu.clients' => 'Zákazníci', // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 01a71f892..02b75e54d 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -59,6 +59,7 @@ 'menu.users' => 'Brugere', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Eksport', 'menu.clients' => 'Kunder', 'menu.options' => 'Indstillinger', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index aa828b220..b0729b6ea 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -56,6 +56,8 @@ 'menu.tasks' => 'Aufgaben', 'menu.users' => 'Personen', 'menu.groups' => 'Gruppen', +// TODO: translate the following. +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Exportieren', 'menu.clients' => 'Kunden', 'menu.options' => 'Optionen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 31a243414..c230ebad5 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -47,6 +47,7 @@ 'menu.create_group' => 'Create Group', 'menu.profile' => 'Profile', 'menu.group' => 'Group', +'menu.subgroups' => 'Subgroups', 'menu.plugins' => 'Plugins', 'menu.time' => 'Time', 'menu.expenses' => 'Expenses', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index f9139807c..d9db4ffe9 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -62,6 +62,7 @@ 'menu.users' => 'Personas', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Clientes', 'menu.options' => 'Opciones', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 03d5c3603..bbd21100e 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -65,6 +65,7 @@ 'menu.users' => 'Kasutajad', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Kliendid', 'menu.options' => 'Suvandid', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index e90fd976c..41e87c53a 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -60,6 +60,7 @@ 'menu.users' => 'کاربران', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'پشتیبانی', 'menu.clients' => 'مشتری ها', 'menu.options' => 'تنظیمات', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 8ec0afc59..3ed9b100f 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -59,6 +59,7 @@ 'menu.users' => 'Käyttäjät', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Vie', 'menu.clients' => 'Asiakkaat', 'menu.options' => 'Optiot', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 9805bfd4c..fd6cef4d9 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -59,6 +59,7 @@ 'menu.users' => 'Utilisateurs', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Exporter', 'menu.clients' => 'Clients', 'menu.options' => 'Options', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 90a5fea85..f2b7551c7 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -56,6 +56,8 @@ 'menu.tasks' => 'Εργασίες', 'menu.users' => 'Χρήστες', 'menu.groups' => 'Ομάδες', +// TODO: translate the following. +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Εξαγωγή', 'menu.clients' => 'Πελάτες', 'menu.options' => 'Επιλογές', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 615e40ada..8433cc585 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -61,6 +61,7 @@ 'menu.users' => 'משתמשים', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'ייצוא', 'menu.clients' => 'לקוחות', 'menu.options' => 'אפשרויות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index bcb236bc9..d5a3bb12a 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -63,6 +63,8 @@ // 'menu.users' => 'Users', 'menu.groups' => 'Csoportok', // TODO: translate the following. +// 'menu.subgroups' => 'Subgroups', +// TODO: translate the following. // 'menu.export' => 'Export', 'menu.clients' => 'Ügyfelek', 'menu.options' => 'Opciók', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index fa488a65e..fdb1df325 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -58,6 +58,8 @@ 'menu.tasks' => 'Compiti', 'menu.users' => 'Utenti', 'menu.groups' => 'Gruppi', +// TODO: translate the following. +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Esportazione', 'menu.clients' => 'Clienti', 'menu.options' => 'Opzioni', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 142e4c684..6eb90e805 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -63,6 +63,7 @@ 'menu.users' => 'ユーザー', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'クライアント', 'menu.options' => 'オプション', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index f30d279e4..03730d428 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -63,6 +63,7 @@ 'menu.users' => '사용자', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => '클라이언트', 'menu.options' => '옵션', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index c6786e0c7..26f76b55a 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -56,6 +56,8 @@ 'menu.tasks' => 'Taken', 'menu.users' => 'Medewerkers', 'menu.groups' => 'Groepen', +// TODO: translate the following. +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Exporteren', 'menu.clients' => 'Klanten', 'menu.options' => 'Opties', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index c14345d1b..7202ac1c2 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -63,6 +63,7 @@ 'menu.users' => 'Brukere', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Eksport', 'menu.clients' => 'Klienter', 'menu.options' => 'Opsjoner', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 92df49acb..5e448b729 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -59,6 +59,7 @@ 'menu.users' => 'Użytkownicy', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Eksport', 'menu.clients' => 'Klienci', 'menu.options' => 'Opcje', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 7a508d98d..9c20ecd7c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -59,6 +59,7 @@ 'menu.users' => 'Usuários', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Exportar', 'menu.clients' => 'Clientes', 'menu.options' => 'Opções', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 2ec859189..fd0f8d680 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -65,6 +65,7 @@ 'menu.users' => 'Usuários', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', // 'menu.clients' => 'Clients', 'menu.options' => 'Opções', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 978117524..2f9bcfef7 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -65,6 +65,7 @@ 'menu.users' => 'Utilizatori', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Clienti', // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index d026b2811..44b702b07 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -56,6 +56,7 @@ 'menu.tasks' => 'Задачи', 'menu.users' => 'Пользователи', 'menu.groups' => 'Группы', +'menu.subgroups' => 'Подгруппы', 'menu.export' => 'Экспорт', 'menu.clients' => 'Клиенты', 'menu.options' => 'Опции', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 5f454d1a6..630ba5a73 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -60,6 +60,7 @@ 'menu.users' => 'Používatelia', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Export', 'menu.clients' => 'Klienti', 'menu.options' => 'Nastavenia', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index f980d69e3..ec6ad45d2 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -63,6 +63,7 @@ // 'menu.tasks' => 'Tasks', // 'menu.users' => 'Users', // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Stranke', 'menu.options' => 'Možnosti', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 5165ca61b..bc411671b 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -59,6 +59,7 @@ 'menu.users' => 'Korisnici', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Izvoz', 'menu.clients' => 'Klijenti', 'menu.options' => 'Opcije', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index a8e793364..969380b5d 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -56,6 +56,8 @@ 'menu.tasks' => 'Arbetsuppgifter', 'menu.users' => 'Användare', 'menu.groups' => 'Grupper', +// TODO: translate the following. +// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Exportera', 'menu.clients' => 'Kunder', 'menu.options' => 'Alternativ', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 2600f1d40..cf64056a0 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -65,6 +65,7 @@ 'menu.users' => 'Kullanıcılar', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Müşteriler', // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 511963efb..36b078454 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -59,6 +59,7 @@ 'menu.users' => '用户', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => '导出数据', 'menu.clients' => '客户', 'menu.options' => '选项', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 49fd53b6d..d6eebdb90 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -61,6 +61,7 @@ 'menu.users' => '用戶', // TODO: translate the following. // 'menu.groups' => 'Groups', +// 'menu.subgroups' => 'Subgroups', 'menu.export' => '輸出資料', 'menu.clients' => '客戶', 'menu.options' => '選項', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 53f93aceb..7fa4b1383 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.25.4477 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4478 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index ef00ca4db..ea46bec6f 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -41,6 +41,14 @@ function handleTaskRequiredCheckbox() { {$i18n.label.configure}
{$i18n.label.subgroups}:{$i18n.label.configure}
{$i18n.label.language}: {$forms.groupForm.lang.control}
-
 Anuko Time Tracker 1.18.25.4478 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4479 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 235858d0ca557daca78f85706512dfd01fe1f77d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 13:44:18 +0000 Subject: [PATCH 0398/1848] Introduced title.subgroups in translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 4 +++- WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 4 +++- WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 48 insertions(+), 3 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index d42e37e6b..47b3e8a19 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -262,6 +262,7 @@ 'title.login' => 'Sessió iniciada', 'title.groups' => 'Grups', // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Eliminar grup', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 526b2215d..179b5a3c7 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -272,6 +272,7 @@ 'title.login' => 'Přihlásit', 'title.groups' => 'Týmy', // TODO: change "teams" to "groups". // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Smazat tým', // TODO: change "team" to "group". @@ -336,6 +337,7 @@ 'title.profile' => 'Profil', // TODO: translate the following. // 'title.group' => 'Group Settings', +// 'title.subgroups' => 'Subgroups', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 02b75e54d..0fe7c608a 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -241,7 +241,9 @@ // Form titles. 'title.login' => 'Login', 'title.groups' => 'Teams', // TODO: change "teams" to "groups". -'title.create_gtoup' => 'Opret Team', // TODO: change "team" to "group". +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', +'title.create_group' => 'Opret Team', // TODO: change "team" to "group". 'title.edit_group' => 'Redigér Team', // TODO: change "team" to "group". 'title.delete_group' => 'Slet Team', // TODO: change "team" to "group". 'title.reset_password' => 'Nulstilling af Adgangskode', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index b0729b6ea..6a90ab1fa 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -229,6 +229,8 @@ // Form titles. 'title.login' => 'Anmelden', 'title.groups' => 'Gruppen', +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Gruppe anlegen', 'title.edit_group' => 'Gruppe bearbeiten', 'title.delete_group' => 'Gruppe löschen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index c230ebad5..fbe1f0dcd 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -225,6 +225,7 @@ // Form titles. 'title.login' => 'Login', 'title.groups' => 'Groups', +'title.subgroups' => 'Subgroups', 'title.create_group' => 'Creating Group', 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Deleting Group', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index d9db4ffe9..b525fe61a 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -261,6 +261,7 @@ 'title.login' => 'Sesión iniciada', 'title.groups' => 'Grupos', // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', // 'title.delete_group' => 'Deleting Group', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index bbd21100e..56459f121 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -269,6 +269,7 @@ 'title.login' => 'Login', 'title.groups' => 'Meeskonnad', // TODO: change "teams" to "groups". // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Kustuta meeskond', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 41e87c53a..dd3e879e1 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -252,6 +252,8 @@ // Form titles. 'title.login' => 'ورود', 'title.groups' => 'تیم ها', // TODO: change "teams" to "groups". +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'ایجاد تیم', // TODO: change "team" to "group". // TODO: translate the following. // 'title.edit_group' => 'Editing Group', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 3ed9b100f..18eb89c09 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -244,7 +244,9 @@ // Form titles. 'title.login' => 'Kirjautuminen', -'title.groupd' => 'Tiimit', // TODO: change "teams" to "groups". +'title.groups' => 'Tiimit', // TODO: change "teams" to "groups". +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Tiimin luonti', // TODO: change "team" to "group". 'title.edit_group' => 'Tiimin muokkaus', // TODO: change "team" to "group". 'title.delete_group' => 'Tiimin poisto', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index fd6cef4d9..e0e4eb9a5 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -239,6 +239,8 @@ // Form titles. 'title.login' => 'Connexion', 'title.groups' => 'Équipes', // TODO: change "teams" to "groups". +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Création d\\\'une nouvelle équipe', // TODO: change "team" to "group". 'title.edit_group' => 'Modification d\\\'une équipe', // TODO: change "team" to "group". 'title.delete_group' => 'Suppression d\\\'une équipe', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index f2b7551c7..fbdf23950 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -232,6 +232,8 @@ // Form titles. 'title.login' => 'Σύνδεση', 'title.groups' => 'Ομάδες', +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Δημιουργία ομάδας', 'title.edit_group' => 'Επεξεργασία ομάδας', 'title.delete_group' => 'Διαγραφή ομάδας', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 8433cc585..a1b09733c 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -262,6 +262,8 @@ // Form titles. 'title.login' => 'כניסה', 'title.groups' => 'צוותים', // TODO: change "teams" to "groups". +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'יצירת צוות', // TODO: change "team" to "group". // TODO: translate the following. // 'title.edit_group' => 'Editing Group', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index d5a3bb12a..a7bcb7874 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -263,6 +263,7 @@ 'title.login' => 'Bejelentkezés', 'title.groups' => 'Csoportok', // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Csoport törlése', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index fdb1df325..5dcf7f3d8 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -240,6 +240,8 @@ // Specifically: Eliminazione vs Elimina - we probably want nouns in titles. 'title.login' => 'Login', 'title.groups' => 'Gruppi', +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Creazione gruppo', 'title.edit_group' => 'Modifica gruppo', 'title.delete_group' => 'Elimina gruppo', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 6eb90e805..917112ac0 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -268,6 +268,7 @@ 'title.login' => 'ログイン', 'title.groups' => 'チーム', // TODO: change "teams" to "groups". // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'チームの削除', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 03730d428..b78d5b364 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -268,6 +268,7 @@ 'title.login' => '로그인', 'title.groups' => '팀', // TODO: change "teams" to "groups". // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => '팀 삭제', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 26f76b55a..20b42e1ed 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -226,6 +226,8 @@ // Form titles. 'title.login' => 'Aanmelden', 'title.groups' => 'Groepen', +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Groep maken', 'title.edit_group' => 'Groep bewerken', 'title.delete_group' => 'Groep aan het verwijderen', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 7202ac1c2..60899aeea 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -266,6 +266,7 @@ 'title.login' => 'Innlogging', // TODO: translate the following. // 'title.groups' => 'Groups', +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Slett team', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 5e448b729..d2bc47b39 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -246,6 +246,8 @@ // Form titles. 'title.login' => 'Logowanie', 'title.groups' => 'Zespoły', // TODO: change "teams" to "groups". +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Zakładanie zespołu', // TODO: change "team" to "group". 'title.edit_group' => 'Edytowanie zespołu', // TODO: change "team" to "group". 'title.delete_group' => 'Usuwanie zespołu', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 9c20ecd7c..5895273ca 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -243,6 +243,8 @@ // Form titles. 'title.login' => 'Login', 'title.groups' => 'Equipes', // TODO: change "teams" to "groups". +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Criando equipe', // TODO: change "team" to "group". 'title.edit_group' => 'Editando equipe', // TODO: change "team" to "group". 'title.delete_group' => 'Apagando equipe', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index fd0f8d680..52abd787e 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -253,6 +253,7 @@ 'title.login' => 'Login', // TODO: translate the following. // 'title.groups' => 'Groups', +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', // 'title.delete_group' => 'Deleting Group', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 2f9bcfef7..e7e638be3 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -268,6 +268,7 @@ 'title.login' => 'Autentificare', 'title.groups' => 'Echipe', // TODO: change "teams" to "groups". // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Team', // 'title.edit_group' => 'Editing Team', 'title.delete_group' => 'Șterge echipa', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 44b702b07..5c364bb15 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -224,6 +224,7 @@ // Form titles. 'title.login' => 'Вход в систему', 'title.groups' => 'Группы', +'title.subgroups' => 'Подгруппы', 'title.create_group' => 'Создание группы', 'title.edit_group' => 'Редактирование группы', 'title.delete_group' => 'Удаление группы', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 630ba5a73..2b2fe7376 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -252,6 +252,8 @@ // Form titles. 'title.login' => 'Prihlásenie', 'title.groups' => 'Tímy', // TODO: change "teams" to "groups". +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Vytváranie tímu', // TODO: change "team" to "group". // TODO: translate the following. // 'title.edit_group' => 'Editing Group', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ec6ad45d2..dafd82b72 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -248,6 +248,7 @@ 'title.login' => 'Prijava', 'title.groups' => 'Timi', // TODO: change "teams" to "groups". // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', // 'title.delete_group' => 'Deleting Group', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index bc411671b..79712abf7 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -244,6 +244,8 @@ // Form titles. 'title.login' => 'Prijava', 'title.groups' => 'Timovi', // TODO: change "teams" to "groups". +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Napravi tim', // TODO: change "team" to "group". 'title.edit_group' => 'Izmeni tim', // TODO: change "team" to "group". 'title.delete_group' => 'Obriši tim', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 969380b5d..785a88ee4 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -240,6 +240,8 @@ // Rubriker för formulär 'title.login' => 'Logga in', 'title.groups' => 'Grupper', +// TODO: translate the following. +// 'title.subgroups' => 'Subgroups', 'title.create_group' => 'Skapa grupp', 'title.edit_group' => 'Redigera grupp', 'title.delete_group' => 'Ta bort grupp', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index cf64056a0..b813f8a46 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -277,6 +277,7 @@ 'title.login' => 'Giriş', 'title.groups' => 'Ekipler', // TODO: change "teams" to "groups". // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Ekibi sil', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 36b078454..4ecbc340d 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -257,6 +257,7 @@ 'title.login' => '登录', 'title.groups' => '团队', // TODO: change "teams" to "groups". // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => '删除团队', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index d6eebdb90..40a5265c7 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -264,6 +264,7 @@ 'title.login' => '登錄', 'title.groups' => '團隊', // TODO: change "teams" to "groups". // TODO: translate the following. +// 'title.subgroups' => 'Subgroups', // 'title.create_group' => 'Creating Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => '刪除團隊', // TODO: change "team" to "group". diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7fa4b1383..d4a8f9087 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.25.4479 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4480 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 62bebb89af9afb9c4008d799c67e24988cb3688d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 14:18:28 +0000 Subject: [PATCH 0399/1848] Refactoring - renamed title.create_group with title.add_group for consistency. --- WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/cs.lang.php | 2 +- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/en.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 3 +-- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 3 +-- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 4 ++-- WEB-INF/resources/ru.lang.php | 4 ++-- WEB-INF/resources/sk.lang.php | 3 +-- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 +- WEB-INF/resources/sv.lang.php | 2 +- WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- WEB-INF/resources/zh-tw.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- admin_group_add.php | 2 +- register.php | 2 +- 33 files changed, 35 insertions(+), 38 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 47b3e8a19..b250c85d9 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -263,7 +263,7 @@ 'title.groups' => 'Grups', // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Eliminar grup', 'title.reset_password' => 'Restablir paraula de pas', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 179b5a3c7..12cf6ba1c 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -273,7 +273,7 @@ 'title.groups' => 'Týmy', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Smazat tým', // TODO: change "team" to "group". 'title.reset_password' => 'Resetovat heslo', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 0fe7c608a..581b3056d 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -243,7 +243,7 @@ 'title.groups' => 'Teams', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Opret Team', // TODO: change "team" to "group". +// 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Redigér Team', // TODO: change "team" to "group". 'title.delete_group' => 'Slet Team', // TODO: change "team" to "group". 'title.reset_password' => 'Nulstilling af Adgangskode', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 6a90ab1fa..be82a10d9 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -231,7 +231,7 @@ 'title.groups' => 'Gruppen', // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Gruppe anlegen', +'title.add_group' => 'Gruppe anlegen', 'title.edit_group' => 'Gruppe bearbeiten', 'title.delete_group' => 'Gruppe löschen', 'title.reset_password' => 'Passworterinnerung', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index fbe1f0dcd..3c955c3e9 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -226,7 +226,7 @@ 'title.login' => 'Login', 'title.groups' => 'Groups', 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Creating Group', +'title.add_group' => 'Adding Group', 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Deleting Group', 'title.reset_password' => 'Resetting Password', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index b525fe61a..71efd88c7 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -262,7 +262,7 @@ 'title.groups' => 'Grupos', // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', // 'title.delete_group' => 'Deleting Group', 'title.reset_password' => 'Reestablecer contraseña', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 56459f121..338765bd0 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -270,7 +270,7 @@ 'title.groups' => 'Meeskonnad', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Kustuta meeskond', // TODO: change "team" to "group". 'title.reset_password' => 'Tühjenda salasõna', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index dd3e879e1..ccc73725b 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -254,8 +254,7 @@ 'title.groups' => 'تیم ها', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'ایجاد تیم', // TODO: change "team" to "group". -// TODO: translate the following. +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'حذف تیم', // TODO: change "team" to "group". 'title.reset_password' => 'بازیابی رمزعبور', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 18eb89c09..37477d1c7 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -247,7 +247,7 @@ 'title.groups' => 'Tiimit', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Tiimin luonti', // TODO: change "team" to "group". +// 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Tiimin muokkaus', // TODO: change "team" to "group". 'title.delete_group' => 'Tiimin poisto', // TODO: change "team" to "group". 'title.reset_password' => 'Salasanan nollaus', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index e0e4eb9a5..983bb1b0e 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -241,7 +241,7 @@ 'title.groups' => 'Équipes', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Création d\\\'une nouvelle équipe', // TODO: change "team" to "group". +// 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Modification d\\\'une équipe', // TODO: change "team" to "group". 'title.delete_group' => 'Suppression d\\\'une équipe', // TODO: change "team" to "group". 'title.reset_password' => 'Réinitialisation du mot de passe', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index fbdf23950..ea70b4b41 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -234,7 +234,7 @@ 'title.groups' => 'Ομάδες', // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Δημιουργία ομάδας', +// 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Επεξεργασία ομάδας', 'title.delete_group' => 'Διαγραφή ομάδας', 'title.reset_password' => 'Επαναφορά κωδικού πρόσβασης', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index a1b09733c..0df67c7fc 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -264,8 +264,7 @@ 'title.groups' => 'צוותים', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'יצירת צוות', // TODO: change "team" to "group". -// TODO: translate the following. +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'מחיקת צוות', // TODO: change "team" to "group". 'title.reset_password' => 'איפוס סיסמה', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index a7bcb7874..305d5b6be 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -264,7 +264,7 @@ 'title.groups' => 'Csoportok', // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Csoport törlése', // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 5dcf7f3d8..2d9a3cf44 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -242,7 +242,7 @@ 'title.groups' => 'Gruppi', // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Creazione gruppo', +// 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Modifica gruppo', 'title.delete_group' => 'Elimina gruppo', 'title.reset_password' => 'Reset password', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 917112ac0..8bb27cfde 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -269,7 +269,7 @@ 'title.groups' => 'チーム', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'チームの削除', // TODO: change "team" to "group". 'title.reset_password' => 'パスワードの初期化', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index b78d5b364..825971039 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -269,7 +269,7 @@ 'title.groups' => '팀', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => '팀 삭제', // TODO: change "team" to "group". 'title.reset_password' => '암호 재설정', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 20b42e1ed..a23985599 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -228,7 +228,7 @@ 'title.groups' => 'Groepen', // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Groep maken', +// 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Groep bewerken', 'title.delete_group' => 'Groep aan het verwijderen', 'title.reset_password' => 'Wachtwoord herstellen', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 60899aeea..6b4e37604 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -267,7 +267,7 @@ // TODO: translate the following. // 'title.groups' => 'Groups', // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Slett team', // TODO: change "team" to "group". // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index d2bc47b39..dc79976db 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -248,7 +248,7 @@ 'title.groups' => 'Zespoły', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Zakładanie zespołu', // TODO: change "team" to "group". +// 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Edytowanie zespołu', // TODO: change "team" to "group". 'title.delete_group' => 'Usuwanie zespołu', // TODO: change "team" to "group". 'title.reset_password' => 'Resetowanie hasła', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 5895273ca..1ad30fcc1 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -245,7 +245,7 @@ 'title.groups' => 'Equipes', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Criando equipe', // TODO: change "team" to "group". +// 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Editando equipe', // TODO: change "team" to "group". 'title.delete_group' => 'Apagando equipe', // TODO: change "team" to "group". 'title.reset_password' => 'Resetando a senha', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 52abd787e..fd50d487a 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -254,7 +254,7 @@ // TODO: translate the following. // 'title.groups' => 'Groups', // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', // 'title.delete_group' => 'Deleting Group', // 'title.reset_password' => 'Resetting Password', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index e7e638be3..37f55ba8d 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -269,8 +269,8 @@ 'title.groups' => 'Echipe', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Team', -// 'title.edit_group' => 'Editing Team', +// 'title.add_group' => 'Adding Group', +// 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Șterge echipa', // TODO: change "team" to "group". 'title.reset_password' => 'Reseteaza parola', // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 5c364bb15..d02b91c5d 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -225,7 +225,7 @@ 'title.login' => 'Вход в систему', 'title.groups' => 'Группы', 'title.subgroups' => 'Подгруппы', -'title.create_group' => 'Создание группы', +'title.add_group' => 'Добавление группы', 'title.edit_group' => 'Редактирование группы', 'title.delete_group' => 'Удаление группы', 'title.reset_password' => 'Cброс пароля', @@ -247,7 +247,7 @@ 'title.send_invoice' => 'Отсылка счёта', 'title.charts' => 'Диаграммы', 'title.projects' => 'Проекты', -'title.add_project' => 'Создание проекта', +'title.add_project' => 'Добавление проекта', 'title.edit_project' => 'Редактирование проекта', 'title.delete_project' => 'Удаление проекта', 'title.tasks' => 'Задачи', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 2b2fe7376..a4dee66f7 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -254,8 +254,7 @@ 'title.groups' => 'Tímy', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Vytváranie tímu', // TODO: change "team" to "group". -// TODO: translate the following. +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Vymazávanie tímu', // TODO: change "team" to "group". 'title.reset_password' => 'Obnovovanie hesla', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index dafd82b72..c989f8a2c 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -249,7 +249,7 @@ 'title.groups' => 'Timi', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', // 'title.delete_group' => 'Deleting Group', 'title.reset_password' => 'Razveljavi geslo', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 79712abf7..73baaf8bd 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -246,7 +246,7 @@ 'title.groups' => 'Timovi', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Napravi tim', // TODO: change "team" to "group". +// 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Izmeni tim', // TODO: change "team" to "group". 'title.delete_group' => 'Obriši tim', // TODO: change "team" to "group". 'title.reset_password' => 'Resetuj Lozinku', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 785a88ee4..84716b72e 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -242,7 +242,7 @@ 'title.groups' => 'Grupper', // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -'title.create_group' => 'Skapa grupp', +// 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Redigera grupp', 'title.delete_group' => 'Ta bort grupp', 'title.reset_password' => 'Återställ lösenord', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index b813f8a46..9bcab60d8 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -278,7 +278,7 @@ 'title.groups' => 'Ekipler', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Ekibi sil', // TODO: change "team" to "group". 'title.reset_password' => 'Parolayı sıfırla', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 4ecbc340d..f8104a67e 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -258,7 +258,7 @@ 'title.groups' => '团队', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => '删除团队', // TODO: change "team" to "group". 'title.reset_password' => '重设密码', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 40a5265c7..a2cbd5188 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -265,7 +265,7 @@ 'title.groups' => '團隊', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.subgroups' => 'Subgroups', -// 'title.create_group' => 'Creating Group', +// 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => '刪除團隊', // TODO: change "team" to "group". 'title.reset_password' => '重設密碼', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d4a8f9087..40e99b909 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.25.4480 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4481 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_group_add.php b/admin_group_add.php index e40be98e4..40d7a8748 100644 --- a/admin_group_add.php +++ b/admin_group_add.php @@ -117,5 +117,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.groupForm.group_name.focus()"'); $smarty->assign('content_page_name', 'admin_group_add.tpl'); -$smarty->assign('title', $i18n->get('title.create_group')); +$smarty->assign('title', $i18n->get('title.add_group')); $smarty->display('index.tpl'); diff --git a/register.php b/register.php index 4568e3709..298f2818f 100644 --- a/register.php +++ b/register.php @@ -111,7 +111,7 @@ } } // isPost -$smarty->assign('title', $i18n->get('title.create_group')); +$smarty->assign('title', $i18n->get('title.add_group')); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.groupForm.group_name.focus()"'); $smarty->assign('content_page_name', 'register.tpl'); From 69915aba68a312fb2080c2356a482736efc254ae Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 14:38:03 +0000 Subject: [PATCH 0400/1848] Replaced usage of title.group with title.group_edit. --- WEB-INF/resources/ca.lang.php | 1 - WEB-INF/resources/cs.lang.php | 2 -- WEB-INF/resources/da.lang.php | 2 -- WEB-INF/resources/de.lang.php | 1 - WEB-INF/resources/en.lang.php | 1 - WEB-INF/resources/es.lang.php | 1 - WEB-INF/resources/et.lang.php | 1 - WEB-INF/resources/fa.lang.php | 2 -- WEB-INF/resources/fi.lang.php | 2 -- WEB-INF/resources/fr.lang.php | 2 -- WEB-INF/resources/gr.lang.php | 2 -- WEB-INF/resources/he.lang.php | 2 -- WEB-INF/resources/hu.lang.php | 1 - WEB-INF/resources/it.lang.php | 2 -- WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 1 - WEB-INF/resources/no.lang.php | 1 - WEB-INF/resources/pl.lang.php | 2 -- WEB-INF/resources/pt-br.lang.php | 2 -- WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 1 - WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 2 -- WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 2 -- WEB-INF/resources/sv.lang.php | 2 -- WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 1 - WEB-INF/resources/zh-tw.lang.php | 1 - WEB-INF/templates/footer.tpl | 2 +- group_edit.php | 2 +- 32 files changed, 2 insertions(+), 45 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index b250c85d9..a0accefda 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -325,7 +325,6 @@ 'title.options' => 'Opcions', 'title.profile' => 'Perfil', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 12cf6ba1c..a42826fad 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -336,8 +336,6 @@ // 'title.options' => 'Options', 'title.profile' => 'Profil', // TODO: translate the following. -// 'title.group' => 'Group Settings', -// 'title.subgroups' => 'Subgroups', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 581b3056d..7eaec94cc 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -298,8 +298,6 @@ 'title.import' => 'Importer Team Data', // TODO: replace "team" with "group". 'title.options' => 'Indstillinger', 'title.profile' => 'Profil', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Brugerdefineret Felt', 'title.cf_add_custom_field' => 'Tilføj Brugerdefineret Felt', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index be82a10d9..627941493 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -281,7 +281,6 @@ 'title.import' => 'Daten importieren', 'title.options' => 'Optionen', 'title.profile' => 'Profil', -'title.group' => 'Gruppeneinstellungen', 'title.plugins' => 'Erweiterungen', 'title.cf_custom_fields' => 'Benutzerfelder', 'title.cf_add_custom_field' => 'Benutzerfeld hinzufügen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 3c955c3e9..6d7a47c73 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -280,7 +280,6 @@ 'title.import' => 'Importing Group Data', 'title.options' => 'Options', 'title.profile' => 'Profile', -'title.group' => 'Group Settings', 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Custom Fields', 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 71efd88c7..b53ebd944 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -324,7 +324,6 @@ 'title.options' => 'Opciones', 'title.profile' => 'Perfil', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 338765bd0..4aede3a4d 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -332,7 +332,6 @@ 'title.options' => 'Suvandid', 'title.profile' => 'Profiili', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index ccc73725b..140da1bcb 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -306,8 +306,6 @@ 'title.import' => 'وارد کردن اطلاعات تیم', // TODO: replace "team" with "group". 'title.options' => 'گزینه ها', 'title.profile' => 'پروفایل', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'پلاگین ها', 'title.cf_custom_fields' => 'فیلدهای سفارشی', 'title.cf_add_custom_field' => 'درج فیلد سفارشی', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 37477d1c7..f290ff5ba 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -299,8 +299,6 @@ 'title.import' => 'Tiimitietojen tunti', // TODO: replace "team" with "group". 'title.options' => 'Optiot', 'title.profile' => 'Profiili', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'Lisäosat', 'title.cf_custom_fields' => 'Omat kentät', 'title.cf_add_custom_field' => 'Oman kentän lisäys', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 983bb1b0e..d4f372b17 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -292,8 +292,6 @@ 'title.import' => 'Importation des données', 'title.options' => 'Options', 'title.profile' => 'Profil', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Champs personalisés', 'title.cf_add_custom_field' => 'Ajout d\\\'un champ', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index ea70b4b41..ef78fd501 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -288,8 +288,6 @@ 'title.import' => 'Εισαγωγή δεδομένων ομάδας', 'title.options' => 'Επιλογές', 'title.profile' => 'Προφίλ', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'Πρόσθετα', 'title.cf_custom_fields' => 'Προσαρμοσμένα πεδία', 'title.cf_add_custom_field' => 'Προσθήκη προσαρμοσμένου πεδίου', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 0df67c7fc..661ff27a4 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -317,8 +317,6 @@ 'title.import' => 'ייבוא נתוני צוות', // TODO: replace "team" with "group". 'title.options' => 'אפשרויות', 'title.profile' => 'פרופיל', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'תוספים', 'title.cf_custom_fields' => 'שדות אישיים', 'title.cf_add_custom_field' => 'הוספת שדה אישי', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 305d5b6be..30d9a9a0e 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -324,7 +324,6 @@ 'title.options' => 'Opciók', 'title.profile' => 'Profil', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 2d9a3cf44..2f0535781 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -297,8 +297,6 @@ 'title.import' => 'Importa i dati del gruppo', 'title.options' => 'Opzioni', 'title.profile' => 'Profilo', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'Plugin', 'title.cf_custom_fields' => 'Campi personalizzati', 'title.cf_add_custom_field' => 'Aggiunta campo personalizzato', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 8bb27cfde..29a7a034b 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -331,7 +331,6 @@ 'title.options' => 'オプション', 'title.profile' => 'プロファイル', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 825971039..f8d99f1b4 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -332,7 +332,6 @@ 'title.options' => '옵션', 'title.profile' => '프로필', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index a23985599..531953e23 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -282,7 +282,6 @@ 'title.import' => 'Importeer groepsgegevens', 'title.options' => 'Opties', 'title.profile' => 'Profiel', -'title.group' => 'Groep instelling', 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Eigen velden', 'title.cf_add_custom_field' => 'Eigen veld toevoegen', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 6b4e37604..35ec512be 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -328,7 +328,6 @@ 'title.options' => 'Opsjoner', 'title.profile' => 'Profil', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index dc79976db..301e002cb 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -299,8 +299,6 @@ 'title.import' => 'Import danych zespołu', // TODO: replace "team" with "group". 'title.options' => 'Opcje', 'title.profile' => 'Profil', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'Dodatkowe moduły', 'title.cf_custom_fields' => 'Pola niestandardowe', 'title.cf_add_custom_field' => 'Dodawanie pola niestandardowego', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 1ad30fcc1..b97881572 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -296,8 +296,6 @@ 'title.import' => 'Importando dados de equipe', // TODO: replace "team" with "group". 'title.options' => 'Opções', 'title.profile' => 'Perfil', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Campos personalizados', 'title.cf_add_custom_field' => 'Adicionando campo personalizado', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index fd50d487a..8de4afaf0 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -312,7 +312,6 @@ 'title.options' => 'Opções', 'title.profile' => 'Perfil', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 37f55ba8d..d43f76b42 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -331,7 +331,6 @@ // 'title.options' => 'Options', 'title.profile' => 'Profil', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index d02b91c5d..40a5c1e30 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -279,7 +279,6 @@ 'title.import' => 'Импортирование данных группы', 'title.options' => 'Опции', 'title.profile' => 'Профиль', -'title.group' => 'Настройки группы', 'title.plugins' => 'Плагины', 'title.cf_custom_fields' => 'Дополнительные поля', 'title.cf_add_custom_field' => 'Добавление поля', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index a4dee66f7..de985d430 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -307,8 +307,6 @@ 'title.import' => 'Importovanie údajov o tíme', // TODO: replace "team" with "group". 'title.options' => 'Nastavenia', 'title.profile' => 'Profil', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'Doplnkové moduly', 'title.cf_custom_fields' => 'Vlastné polia', 'title.cf_add_custom_field' => 'Pridávanie vlastného poľa', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index c989f8a2c..83815f7de 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -306,7 +306,6 @@ // 'title.options' => 'Options', 'title.profile' => 'Profil', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 73baaf8bd..42ded8f94 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -297,8 +297,6 @@ 'title.import' => 'Uvoz podataka tim-a', // TODO: replace "team" with "group". 'title.options' => 'Opcije', 'title.profile' => 'Profil', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'Dodaci', 'title.cf_custom_fields' => 'Dodatna polja', 'title.cf_add_custom_field' => 'Dodavanje dodatnih polja', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 84716b72e..43c76d0e4 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -297,8 +297,6 @@ 'title.import' => 'Importera grupp', 'title.options' => 'Alternativ', 'title.profile' => 'Profil', -// TODO: translate the following. -// 'title.group' => 'Group Settings', 'title.plugins' => 'Tillägg', 'title.cf_custom_fields' => 'Egna fält', 'title.cf_add_custom_field' => 'Lägg till fält', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 9bcab60d8..d5764bedf 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -340,7 +340,6 @@ // 'title.options' => 'Options', 'title.profile' => 'Profili', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index f8104a67e..a60145578 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -320,7 +320,6 @@ 'title.options' => '选项', 'title.profile' => '简介', // TODO: translate the following. -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index a2cbd5188..c51900fac 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -327,7 +327,6 @@ 'title.options' => '選項', // TODO: translate the following. // 'title.profile' => 'Profile', -// 'title.group' => 'Group Settings', // 'title.plugins' => 'Plugins', // 'title.cf_custom_fields' => 'Custom Fields', // 'title.cf_add_custom_field' => 'Adding Custom Field', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 40e99b909..f1450a136 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.25.4481 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4482 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_edit.php b/group_edit.php index e9d5189a1..872fe1480 100644 --- a/group_edit.php +++ b/group_edit.php @@ -222,6 +222,6 @@ $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="handleTaskRequiredCheckbox(); handlePluginCheckboxes();"'); -$smarty->assign('title', $i18n->get('title.group')); +$smarty->assign('title', $i18n->get('title.edit_group')); $smarty->assign('content_page_name', 'group_edit.tpl'); $smarty->display('index.tpl'); From 7faef0e6d81444ad3ae10d1a2ce62fa753c80a9f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 15:42:59 +0000 Subject: [PATCH 0401/1848] Improved isTrue() function and its usage to streamline code. --- WEB-INF/lib/Auth.class.php | 6 +++--- WEB-INF/lib/I18n.class.php | 4 ---- WEB-INF/lib/auth/Auth_db.class.php | 2 +- WEB-INF/lib/auth/Auth_ldap.class.php | 24 ++++++++++++------------ WEB-INF/lib/common.lib.php | 2 +- WEB-INF/lib/mail/Mailer.class.php | 6 +++--- WEB-INF/templates/footer.tpl | 2 +- time.php | 2 +- tofile.php | 8 ++++---- 9 files changed, 26 insertions(+), 30 deletions(-) diff --git a/WEB-INF/lib/Auth.class.php b/WEB-INF/lib/Auth.class.php index 354d34ba2..d57a0c4a3 100644 --- a/WEB-INF/lib/Auth.class.php +++ b/WEB-INF/lib/Auth.class.php @@ -64,7 +64,7 @@ function isPasswordExternal() function doLogin($login, $password) { $auth = $this->authenticate($login, $password); - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '
'; var_dump($auth); echo '
'; } @@ -77,13 +77,13 @@ function doLogin($login, $password) { $sql = "SELECT id FROM tt_users WHERE login = ".$mdb2->quote($login)." AND status = 1"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) { - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) + if (isTrue(AUTH_DEBUG)) echo 'db error!
'; return false; } $val = $res->fetchRow(); if (!$val['id']) { - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) + if (isTrue(AUTH_DEBUG)) echo 'login "'.$login.'" does not exist in Time Tracker database.
'; return false; } diff --git a/WEB-INF/lib/I18n.class.php b/WEB-INF/lib/I18n.class.php index 0e3dd02a4..15799c23e 100644 --- a/WEB-INF/lib/I18n.class.php +++ b/WEB-INF/lib/I18n.class.php @@ -70,9 +70,7 @@ function load($localName) { $this->weekdayNames = $i18n_weekdays; $this->weekdayShortNames = $i18n_weekdays_short; -// if (defined('SHOW_HOLIDAYS') && isTrue(SHOW_HOLIDAYS)) { $this->holidays = $i18n_holidays; -// } foreach ($i18n_key_words as $kword=>$value) { $pos = strpos($kword, "."); @@ -97,9 +95,7 @@ function load($localName) { $this->monthNames = $i18n_months; $this->weekdayNames = $i18n_weekdays; $this->weekdayShortNames = $i18n_weekdays_short; -// if (defined('SHOW_HOLIDAYS') && isTrue(SHOW_HOLIDAYS)) { $this->holidays = $i18n_holidays; -// } foreach ($i18n_key_words as $kword=>$value) { if (!$value) continue; $pos = strpos($kword, "."); diff --git a/WEB-INF/lib/auth/Auth_db.class.php b/WEB-INF/lib/auth/Auth_db.class.php index 937ad3cc9..c380330c0 100644 --- a/WEB-INF/lib/auth/Auth_db.class.php +++ b/WEB-INF/lib/auth/Auth_db.class.php @@ -58,7 +58,7 @@ function authenticate($login, $password) } else { // If the OLD_PASSWORDS option is defined - set it. - if (defined('OLD_PASSWORDS') && isTrue(OLD_PASSWORDS)) { + if (isTrue(OLD_PASSWORDS)) { $sql = "SET SESSION old_passwords = 1"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/lib/auth/Auth_ldap.class.php b/WEB-INF/lib/auth/Auth_ldap.class.php index e17b6e7c9..23ea127e6 100644 --- a/WEB-INF/lib/auth/Auth_ldap.class.php +++ b/WEB-INF/lib/auth/Auth_ldap.class.php @@ -96,7 +96,7 @@ function authenticate($login, $password) $lc = ldap_connect($this->params['server']); - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '
'; echo '$lc='; var_dump($lc); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; @@ -106,7 +106,7 @@ function authenticate($login, $password) ldap_set_option($lc, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($lc, LDAP_OPT_REFERRALS, 0); - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { ldap_set_option($lc, LDAP_OPT_DEBUG_LEVEL, 7); } @@ -119,13 +119,13 @@ function authenticate($login, $password) $login .= '@' . $this->params['default_domain']; } - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '$login='; var_dump($login); echo '
'; } $lb = @ldap_bind($lc, $login, $password); - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '$lb='; var_dump($lb); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -142,7 +142,7 @@ function authenticate($login, $password) $fields = array('memberof'); $sr = @ldap_search($lc, $this->params['base_dn'], $filter, $fields); - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '$sr='; var_dump($sr); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -154,7 +154,7 @@ function authenticate($login, $password) $entries = @ldap_get_entries($lc, $sr); - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '$entries='; var_dump($entries); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -173,7 +173,7 @@ function authenticate($login, $password) $groups[] = substr($grp_fields[0], 3); } - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '$member_of'; var_dump($member_of); echo '
'; }; @@ -195,7 +195,7 @@ function authenticate($login, $password) // Assuming OpenLDAP server. $login_oldap = 'uid='.$login.','.$this->params['base_dn']; - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '$login_oldap='; var_dump($login_oldap); echo '
'; } @@ -207,7 +207,7 @@ function authenticate($login, $password) $lb = @ldap_bind($lc, $login_oldap, $password); - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '$lb='; var_dump($lb); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -225,7 +225,7 @@ function authenticate($login, $password) $fields = array('samaccountname', 'mail', 'memberof', 'department', 'displayname', 'telephonenumber', 'primarygroupid'); $sr = @ldap_search($lc, $this->params['base_dn'], $filter, $fields); - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '$sr='; var_dump($sr); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -238,7 +238,7 @@ function authenticate($login, $password) $entries = @ldap_get_entries($lc, $sr); - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '$entries='; var_dump($entries); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -258,7 +258,7 @@ function authenticate($login, $password) $groups[] = substr($grp_fields[0], 3); } - if (defined('AUTH_DEBUG') && isTrue(AUTH_DEBUG)) { + if (isTrue(AUTH_DEBUG)) { echo '$member_of'; var_dump($member_of); echo '
'; } diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index d29ba1a12..4411fb585 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -165,7 +165,7 @@ function check_extension($ext) // isTrue is a helper function to return correct false for older config.php values defined as a string 'false'. function isTrue($val) { - return ($val == false || $val === 'false') ? false : true; + return ($val === true); } // ttValidString is used to check user input to validate a string. diff --git a/WEB-INF/lib/mail/Mailer.class.php b/WEB-INF/lib/mail/Mailer.class.php index 2d674ac3d..68142028e 100644 --- a/WEB-INF/lib/mail/Mailer.class.php +++ b/WEB-INF/lib/mail/Mailer.class.php @@ -104,8 +104,8 @@ function send($subject, $data) { $port = defined('MAIL_SMTP_PORT') ? MAIL_SMTP_PORT : '25'; $username = defined('MAIL_SMTP_USER') ? MAIL_SMTP_USER : null; $password = defined('MAIL_SMTP_PASSWORD') ? MAIL_SMTP_PASSWORD : null; - $auth = (defined('MAIL_SMTP_AUTH') && isTrue(MAIL_SMTP_AUTH)) ? true : false; - $debug = (defined('MAIL_SMTP_DEBUG') && isTrue(MAIL_SMTP_DEBUG)) ? true : false; + $auth = isTrue(MAIL_SMTP_AUTH); + $debug = isTrue(MAIL_SMTP_DEBUG); $mail = Mail::factory('smtp', array ('host' => $host, 'port' => $port, @@ -116,7 +116,7 @@ function send($subject, $data) { break; } - if (defined('MAIL_SMTP_DEBUG') && isTrue(MAIL_SMTP_DEBUG)) + if (isTrue(MAIL_SMTP_DEBUG)) PEAR::setErrorHandling(PEAR_ERROR_PRINT); $res = $mail->send($recipients, $headers, $data); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f1450a136..73cd97e03 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.25.4482 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4483 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/time.php b/time.php index 68aaf40e7..9e6be9a8f 100644 --- a/time.php +++ b/time.php @@ -107,7 +107,7 @@ // Elements of timeRecordForm. $form = new Form('timeRecordForm'); -if (defined('SUBGROUP_DEBUG') && isTrue(SUBGROUP_DEBUG)) { +if (isTrue(SUBGROUP_DEBUG)) { if ($user->can('manage_subgroups')) { $groups = $user->getGroups(); if (count($groups) > 1) { diff --git a/tofile.php b/tofile.php index 07bbc11a6..445b32d94 100644 --- a/tofile.php +++ b/tofile.php @@ -94,7 +94,7 @@ print "\t<".$group_by_tag.">\n"; if ($bean->getAttribute('chduration')) { $val = $subtotal['time']; - if($val && defined('EXPORT_DECIMAL_DURATION') && isTrue(EXPORT_DECIMAL_DURATION)) + if($val && isTrue(EXPORT_DECIMAL_DURATION)) $val = time_to_decimal($val); print "\t\n"; } @@ -126,7 +126,7 @@ if ($bean->getAttribute('chfinish')) print "\t\n"; if ($bean->getAttribute('chduration')) { $duration = $item['duration']; - if($duration && defined('EXPORT_DECIMAL_DURATION') && isTrue(EXPORT_DECIMAL_DURATION)) + if($duration && isTrue(EXPORT_DECIMAL_DURATION)) $duration = time_to_decimal($duration); print "\t\n"; } @@ -179,7 +179,7 @@ print '"'.$subtotal['name'].'"'; if ($bean->getAttribute('chduration')) { $val = $subtotal['time']; - if($val && defined('EXPORT_DECIMAL_DURATION') && isTrue(EXPORT_DECIMAL_DURATION)) + if($val && isTrue(EXPORT_DECIMAL_DURATION)) $val = time_to_decimal($val); print ',"'.$val.'"'; } @@ -223,7 +223,7 @@ if ($bean->getAttribute('chfinish')) print ',"'.$item['finish'].'"'; if ($bean->getAttribute('chduration')) { $val = $item['duration']; - if($val && defined('EXPORT_DECIMAL_DURATION') && isTrue(EXPORT_DECIMAL_DURATION)) + if($val && isTrue(EXPORT_DECIMAL_DURATION)) $val = time_to_decimal($val); print ',"'.$val.'"'; } From 4782eac1a659d576f7e50e6a9e94fdfa316bfc7f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 16:05:22 +0000 Subject: [PATCH 0402/1848] Removed handling of OLD_PASSWORDS to simplify login code. --- WEB-INF/config.php.dist | 10 ---------- WEB-INF/lib/auth/Auth_db.class.php | 25 ------------------------- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 1 insertion(+), 36 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 1d852c21a..17b4d087d 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -59,16 +59,6 @@ define('MULTITEAM_MODE', true); define('APP_NAME', ''); -// OLD_PASSWORDS -// -// You may need to set this option if you migrate an older version of TT installation to a new server. -// Older versions of TT used mysql password function to hash user passwords. Newer versions use md5. -// Because the password function may behave differently between servers, the OLD_PASSWORD settings -// gives you an opportunity to control it, if needed. -// -// define('OLD_PASSWORDS', true); - - // WEEKEND_START_DAY // // This option defines which days are highlighted with weekend color. diff --git a/WEB-INF/lib/auth/Auth_db.class.php b/WEB-INF/lib/auth/Auth_db.class.php index c380330c0..a3885fb66 100644 --- a/WEB-INF/lib/auth/Auth_db.class.php +++ b/WEB-INF/lib/auth/Auth_db.class.php @@ -55,31 +55,6 @@ function authenticate($login, $password) $val = $res->fetchRow(); if ($val['id'] > 0) { return array('login'=>$login,'id'=>$val['id']); - } else { - - // If the OLD_PASSWORDS option is defined - set it. - if (isTrue(OLD_PASSWORDS)) { - $sql = "SET SESSION old_passwords = 1"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) { - die($res->getMessage()); - } - } - - // Try legacy password match. This is needed for compatibility with older versions of TT. - $sql = "SELECT id FROM tt_users - WHERE login = ".$mdb2->quote($login)." AND password = old_password(".$mdb2->quote($password).") AND status = 1"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) { - return false; // Simply return false for a meaningful error message on screen, see the comment below. - // die($res->getMessage()); // old_password() function is removed in MySQL 5.7.5. - // We are getting a confusing "MDB2 Error: not found" in this case if we die. - // TODO: perhaps it's time to simplify things and remove handling of old passwords completely. - } - $val = $res->fetchRow(); - if ($val['id'] > 0) { - return array('login'=>$login,'id'=>$val['id']); - } } // Special handling for admin@localhost - search for an account with admin role with a matching password. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 73cd97e03..04f99546c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.25.4483 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4484 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 80d8ba7ca7444b575edc4930ee45e46dca66144b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 17:01:12 +0000 Subject: [PATCH 0403/1848] Refactoring in export to use a generic get function to keep things simple. --- WEB-INF/lib/ttGroupExportHelper.class.php | 173 ++-------------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 12 insertions(+), 163 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index c6e1d9a5d..a520e7fbe 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -28,9 +28,6 @@ // ttGroupExportHelper - this class is used to write data for a single group // to a file. When group contains other groups, it reuses itself recursively. -// -// Currently, it is work in progress. -// When done, it should handle export of organizations containing multiple groups. class ttGroupExportHelper { var $group_id = null; // Group we are exporting. @@ -71,8 +68,8 @@ function __construct($group_id, $file, $indentation) { } } - // getGroupData obtains group attributes for export. - private function getGroupData() { + // getGroupAttrs obtains group attributes for export. + private function getGroupAttrs() { global $user; $mdb2 = getConnection(); @@ -85,153 +82,6 @@ private function getGroupData() { return $val; } - // The getUsers obtains all users in group for the purpose of export. - private function getUsers() { - global $user; - $mdb2 = getConnection(); - - $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id)". - " where u.group_id = $this->group_id and u.org_id = $user->org_id order by upper(u.name)"; // Note: deleted users are included. - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - - // TODO: write a generic (private?) get function for exclusive use in this class, that obtains - // all fields from a given table. - - // getRoles - obtains all roles defined for group. - function getRoles() { - global $user; - $mdb2 = getConnection(); - - $result = array(); - $sql = "select * from tt_roles where group_id = $this->group_id and org_id = $user->org_id"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - - // getTasks - obtains all tasks defined for group. - function getTasks() { - global $user; - $mdb2 = getConnection(); - - $result = array(); - $sql = "select * from tt_tasks where group_id = $this->group_id and org_id = $user->org_id"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - - // getProjects - obtains all projects defined for group. - function getProjects() { - global $user; - $mdb2 = getConnection(); - - $result = array(); - $sql = "select * from tt_projects where group_id = $this->group_id and org_id = $user->org_id"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - - // getClients - obtains all clients defined for group. - function getClients() { - global $user; - $mdb2 = getConnection(); - - $result = array(); - $sql = "select * from tt_clients where group_id = $this->group_id and org_id = $user->org_id"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - - // getFavReports - obtains all favorite reports defined for group. - function getFavReports() { - global $user; - $mdb2 = getConnection(); - - $result = array(); - $sql = "select * from tt_fav_reports where group_id = $this->group_id and org_id = $user->org_id"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - - // getPredefinedExpenses - obtains all predefined expenses for group. - function getPredefinedExpenses() { - global $user; - $mdb2 = getConnection(); - - $result = array(); - $sql = "select * from tt_predefined_expenses where group_id = $this->group_id and org_id = $user->org_id"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - - // getNotifications - obtains all notifications defined for group. - function getNotifications() { - global $user; - $mdb2 = getConnection(); - - $result = array(); - $sql = "select * from tt_cron where group_id = $this->group_id and org_id = $user->org_id"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - // getRecordsFromTable - obtains all fields from a given table for a group. function getRecordsFromTable($table_name) { global $user; @@ -254,7 +104,7 @@ function getRecordsFromTable($table_name) { function writeData() { // Write group info. - $group = $this->getGroupData(); + $group = $this->getGroupAttrs(); $group_part = "getUsers(); + $users = $this->getRecordsFromTable('tt_users'); foreach ($users as $key=>$user_item) $this->userMap[$user_item['id']] = $key + 1; // Prepare role map. - $roles = $this->getRoles(); + $roles = $this->getRecordsFromTable('tt_roles'); foreach ($roles as $key=>$role_item) $this->roleMap[$role_item['id']] = $key + 1; // Prepare task map. - $tasks = $this->getTasks(); + $tasks = $this->getRecordsFromTable('tt_tasks'); foreach ($tasks as $key=>$task_item) $this->taskMap[$task_item['id']] = $key + 1; // Prepare project map. - $projects = $this->getProjects(); + $projects = $this->getRecordsFromTable('tt_projects'); foreach ($projects as $key=>$project_item) $this->projectMap[$project_item['id']] = $key + 1; // Prepare client map. - $clients = $this->getClients(); + $clients = $this->getRecordsFromTable('tt_clients'); foreach ($clients as $key=>$client_item) $this->clientMap[$client_item['id']] = $key + 1; @@ -322,7 +172,7 @@ function writeData() { $this->customFieldOptionMap[$option['id']] = $key + 1; // Prepare favorite report map. - $fav_reports = $this->getFavReports(); + $fav_reports = $this->getRecordsFromTable('tt_fav_reports'); foreach ($fav_reports as $key=>$fav_report) $this->favReportMap[$fav_report['id']] = $key + 1; @@ -550,7 +400,7 @@ function writeData() { unset($expense_item_part); // Write predefined expenses. - $predefined_expenses = $this->getPredefinedExpenses(); + $predefined_expenses = $this->getRecordsFromTable('tt_predefined_expenses'); fwrite($this->file, $this->indentation." \n"); foreach ($predefined_expenses as $predefined_expense) { $predefined_expense_part = $this->indentation.' '."getFavReports(); fwrite($this->file, $this->indentation." \n"); foreach ($fav_reports as $fav_report) { $user_list = ''; @@ -625,7 +474,7 @@ function writeData() { unset($fav_report_part); // Write notifications. - $notifications = $this->getNotifications(); + $notifications = $this->getRecordsFromTable('tt_cron'); fwrite($this->file, $this->indentation." \n"); foreach ($notifications as $notification) { $notification_part = $this->indentation.' '." -
 Anuko Time Tracker 1.18.25.4484 | Copyright © Anuko | +  Anuko Time Tracker 1.18.25.4485 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 7143cc6750a18461fcd29964c41f23b4cbd27d21 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 18:23:49 +0000 Subject: [PATCH 0404/1848] Rolling back getUsers as previous commit broke export-import. --- WEB-INF/lib/ttGroupExportHelper.class.php | 19 ++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index a520e7fbe..54b8aaa11 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -82,6 +82,23 @@ private function getGroupAttrs() { return $val; } + // The getUsers obtains all users in group for the purpose of export. + private function getUsers() { + global $user; + $mdb2 = getConnection(); + $sql = "select u.*, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id)". + " where u.group_id = $this->group_id and u.org_id = $user->org_id order by upper(u.name)"; // Note: deleted users are included. + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } + // getRecordsFromTable - obtains all fields from a given table for a group. function getRecordsFromTable($table_name) { global $user; @@ -132,7 +149,7 @@ function writeData() { unset($group_part); // Prepare user map. - $users = $this->getRecordsFromTable('tt_users'); + $users = $this->getUsers(); foreach ($users as $key=>$user_item) $this->userMap[$user_item['id']] = $key + 1; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7e7093dc7..d6b001fa0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.25.4485 | Copyright © Anuko | +  Anuko Time Tracker 1.18.26.4486 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 15c56c8682a43ed4ac3cbe98ca1772478876d5b9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 18:41:49 +0000 Subject: [PATCH 0405/1848] Added subgroups menu. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d6b001fa0..8831f22f3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.26.4486 | Copyright © Anuko | +  Anuko Time Tracker 1.18.26.4487 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 430c1c2b0..23dfdc117 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -89,6 +89,11 @@ {if $user->can('manage_basic_settings')} {$i18n.menu.group} · {/if} +{if isTrue($smarty.const.SUBGROUP_DEBUG)} + {if $user->can('manage_subgroups')} + {$i18n.menu.subgroups} · + {/if} +{/if} {if $user->can('manage_features')} {$i18n.menu.plugins} · {/if} From 32e0397e34d3092eb2b89411ab97ee288f88038a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 18:51:25 +0000 Subject: [PATCH 0406/1848] Introduced description field for groups as part of subgroup support. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 2 ++ mysql.sql | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8831f22f3..81f3d40a2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.26.4487 | Copyright © Anuko | +  Anuko Time Tracker 1.18.26.4488 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 264fc379d..f87b2a4e9 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1037,6 +1037,8 @@ function setChange($sql) { setChange("update `tt_custom_field_log` cfl inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfl.field_id set cfl.group_id = cf.group_id, cfl.org_id = cf.org_id where cfl.org_id is null"); setChange("ALTER TABLE `tt_custom_field_options` ADD `status` tinyint(4) default '1' after `value`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.24', modified = now() where param_name = 'version_db' and param_value = '1.18.23'"); + setChange("ALTER TABLE `tt_groups` ADD COLUMN `description` varchar(255) default NULL after `name`"); + setChange("UPDATE `tt_site_config` SET param_value = '1.18.26', modified = now() where param_name = 'version_db' and param_value = '1.18.24'"); } if ($_POST["cleanup"]) { diff --git a/mysql.sql b/mysql.sql index 0ddf3bfa9..0f3f00c9b 100644 --- a/mysql.sql +++ b/mysql.sql @@ -17,6 +17,7 @@ CREATE TABLE `tt_groups` ( `parent_id` int(11) default NULL, # parent group id `org_id` int(11) default NULL, # organization id (id of top group) `name` varchar(80) default NULL, # group name + `description` varchar(255) default NULL, # group description `currency` varchar(7) default NULL, # currency symbol `decimal_mark` char(1) NOT NULL default '.', # separator in decimals `lang` varchar(10) NOT NULL default 'en', # language @@ -487,4 +488,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.24', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.26', now()); # TODO: change when structure changes. From 6f1a57ddce604840c432915d97574f175b935475 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 21:24:01 +0000 Subject: [PATCH 0407/1848] Some more work in progress on subgroups. --- WEB-INF/templates/group_add.tpl | 28 ++++++++++++ WEB-INF/templates/groups.tpl | 4 +- dbinstall.php | 8 ++-- group_add.php | 78 +++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 WEB-INF/templates/group_add.tpl create mode 100644 group_add.php diff --git a/WEB-INF/templates/group_add.tpl b/WEB-INF/templates/group_add.tpl new file mode 100644 index 000000000..852f1b78b --- /dev/null +++ b/WEB-INF/templates/group_add.tpl @@ -0,0 +1,28 @@ +{$forms.groupForm.open} + + + + +
+ + + + + + + + + + + + + + + + + + + +
{$i18n.label.thing_name} (*):{$forms.groupForm.group_name.control}
{$i18n.label.description}:{$forms.groupForm.description.control}
{$i18n.label.required_fields}
 
{$forms.groupForm.btn_add.control}
+
+{$forms.groupForm.close} diff --git a/WEB-INF/templates/groups.tpl b/WEB-INF/templates/groups.tpl index d9748bcbd..581055193 100644 --- a/WEB-INF/templates/groups.tpl +++ b/WEB-INF/templates/groups.tpl @@ -4,7 +4,8 @@ - + + @@ -12,6 +13,7 @@ {foreach $groups as $group} + diff --git a/dbinstall.php b/dbinstall.php index f87b2a4e9..653d13a1f 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function setChange($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11824"]) { + if ($_POST["convert11797to11826"]) { setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1086,7 +1086,7 @@ function setChange($sql) {

DB Install

{$i18n.label.thing_name}{$i18n.label.thing_name}{$i18n.label.description} {$i18n.label.edit} {$i18n.label.delete}
{$group.name|escape}{$group.description|escape} {$i18n.label.edit} {$i18n.label.delete}
-
Create database structure (v1.18.24) + Create database structure (v1.18.26)
(applies only to new installations, do not execute when updating)
@@ -1131,8 +1131,8 @@ function setChange($sql) {
Update database structure (v1.17.97 to v1.18.24)Update database structure (v1.17.97 to v1.18.26)
diff --git a/group_add.php b/group_add.php new file mode 100644 index 000000000..8bb8d003f --- /dev/null +++ b/group_add.php @@ -0,0 +1,78 @@ +isPost()) { + $cl_name = trim($request->getParameter('group_name')); + $cl_description = trim($request->getParameter('description')); +} + +$form = new Form('groupForm'); +$form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'group_name','value'=>$cl_group,'enable'=>$advanced_settings)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); +/* + if ($err->no()) { + if (!ttProjectHelper::getProjectByName($cl_name)) { + if (ttProjectHelper::insert(array( + 'group_id' => $user->getActiveGroup(), + 'org_id' => $user->org_id, + 'name' => $cl_name, + 'description' => $cl_description, + 'users' => $cl_users, + 'tasks' => $cl_tasks, + 'status' => ACTIVE))) { + header('Location: projects.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } else + $err->add($i18n->get('error.project_exists')); + } +*/ +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +//$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); +$smarty->assign('title', $i18n->get('title.add_group')); +$smarty->assign('content_page_name', 'group_add.tpl'); +$smarty->display('index.tpl'); From d3bcdee6ccc7bd00dce1fdfd89dc604f9016b52c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 21:36:26 +0000 Subject: [PATCH 0408/1848] Using error.object_exists instead of error.project_exists to streamline error messages. --- WEB-INF/resources/ca.lang.php | 2 -- WEB-INF/resources/cs.lang.php | 2 -- WEB-INF/resources/da.lang.php | 1 - WEB-INF/resources/de.lang.php | 1 - WEB-INF/resources/en.lang.php | 1 - WEB-INF/resources/es.lang.php | 2 -- WEB-INF/resources/et.lang.php | 2 -- WEB-INF/resources/fa.lang.php | 1 - WEB-INF/resources/fi.lang.php | 1 - WEB-INF/resources/fr.lang.php | 1 - WEB-INF/resources/gr.lang.php | 1 - WEB-INF/resources/he.lang.php | 1 - WEB-INF/resources/hu.lang.php | 2 -- WEB-INF/resources/it.lang.php | 1 - WEB-INF/resources/ja.lang.php | 2 -- WEB-INF/resources/ko.lang.php | 2 -- WEB-INF/resources/nl.lang.php | 1 - WEB-INF/resources/no.lang.php | 2 -- WEB-INF/resources/pl.lang.php | 1 - WEB-INF/resources/pt-br.lang.php | 1 - WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 2 -- WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 1 - WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 1 - WEB-INF/resources/sv.lang.php | 1 - WEB-INF/resources/tr.lang.php | 2 -- WEB-INF/resources/zh-cn.lang.php | 2 -- WEB-INF/resources/zh-tw.lang.php | 2 -- WEB-INF/templates/footer.tpl | 2 +- group_add.php | 2 +- mobile/project_add.php | 2 +- mobile/project_edit.php | 4 ++-- project_add.php | 2 +- project_edit.php | 4 ++-- 36 files changed, 8 insertions(+), 50 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index a0accefda..dc1e2070b 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -99,8 +99,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Ja existeix un projecte amb aquest nom.', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index a42826fad..529e8020b 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -101,8 +101,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Projekt tohoto jména již existuje.', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 7eaec94cc..995ce5e08 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -90,7 +90,6 @@ 'error.user_exists' => 'Brugernavn eksistere allerede.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Der eksiterer allerede et projekt med det navn.', 'error.task_exists' => 'Opgavenavn eksistere allerede.', 'error.client_exists' => 'Der eksistere allerede en klient med dette navn.', 'error.invoice_exists' => 'Fakturanummer eksistere allerede.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 627941493..425f1fcf2 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -85,7 +85,6 @@ 'error.auth' => 'Benutzername oder Passwort ungültig.', 'error.user_exists' => 'Benutzer mit diesem Konto ist bereits vorhanden.', 'error.object_exists' => 'Objekt mit diesem Namen ist bereits vorhanden.', -'error.project_exists' => 'Es gibt bereits ein Projekt mit diesem Namen.', 'error.task_exists' => 'Task mit diesem Namen existiert bereits.', 'error.client_exists' => 'Der Kunde mit dem Namen existiert schon.', 'error.invoice_exists' => 'Rechnung mit dieser Nummer existiert bereits.', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 6d7a47c73..6282874cd 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -85,7 +85,6 @@ 'error.auth' => 'Incorrect login or password.', 'error.user_exists' => 'User with this login already exists.', 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Project with this name already exists.', 'error.task_exists' => 'Task with this name already exists.', 'error.client_exists' => 'Client with this name already exists.', 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index b53ebd944..94d506374 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -97,8 +97,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Ya existe un proyecto con este nombre.', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 4aede3a4d..5ab3de4a5 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -101,8 +101,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Selle nimega projekt on juba olemas.', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 140da1bcb..4e5b011aa 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -95,7 +95,6 @@ 'error.user_exists' => 'کاربری با این نام کاربری موجود است.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'پروژه ای با این نام موجود است.', 'error.task_exists' => 'وظیفه ای با این نام هم اکنون وجود دارد.', 'error.client_exists' => 'مشتری با این نام هم اکنون وجود دارد.', 'error.invoice_exists' => 'فاکتوری با این شماره هم اکنون موجود است.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index f290ff5ba..f4ac6c4e2 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -92,7 +92,6 @@ 'error.user_exists' => 'Tämä käyttäjänimi on jo olemassa.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Tämän niminen projekti on jo olemassa.', 'error.task_exists' => 'Tämän niminen tehtävä on jo olemassa.', 'error.client_exists' => 'Tämän niminen asiakas on jo olemassa.', 'error.invoice_exists' => 'Tällä numerolla oleva lasku on jo olemassa.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index d4f372b17..47dc7f79b 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -90,7 +90,6 @@ 'error.user_exists' => 'Un utilisateur avec cet identifiant existe déjà.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Un projet avec ce nom existe déjà.', 'error.task_exists' => 'Une tâche avec ce nom existe déjà.', 'error.client_exists' => 'Un client avec ce nom existe déjà.', 'error.invoice_exists' => 'Une facture avec ce numéro existe déjà.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index ef78fd501..a85c30e9b 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -86,7 +86,6 @@ 'error.auth' => 'Λανθασμένο όνομα εισόδου ή κωδικός.', 'error.user_exists' => 'Ο χρήστης με αυτήν τη σύνδεση υπάρχει ήδη.', 'error.object_exists' => 'Το αντικείμενο με αυτό το όνομα υπάρχει ήδη.', -'error.project_exists' => 'Το έργα με αυτό το όνομα υπάρχει ήδη.', 'error.task_exists' => 'Η εργασία με αυτό το όνομα υπάρχει ήδη.', 'error.client_exists' => 'Ο πελάτης με αυτό το όνομα υπάρχει ήδη.', 'error.invoice_exists' => 'Το τιμολόγιο με αυτόν τον αριθμό υπάρχει ήδη.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 661ff27a4..cfa471e69 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -106,7 +106,6 @@ 'error.user_exists' => 'שם משתמש כבר קיים', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'שם פרוייקט כבר קיים', 'error.task_exists' => 'קיימת משימה עם שם דומה', 'error.client_exists' => 'שם לקוח כבר קיים', 'error.invoice_exists' => 'קיימת חשבונית עם מספר זה', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 30d9a9a0e..beea7ac4e 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -99,8 +99,6 @@ // 'error.auth' => 'Incorrect login or password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Ilyen nevű projekt már létezik.', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 2f0535781..063318ebd 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -89,7 +89,6 @@ 'error.user_exists' => 'Esiste già un utente con questo username.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Esiste già un progetto con questo nome.', 'error.task_exists' => 'Esiste già un compito con questo nome.', 'error.client_exists' => 'Esiste già un cliente con questo nome.', 'error.invoice_exists' => 'Esiste già una fattura con questo numero.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 29a7a034b..f0c52121e 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -99,8 +99,6 @@ 'error.user_exists' => 'このログインと関連されたユーザーは既に存在します。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'この名前のプロジェクトは既に存在します。', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index f8d99f1b4..a426f24d2 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -99,8 +99,6 @@ 'error.user_exists' => '본 로그인과 연계된 사용자가 이미 있습니다.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => '본 이름과 연계된 프로젝트가 이미 있습니다.', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 531953e23..d30caf44a 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -85,7 +85,6 @@ 'error.auth' => 'Onjuiste inlognaam of wachtwoord.', 'error.user_exists' => 'Een gebruiker met deze inlognaam bestaat al.', 'error.object_exists' => 'Een object met deze naam bestaat al.', -'error.project_exists' => 'Een project met deze naam bestaat al.', 'error.task_exists' => 'Er bestaat al een taak met deze naam.', 'error.client_exists' => 'Een klant met deze naam bestaat al.', 'error.invoice_exists' => 'Dit nummer is al eens toegekend aan een factuur.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 35ec512be..a8cdd34a9 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -99,8 +99,6 @@ 'error.user_exists' => 'Bruker med et slikt brukernavn eksisterer allerede.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Et prosjekt med dette navnet er allerede opprettet.', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', 'error.client_exists' => 'En klient med dette navnet er allerede opprettet.', // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 301e002cb..b2bf0e153 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -93,7 +93,6 @@ 'error.user_exists' => 'Użytkownik o takiej nazwie już istnieje.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Projekt o takiej nazwie już istnieje.', 'error.task_exists' => 'Zadanie o takiej nazwie już istnieje.', 'error.client_exists' => 'Klient o takiej nazwie już istnieje.', 'error.invoice_exists' => 'Faktura o tym numerze już istnieje.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index b97881572..7077f2e13 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -91,7 +91,6 @@ 'error.user_exists' => 'Já existe usuário com este login.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Já existe projeto com este nome.', 'error.task_exists' => 'Já existe tarefa com este nome.', 'error.client_exists' => 'Já existe cliente com este nome.', 'error.invoice_exists' => 'Já existe fatura com este número.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 8de4afaf0..595e9c0fa 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -97,7 +97,6 @@ // 'error.auth' => 'Incorrect login or password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.project_exists' => 'Project with this name already exists.', // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index d43f76b42..1e5eb55c2 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -103,8 +103,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Proiectul cu acest nume exista deja.', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 40a5c1e30..4b2a9ca7b 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -84,7 +84,6 @@ 'error.auth' => 'Неправильно введен логин или пароль.', 'error.user_exists' => 'Пользователь с таким логином уже существует.', 'error.object_exists' => 'Объект с таким именем уже есть.', -'error.project_exists' => 'Проект с таким именем уже есть.', 'error.task_exists' => 'Задача с таким названием уже есть.', 'error.client_exists' => 'Клиент с таким именем уже есть.', 'error.invoice_exists' => 'Счёт с таким номером уже есть.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index de985d430..a2ae001b9 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -95,7 +95,6 @@ 'error.user_exists' => 'Používateľ s týmto prihlasovacím menom už existuje.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Projekt s týmto názvom už existuje.', 'error.task_exists' => 'Úloha s týmto názvom už existuje.', 'error.client_exists' => 'Klient s týmto menom už existuje.', 'error.invoice_exists' => 'Faktúra s týmto číslom už existuje.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 83815f7de..490677a23 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -94,7 +94,6 @@ // 'error.auth' => 'Incorrect login or password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.project_exists' => 'Project with this name already exists.', // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 42ded8f94..39aa0b334 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -90,7 +90,6 @@ 'error.user_exists' => 'Korisnik pod ovim imenom već postoji.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Projekat pod ovim nazivom već postoji.', 'error.task_exists' => 'Zadatak pod ovim nazivom već postoji.', 'error.client_exists' => 'Klijent pod ovim imenom već postoji.', 'error.invoice_exists' => 'Račun pod ovim brojem već postoji.', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 43c76d0e4..3861f8d45 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -89,7 +89,6 @@ 'error.user_exists' => 'Det finns redan en användare med det här användarnamnet.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Det finns redan ett projekt med det här namnet.', 'error.task_exists' => 'Det finns redan en arbetsuppgift med det här namnet.', 'error.client_exists' => 'Det finns redan en kund med det här namnet.', 'error.invoice_exists' => 'Det finns redan en faktura med det här numret.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index d5764bedf..de1c41aec 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -106,8 +106,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => 'Bu isimde proje zaten vardır.', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index a60145578..271ad93e2 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -92,8 +92,6 @@ 'error.user_exists' => '该用户登录信息已经存在。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => '该项目名称已经存在。', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', 'error.client_exists' => '具有此名称的客户端已经存在。', // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index c51900fac..81a90380a 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -97,8 +97,6 @@ 'error.user_exists' => '該使用者登錄資訊已經存在。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.project_exists' => '該專案名稱已經存在。', -// TODO: translate the following. // 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 81f3d40a2..a6ffa5370 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.26.4488 | Copyright © Anuko | +  Anuko Time Tracker 1.18.26.4489 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_add.php b/group_add.php index 8bb8d003f..4e8cb91a3 100644 --- a/group_add.php +++ b/group_add.php @@ -66,7 +66,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.project_exists')); + $err->add($i18n->get('error.object_exists')); } */ } // isPost diff --git a/mobile/project_add.php b/mobile/project_add.php index 6d68a178e..3b1d0fb0d 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -90,7 +90,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.project_exists')); + $err->add($i18n->get('error.object_exists')); } } // isPost diff --git a/mobile/project_edit.php b/mobile/project_edit.php index defec7add..2d67b88d8 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -113,7 +113,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.project_exists')); + $err->add($i18n->get('error.object_exists')); } if ($request->getParameter('btn_copy')) { @@ -131,7 +131,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.project_exists')); + $err->add($i18n->get('error.object_exists')); } if ($request->getParameter('btn_delete')) { diff --git a/project_add.php b/project_add.php index 3b4c73d36..930adf1f8 100644 --- a/project_add.php +++ b/project_add.php @@ -89,7 +89,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.project_exists')); + $err->add($i18n->get('error.object_exists')); } } // isPost diff --git a/project_edit.php b/project_edit.php index 77312b0b2..3cdb44375 100644 --- a/project_edit.php +++ b/project_edit.php @@ -112,7 +112,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.project_exists')); + $err->add($i18n->get('error.object_exists')); } if ($request->getParameter('btn_copy')) { @@ -130,7 +130,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.project_exists')); + $err->add($i18n->get('error.object_exists')); } } } // isPost From 04565403a39edd462f6f7d2ef737366cdc40acf1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 21:51:56 +0000 Subject: [PATCH 0409/1848] Using error.object_exists instead of error.task_exists to streamline error messages. --- WEB-INF/resources/ca.lang.php | 1 - WEB-INF/resources/cs.lang.php | 1 - WEB-INF/resources/da.lang.php | 1 - WEB-INF/resources/de.lang.php | 1 - WEB-INF/resources/en.lang.php | 1 - WEB-INF/resources/es.lang.php | 1 - WEB-INF/resources/et.lang.php | 1 - WEB-INF/resources/fa.lang.php | 1 - WEB-INF/resources/fi.lang.php | 1 - WEB-INF/resources/fr.lang.php | 1 - WEB-INF/resources/gr.lang.php | 1 - WEB-INF/resources/he.lang.php | 1 - WEB-INF/resources/hu.lang.php | 1 - WEB-INF/resources/it.lang.php | 1 - WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 1 - WEB-INF/resources/no.lang.php | 1 - WEB-INF/resources/pl.lang.php | 1 - WEB-INF/resources/pt-br.lang.php | 1 - WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 1 - WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 1 - WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 1 - WEB-INF/resources/sv.lang.php | 1 - WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 1 - WEB-INF/resources/zh-tw.lang.php | 1 - WEB-INF/templates/footer.tpl | 2 +- mobile/task_add.php | 2 +- mobile/task_edit.php | 4 ++-- task_add.php | 2 +- task_edit.php | 4 ++-- 35 files changed, 7 insertions(+), 37 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index dc1e2070b..e8c811893 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -99,7 +99,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 529e8020b..d80ebf09d 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -101,7 +101,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 995ce5e08..fc165df4b 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -90,7 +90,6 @@ 'error.user_exists' => 'Brugernavn eksistere allerede.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'Opgavenavn eksistere allerede.', 'error.client_exists' => 'Der eksistere allerede en klient med dette navn.', 'error.invoice_exists' => 'Fakturanummer eksistere allerede.', // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 425f1fcf2..940ca1d87 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -85,7 +85,6 @@ 'error.auth' => 'Benutzername oder Passwort ungültig.', 'error.user_exists' => 'Benutzer mit diesem Konto ist bereits vorhanden.', 'error.object_exists' => 'Objekt mit diesem Namen ist bereits vorhanden.', -'error.task_exists' => 'Task mit diesem Namen existiert bereits.', 'error.client_exists' => 'Der Kunde mit dem Namen existiert schon.', 'error.invoice_exists' => 'Rechnung mit dieser Nummer existiert bereits.', 'error.role_exists' => 'Rolle mit diesem Rang existiert bereits.', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 6282874cd..ad1aabf9a 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -85,7 +85,6 @@ 'error.auth' => 'Incorrect login or password.', 'error.user_exists' => 'User with this login already exists.', 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'Task with this name already exists.', 'error.client_exists' => 'Client with this name already exists.', 'error.invoice_exists' => 'Invoice with this number already exists.', 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 94d506374..e19eb4a87 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -97,7 +97,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 5ab3de4a5..f5a580bf3 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -101,7 +101,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 4e5b011aa..ef7a57068 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -95,7 +95,6 @@ 'error.user_exists' => 'کاربری با این نام کاربری موجود است.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'وظیفه ای با این نام هم اکنون وجود دارد.', 'error.client_exists' => 'مشتری با این نام هم اکنون وجود دارد.', 'error.invoice_exists' => 'فاکتوری با این شماره هم اکنون موجود است.', // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index f4ac6c4e2..0aab41824 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -92,7 +92,6 @@ 'error.user_exists' => 'Tämä käyttäjänimi on jo olemassa.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'Tämän niminen tehtävä on jo olemassa.', 'error.client_exists' => 'Tämän niminen asiakas on jo olemassa.', 'error.invoice_exists' => 'Tällä numerolla oleva lasku on jo olemassa.', // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 47dc7f79b..d0ca0fa20 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -90,7 +90,6 @@ 'error.user_exists' => 'Un utilisateur avec cet identifiant existe déjà.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'Une tâche avec ce nom existe déjà.', 'error.client_exists' => 'Un client avec ce nom existe déjà.', 'error.invoice_exists' => 'Une facture avec ce numéro existe déjà.', // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index a85c30e9b..d4bca60ce 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -86,7 +86,6 @@ 'error.auth' => 'Λανθασμένο όνομα εισόδου ή κωδικός.', 'error.user_exists' => 'Ο χρήστης με αυτήν τη σύνδεση υπάρχει ήδη.', 'error.object_exists' => 'Το αντικείμενο με αυτό το όνομα υπάρχει ήδη.', -'error.task_exists' => 'Η εργασία με αυτό το όνομα υπάρχει ήδη.', 'error.client_exists' => 'Ο πελάτης με αυτό το όνομα υπάρχει ήδη.', 'error.invoice_exists' => 'Το τιμολόγιο με αυτόν τον αριθμό υπάρχει ήδη.', 'error.role_exists' => 'Ο ρόλος σε αυτή τη σειρά υπάρχει ήδη.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index cfa471e69..e9e9dd709 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -106,7 +106,6 @@ 'error.user_exists' => 'שם משתמש כבר קיים', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'קיימת משימה עם שם דומה', 'error.client_exists' => 'שם לקוח כבר קיים', 'error.invoice_exists' => 'קיימת חשבונית עם מספר זה', // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index beea7ac4e..0c8dc240f 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -99,7 +99,6 @@ // 'error.auth' => 'Incorrect login or password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 063318ebd..476b1000d 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -89,7 +89,6 @@ 'error.user_exists' => 'Esiste già un utente con questo username.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'Esiste già un compito con questo nome.', 'error.client_exists' => 'Esiste già un cliente con questo nome.', 'error.invoice_exists' => 'Esiste già una fattura con questo numero.', // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index f0c52121e..08ca910fb 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -99,7 +99,6 @@ 'error.user_exists' => 'このログインと関連されたユーザーは既に存在します。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index a426f24d2..91bbf5be6 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -99,7 +99,6 @@ 'error.user_exists' => '본 로그인과 연계된 사용자가 이미 있습니다.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index d30caf44a..434ec9e70 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -85,7 +85,6 @@ 'error.auth' => 'Onjuiste inlognaam of wachtwoord.', 'error.user_exists' => 'Een gebruiker met deze inlognaam bestaat al.', 'error.object_exists' => 'Een object met deze naam bestaat al.', -'error.task_exists' => 'Er bestaat al een taak met deze naam.', 'error.client_exists' => 'Een klant met deze naam bestaat al.', 'error.invoice_exists' => 'Dit nummer is al eens toegekend aan een factuur.', 'error.role_exists' => 'Een rol met deze rangorde bestaat al.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index a8cdd34a9..16a9d83ae 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -99,7 +99,6 @@ 'error.user_exists' => 'Bruker med et slikt brukernavn eksisterer allerede.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', 'error.client_exists' => 'En klient med dette navnet er allerede opprettet.', // TODO: translate the following. // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index b2bf0e153..8e07da861 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -93,7 +93,6 @@ 'error.user_exists' => 'Użytkownik o takiej nazwie już istnieje.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'Zadanie o takiej nazwie już istnieje.', 'error.client_exists' => 'Klient o takiej nazwie już istnieje.', 'error.invoice_exists' => 'Faktura o tym numerze już istnieje.', // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 7077f2e13..566c654bb 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -91,7 +91,6 @@ 'error.user_exists' => 'Já existe usuário com este login.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'Já existe tarefa com este nome.', 'error.client_exists' => 'Já existe cliente com este nome.', 'error.invoice_exists' => 'Já existe fatura com este número.', // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 595e9c0fa..5a05d16c2 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -97,7 +97,6 @@ // 'error.auth' => 'Incorrect login or password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 1e5eb55c2..783219ffc 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -103,7 +103,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 4b2a9ca7b..0d57fe1dc 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -84,7 +84,6 @@ 'error.auth' => 'Неправильно введен логин или пароль.', 'error.user_exists' => 'Пользователь с таким логином уже существует.', 'error.object_exists' => 'Объект с таким именем уже есть.', -'error.task_exists' => 'Задача с таким названием уже есть.', 'error.client_exists' => 'Клиент с таким именем уже есть.', 'error.invoice_exists' => 'Счёт с таким номером уже есть.', 'error.role_exists' => 'Роль с таким рангом уже есть.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index a2ae001b9..40e671795 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -95,7 +95,6 @@ 'error.user_exists' => 'Používateľ s týmto prihlasovacím menom už existuje.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'Úloha s týmto názvom už existuje.', 'error.client_exists' => 'Klient s týmto menom už existuje.', 'error.invoice_exists' => 'Faktúra s týmto číslom už existuje.', // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 490677a23..ebbe4f30f 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -94,7 +94,6 @@ // 'error.auth' => 'Incorrect login or password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 39aa0b334..fe9a47ead 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -90,7 +90,6 @@ 'error.user_exists' => 'Korisnik pod ovim imenom već postoji.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'Zadatak pod ovim nazivom već postoji.', 'error.client_exists' => 'Klijent pod ovim imenom već postoji.', 'error.invoice_exists' => 'Račun pod ovim brojem već postoji.', // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 3861f8d45..60afbfc87 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -89,7 +89,6 @@ 'error.user_exists' => 'Det finns redan en användare med det här användarnamnet.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.task_exists' => 'Det finns redan en arbetsuppgift med det här namnet.', 'error.client_exists' => 'Det finns redan en kund med det här namnet.', 'error.invoice_exists' => 'Det finns redan en faktura med det här numret.', // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index de1c41aec..7beba1506 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -106,7 +106,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 271ad93e2..c5da9b5c9 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -92,7 +92,6 @@ 'error.user_exists' => '该用户登录信息已经存在。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', 'error.client_exists' => '具有此名称的客户端已经存在。', // TODO: translate the following. // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 81a90380a..f48e154da 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -97,7 +97,6 @@ 'error.user_exists' => '該使用者登錄資訊已經存在。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -// 'error.task_exists' => 'Task with this name already exists.', // 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a6ffa5370..01892fc8f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.26.4489 | Copyright © Anuko | +  Anuko Time Tracker 1.18.26.4490 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/task_add.php b/mobile/task_add.php index 796c725c9..d1eab74bc 100644 --- a/mobile/task_add.php +++ b/mobile/task_add.php @@ -79,7 +79,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.task_exists')); + $err->add($i18n->get('error.object_exists')); } } // isPost diff --git a/mobile/task_edit.php b/mobile/task_edit.php index 030cacd1b..784028ee5 100644 --- a/mobile/task_edit.php +++ b/mobile/task_edit.php @@ -97,7 +97,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.task_exists')); + $err->add($i18n->get('error.object_exists')); } if ($request->getParameter('btn_copy')) { @@ -114,7 +114,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.task_exists')); + $err->add($i18n->get('error.object_exists')); } if ($request->getParameter('btn_delete')) { diff --git a/task_add.php b/task_add.php index 383a3935a..a93c80e28 100644 --- a/task_add.php +++ b/task_add.php @@ -79,7 +79,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.task_exists')); + $err->add($i18n->get('error.object_exists')); } } // isPost diff --git a/task_edit.php b/task_edit.php index e63817313..630a22cd2 100644 --- a/task_edit.php +++ b/task_edit.php @@ -95,7 +95,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.task_exists')); + $err->add($i18n->get('error.object_exists')); } if ($request->getParameter('btn_copy')) { @@ -112,7 +112,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.task_exists')); + $err->add($i18n->get('error.object_exists')); } } } // isPost From 79a38d5d7579d6ba89efdc1b077b87a2e324cbd3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 22:06:27 +0000 Subject: [PATCH 0410/1848] Further streamlining of error messages. --- WEB-INF/resources/ca.lang.php | 1 - WEB-INF/resources/cs.lang.php | 1 - WEB-INF/resources/da.lang.php | 1 - WEB-INF/resources/de.lang.php | 1 - WEB-INF/resources/en.lang.php | 1 - WEB-INF/resources/es.lang.php | 1 - WEB-INF/resources/et.lang.php | 1 - WEB-INF/resources/fa.lang.php | 1 - WEB-INF/resources/fi.lang.php | 1 - WEB-INF/resources/fr.lang.php | 1 - WEB-INF/resources/gr.lang.php | 1 - WEB-INF/resources/he.lang.php | 1 - WEB-INF/resources/hu.lang.php | 1 - WEB-INF/resources/it.lang.php | 1 - WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 1 - WEB-INF/resources/no.lang.php | 2 -- WEB-INF/resources/pl.lang.php | 1 - WEB-INF/resources/pt-br.lang.php | 1 - WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 1 - WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 1 - WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 1 - WEB-INF/resources/sv.lang.php | 1 - WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 2 -- WEB-INF/resources/zh-tw.lang.php | 1 - WEB-INF/templates/footer.tpl | 2 +- client_add.php | 2 +- client_edit.php | 4 ++-- mobile/client_add.php | 2 +- mobile/client_edit.php | 4 ++-- 35 files changed, 7 insertions(+), 39 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index e8c811893..80d11cdfe 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -99,7 +99,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d80ebf09d..191600627 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -101,7 +101,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index fc165df4b..f0d7c4382 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -90,7 +90,6 @@ 'error.user_exists' => 'Brugernavn eksistere allerede.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'Der eksistere allerede en klient med dette navn.', 'error.invoice_exists' => 'Fakturanummer eksistere allerede.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 940ca1d87..69bdffba2 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -85,7 +85,6 @@ 'error.auth' => 'Benutzername oder Passwort ungültig.', 'error.user_exists' => 'Benutzer mit diesem Konto ist bereits vorhanden.', 'error.object_exists' => 'Objekt mit diesem Namen ist bereits vorhanden.', -'error.client_exists' => 'Der Kunde mit dem Namen existiert schon.', 'error.invoice_exists' => 'Rechnung mit dieser Nummer existiert bereits.', 'error.role_exists' => 'Rolle mit diesem Rang existiert bereits.', 'error.no_invoiceable_items' => 'Keine Einträge zur Rechnungsstellung gefunden.', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index ad1aabf9a..4c569dc68 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -85,7 +85,6 @@ 'error.auth' => 'Incorrect login or password.', 'error.user_exists' => 'User with this login already exists.', 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'Client with this name already exists.', 'error.invoice_exists' => 'Invoice with this number already exists.', 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index e19eb4a87..44bca1bbe 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -97,7 +97,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index f5a580bf3..8f159c0b7 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -101,7 +101,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index ef7a57068..2620ffc12 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -95,7 +95,6 @@ 'error.user_exists' => 'کاربری با این نام کاربری موجود است.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'مشتری با این نام هم اکنون وجود دارد.', 'error.invoice_exists' => 'فاکتوری با این شماره هم اکنون موجود است.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 0aab41824..2067595de 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -92,7 +92,6 @@ 'error.user_exists' => 'Tämä käyttäjänimi on jo olemassa.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'Tämän niminen asiakas on jo olemassa.', 'error.invoice_exists' => 'Tällä numerolla oleva lasku on jo olemassa.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index d0ca0fa20..bbd315b0f 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -90,7 +90,6 @@ 'error.user_exists' => 'Un utilisateur avec cet identifiant existe déjà.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'Un client avec ce nom existe déjà.', 'error.invoice_exists' => 'Une facture avec ce numéro existe déjà.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index d4bca60ce..6520d46b9 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -86,7 +86,6 @@ 'error.auth' => 'Λανθασμένο όνομα εισόδου ή κωδικός.', 'error.user_exists' => 'Ο χρήστης με αυτήν τη σύνδεση υπάρχει ήδη.', 'error.object_exists' => 'Το αντικείμενο με αυτό το όνομα υπάρχει ήδη.', -'error.client_exists' => 'Ο πελάτης με αυτό το όνομα υπάρχει ήδη.', 'error.invoice_exists' => 'Το τιμολόγιο με αυτόν τον αριθμό υπάρχει ήδη.', 'error.role_exists' => 'Ο ρόλος σε αυτή τη σειρά υπάρχει ήδη.', 'error.no_invoiceable_items' => 'Δεν υπάρχουν στοιχεία προς τιμολόγηση.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index e9e9dd709..250ea7dc0 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -106,7 +106,6 @@ 'error.user_exists' => 'שם משתמש כבר קיים', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'שם לקוח כבר קיים', 'error.invoice_exists' => 'קיימת חשבונית עם מספר זה', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 0c8dc240f..ae7920530 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -99,7 +99,6 @@ // 'error.auth' => 'Incorrect login or password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 476b1000d..7ecc26e4a 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -89,7 +89,6 @@ 'error.user_exists' => 'Esiste già un utente con questo username.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'Esiste già un cliente con questo nome.', 'error.invoice_exists' => 'Esiste già una fattura con questo numero.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 08ca910fb..9e6d99a79 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -99,7 +99,6 @@ 'error.user_exists' => 'このログインと関連されたユーザーは既に存在します。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 91bbf5be6..f577566dd 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -99,7 +99,6 @@ 'error.user_exists' => '본 로그인과 연계된 사용자가 이미 있습니다.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 434ec9e70..5d11a8a0d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -85,7 +85,6 @@ 'error.auth' => 'Onjuiste inlognaam of wachtwoord.', 'error.user_exists' => 'Een gebruiker met deze inlognaam bestaat al.', 'error.object_exists' => 'Een object met deze naam bestaat al.', -'error.client_exists' => 'Een klant met deze naam bestaat al.', 'error.invoice_exists' => 'Dit nummer is al eens toegekend aan een factuur.', 'error.role_exists' => 'Een rol met deze rangorde bestaat al.', 'error.no_invoiceable_items' => 'Er zijn geen factuureerbare onderdelen.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 16a9d83ae..a7a82d753 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -99,8 +99,6 @@ 'error.user_exists' => 'Bruker med et slikt brukernavn eksisterer allerede.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'En klient med dette navnet er allerede opprettet.', -// TODO: translate the following. // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 8e07da861..eeedb29c2 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -93,7 +93,6 @@ 'error.user_exists' => 'Użytkownik o takiej nazwie już istnieje.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'Klient o takiej nazwie już istnieje.', 'error.invoice_exists' => 'Faktura o tym numerze już istnieje.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 566c654bb..e72b03b6e 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -91,7 +91,6 @@ 'error.user_exists' => 'Já existe usuário com este login.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'Já existe cliente com este nome.', 'error.invoice_exists' => 'Já existe fatura com este número.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 5a05d16c2..e5a5c5022 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -97,7 +97,6 @@ // 'error.auth' => 'Incorrect login or password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 783219ffc..8cf13bb96 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -103,7 +103,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 0d57fe1dc..926834e23 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -84,7 +84,6 @@ 'error.auth' => 'Неправильно введен логин или пароль.', 'error.user_exists' => 'Пользователь с таким логином уже существует.', 'error.object_exists' => 'Объект с таким именем уже есть.', -'error.client_exists' => 'Клиент с таким именем уже есть.', 'error.invoice_exists' => 'Счёт с таким номером уже есть.', 'error.role_exists' => 'Роль с таким рангом уже есть.', 'error.no_invoiceable_items' => 'Нет записей для включения в счёт.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 40e671795..2499ea753 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -95,7 +95,6 @@ 'error.user_exists' => 'Používateľ s týmto prihlasovacím menom už existuje.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'Klient s týmto menom už existuje.', 'error.invoice_exists' => 'Faktúra s týmto číslom už existuje.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ebbe4f30f..c52130efa 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -94,7 +94,6 @@ // 'error.auth' => 'Incorrect login or password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index fe9a47ead..bd041e508 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -90,7 +90,6 @@ 'error.user_exists' => 'Korisnik pod ovim imenom već postoji.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'Klijent pod ovim imenom već postoji.', 'error.invoice_exists' => 'Račun pod ovim brojem već postoji.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 60afbfc87..8e776e889 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -89,7 +89,6 @@ 'error.user_exists' => 'Det finns redan en användare med det här användarnamnet.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => 'Det finns redan en kund med det här namnet.', 'error.invoice_exists' => 'Det finns redan en faktura med det här numret.', // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 7beba1506..4ea24ff15 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -106,7 +106,6 @@ // TODO: translate the following. // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index c5da9b5c9..29cb05ca4 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -92,8 +92,6 @@ 'error.user_exists' => '该用户登录信息已经存在。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -'error.client_exists' => '具有此名称的客户端已经存在。', -// TODO: translate the following. // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index f48e154da..2a005abc4 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -97,7 +97,6 @@ 'error.user_exists' => '該使用者登錄資訊已經存在。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', -// 'error.client_exists' => 'Client with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 01892fc8f..c1be43aea 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.26.4490 | Copyright © Anuko | +  Anuko Time Tracker 1.18.26.4491 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/client_add.php b/client_add.php index dc99e6c89..db94e6206 100644 --- a/client_add.php +++ b/client_add.php @@ -83,7 +83,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.client_exists')); + $err->add($i18n->get('error.object_exists')); } } // isPost diff --git a/client_edit.php b/client_edit.php index 19aa5f893..a5c1b8b72 100644 --- a/client_edit.php +++ b/client_edit.php @@ -97,7 +97,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.client_exists')); + $err->add($i18n->get('error.object_exists')); } if ($request->getParameter('btn_copy')) { @@ -115,7 +115,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.client_exists')); + $err->add($i18n->get('error.object_exists')); } } } // isPost diff --git a/mobile/client_add.php b/mobile/client_add.php index 7a097b5ff..02de56d1e 100644 --- a/mobile/client_add.php +++ b/mobile/client_add.php @@ -83,7 +83,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.client_exists')); + $err->add($i18n->get('error.object_exists')); } } // isPost diff --git a/mobile/client_edit.php b/mobile/client_edit.php index 73d50cac2..c1004b1bb 100644 --- a/mobile/client_edit.php +++ b/mobile/client_edit.php @@ -98,7 +98,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.client_exists')); + $err->add($i18n->get('error.object_exists')); } if ($request->getParameter('btn_copy')) { @@ -116,7 +116,7 @@ } else $err->add($i18n->get('error.db')); } else - $err->add($i18n->get('error.client_exists')); + $err->add($i18n->get('error.object_exists')); } if ($request->getParameter('btn_delete')) { From ee3957cfc30d8ba3ed92ac99f3e5b784df1a9c58 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Nov 2018 23:05:10 +0000 Subject: [PATCH 0411/1848] Some more work in progress on group editor. --- WEB-INF/lib/ttGroupHelper.class.php | 41 +++++++++++++++++++++++++++++ WEB-INF/lib/ttUser.class.php | 4 +-- WEB-INF/templates/footer.tpl | 2 +- group_add.php | 21 ++++++--------- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 6ddffaa8c..41c03114e 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -59,4 +59,45 @@ static function getParentGroup($group_id) { } return false; } + + // The getSubgroupByName obtain an immediate subgroup by name if one exists. + static function getSubgroupByName($name) { + global $user; + + $mdb2 = getConnection(); + $parent_id = $user->getActiveGroup(); + $org_id = $user->org_id; + + $sql = "select id from tt_groups where parent_id = $parent_id and org_id = $org_id". + " and name = ".$mdb2->quote($name)." and status is not null"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if ($val && $val['id']) + return $val; + } + return false; + } + + // The insertSubgroup inserts a new subgroup in database. + static function insertSubgroup($fields) { + global $user; + + $mdb2 = getConnection(); + $parent_id = $user->getActiveGroup(); + $org_id = $user->org_id; + + // TODO: inherit all attributes from the parent group, if not supplied. + $name = $fields['name']; + $description = $fields['description']; + + $created = 'now()'; + $created_ip = $mdb2->quote($_SERVER['REMOTE_ADDR']); + + $sql = "insert into tt_groups (parent_id, org_id, name, description, created, created_ip)". + " values($parent_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", $created, $created_ip)"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + // TODO: design subgroup roles carefully. Perhaps roles are not to be touched in subgroups at all. + } } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 86174547e..8e9a8f215 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -414,11 +414,11 @@ function getGroups() { function getSubgroups() { $mdb2 = getConnection(); - $sql = "select id, name from tt_groups where org_id = $this->org_id and parent_id = ".$this->getActiveGroup();; + $sql = "select id, name, description from tt_groups where org_id = $this->org_id and parent_id = ".$this->getActiveGroup();; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { - $groups[] = array('id'=>$val['id'],'name'=>$val['name']); + $groups[] = $val; // array('id'=>$val['id'],'name'=>$val['name']); } } return $groups; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c1be43aea..4a7317266 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.26.4491 | Copyright © Anuko | +  Anuko Time Tracker 1.18.26.4492 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_add.php b/group_add.php index 4e8cb91a3..f39ec016c 100644 --- a/group_add.php +++ b/group_add.php @@ -28,6 +28,7 @@ require_once('initialize.php'); import('form.Form'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_subgroups')) { @@ -42,7 +43,7 @@ } $form = new Form('groupForm'); -$form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'group_name','value'=>$cl_group,'enable'=>$advanced_settings)); +$form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'group_name','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); @@ -50,29 +51,23 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); -/* + if ($err->no()) { - if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array( - 'group_id' => $user->getActiveGroup(), - 'org_id' => $user->org_id, + if (!ttGroupHelper::getSubgroupByName($cl_name)) { + if (ttGroupHelper::insertSubgroup(array( 'name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE))) { - header('Location: projects.php'); + 'description' => $cl_description))) { + header('Location: groups.php'); exit(); } else $err->add($i18n->get('error.db')); } else $err->add($i18n->get('error.object_exists')); } -*/ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -//$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); +$smarty->assign('onload', 'onLoad="document.groupForm.group_name.focus()"'); $smarty->assign('title', $i18n->get('title.add_group')); $smarty->assign('content_page_name', 'group_add.tpl'); $smarty->display('index.tpl'); From 8b1efafeb5921f14235cf45cf58ef404700141aa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Nov 2018 13:22:50 +0000 Subject: [PATCH 0412/1848] Rolling back old passwords support as some users never change them. --- WEB-INF/lib/auth/Auth_db.class.php | 25 +++++++++++++++++++++++++ WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/groups.tpl | 22 +++++++++++++++------- groups.php | 16 +++++++++++++++- 5 files changed, 57 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/auth/Auth_db.class.php b/WEB-INF/lib/auth/Auth_db.class.php index a3885fb66..bdde007a9 100644 --- a/WEB-INF/lib/auth/Auth_db.class.php +++ b/WEB-INF/lib/auth/Auth_db.class.php @@ -55,6 +55,31 @@ function authenticate($login, $password) $val = $res->fetchRow(); if ($val['id'] > 0) { return array('login'=>$login,'id'=>$val['id']); + } else { + // If the OLD_PASSWORDS option is defined - set it. + if (isTrue(OLD_PASSWORDS)) { + $sql = "SET SESSION old_passwords = 1"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) { + die($res->getMessage()); + } + } + // Try legacy password match. This is needed for compatibility with older versions of TT. + $sql = "SELECT id FROM tt_users + WHERE login = ".$mdb2->quote($login)." AND password = old_password(".$mdb2->quote($password).") AND status = 1"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) { + return false; // Simply return false for a meaningful error message on screen, see the comment below. + // die($res->getMessage()); // old_password() function is removed in MySQL 5.7.5. + // We are getting a confusing "MDB2 Error: not found" in this case if we die. + // TODO: perhaps it's time to simplify things and remove handling of old passwords completely. + // HOWEVER: some users apparently never change their passwords. When I tried removing OLD_PASSWORDS + // support in November 2018, there were login issues with such users. + } + $val = $res->fetchRow(); + if ($val['id'] > 0) { + return array('login'=>$login,'id'=>$val['id']); + } } // Special handling for admin@localhost - search for an account with admin role with a matching password. diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 8e9a8f215..7a37109eb 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -418,7 +418,7 @@ function getSubgroups() { $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { - $groups[] = $val; // array('id'=>$val['id'],'name'=>$val['name']); + $groups[] = $val; } } return $groups; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4a7317266..0e481fee9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.26.4492 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4493 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/groups.tpl b/WEB-INF/templates/groups.tpl index 581055193..508f17878 100644 --- a/WEB-INF/templates/groups.tpl +++ b/WEB-INF/templates/groups.tpl @@ -1,25 +1,33 @@ - +{$forms.groupsForm.open} +{if $on_behalf_group_control} + + + + + +{/if} -{if $groups} - {foreach $groups as $group} +{if $subgroups} + {foreach $subgroups as $subgroup} - - - - + + + + {/foreach} {/if}
{$i18n.label.group}:{$forms.groupsForm.onBehalfGroup.control}
 
{$i18n.label.thing_name} {$i18n.label.description} {$i18n.label.edit} {$i18n.label.delete}
{$group.name|escape}{$group.description|escape}{$i18n.label.edit}{$i18n.label.delete}{$subgroup.name|escape}{$subgroup.description|escape}{$i18n.label.edit}{$i18n.label.delete}
+{$forms.groupsForm.close} diff --git a/groups.php b/groups.php index 12e54da20..7f4937c9f 100644 --- a/groups.php +++ b/groups.php @@ -39,7 +39,21 @@ } // End of access checks. -$smarty->assign('groups', $user->getSubgroups()); +$form = new Form('groupsForm'); +$groups = $user->getGroups(); +if (count($groups) > 1) { + $form->addInput(array('type'=>'combobox', + 'onchange'=>'this.form.submit();', + 'name'=>'onBehalfGroup', + 'style'=>'width: 250px;', + 'value'=>$on_behalf_group_id, + 'data'=>$groups, + 'datakeys'=>array('id','name'))); + $smarty->assign('on_behalf_group_control', 1); +} + +$smarty->assign('subgroups', $user->getSubgroups()); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('label.subgroups')); $smarty->assign('content_page_name', 'groups.tpl'); $smarty->display('index.tpl'); From ea0882f0753da7c4426b55e7ec526e455ada03a3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Nov 2018 14:58:05 +0000 Subject: [PATCH 0413/1848] Some more progress on group editor. --- WEB-INF/lib/ttUser.class.php | 15 +++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/groups.tpl | 8 ++++---- groups.php | 24 ++++++++++++++++-------- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 7a37109eb..16b536c22 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -27,6 +27,7 @@ // +----------------------------------------------------------------------+ import('ttConfigHelper'); +import('ttGroupHelper'); class ttUser { var $login = null; // User login. @@ -411,10 +412,12 @@ function getGroups() { } // getSubgroups obtains a list of immediate subgroups. - function getSubgroups() { + function getSubgroups($group_id = null) { $mdb2 = getConnection(); - $sql = "select id, name, description from tt_groups where org_id = $this->org_id and parent_id = ".$this->getActiveGroup();; + if (!$group_id) $group_id = $this->getActiveGroup(); + + $sql = "select id, name, description from tt_groups where org_id = $this->org_id and parent_id = $group_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -599,6 +602,14 @@ function enablePlugin($plugin, $enable = true) return true; } + // isGroupValid determines if a group is valid for user. + function isGroupValid($group_id) { + if ($group_id == $this->group_id) + return true; + else + return $this->isSubgroupValid($group_id); + } + // isSubgroupValid determines if a subgroup is valid for user. // A subgroup is valid if: // - user can manage_subgroups; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0e481fee9..0419e9e9f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.27.4493 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4494 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/groups.tpl b/WEB-INF/templates/groups.tpl index 508f17878..d1f174fa5 100644 --- a/WEB-INF/templates/groups.tpl +++ b/WEB-INF/templates/groups.tpl @@ -1,12 +1,12 @@ -{$forms.groupsForm.open} +{$forms.subgroupsForm.open} -{if $on_behalf_group_control} +{if $group_dropdown} - + {/if} @@ -27,7 +27,7 @@ {/foreach} {/if}
{$i18n.label.group}:{$forms.groupsForm.onBehalfGroup.control}{$forms.subgroupsForm.group.control}
 
-{$forms.groupsForm.close} +{$forms.subgroupsForm.close} diff --git a/groups.php b/groups.php index 7f4937c9f..279e50834 100644 --- a/groups.php +++ b/groups.php @@ -27,32 +27,40 @@ // +----------------------------------------------------------------------+ require_once('initialize.php'); +import('ttUser'); import('form.Form'); -import('ttUserHelper'); -import('ttRoleHelper'); -import('ttConfigHelper'); // Access checks. if (!ttAccessAllowed('manage_subgroups')) { header('Location: access_denied.php'); exit(); } +if ($request->isPost() && !$user->isGroupValid($request->getParameter('group'))) { + header('Location: access_denied.php'); // Wrong group id in post. + exit(); +} // End of access checks. -$form = new Form('groupsForm'); +if ($request->isPost()) { + $group_id = $request->getParameter('group'); +} else { + $group_id = $user->getActiveGroup(); +} + +$form = new Form('subgroupsForm'); $groups = $user->getGroups(); if (count($groups) > 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'this.form.submit();', - 'name'=>'onBehalfGroup', + 'name'=>'group', 'style'=>'width: 250px;', - 'value'=>$on_behalf_group_id, + 'value'=>$group_id, 'data'=>$groups, 'datakeys'=>array('id','name'))); - $smarty->assign('on_behalf_group_control', 1); + $smarty->assign('group_dropdown', 1); } -$smarty->assign('subgroups', $user->getSubgroups()); +$smarty->assign('subgroups', $user->getSubgroups($group_id)); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('label.subgroups')); $smarty->assign('content_page_name', 'groups.tpl'); From 7961e2909a8c8c456c1b0d6bee2944cabde592c0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Nov 2018 19:33:31 +0000 Subject: [PATCH 0414/1848] Implemented delete group feature in group editor. --- WEB-INF/lib/ttAdmin.class.php | 2 +- WEB-INF/lib/ttGroupHelper.class.php | 105 ++++++++++++++++++++++++++++ WEB-INF/lib/ttUser.class.php | 12 ++-- WEB-INF/templates/footer.tpl | 2 +- group_delete.php | 46 +++++++----- 5 files changed, 142 insertions(+), 25 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index ef55ae50b..a2388edf6 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -115,7 +115,7 @@ function markTasksDeleted($group_id) { return true; } - // markGroupDeleted marks the group and everything in it as deleted. + // markGroupDeleted marks a group and everything in it as deleted. function markGroupDeleted($group_id) { // Keep the logic simple by returning false on first error. diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 41c03114e..a6d5fea79 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -100,4 +100,109 @@ static function insertSubgroup($fields) { return (!is_a($affected, 'PEAR_Error')); // TODO: design subgroup roles carefully. Perhaps roles are not to be touched in subgroups at all. } + + // markGroupDeleted marks a group and everything in it as deleted. + // This function is called in context of a logged on user (global $user object). + // It uses current user attributes for access checks and in sql queries. + // Compare this with admin: + // admin can delete any group. + // user can delete only relevant groups and only if allowed. + static function markGroupDeleted($group_id) { + global $user; + + $mdb2 = getConnection(); + $org_id = $user->org_id; + + // Security check. + if (!$user->isGroupValid($group_id)) + return false; + + // Keep the logic simple by returning false on first error. + + // Obtain subgroups and call self recursively on them. + $subgroups = $user->getSubgroups($group_id); + foreach($subgroups as $subgroup) { + if (!$this->markGroupDeleted($subgroup['id'])) + return false; + } + + // Now do actual work with all entities. + + // Some things cannot be marked deleted as we don't have the status field for them. + // Just delete such things (until we have a better way to deal with them). + $tables_to_delete_from = array( + 'tt_config', + 'tt_predefined_expenses', + 'tt_client_project_binds', + 'tt_project_task_binds' + ); + foreach($tables_to_delete_from as $table) { + if (!ttGroupHelper::deleteGroupEntriesFromTable($group_id, $table)) + return false; + } + + // Now mark status deleted where we can. + // Note: we don't mark tt_log, tt_custom_field_lod, or tt_expense_items deleted here. + // Reasoning is: + // + // 1) Users may mark some of them deleted during their work. + // If we mark all of them deleted here, we can't recover nicely + // as we'll lose track of what was accidentally deleted by user. + // + // 2) DB maintenance script (Clean up DB from inactive groups) should + // get rid of these items permanently eventually. + $tables_to_mark_deleted_in = array( + 'tt_cron', + 'tt_fav_reports', + // 'tt_expense_items', + // 'tt_custom_field_log', + 'tt_custom_field_options', + 'tt_custom_fields', + // 'tt_log', + 'tt_invoices', + 'tt_user_project_binds', + 'tt_users', + 'tt_clients', + 'tt_projects', + 'tt_tasks', + 'tt_roles' + ); + foreach($tables_to_mark_deleted_in as $table) { + if (!ttGroupHelper::markGroupDeletedInTable($group_id, $table)) + return false; + } + + // Mark group deleted. + $sql = "update tt_groups set status = null where id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + return true; + } + + // markGroupDeletedInTable is a generic helper function for markGroupDeleted. + // It updates ONE table by setting status to NULL for all records belonging to a group. + static function markGroupDeletedInTable($group_id, $table_name) { + global $user; + $mdb2 = getConnection(); + + // TODO: add modified info to sql for some tables, depending on table name. + + $org_id = $user->org_id; // The only security measure we use here for match. + $sql = "update $table_name set status = null where group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // deleteGroupEntriesFromTable is a generic helper function for markGroupDeleted. + // It deletes entries in ONE table belonging to a given group. + static function deleteGroupEntriesFromTable($group_id, $table_name) { + global $user; + $mdb2 = getConnection(); + + $org_id = $user->org_id; // The only security measure we use here for match. + $sql = "delete from $table_name where group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 16b536c22..ad5c04101 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -380,14 +380,14 @@ function getGroups() { if ($selected_group_id != $this->group_id) { // We are in one of subgroups, and a parent exists. // Get parent group info. - $sql = "select parent_id from tt_groups where org_id = $this->org_id and id = $selected_group_id"; + $sql = "select parent_id from tt_groups where org_id = $this->org_id and id = $selected_group_id and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); $parent_id = $val['parent_id']; if ($parent_id) { // Get parent group name. - $sql = "select name from tt_groups where org_id = $this->org_id and id = $parent_id"; + $sql = "select name from tt_groups where org_id = $this->org_id and id = $parent_id and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -401,11 +401,12 @@ function getGroups() { $groups[] = array('id'=>$selected_group_id,'name'=>$selected_group_name); // Add subgroups. - $sql = "select id, name from tt_groups where org_id = $this->org_id and parent_id = $selected_group_id"; + $sql = "select id, name from tt_groups where org_id = $this->org_id and parent_id = $selected_group_id and status = 1"; + //die($sql); $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { - $groups[] = array('id'=>$val['id'],'name'=>$val['name']); + $groups[] = $val; } } return $groups; @@ -417,7 +418,8 @@ function getSubgroups($group_id = null) { if (!$group_id) $group_id = $this->getActiveGroup(); - $sql = "select id, name, description from tt_groups where org_id = $this->org_id and parent_id = $group_id"; + $sql = "select id, name, description from tt_groups where org_id = $this->org_id". + " and parent_id = $group_id and status is not null"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0419e9e9f..50749d42f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.27.4494 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4495 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_delete.php b/group_delete.php index b2977ee44..db24a4481 100644 --- a/group_delete.php +++ b/group_delete.php @@ -28,26 +28,21 @@ require_once('initialize.php'); import('form.Form'); -import('ttAdmin'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('delete_group')) { - header('Location: access_denied.php'); + header('Location: access_denied.php'); // No rights. exit(); } -$group_id = (int)$request->getParameter('id'); -if ($user->group_id != $group_id) { - header('Location: access_denied.php'); +if (!$user->isGroupValid($request->getParameter('id'))) { + header('Location: access_denied.php'); // Wrong group id. exit(); } // End of access checks. -// Note: reuse ttAdmin class here because deleting a group is a complicated task. -// This creates an issue of using the class for not intended purpose. -// However, otherwise we have to duplicate code, so reuse it is, for now. -$admin = new ttAdmin(); -$group_details = $admin->getGroupDetails($group_id); -$group_name = $group_details['group_name']; +$group_id = (int)$request->getParameter('id'); +$group_name = ttGroupHelper::getGroupName($group_id); $form = new Form('groupForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$group_id)); @@ -56,18 +51,33 @@ if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if ($admin->markGroupDeleted($group_id)) { - $auth->doLogout(); - session_unset(); - header('Location: login.php'); - exit(); + $markedDeleted = ttGroupHelper::markGroupDeleted($group_id); + if ($markedDeleted) { + // TODO: conditional redirects don't look nice. Any better ideas? + if ($group_id == $user->group_id) { + // We marked deleted our own group. Logout and redirect to login page. + $auth->doLogout(); + session_unset(); + header('Location: login.php'); + exit(); + } else { + // We marked deleted a subgroup. Redirect to groups.pgp. + header('Location: groups.php'); + exit(); + } } else $err->add($i18n->get('error.db')); } if ($request->getParameter('btn_cancel')) { - header('Location: group_edit.php'); - exit(); + // TODO: conditional redirects don't look nice. Any better ideas? + if ($group_id == $user->group_id) { + header('Location: group_edit.php'); + exit(); + } else { + header('Location: groups.php'); + exit(); + } } } // isPost From 78fdadfb6001c22512856ee6a5771b8d5a5ae122 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Nov 2018 23:11:25 +0000 Subject: [PATCH 0415/1848] Introduced 2 more localization strings. --- WEB-INF/resources/ca.lang.php | 3 +++ WEB-INF/resources/cs.lang.php | 3 +++ WEB-INF/resources/da.lang.php | 3 +++ WEB-INF/resources/de.lang.php | 3 +++ WEB-INF/resources/en.lang.php | 5 +++++ WEB-INF/resources/es.lang.php | 3 +++ WEB-INF/resources/et.lang.php | 3 +++ WEB-INF/resources/fa.lang.php | 3 +++ WEB-INF/resources/fi.lang.php | 3 +++ WEB-INF/resources/fr.lang.php | 3 +++ WEB-INF/resources/gr.lang.php | 3 +++ WEB-INF/resources/he.lang.php | 3 +++ WEB-INF/resources/hu.lang.php | 3 +++ WEB-INF/resources/it.lang.php | 3 +++ WEB-INF/resources/ja.lang.php | 3 +++ WEB-INF/resources/ko.lang.php | 3 +++ WEB-INF/resources/nl.lang.php | 3 +++ WEB-INF/resources/no.lang.php | 3 +++ WEB-INF/resources/pl.lang.php | 3 +++ WEB-INF/resources/pt-br.lang.php | 3 +++ WEB-INF/resources/pt.lang.php | 3 +++ WEB-INF/resources/ro.lang.php | 3 +++ WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 3 +++ WEB-INF/resources/sl.lang.php | 3 +++ WEB-INF/resources/sr.lang.php | 3 +++ WEB-INF/resources/sv.lang.php | 3 +++ WEB-INF/resources/tr.lang.php | 3 +++ WEB-INF/resources/zh-cn.lang.php | 3 +++ WEB-INF/resources/zh-tw.lang.php | 3 +++ 30 files changed, 91 insertions(+) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 80d11cdfe..a54e3d7a2 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -255,6 +255,9 @@ // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. // Compare with English file to see how it is done there and do Catalan titles similarly. // Specifically: Agregant vs Agregar, etc. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Sessió iniciada', 'title.groups' => 'Grups', // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 191600627..6dfed8f29 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -265,6 +265,9 @@ // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. // Compare with English file to see how it is done there and do Czech titles similarly. // Specifically: Vytváření vs Pridat, etc. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Přihlásit', 'title.groups' => 'Týmy', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index f0d7c4382..475da0010 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -236,6 +236,9 @@ 'label.totals_only' => 'Kun Total', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Login', 'title.groups' => 'Teams', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 69bdffba2..16994c9f4 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -224,6 +224,9 @@ 'label.totals_only' => 'Nur Gesamtstunden', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Anmelden', 'title.groups' => 'Gruppen', // TODO: translate the following. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 4c569dc68..54ebbd94b 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -102,6 +102,9 @@ 'error.cannot_import' => 'Cannot import: %s.', 'error.format' => 'Invalid file format.', +// Success messages. +'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Login', 'button.now' => 'Now', @@ -220,6 +223,8 @@ 'label.totals_only' => 'Totals only', // Form titles. +'title.error' => 'Error', +'title.success' => 'Success', 'title.login' => 'Login', 'title.groups' => 'Groups', 'title.subgroups' => 'Subgroups', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 44bca1bbe..f4f803d38 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -254,6 +254,9 @@ 'label.totals_only' => 'Solo totales', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Sesión iniciada', 'title.groups' => 'Grupos', // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 8f159c0b7..821247454 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -262,6 +262,9 @@ // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. // Compare with English file to see how it is done there and do Estonian titles similarly. // Specifically: lisamine vs lisa, etc. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Login', 'title.groups' => 'Meeskonnad', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 2620ffc12..afc378eb7 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -247,6 +247,9 @@ // 'label.totals_only' => 'Totals only', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'ورود', 'title.groups' => 'تیم ها', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 2067595de..8efb0bf38 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -240,6 +240,9 @@ 'label.totals_only' => 'Vain yhteissummat', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Kirjautuminen', 'title.groups' => 'Tiimit', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index bbd315b0f..3a8804944 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -234,6 +234,9 @@ 'label.totals_only' => 'Totaux uniquement', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Connexion', 'title.groups' => 'Équipes', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 6520d46b9..5f2f9176a 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -227,6 +227,9 @@ 'label.totals_only' => 'Σύνολα μόνο', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Σύνδεση', 'title.groups' => 'Ομάδες', // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 250ea7dc0..37ed7ace4 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -257,6 +257,9 @@ 'labl.totals_only' => 'סיכומים בלבד', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'כניסה', 'title.groups' => 'צוותים', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index ae7920530..e90c53e3e 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -256,6 +256,9 @@ // 'label.totals_only' => 'Totals only', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Bejelentkezés', 'title.groups' => 'Csoportok', // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 7ecc26e4a..923e5b80e 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -235,6 +235,9 @@ // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. // Compare with English file to see how it is done there and do Italian titles similarly. // Specifically: Eliminazione vs Elimina - we probably want nouns in titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Login', 'title.groups' => 'Gruppi', // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 9e6d99a79..3ce170cde 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -261,6 +261,9 @@ 'label.totals_only' => '全体だけ', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'ログイン', 'title.groups' => 'チーム', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index f577566dd..2e9a03f6c 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -261,6 +261,9 @@ 'label.totals_only' => '오직 전체만', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => '로그인', 'title.groups' => '팀', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 5d11a8a0d..0c449ced5 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -221,6 +221,9 @@ 'label.totals_only' => 'Alleen totalen', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Aanmelden', 'title.groups' => 'Groepen', // TODO: translate the following. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index a7a82d753..03a86435d 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -258,6 +258,9 @@ // 'label.totals_only' => 'Totals only', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Innlogging', // TODO: translate the following. // 'title.groups' => 'Groups', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index eeedb29c2..2847ba517 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -241,6 +241,9 @@ 'label.totals_only' => 'Tylko sumy', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Logowanie', 'title.groups' => 'Zespoły', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index e72b03b6e..58795b961 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -238,6 +238,9 @@ 'label.totals_only' => 'Somente totais', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Login', 'title.groups' => 'Equipes', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index e5a5c5022..6ee2ac68f 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -247,6 +247,9 @@ // 'label.totals_only' => 'Totals only', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Login', // TODO: translate the following. // 'title.groups' => 'Groups', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 8cf13bb96..a125e2559 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -261,6 +261,9 @@ // TODO: Improve titles for consistency, so that each title explains correctly what each // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. // Compare with English file to see how it is done there and do Romanian titles similarly. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Autentificare', 'title.groups' => 'Echipe', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 926834e23..cbfc3d77f 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -219,6 +219,8 @@ 'label.totals_only' => 'Только итоги', // Form titles. +'title.error' => 'Ошибка', +'title.success' => 'Успешная операция', 'title.login' => 'Вход в систему', 'title.groups' => 'Группы', 'title.subgroups' => 'Подгруппы', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 2499ea753..56de57ba7 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -247,6 +247,9 @@ 'label.totals_only' => 'Iba celkové', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Prihlásenie', 'title.groups' => 'Tímy', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index c52130efa..59e05d7fd 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -242,6 +242,9 @@ // 'label.totals_only' => 'Totals only', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Prijava', 'title.groups' => 'Timi', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index bd041e508..9bf436fde 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -239,6 +239,9 @@ 'label.totals_only' => 'Samo zbirno', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Prijava', 'title.groups' => 'Timovi', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 8e776e889..1b309afd4 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -235,6 +235,9 @@ 'label.totals_only' => 'Visa endast summeringar', // Rubriker för formulär +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Logga in', 'title.groups' => 'Grupper', // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 4ea24ff15..27742da24 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -270,6 +270,9 @@ // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. // Compare with English file to see how it is done there and do Romanian titles similarly. // Specifically: compare project and client titles and see how they differ. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => 'Giriş', 'title.groups' => 'Ekipler', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 29cb05ca4..ec2e54615 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -249,6 +249,9 @@ // 'label.totals_only' => 'Totals only', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => '登录', 'title.groups' => '团队', // TODO: change "teams" to "groups". // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 2a005abc4..3ede87156 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -257,6 +257,9 @@ // 'label.totals_only' => 'Totals only', // Form titles. +// TODO: Translate the following. +// 'title.error' => 'Error', +// 'title.success' => 'Success', 'title.login' => '登錄', 'title.groups' => '團隊', // TODO: change "teams" to "groups". // TODO: translate the following. From 7f0309861f7e86e63d71775df7e491cdb25433e5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Nov 2018 23:27:06 +0000 Subject: [PATCH 0416/1848] Some recycling in translation files. --- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 +- WEB-INF/resources/sv.lang.php | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 475da0010..29aff6cd8 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -236,8 +236,8 @@ 'label.totals_only' => 'Kun Total', // Form titles. +'title.error' => 'Fejl', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Login', 'title.groups' => 'Teams', // TODO: change "teams" to "groups". diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 16994c9f4..f58a50880 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -224,8 +224,8 @@ 'label.totals_only' => 'Nur Gesamtstunden', // Form titles. +'title.error' => 'Fehler', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Anmelden', 'title.groups' => 'Gruppen', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index afc378eb7..8f374cc32 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -247,8 +247,8 @@ // 'label.totals_only' => 'Totals only', // Form titles. +'title.error' => 'خطا', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'ورود', 'title.groups' => 'تیم ها', // TODO: change "teams" to "groups". diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 8efb0bf38..9fcfdce51 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -240,8 +240,8 @@ 'label.totals_only' => 'Vain yhteissummat', // Form titles. +'title.error' => 'Virhe', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Kirjautuminen', 'title.groups' => 'Tiimit', // TODO: change "teams" to "groups". diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 3a8804944..9b39ee17f 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -234,8 +234,8 @@ 'label.totals_only' => 'Totaux uniquement', // Form titles. +'title.error' => 'Erreur', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Connexion', 'title.groups' => 'Équipes', // TODO: change "teams" to "groups". diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 5f2f9176a..bfc15b015 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -227,8 +227,8 @@ 'label.totals_only' => 'Σύνολα μόνο', // Form titles. +'title.error' => 'Σφάλμα', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Σύνδεση', 'title.groups' => 'Ομάδες', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 37ed7ace4..94d0f5e76 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -257,8 +257,8 @@ 'labl.totals_only' => 'סיכומים בלבד', // Form titles. +'title.error' => 'שגיאה', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'כניסה', 'title.groups' => 'צוותים', // TODO: change "teams" to "groups". diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 923e5b80e..2cb823628 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -235,8 +235,8 @@ // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. // Compare with English file to see how it is done there and do Italian titles similarly. // Specifically: Eliminazione vs Elimina - we probably want nouns in titles. +'title.error' => 'Errore', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Login', 'title.groups' => 'Gruppi', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 0c449ced5..94f612c65 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -221,8 +221,8 @@ 'label.totals_only' => 'Alleen totalen', // Form titles. +'title.error' => 'Fout', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Aanmelden', 'title.groups' => 'Groepen', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 2847ba517..16d4a5d27 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -241,8 +241,8 @@ 'label.totals_only' => 'Tylko sumy', // Form titles. +'title.error' => 'Błąd', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Logowanie', 'title.groups' => 'Zespoły', // TODO: change "teams" to "groups". diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 58795b961..69976b08d 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -238,8 +238,8 @@ 'label.totals_only' => 'Somente totais', // Form titles. +'title.error' => 'Erro', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Login', 'title.groups' => 'Equipes', // TODO: change "teams" to "groups". diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index cbfc3d77f..8c0aebfec 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -220,7 +220,7 @@ // Form titles. 'title.error' => 'Ошибка', -'title.success' => 'Успешная операция', +'title.success' => 'Успех', 'title.login' => 'Вход в систему', 'title.groups' => 'Группы', 'title.subgroups' => 'Подгруппы', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 56de57ba7..a2b79c4ba 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -247,8 +247,8 @@ 'label.totals_only' => 'Iba celkové', // Form titles. +'title.error' => 'Chyba', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Prihlásenie', 'title.groups' => 'Tímy', // TODO: change "teams" to "groups". diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 9bf436fde..1b3f4719d 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -239,8 +239,8 @@ 'label.totals_only' => 'Samo zbirno', // Form titles. +'title.error' => 'Greška', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Prijava', 'title.groups' => 'Timovi', // TODO: change "teams" to "groups". diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 1b309afd4..c09bb77fd 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -235,8 +235,8 @@ 'label.totals_only' => 'Visa endast summeringar', // Rubriker för formulär +'title.error' => 'Fel', // TODO: Translate the following. -// 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Logga in', 'title.groups' => 'Grupper', From 220a0a7280b0fc7baa5a26123ac32b148c567d83 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Nov 2018 23:35:45 +0000 Subject: [PATCH 0417/1848] Introduced msg.success in translation files. --- WEB-INF/resources/ca.lang.php | 4 ++++ WEB-INF/resources/cs.lang.php | 4 ++++ WEB-INF/resources/da.lang.php | 4 ++++ WEB-INF/resources/de.lang.php | 4 ++++ WEB-INF/resources/es.lang.php | 4 ++++ WEB-INF/resources/et.lang.php | 4 ++++ WEB-INF/resources/fa.lang.php | 4 ++++ WEB-INF/resources/fi.lang.php | 4 ++++ WEB-INF/resources/fr.lang.php | 4 ++++ WEB-INF/resources/gr.lang.php | 4 ++++ WEB-INF/resources/he.lang.php | 4 ++++ WEB-INF/resources/hu.lang.php | 4 ++++ WEB-INF/resources/it.lang.php | 4 ++++ WEB-INF/resources/ja.lang.php | 4 ++++ WEB-INF/resources/ko.lang.php | 4 ++++ WEB-INF/resources/nl.lang.php | 4 ++++ WEB-INF/resources/no.lang.php | 4 ++++ WEB-INF/resources/pl.lang.php | 4 ++++ WEB-INF/resources/pt-br.lang.php | 4 ++++ WEB-INF/resources/pt.lang.php | 4 ++++ WEB-INF/resources/ro.lang.php | 4 ++++ WEB-INF/resources/ru.lang.php | 3 +++ WEB-INF/resources/sk.lang.php | 4 ++++ WEB-INF/resources/sl.lang.php | 4 ++++ WEB-INF/resources/sr.lang.php | 4 ++++ WEB-INF/resources/sv.lang.php | 4 ++++ WEB-INF/resources/tr.lang.php | 4 ++++ WEB-INF/resources/zh-cn.lang.php | 4 ++++ WEB-INF/resources/zh-tw.lang.php | 4 ++++ 29 files changed, 115 insertions(+) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index a54e3d7a2..2aa222ddd 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -117,6 +117,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Iniciar sessió', 'button.now' => 'Ara', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 6dfed8f29..92ce94280 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -119,6 +119,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Přihlásit', 'button.now' => 'Teď', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 29aff6cd8..7ffc07992 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -111,6 +111,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Log ind', 'button.now' => 'Nu', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index f58a50880..07da56ca0 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -105,6 +105,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Anmelden', 'button.now' => 'Jetzt', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index f4f803d38..819df1a32 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -115,6 +115,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Iniciar sesion', 'button.now' => 'Ahora', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 821247454..b8679a4ea 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -120,6 +120,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Login', 'button.now' => 'Kohe', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 8f374cc32..a9533c72e 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -118,6 +118,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'ورود', 'button.now' => 'هم اکنون', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 9fcfdce51..d8454884d 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -113,6 +113,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Kirjaudu', 'button.now' => 'Nyt', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 9b39ee17f..0b274de7e 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -111,6 +111,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Connexion', 'button.now' => 'Maintenant', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index bfc15b015..d98ad087e 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -106,6 +106,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Σύνδεση', 'button.now' => 'Τώρα', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 94d0f5e76..6529b77c4 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -128,6 +128,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'היכנס', 'button.now' => 'עכשיו', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index e90c53e3e..5bcd7ee39 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -117,6 +117,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Bejelentkezés', 'button.now' => 'Most', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 2cb823628..5c82b747f 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -110,6 +110,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Login', 'button.now' => 'Adesso', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 3ce170cde..4342bc55e 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -121,6 +121,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'ログイン', 'button.now' => '現在', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 2e9a03f6c..9cbc4e5ec 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -120,6 +120,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => '로그인', 'button.now' => '지금', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 94f612c65..3fe368186 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -102,6 +102,10 @@ 'error.cannot_import' => 'Kan het volgende niet importeren: %s.', 'error.format' => 'Bestandsformaat niet valide.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Aanmelden', 'button.now' => 'Nu', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 03a86435d..f494bc0f1 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -120,6 +120,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Innlogging', 'button.now' => 'Nå', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 16d4a5d27..e21bf1be1 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -115,6 +115,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons 'button.login' => 'Login', 'button.now' => 'Teraz', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 69976b08d..98a9b4a61 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -112,6 +112,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Login', 'button.now' => 'Agora', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 6ee2ac68f..9b7cd5d8e 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -114,6 +114,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Login', 'button.now' => 'Hoje', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index a125e2559..2763bac03 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -121,6 +121,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Autentifica', 'button.now' => 'Acum', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 8c0aebfec..ad24983c3 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -101,6 +101,9 @@ 'error.cannot_import' => 'Невозможно импортировать: %s.', 'error.format' => 'Неверный формат файла.', +// Success messages. +'msg.success' => 'Операция завершена успешно.', + // Labels for buttons. 'button.login' => 'Войти', 'button.now' => 'Сейчас', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index a2b79c4ba..a70af3993 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -117,6 +117,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Prihlásiť', 'button.now' => 'Teraz', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 59e05d7fd..b0d4a0b18 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -111,6 +111,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Prijava', 'button.now' => 'Zdaj', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 1b3f4719d..dd9c3476a 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -112,6 +112,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Prijava', 'button.now' => 'Sada', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index c09bb77fd..4fe3b0422 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -110,6 +110,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Logga in', 'button.now' => 'Nu', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 27742da24..1d0c0ea75 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -124,6 +124,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => 'Giriş', 'button.now' => 'Şimdi', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index ec2e54615..7bad3fa9d 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -112,6 +112,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => '登录', 'button.now' => '当前时间', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 3ede87156..d25f94979 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -118,6 +118,10 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// Success messages. +// TODO: translate the following. +// 'msg.success' => 'Operation completed successfully.', + // Labels for buttons. 'button.login' => '登錄', 'button.now' => '當前時間', From 24d92ab1a3273b9aa6e678f3d381ef9f931ceeb6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Nov 2018 23:39:35 +0000 Subject: [PATCH 0418/1848] Added success.php and .tpl for redirect to. --- WEB-INF/templates/success.tpl | 1 + success.php | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 WEB-INF/templates/success.tpl create mode 100644 success.php diff --git a/WEB-INF/templates/success.tpl b/WEB-INF/templates/success.tpl new file mode 100644 index 000000000..c341a4039 --- /dev/null +++ b/WEB-INF/templates/success.tpl @@ -0,0 +1 @@ + diff --git a/success.php b/success.php new file mode 100644 index 000000000..6af07ef6b --- /dev/null +++ b/success.php @@ -0,0 +1,36 @@ +add($i18n->get('msg.success')); +if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. + +$smarty->assign('title', $i18n->get('title.success')); +$smarty->assign('content_page_name', 'success.tpl'); +$smarty->display('index.tpl'); From 94737b99e973c5ff06e58d10f1c32c0955462a8f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Nov 2018 12:20:09 +0000 Subject: [PATCH 0419/1848] Improved ttUser::updateGroup for subgroup support. --- WEB-INF/lib/ttUser.class.php | 7 ++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index ad5c04101..79f7ae77b 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -509,8 +509,13 @@ function updateGroup($fields) { if (!($this->can('manage_basic_settings') || $this->can('manage_advanced_settings') || $this->can('manage_features'))) return false; + // TODO: update the above for subgroup updates. + + $group_id = $fields['group_id']; + if ($group_id && !$this->isGroupValid($group_id)) return false; $mdb2 = getConnection(); + if (!$group_id) $group_id = $this->getActiveGroup(); if (isset($fields['name'])) $name_part = ', name = '.$mdb2->quote($fields['name']); if (isset($fields['currency'])) $currency_part = ', currency = '.$mdb2->quote($fields['currency']); @@ -537,7 +542,7 @@ function updateGroup($fields) { $time_format_part.$week_start_part.$tracking_mode_part.$task_required_part.$project_required_part.$record_type_part. $bcc_email_part.$allow_ip_part.$plugins_part.$config_part.$lock_spec_part.$workday_minutes_part.$modified_part, ','); - $sql = "update tt_groups set $parts where id = $this->group_id"; + $sql = "update tt_groups set $parts where id = $group_id and org_id = $this->org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 50749d42f..72436ab58 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.27.4495 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4496 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 8a47b340fd212894ebb7b4456f3f0cb647c9ac68 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Nov 2018 12:26:28 +0000 Subject: [PATCH 0420/1848] Wrote ttGroupHelper::getGroupAttrs function. --- WEB-INF/lib/ttGroupHelper.class.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index a6d5fea79..21e62a602 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -205,4 +205,18 @@ static function deleteGroupEntriesFromTable($group_id, $table_name) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // getGroupAttrs obtains all group attributes. + static function getGroupAttrs($group_id) { + global $user; + $mdb2 = getConnection(); + + $sql = "select * from tt_groups". + " where status = 1 and id = $group_id and org_id = $user->org_id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + } + return $val; + } } From 807daaa6d030a1ee01a5fb3822db3a299a84bfc9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Nov 2018 12:46:40 +0000 Subject: [PATCH 0421/1848] Adjusted group_edit.php to work with subgroups. --- WEB-INF/templates/footer.tpl | 2 +- group_edit.php | 51 +++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 72436ab58..ab601cace 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.27.4496 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4497 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_edit.php b/group_edit.php index 872fe1480..a98243cbb 100644 --- a/group_edit.php +++ b/group_edit.php @@ -37,9 +37,16 @@ header('Location: access_denied.php'); exit(); } +$group_id = (int)$request->getParameter('id'); +if ($group_id && !$user->isGroupValid($group_id)) { + header('Location: access_denied.php'); + exit(); +} // End of access checks. -$config = new ttConfigHelper($user->config); +if (!$group_id) $group_id = $user->getActiveGroup(); +$group = ttGroupHelper::getGroupAttrs($group_id); +$config = new ttConfigHelper($group['config']); $advanced_settings = $user->can('manage_advanced_settings'); if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); @@ -65,27 +72,28 @@ $cl_bcc_email = trim($request->getParameter('bcc_email')); $cl_allow_ip = trim($request->getParameter('allow_ip')); } else { - $cl_group = $user->group_name; - $cl_currency = ($user->currency == ''? CURRENCY_DEFAULT : $user->currency); - $cl_lang = $user->lang; - $cl_decimal_mark = $user->decimal_mark; - $cl_date_format = $user->date_format; - $cl_time_format = $user->time_format; - $cl_start_week = $user->week_start; - $cl_show_holidays = $user->show_holidays; - $cl_tracking_mode = $user->tracking_mode; - $cl_project_required = $user->project_required; - $cl_task_required = $user->task_required; - $cl_record_type = $user->record_type; - $cl_punch_mode = $user->punch_mode; - $cl_allow_overlap = $user->allow_overlap; - $cl_future_entries = $user->future_entries; - $cl_uncompleted_indicators = $user->uncompleted_indicators; - $cl_bcc_email = $user->bcc_email; - $cl_allow_ip = $user->allow_ip; + $cl_group = $group['name']; + $cl_currency = ($group['currency'] == ''? CURRENCY_DEFAULT : $group['currency']); + $cl_lang = $group['lang']; + $cl_decimal_mark = $group['decimal_mark']; + $cl_date_format = $group['date_format']; + $cl_time_format = $group['time_format']; + $cl_start_week = $group['week_start']; + $cl_show_holidays = $config->getDefinedValue('show_holidays'); + $cl_tracking_mode = $group['tracking_mode']; + $cl_project_required = $group['project_required']; + $cl_task_required = $group['task_required']; + $cl_record_type = $group['record_type']; + $cl_punch_mode = $config->getDefinedValue('punch_mode'); + $cl_allow_overlap = $config->getDefinedValue('allow_overlap'); + $cl_future_entries = $config->getDefinedValue('future_entries'); + $cl_uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators'); + $cl_bcc_email = $group['bcc_email']; + $cl_allow_ip = $group['allow_ip']; } $form = new Form('groupForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$group_id)); $form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'group_name','value'=>$cl_group,'enable'=>$advanced_settings)); $form->addInput(array('type'=>'text','maxlength'=>'7','name'=>'currency','value'=>$cl_currency)); @@ -175,7 +183,7 @@ if ($request->getParameter('btn_delete')) { // Delete button pressed, redirect. - header('Location: group_delete.php?id='.$user->group_id); + header('Location: group_delete.php?id='.$group_id); exit(); } @@ -197,6 +205,7 @@ $config->setDefinedValue('uncompleted_indicators', $cl_uncompleted_indicators); if ($user->updateGroup(array( + 'group_id' => $group_id, 'name' => $cl_group, 'currency' => $cl_currency, 'lang' => $cl_lang, @@ -212,7 +221,7 @@ 'bcc_email' => $cl_bcc_email, 'allow_ip' => $cl_allow_ip, 'config' => $config->getConfig()))) { - header('Location: time.php'); + header('Location: success.php'); exit(); } else $err->add($i18n->get('error.db')); From e19990636073ca1aa353a67033dc0cec311fdab9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Nov 2018 13:10:34 +0000 Subject: [PATCH 0422/1848] Added description field on group_edit.php. --- WEB-INF/lib/ttUser.class.php | 3 ++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 4 ++++ group_edit.php | 5 +++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 79f7ae77b..ab5bdbff4 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -518,6 +518,7 @@ function updateGroup($fields) { if (!$group_id) $group_id = $this->getActiveGroup(); if (isset($fields['name'])) $name_part = ', name = '.$mdb2->quote($fields['name']); + if (isset($fields['description'])) $description_part = ', description = '.$mdb2->quote($fields['description']); if (isset($fields['currency'])) $currency_part = ', currency = '.$mdb2->quote($fields['currency']); if (isset($fields['lang'])) $lang_part = ', lang = '.$mdb2->quote($fields['lang']); if (isset($fields['decimal_mark'])) $decimal_mark_part = ', decimal_mark = '.$mdb2->quote($fields['decimal_mark']); @@ -538,7 +539,7 @@ function updateGroup($fields) { if (isset($fields['workday_minutes'])) $workday_minutes_part = ', workday_minutes = '.$mdb2->quote($fields['workday_minutes']); $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($this->id); - $parts = trim($name_part.$currency_part.$lang_part.$decimal_mark_part.$date_format_part. + $parts = trim($name_part.$description_part.$currency_part.$lang_part.$decimal_mark_part.$date_format_part. $time_format_part.$week_start_part.$tracking_mode_part.$task_required_part.$project_required_part.$record_type_part. $bcc_email_part.$allow_ip_part.$plugins_part.$config_part.$lock_spec_part.$workday_minutes_part.$modified_part, ','); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ab601cace..814be7981 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + diff --git a/group_edit.php b/group_edit.php index a98243cbb..77ddc6189 100644 --- a/group_edit.php +++ b/group_edit.php @@ -53,6 +53,7 @@ if ($request->isPost()) { $cl_group = trim($request->getParameter('group_name')); + $cl_description = trim($request->getParameter('description')); $cl_currency = trim($request->getParameter('currency')); if (!$cl_currency) $cl_currency = CURRENCY_DEFAULT; $cl_lang = $request->getParameter('lang'); @@ -73,6 +74,7 @@ $cl_allow_ip = trim($request->getParameter('allow_ip')); } else { $cl_group = $group['name']; + $cl_description = $group['description']; $cl_currency = ($group['currency'] == ''? CURRENCY_DEFAULT : $group['currency']); $cl_lang = $group['lang']; $cl_decimal_mark = $group['decimal_mark']; @@ -95,6 +97,7 @@ $form = new Form('groupForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$group_id)); $form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'group_name','value'=>$cl_group,'enable'=>$advanced_settings)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'text','maxlength'=>'7','name'=>'currency','value'=>$cl_currency)); // Prepare an array of available languages. @@ -189,6 +192,7 @@ // Validate user input. if (!ttValidString($cl_group, true)) $err->add($i18n->get('error.field'), $i18n->get('label.group_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidString($cl_currency, true)) $err->add($i18n->get('error.field'), $i18n->get('label.currency')); if ($advanced_settings) { if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.bcc')); @@ -207,6 +211,7 @@ if ($user->updateGroup(array( 'group_id' => $group_id, 'name' => $cl_group, + 'description' => $cl_description, 'currency' => $cl_currency, 'lang' => $cl_lang, 'decimal_mark' => $cl_decimal_mark, From 2f8a9f1fb0051c27a7235ef42af6502782cf2f83 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Nov 2018 13:38:45 +0000 Subject: [PATCH 0423/1848] Fixed export-import to include group descriptions. --- WEB-INF/lib/ttGroupExportHelper.class.php | 1 + WEB-INF/lib/ttOrgImportHelper.class.php | 4 +++- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 54b8aaa11..9490f0757 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -123,6 +123,7 @@ function writeData() { // Write group info. $group = $this->getGroupAttrs(); $group_part = " $this->current_parent_group_id, 'org_id' => $this->org_id, 'name' => $attrs['NAME'], + 'description' => $attrs['DESCRIPTION'], 'currency' => $attrs['CURRENCY'], 'decimal_mark' => $attrs['DECIMAL_MARK'], 'lang' => $attrs['LANG'], @@ -655,7 +656,7 @@ private function createGroup($fields) { global $i18n; $mdb2 = getConnection(); - $columns = '(parent_id, org_id, name, currency, decimal_mark, lang, date_format, time_format'. + $columns = '(parent_id, org_id, name, description, currency, decimal_mark, lang, date_format, time_format'. ', week_start, tracking_mode, project_required, task_required, record_type, bcc_email'. ', allow_ip, password_complexity, plugins, lock_spec'. ', workday_minutes, config, created, created_ip, created_by)'; @@ -664,6 +665,7 @@ private function createGroup($fields) { $values .= $mdb2->quote($fields['parent_id']); $values .= ', '.$mdb2->quote($fields['org_id']); $values .= ', '.$mdb2->quote(trim($fields['name'])); + $values .= ', '.$mdb2->quote(trim($fields['description'])); $values .= ', '.$mdb2->quote(trim($fields['currency'])); $values .= ', '.$mdb2->quote($fields['decimal_mark']); $values .= ', '.$mdb2->quote($fields['lang']); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 814be7981..4829793a8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.27.4497 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4498 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index ea46bec6f..d15944899 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -31,6 +31,10 @@ function handleTaskRequiredCheckbox() { {$i18n.label.group_name}: {$forms.groupForm.group_name.control}
{$i18n.label.description}:{$forms.groupForm.description.control}
{$i18n.label.currency}: {$forms.groupForm.currency.control}
-
 Anuko Time Tracker 1.18.27.4498 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4499 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From d82f2da8a4df2190f26f1ce8a44fe35c42bba1da Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Nov 2018 15:16:32 +0000 Subject: [PATCH 0424/1848] Fixed import for subgroups. --- WEB-INF/lib/ttOrgImportHelper.class.php | 30 +++++++++++++++++++------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 124b035b0..30b9a09da 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -45,7 +45,7 @@ class ttOrgImportHelper { var $firstPass = true; // True during first pass through the file. var $org_id = null; // Organization id (same as top group_id). var $current_group_id = null; // Current group id during parsing. - var $current_parent_group_id = null; // Current parent group id during parsing. + var $parents = array(); // A stack of parent group ids for current group all the way to the root including self. var $top_role_id = 0; // Top role id. // Entity maps for current group. They map XML ids with database ids. @@ -106,7 +106,7 @@ function startElement($parser, $name, $attrs) { if ($name == 'GROUP') { // Create a new group. $this->current_group_id = $this->createGroup(array( - 'parent_id' => $this->current_parent_group_id, + 'parent_id' => $this->current_group_id, // Note: after insert current_group_id changes. 'org_id' => $this->org_id, 'name' => $attrs['NAME'], 'description' => $attrs['DESCRIPTION'], @@ -135,8 +135,8 @@ function startElement($parser, $name, $attrs) { $sql = "update tt_groups set org_id = $this->current_group_id where org_id is NULL and id = $this->current_group_id"; $affected = $mdb2->exec($sql); } - // Set parent group to create subgroups with this group as parent at next entry here. - $this->current_parent_group_id = $this->current_group_id; + // Add self to parent stack. + array_push($this->parents, $this->current_group_id); return; } @@ -541,6 +541,22 @@ function startElement($parser, $name, $attrs) { } } + // endElement - callback handler for ending tags in XML. + // We use this only for process element endings and + // set current_group_id to an immediate parent. + // This is required to import group hierarchy correctly. + function endElement($parser, $name) { + // No need to care about first or second pass, as this is used only in second pass. + // See 2nd xml_set_element_handler, where this handler is set. + if ($name == 'GROUP') { + // Remove self from the parent stack. + $self = array_pop($this->parents); + // Set current group id to an immediate parent. + $len = count($this->parents); + $this->current_group_id = $len ? $this->parents[$len-1] : null; + } + } + // importXml - uncompresses the file, reads and parses its content. During parsing, // startElement, endElement, and dataElement functions are called as many times as necessary. // Actual import occurs in the endElement handler. @@ -575,7 +591,7 @@ function importXml() { // Initialize XML parser. $parser = xml_parser_create(); xml_set_object($parser, $this); - xml_set_element_handler($parser, 'startElement', false); + xml_set_element_handler($parser, 'startElement', false); // No need to process end tags in 1st pass. // We need to parse the file 2 times: // 1) First pass: determine if import is possible. @@ -608,9 +624,9 @@ function importXml() { // Now we can do a second pass, where real work is done. $parser = xml_parser_create(); xml_set_object($parser, $this); - xml_set_element_handler($parser, 'startElement', false); + xml_set_element_handler($parser, 'startElement', 'endElement'); // Need to process ending tags too. - // Read and parse the content of the file. During parsing, startElement is called back for each tag. + // Read and parse the content of the file. During parsing, startElement and endElement are called back for each tag. $file = fopen($filename, 'r'); while (($data = fread($file, 4096)) && $this->errors->no()) { if (!xml_parse($parser, $data, feof($file))) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4829793a8..a59278ed9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.27.4499 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4500 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b9450dc964f5b244713dc5c799a81a660269f22b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Nov 2018 16:58:23 +0000 Subject: [PATCH 0425/1848] Wrote ttUser::getUserPartForHeader and included on behalf group in output. --- WEB-INF/lib/ttUser.class.php | 19 +++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 6 +----- default.css | 4 ++++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index ab5bdbff4..f89bba684 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -652,4 +652,23 @@ function getMaxRankForGroup($group_id) { return $max_rank; } + + // getUserPartForHeader constructs a string for user to display on pages header. + // It changes with "on behalf" attributes for both user and group. + function getUserPartForHeader() { + global $i18n; + + $user_part = htmlspecialchars($this->name); + $user_part .= ' - '.htmlspecialchars($this->role_name); + if ($this->behalf_id) { + $user_part .= ' '.$i18n->get('label.on_behalf').' '.htmlspecialchars($this->behalf_name).''; + } + if ($this->behalf_group_id) { + $user_part .= ', '.$i18n->get('label.on_behalf').' '.htmlspecialchars($this->behalf_group_name).''; + } else { + if ($this->group_name) // Note: we did not require group names in the past. + $user_part .= ', '.$this->group_name; + } + return $user_part; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a59278ed9..0240ecfba 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.27.4500 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4501 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 23dfdc117..de25c0660 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -165,11 +165,7 @@ {if $title} - {if $user->name} - - {else} - - {/if} + {* No need to escape as it is done in the class. *}
{$title}{if $timestring}: {$timestring}{/if}
{$user->name|escape} - {$user->role_name|escape}{if $user->behalf_id > 0} {$i18n.label.on_behalf} {$user->behalf_name|escape}{/if}{if $user->group_name}, {$user->group_name|escape}{/if}
 
{$user->getUserPartForHeader()}
{/if} diff --git a/default.css b/default.css index ee6a5b167..47dc81e44 100644 --- a/default.css +++ b/default.css @@ -74,6 +74,10 @@ input[type=checkbox], label { color: #444444; } +.onBehalf { + font-weight: bold; +} + .tableHeader { font-weight: bold; text-align: left; From 460983ff96c7f6b57d7d7d567c767730fb1ba36e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Nov 2018 17:04:48 +0000 Subject: [PATCH 0426/1848] Fixed user details output. --- WEB-INF/lib/ttUser.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index f89bba684..25cc83f7a 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -657,6 +657,7 @@ function getMaxRankForGroup($group_id) { // It changes with "on behalf" attributes for both user and group. function getUserPartForHeader() { global $i18n; + if (!$this->id) return null; $user_part = htmlspecialchars($this->name); $user_part .= ' - '.htmlspecialchars($this->role_name); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0240ecfba..161df0208 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.27.4501 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4503 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From d27960ac5530c7c81b9adba85253b0e216f81476 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Nov 2018 19:14:59 +0000 Subject: [PATCH 0427/1848] Made group name mandatory for subgroup support. --- WEB-INF/lib/ttAdmin.class.php | 2 +- WEB-INF/lib/ttRegistrator.class.php | 2 +- WEB-INF/templates/admin_group_add.tpl | 2 +- WEB-INF/templates/admin_group_edit.tpl | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 6 +++++- WEB-INF/templates/register.tpl | 2 +- group_edit.php | 2 +- 8 files changed, 12 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index a2388edf6..747274f12 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -198,7 +198,7 @@ function validateGroupInfo($fields) { $result = true; - if (!ttValidString($fields['group_name'], true)) { + if (!ttValidString($fields['new_group_name'])) { $this->err->add($i18n->get('error.field'), $i18n->get('label.group_name')); $result = false; } diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 8e755837e..77ffb6b57 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -67,7 +67,7 @@ function __construct($fields, &$err) { function validate() { global $i18n; - if (!ttValidString($this->group_name, true)) + if (!ttValidString($this->group_name)) $this->err->add($i18n->get('error.field'), $i18n->get('label.group_name')); if (!ttValidString($this->currency, true)) $this->err->add($i18n->get('error.field'), $i18n->get('label.currency')); diff --git a/WEB-INF/templates/admin_group_add.tpl b/WEB-INF/templates/admin_group_add.tpl index fd671e9c7..029b52545 100644 --- a/WEB-INF/templates/admin_group_add.tpl +++ b/WEB-INF/templates/admin_group_add.tpl @@ -4,7 +4,7 @@ - + diff --git a/WEB-INF/templates/admin_group_edit.tpl b/WEB-INF/templates/admin_group_edit.tpl index 4c52580eb..70443e327 100644 --- a/WEB-INF/templates/admin_group_edit.tpl +++ b/WEB-INF/templates/admin_group_edit.tpl @@ -4,7 +4,7 @@
{$i18n.label.group_name}:{$i18n.label.group_name} (*): {$forms.groupForm.group_name.control}
- + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 161df0208..ec0063a31 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.group_name}:{$i18n.label.group_name} (*): {$forms.groupForm.group_name.control}
 
-
 Anuko Time Tracker 1.18.27.4503 | Copyright © Anuko | +  Anuko Time Tracker 1.18.27.4504 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index d15944899..8ccb258fd 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -28,7 +28,7 @@ function handleTaskRequiredCheckbox() { {if $user->can('manage_basic_settings')} - + @@ -109,6 +109,10 @@ function handleTaskRequiredCheckbox() { + + + + {/if} {* initialize preview text *} + {$forms.timeRecordForm.open}
{$i18n.label.group_name}:{$i18n.label.group_name} (*): {$forms.groupForm.group_name.control}
{$i18n.form.group_edit.allow_ip}: {$forms.groupForm.allow_ip.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
diff --git a/expense_edit.php b/expense_edit.php index 049bc4bee..cca8225a4 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -147,7 +147,8 @@ // Hidden control for record id. $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.save'))); +// TODO: improve on conditional confirmSave. +$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date();return(confirmSave())','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.copy'))); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); @@ -220,6 +221,9 @@ } } // isPost +// TODO: improve on conditional confirmSave. +$smarty->assign('entry_date', $cl_date); + $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); diff --git a/time_edit.php b/time_edit.php index 5670f1936..17ba34b41 100644 --- a/time_edit.php +++ b/time_edit.php @@ -210,7 +210,8 @@ if ($user->can('manage_invoices') && $user->isPluginEnabled('ps')) $form->addInput(array('type'=>'checkbox','name'=>'paid','value'=>$cl_paid)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.save'))); +// TODO: improve on conditional confirmSave. +$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date();return(confirmSave())','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.copy'))); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); @@ -400,6 +401,9 @@ } } // isPost +// TODO: improve on conditional confirmSave. +$smarty->assign('entry_date', $cl_date); + $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); From b1082e6ec27ca11586bd786b65f509d1a20220f6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 12:35:35 +0000 Subject: [PATCH 0467/1848] Refactoring in import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 28 ++++++++++++++++++++++++- WEB-INF/lib/ttRoleHelper.class.php | 5 +++-- WEB-INF/templates/footer.tpl | 2 +- role_add.php | 2 -- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 345b1d2e4..011f2081d 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -155,7 +155,7 @@ function startElement($parser, $name, $attrs) { if ($name == 'ROLE') { // We get here when processing tags for the current group. - $role_id = ttRoleHelper::insert(array( + $role_id = $this->insertRole(array( 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, 'name' => $attrs['NAME'], @@ -745,6 +745,32 @@ private function insertProject($fields) return $last_id; } + // insertRole - inserts a role into tt_roles table. + private function insertRole($fields) + { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $name = $fields['name']; + $rank = (int) $fields['rank']; + $description = $fields['description']; + $rights = $fields['rights']; + $status = $fields['status']; + + $sql = "insert into tt_roles (group_id, org_id, name, rank, description, rights, status) + values ($group_id, $org_id, ".$mdb2->quote($name).", $rank, ".$mdb2->quote($description).", ".$mdb2->quote($rights).", ".$mdb2->quote($status).")"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + $sql = "SELECT LAST_INSERT_ID() AS last_id"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + $last_id = $val['last_id']; + return $last_id; + } + // The insertClient function inserts a new client as well as client to project binds. private function insertClient($fields) { diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 353744699..c14bc970f 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -156,10 +156,11 @@ static function delete($role_id) { // insert - inserts an entry into tt_roles table. static function insert($fields) { + global $user; $mdb2 = getConnection(); - $group_id = (int) $fields['group_id']; - $org_id = (int) $fields['org_id']; + $group_id = $user->getGroup(); + $org_id = $user->org_id; $name = $fields['name']; $rank = (int) $fields['rank']; $description = $fields['description']; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5879e8894..9f251f40c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.28.4542 | Copyright © Anuko | +  Anuko Time Tracker 1.18.28.4543 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/role_add.php b/role_add.php index e1e16cc77..0386e5b14 100644 --- a/role_add.php +++ b/role_add.php @@ -63,8 +63,6 @@ if (!$existing_role) { // Insert a role with default user rights. if (ttRoleHelper::insert(array( - 'group_id' => $user->group_id, - 'org_id' => $user->org_id, 'name' => $cl_name, 'rank' => $cl_rank, 'description' => $cl_description, From cbc2ae6c2e83edfe7b4242b7dd2f9bfb1359820e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 13:22:19 +0000 Subject: [PATCH 0468/1848] Ongoing refactoring, replacing the method to obtain last insert ids. --- WEB-INF/lib/ttClientHelper.class.php | 7 +- WEB-INF/lib/ttCustomFieldHelper.class.php | 100 ---------------------- WEB-INF/lib/ttUserHelper.class.php | 6 +- WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 3 insertions(+), 112 deletions(-) delete mode 100644 WEB-INF/lib/ttCustomFieldHelper.class.php diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 24d00d236..3dc60bdb7 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -189,12 +189,7 @@ static function insert($fields) if (is_a($affected, 'PEAR_Error')) return false; - $last_id = 0; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; - + $last_id = $mdb2->lastInsertID('tt_clients', 'id'); if (count($projects) > 0) foreach ($projects as $p_id) { $sql = "insert into tt_client_project_binds (client_id, project_id, group_id, org_id) values($last_id, $p_id, $group_id, $org_id)"; diff --git a/WEB-INF/lib/ttCustomFieldHelper.class.php b/WEB-INF/lib/ttCustomFieldHelper.class.php deleted file mode 100644 index 15c7ca054..000000000 --- a/WEB-INF/lib/ttCustomFieldHelper.class.php +++ /dev/null @@ -1,100 +0,0 @@ -quote($label).", $required, ".$mdb2->quote($status).")"; - - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - $last_id = 0; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; - - return $last_id; - } - - // The insertOption function inserts a new custom field option in database. - static function insertOption($fields) - { - $mdb2 = getConnection(); - - $field_id = (int) $fields['field_id']; - $value = $fields['value']; - - $sql = "insert into tt_custom_field_options (field_id, value) - values ($field_id, ".$mdb2->quote($value).")"; - - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - $last_id = 0; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; - - return $last_id; - } - - // The insertLogEntry function inserts a new custom field log entry in database. - static function insertLogEntry($fields) - { - $mdb2 = getConnection(); - - $log_id = (int) $fields['log_id']; - $field_id = (int) $fields['field_id']; - $option_id = $fields['option_id']; - $value = $fields['value']; - $status = $fields['status']; - - $sql = "insert into tt_custom_field_log (log_id, field_id, option_id, value, status) - values ($log_id, $field_id, ".$mdb2->quote($option_id).", ".$mdb2->quote($value).", ".$mdb2->quote($status).")"; - - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } -} diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 2ff774ff5..42d7c9109 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -120,11 +120,7 @@ static function insert($fields, $hash = true) { // Now deal with project assignment. if (!is_a($affected, 'PEAR_Error')) { - $sql = "SELECT LAST_INSERT_ID() AS last_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_id']; - + $last_id = $mdb2->lastInsertID('tt_users', 'id'); $projects = isset($fields['projects']) ? $fields['projects'] : array(); if (count($projects) > 0) { // We have at least one project assigned. Insert corresponding entries in tt_user_project_binds table. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9f251f40c..501ebf76a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.28.4543 | Copyright © Anuko | +  Anuko Time Tracker 1.18.28.4544 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b43967e75a9a02e61a8ac2263f3b5432556d661f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 13:32:31 +0000 Subject: [PATCH 0469/1848] A bit more refactoring. --- WEB-INF/lib/ttFavReportHelper.class.php | 9 ++------- WEB-INF/lib/ttInvoiceHelper.class.php | 7 +------ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index f1943f71f..36600e219 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -107,13 +107,8 @@ static function insertReport($fields) { if (is_a($affected, 'PEAR_Error')) return false; - $sql = "select last_insert_id() as last_id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) - return false; - - $val = $res->fetchRow(); - return $val['last_id']; + $last_id = $mdb2->lastInsertID('tt_fav_reports', 'id'); + return $last_id; } // updateReport - updates report options in the database. diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 3d67f6a78..41dace01b 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -56,12 +56,7 @@ static function insert($fields) if (is_a($affected, 'PEAR_Error')) return false; - $last_id = 0; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; - + $last_id = $mdb2->lastInsertID('tt_invoices', 'id'); return $last_id; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 501ebf76a..c16158002 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.28.4544 | Copyright © Anuko | +  Anuko Time Tracker 1.18.28.4545 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c30bd94928988ff03ade10ca872968681456e12c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 14:31:27 +0000 Subject: [PATCH 0470/1848] Refactoring, finished with last insert ids. --- WEB-INF/lib/ttInvoiceHelper.class.php | 6 +--- WEB-INF/lib/ttOrgImportHelper.class.php | 38 +++++-------------------- WEB-INF/lib/ttProjectHelper.class.php | 8 ++---- WEB-INF/lib/ttRoleHelper.class.php | 5 +--- WEB-INF/lib/ttTaskHelper.class.php | 7 ++--- WEB-INF/templates/footer.tpl | 2 +- 6 files changed, 14 insertions(+), 52 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 41dace01b..0867ee1eb 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -332,11 +332,7 @@ static function createInvoice($fields) { if (is_a($affected, 'PEAR_Error')) return false; // Mark associated invoice items with invoice id. - $last_id = 0; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; + $last_id = $mdb2->lastInsertID('tt_invoices', 'id'); // Our update sql is different depending on tracking mode. if (MODE_TIME == $user->getTrackingMode()) { diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 011f2081d..328eabefb 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -725,11 +725,7 @@ private function insertProject($fields) if (is_a($affected, 'PEAR_Error')) return false; - $last_id = 0; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; + $last_id = $mdb2->lastInsertID('tt_projects', 'id'); // Insert binds into tt_project_task_binds table. if (is_array($tasks)) { @@ -764,10 +760,7 @@ private function insertRole($fields) if (is_a($affected, 'PEAR_Error')) return false; - $sql = "SELECT LAST_INSERT_ID() AS last_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_id']; + $last_id = $mdb2->lastInsertID('tt_roles', 'id'); return $last_id; } @@ -796,11 +789,7 @@ private function insertClient($fields) if (is_a($affected, 'PEAR_Error')) return false; - $last_id = 0; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; + $last_id = $mdb2->lastInsertID('tt_clients', 'id'); if (count($projects) > 0) foreach ($projects as $p_id) { @@ -844,13 +833,8 @@ private function insertFavReport($fields) { if (is_a($affected, 'PEAR_Error')) return false; - $sql = "select last_insert_id() as last_id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) - return false; - - $val = $res->fetchRow(); - return $val['last_id']; + $last_id = $mdb2->lastInsertID('tt_fav_reports', 'id'); + return $last_id; } // insertNotification function inserts a new notification into database. @@ -912,11 +896,7 @@ private function insertCustomField($fields) { if (is_a($affected, 'PEAR_Error')) return false; - $last_id = 0; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; + $last_id = $mdb2->lastInsertID('tt_custom_fields', 'id'); return $last_id; } @@ -935,11 +915,7 @@ private function insertCustomFieldOption($fields) { if (is_a($affected, 'PEAR_Error')) return false; - $last_id = 0; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; + $last_id = $mdb2->lastInsertID('tt_custom_field_options', 'id'); return $last_id; } diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 2a439dd9f..98d928f96 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -206,12 +206,8 @@ static function insert($fields) $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - - $last_id = 0; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; + + $last_id = $mdb2->lastInsertID('tt_projects', 'id'); // Bind the project to users. $active_users = ttTeamHelper::getActiveUsers(array('getAllFields'=>true)); diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index c14bc970f..0686b1cdf 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -173,10 +173,7 @@ static function insert($fields) if (is_a($affected, 'PEAR_Error')) return false; - $sql = "SELECT LAST_INSERT_ID() AS last_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_id']; + $last_id = $mdb2->lastInsertID('tt_roles', 'id'); return $last_id; } diff --git a/WEB-INF/lib/ttTaskHelper.class.php b/WEB-INF/lib/ttTaskHelper.class.php index 0d4d5eff4..2987d2781 100644 --- a/WEB-INF/lib/ttTaskHelper.class.php +++ b/WEB-INF/lib/ttTaskHelper.class.php @@ -153,11 +153,8 @@ static function insert($fields) if (is_a($affected, 'PEAR_Error')) return false; - $sql = "select last_insert_id() as last_insert_id"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $last_id = $val['last_insert_id']; - + $last_id = $mdb2->lastInsertID('tt_tasks', 'id'); + if (is_array($projects)) { foreach ($projects as $p_id) { // Insert task binds into tt_project_task_binds table. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c16158002..0b4dd2b45 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.28.4545 | Copyright © Anuko | +  Anuko Time Tracker 1.18.28.4546 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From db51a4b1e95f48d82bf2a214f8d0736f2485e3a2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 14:51:33 +0000 Subject: [PATCH 0471/1848] Ongoing refactoring on decoupling import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 23 +++++++++++++++++------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 328eabefb..060a7c1d8 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -27,13 +27,8 @@ // +----------------------------------------------------------------------+ import('ttUserHelper'); -import('ttRoleHelper'); import('ttTaskHelper'); -import('ttClientHelper'); import('ttInvoiceHelper'); -import('ttTimeHelper'); -import('ttExpenseHelper'); -import('ttFavReportHelper'); // ttOrgImportHelper class is used to import organization data from an XML file // prepared by ttOrgExportHelper and consisting of nested groups with their info. @@ -63,7 +58,7 @@ class ttOrgImportHelper { // Constructor. function __construct(&$errors) { $this->errors = &$errors; - $this->top_role_id = ttRoleHelper::getRoleByRank(512, 0); + $this->top_role_id = $this->getTopRole(); } // startElement - callback handler for opening tags in XML. @@ -981,4 +976,20 @@ private function insertCustomFieldLogEntry($fields) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // getTopRole returns top role id. + private function getTopRole() { + global $user; + $mdb2 = getConnection(); + + $sql = "select id from tt_roles where group_id = 0 and rank = ".MAX_RANK." and status = 1"; + $res = $mdb2->query($sql); + + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if ($val['id']) + return $val['id']; + } + return false; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0b4dd2b45..f0d3ff542 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.28.4546 | Copyright © Anuko | +  Anuko Time Tracker 1.18.28.4547 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 109089e858e28200e714a790883c236230b3922f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 15:09:02 +0000 Subject: [PATCH 0472/1848] Refactored ttRoleHelper::getRoleByRank(). --- WEB-INF/lib/ttOrgImportHelper.class.php | 1 - WEB-INF/lib/ttRoleHelper.class.php | 8 +++++--- WEB-INF/templates/footer.tpl | 2 +- role_add.php | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 060a7c1d8..ebb5febd2 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -979,7 +979,6 @@ private function insertCustomFieldLogEntry($fields) { // getTopRole returns top role id. private function getTopRole() { - global $user; $mdb2 = getConnection(); $sql = "select id from tt_roles where group_id = 0 and rank = ".MAX_RANK." and status = 1"; diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 0686b1cdf..c324d6805 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -102,13 +102,15 @@ static function isClientRole($role_id) { } // getRoleByRank looks up a role by its rank. - static function getRoleByRank($rank, $group_id) { + static function getRoleByRank($rank) { global $user; $mdb2 = getConnection(); - $rank = (int) $rank; // Cast to int just in case for better security. + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $rank = (int) $rank; // Cast to int just in case. - $sql = "select id from tt_roles where group_id = $group_id and rank = $rank and (status = 1 or status = 0)"; + $sql = "select id from tt_roles where group_id = $group_id and org_id = $org_id and rank = $rank and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f0d3ff542..3b96b55be 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.28.4547 | Copyright © Anuko | +  Anuko Time Tracker 1.18.28.4548 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/role_add.php b/role_add.php index 0386e5b14..97883151b 100644 --- a/role_add.php +++ b/role_add.php @@ -59,7 +59,7 @@ if ($err->no() && ttRoleHelper::getRoleByName($cl_name)) $err->add($i18n->get('error.object_exists')); if ($err->no()) { - $existing_role = ttRoleHelper::getRoleByRank($cl_rank, $user->group_id); + $existing_role = ttRoleHelper::getRoleByRank($cl_rank); if (!$existing_role) { // Insert a role with default user rights. if (ttRoleHelper::insert(array( From dd0021e48080a708591d7ad763c63f5fb98e3fb7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 15:57:21 +0000 Subject: [PATCH 0473/1848] A bit more progress on decoupling import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 26 +++++++++++++++++++++++-- WEB-INF/lib/ttTaskHelper.class.php | 21 ++++++++++---------- WEB-INF/templates/footer.tpl | 2 +- mobile/task_add.php | 2 -- mobile/task_edit.php | 2 -- task_add.php | 2 -- task_edit.php | 2 -- 7 files changed, 36 insertions(+), 21 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index ebb5febd2..cbf7d28a2 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -27,7 +27,6 @@ // +----------------------------------------------------------------------+ import('ttUserHelper'); -import('ttTaskHelper'); import('ttInvoiceHelper'); // ttOrgImportHelper class is used to import organization data from an XML file @@ -167,7 +166,7 @@ function startElement($parser, $name, $attrs) { if ($name == 'TASK') { // We get here when processing tags for the current group. - $task_id = ttTaskHelper::insert(array( + $task_id = $this->insertTask(array( 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, 'name' => $attrs['NAME'], @@ -700,6 +699,29 @@ private function insertExpense($fields) { return (!is_a($affected, 'PEAR_Error')); } + // insertTask function inserts a new task into database. + private function insertTask($fields) + { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $name = $fields['name']; + $description = $fields['description']; + $projects = $fields['projects']; + $status = $fields['status']; + + $sql = "insert into tt_tasks (group_id, org_id, name, description, status) + values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($status).")"; + $affected = $mdb2->exec($sql); + $last_id = 0; + if (is_a($affected, 'PEAR_Error')) + return false; + + $last_id = $mdb2->lastInsertID('tt_tasks', 'id'); + return $last_id; + } + // insertProject - a helper function to insert a project as well as project to task binds. private function insertProject($fields) { diff --git a/WEB-INF/lib/ttTaskHelper.class.php b/WEB-INF/lib/ttTaskHelper.class.php index 2987d2781..015674067 100644 --- a/WEB-INF/lib/ttTaskHelper.class.php +++ b/WEB-INF/lib/ttTaskHelper.class.php @@ -137,10 +137,11 @@ static function delete($task_id) { // insert function inserts a new task into database. static function insert($fields) { + global $user; $mdb2 = getConnection(); - $group_id = (int) $fields['group_id']; - $org_id = (int) $fields['org_id']; + $group_id = $user->getGroup(); + $org_id = $user->org_id; $name = $fields['name']; $description = $fields['description']; $projects = $fields['projects']; @@ -270,17 +271,17 @@ static function update($fields) // sort function sorts task ids passed as comma-separated list by their name. static function sort($comma_separated) { - // We can't sort an empty string. - if (!$comma_separated) - return $comma_separated; - + // We can't sort an empty string. + if (!$comma_separated) + return $comma_separated; + $mdb2 = getConnection(); - - $sql = "select id, name from tt_tasks where id in ($comma_separated)"; + + $sql = "select id, name from tt_tasks where id in ($comma_separated)"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die ($res->getMessage()); - + $task_arr = array(); while ($val = $res->fetchRow()) { $task_arr[] = array('id'=>$val['id'],'name'=>$val['name']); @@ -290,7 +291,7 @@ static function sort($comma_separated) { for($i = 0; $i < count($task_arr); $i++) { $task_ids[] = $task_arr[$i]['id']; } - $result = implode(',', $task_ids); + $result = implode(',', $task_ids); return $result; } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3b96b55be..85ad89fe3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.28.4548 | Copyright © Anuko | +  Anuko Time Tracker 1.18.28.4549 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/task_add.php b/mobile/task_add.php index 003003479..9deed925d 100644 --- a/mobile/task_add.php +++ b/mobile/task_add.php @@ -68,8 +68,6 @@ if ($err->no()) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => ACTIVE, diff --git a/mobile/task_edit.php b/mobile/task_edit.php index 47dc5d710..ba36ea56e 100644 --- a/mobile/task_edit.php +++ b/mobile/task_edit.php @@ -103,8 +103,6 @@ if ($request->getParameter('btn_copy')) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => $cl_status, diff --git a/task_add.php b/task_add.php index 91f0e4fcd..1fdc7b18c 100644 --- a/task_add.php +++ b/task_add.php @@ -68,8 +68,6 @@ if ($err->no()) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => ACTIVE, diff --git a/task_edit.php b/task_edit.php index c9f95ecb7..efe8509d3 100644 --- a/task_edit.php +++ b/task_edit.php @@ -101,8 +101,6 @@ if ($request->getParameter('btn_copy')) { if (!ttTaskHelper::getTaskByName($cl_name)) { if (ttTaskHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => $cl_status, From a2f024d2184505a889e51d92337d9f40e392a1be Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 18:32:47 +0000 Subject: [PATCH 0474/1848] More refactoring on decoupling import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 41 +++++++++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index cbf7d28a2..349334114 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -27,7 +27,6 @@ // +----------------------------------------------------------------------+ import('ttUserHelper'); -import('ttInvoiceHelper'); // ttOrgImportHelper class is used to import organization data from an XML file // prepared by ttOrgExportHelper and consisting of nested groups with their info. @@ -160,7 +159,9 @@ function startElement($parser, $name, $attrs) { if ($role_id) { // Add a mapping. $this->currentGroupRoleMap[$attrs['ID']] = $role_id; - } else $this->errors->add($i18n->get('error.db')); + } else { + $this->errors->add($i18n->get('error.db')); + } return; } @@ -228,7 +229,9 @@ function startElement($parser, $name, $attrs) { if ($client_id) { // Add a mapping. $this->currentGroupClientMap[$attrs['ID']] = $client_id; - } else $this->errors->add($i18n->get('error.db')); + } else { + $this->errors->add($i18n->get('error.db')); + } return; } @@ -251,7 +254,9 @@ function startElement($parser, $name, $attrs) { if ($user_id) { // Add a mapping. $this->currentGroupUserMap[$attrs['ID']] = $user_id; - } else $this->errors->add($i18n->get('error.db')); + } else { + $this->errors->add($i18n->get('error.db')); + } return; } @@ -270,7 +275,7 @@ function startElement($parser, $name, $attrs) { if ($name == 'INVOICE') { // We get here when processing tags for the current group. - $invoice_id = ttInvoiceHelper::insert(array( + $invoice_id = $this->insertInvoice(array( 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, 'name' => $attrs['NAME'], @@ -280,7 +285,9 @@ function startElement($parser, $name, $attrs) { if ($invoice_id) { // Add a mapping. $this->currentGroupInvoiceMap[$attrs['ID']] = $invoice_id; - } else $this->errors->add($i18n->get('error.db')); + } else { + $this->errors->add($i18n->get('error.db')); + } return; } @@ -781,6 +788,28 @@ private function insertRole($fields) return $last_id; } + // insertInvoice - inserts an invoice in database. + private function insertInvoice($fields) + { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $name = $fields['name']; + $client_id = (int) $fields['client_id']; + $date = $fields['date']; + $status = $fields['status']; + + // Insert a new invoice record. + $sql = "insert into tt_invoices (group_id, org_id, name, date, client_id, status)". + " values($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id, ".$mdb2->quote($fields['status']).")"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + $last_id = $mdb2->lastInsertID('tt_invoices', 'id'); + return $last_id; + } + // The insertClient function inserts a new client as well as client to project binds. private function insertClient($fields) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 85ad89fe3..9b68b6a8b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.28.4549 | Copyright © Anuko | +  Anuko Time Tracker 1.18.28.4550 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 42dcc17360038e8fdfdb3bbdc7983bf5fe727954 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 19:45:19 +0000 Subject: [PATCH 0475/1848] Fully decoupled import code from the rest of the app. --- WEB-INF/lib/ttInvoiceHelper.class.php | 28 ---------- WEB-INF/lib/ttOrgImportHelper.class.php | 74 +++++++++++++++++++++++-- WEB-INF/lib/ttUserHelper.class.php | 8 +-- WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 71 insertions(+), 41 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 0867ee1eb..13e784d07 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -32,34 +32,6 @@ // Class ttInvoiceHelper is used for help with invoices. class ttInvoiceHelper { - // insert - inserts an invoice in database. - static function insert($fields) - { - $mdb2 = getConnection(); - - $group_id = (int) $fields['group_id']; - $org_id = (int) $fields['org_id']; - $name = $fields['name']; - if (!$name) return false; - - $client_id = (int) $fields['client_id']; - $date = $fields['date']; - if (array_key_exists('status', $fields)) { // Key exists and may be NULL during migration of data. - $status_f = ', status'; - $status_v = ', '.$mdb2->quote($fields['status']); - } - - // Insert a new invoice record. - $sql = "insert into tt_invoices (group_id, org_id, name, date, client_id $status_f)". - " values($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id $status_v)"; - $affected = $mdb2->exec($sql); - - if (is_a($affected, 'PEAR_Error')) return false; - - $last_id = $mdb2->lastInsertID('tt_invoices', 'id'); - return $last_id; - } - // getInvoice - obtains invoice data from the database. static function getInvoice($invoice_id) { global $user; diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 349334114..ff3376d32 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -26,8 +26,6 @@ // | https://www.anuko.com/time_tracker/credits.htm // +----------------------------------------------------------------------+ -import('ttUserHelper'); - // ttOrgImportHelper class is used to import organization data from an XML file // prepared by ttOrgExportHelper and consisting of nested groups with their info. class ttOrgImportHelper { @@ -83,7 +81,7 @@ function startElement($parser, $name, $attrs) { // In first pass we check user logins for potential collisions with existing. if ($name == 'USER' && $this->canImport) { $login = $attrs['LOGIN']; - if ('' != $attrs['STATUS'] && ttUserHelper::getUserByLogin($login)) { + if ('' != $attrs['STATUS'] && $this->loginExists($login)) { // We have a login collision. Append colliding login to a list of things we cannot import. $this->conflicting_logins .= ($this->conflicting_logins ? ", $login" : $login); // The above is printed in error message with all found colliding logins. @@ -240,7 +238,7 @@ function startElement($parser, $name, $attrs) { $role_id = $attrs['ROLE_ID'] === '0' ? $this->top_role_id : $this->currentGroupRoleMap[$attrs['ROLE_ID']]; // 0 (not null) means top manager role. - $user_id = ttUserHelper::insert(array( + $user_id = $this->insertUser(array( 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, 'role_id' => $role_id, @@ -261,7 +259,7 @@ function startElement($parser, $name, $attrs) { } if ($name == 'USER_PROJECT_BIND') { - if (!ttUserHelper::insertBind(array( + if (!$this->insertUserProjectBind(array( 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], 'group_id' => $this->current_group_id, @@ -654,6 +652,7 @@ private function createGroup($fields) { // insertMonthlyQuota - a helper function to insert a monthly quota. private function insertMonthlyQuota($fields) { $mdb2 = getConnection(); + $group_id = (int) $fields['group_id']; $org_id = (int) $fields['org_id']; $year = (int) $fields['year']; @@ -669,6 +668,7 @@ private function insertMonthlyQuota($fields) { // insertPredefinedExpense - a helper function to insert a predefined expense. private function insertPredefinedExpense($fields) { $mdb2 = getConnection(); + $group_id = (int) $fields['group_id']; $org_id = (int) $fields['org_id']; $name = $mdb2->quote($fields['name']); @@ -729,6 +729,55 @@ private function insertTask($fields) return $last_id; } + // insertUserProjectBind - inserts a user to project bind into tt_user_project_binds table. + private function insertUserProjectBind($fields) { + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $user_id = (int) $fields['user_id']; + $project_id = (int) $fields['project_id']; + $rate = $mdb2->quote($fields['rate']); + $status = $mdb2->quote($fields['status']); + + $sql = "insert into tt_user_project_binds (user_id, project_id, group_id, org_id, rate, status)". + " values($user_id, $project_id, $group_id, $org_id, $rate, $status)"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // insertUser - inserts a user into database. + private function insertUser($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + + $columns = '(login, password, name, group_id, org_id, role_id, client_id, rate, email, created, created_ip, created_by, status)'; + + $values = 'values ('; + $values .= $mdb2->quote($fields['login']); + $values .= ', '.$mdb2->quote($fields['password']); + $values .= ', '.$mdb2->quote($fields['name']); + $values .= ', '.$group_id; + $values .= ', '.$org_id; + $values .= ', '.(int)$fields['role_id']; + $values .= ', '.$mdb2->quote($fields['client_id']); + $values .= ', '.$mdb2->quote($fields['rate']); + $values .= ', '.$mdb2->quote($fields['email']); + $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$user->id; + $values .= ', '.$mdb2->quote($fields['status']); + $values .= ')'; + + $sql = "insert into tt_users $columns $values"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + $last_id = $mdb2->lastInsertID('tt_users', 'id'); + return $last_id; + } + // insertProject - a helper function to insert a project as well as project to task binds. private function insertProject($fields) { @@ -736,7 +785,6 @@ private function insertProject($fields) $group_id = (int) $fields['group_id']; $org_id = (int) $fields['org_id']; - $name = $fields['name']; $description = $fields['description']; $tasks = $fields['tasks']; @@ -1042,4 +1090,18 @@ private function getTopRole() { } return false; } + + // The loginExists function detrmines if a login already exists. + private function loginExists($login) { + $mdb2 = getConnection(); + + $sql = "select id from tt_users where login = ".$mdb2->quote($login)." and (status = 1 or status = 0)"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + if ($val = $res->fetchRow()) { + return true; + } + } + return false; + } } diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 42d7c9109..1d1b178a6 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -228,8 +228,6 @@ static function update($user_id, $fields) { ttUserHelper::insertBind(array( 'user_id' => $user_id, 'project_id' => $project_id, - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, 'rate' => $rate, 'status' => ACTIVE)); } @@ -315,10 +313,8 @@ static function insertBind($fields) { global $user; $mdb2 = getConnection(); - // This may be used during import. Use the following until we have import refactored. - $group_id = $fields['group_id'] ? (int) $fields['group_id'] : $user->getGroup(); - $org_id = $fields['org_id'] ? (int) $fields['org_id'] : $user->org_id; - + $group_id = $user->getGroup(); + $org_id = $user->org_id; $user_id = (int) $fields['user_id']; $project_id = (int) $fields['project_id']; $rate = $mdb2->quote($fields['rate']); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9b68b6a8b..b54e88149 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.28.4550 | Copyright © Anuko | +  Anuko Time Tracker 1.18.28.4551 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 35af76f7c66ba10e2e1279f2e9afbdb2b09a141d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 21:27:42 +0000 Subject: [PATCH 0476/1848] Some improvements to confirm save feature. --- WEB-INF/lib/ttUser.class.php | 6 ++ WEB-INF/templates/expense_edit.tpl | 6 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/expense_edit.tpl | 12 ++++ WEB-INF/templates/mobile/time_edit.tpl | 16 ++++- WEB-INF/templates/time_edit.tpl | 6 +- expense_edit.php | 15 +++-- mobile/expense_edit.php | 11 +++- mobile/time_edit.php | 73 ++++++++++++++++++++++- time_edit.php | 15 +++-- 10 files changed, 139 insertions(+), 23 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 8b98caa37..692d80ef0 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -202,6 +202,12 @@ function getConfig() { return ($this->behalfGroup ? $this->behalfGroup->config : $this->config); } + // getConfirmSave returns confirm_save option for user. + function getConfirmSave() { + return true; // TODO: implement this properly. + // return ($this->behalfGroup ? $this->behalfGroup->config : $this->config); + } + // can - determines whether user has a right to do something. function can($do_something) { return in_array($do_something, $this->rights); diff --git a/WEB-INF/templates/expense_edit.tpl b/WEB-INF/templates/expense_edit.tpl index 9e447a30b..d3a27375c 100644 --- a/WEB-INF/templates/expense_edit.tpl +++ b/WEB-INF/templates/expense_edit.tpl @@ -34,8 +34,8 @@ var defined_expenses = new Array(); idx++; {/foreach} -// TODO: improve on conditional confirmSave. -// Existing entry date for confirm save warnings. +{* Conditional include of confirmSave handler. *} +{if $confirm_save} var original_date = "{$entry_date}"; function confirmSave() { @@ -44,7 +44,7 @@ function confirmSave() { return confirm("{$i18n.warn.confirm_save}"); } } -// TODO: improve on conditional confirmSave above. +{/if} // The fillProjectDropdown function populates the project combo box with // projects associated with a selected client (client id is passed here as id). diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b54e88149..9d88e933e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/WEB-INF/templates/time_edit.tpl b/WEB-INF/templates/time_edit.tpl index f6f469398..bc563e9ea 100644 --- a/WEB-INF/templates/time_edit.tpl +++ b/WEB-INF/templates/time_edit.tpl @@ -1,8 +1,8 @@ {include file="time_script.tpl"} +{* Conditional include of confirmSave handler. *} +{if $confirm_save} +{/if} {$forms.timeRecordForm.open}
 Anuko Time Tracker 1.18.28.4551 | Copyright © Anuko | +  Anuko Time Tracker 1.18.28.4552 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/expense_edit.tpl b/WEB-INF/templates/mobile/expense_edit.tpl index ea2972381..971405079 100644 --- a/WEB-INF/templates/mobile/expense_edit.tpl +++ b/WEB-INF/templates/mobile/expense_edit.tpl @@ -34,6 +34,18 @@ var defined_expenses = new Array(); idx++; {/foreach} +{* Conditional include of confirmSave handler. *} +{if $confirm_save} +var original_date = "{$entry_date}"; + +function confirmSave() { + var date_on_save = document.getElementById("date").value; + if (original_date != date_on_save) { + return confirm("{$i18n.warn.confirm_save}"); + } +} +{/if} + // The fillProjectDropdown function populates the project combo box with // projects associated with a selected client (client id is passed here as id). function fillProjectDropdown(id) { diff --git a/WEB-INF/templates/mobile/time_edit.tpl b/WEB-INF/templates/mobile/time_edit.tpl index 8c6a14142..79c5c03c4 100644 --- a/WEB-INF/templates/mobile/time_edit.tpl +++ b/WEB-INF/templates/mobile/time_edit.tpl @@ -1,5 +1,19 @@ {include file="time_script.tpl"} +{* Conditional include of confirmSave handler. *} +{if $confirm_save} + +{/if} + {$forms.timeRecordForm.open} @@ -41,7 +55,7 @@ - +
{$forms.timeRecordForm.date.control}
{$i18n.label.note}:
{$forms.timeRecordForm.note.control}
{$forms.timeRecordForm.btn_save.control} {$forms.timeRecordForm.btn_delete.control}
{$forms.timeRecordForm.btn_save.control} {$forms.timeRecordForm.btn_copy.control} {$forms.timeRecordForm.btn_delete.control}
diff --git a/expense_edit.php b/expense_edit.php index cca8225a4..a4bb6a4f4 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -51,6 +51,7 @@ } $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); +$confirm_save = $user->getConfirmSave(); // Initialize variables. $cl_date = $cl_client = $cl_project = $cl_item_name = $cl_cost = null; @@ -147,9 +148,10 @@ // Hidden control for record id. $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -// TODO: improve on conditional confirmSave. -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date();return(confirmSave())','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.copy'))); +$on_click_action = 'browser_today.value=get_date();'; +$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>$on_click_action,'value'=>$i18n->get('button.copy'))); +if ($confirm_save) $on_click_action .= 'return(confirmSave());'; +$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>$on_click_action,'value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { @@ -221,9 +223,10 @@ } } // isPost -// TODO: improve on conditional confirmSave. -$smarty->assign('entry_date', $cl_date); - +if ($confirm_save) { + $smarty->assign('confirm_save', true); + $smarty->assign('entry_date', $cl_date); +} $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index a039f42f8..9cae01814 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -51,6 +51,7 @@ } $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); +$confirm_save = $user->getConfirmSave(); // Initialize variables. $cl_date = $cl_client = $cl_project = $cl_item_name = $cl_cost = null; @@ -142,8 +143,10 @@ // Hidden control for record id. $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.copy'))); +$on_click_action = 'browser_today.value=get_date();'; +$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>$on_click_action,'value'=>$i18n->get('button.copy'))); +if ($confirm_save) $on_click_action .= 'return(confirmSave());'; +$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>$on_click_action,'value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { @@ -215,6 +218,10 @@ } } // isPost +if ($confirm_save) { + $smarty->assign('confirm_save', true); + $smarty->assign('entry_date', $cl_date); +} $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); diff --git a/mobile/time_edit.php b/mobile/time_edit.php index b2655e8f6..3094df64b 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -57,6 +57,7 @@ } $item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); +$confirm_save = $user->getConfirmSave(); // Initialize variables. $cl_start = $cl_finish = $cl_duration = $cl_date = $cl_note = $cl_project = $cl_task = $cl_billable = null; @@ -205,7 +206,10 @@ if ($user->isPluginEnabled('iv')) $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save click. -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.save'))); +$on_click_action = 'browser_today.value=get_date();'; +$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>$on_click_action,'value'=>$i18n->get('button.copy'))); +if ($confirm_save) $on_click_action .= 'return(confirmSave());'; +$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>$on_click_action,'value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { @@ -324,12 +328,79 @@ } } + // Save as new record. + if ($request->getParameter('btn_copy')) { + // We need to: + // 1) Prohibit saving into locked range. + // 2) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. + + // Now, step by step. + if ($err->no()) { + // 1) Prohibit saving into locked range. + if ($user->isDateLocked($new_date)) + $err->add($i18n->get('error.range_locked')); + + // 2) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. + $uncompleted = ($cl_finish == '' && $cl_duration == ''); + if ($uncompleted) { + $not_completed_rec = ttTimeHelper::getUncompleted($user_id); + if ($not_completed_rec) { + // We have another not completed record. + $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); + } + } + } + + // Prohibit creating an overlapping record. + if ($err->no()) { + if (ttTimeHelper::overlaps($user_id, $new_date->toString(DB_DATEFORMAT), $cl_start, $cl_finish)) + $err->add($i18n->get('error.overlap')); + } + + // Now, a new insert. + if ($err->no()) { + + $id = ttTimeHelper::insert(array( + 'date'=>$new_date->toString(DB_DATEFORMAT), + 'user_id'=>$user_id, + 'group_id'=>$user->getGroup(), + 'org_id' => $user->org_id, + 'client'=>$cl_client, + 'project'=>$cl_project, + 'task'=>$cl_task, + 'start'=>$cl_start, + 'finish'=>$cl_finish, + 'duration'=>$cl_duration, + 'note'=>$cl_note, + 'billable'=>$cl_billable, + 'paid'=>$cl_paid)); + + // Insert a custom field if we have it. + $res = true; + if ($id && $custom_fields && $cl_cf_1) { + if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) + $res = $custom_fields->insert($id, $custom_fields->fields[0]['id'], null, $cl_cf_1); + elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) + $res = $custom_fields->insert($id, $custom_fields->fields[0]['id'], $cl_cf_1, null); + } + if ($id && $res) { + header('Location: time.php?date='.$new_date->toString(DB_DATEFORMAT)); + exit(); + } + $err->add($i18n->get('error.db')); + } + } + if ($request->getParameter('btn_delete')) { header("Location: time_delete.php?id=$cl_id"); exit(); } } // isPost +if ($confirm_save) { + $smarty->assign('confirm_save', true); + $smarty->assign('entry_date', $cl_date); +} $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); diff --git a/time_edit.php b/time_edit.php index 17ba34b41..5dd958b5b 100644 --- a/time_edit.php +++ b/time_edit.php @@ -57,6 +57,7 @@ } $item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); +$confirm_save = $user->getConfirmSave(); // Initialize variables. $cl_start = $cl_finish = $cl_duration = $cl_date = $cl_note = $cl_project = $cl_task = $cl_billable = null; @@ -210,9 +211,10 @@ if ($user->can('manage_invoices') && $user->isPluginEnabled('ps')) $form->addInput(array('type'=>'checkbox','name'=>'paid','value'=>$cl_paid)); $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -// TODO: improve on conditional confirmSave. -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>'browser_today.value=get_date();return(confirmSave())','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.copy'))); +$on_click_action = 'browser_today.value=get_date();'; +$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>$on_click_action,'value'=>$i18n->get('button.copy'))); +if ($confirm_save) $on_click_action .= 'return(confirmSave());'; +$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>$on_click_action,'value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { @@ -401,9 +403,10 @@ } } // isPost -// TODO: improve on conditional confirmSave. -$smarty->assign('entry_date', $cl_date); - +if ($confirm_save) { + $smarty->assign('confirm_save', true); + $smarty->assign('entry_date', $cl_date); +} $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); From a8d2a373388113fc60233feda3b971c4d67e6211 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Nov 2018 23:28:06 +0000 Subject: [PATCH 0477/1848] Implemented configurable confirm save option. --- WEB-INF/lib/ttGroup.class.php | 4 +++- WEB-INF/lib/ttUser.class.php | 6 +++--- WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/cs.lang.php | 2 +- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/en.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 +- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 +- WEB-INF/resources/sv.lang.php | 2 +- WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- WEB-INF/resources/zh-tw.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 4 ++++ group_edit.php | 6 ++++++ 35 files changed, 47 insertions(+), 35 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index e232a0e1a..865363494 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -50,6 +50,7 @@ class ttGroup { var $allow_overlap = 0; // Whether to allow overlapping time entries. var $future_entries = 0; // Whether to allow creating future entries. var $uncompleted_indicators = 0; // Uncompleted time entry indicators (show nowhere or on users page). + var $confirm_save = 0; // Whether to show warnings for save action when date changed. var $bcc_email = null; // Bcc email. var $allow_ip = null; // Specification from where user is allowed access. var $password_complexity = null; // Password complexity example. @@ -104,7 +105,6 @@ function __construct($id, $org_id) { $this->custom_logo = $val['custom_logo']; */ $this->config = $val['config']; - /* $config = new ttConfigHelper($this->config); // Set user config options. $this->show_holidays = $config->getDefinedValue('show_holidays'); @@ -112,6 +112,8 @@ function __construct($id, $org_id) { $this->allow_overlap = $config->getDefinedValue('allow_overlap'); $this->future_entries = $config->getDefinedValue('future_entries'); $this->uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators'); + $this->confirm_save = $config->getDefinedValue('confirm_save'); + /* if ($this->isPluginEnabled('wu')) { $minutes_in_unit = $config->getIntValue('minutes_in_unit'); if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 692d80ef0..7a102a27c 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -60,7 +60,7 @@ class ttUser { var $allow_overlap = 0; // Whether to allow overlapping time entries. var $future_entries = 0; // Whether to allow creating future entries. var $uncompleted_indicators = 0; // Uncompleted time entry indicators (show nowhere or on users page). - var $confirm_save = 1; // Work in progress. TODO: change default to 0 and get from group config upon init. + var $confirm_save = 0; // Whether to show warnings for save action when date changed. var $bcc_email = null; // Bcc email. var $allow_ip = null; // Specification from where user is allowed access. var $password_complexity = null; // Password complexity example. @@ -144,6 +144,7 @@ function __construct($login, $id = null) { $this->allow_overlap = $config->getDefinedValue('allow_overlap'); $this->future_entries = $config->getDefinedValue('future_entries'); $this->uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators'); + $this->confirm_save = $config->getDefinedValue('confirm_save'); if ($this->isPluginEnabled('wu')) { $minutes_in_unit = $config->getIntValue('minutes_in_unit'); if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit; @@ -204,8 +205,7 @@ function getConfig() { // getConfirmSave returns confirm_save option for user. function getConfirmSave() { - return true; // TODO: implement this properly. - // return ($this->behalfGroup ? $this->behalfGroup->config : $this->config); + return ($this->behalfGroup ? $this->behalfGroup->confirm_save : $this->confirm_save); } // can - determines whether user has a right to do something. diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 2b0b17bdb..68c6e6a96 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -532,7 +532,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 7150a6fb1..bcda74010 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -546,7 +546,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index bad0297c2..45cf377ee 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -496,7 +496,7 @@ // 'form.group_edit.future_entries' => 'Future entries', 'form.group_edit.uncompleted_indicators' => 'Uafsluttede indikatore', // TODO: translate the following. -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index cc2800655..80c78537b 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -468,7 +468,7 @@ 'form.group_edit.future_entries' => 'Einträge in der Zukunft', 'form.group_edit.uncompleted_indicators' => 'Zeige unfertige Einträge', // TODO: translate the following. -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', 'form.group_edit.allow_ip' => 'Erlaube IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 1d27ce90a..fee9fdbf0 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -465,7 +465,7 @@ 'form.group_edit.allow_overlap' => 'Allow overlap', 'form.group_edit.future_entries' => 'Future entries', 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -'form.group_edit.copy_warning' => 'Warn on copy', +'form.group_edit.confirm_save' => 'Confirm saving', 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index c82df5b55..aa6425547 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -546,7 +546,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index e6d2dbe86..a61a13056 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -543,7 +543,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 412345f1a..86f3930de 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -518,7 +518,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 1dcc17081..4687e6f53 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -503,7 +503,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 6900fa7bc..ad77095c2 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -492,7 +492,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index ce382635a..f4859df7f 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -477,7 +477,7 @@ 'form.group_edit.future_entries' => 'Μελλοντικές καταχωρήσεις', 'form.group_edit.uncompleted_indicators' => 'Μη ολοκληρωμένες ενδείξεις', // TODO: translate the following. -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index d955c857d..d7abe002d 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -527,7 +527,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 884db355c..0e0e4522f 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -537,7 +537,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 8c9a07dab..ce1ab88cc 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -492,7 +492,7 @@ // 'form.group_edit.future_entries' => 'Future entries', 'form.group_edit.uncompleted_indicators' => 'Indicatori incompleti', // TODO: translate the following. -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 5211d0684..431915fd8 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -540,7 +540,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 2344ac14c..7ac2dd4ef 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -538,7 +538,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 2e357f9c6..3cad307be 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -469,7 +469,7 @@ 'form.group_edit.future_entries' => 'Toevoegingen toestaan in de toekomst', 'form.group_edit.uncompleted_indicators' => 'Onvolledige indicatoren', // TODO: translate the following. -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', 'form.group_edit.allow_ip' => 'Toegestane IP adressen', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 8b7762e2a..d7847c153 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -536,7 +536,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 7a7852a73..a36b06c14 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -505,7 +505,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index df2ccc0e3..7bfb95529 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -500,7 +500,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d963d1ea3..bdb1c3753 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -520,7 +520,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index e8f84cbc8..e1c24e2de 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -541,7 +541,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index dede24edd..5710cbb36 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -462,7 +462,7 @@ 'form.group_edit.allow_overlap' => 'Возможное перекрывание', 'form.group_edit.future_entries' => 'Будущие записи', 'form.group_edit.uncompleted_indicators' => 'Индикаторы незавершения', -'form.group_edit.copy_warning' => 'Предупреждать при копировании', +'form.group_edit.confirm_save' => 'Предупреждать при сохранении', 'form.group_edit.allow_ip' => 'Разрешить доступ с IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d3e4f4d40..0097e09b7 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -518,7 +518,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index c9a4a1b71..dfc9fd32a 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -516,7 +516,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 6e5dbbbd3..1c59de37e 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -503,7 +503,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index e23ea1a7a..a20aed921 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -500,7 +500,7 @@ // 'form.group_edit.future_entries' => 'Future entries', 'form.group_edit.uncompleted_indicators' => 'Indikatorer för oavslutad registrering', // TODO: translate the following. -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index b2f705a42..771ccb904 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -554,7 +554,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5470ffec6..190cf5a48 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -523,7 +523,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index a8f7224a3..7b1bcdba0 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -532,7 +532,7 @@ // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.copy_warning' => 'Warn on copy', +// 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9d88e933e..d942b96c6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + {if $user->can('manage_advanced_settings')} diff --git a/group_edit.php b/group_edit.php index 6a16dc1f0..44c5d7f9b 100644 --- a/group_edit.php +++ b/group_edit.php @@ -77,6 +77,7 @@ $cl_allow_overlap = $request->getParameter('allow_overlap'); $cl_future_entries = $request->getParameter('future_entries'); $cl_uncompleted_indicators = $request->getParameter('uncompleted_indicators'); + $cl_confirm_save = $request->getParameter('confirm_save'); $cl_bcc_email = trim($request->getParameter('bcc_email')); $cl_allow_ip = trim($request->getParameter('allow_ip')); } else { @@ -97,6 +98,7 @@ $cl_allow_overlap = $config->getDefinedValue('allow_overlap'); $cl_future_entries = $config->getDefinedValue('future_entries'); $cl_uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators'); + $cl_confirm_save = $config->getDefinedValue('confirm_save'); $cl_bcc_email = $group['bcc_email']; $cl_allow_ip = $group['allow_ip']; } @@ -191,6 +193,9 @@ // Uncompleted indicators checkbox. $form->addInput(array('type'=>'checkbox','name'=>'uncompleted_indicators','value'=>$cl_uncompleted_indicators)); +// Confirm save checkbox. +$form->addInput(array('type'=>'checkbox','name'=>'confirm_save','value'=>$cl_confirm_save)); + // Add bcc email control. if ($advanced_settings) { $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'bcc_email','value'=>$cl_bcc_email)); @@ -234,6 +239,7 @@ $config->setDefinedValue('allow_overlap', $cl_allow_overlap); $config->setDefinedValue('future_entries', $cl_future_entries); $config->setDefinedValue('uncompleted_indicators', $cl_uncompleted_indicators); + $config->setDefinedValue('confirm_save', $cl_confirm_save); if ($user->updateGroup(array( 'group_id' => $group_id, From 7a59cd1320f833a7cc2a29f5fd2806f84a4f0e94 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 14:23:31 +0000 Subject: [PATCH 0478/1848] Some improvements in ttConfigHelper class. --- WEB-INF/lib/ttConfigHelper.class.php | 63 +++++++++++++++------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/WEB-INF/lib/ttConfigHelper.class.php b/WEB-INF/lib/ttConfigHelper.class.php index 20af19ad0..6790e2140 100644 --- a/WEB-INF/lib/ttConfigHelper.class.php +++ b/WEB-INF/lib/ttConfigHelper.class.php @@ -38,13 +38,15 @@ class ttConfigHelper { // Constructor. function __construct($config) { - $this->config = $config; - $this->config_array = explode(',', $this->config); + $this->config = trim($config, ' ,'); + if ($this->config) + $this->config_array = explode(',', $this->config); } // getDefinedValue determines if a value identified by name is defined. function getDefinedValue($name) { - return in_array($name, $this->config_array); + $defined = $this->config_array ? in_array($name, $this->config_array) : false; + return $defined; } // setDefinedValue either sets or deletes a defined value identified by name. @@ -58,29 +60,32 @@ function setDefinedValue($name, $set = true) { } } else { // Deleting part. - foreach ($this->config_array as $key => $value) { - if ($value === $name) { - unset($this->config_array[$key]); - $this->config = implode(',', $this->config_array); - return; + if ($this->config_array) { + foreach ($this->config_array as $key => $value) { + if ($value === $name) { + unset($this->config_array[$key]); + $this->config = implode(',', $this->config_array); + return; + } } } } } - // The getIntValue parses an integer value from the source config string. + // The getIntValue parses an integer value from the source config array. function getIntValue($name) { $name_with_colon = $name.':'; $len = strlen($name_with_colon); - foreach ($this->config_array as $unparsed_value) { - if (substr($unparsed_value, 0, $len) === $name_with_colon) { - // Found value. - $unparsed_len = strlen($unparsed_value); - $int_value = (int) substr($unparsed_value, -($unparsed_len - $len)); - return $int_value; + if ($this->config_array) { + foreach ($this->config_array as $unparsed_value) { + if (substr($unparsed_value, 0, $len) === $name_with_colon) { + // Found value. + $unparsed_len = strlen($unparsed_value); + $int_value = (int) substr($unparsed_value, -($unparsed_len - $len)); + return $int_value; + } } - } return false; } @@ -91,18 +96,20 @@ function setIntValue($name, $value) { $name_with_colon = $name.':'; $len = strlen($name_with_colon); - foreach ($this->config_array as $key => $unparsed_value) { - if (substr($unparsed_value, 0, $len) === $name_with_colon) { - // Found an already existing value. - if ($value !== null) { - // Replace value. - $this->config_array[$key] = $name.':'.$value; - } else { - // Remove value if our new value is NULL. - unset($this->config_array[$key]); + if ($this->config_array) { + foreach ($this->config_array as $key => $unparsed_value) { + if (substr($unparsed_value, 0, $len) === $name_with_colon) { + // Found an already existing value. + if ($value !== null) { + // Replace value. + $this->config_array[$key] = $name.':'.$value; + } else { + // Remove value if our new value is NULL. + unset($this->config_array[$key]); + } + $this->config = implode(',', $this->config_array); + return; } - $this->config = implode(',', $this->config_array); - return; } } // If we get here, the value was not found, so add it. @@ -113,6 +120,6 @@ function setIntValue($name, $value) { // The getConfig returns the config string. function getConfig() { - return $this->config; + return trim($this->config, ' ,'); } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d942b96c6..90b3e9000 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.28.4552 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4553 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index 8f683de44..f839d7e93 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -100,6 +100,10 @@ function handleTaskRequiredCheckbox() { {$i18n.form.group_edit.uncompleted_indicators}: {$forms.groupForm.uncompleted_indicators.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.confirm_save}:{$forms.groupForm.confirm_save.control} {$i18n.label.what_is_it}
{$i18n.label.bcc}:
-
 Anuko Time Tracker 1.18.29.4553 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4554 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 91f127aa192430faa62c59530f42ee5d82b9f7e3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 15:46:45 +0000 Subject: [PATCH 0479/1848] Some optimization related to confirm save feature. --- WEB-INF/lib/ttGroup.class.php | 2 -- WEB-INF/lib/ttUser.class.php | 12 +++++++----- WEB-INF/templates/footer.tpl | 2 +- expense_edit.php | 2 +- mobile/expense_edit.php | 2 +- mobile/time_edit.php | 2 +- time_edit.php | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index 865363494..44e225b23 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -50,7 +50,6 @@ class ttGroup { var $allow_overlap = 0; // Whether to allow overlapping time entries. var $future_entries = 0; // Whether to allow creating future entries. var $uncompleted_indicators = 0; // Uncompleted time entry indicators (show nowhere or on users page). - var $confirm_save = 0; // Whether to show warnings for save action when date changed. var $bcc_email = null; // Bcc email. var $allow_ip = null; // Specification from where user is allowed access. var $password_complexity = null; // Password complexity example. @@ -112,7 +111,6 @@ function __construct($id, $org_id) { $this->allow_overlap = $config->getDefinedValue('allow_overlap'); $this->future_entries = $config->getDefinedValue('future_entries'); $this->uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators'); - $this->confirm_save = $config->getDefinedValue('confirm_save'); /* if ($this->isPluginEnabled('wu')) { $minutes_in_unit = $config->getIntValue('minutes_in_unit'); diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 7a102a27c..60f4f984b 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -60,7 +60,6 @@ class ttUser { var $allow_overlap = 0; // Whether to allow overlapping time entries. var $future_entries = 0; // Whether to allow creating future entries. var $uncompleted_indicators = 0; // Uncompleted time entry indicators (show nowhere or on users page). - var $confirm_save = 0; // Whether to show warnings for save action when date changed. var $bcc_email = null; // Bcc email. var $allow_ip = null; // Specification from where user is allowed access. var $password_complexity = null; // Password complexity example. @@ -144,7 +143,6 @@ function __construct($login, $id = null) { $this->allow_overlap = $config->getDefinedValue('allow_overlap'); $this->future_entries = $config->getDefinedValue('future_entries'); $this->uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators'); - $this->confirm_save = $config->getDefinedValue('confirm_save'); if ($this->isPluginEnabled('wu')) { $minutes_in_unit = $config->getIntValue('minutes_in_unit'); if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit; @@ -203,9 +201,13 @@ function getConfig() { return ($this->behalfGroup ? $this->behalfGroup->config : $this->config); } - // getConfirmSave returns confirm_save option for user. - function getConfirmSave() { - return ($this->behalfGroup ? $this->behalfGroup->confirm_save : $this->confirm_save); + // getConfigOption returns true if an option is defined for group. + // This helps us keeping a set of user attributes smaller. + // We determine whether the option is set only on pages that need to know. + // For example: confirm_save is used only on time and expense edit pages. + function getConfigOption($name) { + $config = new ttConfigHelper($this->getConfig()); + return $config->getDefinedValue($name); } // can - determines whether user has a right to do something. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 90b3e9000..b17fa6750 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4554 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4555 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expense_edit.php b/expense_edit.php index a4bb6a4f4..9768fa23e 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -51,7 +51,7 @@ } $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); -$confirm_save = $user->getConfirmSave(); +$confirm_save = $user->getConfigOption('confirm_save'); // Initialize variables. $cl_date = $cl_client = $cl_project = $cl_item_name = $cl_cost = null; diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index 9cae01814..d139530c9 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -51,7 +51,7 @@ } $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); -$confirm_save = $user->getConfirmSave(); +$confirm_save = $user->getConfigOption('confirm_save'); // Initialize variables. $cl_date = $cl_client = $cl_project = $cl_item_name = $cl_cost = null; diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 3094df64b..925220430 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -57,7 +57,7 @@ } $item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); -$confirm_save = $user->getConfirmSave(); +$confirm_save = $user->getConfigOption('confirm_save'); // Initialize variables. $cl_start = $cl_finish = $cl_duration = $cl_date = $cl_note = $cl_project = $cl_task = $cl_billable = null; diff --git a/time_edit.php b/time_edit.php index 5dd958b5b..08a5f392e 100644 --- a/time_edit.php +++ b/time_edit.php @@ -57,7 +57,7 @@ } $item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); -$confirm_save = $user->getConfirmSave(); +$confirm_save = $user->getConfigOption('confirm_save'); // Initialize variables. $cl_start = $cl_finish = $cl_duration = $cl_date = $cl_note = $cl_project = $cl_task = $cl_billable = null; From 035970e91c0a4c132874656b8f13a88c46684717 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 16:25:54 +0000 Subject: [PATCH 0480/1848] Optimized a bit more for uncompleted indicators option. --- WEB-INF/lib/ttGroup.class.php | 2 -- WEB-INF/lib/ttUser.class.php | 2 -- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/users.tpl | 2 +- WEB-INF/templates/users.tpl | 2 +- mobile/users.php | 6 ++++-- users.php | 5 +++-- 7 files changed, 10 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index 44e225b23..b7e78f959 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -49,7 +49,6 @@ class ttGroup { var $punch_mode = 0; // Whether punch mode is enabled for user. var $allow_overlap = 0; // Whether to allow overlapping time entries. var $future_entries = 0; // Whether to allow creating future entries. - var $uncompleted_indicators = 0; // Uncompleted time entry indicators (show nowhere or on users page). var $bcc_email = null; // Bcc email. var $allow_ip = null; // Specification from where user is allowed access. var $password_complexity = null; // Password complexity example. @@ -110,7 +109,6 @@ function __construct($id, $org_id) { $this->punch_mode = $config->getDefinedValue('punch_mode'); $this->allow_overlap = $config->getDefinedValue('allow_overlap'); $this->future_entries = $config->getDefinedValue('future_entries'); - $this->uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators'); /* if ($this->isPluginEnabled('wu')) { $minutes_in_unit = $config->getIntValue('minutes_in_unit'); diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 60f4f984b..0db272ff6 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -59,7 +59,6 @@ class ttUser { var $punch_mode = 0; // Whether punch mode is enabled for user. var $allow_overlap = 0; // Whether to allow overlapping time entries. var $future_entries = 0; // Whether to allow creating future entries. - var $uncompleted_indicators = 0; // Uncompleted time entry indicators (show nowhere or on users page). var $bcc_email = null; // Bcc email. var $allow_ip = null; // Specification from where user is allowed access. var $password_complexity = null; // Password complexity example. @@ -142,7 +141,6 @@ function __construct($login, $id = null) { $this->punch_mode = $config->getDefinedValue('punch_mode'); $this->allow_overlap = $config->getDefinedValue('allow_overlap'); $this->future_entries = $config->getDefinedValue('future_entries'); - $this->uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators'); if ($this->isPluginEnabled('wu')) { $minutes_in_unit = $config->getIntValue('minutes_in_unit'); if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b17fa6750..071a29a46 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4555 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4556 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/users.tpl b/WEB-INF/templates/mobile/users.tpl index e2b815f1b..ae04bd448 100644 --- a/WEB-INF/templates/mobile/users.tpl +++ b/WEB-INF/templates/mobile/users.tpl @@ -19,7 +19,7 @@ {foreach $active_users as $u}
- {if $user->uncompleted_indicators} + {if $uncompleted_indicators} {/if} {if $u.rank < $user->rank || ($u.rank == $user->rank && $u.id == $user->id)} diff --git a/WEB-INF/templates/users.tpl b/WEB-INF/templates/users.tpl index fb46c96d6..4faf1249d 100644 --- a/WEB-INF/templates/users.tpl +++ b/WEB-INF/templates/users.tpl @@ -31,7 +31,7 @@ {foreach $active_users as $u}
- {if $user->uncompleted_indicators} + {if $uncompleted_indicators} {/if} {$u.name|escape} diff --git a/mobile/users.php b/mobile/users.php index d0b5d2189..874b07634 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -38,6 +38,8 @@ } // End of access checks. +$uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); + // Get users. $active_users = ttTeamHelper::getActiveUsers(array('getAllFields'=>true)); if($user->can('manage_users')) { @@ -45,12 +47,12 @@ $inactive_users = ttTeamHelper::getInactiveUsers($user->group_id, true); } -// Check if the group is set to show indicators for uncompleted time entries. -if ($user->uncompleted_indicators) { +if ($uncompleted_indicators) { // Check each active user if they have an uncompleted time entry. foreach ($active_users as $key => $user) { $active_users[$key]['has_uncompleted_entry'] = (bool) ttTimeHelper::getUncompleted($user['id']); } + $smarty->assign('uncompleted_indicators', true); } $smarty->assign('active_users', $active_users); diff --git a/users.php b/users.php index fe0e92da9..47ec0145a 100644 --- a/users.php +++ b/users.php @@ -50,6 +50,7 @@ } else { $group_id = $user->getGroup(); } +$uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); $form = new Form('usersForm'); if ($user->can('manage_subgroups')) { @@ -79,12 +80,12 @@ $inactive_users = $user->getUsers($options); } -// Check if the group is set to show indicators for uncompleted time entries. -if ($user->uncompleted_indicators) { +if ($uncompleted_indicators) { // Check each active user if they have an uncompleted time entry. foreach ($active_users as $key => $user) { $active_users[$key]['has_uncompleted_entry'] = (bool) ttTimeHelper::getUncompleted($user['id']); } + $smarty->assign('uncompleted_indicators', true); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); From 5be0f37534b82691a7707cde3aeb3d0b41fd71e5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 17:32:37 +0000 Subject: [PATCH 0481/1848] Resuming refactoring for subgroup support. --- WEB-INF/templates/clients.tpl | 9 +++++++++ WEB-INF/templates/footer.tpl | 2 +- clients.php | 36 +++++++++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/clients.tpl b/WEB-INF/templates/clients.tpl index a31a8cd05..2e8b2b82f 100644 --- a/WEB-INF/templates/clients.tpl +++ b/WEB-INF/templates/clients.tpl @@ -6,6 +6,15 @@
{if $user->can('manage_clients')} + {if $group_dropdown} +{$forms.clientsForm.open} {* clientsForm consists only of one dropdown group control *} + + + + +
{$i18n.label.group}: {$forms.clientsForm.group.control}
+{$forms.clientsForm.close} + {/if} {if $inactive_clients} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 071a29a46..1a9987d8c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.clients.active_clients}
-
 Anuko Time Tracker 1.18.29.4556 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4557 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/clients.php b/clients.php index 6bf48097f..ca83efd90 100644 --- a/clients.php +++ b/clients.php @@ -39,13 +39,45 @@ header('Location: feature_disabled.php'); exit(); } +if ($request->isPost()) { + $groupChanged = $request->getParameter('group_changed'); // Reused in multiple places below. + if ($groupChanged && !($user->can('manage_subgroups') && $user->isGroupValid($request->getParameter('group')))) { + header('Location: access_denied.php'); // Group changed, but no rght or wrong group id. + exit(); + } +} + +// Determine group for which we display this page. +if ($request->isPost() && $groupChanged) { + $group_id = $request->getParameter('group'); + $user->setOnBehalfGroup($group_id); +} else { + $group_id = $user->getGroup(); +} + +$form = new Form('clientsForm'); +if ($user->can('manage_subgroups')) { + $groups = $user->getGroupsForDropdown(); + if (count($groups) > 1) { + $form->addInput(array('type'=>'combobox', + 'onchange'=>'document.clientsForm.group_changed.value=1;document.clientsForm.submit();', + 'name'=>'group', + 'style'=>'width: 250px;', + 'value'=>$group_id, + 'data'=>$groups, + 'datakeys'=>array('id','name'))); + $form->addInput(array('type'=>'hidden','name'=>'group_changed')); + $smarty->assign('group_dropdown', 1); + } +} if($user->can('manage_clients')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); - $inactive_clients = ttTeamHelper::getInactiveClients($user->group_id, true); + $active_clients = ttTeamHelper::getActiveClients($user->getGroup(), true); + $inactive_clients = ttTeamHelper::getInactiveClients($user->getGroup(), true); } else $active_clients = $user->getAssignedClients(); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('active_clients', $active_clients); $smarty->assign('inactive_clients', $inactive_clients); $smarty->assign('title', $i18n->get('title.clients')); From a96c4f4e05e68e875ce088201ad011d6fc3e1e1c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 17:49:11 +0000 Subject: [PATCH 0482/1848] A bit more refactoring of clients.php for subgroups. --- WEB-INF/lib/ttClientHelper.class.php | 12 -------- WEB-INF/lib/ttGroupHelper.class.php | 46 ++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- clients.php | 5 +-- 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 3dc60bdb7..9009f570a 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -239,18 +239,6 @@ static function update($fields) return (!is_a($affected, 'PEAR_Error')); } - // The setMappedClient function is used during group import to change client_id value for tt_users to a mapped value. - static function setMappedClient($group_id, $imported_id, $mapped_id) - { - $mdb2 = getConnection(); - $sql = "update tt_users set client_id = $mapped_id where client_id = $imported_id and group_id = $group_id "; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - return true; - } - // The fillBean function fills the ActionForm object with client data. static function fillBean($client_id, &$bean) { $client = ttClientHelper::getClient($client_id, true); diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 8b02c85e1..e04c221d1 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -274,4 +274,50 @@ static function getRoles() { } return $roles; } + + // The getActiveClients returns an array of active clients for a group. + static function getActiveClients($all_fields = false) + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + if ($all_fields) + $sql = "select * from tt_clients where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)"; + else + $sql = "select id, name from tt_clients where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)"; + + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } + + // The getInactiveClients returns an array of inactive clients for a group. + static function getInactiveClients($all_fields = false) + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + if ($all_fields) + $sql = "select * from tt_clients where group_id = $group_id and org_id = $org_id and status = 0 order by upper(name)"; + else + $sql = "select id, name from tt_clients where group_id = $group_id and org_id = $org_id and status = 0 order by upper(name)"; + + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1a9987d8c..b11d78eb7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4557 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4559 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/clients.php b/clients.php index ca83efd90..cc08f9a3c 100644 --- a/clients.php +++ b/clients.php @@ -29,6 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!(ttAccessAllowed('view_own_clients') || ttAccessAllowed('manage_clients'))) { @@ -72,8 +73,8 @@ } if($user->can('manage_clients')) { - $active_clients = ttTeamHelper::getActiveClients($user->getGroup(), true); - $inactive_clients = ttTeamHelper::getInactiveClients($user->getGroup(), true); + $active_clients = ttGroupHelper::getActiveClients(true); + $inactive_clients = ttGroupHelper::getInactiveClients(true); } else $active_clients = $user->getAssignedClients(); From 38b85fc251ea53e5d5842e25c8fc9b066a474a54 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 18:58:57 +0000 Subject: [PATCH 0483/1848] More refactoring for subgroups. --- WEB-INF/lib/ttTeamHelper.class.php | 21 --------------------- WEB-INF/templates/footer.tpl | 2 +- expense_edit.php | 5 +++-- expenses.php | 5 +++-- invoice_add.php | 3 ++- mobile/clients.php | 6 +++--- 6 files changed, 12 insertions(+), 30 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 08c52f453..44f3d7a01 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -400,27 +400,6 @@ static function getActiveClients($group_id, $all_fields = false) return $result; } - // The getInactiveClients returns an array of inactive clients for a group. - static function getInactiveClients($group_id, $all_fields = false) - { - $result = array(); - $mdb2 = getConnection(); - - if ($all_fields) - $sql = "select * from tt_clients where group_id = $group_id and status = 0 order by upper(name)"; - else - $sql = "select id, name from tt_clients where group_id = $group_id and status = 0 order by upper(name)"; - - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - } - return $result; - } - // The getAllClients obtains all clients in a group. static function getAllClients($group_id, $all_fields = false) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b11d78eb7..501e850dc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4559 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4560 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expense_edit.php b/expense_edit.php index 9768fa23e..80f861c8b 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -29,6 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); import('DateAndTime'); import('ttExpenseHelper'); @@ -77,7 +78,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -102,7 +103,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; diff --git a/expenses.php b/expenses.php index aa0d97769..1ff638fbe 100644 --- a/expenses.php +++ b/expenses.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttUserHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); import('DateAndTime'); import('ttExpenseHelper'); @@ -92,7 +93,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -118,7 +119,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; diff --git a/invoice_add.php b/invoice_add.php index 61568e2aa..0cda1a386 100644 --- a/invoice_add.php +++ b/invoice_add.php @@ -29,6 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttInvoiceHelper'); // Access checks. @@ -56,7 +57,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $clients = ttTeamHelper::getActiveClients($user->group_id); + $clients = ttGroupHelper::getActiveClients(); $form->addInput(array('type'=>'combobox','name'=>'client','style'=>'width: 250px;','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->get('dropdown.select')))); } // Dropdown for projects. diff --git a/mobile/clients.php b/mobile/clients.php index 61cc304ea..d1e6b38f3 100644 --- a/mobile/clients.php +++ b/mobile/clients.php @@ -28,7 +28,7 @@ require_once('../initialize.php'); import('form.Form'); -import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!(ttAccessAllowed('view_own_clients') || ttAccessAllowed('manage_clients'))) { @@ -42,8 +42,8 @@ // End of access checks. if($user->can('manage_clients')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); - $inactive_clients = ttTeamHelper::getInactiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); + $inactive_clients = ttGroupHelper::getInactiveClients(true); } else $active_clients = $user->getAssignedClients(); From 1bebedf4f6025a06d5c738a82ef057d2d0200eac Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 20:20:08 +0000 Subject: [PATCH 0484/1848] More refactoring for subgroups. --- WEB-INF/lib/ttTeamHelper.class.php | 21 --------------------- WEB-INF/templates/footer.tpl | 2 +- mobile/expense_edit.php | 5 +++-- mobile/expenses.php | 5 +++-- mobile/time.php | 5 +++-- mobile/time_edit.php | 5 +++-- mobile/timer.php | 5 +++-- mobile/user_add.php | 3 ++- mobile/user_edit.php | 3 ++- time.php | 4 ++-- time_edit.php | 5 +++-- user_add.php | 3 ++- user_edit.php | 3 ++- week.php | 5 +++-- 14 files changed, 32 insertions(+), 42 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 44f3d7a01..f82fc2630 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -379,27 +379,6 @@ static function getInactiveRolesForUser() return $result; } - // The getActiveClients returns an array of active clients for a group. - static function getActiveClients($group_id, $all_fields = false) - { - $result = array(); - $mdb2 = getConnection(); - - if ($all_fields) - $sql = "select * from tt_clients where group_id = $group_id and status = 1 order by upper(name)"; - else - $sql = "select id, name from tt_clients where group_id = $group_id and status = 1 order by upper(name)"; - - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - } - return $result; - } - // The getAllClients obtains all clients in a group. static function getAllClients($group_id, $all_fields = false) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 501e850dc..7c66412a1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4560 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4561 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index d139530c9..fa00b5863 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -29,6 +29,7 @@ require_once('../initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); import('DateAndTime'); import('ttExpenseHelper'); @@ -74,7 +75,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -99,7 +100,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; diff --git a/mobile/expenses.php b/mobile/expenses.php index de1e67783..a39bf4a99 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttUserHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); import('DateAndTime'); import('ttExpenseHelper'); @@ -96,7 +97,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -122,7 +123,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; diff --git a/mobile/time.php b/mobile/time.php index 2b8e01f05..c8ec97977 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttUserHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); import('DateAndTime'); @@ -92,7 +93,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -118,7 +119,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 925220430..cbe4c9359 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttUserHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); import('DateAndTime'); @@ -109,7 +110,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -135,7 +136,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; diff --git a/mobile/timer.php b/mobile/timer.php index ae5a96f59..bf92a89ef 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttUserHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); import('DateAndTime'); @@ -88,7 +89,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -116,7 +117,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; diff --git a/mobile/user_add.php b/mobile/user_add.php index 9d2b539e0..20c2b1ffb 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -29,6 +29,7 @@ require_once('../initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttUserHelper'); import('form.Table'); import('form.TableColumn'); @@ -45,7 +46,7 @@ @include('../plugins/limit/user_add.php'); if ($user->isPluginEnabled('cl')) - $clients = ttTeamHelper::getActiveClients($user->group_id); + $clients = ttGroupHelper::getActiveClients(); $assigned_projects = array(); if ($request->isPost()) { diff --git a/mobile/user_edit.php b/mobile/user_edit.php index c9b4af81c..81947dbdc 100644 --- a/mobile/user_edit.php +++ b/mobile/user_edit.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttProjectHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttUserHelper'); import('form.Table'); import('form.TableColumn'); @@ -48,7 +49,7 @@ // End of access checks. if ($user->isPluginEnabled('cl')) - $clients = ttTeamHelper::getActiveClients($user->group_id); + $clients = ttGroupHelper::getActiveClients(); $projects = ttTeamHelper::getActiveProjects($user->group_id); $assigned_projects = array(); diff --git a/time.php b/time.php index ce622b233..fb507fb5f 100644 --- a/time.php +++ b/time.php @@ -170,7 +170,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->getTrackingMode() && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -196,7 +196,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; diff --git a/time_edit.php b/time_edit.php index 08a5f392e..e6a8adb81 100644 --- a/time_edit.php +++ b/time_edit.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttUserHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); import('DateAndTime'); @@ -112,7 +113,7 @@ // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -138,7 +139,7 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; diff --git a/user_add.php b/user_add.php index 7fb6ea3c7..e948aa712 100644 --- a/user_add.php +++ b/user_add.php @@ -29,6 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttUserHelper'); import('form.Table'); import('form.TableColumn'); @@ -46,7 +47,7 @@ @include('plugins/limit/user_add.php'); if ($user->isPluginEnabled('cl')) - $clients = ttTeamHelper::getActiveClients($user->getGroup()); + $clients = ttGroupHelper::getActiveClients(); $assigned_projects = array(); if ($request->isPost()) { diff --git a/user_edit.php b/user_edit.php index 8a4e421b1..df3ada4f1 100644 --- a/user_edit.php +++ b/user_edit.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttProjectHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttUserHelper'); import('form.Table'); import('form.TableColumn'); @@ -49,7 +50,7 @@ // End of access checks. if ($user->isPluginEnabled('cl')) - $clients = ttTeamHelper::getActiveClients($user->getGroup()); + $clients = ttGroupHelper::getActiveClients(); $projects = ttTeamHelper::getActiveProjects($user->getGroup()); $assigned_projects = array(); diff --git a/week.php b/week.php index 927e8a776..95dc31b12 100644 --- a/week.php +++ b/week.php @@ -33,6 +33,7 @@ import('form.TextField'); import('ttUserHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttWeekViewHelper'); import('ttClientHelper'); import('ttTimeHelper'); @@ -244,7 +245,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Dropdown for clients in MODE_TIME. Use all active clients. if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', @@ -270,7 +271,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { - $active_clients = ttTeamHelper::getActiveClients($user->group_id, true); + $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; From 884b152e088f23cfec4342db48fb9924cc647cee Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 21:30:52 +0000 Subject: [PATCH 0485/1848] Improved clients.php to support subgroups. --- WEB-INF/lib/ttUser.class.php | 16 +++++++++++----- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 0db272ff6..73393c0ac 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -230,11 +230,14 @@ function getAssignedProjects() $result = array(); $mdb2 = getConnection(); - $group_id = $this->behalf_group_id ? $this->behalf_group_id : $this->group_id; + $group_id = $this->getGroup(); + $org_id = $this->org_id; + $user_id = $this->getUser(); + // Do a query with inner join to get assigned projects. - $sql = "select p.id, p.name, p.description, p.tasks, upb.rate from tt_projects p - inner join tt_user_project_binds upb on (upb.user_id = ".$this->getUser()." and upb.project_id = p.id and upb.status = 1) - where p.group_id = $group_id and p.status = 1 order by p.name"; + $sql = "select p.id, p.name, p.description, p.tasks, upb.rate from tt_projects p". + " inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id and upb.status = 1)". + " where p.group_id = $group_id and p.org_id = $org_id and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -288,9 +291,12 @@ function getAssignedClients() $mdb2 = getConnection(); + $group_id = $this->getGroup(); + $org_id = $this->org_id; + // Get active clients for group. $clients = array(); - $sql = "select id, name, address, projects from tt_clients where group_id = $this->group_id and status = 1"; + $sql = "select id, name, address, projects from tt_clients where group_id = $group_id and org_id = $org_id and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7c66412a1..111e83dd0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4561 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4562 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e92d4ffe1d8dfe70c11be7862b31de432a6bab07 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 22:07:26 +0000 Subject: [PATCH 0486/1848] Adjusting client_add.php and client_edit.php for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- client_add.php | 4 ++-- client_edit.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 111e83dd0..83288cf47 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4562 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4563 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/client_add.php b/client_add.php index b3d27ac79..6f678cea2 100644 --- a/client_add.php +++ b/client_add.php @@ -41,7 +41,7 @@ exit(); } -$projects = ttTeamHelper::getActiveProjects($user->group_id); +$projects = ttTeamHelper::getActiveProjects($user->getGroup()); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -58,7 +58,7 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 350px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','style'=>'width: 350px; height: 80px;','value'=>$cl_address)); $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); diff --git a/client_edit.php b/client_edit.php index 34c0a0706..0d57c9d29 100644 --- a/client_edit.php +++ b/client_edit.php @@ -43,7 +43,7 @@ $cl_id = (int) $request->getParameter('id'); -$projects = ttTeamHelper::getActiveProjects($user->group_id); +$projects = ttTeamHelper::getActiveProjects($user->getGroup()); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -70,7 +70,7 @@ $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'datakeys'=>array('id','name'),'layout'=>'H','value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); From 75ff7ff29a038803d3b6e2c31b793049bbb2fbd4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 22:58:13 +0000 Subject: [PATCH 0487/1848] Some more refactoring for subgroups. --- WEB-INF/lib/ttGroupHelper.class.php | 42 +++++++++++++++++++++++++++++ WEB-INF/lib/ttTeamHelper.class.php | 18 ------------- WEB-INF/templates/footer.tpl | 2 +- mobile/projects.php | 5 ++-- projects.php | 5 ++-- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index e04c221d1..9f9f4a2f9 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -320,4 +320,46 @@ static function getInactiveClients($all_fields = false) } return $result; } + + // getActiveProjects - returns an array of active projects for a group. + static function getActiveProjects() + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, name, description, tasks from tt_projects". + " where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } + + // getInactiveProjects - returns an array of inactive projects for a group. + static function getInactiveProjects() + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, name, description, tasks from tt_projects". + " where group_id = $group_id and org_id = $org_id and status = 0 order by upper(name)"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index f82fc2630..67d97b850 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -194,24 +194,6 @@ static function getActiveProjects($group_id) return $result; } - // getInactiveProjects - returns an array of inactive projects for a group. - static function getInactiveProjects($group_id) - { - $result = array(); - $mdb2 = getConnection(); - - $sql = "select id, name, description, tasks from tt_projects - where group_id = $group_id and status = 0 order by upper(name)"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - } - return $result; - } - // The getAllProjects obtains all projects in a group. static function getAllProjects($group_id, $all_fields = false) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 83288cf47..00eaa060a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4563 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4564 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/projects.php b/mobile/projects.php index e3dc2f87e..d244ae1b7 100644 --- a/mobile/projects.php +++ b/mobile/projects.php @@ -29,6 +29,7 @@ require_once('../initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!(ttAccessAllowed('view_own_projects') || ttAccessAllowed('manage_projects'))) { @@ -42,8 +43,8 @@ // End of access checks. if($user->can('manage_projects')) { - $active_projects = ttTeamHelper::getActiveProjects($user->group_id); - $inactive_projects = ttTeamHelper::getInactiveProjects($user->group_id); + $active_projects = ttGroupHelper::getActiveProjects(); + $inactive_projects = ttGroupHelper::getInactiveProjects(); } else $active_projects = $user->getAssignedProjects(); diff --git a/projects.php b/projects.php index b8faa14d6..8b4537e79 100644 --- a/projects.php +++ b/projects.php @@ -29,6 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!(ttAccessAllowed('view_own_projects') || ttAccessAllowed('manage_projects'))) { @@ -73,8 +74,8 @@ } if($user->can('manage_projects')) { - $active_projects = ttTeamHelper::getActiveProjects($group_id); - $inactive_projects = ttTeamHelper::getInactiveProjects($group_id); + $active_projects = ttGroupHelper::getActiveProjects(); + $inactive_projects = ttGroupHelper::getInactiveProjects(); } else $active_projects = $user->getAssignedProjects(); From 11868a92089a10db070993b89e595f45fac3f6ff Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Dec 2018 23:19:41 +0000 Subject: [PATCH 0488/1848] Some more refactoring for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- client_add.php | 4 ++-- client_edit.php | 3 ++- invoice_add.php | 4 ++-- mobile/client_add.php | 6 +++--- mobile/client_edit.php | 6 +++--- mobile/task_add.php | 7 +++---- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 00eaa060a..5c66c159e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4564 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4565 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/client_add.php b/client_add.php index 6f678cea2..b14e8b454 100644 --- a/client_add.php +++ b/client_add.php @@ -29,7 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('ttClientHelper'); -import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_clients')) { @@ -41,7 +41,7 @@ exit(); } -$projects = ttTeamHelper::getActiveProjects($user->getGroup()); +$projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); diff --git a/client_edit.php b/client_edit.php index 0d57c9d29..0dc3bb655 100644 --- a/client_edit.php +++ b/client_edit.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttClientHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_clients')) { @@ -43,7 +44,7 @@ $cl_id = (int) $request->getParameter('id'); -$projects = ttTeamHelper::getActiveProjects($user->getGroup()); +$projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); diff --git a/invoice_add.php b/invoice_add.php index 0cda1a386..e29de2eb6 100644 --- a/invoice_add.php +++ b/invoice_add.php @@ -61,8 +61,8 @@ $form->addInput(array('type'=>'combobox','name'=>'client','style'=>'width: 250px;','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->get('dropdown.select')))); } // Dropdown for projects. -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $projects = ttTeamHelper::getActiveProjects($user->group_id); +if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { + $projects = ttGroupHelper::getActiveProjects(); $form->addInput(array('type'=>'combobox','name'=>'project','style'=>'width: 250px;','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_project,'empty'=>array(''=>$i18n->get('dropdown.all')))); } $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'number','style'=>'width: 250px;','value'=>$cl_number)); diff --git a/mobile/client_add.php b/mobile/client_add.php index 222012d48..f5cc5b694 100644 --- a/mobile/client_add.php +++ b/mobile/client_add.php @@ -29,7 +29,7 @@ require_once('../initialize.php'); import('form.Form'); import('ttClientHelper'); -import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_clients')) { @@ -41,7 +41,7 @@ exit(); } -$projects = ttTeamHelper::getActiveProjects($user->group_id); +$projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -58,7 +58,7 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','class'=>'mobile-textarea','value'=>$cl_address)); $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); diff --git a/mobile/client_edit.php b/mobile/client_edit.php index 917b656a8..4044637bf 100644 --- a/mobile/client_edit.php +++ b/mobile/client_edit.php @@ -29,7 +29,7 @@ require_once('../initialize.php'); import('form.Form'); import('ttClientHelper'); -import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_clients')) { @@ -43,7 +43,7 @@ $cl_id = (int) $request->getParameter('id'); -$projects = ttTeamHelper::getActiveProjects($user->group_id); +$projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -70,7 +70,7 @@ $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'datakeys'=>array('id','name'),'layout'=>'H','value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); diff --git a/mobile/task_add.php b/mobile/task_add.php index 9deed925d..db73d1c77 100644 --- a/mobile/task_add.php +++ b/mobile/task_add.php @@ -28,8 +28,7 @@ require_once('../initialize.php'); import('form.Form'); -import('form.ActionForm'); -import('ttTeamHelper'); +import('ttGroupHelper'); import('ttTaskHelper'); // Access checks. @@ -37,13 +36,13 @@ header('Location: access_denied.php'); exit(); } -if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +if (MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { header('Location: feature_disabled.php'); exit(); } // End of access checks. -$projects = ttTeamHelper::getActiveProjects($user->group_id); +$projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); From 81763e3414521856124ea022ab9ef52947da89b2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 Dec 2018 13:13:05 +0000 Subject: [PATCH 0489/1848] A bit more refactoring. --- WEB-INF/lib/ttTeamHelper.class.php | 18 ------------------ WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- mobile/task_edit.php | 4 ++-- mobile/user_add.php | 2 +- mobile/user_edit.php | 2 +- task_add.php | 4 ++-- task_edit.php | 4 ++-- user_add.php | 2 +- user_edit.php | 2 +- 10 files changed, 12 insertions(+), 30 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 67d97b850..e64bd6724 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -176,24 +176,6 @@ static function getInactiveUsers($group_id, $all_fields = false) { return false; } - // getActiveProjects - returns an array of active projects for a group. - static function getActiveProjects($group_id) - { - $result = array(); - $mdb2 = getConnection(); - - $sql = "select id, name, description, tasks from tt_projects - where group_id = $group_id and status = 1 order by upper(name)"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - } - return $result; - } - // The getAllProjects obtains all projects in a group. static function getAllProjects($group_id, $all_fields = false) { $mdb2 = getConnection(); diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 73393c0ac..587ca73c6 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -746,7 +746,7 @@ function getUserPartForHeader() { $user_part .= ' '.$i18n->get('label.on_behalf').' '.htmlspecialchars($this->behalf_name).''; } if ($this->behalf_group_id) { - $user_part .= ', '.$i18n->get('label.on_behalf').' '.htmlspecialchars($this->behalf_group_name).''; + $user_part .= ', '.htmlspecialchars($this->behalf_group_name).''; } else { if ($this->group_name) // Note: we did not require group names in the past. $user_part .= ', '.$this->group_name; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5c66c159e..91ff8c9f5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4565 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4566 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/task_edit.php b/mobile/task_edit.php index ba36ea56e..facf18c67 100644 --- a/mobile/task_edit.php +++ b/mobile/task_edit.php @@ -28,7 +28,7 @@ require_once('../initialize.php'); import('form.Form'); -import('ttTeamHelper'); +import('ttGroupHelper'); import('ttTaskHelper'); // Access checks. @@ -48,7 +48,7 @@ } // End of access checks. -$projects = ttTeamHelper::getActiveProjects($user->group_id); +$projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); diff --git a/mobile/user_add.php b/mobile/user_add.php index 20c2b1ffb..fbd82835f 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -90,7 +90,7 @@ $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -$projects = ttTeamHelper::getActiveProjects($user->group_id); +$projects = ttGroupHelper::getActiveProjects(); // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { diff --git a/mobile/user_edit.php b/mobile/user_edit.php index 81947dbdc..df184fcfb 100644 --- a/mobile/user_edit.php +++ b/mobile/user_edit.php @@ -51,7 +51,7 @@ if ($user->isPluginEnabled('cl')) $clients = ttGroupHelper::getActiveClients(); -$projects = ttTeamHelper::getActiveProjects($user->group_id); +$projects = ttGroupHelper::getActiveProjects(); $assigned_projects = array(); if ($request->isPost()) { diff --git a/task_add.php b/task_add.php index 1fdc7b18c..078bd5ca1 100644 --- a/task_add.php +++ b/task_add.php @@ -29,7 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('form.ActionForm'); -import('ttTeamHelper'); +import('ttGroupHelper'); import('ttTaskHelper'); // Access checks. @@ -43,7 +43,7 @@ } // End of access checks. -$projects = ttTeamHelper::getActiveProjects($user->getGroup()); +$projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); diff --git a/task_edit.php b/task_edit.php index efe8509d3..10410c4b3 100644 --- a/task_edit.php +++ b/task_edit.php @@ -28,7 +28,7 @@ require_once('initialize.php'); import('form.Form'); -import('ttTeamHelper'); +import('ttGroupHelper'); import('ttTaskHelper'); // Access checks. @@ -48,7 +48,7 @@ } // End of access checks. -$projects = ttTeamHelper::getActiveProjects($user->getGroup()); +$projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); diff --git a/user_add.php b/user_add.php index e948aa712..8a507e9ee 100644 --- a/user_add.php +++ b/user_add.php @@ -91,7 +91,7 @@ $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -$projects = ttTeamHelper::getActiveProjects($user->getGroup()); +$projects = ttGroupHelper::getActiveProjects(); // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { diff --git a/user_edit.php b/user_edit.php index df3ada4f1..531d2efec 100644 --- a/user_edit.php +++ b/user_edit.php @@ -52,7 +52,7 @@ if ($user->isPluginEnabled('cl')) $clients = ttGroupHelper::getActiveClients(); -$projects = ttTeamHelper::getActiveProjects($user->getGroup()); +$projects = ttGroupHelper::getActiveProjects(); $assigned_projects = array(); if ($request->isPost()) { From b5426618bbd3ee3178a86f6318b321632047f25b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 Dec 2018 14:01:13 +0000 Subject: [PATCH 0490/1848] Adjusted custom field config pages for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- admin_options.php | 1 + cf_custom_field_add.php | 1 + cf_custom_field_delete.php | 21 +++++++++--------- cf_custom_field_edit.php | 10 +++++---- cf_custom_fields.php | 1 + plugins/CustomFields.class.php | 39 ++++++++++++++++++++-------------- 7 files changed, 43 insertions(+), 32 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 91ff8c9f5..77ebe494d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4566 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4567 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_options.php b/admin_options.php index 164ff33a1..9448ef788 100644 --- a/admin_options.php +++ b/admin_options.php @@ -36,6 +36,7 @@ header('Location: access_denied.php'); exit(); } +// End of access checks. if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index 8227d2541..c0dc255f6 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -45,6 +45,7 @@ header('Location: access_denied.php'); exit(); } +// End of access checks. if ($request->isPost()) { $cl_field_name = trim($request->getParameter('name')); diff --git a/cf_custom_field_delete.php b/cf_custom_field_delete.php index 86c10b1ff..c8a133692 100644 --- a/cf_custom_field_delete.php +++ b/cf_custom_field_delete.php @@ -39,8 +39,13 @@ header('Location: feature_disabled.php'); exit(); } - -$id = $request->getParameter('id'); +$id = (int)$request->getParameter('id'); +$field = CustomFields::getField($id); +if (!$field) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. $form = new Form('fieldDeleteForm'); @@ -60,15 +65,9 @@ exit(); } } else { - $field = CustomFields::getField($id); - if (false === $field) - $err->add($i18n->get('error.db')); - - if ($err->no()) { - $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$id)); - $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - } + $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$id)); + $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); + $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); } $smarty->assign('field', $field['label']); diff --git a/cf_custom_field_edit.php b/cf_custom_field_edit.php index 499f6d02a..0bf5818d8 100644 --- a/cf_custom_field_edit.php +++ b/cf_custom_field_edit.php @@ -39,11 +39,13 @@ header('Location: feature_disabled.php'); exit(); } - -$cl_id = $request->getParameter('id'); +$cl_id = (int)$request->getParameter('id'); $field = CustomFields::getField($cl_id); -if (false === $field) - $err->add($i18n->get('error.db')); +if (!$field) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. $form = new Form('fieldForm'); if ($err->no()) { diff --git a/cf_custom_fields.php b/cf_custom_fields.php index 53f80e400..6de626cc9 100644 --- a/cf_custom_fields.php +++ b/cf_custom_fields.php @@ -39,6 +39,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. $form = new Form('customFieldsForm'); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 74fef831c..885f60b90 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -237,8 +237,12 @@ static function getFields() { global $user; $mdb2 = getConnection(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $fields = array(); - $sql = "select id, type, label from tt_custom_fields where group_id = $user->group_id and status = 1 and type > 0"; + $sql = "select id, type, label from tt_custom_fields". + " where group_id = $group_id and org_id = $org_id and status = 1 and type > 0"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -254,7 +258,11 @@ static function getField($id) { global $user; $mdb2 = getConnection(); - $sql = "select label, type, required from tt_custom_fields where id = $id and group_id = $user->group_id"; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select label, type, required from tt_custom_fields". + " where id = $id and group_id = $group_id and org_id = $org_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -295,40 +303,39 @@ static function insertField($field_name, $field_type, $required) { static function updateField($id, $name, $type, $required) { global $user; $mdb2 = getConnection(); - $sql = "update tt_custom_fields set label = ".$mdb2->quote($name).", type = $type, required = $required where id = $id and group_id = $user->group_id"; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $sql = "update tt_custom_fields set label = ".$mdb2->quote($name).", type = $type, required = $required". + " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } // The deleteField deletes a custom field, its options and log entries for group. static function deleteField($field_id) { - global $user; $mdb2 = getConnection(); - // First make sure that the field is ours so that we can safely delete it. - $sql = "select group_id from tt_custom_fields where id = $field_id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) - return false; - $val = $res->fetchRow(); - if ($user->group_id != $val['group_id']) - return false; + $group_id = $user->getGroup(); + $org_id = $user->org_id; - // Mark log entries as deleted. - $sql = "update tt_custom_field_log set status = NULL where field_id = $field_id"; + // Mark log entries as deleted. TODO: why are we doing this? Research impact. + $sql = "update tt_custom_field_log set status = null". + " where field_id = $field_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark field options as deleted. - $sql = "update tt_custom_field_options set status = NULL where field_id = $field_id"; + $sql = "update tt_custom_field_options set status = null". + " where field_id = $field_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark custom field as deleted. - $sql = "update tt_custom_fields set status = NULL where id = $field_id and group_id = $user->group_id"; + $sql = "update tt_custom_fields set status = null". + " where id = $field_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } From 95d031241d1e1970e92171e733c81896b53f7cdc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 Dec 2018 15:38:41 +0000 Subject: [PATCH 0491/1848] Ongoing refactoring of custom fields for subgroups. --- WEB-INF/templates/cf_dropdown_options.tpl | 2 - WEB-INF/templates/footer.tpl | 2 +- cf_dropdown_options.php | 13 ++-- plugins/CustomFields.class.php | 94 ++++++++++++----------- time_edit.php | 2 +- 5 files changed, 60 insertions(+), 53 deletions(-) diff --git a/WEB-INF/templates/cf_dropdown_options.tpl b/WEB-INF/templates/cf_dropdown_options.tpl index ba15a416f..f9dfcd0d7 100644 --- a/WEB-INF/templates/cf_dropdown_options.tpl +++ b/WEB-INF/templates/cf_dropdown_options.tpl @@ -2,7 +2,6 @@ function chLocation(newLocation) { document.location = newLocation; } -{$forms.dropdownOptionsForm.open}
@@ -38,4 +37,3 @@
-{$forms.dropdownOptionsForm.close} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 77ebe494d..4cfac191c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4567 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4568 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cf_dropdown_options.php b/cf_dropdown_options.php index 1afce7348..3b4663f8c 100644 --- a/cf_dropdown_options.php +++ b/cf_dropdown_options.php @@ -39,15 +39,16 @@ header('Location: feature_disabled.php'); exit(); } +$field_id = (int)$request->getParameter('field_id'); +$field = CustomFields::getField($field_id); +if (!$field) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. -$field_id = $request->getParameter('field_id'); $options = CustomFields::getOptions($field_id); -if (false === $options) - $err->add($i18n->get('error.db')); - -$form = new Form('dropdownOptionsForm'); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('field_id', $field_id); $smarty->assign('options', $options); $smarty->assign('title', $i18n->get('title.cf_dropdown_options')); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 885f60b90..a2e883269 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -91,20 +91,30 @@ function update($log_id, $field_id, $option_id, $value) { } function delete($log_id) { - + global $user; $mdb2 = getConnection(); - $sql = "update tt_custom_field_log set status = NULL where log_id = $log_id"; + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "update tt_custom_field_log set status = null". + " where log_id = $log_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } function get($log_id) { - $fields = array(); - + global $user; $mdb2 = getConnection(); - $sql = "select id, field_id, option_id, value from tt_custom_field_log where log_id = $log_id and status = 1"; + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, field_id, option_id, value from tt_custom_field_log". + " where log_id = $log_id and group_id = $group_id and org_id = $org_id and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { + $fields = array(); while ($val = $res->fetchRow()) { $fields[] = $val; } @@ -123,7 +133,8 @@ static function insertOption($field_id, $option_name) { // Check if the option exists. $id = 0; - $sql = "select id from tt_custom_field_options where field_id = $field_id and value = ".$mdb2->quote($option_name); + $sql = "select id from tt_custom_field_options". + " where field_id = $field_id and group_id = $group_id and org_id = $org_id and value = ".$mdb2->quote($option_name); $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; @@ -142,10 +153,14 @@ static function insertOption($field_id, $option_name) { // updateOption updates option name. static function updateOption($id, $option_name) { - + global $user; $mdb2 = getConnection(); - $sql = "update tt_custom_field_options set value = ".$mdb2->quote($option_name)." where id = $id"; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "update tt_custom_field_options set value = ".$mdb2->quote($option_name). + " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -155,25 +170,22 @@ static function deleteOption($id) { global $user; $mdb2 = getConnection(); - $field_id = CustomFields::getFieldIdForOption($id); + $group_id = $user->getGroup(); + $org_id = $user->org_id; - // First make sure that the field is ours. - $sql = "select group_id from tt_custom_fields where id = $field_id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) - return false; - $val = $res->fetchRow(); - if ($user->group_id != $val['group_id']) - return false; + $field_id = CustomFields::getFieldIdForOption($id); + if (!$field_id) return false; - // Delete log entries with this option. - $sql = "update tt_custom_field_log set status = NULL where field_id = $field_id and value = ".$mdb2->quote($id); + // Delete log entries with this option. TODO: why? Research impact. + $sql = "update tt_custom_field_log set status = null". + " where field_id = $field_id and group_id = $group_id and org_id = $org_id and value = ".$mdb2->quote($id); $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Delete the option. - $sql = "update tt_custom_field_options set status = NULL where id = $id"; + $sql = "update tt_custom_field_options set status = null". + " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -182,21 +194,16 @@ static function deleteOption($id) { static function getOptions($field_id) { global $user; $mdb2 = getConnection(); - $options = array(); - // First make sure that the field is ours. - $sql = "select group_id from tt_custom_fields where id = $field_id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) - return false; - $val = $res->fetchRow(); - if ($user->group_id != $val['group_id']) - return false; + $group_id = $user->getGroup(); + $org_id = $user->org_id; // Get options. - $sql = "select id, value from tt_custom_field_options where field_id = $field_id and status = 1 order by value"; + $sql = "select id, value from tt_custom_field_options". + " where field_id = $field_id and group_id = $group_id and org_id = $org_id and status = 1 order by value"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { + $options = array(); while ($val = $res->fetchRow()) { $options[$val['id']] = $val['value']; } @@ -210,19 +217,11 @@ static function getOptionName($id) { global $user; $mdb2 = getConnection(); - $field_id = CustomFields::getFieldIdForOption($id); - - // First make sure that the field is ours. - $sql = "select group_id from tt_custom_fields where id = $field_id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) - return false; - $val = $res->fetchRow(); - if ($user->group_id != $val['group_id']) - return false; + $group_id = $user->getGroup(); + $org_id = $user->org_id; - // Get option name. - $sql = "select value from tt_custom_field_options where id = $id"; + $sql = "select value from tt_custom_field_options". + " where id = $id and group_id = $group_id and org_id = $org_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -275,9 +274,14 @@ static function getField($id) { // getFieldIdForOption returns field id from an associated option id. static function getFieldIdForOption($option_id) { + global $user; $mdb2 = getConnection(); - $sql = "select field_id from tt_custom_field_options where id = $option_id"; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select field_id from tt_custom_field_options". + " where id = $option_id and group_id = $group_id and org_id = $org_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -291,8 +295,10 @@ static function getFieldIdForOption($option_id) { static function insertField($field_name, $field_type, $required) { global $user; $mdb2 = getConnection(); + $group_id = $user->getGroup(); $org_id = $user->org_id; + $sql = "insert into tt_custom_fields (group_id, org_id, type, label, required, status)". " values($group_id, $org_id, $field_type, ".$mdb2->quote($field_name).", $required, 1)"; $affected = $mdb2->exec($sql); @@ -303,8 +309,10 @@ static function insertField($field_name, $field_type, $required) { static function updateField($id, $name, $type, $required) { global $user; $mdb2 = getConnection(); + $group_id = $user->getGroup(); $org_id = $user->org_id; + $sql = "update tt_custom_fields set label = ".$mdb2->quote($name).", type = $type, required = $required". " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); diff --git a/time_edit.php b/time_edit.php index e6a8adb81..f4eb41d29 100644 --- a/time_edit.php +++ b/time_edit.php @@ -53,7 +53,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields($user->getGroup()); $smarty->assign('custom_fields', $custom_fields); } From 45a530c33fdd7ab2ccd1905c24a371c94e17eac5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 Dec 2018 15:58:41 +0000 Subject: [PATCH 0492/1848] More refactoring for subgroups. --- WEB-INF/lib/ttTimeHelper.class.php | 13 ++++++++++--- WEB-INF/templates/footer.tpl | 2 +- mobile/time_delete.php | 2 +- time_delete.php | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 5f8852eff..6ddedc456 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -506,15 +506,22 @@ static function update($fields) } // delete - deletes a record from tt_log table and its associated custom field values. - static function delete($id, $user_id) { + static function delete($id) { + global $user; $mdb2 = getConnection(); - $sql = "update tt_log set status = NULL where id = $id and user_id = $user_id"; + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "update tt_log set status = null". + " where id = $id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $sql = "update tt_custom_field_log set status = NULL where log_id = $id"; + $sql = "update tt_custom_field_log set status = null". + " where log_id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4cfac191c..b0529d290 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4568 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4569 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/time_delete.php b/mobile/time_delete.php index f5305bc62..104732601 100644 --- a/mobile/time_delete.php +++ b/mobile/time_delete.php @@ -64,7 +64,7 @@ if ($err->no()) { // Delete the record. - if (ttTimeHelper::delete($cl_id, $user_id)) { + if (ttTimeHelper::delete($cl_id)) { header('Location: time.php'); exit(); } else { diff --git a/time_delete.php b/time_delete.php index 385e4f114..5d6e57298 100644 --- a/time_delete.php +++ b/time_delete.php @@ -64,7 +64,7 @@ if ($err->no()) { // Delete the record. - if (ttTimeHelper::delete($cl_id, $user_id)) { + if (ttTimeHelper::delete($cl_id)) { header('Location: time.php'); exit(); } else { From 49c25be4ace17ab7495824a08c37a061a5a75b25 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 Dec 2018 16:18:14 +0000 Subject: [PATCH 0493/1848] More refactoring in custom fields for subgroups. --- WEB-INF/lib/ttReportHelper.class.php | 6 +++--- WEB-INF/lib/ttWeekViewHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- mobile/time.php | 2 +- mobile/time_edit.php | 2 +- mobile/timer.php | 2 +- plugins/CustomFields.class.php | 12 +++++++++--- report.php | 2 +- reports.php | 2 +- time.php | 2 +- time_edit.php | 2 +- tofile.php | 2 +- topdf.php | 2 +- week.php | 2 +- 14 files changed, 24 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 16277bd19..0d99ce88a 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -157,7 +157,7 @@ static function getItems($options) { // Add custom field. $include_cf_1 = $options['show_custom_field_1'] || $grouping_by_cf_1; if ($include_cf_1) { - $custom_fields = new CustomFields($user->getGroup()); + $custom_fields = new CustomFields(); $cf_1_type = $custom_fields->fields[0]['type']; if ($cf_1_type == CustomFields::TYPE_TEXT) { array_push($fields, 'cfl.value as cf_1'); @@ -616,7 +616,7 @@ static function prepareReportBody($options, $comment = null) // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) - $custom_fields = new CustomFields($user->getGroup()); + $custom_fields = new CustomFields(); // Define some styles to use in email. $style_title = 'text-align: center; font-size: 15pt; font-family: Arial, Helvetica, sans-serif;'; @@ -1460,7 +1460,7 @@ static function makeJoinPart($options) { $join .= ' left join tt_tasks t on (l.task_id = t.id)'; } if (ttReportHelper::groupingBy('cf_1', $options)) { - $custom_fields = new CustomFields($user->getGroup()); + $custom_fields = new CustomFields(); if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) $join .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id)'; elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index 2cfb3813d..782f309b4 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -45,7 +45,7 @@ static function getRecordsForInterval($user_id, $start_date, $end_date) { $custom_field_1 = null; if ($user->isPluginEnabled('cf')) { - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields(); $cf_1_type = $custom_fields->fields[0]['type']; if ($cf_1_type == CustomFields::TYPE_TEXT) { $custom_field_1 = ', cfl.value as cf_1_value'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b0529d290..c391edf46 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4569 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4570 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/time.php b/mobile/time.php index c8ec97977..9e51633b2 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -60,7 +60,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('../plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields(); $smarty->assign('custom_fields', $custom_fields); } diff --git a/mobile/time_edit.php b/mobile/time_edit.php index cbe4c9359..60a14e2c6 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -53,7 +53,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('../plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields(); $smarty->assign('custom_fields', $custom_fields); } diff --git a/mobile/timer.php b/mobile/timer.php index bf92a89ef..184e6274c 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -54,7 +54,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('../plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields(); $smarty->assign('custom_fields', $custom_fields); } diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index a2e883269..a7945aba4 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -37,11 +37,16 @@ class CustomFields { var $options = array(); // Array of options for a dropdown custom field. // Constructor. - function __construct($group_id) { + function __construct() { + global $user; $mdb2 = getConnection(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + // Get fields. - $sql = "select id, type, label, required from tt_custom_fields where group_id = $group_id and status = 1 and type > 0"; + $sql = "select id, type, label, required from tt_custom_fields". + " where group_id = $group_id and org_id = $org_id and status = 1 and type > 0"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -52,7 +57,8 @@ function __construct($group_id) { // If we have a dropdown obtain options for it. if ((count($this->fields) > 0) && ($this->fields[0]['type'] == CustomFields::TYPE_DROPDOWN)) { - $sql = "select id, value from tt_custom_field_options where field_id = ".$this->fields[0]['id']." and status = 1 order by value"; + $sql = "select id, value from tt_custom_field_options". + " where field_id = ".$this->fields[0]['id']." and group_id = $group_id and org_id = $org_id and status = 1 order by value"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/report.php b/report.php index 28e086c4d..1a8ce63cc 100644 --- a/report.php +++ b/report.php @@ -54,7 +54,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields(); $smarty->assign('custom_fields', $custom_fields); } diff --git a/reports.php b/reports.php index efbf96421..8310f5ddc 100644 --- a/reports.php +++ b/reports.php @@ -46,7 +46,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields(); $smarty->assign('custom_fields', $custom_fields); } diff --git a/time.php b/time.php index fb507fb5f..a428b9a2b 100644 --- a/time.php +++ b/time.php @@ -89,7 +89,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($group_id); + $custom_fields = new CustomFields(); $smarty->assign('custom_fields', $custom_fields); } diff --git a/time_edit.php b/time_edit.php index f4eb41d29..4b3f4c2c0 100644 --- a/time_edit.php +++ b/time_edit.php @@ -53,7 +53,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->getGroup()); + $custom_fields = new CustomFields(); $smarty->assign('custom_fields', $custom_fields); } diff --git a/tofile.php b/tofile.php index 445b32d94..990b8a555 100644 --- a/tofile.php +++ b/tofile.php @@ -41,7 +41,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields(); } // Report settings are stored in session bean before we get here. diff --git a/topdf.php b/topdf.php index e3801d273..fd3016e55 100644 --- a/topdf.php +++ b/topdf.php @@ -52,7 +52,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields(); } // Report settings are stored in session bean before we get here. diff --git a/week.php b/week.php index 95dc31b12..289d95127 100644 --- a/week.php +++ b/week.php @@ -84,7 +84,7 @@ // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields($user->group_id); + $custom_fields = new CustomFields(); $smarty->assign('custom_fields', $custom_fields); } From 2da96fa165c607461c7f518a08cc4040f92801bb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 Dec 2018 17:03:32 +0000 Subject: [PATCH 0494/1848] Refactored custom field option config pages. --- WEB-INF/templates/footer.tpl | 2 +- cf_dropdown_option_add.php | 10 ++++++---- cf_dropdown_option_delete.php | 20 ++++++++++---------- cf_dropdown_option_edit.php | 8 +++++--- plugins/CustomFields.class.php | 2 +- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c391edf46..fab529754 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4570 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4571 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cf_dropdown_option_add.php b/cf_dropdown_option_add.php index 7b49424e5..de598186e 100644 --- a/cf_dropdown_option_add.php +++ b/cf_dropdown_option_add.php @@ -39,11 +39,13 @@ header('Location: feature_disabled.php'); exit(); } - -$cl_field_id = $request->getParameter('field_id'); +$cl_field_id = (int)$request->getParameter('field_id'); $field = CustomFields::getField($cl_field_id); -if (false === $field) - $err->add($i18n->get('error.db')); +if (!$field) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. $form = new Form('optionAddForm'); if ($err->no()) { diff --git a/cf_dropdown_option_delete.php b/cf_dropdown_option_delete.php index 4cb2aca8a..999094e53 100644 --- a/cf_dropdown_option_delete.php +++ b/cf_dropdown_option_delete.php @@ -39,8 +39,14 @@ header('Location: feature_disabled.php'); exit(); } - $cl_id = $request->getParameter('id'); +$option = CustomFields::getOptionName($cl_id); +if (!$option) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + $form = new Form('optionDeleteForm'); if ($request->isPost()) { @@ -62,15 +68,9 @@ exit(); } } else { - $option = CustomFields::getOptionName($cl_id); - if (false === $option) - $err->add($i18n->get('error.db')); - - if ($err->no()) { - $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); - $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - } + $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); + $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); + $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); } $smarty->assign('option', $option); diff --git a/cf_dropdown_option_edit.php b/cf_dropdown_option_edit.php index 5522accf1..4f1103d7b 100644 --- a/cf_dropdown_option_edit.php +++ b/cf_dropdown_option_edit.php @@ -39,11 +39,13 @@ header('Location: feature_disabled.php'); exit(); } - $cl_id = $request->getParameter('id'); $cl_name = CustomFields::getOptionName($cl_id); -if (false === $cl_name) - $err->add($i18n->get('error.db')); +if (!$cl_name) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. $form = new Form('optionEditForm'); if ($err->no()) { diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index a7945aba4..d9762b58d 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -227,7 +227,7 @@ static function getOptionName($id) { $org_id = $user->org_id; $sql = "select value from tt_custom_field_options". - " where id = $id and group_id = $group_id and org_id = $org_id"; + " where id = $id and group_id = $group_id and org_id = $org_id and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); From 796b9e17473ca045e448b7876472bb73015247e9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 Dec 2018 20:30:27 +0000 Subject: [PATCH 0495/1848] Refactored and renamed ttSysConfig class. --- WEB-INF/lib/ttInvoiceHelper.class.php | 26 +++++++++------- ...onfig.class.php => ttUserConfig.class.php} | 31 +++++++++++-------- WEB-INF/templates/footer.tpl | 2 +- charts.php | 22 ++++++------- invoice_send.php | 12 +++---- report_send.php | 12 +++---- 6 files changed, 56 insertions(+), 49 deletions(-) rename WEB-INF/lib/{ttSysConfig.class.php => ttUserConfig.class.php} (71%) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 13e784d07..042acd821 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -257,18 +257,20 @@ static function invoiceableItemsExist($fields) { } } - // sql part for project id. - if ($project_id) $project_part = " and ei.project_id = $project_id"; - - $sql = "select count(*) as num from tt_expense_items ei - where ei.client_id = $client_id $project_part and ei.invoice_id is NULL - and ei.date >= ".$mdb2->quote($start)." and ei.date <= ".$mdb2->quote($end)." - and ei.cost <> 0 and ei.status = 1"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - $val = $res->fetchRow(); - if ($val['num']) { - return true; + if ($user->isPluginEnabled('ex')) { + // sql part for project id. + if ($project_id) $project_part = " and ei.project_id = $project_id"; + + $sql = "select count(*) as num from tt_expense_items ei + where ei.client_id = $client_id $project_part and ei.invoice_id is NULL + and ei.date >= ".$mdb2->quote($start)." and ei.date <= ".$mdb2->quote($end)." + and ei.cost <> 0 and ei.status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if ($val['num']) { + return true; + } } } diff --git a/WEB-INF/lib/ttSysConfig.class.php b/WEB-INF/lib/ttUserConfig.class.php similarity index 71% rename from WEB-INF/lib/ttSysConfig.class.php rename to WEB-INF/lib/ttUserConfig.class.php index 4cc5f8c26..b92699440 100644 --- a/WEB-INF/lib/ttSysConfig.class.php +++ b/WEB-INF/lib/ttUserConfig.class.php @@ -33,25 +33,28 @@ define('SYSC_LAST_INVOICE_EMAIL', 'last_invoice_email'); define('SYSC_LAST_INVOICE_CC', 'last_invoice_cc'); -// Class ttSysConfig is used for storing and retrieving named values associated with users. -class ttSysConfig { +// Class ttUserConfig is used for storing and retrieving named values associated with users. +// When user is working on behalf of someone else, this class is still associated with a user. +class ttUserConfig { var $user_id = null; var $group_id = null; var $org_id = null; var $mdb2 = null; // Constructor. - function __construct($user_id) { + function __construct() { global $user; - $this->user_id = $user_id; // TODO: review "on behalf" situation and refactor if necessary. - $this->group_id = $user->getGroup(); + $this->user_id = $user->id; // Not behalf id by design. + $this->group_id = $user->group_id; $this->org_id = $user->org_id; $this->mdb2 = getConnection(); } // The getValue retrieves a value identified by name. function getValue($name) { - $res = $this->mdb2->query("select param_value from tt_config where user_id = ".$this->user_id." and param_name=".$this->mdb2->quote($name)); + $res = $this->mdb2->query("select param_value from tt_config". + " where user_id = $this->user_id and group_id = $this->group_id and org_id = $this->org_id". + " and param_name=".$this->mdb2->quote($name)); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); return $val['param_value']; @@ -61,15 +64,17 @@ function getValue($name) { // The setValue sets a value identified by name. function setValue($name, $value) { - $rcnt = 0; - $res = $this->mdb2->query("select count(*) as rcnt from tt_config where user_id = ".$this->user_id." and param_name = ".$this->mdb2->quote($name)); - if ($val = $res->fetchRow()) $rcnt = $val['rcnt']; - - if ($rcnt > 0) { - $affected = $this->mdb2->exec("update tt_config set param_value = ".$this->mdb2->quote($value)." where user_id = ".$this->user_id." and param_name=".$this->mdb2->quote($name)); + $count = 0; + $res = $this->mdb2->query("select count(*) as count from tt_config where user_id = ".$this->user_id." and param_name = ".$this->mdb2->quote($name)); + if ($val = $res->fetchRow()) $count = $val['count']; + + if ($count > 0) { + $affected = $this->mdb2->exec("update tt_config set param_value = ".$this->mdb2->quote($value). + " where user_id = $this->user_id and group_id = $this->group_id and org_id = $this->org_id". + " and param_name=".$this->mdb2->quote($name)); } else { $sql = "insert into tt_config set param_value = ".$this->mdb2->quote($value). - ", param_name = ".$this->mdb2->quote($name).", user_id = ".$this->user_id.", group_id = ".$this->group_id.", org_id = ".$this->org_id; + ", param_name = ".$this->mdb2->quote($name).", user_id = $this->user_id, group_id = $this->group_id, org_id = ".$this->org_id; $affected = $this->mdb2->exec($sql); } return (!is_a($affected, 'PEAR_Error')); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fab529754..dbbcb63f9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4571 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4572 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/charts.php b/charts.php index d6707038f..3923d9a0a 100644 --- a/charts.php +++ b/charts.php @@ -32,7 +32,7 @@ import('form.Form'); import('DateAndTime'); import('ttChartHelper'); -import('ttSysConfig'); +import('ttUserConfig'); import('PieChartEx'); import('ttUserHelper'); import('ttTeamHelper'); @@ -66,8 +66,8 @@ // Initialize chart interval. $cl_interval = $_SESSION['chart_interval']; if (!$cl_interval) { - $sc = new ttSysConfig($user->id); - $cl_interval = $sc->getValue(SYSC_CHART_INTERVAL); + $uc = new ttUserConfig(); + $cl_interval = $uc->getValue(SYSC_CHART_INTERVAL); } if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; $_SESSION['chart_interval'] = $cl_interval; @@ -75,10 +75,10 @@ // Initialize chart type. $cl_type = $_SESSION['chart_type']; if (!$cl_type) { - $sc = new ttSysConfig($user->id); - $cl_type = $sc->getValue(SYSC_CHART_TYPE); + $uc = new ttUserConfig(); + $cl_type = $uc->getValue(SYSC_CHART_TYPE); } -if (MODE_TIME == $user->tracking_mode) { +if (MODE_TIME == $user->getTrackingMode()) { if ($user->isPluginEnabled('cl')) $cl_type = CHART_CLIENTS; } else { @@ -86,7 +86,7 @@ if (!$user->isPluginEnabled('cl')) $cl_type = CHART_PROJECTS; } elseif ($cl_type == CHART_TASKS) { - if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) + if (MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) $cl_type = CHART_PROJECTS; } } @@ -103,8 +103,8 @@ // Save in the session $_SESSION['chart_interval'] = $cl_interval; // and permanently. - $sc = new ttSysConfig($user->id); - $sc->setValue(SYSC_CHART_INTERVAL, $cl_interval); + $uc = new ttUserConfig(); + $uc->setValue(SYSC_CHART_INTERVAL, $cl_interval); } // If chart type changed - save it. $cl_type = $request->getParameter('type'); @@ -112,8 +112,8 @@ // Save in the session $_SESSION['chart_type'] = $cl_type; // and permanently. - $sc = new ttSysConfig($user->id); - $sc->setValue(SYSC_CHART_TYPE, $cl_type); + $uc = new ttUserConfig(); + $uc->setValue(SYSC_CHART_TYPE, $cl_type); } // If user has changed - set behalf_id accordingly in the session. if ($request->getParameter('onBehalfUser')) { diff --git a/invoice_send.php b/invoice_send.php index 135453b53..c86cebb53 100644 --- a/invoice_send.php +++ b/invoice_send.php @@ -29,7 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('ttInvoiceHelper'); -import('ttSysConfig'); +import('ttUserConfig'); // Access checks. if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices'))) { @@ -48,7 +48,7 @@ } // End of access checks. -$sc = new ttSysConfig($user->id); +$uc = new ttUserConfig(); if ($request->isPost()) { $cl_receiver = trim($request->getParameter('receiver')); @@ -56,8 +56,8 @@ $cl_subject = trim($request->getParameter('subject')); $cl_comment = trim($request->getParameter('comment')); } else { - $cl_receiver = $sc->getValue(SYSC_LAST_INVOICE_EMAIL); - $cl_cc = $sc->getValue(SYSC_LAST_INVOICE_CC); + $cl_receiver = $uc->getValue(SYSC_LAST_INVOICE_EMAIL); + $cl_cc = $uc->getValue(SYSC_LAST_INVOICE_CC); $cl_subject = $i18n->get('title.invoice').' '.$invoice['name'].', '.$user->group_name; } @@ -78,8 +78,8 @@ if ($err->no()) { // Save last invoice emails for future use. - $sc->setValue(SYSC_LAST_INVOICE_EMAIL, $cl_receiver); - $sc->setValue(SYSC_LAST_INVOICE_CC, $cl_cc); + $uc->setValue(SYSC_LAST_INVOICE_EMAIL, $cl_receiver); + $uc->setValue(SYSC_LAST_INVOICE_CC, $cl_cc); $body = ttInvoiceHelper::prepareInvoiceBody($cl_invoice_id, $cl_comment); diff --git a/report_send.php b/report_send.php index 9bbf9f51c..526457bf4 100644 --- a/report_send.php +++ b/report_send.php @@ -29,7 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('form.ActionForm'); -import('ttSysConfig'); +import('ttUserConfig'); import('ttReportHelper'); // Access check. @@ -38,7 +38,7 @@ exit(); } -$sc = new ttSysConfig($user->id); +$uc = new ttUserConfig(); if ($request->isPost()) { $cl_receiver = trim($request->getParameter('receiver')); @@ -46,8 +46,8 @@ $cl_subject = trim($request->getParameter('subject')); $cl_comment = trim($request->getParameter('comment')); } else { - $cl_receiver = $sc->getValue(SYSC_LAST_REPORT_EMAIL); - $cl_cc = $sc->getValue(SYSC_LAST_REPORT_CC); + $cl_receiver = $uc->getValue(SYSC_LAST_REPORT_EMAIL); + $cl_cc = $uc->getValue(SYSC_LAST_REPORT_CC); $cl_subject = $i18n->get('form.mail.report_subject'); } @@ -67,8 +67,8 @@ if ($err->no()) { // Save last report emails for future use. - $sc->setValue(SYSC_LAST_REPORT_EMAIL, $cl_receiver); - $sc->setValue(SYSC_LAST_REPORT_CC, $cl_cc); + $uc->setValue(SYSC_LAST_REPORT_EMAIL, $cl_receiver); + $uc->setValue(SYSC_LAST_REPORT_CC, $cl_cc); // Obtain session bean with report attributes. $bean = new ActionForm('reportBean', new Form('reportForm')); From 059ee30555153c4a73ee68f80c78351f15feb723 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 Dec 2018 13:03:39 +0000 Subject: [PATCH 0496/1848] Improved db cleanup code to not operate on admin group. --- WEB-INF/lib/ttOrgHelper.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index 8b3f95ff0..f77d1eb6e 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -71,7 +71,7 @@ static function getInactiveOrgs() { // Determine inactive organizations by querying the database for max access timestamp for its users. $cutoff_timestamp = $mdb2->quote(date('Y-m-d', strtotime('-1 year'))); $sql = "select org_id from". - " (select max(accessed) as last_access, org_id from tt_users group by org_id order by last_access, org_id) as t". + " (select max(accessed) as last_access, org_id from tt_users where org_id > 0 group by org_id order by last_access, org_id) as t". " where last_access is null or last_access < $cutoff_timestamp limit 5"; // Max 5 orgs at a time for now... $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { From 9af5722a81d1999243ac3a3d51d3cf3c3256d86a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 Dec 2018 15:09:57 +0000 Subject: [PATCH 0497/1848] Adjusted charts.php for subgroups. --- WEB-INF/lib/ttChartHelper.class.php | 35 ++++++++ WEB-INF/lib/ttUser.class.php | 11 ++- WEB-INF/templates/charts.tpl | 4 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 8 +- charts.php | 127 ++++++++++++---------------- 6 files changed, 100 insertions(+), 87 deletions(-) diff --git a/WEB-INF/lib/ttChartHelper.class.php b/WEB-INF/lib/ttChartHelper.class.php index 75a38d072..7a4d25843 100644 --- a/WEB-INF/lib/ttChartHelper.class.php +++ b/WEB-INF/lib/ttChartHelper.class.php @@ -132,4 +132,39 @@ static function getTotals($user_id, $chart_type, $selected_date, $interval_type) return $result; } + + // adjustType - adjust chart type to something that is available for a group. + static function adjustType($requested_type) { + global $user; + $tracking_mode = $user->getTrackingMode(); + $client_option = $user->isPluginEnabled('cl'); + + // We have 3 possible options for chart tyep: projects, tasks, or clients. + // Deal with each one individually. + + if ($requested_type == CHART_PROJECTS) { + if ($tracking_mode == MODE_PROJECTS || $tracking_mode == MODE_PROJECTS_AND_TASKS) + return CHART_PROJECTS; + else if ($client_option) + return CHART_CLIENTS; + } + + if ($requested_type == CHART_TASKS) { + if ($tracking_mode == MODE_PROJECTS_AND_TASKS) + return CHART_TASKS; + if ($tracking_mode == MODE_PROJECTS) + return CHART_PROJECTS; + else if ($client_option) + return CHART_CLIENTS; + } + + if ($requested_type == CHART_CLIENTS) { + if ($client_option) + return CHART_CLIENTS; + else if ($tracking_mode == MODE_PROJECTS || ($tracking_mode == MODE_PROJECTS_AND_TASKS)) + return CHART_PROJECTS; + } + + return CHART_PROJECTS; + } } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 587ca73c6..5e359cd21 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -523,7 +523,7 @@ function getUserDetails($user_id) { // - subgroup must ve valid; // - user should be a member of it. function checkBehalfId() { - if (!$this->behalf_group_id) { + if (!$this->behalfGroup) { // Checking user from home group. $options = array('status'=>ACTIVE,'max_rank'=>$this->rank-1); $users = $this->getUsers($options); @@ -533,7 +533,7 @@ function checkBehalfId() { } } else { // Checking user from a subgroup. - $group_id = $this->behalf_group_id; + $group_id = $this->behalfGroup->id; if (!$this->isSubgroupValid($group_id)) return false; @@ -556,11 +556,10 @@ function checkBehalfId() { // In this case we still allow access to charts, but set behalf_id to someone else. // Another example: working in a subgroup on behalf of someone else. function adjustBehalfId() { - $group_id = $this->behalf_group_id ? $this->behalf_group_id : $this->group_id; - $rank = $this->getMaxRankForGroup($group_id); + $rank = $this->getMaxRankForGroup($this->getGroup()); // Adjust to first found user in group. - $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank); + $options = array('status'=>ACTIVE,'max_rank'=>$rank); $users = $this->getUsers($options); foreach($users as $one_user) { // Fake loop to access first element. @@ -786,7 +785,7 @@ function setOnBehalfGroup($group_id) { $this->behalfGroup = new ttGroup($this->behalf_group_id, $this->org_id); - // Adjust on behalf user. + // Adjust on behalf user to first found user in subgroup. $this->adjustBehalfId(); return; } diff --git a/WEB-INF/templates/charts.tpl b/WEB-INF/templates/charts.tpl index 5e173e109..b7df0e85e 100644 --- a/WEB-INF/templates/charts.tpl +++ b/WEB-INF/templates/charts.tpl @@ -2,8 +2,8 @@ {$forms.chartForm.open} -{if $on_behalf_control} - +{if $user_dropdown} + {if $chart_selector} {/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index dbbcb63f9..aacf7a64c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.user}: {$forms.chartForm.onBehalfUser.control}{$i18n.label.user}: {$forms.chartForm.user.control}{$i18n.form.charts.chart}: {$forms.chartForm.type.control}
-
 Anuko Time Tracker 1.18.29.4572 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4573 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index de25c0660..57e842ee1 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -120,14 +120,14 @@ {if $user->isPluginEnabled('iv') && ($user->can('view_own_invoices') || $user->can('manage_invoices'))} · {$i18n.title.invoices} {/if} - {if ($user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts'))) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode - || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode || $user->isPluginEnabled('cl'))} + {if ($user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts'))) && ($smarty.const.MODE_PROJECTS == $user->getTrackingMode() + || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() || $user->isPluginEnabled('cl'))} · {$i18n.menu.charts} {/if} - {if ($user->can('view_own_projects') || $user->can('manage_projects')) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if ($user->can('view_own_projects') || $user->can('manage_projects')) && ($smarty.const.MODE_PROJECTS == $user->getTrackingMode() || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode())} · {$i18n.menu.projects} {/if} - {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode && ($user->can('view_own_tasks') || $user->can('manage_tasks')))} + {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && ($user->can('view_own_tasks') || $user->can('manage_tasks')))} · {$i18n.menu.tasks} {/if} {if $user->can('view_users') || $user->can('manage_users')} diff --git a/charts.php b/charts.php index 3923d9a0a..adaa8ae52 100644 --- a/charts.php +++ b/charts.php @@ -54,6 +54,28 @@ header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to view on behalf. exit(); } +if ($request->isPost() && $request->getParameter('user')) { + if (!$user->isUserValid($request->getParameter('user'))) { + header('Location: access_denied.php'); // Wrong user id on post. + exit(); + } +} +// End of access checks. + +// Determine user for which we display this page. +$userChanged = $request->getParameter('user_changed'); +if ($request->isPost() && $userChanged) { + $user_id = $request->getParameter('user'); + $user->setOnBehalfUser($user_id); +} else { + $user_id = $user->getUser(); + // Handle a situation for no users in on behalf group. + if ($user->behalfGroup && $user_id == $user->id) + $user_id = null; +} + +$uc = new ttUserConfig(); +$tracking_mode = $user->getTrackingMode(); // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -63,73 +85,29 @@ } $_SESSION['date'] = $cl_date; -// Initialize chart interval. -$cl_interval = $_SESSION['chart_interval']; -if (!$cl_interval) { - $uc = new ttUserConfig(); - $cl_interval = $uc->getValue(SYSC_CHART_INTERVAL); -} -if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; -$_SESSION['chart_interval'] = $cl_interval; - -// Initialize chart type. -$cl_type = $_SESSION['chart_type']; -if (!$cl_type) { - $uc = new ttUserConfig(); - $cl_type = $uc->getValue(SYSC_CHART_TYPE); -} -if (MODE_TIME == $user->getTrackingMode()) { - if ($user->isPluginEnabled('cl')) - $cl_type = CHART_CLIENTS; -} else { - if ($cl_type == CHART_CLIENTS) { - if (!$user->isPluginEnabled('cl')) - $cl_type = CHART_PROJECTS; - } elseif ($cl_type == CHART_TASKS) { - if (MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) - $cl_type = CHART_PROJECTS; - } -} -if (!$cl_type) $cl_type = CHART_PROJECTS; -$_SESSION['chart_type'] = $cl_type; - -// Who do we draw charts for? -$on_behalf_id = $request->getParameter('onBehalfUser', (isset($_SESSION['behalf_id'])? $_SESSION['behalf_id'] : $user->id)); - if ($request->isPost()) { - // If chart interval changed - save it. $cl_interval = $request->getParameter('interval'); - if ($cl_interval) { - // Save in the session - $_SESSION['chart_interval'] = $cl_interval; - // and permanently. - $uc = new ttUserConfig(); - $uc->setValue(SYSC_CHART_INTERVAL, $cl_interval); - } - // If chart type changed - save it. + if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; + $_SESSION['chart_interval'] = $cl_interval; + $uc->setValue(SYSC_CHART_INTERVAL, $cl_interval); + $cl_type = $request->getParameter('type'); - if ($cl_type) { - // Save in the session - $_SESSION['chart_type'] = $cl_type; - // and permanently. - $uc = new ttUserConfig(); - $uc->setValue(SYSC_CHART_TYPE, $cl_type); - } - // If user has changed - set behalf_id accordingly in the session. - if ($request->getParameter('onBehalfUser')) { - if($user->can('view_charts')) { - unset($_SESSION['behalf_id']); - unset($_SESSION['behalf_name']); - - if($on_behalf_id != $user->id) { - $_SESSION['behalf_id'] = $on_behalf_id; - $_SESSION['behalf_name'] = ttUserHelper::getUserName($on_behalf_id); - } - header('Location: charts.php'); - exit(); - } - } -} // isPost + if (!$cl_type) $cl_type = ttChartHelper::adjustType($cl_type); + $_SESSION['chart_type'] = $cl_type; + $uc->setValue(SYSC_CHART_TYPE, $cl_type); +} else { + // Initialize chart interval. + $cl_interval = $_SESSION['chart_interval']; + if (!$cl_interval) $cl_interval = $uc->getValue(SYSC_CHART_INTERVAL); + if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; + $_SESSION['chart_interval'] = $cl_interval; + + // Initialize chart type. + $cl_type = $_SESSION['chart_type']; + if (!$cl_type) $cl_type = $uc->getValue(SYSC_CHART_TYPE); + $cl_type = ttChartHelper::adjustType($cl_type); + $_SESSION['chart_type'] = $cl_type; +} // Elements of chartForm. $chart_form = new Form('chartForm'); @@ -143,13 +121,14 @@ $user_list = $user->getUsers($options); if (count($user_list) >= 1) { $chart_form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.submit();', - 'name'=>'onBehalfUser', - 'value'=>$on_behalf_id, + 'onchange'=>'this.form.user_changed.value=1;this.form.submit();', + 'name'=>'user', + 'value'=>$user_id, 'data'=>$user_list, 'datakeys'=>array('id','name'), )); - $smarty->assign('on_behalf_control', 1); + $chart_form->addInput(array('type'=>'hidden','name'=>'user_changed')); + $smarty->assign('user_dropdown', 1); } } @@ -163,26 +142,26 @@ // Chart interval dropdown. $chart_form->addInput(array('type' => 'combobox', - 'onchange' => 'if(this.form) this.form.submit();', + 'onchange' => 'this.form.submit();', 'name' => 'interval', 'value' => $cl_interval, 'data' => $intervals )); // Chart type options. -$chart_selector = (MODE_PROJECTS_AND_TASKS == $user->tracking_mode || $user->isPluginEnabled('cl')); +$chart_selector = (MODE_PROJECTS_AND_TASKS == $tracking_mode || $user->isPluginEnabled('cl')); if ($chart_selector) { $types = array(); - if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) + if (MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode) $types[CHART_PROJECTS] = $i18n->get('dropdown.projects'); - if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) + if (MODE_PROJECTS_AND_TASKS == $tracking_mode) $types[CHART_TASKS] = $i18n->get('dropdown.tasks'); if ($user->isPluginEnabled('cl')) $types[CHART_CLIENTS] = $i18n->get('dropdown.clients'); // Add chart type dropdown. $chart_form->addInput(array('type' => 'combobox', - 'onchange' => 'if(this.form) this.form.submit();', + 'onchange' => 'this.form.submit();', 'name' => 'type', 'value' => $cl_type, 'data' => $types @@ -193,7 +172,7 @@ $chart_form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar // Get data for our chart. -$totals = ttChartHelper::getTotals($on_behalf_id, $cl_type, $cl_date, $cl_interval); +$totals = ttChartHelper::getTotals($user_id, $cl_type, $cl_date, $cl_interval); $smarty->assign('totals', $totals); // Prepare chart for drawing. From d6949642980a9d59eae3378d5b350fd59b6905fe Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 Dec 2018 15:54:34 +0000 Subject: [PATCH 0498/1848] Reduced flicker on charts.php by specifying image size. --- WEB-INF/lib/ttChartHelper.class.php | 2 +- WEB-INF/templates/charts.tpl | 2 +- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttChartHelper.class.php b/WEB-INF/lib/ttChartHelper.class.php index 7a4d25843..528fcdb0a 100644 --- a/WEB-INF/lib/ttChartHelper.class.php +++ b/WEB-INF/lib/ttChartHelper.class.php @@ -77,7 +77,7 @@ static function getTotals($user_id, $chart_type, $selected_date, $interval_type) where l.status = 1 and l.duration > 0 and l.user_id = $user_id $q_period group by l.task_id"; } elseif (CHART_CLIENTS == $chart_type) { // Data for clients. - $sql = "select coalesce(c.name, 'NULL') as name, sum(time_to_sec(l.duration)) as time from tt_log l + $sql = "select c.name as name, sum(time_to_sec(l.duration)) as time from tt_log l left join tt_clients c on (c.id = l.client_id) where l.status = 1 and l.duration > 0 and l.user_id = $user_id $q_period group by l.client_id"; } diff --git a/WEB-INF/templates/charts.tpl b/WEB-INF/templates/charts.tpl index b7df0e85e..8e05e1985 100644 --- a/WEB-INF/templates/charts.tpl +++ b/WEB-INF/templates/charts.tpl @@ -17,7 +17,7 @@
- +
{section name=i loop=$totals} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index aacf7a64c..00e7a3f05 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4573 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4574 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b239e5e01ca823026e96776413f6bb0de0f9e478 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 Dec 2018 17:46:41 +0000 Subject: [PATCH 0499/1848] Improved access checks on client_delete.php. --- WEB-INF/templates/footer.tpl | 2 +- client_delete.php | 23 ++++++++++++----------- mobile/client_delete.php | 21 +++++++++++---------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 00e7a3f05..ba7efd420 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_projects} diff --git a/WEB-INF/templates/client_edit.tpl b/WEB-INF/templates/client_edit.tpl index 92319b68f..12f6bf0d7 100644 --- a/WEB-INF/templates/client_edit.tpl +++ b/WEB-INF/templates/client_edit.tpl @@ -13,7 +13,7 @@ - + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ba7efd420..2031cbf1d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4574 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4575 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/client_delete.php b/client_delete.php index 22ae9d4a6..a5f00656e 100644 --- a/client_delete.php +++ b/client_delete.php @@ -39,9 +39,13 @@ header('Location: feature_disabled.php'); exit(); } - $id = (int)$request->getParameter('id'); $client = ttClientHelper::getClient($id); +if (!$client) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. $client_to_delete = $client['name']; @@ -53,16 +57,13 @@ $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { - if(ttClientHelper::getClient($id)) { - if ($request->getParameter('btn_delete')) { - if (ttClientHelper::delete($id, $request->getParameter('delete_client_entries'))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } else - $err->add($i18n->get('error.db')); + if ($request->getParameter('btn_delete')) { + if (ttClientHelper::delete($id, $request->getParameter('delete_client_entries'))) { + header('Location: clients.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } if ($request->getParameter('btn_cancel')) { header('Location: clients.php'); diff --git a/mobile/client_delete.php b/mobile/client_delete.php index 154d89308..8e05ccde8 100644 --- a/mobile/client_delete.php +++ b/mobile/client_delete.php @@ -39,9 +39,13 @@ header('Location: feature_disabled.php'); exit(); } - $id = (int)$request->getParameter('id'); $client = ttClientHelper::getClient($id); +if (!$client) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. $client_to_delete = $client['name']; @@ -53,16 +57,13 @@ $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { - if(ttClientHelper::getClient($id)) { - if ($request->getParameter('btn_delete')) { - if (ttClientHelper::delete($id, $request->getParameter('delete_client_entries'))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } else + if ($request->getParameter('btn_delete')) { + if (ttClientHelper::delete($id, $request->getParameter('delete_client_entries'))) { + header('Location: clients.php'); + exit(); + } else $err->add($i18n->get('error.db')); + } if ($request->getParameter('btn_cancel')) { header('Location: clients.php'); From caa61e7cf00098a2cd64d0d716abb2d6b09982e7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 Dec 2018 20:24:43 +0000 Subject: [PATCH 0500/1848] Refactoring of client config pages for subgroups. --- WEB-INF/lib/ttClientHelper.class.php | 75 ++++++++++++++++--------- WEB-INF/templates/client_add.tpl | 4 +- WEB-INF/templates/client_edit.tpl | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/client_add.tpl | 4 +- client_add.php | 10 ++-- mobile/client_add.php | 10 ++-- 7 files changed, 63 insertions(+), 44 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 9009f570a..42eb128a8 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -54,14 +54,16 @@ static function getClient($client_id, $all_fields = false) { } // getClients - returns an array of active and inactive clients in a group. - static function getClients() - { + static function getClients() { global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; $result = array(); - $mdb2 = getConnection(); - $sql = "select id, name from tt_clients where group_id = ".$user->getGroup()." and (status = 0 or status = 1) order by upper(name)"; + $sql = "select id, name from tt_clients where group_id = $group_id and org_id = $org_id and (status = 0 or status = 1) order by upper(name)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -73,13 +75,14 @@ static function getClients() // The getClientByName looks up a client by name. static function getClientByName($client_name) { - - $mdb2 = getConnection(); global $user; + $mdb2 = getConnection(); - $sql = "select id from tt_clients where group_id = ".$user->getGroup(). - " and name = ".$mdb2->quote($client_name)." and (status = 1 or status = 0)"; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $sql = "select id from tt_clients where group_id = $group_id and org_id = $org_id". + " and name = ".$mdb2->quote($client_name)." and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -92,11 +95,13 @@ static function getClientByName($client_name) { // The getDeletedClient looks up a deleted client by id. static function getDeletedClient($client_id) { - - $mdb2 = getConnection(); global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; - $sql = "select name, address from tt_clients where group_id = ".$user->getGroup(). + $sql = "select name, address from tt_clients where group_id = $group_id and org_id = $org_id". " and id = $client_id and status is NULL"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -108,22 +113,26 @@ static function getDeletedClient($client_id) { // The delete function marks client as deleded. static function delete($id, $delete_client_entries) { - - $mdb2 = getConnection(); global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; // Handle custom field log records. if ($delete_client_entries) { - $sql = "update tt_custom_field_log set status = NULL where log_id in (select id from tt_log where client_id = $id and status = 1)"; + $sql = "update tt_custom_field_log set status = null". + " where log_id in (select id from tt_log where client_id = $id and status = 1) and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; + if (is_a($affected, 'PEAR_Error')) + return false; } // Handle time records. $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; if ($delete_client_entries) { - $sql = 'update tt_log set status = NULL'.$modified_part." where client_id = $id"; + $sql = 'update tt_log set status = null'.$modified_part. + " where client_id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -131,7 +140,8 @@ static function delete($id, $delete_client_entries) { // Handle expense items. if ($delete_client_entries) { - $sql = 'update tt_expense_items set status = NULL'.$modified_part." where client_id = $id"; + $sql = 'update tt_expense_items set status = null'.$modified_part. + " where client_id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -139,26 +149,30 @@ static function delete($id, $delete_client_entries) { // Handle invoices. if ($delete_client_entries) { - $sql = "update tt_invoices set status = NULL where client_id = $id and group_id = ".$user->getGroup(); + $sql = "update tt_invoices set status = null". + " where client_id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; } // Delete project binds to this client. - $sql = "delete from tt_client_project_binds where client_id = $id"; + $sql = "delete from tt_client_project_binds". + " where client_id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Handle users for client. - $sql = 'update tt_users set status = NULL'.$modified_part." where client_id = $id and group_id = ".$user->getGroup(); + $sql = 'update tt_users set status = null'.$modified_part. + " where client_id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Mark client deleted. - $sql = "update tt_clients set status = NULL where id = $id and group_id = ".$user->getGroup(); + $sql = "update tt_clients set status = null". + " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -169,8 +183,9 @@ static function insert($fields) global $user; $mdb2 = getConnection(); - $group_id = (int) $fields['group_id']; - $org_id = (int) $fields['org_id']; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $name = $fields['name']; $address = $fields['address']; $tax = $fields['tax']; @@ -204,8 +219,11 @@ static function insert($fields) // The update function updates a client record in tt_clients table. static function update($fields) { - $mdb2 = getConnection(); global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; $id = $fields['id']; $name = $fields['name']; @@ -218,13 +236,14 @@ static function update($fields) if ($tax == '') $tax = 0; // Insert client to project binds into tt_client_project_binds table. - $sql = "delete from tt_client_project_binds where client_id = $id"; + $sql = "delete from tt_client_project_binds". + " where client_id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); if (count($projects) > 0) foreach ($projects as $p_id) { - $sql = "insert into tt_client_project_binds (client_id, project_id) values($id, $p_id)"; + $sql = "insert into tt_client_project_binds (client_id, project_id, group_id, org_id) values($id, $p_id, $group_id, $org_id)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -234,7 +253,7 @@ static function update($fields) $comma_separated = implode(",", $projects); // This is a comma-separated list of associated project ids. $sql = "update tt_clients set name = ".$mdb2->quote($name).", address = ".$mdb2->quote($address). ", tax = $tax, projects = ".$mdb2->quote($comma_separated).", status = $status". - " where group_id = ".$user->getGroup()." and id = ".$id; + " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/client_add.tpl b/WEB-INF/templates/client_add.tpl index 8db93a418..db10ede45 100644 --- a/WEB-INF/templates/client_add.tpl +++ b/WEB-INF/templates/client_add.tpl @@ -13,14 +13,14 @@
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->decimal_mark}00){$forms.clientForm.tax.control} (0{$user->getDecimalMark()}00)
{$i18n.label.required_fields}
 
{$i18n.label.projects}: {$forms.clientForm.projects.control}
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->decimal_mark}00){$forms.clientForm.tax.control} (0{$user->getDecimalMark()}00)
{$i18n.label.status}:
- - + -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_projects} diff --git a/client_add.php b/client_add.php index b14e8b454..4d26e2a11 100644 --- a/client_add.php +++ b/client_add.php @@ -54,11 +54,13 @@ // $cl_projects[] = $project_item['id']; } +$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; + $form = new Form('clientForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 350px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','style'=>'width: 350px; height: 80px;','value'=>$cl_address)); $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) +if ($show_projects) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); @@ -70,10 +72,7 @@ if ($err->no()) { if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'name' => $cl_name, + if (ttClientHelper::insert(array('name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, 'projects' => $cl_projects, @@ -89,6 +88,7 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"'); +$smarty->assign('show_projects',$show_projects); $smarty->assign('title', $i18n->get('title.add_client')); $smarty->assign('content_page_name', 'client_add.tpl'); $smarty->display('index.tpl'); diff --git a/mobile/client_add.php b/mobile/client_add.php index f5cc5b694..2050204a6 100644 --- a/mobile/client_add.php +++ b/mobile/client_add.php @@ -54,11 +54,13 @@ // $cl_projects[] = $project_item['id']; } +$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; + $form = new Form('clientForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','class'=>'mobile-textarea','value'=>$cl_address)); $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) +if ($show_projects) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); @@ -70,10 +72,7 @@ if ($err->no()) { if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'name' => $cl_name, + if (ttClientHelper::insert(array('name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, 'projects' => $cl_projects, @@ -89,6 +88,7 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"'); +$smarty->assign('show_projects',$show_projects); $smarty->assign('title', $i18n->get('title.add_client')); $smarty->assign('content_page_name', 'mobile/client_add.tpl'); $smarty->display('mobile/index.tpl'); From f5d19e5d5fd205d81367ab2c82d41c154cad50ff Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 12:59:29 +0000 Subject: [PATCH 0501/1848] Some more refactoring for subgroups. --- WEB-INF/lib/ttClientHelper.class.php | 21 ++++++++++++++------- WEB-INF/templates/client_edit.tpl | 2 +- WEB-INF/templates/footer.tpl | 2 +- client_add.php | 2 +- client_edit.php | 5 ++++- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 42eb128a8..02014f1f5 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -270,14 +270,17 @@ static function fillBean($client_id, &$bean) { static function getAssignedProjects($client_id) { global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; $result = array(); - $mdb2 = getConnection(); // Do a query with inner join to get assigned projects. $sql = "select p.id, p.name from tt_projects p". " inner join tt_client_project_binds cpb on (cpb.client_id = $client_id and cpb.project_id = p.id)". - " where p.group_id = ".$user->getGroup()." and p.status = 1 order by p.name"; + " where p.group_id = $group_id and p.org_id = $org_id and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -291,15 +294,19 @@ static function getAssignedProjects($client_id) static function getClientsForUser() { global $user; + $mdb2 = getConnection(); + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; $result = array(); - $mdb2 = getConnection(); - $sql = "select distinct c.id, c.name, c.projects from tt_user_project_binds upb - inner join tt_client_project_binds cpb on (cpb.project_id = upb.project_id) - inner join tt_clients c on (c.id = cpb.client_id and c.status = 1) - where upb.user_id = $user_id and upb.status = 1 order by upper(c.name)"; + $sql = "select distinct c.id, c.name, c.projects from tt_user_project_binds upb". + " inner join tt_client_project_binds cpb on (cpb.project_id = upb.project_id)". + " inner join tt_clients c on (c.id = cpb.client_id and c.status = 1)". + " where upb.user_id = $user_id and upb.group_id = $group_id and upb.org_id = $org_id". + " and upb.status = 1 order by upper(c.name)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/client_edit.tpl b/WEB-INF/templates/client_edit.tpl index 12f6bf0d7..2abf70dc1 100644 --- a/WEB-INF/templates/client_edit.tpl +++ b/WEB-INF/templates/client_edit.tpl @@ -24,7 +24,7 @@ -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_projects} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2031cbf1d..5bb1100af 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4575 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4576 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/client_add.tpl b/WEB-INF/templates/mobile/client_add.tpl index 8db93a418..db10ede45 100644 --- a/WEB-INF/templates/mobile/client_add.tpl +++ b/WEB-INF/templates/mobile/client_add.tpl @@ -13,14 +13,14 @@
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->decimal_mark}00){$forms.clientForm.tax.control} (0{$user->getDecimalMark()}00)
{$i18n.label.required_fields}
 
{$i18n.label.projects}: {$forms.clientForm.projects.control}{$i18n.label.required_fields}
 
{$i18n.label.projects}: {$forms.clientForm.projects.control}
-
 Anuko Time Tracker 1.18.29.4576 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4578 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/client_add.php b/client_add.php index 4d26e2a11..820a32fde 100644 --- a/client_add.php +++ b/client_add.php @@ -88,7 +88,7 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"'); -$smarty->assign('show_projects',$show_projects); +$smarty->assign('show_projects', $show_projects); $smarty->assign('title', $i18n->get('title.add_client')); $smarty->assign('content_page_name', 'client_add.tpl'); $smarty->display('index.tpl'); diff --git a/client_edit.php b/client_edit.php index 0dc3bb655..2b26d86df 100644 --- a/client_edit.php +++ b/client_edit.php @@ -64,6 +64,8 @@ } } +$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; + $form = new Form('clientForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'text','name'=>'name','maxlength'=>'100','style'=>'width: 350px;','value'=>$cl_name)); @@ -71,7 +73,7 @@ $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) +if ($show_projects) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'datakeys'=>array('id','name'),'layout'=>'H','value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); @@ -122,6 +124,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('show_projects', $show_projects); $smarty->assign('title', $i18n->get('title.edit_client')); $smarty->assign('content_page_name', 'client_edit.tpl'); $smarty->display('index.tpl'); From cb86dc570b33c9ed1199a5b9c473c0cdbbed32a3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 13:41:13 +0000 Subject: [PATCH 0502/1848] Improved project delete by also deleting client binds. --- WEB-INF/lib/ttProjectHelper.class.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 98d928f96..b5fb74dc0 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -183,6 +183,12 @@ static function delete($id) { if (is_a($affected, 'PEAR_Error')) return false; + // Delete client binds to this project. + $sql = "delete from tt_client_project_binds where project_id = $id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + return true; } From 9a1496f75c8f6cb5304968b2c0a377161af8f973 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 14:48:38 +0000 Subject: [PATCH 0503/1848] A bit more refactoring. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/client_edit.tpl | 2 +- client_edit.php | 5 +---- mobile/client_edit.php | 13 ++++++------- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5bb1100af..09e0d89cf 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_projects} diff --git a/client_edit.php b/client_edit.php index 2b26d86df..a1f98249c 100644 --- a/client_edit.php +++ b/client_edit.php @@ -105,10 +105,7 @@ if ($request->getParameter('btn_copy')) { if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'name' => $cl_name, + if (ttClientHelper::insert(array('name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, 'status' => $cl_status, diff --git a/mobile/client_edit.php b/mobile/client_edit.php index 4044637bf..b65ac99dc 100644 --- a/mobile/client_edit.php +++ b/mobile/client_edit.php @@ -63,6 +63,8 @@ } } +$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; + $form = new Form('clientForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'text','name'=>'name','maxlength'=>'100','value'=>$cl_name)); @@ -70,7 +72,7 @@ $form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) +if ($show_projects) $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'datakeys'=>array('id','name'),'layout'=>'H','value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); @@ -86,8 +88,7 @@ if ($request->getParameter('btn_save')) { $client = ttClientHelper::getClientByName($cl_name); if (($client && ($cl_id == $client['id'])) || !$client) { - if (ttClientHelper::update(array( - 'id' => $cl_id, + if (ttClientHelper::update(array('id' => $cl_id, 'name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, @@ -103,10 +104,7 @@ if ($request->getParameter('btn_copy')) { if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'name' => $cl_name, + if (ttClientHelper::insert(array('name' => $cl_name, 'address' => $cl_address, 'tax' => $cl_tax, 'status' => $cl_status, @@ -127,6 +125,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('show_projects', $show_projects); $smarty->assign('title', $i18n->get('title.edit_client')); $smarty->assign('content_page_name', 'mobile/client_edit.tpl'); $smarty->display('mobile/index.tpl'); From e63eef54095a467d0dfd64646c6ef574bab09e89 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 15:07:39 +0000 Subject: [PATCH 0504/1848] Improved access check for client edit. --- WEB-INF/templates/footer.tpl | 2 +- client_edit.php | 10 +++++++--- mobile/client_edit.php | 10 +++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 09e0d89cf..c5ff71ca3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4578 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4579 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/client_edit.tpl b/WEB-INF/templates/mobile/client_edit.tpl index d01731f0a..4f70ced7a 100644 --- a/WEB-INF/templates/mobile/client_edit.tpl +++ b/WEB-INF/templates/mobile/client_edit.tpl @@ -24,7 +24,7 @@ {$i18n.label.required_fields}
 
{$i18n.label.projects}: {$forms.clientForm.projects.control}
-
 Anuko Time Tracker 1.18.29.4579 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4580 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/client_edit.php b/client_edit.php index a1f98249c..7b572ea7c 100644 --- a/client_edit.php +++ b/client_edit.php @@ -41,8 +41,13 @@ header('Location: feature_disabled.php'); exit(); } - -$cl_id = (int) $request->getParameter('id'); +$cl_id = (int)$request->getParameter('id'); +$client = ttClientHelper::getClient($cl_id, true); +if (!$client) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. $projects = ttGroupHelper::getActiveProjects(); @@ -53,7 +58,6 @@ $cl_status = $request->getParameter('status'); $cl_projects = $request->getParameter('projects'); } else { - $client = ttClientHelper::getClient($cl_id, true); $cl_name = $client['name']; $cl_address = $client['address']; $cl_tax = $client['tax']; diff --git a/mobile/client_edit.php b/mobile/client_edit.php index b65ac99dc..ab8686509 100644 --- a/mobile/client_edit.php +++ b/mobile/client_edit.php @@ -40,8 +40,13 @@ header('Location: feature_disabled.php'); exit(); } - -$cl_id = (int) $request->getParameter('id'); +$cl_id = (int)$request->getParameter('id'); +$client = ttClientHelper::getClient($cl_id, true); +if (!$client) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. $projects = ttGroupHelper::getActiveProjects(); @@ -52,7 +57,6 @@ $cl_status = $request->getParameter('status'); $cl_projects = $request->getParameter('projects'); } else { - $client = ttClientHelper::getClient($cl_id, true); $cl_name = $client['name']; $cl_address = $client['address']; $cl_tax = $client['tax']; From 21a88534ce3aeaf84ea76f4fef0581f2eec037b6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 15:31:07 +0000 Subject: [PATCH 0505/1848] Removed group selector from clients.php as design approach changed. --- WEB-INF/templates/clients.tpl | 9 --------- WEB-INF/templates/footer.tpl | 2 +- clients.php | 33 +-------------------------------- 3 files changed, 2 insertions(+), 42 deletions(-) diff --git a/WEB-INF/templates/clients.tpl b/WEB-INF/templates/clients.tpl index 2e8b2b82f..a31a8cd05 100644 --- a/WEB-INF/templates/clients.tpl +++ b/WEB-INF/templates/clients.tpl @@ -6,15 +6,6 @@
{if $user->can('manage_clients')} - {if $group_dropdown} -{$forms.clientsForm.open} {* clientsForm consists only of one dropdown group control *} - - - - -
{$i18n.label.group}: {$forms.clientsForm.group.control}
-{$forms.clientsForm.close} - {/if} {if $inactive_clients} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c5ff71ca3..a4ddf7cc1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.clients.active_clients}
-
 Anuko Time Tracker 1.18.29.4580 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4581 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/clients.php b/clients.php index cc08f9a3c..a299d3061 100644 --- a/clients.php +++ b/clients.php @@ -40,37 +40,7 @@ header('Location: feature_disabled.php'); exit(); } -if ($request->isPost()) { - $groupChanged = $request->getParameter('group_changed'); // Reused in multiple places below. - if ($groupChanged && !($user->can('manage_subgroups') && $user->isGroupValid($request->getParameter('group')))) { - header('Location: access_denied.php'); // Group changed, but no rght or wrong group id. - exit(); - } -} - -// Determine group for which we display this page. -if ($request->isPost() && $groupChanged) { - $group_id = $request->getParameter('group'); - $user->setOnBehalfGroup($group_id); -} else { - $group_id = $user->getGroup(); -} - -$form = new Form('clientsForm'); -if ($user->can('manage_subgroups')) { - $groups = $user->getGroupsForDropdown(); - if (count($groups) > 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'document.clientsForm.group_changed.value=1;document.clientsForm.submit();', - 'name'=>'group', - 'style'=>'width: 250px;', - 'value'=>$group_id, - 'data'=>$groups, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'group_changed')); - $smarty->assign('group_dropdown', 1); - } -} +// End of access checks. if($user->can('manage_clients')) { $active_clients = ttGroupHelper::getActiveClients(true); @@ -78,7 +48,6 @@ } else $active_clients = $user->getAssignedClients(); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('active_clients', $active_clients); $smarty->assign('inactive_clients', $inactive_clients); $smarty->assign('title', $i18n->get('title.clients')); From c294ba4289d15382b0889be57d63a9297e10291d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 15:57:22 +0000 Subject: [PATCH 0506/1848] Refactoring expense related things for subgroups. --- WEB-INF/lib/ttExpenseHelper.class.php | 36 ++++++++++++++++++--------- WEB-INF/templates/footer.tpl | 2 +- expense_delete.php | 2 +- expenses.php | 2 +- mobile/expense_delete.php | 2 +- mobile/expenses.php | 2 +- 6 files changed, 29 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttExpenseHelper.class.php b/WEB-INF/lib/ttExpenseHelper.class.php index b11e71fd0..bfc3ab727 100644 --- a/WEB-INF/lib/ttExpenseHelper.class.php +++ b/WEB-INF/lib/ttExpenseHelper.class.php @@ -29,8 +29,7 @@ // The ttExpenseHelper is a class to help with expense items. class ttExpenseHelper { // insert - inserts an entry into tt_expense_items table. - static function insert($fields) - { + static function insert($fields) { global $user; $mdb2 = getConnection(); @@ -57,11 +56,13 @@ static function insert($fields) } // update - updates a record in tt_expense_items table. - static function update($fields) - { + static function update($fields) { global $user; $mdb2 = getConnection(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $id = (int) $fields['id']; $date = $fields['date']; $user_id = (int) $fields['user_id']; @@ -77,34 +78,45 @@ static function update($fields) } $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; - $sql = "UPDATE tt_expense_items set date = ".$mdb2->quote($date).", user_id = $user_id, client_id = ".$mdb2->quote($client_id). + $sql = "update tt_expense_items set date = ".$mdb2->quote($date).", user_id = $user_id, client_id = ".$mdb2->quote($client_id). ", project_id = ".$mdb2->quote($project_id).", name = ".$mdb2->quote($name). ", cost = ".$mdb2->quote($cost)."$paid_part $modified_part, invoice_id = ".$mdb2->quote($invoice_id). - " WHERE id = $id"; + " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } // markDeleted - marks an item as deleted in tt_expense_items table. - static function markDeleted($id, $user_id) { + static function markDeleted($id) { + global $user; $mdb2 = getConnection(); - $sql = "update tt_expense_items set status = NULL where id = $id and user_id = $user_id"; + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "update tt_expense_items set status = null". + " where id = $id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } // getTotalForDay - gets total expenses for a user for a specific date. - static function getTotalForDay($user_id, $date) { + static function getTotalForDay($date) { global $user; - $mdb2 = getConnection(); - $sql = "select sum(cost) as sm from tt_expense_items where user_id = $user_id and date = ".$mdb2->quote($date)." and status = 1"; + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select sum(cost) as sm from tt_expense_items". + " where user_id = $user_id and group_id = $group_id and org_id = $org_id". + " and date = ".$mdb2->quote($date)." and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - $val['sm'] = str_replace('.', $user->decimal_mark, $val['sm']); + $val['sm'] = str_replace('.', $user->getDecimalMark(), $val['sm']); return $val['sm']; } return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a4ddf7cc1..05f357bc6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4581 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4582 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expense_delete.php b/expense_delete.php index fcb039f07..32b9ab679 100644 --- a/expense_delete.php +++ b/expense_delete.php @@ -59,7 +59,7 @@ if ($err->no()) { // Mark the record as deleted. - if (ttExpenseHelper::markDeleted($cl_id, $user->getUser())) { + if (ttExpenseHelper::markDeleted($cl_id)) { header('Location: expenses.php'); exit(); } else diff --git a/expenses.php b/expenses.php index 1ff638fbe..eea55d1c0 100644 --- a/expenses.php +++ b/expenses.php @@ -211,7 +211,7 @@ } } -$smarty->assign('day_total', ttExpenseHelper::getTotalForDay($user->getUser(), $cl_date)); +$smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); $smarty->assign('expense_items', ttExpenseHelper::getItems($user->getUser(), $cl_date)); $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); diff --git a/mobile/expense_delete.php b/mobile/expense_delete.php index c0fa032eb..93d6d59f1 100644 --- a/mobile/expense_delete.php +++ b/mobile/expense_delete.php @@ -59,7 +59,7 @@ if ($err->no()) { // Mark the record as deleted. - if (ttExpenseHelper::markDeleted($cl_id, $user->getUser())) { + if (ttExpenseHelper::markDeleted($cl_id)) { header('Location: expenses.php'); exit(); } else diff --git a/mobile/expenses.php b/mobile/expenses.php index a39bf4a99..656b20e05 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -217,7 +217,7 @@ $smarty->assign('next_date', $next_date); $smarty->assign('prev_date', $prev_date); -$smarty->assign('day_total', ttExpenseHelper::getTotalForDay($user->getUser(), $cl_date)); +$smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); $smarty->assign('expense_items', ttExpenseHelper::getItems($user->getUser(), $cl_date)); $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); From 6289820a41e9ab79635294c1d6a22583aacf6e77 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 16:40:34 +0000 Subject: [PATCH 0507/1848] Some more progress with refactoring for subgroups. --- WEB-INF/lib/ttExpenseHelper.class.php | 35 +++++++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- expense_delete.php | 2 +- expense_edit.php | 2 +- expenses.php | 2 +- mobile/expense_delete.php | 2 +- mobile/expense_edit.php | 2 +- mobile/expenses.php | 2 +- 8 files changed, 27 insertions(+), 22 deletions(-) diff --git a/WEB-INF/lib/ttExpenseHelper.class.php b/WEB-INF/lib/ttExpenseHelper.class.php index bfc3ab727..9f5e838d2 100644 --- a/WEB-INF/lib/ttExpenseHelper.class.php +++ b/WEB-INF/lib/ttExpenseHelper.class.php @@ -123,11 +123,14 @@ static function getTotalForDay($date) { } // getItem - retrieves an entry from tt_expense_items table. - static function getItem($id, $user_id) { + static function getItem($id) { global $user; - $mdb2 = getConnection(); + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $client_field = null; if ($user->isPluginEnabled('cl')) $client_field = ", c.name as client_name"; @@ -137,17 +140,16 @@ static function getItem($id, $user_id) { if ($user->isPluginEnabled('cl')) $left_joins .= " left join tt_clients c on (ei.client_id = c.id)"; - $sql = "select ei.id, ei.date, ei.client_id, ei.project_id, ei.name, ei.cost, ei.invoice_id, ei.paid $client_field, p.name as project_name - from tt_expense_items ei - $left_joins - where ei.id = $id and ei.user_id = $user_id and ei.status = 1"; + $sql = "select ei.id, ei.date, ei.client_id, ei.project_id, ei.name, ei.cost, ei.invoice_id, ei.paid $client_field, p.name as project_name". + " from tt_expense_items ei $left_joins". + " where ei.id = $id and ei.group_id = $group_id and ei.org_id = $org_id and ei.user_id = $user_id and ei.status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if (!$res->numRows()) { return false; } if ($val = $res->fetchRow()) { - $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); + $val['cost'] = str_replace('.', $user->getDecimalMark(), $val['cost']); return $val; } } @@ -155,11 +157,15 @@ static function getItem($id, $user_id) { } // getItems - returns expense items for a user for a given date. - static function getItems($user_id, $date) { + static function getItems($date) { global $user; + $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; $result = array(); - $mdb2 = getConnection(); $client_field = null; if ($user->isPluginEnabled('cl')) @@ -170,16 +176,15 @@ static function getItems($user_id, $date) { if ($user->isPluginEnabled('cl')) $left_joins .= " left join tt_clients c on (ei.client_id = c.id)"; - $sql = "select ei.id as id $client_field, p.name as project, ei.name as item, ei.cost as cost, - ei.invoice_id from tt_expense_items ei - $left_joins - where ei.date = ".$mdb2->quote($date)." and ei.user_id = $user_id and ei.status = 1 - order by ei.id"; + $sql = "select ei.id as id $client_field, p.name as project, ei.name as item, ei.cost as cost,". + " ei.invoice_id from tt_expense_items ei $left_joins". + " where ei.date = ".$mdb2->quote($date)." and ei.user_id = $user_id". + " and ei.group_id = $group_id and ei.org_id = $org_id and ei.status = 1 order by ei.id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { - $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); + $val['cost'] = str_replace('.', $user->getDecimalMark(), $val['cost']); $result[] = $val; } } else return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 05f357bc6..747f72017 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4582 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4583 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expense_delete.php b/expense_delete.php index 32b9ab679..d5eccf79d 100644 --- a/expense_delete.php +++ b/expense_delete.php @@ -42,7 +42,7 @@ } $cl_id = (int)$request->getParameter('id'); // Get the expense item we are deleting. -$expense_item = ttExpenseHelper::getItem($cl_id, $user->getUser()); +$expense_item = ttExpenseHelper::getItem($cl_id); if (!$expense_item || $expense_item['invoice_id']) { // Prohibit deleting not ours or invoiced items. header('Location: access_denied.php'); diff --git a/expense_edit.php b/expense_edit.php index 80f861c8b..dd4a133bd 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -44,7 +44,7 @@ } $cl_id = (int)$request->getParameter('id'); // Get the expense item we are editing. -$expense_item = ttExpenseHelper::getItem($cl_id, $user->getUser()); +$expense_item = ttExpenseHelper::getItem($cl_id); if (!$expense_item || $expense_item['invoice_id']) { // Prohibit editing not ours or invoiced items. header('Location: access_denied.php'); diff --git a/expenses.php b/expenses.php index eea55d1c0..1c70a5a3d 100644 --- a/expenses.php +++ b/expenses.php @@ -212,7 +212,7 @@ } $smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); -$smarty->assign('expense_items', ttExpenseHelper::getItems($user->getUser(), $cl_date)); +$smarty->assign('expense_items', ttExpenseHelper::getItems($cl_date)); $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); diff --git a/mobile/expense_delete.php b/mobile/expense_delete.php index 93d6d59f1..c33f5232e 100644 --- a/mobile/expense_delete.php +++ b/mobile/expense_delete.php @@ -42,7 +42,7 @@ } $cl_id = (int)$request->getParameter('id'); // Get the expense item we are deleting. -$expense_item = ttExpenseHelper::getItem($cl_id, $user->getUser()); +$expense_item = ttExpenseHelper::getItem($cl_id); if (!$expense_item || $expense_item['invoice_id']) { // Prohibit deleting not ours or invoiced items. header('Location: access_denied.php'); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index fa00b5863..7938a4f1a 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -44,7 +44,7 @@ } $cl_id = (int)$request->getParameter('id'); // Get the expense item we are editing. -$expense_item = ttExpenseHelper::getItem($cl_id, $user->getUser()); +$expense_item = ttExpenseHelper::getItem($cl_id); if (!$expense_item || $expense_item['invoice_id']) { // Prohibit editing not ours or invoiced items. header('Location: access_denied.php'); diff --git a/mobile/expenses.php b/mobile/expenses.php index 656b20e05..15f914b24 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -218,7 +218,7 @@ $smarty->assign('next_date', $next_date); $smarty->assign('prev_date', $prev_date); $smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); -$smarty->assign('expense_items', ttExpenseHelper::getItems($user->getUser(), $cl_date)); +$smarty->assign('expense_items', ttExpenseHelper::getItems($cl_date)); $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); From b10bedad0cf854c9cb49bf0582b20869cb0c458d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 17:33:36 +0000 Subject: [PATCH 0508/1848] A bit more refactoring for subgroups. --- WEB-INF/lib/ttExpenseHelper.class.php | 6 +++--- WEB-INF/lib/ttGroup.class.php | 2 +- WEB-INF/lib/ttUser.class.php | 15 +++++++++++++++ WEB-INF/templates/expenses.tpl | 8 ++++---- WEB-INF/templates/footer.tpl | 2 +- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttExpenseHelper.class.php b/WEB-INF/lib/ttExpenseHelper.class.php index 9f5e838d2..0b202c6bf 100644 --- a/WEB-INF/lib/ttExpenseHelper.class.php +++ b/WEB-INF/lib/ttExpenseHelper.class.php @@ -110,14 +110,14 @@ static function getTotalForDay($date) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $sql = "select sum(cost) as sm from tt_expense_items". + $sql = "select sum(cost) as total from tt_expense_items". " where user_id = $user_id and group_id = $group_id and org_id = $org_id". " and date = ".$mdb2->quote($date)." and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - $val['sm'] = str_replace('.', $user->getDecimalMark(), $val['sm']); - return $val['sm']; + $val['total'] = str_replace('.', $user->getDecimalMark(), $val['total']); + return $val['total']; } return false; } diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index b7e78f959..b0c50eef5 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -94,8 +94,8 @@ function __construct($id, $org_id) { $this->allow_ip = $val['allow_ip']; $this->password_complexity = $val['password_complexity']; $this->group_name = $val['group_name']; - $this->currency = $val['currency']; */ + $this->currency = $val['currency']; $this->plugins = $val['plugins']; /* $this->lock_spec = $val['lock_spec']; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 5e359cd21..548d70ec7 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -179,6 +179,16 @@ function getDecimalMark() { return ($this->behalfGroup ? $this->behalfGroup->decimal_mark : $this->decimal_mark); } + // getDateFormat returns date format for active group. + function getDateFormat() { + return ($this->behalfGroup ? $this->behalfGroup->date_format : $this->date_format); + } + + // getTimeFormat returns time format for active group. + function getTimeFormat() { + return ($this->behalfGroup ? $this->behalfGroup->time_format : $this->time_format); + } + // getTrackingMode returns tracking mode for active group. function getTrackingMode() { return ($this->behalfGroup ? $this->behalfGroup->tracking_mode : $this->tracking_mode); @@ -189,6 +199,11 @@ function getRecordType() { return ($this->behalfGroup ? $this->behalfGroup->record_type : $this->record_type); } + // getCurrency returns currency string for active group. + function getCurrency() { + return ($this->behalfGroup ? $this->behalfGroup->currency : $this->currency); + } + // getPlugins returns plugins string for active group. function getPlugins() { return ($this->behalfGroup ? $this->behalfGroup->plugins : $this->plugins); diff --git a/WEB-INF/templates/expenses.tpl b/WEB-INF/templates/expenses.tpl index ed98bb575..8e1ef0a8d 100644 --- a/WEB-INF/templates/expenses.tpl +++ b/WEB-INF/templates/expenses.tpl @@ -86,7 +86,7 @@ function recalculateCost() { var comment_control = document.getElementById("item_name"); var cost_control = document.getElementById("cost"); - var replaceDecimalMark = ("." != "{$user->decimal_mark}"); + var replaceDecimalMark = ("." != "{$user->getDecimalMark()}"); // Calculate cost. var dropdown = document.getElementById("predefined_expense"); @@ -102,10 +102,10 @@ function recalculateCost() { else { var expenseCost = defined_expenses[dropdown.selectedIndex - 1][2]; if (replaceDecimalMark) - expenseCost = expenseCost.replace("{$user->decimal_mark}", "."); + expenseCost = expenseCost.replace("{$user->getDecimalMark()}", "."); var newCost = (quantity_control.value * expenseCost).toFixed(2); if (replaceDecimalMark) - newCost = newCost.replace(".", "{$user->decimal_mark}"); + newCost = newCost.replace(".", "{$user->getDecimalMark()}"); cost_control.value = newCost; } } @@ -201,7 +201,7 @@ function recalculateCost() {
- +
{$i18n.label.day_total}: {$user->currency|escape} {$day_total}{$i18n.label.day_total}: {$user->getCurrency()|escape} {$day_total}
{/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 747f72017..7654f5d8b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} {/if} @@ -18,7 +18,7 @@ {if $user->isPluginEnabled('cl')} {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} {/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7654f5d8b..e74a6a5e0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4583 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4584 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From f8292d356ef3ac53b2bb1183dd462f7c453c20e5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 20:13:57 +0000 Subject: [PATCH 0509/1848] More progress on refactoring expenses for subgroups. --- WEB-INF/lib/ttGroupHelper.class.php | 27 +++++++++++++++++++ .../lib/ttPredefinedExpenseHelper.class.php | 9 +++---- WEB-INF/lib/ttTeamHelper.class.php | 22 --------------- WEB-INF/templates/expense_delete.tpl | 4 +-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/expense_delete.tpl | 4 +-- expense_delete.php | 6 ++++- expense_edit.php | 14 +++++----- expenses.php | 3 +-- mobile/expense_delete.php | 6 ++++- mobile/expense_edit.php | 3 +-- mobile/expenses.php | 3 +-- predefined_expenses.php | 4 +-- 13 files changed, 59 insertions(+), 48 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 9f9f4a2f9..e5288a096 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -362,4 +362,31 @@ static function getInactiveProjects() } return $result; } + + // getPredefinedExpenses - obtains predefined expenses for a group. + static function getPredefinedExpenses() { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $result = array(); + $sql = "select id, name, cost from tt_predefined_expenses". + " where group_id = $group_id and org_id = $org_id"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + $decimal_mark = $user->getDecimalMark(); + $replaceDecimalMark = ('.' != $decimal_mark); + + while ($val = $res->fetchRow()) { + if ($replaceDecimalMark) + $val['cost'] = str_replace('.', $decimal_mark, $val['cost']); + $result[] = $val; + } + return $result; + } + return false; + } } diff --git a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php index 16dff2840..670e061c4 100644 --- a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php +++ b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php @@ -67,18 +67,17 @@ static function delete($id) { } // insert function inserts a new predefined expense into database. - static function insert($fields) - { + static function insert($fields) { global $user; - $mdb2 = getConnection(); $group_id = $user->getGroup(); $org_id = $user->org_id; + $name = $fields['name']; $cost = $fields['cost']; - if ('.' != $user->decimal_mark) - $cost = str_replace($user->decimal_mark, '.', $cost); + if ('.' != $user->getDecimalMark()) + $cost = str_replace($user->getDecimalMark, '.', $cost); $sql = "insert into tt_predefined_expenses (group_id, org_id, name, cost)". " values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($cost).")"; diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index e64bd6724..1e6263131 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -540,28 +540,6 @@ static function getExpenseItems($group_id) { return false; } - // getPredefinedExpenses - obtains predefined expenses for a group. - static function getPredefinedExpenses($group_id) { - global $user; - $replaceDecimalMark = ('.' != $user->decimal_mark); - - $mdb2 = getConnection(); - - $result = array(); - $sql = "select id, name, cost from tt_predefined_expenses where group_id = $group_id"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - if ($replaceDecimalMark) - $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); - $result[] = $val; - } - return $result; - } - return false; - } - // getNotifications - obtains notification descriptions for a group. static function getNotifications($group_id) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/expense_delete.tpl b/WEB-INF/templates/expense_delete.tpl index 52462c8d2..e2c1b6710 100644 --- a/WEB-INF/templates/expense_delete.tpl +++ b/WEB-INF/templates/expense_delete.tpl @@ -8,7 +8,7 @@ {$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$expense_item.client_name|escape}{$expense_item.project_name|escape}{$expense_item.name|escape}
- {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} {/if} @@ -18,7 +18,7 @@ {if $user->isPluginEnabled('cl')} {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} {/if} diff --git a/expense_delete.php b/expense_delete.php index d5eccf79d..c7031769b 100644 --- a/expense_delete.php +++ b/expense_delete.php @@ -48,6 +48,7 @@ header('Location: access_denied.php'); exit(); } +// End of access checks. if ($request->isPost()) { if ($request->getParameter('delete_button')) { // Delete button pressed. @@ -77,8 +78,11 @@ $form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); $form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); -$smarty->assign('expense_item', $expense_item); +$show_project = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); + $smarty->assign('forms', array($form->getName() => $form->toArray())); +$smarty->assign('expense_item', $expense_item); +$smarty->assign('show_project', $show_project); $smarty->assign('title', $i18n->get('title.delete_expense')); $smarty->assign('content_page_name', 'expense_delete.tpl'); $smarty->display('index.tpl'); diff --git a/expense_edit.php b/expense_edit.php index dd4a133bd..c42bddc8b 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -28,7 +28,6 @@ require_once('initialize.php'); import('form.Form'); -import('ttTeamHelper'); import('ttGroupHelper'); import('DateAndTime'); import('ttExpenseHelper'); @@ -50,9 +49,12 @@ header('Location: access_denied.php'); exit(); } +// End of access checks. $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); $confirm_save = $user->getConfigOption('confirm_save'); +$trackingMode = $user->getTrackingMode(); +$show_project = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; // Initialize variables. $cl_date = $cl_client = $cl_project = $cl_item_name = $cl_cost = null; @@ -65,7 +67,7 @@ if ($user->isPluginEnabled('ps')) $cl_paid = $request->getParameter('paid'); } else { - $cl_date = $item_date->toString($user->date_format); + $cl_date = $item_date->toString($user->getDateFormat()); $cl_client = $expense_item['client_id']; $cl_project = $expense_item['project_id']; $cl_item_name = $expense_item['name']; @@ -77,7 +79,7 @@ $form = new Form('expenseItemForm'); // Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { +if (MODE_TIME == $trackingMode && $user->isPluginEnabled('cl')) { $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', @@ -90,7 +92,7 @@ // Note: in other modes the client list is filtered to relevant clients only. See below. } -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { +if ($show_project) { // Dropdown for projects assigned to user. $project_list = $user->getAssignedProjects(); $form->addInput(array('type'=>'combobox', @@ -129,7 +131,7 @@ } } // If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->group_id); +$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); if ($predefined_expenses) { $form->addInput(array('type'=>'combobox', 'onchange'=>'recalculateCost();', @@ -159,7 +161,7 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) $err->add($i18n->get('error.client')); - if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { + if (MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode) { if (!$cl_project) $err->add($i18n->get('error.project')); } if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); diff --git a/expenses.php b/expenses.php index 1c70a5a3d..882e520b1 100644 --- a/expenses.php +++ b/expenses.php @@ -29,7 +29,6 @@ require_once('initialize.php'); import('form.Form'); import('ttUserHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); import('DateAndTime'); import('ttExpenseHelper'); @@ -145,7 +144,7 @@ } } // If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->group_id); +$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); if ($predefined_expenses) { $form->addInput(array('type'=>'combobox', 'onchange'=>'recalculateCost();', diff --git a/mobile/expense_delete.php b/mobile/expense_delete.php index c33f5232e..3bdc179d4 100644 --- a/mobile/expense_delete.php +++ b/mobile/expense_delete.php @@ -48,6 +48,7 @@ header('Location: access_denied.php'); exit(); } +// End of access checks. if ($request->isPost()) { if ($request->getParameter('delete_button')) { // Delete button pressed. @@ -77,8 +78,11 @@ $form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); $form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); -$smarty->assign('expense_item', $expense_item); +$show_project = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); + $smarty->assign('forms', array($form->getName() => $form->toArray())); +$smarty->assign('expense_item', $expense_item); +$smarty->assign('show_project', $show_project); $smarty->assign('title', $i18n->get('title.delete_expense')); $smarty->assign('content_page_name', 'mobile/expense_delete.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index 7938a4f1a..0f657973c 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -28,7 +28,6 @@ require_once('../initialize.php'); import('form.Form'); -import('ttTeamHelper'); import('ttGroupHelper'); import('DateAndTime'); import('ttExpenseHelper'); @@ -126,7 +125,7 @@ } } // If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->group_id); +$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); if ($predefined_expenses) { $form->addInput(array('type'=>'combobox', 'onchange'=>'recalculateCost();', diff --git a/mobile/expenses.php b/mobile/expenses.php index 15f914b24..84d29738a 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -29,7 +29,6 @@ require_once('../initialize.php'); import('form.Form'); import('ttUserHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); import('DateAndTime'); import('ttExpenseHelper'); @@ -149,7 +148,7 @@ } } // If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttTeamHelper::getPredefinedExpenses($user->group_id); +$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); if ($predefined_expenses) { $form->addInput(array('type'=>'combobox', 'onchange'=>'recalculateCost();', diff --git a/predefined_expenses.php b/predefined_expenses.php index 88ac44d70..99c2c899f 100644 --- a/predefined_expenses.php +++ b/predefined_expenses.php @@ -28,7 +28,7 @@ require_once('initialize.php'); import('form.Form'); -import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_advanced_settings')) { @@ -50,7 +50,7 @@ } } else { $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - $predefinedExpenses = ttTeamHelper::getPredefinedExpenses($user->group_id); + $predefinedExpenses = ttGroupHelper::getPredefinedExpenses(); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); From d24d7483854015ce95488831aed43255261a7baf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 20:51:54 +0000 Subject: [PATCH 0510/1848] Refactored ttPredefinedExpenseHelper class. --- .../lib/ttPredefinedExpenseHelper.class.php | 34 ++++++++++--------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php index 670e061c4..8ec8ccfee 100644 --- a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php +++ b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php @@ -31,21 +31,21 @@ class ttPredefinedExpenseHelper { // get - gets predefined expense details. - static function get($id) - { + static function get($id) { global $user; - $replaceDecimalMark = ('.' != $user->decimal_mark); - $mdb2 = getConnection(); - $sql = "select id, name, cost from tt_predefined_expenses - where id = $id and group_id = ".$user->getGroup(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, name, cost from tt_predefined_expenses". + " where id = $id and group_id = $group_id and org_id = $org_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); if ($val && $val['id']) { - if ($replaceDecimalMark) - $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); + if ('.' != $user->getDecimalMark()) + $val['cost'] = str_replace('.', $user->getDecimalMark(), $val['cost']); return $val; } } @@ -55,10 +55,13 @@ static function get($id) // delete - deletes a predefined expense from tt_predefined_expenses table. static function delete($id) { global $user; - $mdb2 = getConnection(); - $sql = "delete from tt_predefined_expenses where id = $id and group_id = ".$user->getGroup(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "delete from tt_predefined_expenses". + " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -77,7 +80,7 @@ static function insert($fields) { $name = $fields['name']; $cost = $fields['cost']; if ('.' != $user->getDecimalMark()) - $cost = str_replace($user->getDecimalMark, '.', $cost); + $cost = str_replace($user->getDecimalMark(), '.', $cost); $sql = "insert into tt_predefined_expenses (group_id, org_id, name, cost)". " values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($cost).")"; @@ -89,19 +92,18 @@ static function insert($fields) { } // update function - updates a predefined expense in database. - static function update($fields) - { + static function update($fields) { global $user; - $mdb2 = getConnection(); $group_id = $user->getGroup(); $org_id = $user->org_id; + $predefined_expense_id = (int) $fields['id']; $name = $fields['name']; $cost = $fields['cost']; - if ('.' != $user->decimal_mark) - $cost = str_replace($user->decimal_mark, '.', $cost); + if ('.' != $user->getDecimalMark()) + $cost = str_replace($user->getDecimalMark(), '.', $cost); $sql = "update tt_predefined_expenses set name = ".$mdb2->quote($name).", cost = ".$mdb2->quote($cost). " where id = $predefined_expense_id and group_id = $group_id and org_id = $org_id"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e74a6a5e0..3af107e9e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4584 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4585 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/expense_delete.tpl b/WEB-INF/templates/mobile/expense_delete.tpl index bfd6dbc17..cbd75aed4 100644 --- a/WEB-INF/templates/mobile/expense_delete.tpl +++ b/WEB-INF/templates/mobile/expense_delete.tpl @@ -8,7 +8,7 @@ {$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$expense_item.client_name|escape}{$expense_item.project_name|escape}{$expense_item.name|escape}
-
 Anuko Time Tracker 1.18.29.4585 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4586 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 7b271fc399126b3dc32aadb30cb839241668cead Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 21:49:24 +0000 Subject: [PATCH 0511/1848] More refactoring for subgroups. --- WEB-INF/lib/form/DateField.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- expense_edit.php | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/form/DateField.class.php b/WEB-INF/lib/form/DateField.class.php index 9016dff0c..f1487d04b 100644 --- a/WEB-INF/lib/form/DateField.class.php +++ b/WEB-INF/lib/form/DateField.class.php @@ -48,7 +48,7 @@ function localize() { global $user; global $i18n; - $this->mDateObj->setFormat($user->date_format); + $this->mDateObj->setFormat($user->getDateFormat()); $this->mMonthNames = $i18n->monthNames; $this->mWeekDayShortNames = $i18n->weekdayShortNames; @@ -56,7 +56,7 @@ function localize() { $this->lCalendarButtons['today'] = $i18n->get('label.today'); $this->lCalendarButtons['close'] = $i18n->get('button.close'); - $this->mDateFormat = $user->date_format; + $this->mDateFormat = $user->getDateFormat(); $this->mWeekStartDay = $user->week_start; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3af107e9e..1ed3fe62f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4586 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4587 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expense_edit.php b/expense_edit.php index c42bddc8b..667d03468 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -161,18 +161,17 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) $err->add($i18n->get('error.client')); - if (MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } + if ($show_project && !$cl_project) + $err->add($i18n->get('error.project')); if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); // This is a new date for the expense item. - $new_date = new DateAndTime($user->date_format, $cl_date); + $new_date = new DateAndTime($user->getDateFormat(), $cl_date); // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->getConfigOption('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); From 80481c14be5a7ac9e4d386ad7b3ec71d7628e03b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 Dec 2018 22:07:41 +0000 Subject: [PATCH 0512/1848] Fixed a check if ldap expension is loaded as per PR #68 by Frank Giesecke. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1ed3fe62f..6d454f1f4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4587 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4588 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 653d13a1f..67fac3182 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -124,7 +124,7 @@ function setChange($sql) { // Check ldap extension. if (AUTH_MODULE == 'ldap') { - if (extension_loaded('ldap_')) { + if (extension_loaded('ldap')) { echo('ldap PHP extension is loaded.
'); } else { echo('Error: ldap PHP extension is not loaded. It is required for LDAP authentication.
'); From 2a7ba96739989c4ae4c8554a37aef62b7066f1ea Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 Dec 2018 13:19:26 +0000 Subject: [PATCH 0513/1848] Another try to fix tt_client_project_binds. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + expenses.php | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6d454f1f4..db9ec58ce 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4588 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4589 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 67fac3182..c9dcc1857 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1039,6 +1039,7 @@ function setChange($sql) { setChange("UPDATE `tt_site_config` SET param_value = '1.18.24', modified = now() where param_name = 'version_db' and param_value = '1.18.23'"); setChange("ALTER TABLE `tt_groups` ADD COLUMN `description` varchar(255) default NULL after `name`"); setChange("UPDATE `tt_site_config` SET param_value = '1.18.26', modified = now() where param_name = 'version_db' and param_value = '1.18.24'"); + setChange("update `tt_client_project_binds` cpb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.26') inner join `tt_clients` c on c.id = cpb.client_id set cpb.group_id = c.group_id, cpb.org_id = c.org_id where cpb.org_id is null"); } if ($_POST["cleanup"]) { diff --git a/expenses.php b/expenses.php index 882e520b1..e459c37c5 100644 --- a/expenses.php +++ b/expenses.php @@ -50,6 +50,7 @@ header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. exit(); } +// End of access checks. // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); From ec990c16140c0a4793c7510e684e7617c5d5306d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 Dec 2018 15:20:58 +0000 Subject: [PATCH 0514/1848] Renamed a function and made error output red. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1078 +++++++++++++++++----------------- 2 files changed, 540 insertions(+), 540 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index db9ec58ce..d7903e75c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 99e8d0eee..20a0db7cb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4589 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4590 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index c9dcc1857..55d09be0a 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -34,19 +34,19 @@ import('ttRoleHelper'); import('ttOrgHelper'); -// setChange - executes an sql statement. TODO: rename this function to something better. -// Better yet, redo the entire thing and make an installer. -function setChange($sql) { +// TODO: we need an installer. + +// ttExecute - executes an sql statement and prints either an error or a success message. +function ttExecute($sql) { print "
".$sql."
"; $mdb2 = getConnection(); $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) - print "error: ".$affected->getMessage()."
"; + print 'Error: '.$affected->getMessage().'.
'; else - print "successful update
\n"; + print "Successful update.
\n"; } - if ($request->isGet()) { echo('

Environment Checks

'); @@ -182,37 +182,37 @@ function setChange($sql) { foreach ($queries as $query) { $query = trim($query); if (strlen($query)>0) { - setChange($query); + ttExecute($query); } } } } if ($_POST["convert5to7"]) { - setChange("alter table `activity_log` CHANGE al_comment al_comment text"); - setChange("CREATE TABLE `sysconfig` (`sysc_id` int(11) unsigned NOT NULL auto_increment,`sysc_name` varchar(32) NOT NULL default '',`sysc_value` varchar(70) default NULL, PRIMARY KEY (`sysc_id`), UNIQUE KEY `sysc_id` (`sysc_id`), UNIQUE KEY `sysc_name` (`sysc_name`))"); - setChange("alter table `companies` add c_locktime int(4) default -1"); - setChange("alter table `activity_log` add al_billable tinyint(4) default 0"); - setChange("alter table `sysconfig` drop INDEX `sysc_name`"); - setChange("alter table `sysconfig` add sysc_id_u int(4)"); - setChange("alter table `report_filter_set` add rfs_billable VARCHAR(10)"); - setChange("ALTER TABLE clients MODIFY clnt_id int(11) NOT NULL AUTO_INCREMENT"); - setChange("ALTER TABLE `users` ADD `u_show_pie` smallint(2) DEFAULT '1'"); - setChange("alter table `users` ADD `u_pie_mode` smallint(2) DEFAULT '1'"); - setChange("alter table users drop `u_aprojects`"); + ttExecute("alter table `activity_log` CHANGE al_comment al_comment text"); + ttExecute("CREATE TABLE `sysconfig` (`sysc_id` int(11) unsigned NOT NULL auto_increment,`sysc_name` varchar(32) NOT NULL default '',`sysc_value` varchar(70) default NULL, PRIMARY KEY (`sysc_id`), UNIQUE KEY `sysc_id` (`sysc_id`), UNIQUE KEY `sysc_name` (`sysc_name`))"); + ttExecute("alter table `companies` add c_locktime int(4) default -1"); + ttExecute("alter table `activity_log` add al_billable tinyint(4) default 0"); + ttExecute("alter table `sysconfig` drop INDEX `sysc_name`"); + ttExecute("alter table `sysconfig` add sysc_id_u int(4)"); + ttExecute("alter table `report_filter_set` add rfs_billable VARCHAR(10)"); + ttExecute("ALTER TABLE clients MODIFY clnt_id int(11) NOT NULL AUTO_INCREMENT"); + ttExecute("ALTER TABLE `users` ADD `u_show_pie` smallint(2) DEFAULT '1'"); + ttExecute("alter table `users` ADD `u_pie_mode` smallint(2) DEFAULT '1'"); + ttExecute("alter table users drop `u_aprojects`"); } if ($_POST["convert7to133"]) { - setChange("ALTER TABLE users ADD COLUMN u_lang VARCHAR(20) DEFAULT NULL"); - setChange("ALTER TABLE users ADD COLUMN u_email VARCHAR(100) DEFAULT NULL"); - setChange("ALTER TABLE `activity_log` drop `al_proof`"); - setChange("ALTER TABLE `activity_log` drop `al_charge`"); - setChange("ALTER TABLE `activities` drop `a_project_id`"); - setChange("DROP TABLE `activity_status_list`"); - setChange("DROP TABLE `project_status_list`"); - setChange("DROP TABLE `user_status_list`"); - setChange("DROP TABLE `companies_c_id_seq`"); - setChange("ALTER TABLE projects ADD COLUMN p_activities TEXT"); + ttExecute("ALTER TABLE users ADD COLUMN u_lang VARCHAR(20) DEFAULT NULL"); + ttExecute("ALTER TABLE users ADD COLUMN u_email VARCHAR(100) DEFAULT NULL"); + ttExecute("ALTER TABLE `activity_log` drop `al_proof`"); + ttExecute("ALTER TABLE `activity_log` drop `al_charge`"); + ttExecute("ALTER TABLE `activities` drop `a_project_id`"); + ttExecute("DROP TABLE `activity_status_list`"); + ttExecute("DROP TABLE `project_status_list`"); + ttExecute("DROP TABLE `user_status_list`"); + ttExecute("DROP TABLE `companies_c_id_seq`"); + ttExecute("ALTER TABLE projects ADD COLUMN p_activities TEXT"); } // The update_projects function updates p_activities field in the projects table so that we could @@ -255,9 +255,9 @@ function setChange($sql) { } if ($_POST["convert133to1340"]) { - setChange("ALTER TABLE companies ADD COLUMN c_show_pie smallint(2) DEFAULT 1"); - setChange("ALTER TABLE companies ADD COLUMN c_pie_mode smallint(2) DEFAULT 1"); - setChange("ALTER TABLE companies ADD COLUMN c_lang varchar(20) default NULL"); + ttExecute("ALTER TABLE companies ADD COLUMN c_show_pie smallint(2) DEFAULT 1"); + ttExecute("ALTER TABLE companies ADD COLUMN c_pie_mode smallint(2) DEFAULT 1"); + ttExecute("ALTER TABLE companies ADD COLUMN c_lang varchar(20) default NULL"); } // The update_companies function sets up c_show_pie, c_pie_mode, and c_lang @@ -290,107 +290,107 @@ function setChange($sql) { } if ($_POST["convert1340to1485"]) { - setChange("ALTER TABLE users DROP u_show_pie"); - setChange("ALTER TABLE users DROP u_pie_mode"); - setChange("ALTER TABLE users DROP u_lang"); - setChange("ALTER TABLE `users` modify u_login varchar(100) NOT NULL"); - setChange("ALTER TABLE `users` modify u_active smallint(6) default '1'"); - setChange("drop index u_login_idx on users"); - setChange("create unique index u_login_idx on users(u_login, u_active)"); - setChange("ALTER TABLE companies MODIFY `c_lang` varchar(20) NOT NULL default 'en'"); - setChange("ALTER TABLE companies ADD COLUMN `c_date_format` varchar(20) NOT NULL default '%Y-%m-%d'"); - setChange("ALTER TABLE companies ADD COLUMN `c_time_format` varchar(20) NOT NULL default '%H:%M'"); - setChange("ALTER TABLE companies ADD COLUMN `c_week_start` smallint(2) NOT NULL DEFAULT '0'"); - setChange("ALTER TABLE clients MODIFY `clnt_status` smallint(6) default '1'"); - setChange("create unique index clnt_name_idx on clients(clnt_id_um, clnt_name, clnt_status)"); - setChange("ALTER TABLE projects modify p_status smallint(6) default '1'"); - setChange("update projects set p_status = NULL where p_status = 1000"); - setChange("drop index p_manager_idx on projects"); - setChange("create unique index p_name_idx on projects(p_manager_id, p_name, p_status)"); - setChange("ALTER TABLE activities modify a_status smallint(6) default '1'"); - setChange("update activities set a_status = NULL where a_status = 1000"); - setChange("drop index a_manager_idx on activities"); - setChange("create unique index a_name_idx on activities(a_manager_id, a_name, a_status)"); - setChange("RENAME TABLE companies TO teams"); - setChange("RENAME TABLE teams TO att_teams"); - setChange("ALTER TABLE att_teams CHANGE c_id id int(11) NOT NULL auto_increment"); - setChange("RENAME TABLE users TO att_users"); - setChange("update att_users set u_company_id = 0 where u_company_id is NULL"); - setChange("ALTER TABLE att_users CHANGE u_company_id team_id int(11) NOT NULL"); - setChange("RENAME TABLE att_teams TO tt_teams"); - setChange("RENAME TABLE att_users TO tt_users"); - setChange("ALTER TABLE tt_teams CHANGE c_name name varchar(80) NOT NULL"); - setChange("ALTER TABLE `tt_teams` drop `c_www`"); - setChange("ALTER TABLE `tt_teams` MODIFY `name` varchar(80) default NULL"); - setChange("ALTER TABLE clients ADD COLUMN `your_name` varchar(255) default NULL"); - setChange("ALTER TABLE tt_teams ADD COLUMN `address` varchar(255) default NULL"); - setChange("ALTER TABLE invoice_header ADD COLUMN `client_name` varchar(255) default NULL"); - setChange("ALTER TABLE invoice_header ADD COLUMN `client_addr` varchar(255) default NULL"); - setChange("ALTER TABLE report_filter_set ADD COLUMN `rfs_cb_cost` tinyint(4) default '0'"); - setChange("ALTER TABLE activity_log DROP primary key"); - setChange("ALTER TABLE activity_log ADD COLUMN `id` bigint NOT NULL auto_increment primary key"); - setChange("CREATE TABLE `tt_custom_fields` (`id` int(11) NOT NULL auto_increment, `team_id` int(11) NOT NULL, `type` tinyint(4) NOT NULL default '0', `label` varchar(32) NOT NULL default '', PRIMARY KEY (`id`))"); - setChange("CREATE TABLE `tt_custom_field_options` (`id` int(11) NOT NULL auto_increment, `field_id` int(11) NOT NULL, `value` varchar(32) NOT NULL default '', PRIMARY KEY (`id`))"); - setChange("CREATE TABLE `tt_custom_field_log` (`id` bigint NOT NULL auto_increment, `al_id` bigint NOT NULL, `field_id` int(11) NOT NULL, `value` varchar(255) default NULL, PRIMARY KEY (`id`))"); - setChange("ALTER TABLE tt_users DROP u_level"); - setChange("ALTER TABLE tt_custom_fields ADD COLUMN `status` tinyint(4) default '1'"); - setChange("ALTER TABLE report_filter_set ADD COLUMN `rfs_cb_cf_1` tinyint(4) default '0'"); - setChange("ALTER TABLE tt_teams ADD COLUMN `plugins` varchar(255) default NULL"); - setChange("ALTER TABLE tt_teams MODIFY c_locktime int(4) default '0'"); - setChange("ALTER TABLE clients DROP your_name"); - setChange("ALTER TABLE clients DROP clnt_addr_your"); - setChange("ALTER TABLE `tt_custom_fields` ADD COLUMN `required` tinyint(4) default '0'"); - setChange("ALTER TABLE tt_teams DROP c_pie_mode"); - setChange("RENAME TABLE report_filter_set TO tt_fav_reports"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_id id int(11) unsigned NOT NULL auto_increment"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_name name varchar(200) NOT NULL"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_id_u user_id int(11) NOT NULL"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_id_p project_id int(11) default NULL"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_id_a task_id int(11) default NULL"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_users users text default NULL"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_period period tinyint(4) default NULL"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_period_start period_start date default NULL"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_period_finish period_end date default NULL"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_cb_project show_project tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_cb_activity show_task tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_cb_note show_note tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_cb_start show_start tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_cb_finish show_end tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_cb_duration show_duration tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_cb_cost show_cost tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_cb_cf_1 show_custom_field_1 tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_cb_idle show_empty_days tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_cb_totals_only show_totals_only tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_groupby group_by varchar(20) default NULL"); - setChange("ALTER TABLE tt_fav_reports CHANGE rfs_billable billable tinyint(4) default NULL"); - setChange("ALTER TABLE projects CHANGE p_activities tasks text default NULL"); - setChange("ALTER TABLE tt_teams CHANGE c_currency currency varchar(7) default NULL"); - setChange("ALTER TABLE tt_teams CHANGE c_locktime locktime int(4) default '0'"); - setChange("ALTER TABLE tt_teams CHANGE c_show_pie show_pie smallint(2) DEFAULT '1'"); - setChange("ALTER TABLE tt_teams CHANGE c_lang lang varchar(10) NOT NULL default 'en'"); - setChange("ALTER TABLE tt_teams CHANGE c_date_format date_format varchar(20) NOT NULL default '%Y-%m-%d'"); - setChange("ALTER TABLE tt_teams CHANGE c_time_format time_format varchar(20) NOT NULL default '%H:%M'"); - setChange("ALTER TABLE tt_teams CHANGE c_week_start week_start smallint(2) NOT NULL DEFAULT '0'"); - setChange("ALTER TABLE tt_users CHANGE u_id id int(11) NOT NULL auto_increment"); - setChange("ALTER TABLE tt_users CHANGE u_timestamp timestamp timestamp NOT NULL"); - setChange("ALTER TABLE tt_users CHANGE u_login login varchar(50) NOT NULL"); - setChange("drop index u_login_idx on tt_users"); - setChange("create unique index login_idx on tt_users(login, u_active)"); - setChange("ALTER TABLE tt_users CHANGE u_password password varchar(50) default NULL"); - setChange("ALTER TABLE tt_users CHANGE u_name name varchar(100) default NULL"); - setChange("ALTER TABLE tt_users CHANGE u_email email varchar(100) default NULL"); - setChange("ALTER TABLE tt_users CHANGE u_rate rate float(6,2) NOT NULL default '0.00'"); - setChange("update tt_users set u_active = NULL where u_active = 1000"); - setChange("ALTER TABLE tt_users CHANGE u_active status tinyint(4) default '1'"); - setChange("ALTER TABLE tt_teams ADD COLUMN status tinyint(4) default '1'"); - setChange("ALTER TABLE tt_users ADD COLUMN role int(11) default '4'"); - setChange("update tt_users set role = 1024 where login = 'admin'"); - setChange("update tt_users set role = 68 where u_comanager = 1"); - setChange("update tt_users set role = 324 where u_manager_id is null and login != 'admin'"); - setChange("ALTER TABLE user_bind CHANGE ub_checked status tinyint(4) default '1'"); - setChange("ALTER TABLE activities ADD COLUMN team_id int(11) NOT NULL"); - setChange("ALTER TABLE clients ADD COLUMN team_id int(11) NOT NULL"); - setChange("ALTER TABLE projects ADD COLUMN team_id int(11) NOT NULL"); + ttExecute("ALTER TABLE users DROP u_show_pie"); + ttExecute("ALTER TABLE users DROP u_pie_mode"); + ttExecute("ALTER TABLE users DROP u_lang"); + ttExecute("ALTER TABLE `users` modify u_login varchar(100) NOT NULL"); + ttExecute("ALTER TABLE `users` modify u_active smallint(6) default '1'"); + ttExecute("drop index u_login_idx on users"); + ttExecute("create unique index u_login_idx on users(u_login, u_active)"); + ttExecute("ALTER TABLE companies MODIFY `c_lang` varchar(20) NOT NULL default 'en'"); + ttExecute("ALTER TABLE companies ADD COLUMN `c_date_format` varchar(20) NOT NULL default '%Y-%m-%d'"); + ttExecute("ALTER TABLE companies ADD COLUMN `c_time_format` varchar(20) NOT NULL default '%H:%M'"); + ttExecute("ALTER TABLE companies ADD COLUMN `c_week_start` smallint(2) NOT NULL DEFAULT '0'"); + ttExecute("ALTER TABLE clients MODIFY `clnt_status` smallint(6) default '1'"); + ttExecute("create unique index clnt_name_idx on clients(clnt_id_um, clnt_name, clnt_status)"); + ttExecute("ALTER TABLE projects modify p_status smallint(6) default '1'"); + ttExecute("update projects set p_status = NULL where p_status = 1000"); + ttExecute("drop index p_manager_idx on projects"); + ttExecute("create unique index p_name_idx on projects(p_manager_id, p_name, p_status)"); + ttExecute("ALTER TABLE activities modify a_status smallint(6) default '1'"); + ttExecute("update activities set a_status = NULL where a_status = 1000"); + ttExecute("drop index a_manager_idx on activities"); + ttExecute("create unique index a_name_idx on activities(a_manager_id, a_name, a_status)"); + ttExecute("RENAME TABLE companies TO teams"); + ttExecute("RENAME TABLE teams TO att_teams"); + ttExecute("ALTER TABLE att_teams CHANGE c_id id int(11) NOT NULL auto_increment"); + ttExecute("RENAME TABLE users TO att_users"); + ttExecute("update att_users set u_company_id = 0 where u_company_id is NULL"); + ttExecute("ALTER TABLE att_users CHANGE u_company_id team_id int(11) NOT NULL"); + ttExecute("RENAME TABLE att_teams TO tt_teams"); + ttExecute("RENAME TABLE att_users TO tt_users"); + ttExecute("ALTER TABLE tt_teams CHANGE c_name name varchar(80) NOT NULL"); + ttExecute("ALTER TABLE `tt_teams` drop `c_www`"); + ttExecute("ALTER TABLE `tt_teams` MODIFY `name` varchar(80) default NULL"); + ttExecute("ALTER TABLE clients ADD COLUMN `your_name` varchar(255) default NULL"); + ttExecute("ALTER TABLE tt_teams ADD COLUMN `address` varchar(255) default NULL"); + ttExecute("ALTER TABLE invoice_header ADD COLUMN `client_name` varchar(255) default NULL"); + ttExecute("ALTER TABLE invoice_header ADD COLUMN `client_addr` varchar(255) default NULL"); + ttExecute("ALTER TABLE report_filter_set ADD COLUMN `rfs_cb_cost` tinyint(4) default '0'"); + ttExecute("ALTER TABLE activity_log DROP primary key"); + ttExecute("ALTER TABLE activity_log ADD COLUMN `id` bigint NOT NULL auto_increment primary key"); + ttExecute("CREATE TABLE `tt_custom_fields` (`id` int(11) NOT NULL auto_increment, `team_id` int(11) NOT NULL, `type` tinyint(4) NOT NULL default '0', `label` varchar(32) NOT NULL default '', PRIMARY KEY (`id`))"); + ttExecute("CREATE TABLE `tt_custom_field_options` (`id` int(11) NOT NULL auto_increment, `field_id` int(11) NOT NULL, `value` varchar(32) NOT NULL default '', PRIMARY KEY (`id`))"); + ttExecute("CREATE TABLE `tt_custom_field_log` (`id` bigint NOT NULL auto_increment, `al_id` bigint NOT NULL, `field_id` int(11) NOT NULL, `value` varchar(255) default NULL, PRIMARY KEY (`id`))"); + ttExecute("ALTER TABLE tt_users DROP u_level"); + ttExecute("ALTER TABLE tt_custom_fields ADD COLUMN `status` tinyint(4) default '1'"); + ttExecute("ALTER TABLE report_filter_set ADD COLUMN `rfs_cb_cf_1` tinyint(4) default '0'"); + ttExecute("ALTER TABLE tt_teams ADD COLUMN `plugins` varchar(255) default NULL"); + ttExecute("ALTER TABLE tt_teams MODIFY c_locktime int(4) default '0'"); + ttExecute("ALTER TABLE clients DROP your_name"); + ttExecute("ALTER TABLE clients DROP clnt_addr_your"); + ttExecute("ALTER TABLE `tt_custom_fields` ADD COLUMN `required` tinyint(4) default '0'"); + ttExecute("ALTER TABLE tt_teams DROP c_pie_mode"); + ttExecute("RENAME TABLE report_filter_set TO tt_fav_reports"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_id id int(11) unsigned NOT NULL auto_increment"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_name name varchar(200) NOT NULL"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_id_u user_id int(11) NOT NULL"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_id_p project_id int(11) default NULL"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_id_a task_id int(11) default NULL"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_users users text default NULL"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_period period tinyint(4) default NULL"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_period_start period_start date default NULL"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_period_finish period_end date default NULL"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_cb_project show_project tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_cb_activity show_task tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_cb_note show_note tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_cb_start show_start tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_cb_finish show_end tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_cb_duration show_duration tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_cb_cost show_cost tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_cb_cf_1 show_custom_field_1 tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_cb_idle show_empty_days tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_cb_totals_only show_totals_only tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_groupby group_by varchar(20) default NULL"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE rfs_billable billable tinyint(4) default NULL"); + ttExecute("ALTER TABLE projects CHANGE p_activities tasks text default NULL"); + ttExecute("ALTER TABLE tt_teams CHANGE c_currency currency varchar(7) default NULL"); + ttExecute("ALTER TABLE tt_teams CHANGE c_locktime locktime int(4) default '0'"); + ttExecute("ALTER TABLE tt_teams CHANGE c_show_pie show_pie smallint(2) DEFAULT '1'"); + ttExecute("ALTER TABLE tt_teams CHANGE c_lang lang varchar(10) NOT NULL default 'en'"); + ttExecute("ALTER TABLE tt_teams CHANGE c_date_format date_format varchar(20) NOT NULL default '%Y-%m-%d'"); + ttExecute("ALTER TABLE tt_teams CHANGE c_time_format time_format varchar(20) NOT NULL default '%H:%M'"); + ttExecute("ALTER TABLE tt_teams CHANGE c_week_start week_start smallint(2) NOT NULL DEFAULT '0'"); + ttExecute("ALTER TABLE tt_users CHANGE u_id id int(11) NOT NULL auto_increment"); + ttExecute("ALTER TABLE tt_users CHANGE u_timestamp timestamp timestamp NOT NULL"); + ttExecute("ALTER TABLE tt_users CHANGE u_login login varchar(50) NOT NULL"); + ttExecute("drop index u_login_idx on tt_users"); + ttExecute("create unique index login_idx on tt_users(login, u_active)"); + ttExecute("ALTER TABLE tt_users CHANGE u_password password varchar(50) default NULL"); + ttExecute("ALTER TABLE tt_users CHANGE u_name name varchar(100) default NULL"); + ttExecute("ALTER TABLE tt_users CHANGE u_email email varchar(100) default NULL"); + ttExecute("ALTER TABLE tt_users CHANGE u_rate rate float(6,2) NOT NULL default '0.00'"); + ttExecute("update tt_users set u_active = NULL where u_active = 1000"); + ttExecute("ALTER TABLE tt_users CHANGE u_active status tinyint(4) default '1'"); + ttExecute("ALTER TABLE tt_teams ADD COLUMN status tinyint(4) default '1'"); + ttExecute("ALTER TABLE tt_users ADD COLUMN role int(11) default '4'"); + ttExecute("update tt_users set role = 1024 where login = 'admin'"); + ttExecute("update tt_users set role = 68 where u_comanager = 1"); + ttExecute("update tt_users set role = 324 where u_manager_id is null and login != 'admin'"); + ttExecute("ALTER TABLE user_bind CHANGE ub_checked status tinyint(4) default '1'"); + ttExecute("ALTER TABLE activities ADD COLUMN team_id int(11) NOT NULL"); + ttExecute("ALTER TABLE clients ADD COLUMN team_id int(11) NOT NULL"); + ttExecute("ALTER TABLE projects ADD COLUMN team_id int(11) NOT NULL"); } // The update_to_team_id function sets team_id field projects, activities, and clients tables. @@ -492,127 +492,127 @@ function setChange($sql) { } if ($_POST["convert1485to1579"]) { - setChange("ALTER TABLE tt_fav_reports MODIFY id int(11) NOT NULL auto_increment"); - setChange("RENAME TABLE clients TO tt_clients"); - setChange("ALTER TABLE tt_clients CHANGE clnt_id id int(11) NOT NULL AUTO_INCREMENT"); - setChange("ALTER TABLE tt_clients CHANGE clnt_status status tinyint(4) default '1'"); - setChange("ALTER TABLE tt_clients DROP clnt_id_um"); - setChange("ALTER TABLE tt_clients CHANGE clnt_name name varchar(80) NOT NULL"); - setChange("drop index clnt_name_idx on tt_clients"); - setChange("drop index client_name_idx on tt_clients"); - setChange("create unique index client_name_idx on tt_clients(team_id, name, status)"); - setChange("ALTER TABLE tt_teams ADD COLUMN `timestamp` timestamp NOT NULL"); - setChange("ALTER TABLE tt_clients CHANGE clnt_addr_cust address varchar(255) default NULL"); - setChange("ALTER TABLE tt_clients DROP clnt_discount"); - setChange("ALTER TABLE tt_clients DROP clnt_comment"); - setChange("ALTER TABLE tt_clients DROP clnt_fsubtotals"); - setChange("ALTER TABLE tt_clients CHANGE clnt_tax tax float(6,2) NOT NULL default '0.00'"); - setChange("ALTER TABLE activity_log ADD COLUMN client_id int(11) default NULL"); - setChange("ALTER TABLE tt_teams DROP show_pie"); - setChange("ALTER TABLE tt_fav_reports CHANGE group_by sort_by varchar(20) default 'date'"); - setChange("RENAME TABLE tmp_refs TO tt_tmp_refs"); - setChange("ALTER TABLE tt_tmp_refs CHANGE tr_created timestamp timestamp NOT NULL"); - setChange("ALTER TABLE tt_tmp_refs CHANGE tr_code ref char(32) NOT NULL default ''"); - setChange("ALTER TABLE tt_tmp_refs CHANGE tr_userid user_id int(11) NOT NULL"); - setChange("RENAME TABLE projects TO tt_projects"); - setChange("ALTER TABLE tt_projects CHANGE p_id id int(11) NOT NULL auto_increment"); - setChange("ALTER TABLE tt_projects DROP p_timestamp"); - setChange("ALTER TABLE tt_projects CHANGE p_name name varchar(80) NOT NULL"); - setChange("ALTER TABLE tt_projects CHANGE p_status status tinyint(4) default '1'"); - setChange("drop index p_name_idx on tt_projects"); - setChange("create unique index project_idx on tt_projects(team_id, name, status)"); - setChange("RENAME TABLE activities TO tt_tasks"); - setChange("ALTER TABLE tt_tasks CHANGE a_id id int(11) NOT NULL auto_increment"); - setChange("ALTER TABLE tt_tasks DROP a_timestamp"); - setChange("ALTER TABLE tt_tasks CHANGE a_name name varchar(80) NOT NULL"); - setChange("ALTER TABLE tt_tasks CHANGE a_status status tinyint(4) default '1'"); - setChange("drop index a_name_idx on tt_tasks"); - setChange("create unique index task_idx on tt_tasks(team_id, name, status)"); - setChange("RENAME TABLE invoice_header TO tt_invoice_headers"); - setChange("ALTER TABLE tt_invoice_headers CHANGE ih_user_id user_id int(11) NOT NULL"); - setChange("ALTER TABLE tt_invoice_headers CHANGE ih_number number varchar(20) default NULL"); - setChange("ALTER TABLE tt_invoice_headers DROP ih_addr_your"); - setChange("ALTER TABLE tt_invoice_headers DROP ih_addr_cust"); - setChange("ALTER TABLE tt_invoice_headers CHANGE ih_comment comment varchar(255) default NULL"); - setChange("ALTER TABLE tt_invoice_headers CHANGE ih_tax tax float(6,2) default '0.00'"); - setChange("ALTER TABLE tt_invoice_headers CHANGE ih_discount discount float(6,2) default '0.00'"); - setChange("ALTER TABLE tt_invoice_headers CHANGE ih_fsubtotals subtotals tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_users DROP u_comanager"); - setChange("ALTER TABLE tt_tasks DROP a_manager_id"); - setChange("ALTER TABLE tt_projects DROP p_manager_id"); - setChange("ALTER TABLE tt_users DROP u_manager_id"); - setChange("ALTER TABLE activity_bind DROP ab_id"); - setChange("RENAME TABLE activity_bind TO tt_project_task_binds"); - setChange("ALTER TABLE tt_project_task_binds CHANGE ab_id_p project_id int(11) NOT NULL"); - setChange("ALTER TABLE tt_project_task_binds CHANGE ab_id_a task_id int(11) NOT NULL"); - setChange("RENAME TABLE user_bind TO tt_user_project_binds"); - setChange("ALTER TABLE tt_user_project_binds CHANGE ub_rate rate float(6,2) NOT NULL default '0.00'"); - setChange("ALTER TABLE tt_user_project_binds CHANGE ub_id_p project_id int(11) NOT NULL"); - setChange("ALTER TABLE tt_user_project_binds CHANGE ub_id_u user_id int(11) NOT NULL"); - setChange("ALTER TABLE tt_user_project_binds CHANGE ub_id id int(11) NOT NULL auto_increment"); - setChange("CREATE TABLE `tt_client_project_binds` (`client_id` int(11) NOT NULL, `project_id` int(11) NOT NULL)"); - setChange("ALTER TABLE tt_user_project_binds MODIFY rate float(6,2) default '0.00'"); - setChange("ALTER TABLE tt_clients MODIFY tax float(6,2) default '0.00'"); - setChange("RENAME TABLE activity_log TO tt_log"); - setChange("ALTER TABLE tt_log CHANGE al_timestamp timestamp timestamp NOT NULL"); - setChange("ALTER TABLE tt_log CHANGE al_user_id user_id int(11) NOT NULL"); - setChange("ALTER TABLE tt_log CHANGE al_date date date NOT NULL"); - setChange("drop index al_date_idx on tt_log"); - setChange("create index date_idx on tt_log(date)"); - setChange("ALTER TABLE tt_log CHANGE al_from start time default NULL"); - setChange("ALTER TABLE tt_log CHANGE al_duration duration time default NULL"); - setChange("ALTER TABLE tt_log CHANGE al_project_id project_id int(11) NOT NULL"); - setChange("ALTER TABLE tt_log MODIFY project_id int(11) default NULL"); - setChange("ALTER TABLE tt_log CHANGE al_activity_id task_id int(11) default NULL"); - setChange("ALTER TABLE tt_log CHANGE al_comment comment text"); - setChange("ALTER TABLE tt_log CHANGE al_billable billable tinyint(4) default '0'"); - setChange("drop index al_user_id_idx on tt_log"); - setChange("drop index al_project_id_idx on tt_log"); - setChange("drop index al_activity_id_idx on tt_log"); - setChange("create index user_idx on tt_log(user_id)"); - setChange("create index project_idx on tt_log(project_id)"); - setChange("create index task_idx on tt_log(task_id)"); - setChange("ALTER TABLE tt_custom_field_log CHANGE al_id log_id bigint NOT NULL"); - setChange("RENAME TABLE sysconfig TO tt_config"); - setChange("ALTER TABLE tt_config DROP sysc_id"); - setChange("ALTER TABLE tt_config CHANGE sysc_id_u user_id int(11) NOT NULL"); - setChange("ALTER TABLE tt_config CHANGE sysc_name param_name varchar(32) NOT NULL"); - setChange("ALTER TABLE tt_config CHANGE sysc_value param_value varchar(80) default NULL"); - setChange("create unique index param_idx on tt_config(user_id, param_name)"); - setChange("ALTER TABLE tt_log ADD COLUMN invoice_id int(11) default NULL"); - setChange("ALTER TABLE tt_projects ADD COLUMN description varchar(255) default NULL"); - setChange("CREATE TABLE `tt_invoices` (`id` int(11) NOT NULL auto_increment, `team_id` int(11) NOT NULL, `number` varchar(20) default NULL, `client_name` varchar(255) default NULL, `client_addr` varchar(255) default NULL, `comment` varchar(255) default NULL, `tax` float(6,2) default '0.00', `discount` float(6,2) default '0.00', PRIMARY KEY (`id`))"); - setChange("ALTER TABLE tt_invoices drop number"); - setChange("ALTER TABLE tt_invoices drop client_name"); - setChange("ALTER TABLE tt_invoices drop client_addr"); - setChange("ALTER TABLE tt_invoices drop comment"); - setChange("ALTER TABLE tt_invoices drop tax"); - setChange("ALTER TABLE tt_invoices ADD COLUMN name varchar(80) NOT NULL"); - setChange("ALTER TABLE tt_invoices ADD COLUMN client_id int(11) NOT NULL"); - setChange("ALTER TABLE tt_invoices ADD COLUMN start_date date NOT NULL"); - setChange("ALTER TABLE tt_invoices ADD COLUMN end_date date NOT NULL"); - setChange("create unique index name_idx on tt_invoices(team_id, name)"); - setChange("drop index ub_id_u on tt_user_project_binds"); - setChange("create unique index bind_idx on tt_user_project_binds(user_id, project_id)"); - setChange("create index client_idx on tt_log(client_id)"); - setChange("create index invoice_idx on tt_log(invoice_id)"); + ttExecute("ALTER TABLE tt_fav_reports MODIFY id int(11) NOT NULL auto_increment"); + ttExecute("RENAME TABLE clients TO tt_clients"); + ttExecute("ALTER TABLE tt_clients CHANGE clnt_id id int(11) NOT NULL AUTO_INCREMENT"); + ttExecute("ALTER TABLE tt_clients CHANGE clnt_status status tinyint(4) default '1'"); + ttExecute("ALTER TABLE tt_clients DROP clnt_id_um"); + ttExecute("ALTER TABLE tt_clients CHANGE clnt_name name varchar(80) NOT NULL"); + ttExecute("drop index clnt_name_idx on tt_clients"); + ttExecute("drop index client_name_idx on tt_clients"); + ttExecute("create unique index client_name_idx on tt_clients(team_id, name, status)"); + ttExecute("ALTER TABLE tt_teams ADD COLUMN `timestamp` timestamp NOT NULL"); + ttExecute("ALTER TABLE tt_clients CHANGE clnt_addr_cust address varchar(255) default NULL"); + ttExecute("ALTER TABLE tt_clients DROP clnt_discount"); + ttExecute("ALTER TABLE tt_clients DROP clnt_comment"); + ttExecute("ALTER TABLE tt_clients DROP clnt_fsubtotals"); + ttExecute("ALTER TABLE tt_clients CHANGE clnt_tax tax float(6,2) NOT NULL default '0.00'"); + ttExecute("ALTER TABLE activity_log ADD COLUMN client_id int(11) default NULL"); + ttExecute("ALTER TABLE tt_teams DROP show_pie"); + ttExecute("ALTER TABLE tt_fav_reports CHANGE group_by sort_by varchar(20) default 'date'"); + ttExecute("RENAME TABLE tmp_refs TO tt_tmp_refs"); + ttExecute("ALTER TABLE tt_tmp_refs CHANGE tr_created timestamp timestamp NOT NULL"); + ttExecute("ALTER TABLE tt_tmp_refs CHANGE tr_code ref char(32) NOT NULL default ''"); + ttExecute("ALTER TABLE tt_tmp_refs CHANGE tr_userid user_id int(11) NOT NULL"); + ttExecute("RENAME TABLE projects TO tt_projects"); + ttExecute("ALTER TABLE tt_projects CHANGE p_id id int(11) NOT NULL auto_increment"); + ttExecute("ALTER TABLE tt_projects DROP p_timestamp"); + ttExecute("ALTER TABLE tt_projects CHANGE p_name name varchar(80) NOT NULL"); + ttExecute("ALTER TABLE tt_projects CHANGE p_status status tinyint(4) default '1'"); + ttExecute("drop index p_name_idx on tt_projects"); + ttExecute("create unique index project_idx on tt_projects(team_id, name, status)"); + ttExecute("RENAME TABLE activities TO tt_tasks"); + ttExecute("ALTER TABLE tt_tasks CHANGE a_id id int(11) NOT NULL auto_increment"); + ttExecute("ALTER TABLE tt_tasks DROP a_timestamp"); + ttExecute("ALTER TABLE tt_tasks CHANGE a_name name varchar(80) NOT NULL"); + ttExecute("ALTER TABLE tt_tasks CHANGE a_status status tinyint(4) default '1'"); + ttExecute("drop index a_name_idx on tt_tasks"); + ttExecute("create unique index task_idx on tt_tasks(team_id, name, status)"); + ttExecute("RENAME TABLE invoice_header TO tt_invoice_headers"); + ttExecute("ALTER TABLE tt_invoice_headers CHANGE ih_user_id user_id int(11) NOT NULL"); + ttExecute("ALTER TABLE tt_invoice_headers CHANGE ih_number number varchar(20) default NULL"); + ttExecute("ALTER TABLE tt_invoice_headers DROP ih_addr_your"); + ttExecute("ALTER TABLE tt_invoice_headers DROP ih_addr_cust"); + ttExecute("ALTER TABLE tt_invoice_headers CHANGE ih_comment comment varchar(255) default NULL"); + ttExecute("ALTER TABLE tt_invoice_headers CHANGE ih_tax tax float(6,2) default '0.00'"); + ttExecute("ALTER TABLE tt_invoice_headers CHANGE ih_discount discount float(6,2) default '0.00'"); + ttExecute("ALTER TABLE tt_invoice_headers CHANGE ih_fsubtotals subtotals tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_users DROP u_comanager"); + ttExecute("ALTER TABLE tt_tasks DROP a_manager_id"); + ttExecute("ALTER TABLE tt_projects DROP p_manager_id"); + ttExecute("ALTER TABLE tt_users DROP u_manager_id"); + ttExecute("ALTER TABLE activity_bind DROP ab_id"); + ttExecute("RENAME TABLE activity_bind TO tt_project_task_binds"); + ttExecute("ALTER TABLE tt_project_task_binds CHANGE ab_id_p project_id int(11) NOT NULL"); + ttExecute("ALTER TABLE tt_project_task_binds CHANGE ab_id_a task_id int(11) NOT NULL"); + ttExecute("RENAME TABLE user_bind TO tt_user_project_binds"); + ttExecute("ALTER TABLE tt_user_project_binds CHANGE ub_rate rate float(6,2) NOT NULL default '0.00'"); + ttExecute("ALTER TABLE tt_user_project_binds CHANGE ub_id_p project_id int(11) NOT NULL"); + ttExecute("ALTER TABLE tt_user_project_binds CHANGE ub_id_u user_id int(11) NOT NULL"); + ttExecute("ALTER TABLE tt_user_project_binds CHANGE ub_id id int(11) NOT NULL auto_increment"); + ttExecute("CREATE TABLE `tt_client_project_binds` (`client_id` int(11) NOT NULL, `project_id` int(11) NOT NULL)"); + ttExecute("ALTER TABLE tt_user_project_binds MODIFY rate float(6,2) default '0.00'"); + ttExecute("ALTER TABLE tt_clients MODIFY tax float(6,2) default '0.00'"); + ttExecute("RENAME TABLE activity_log TO tt_log"); + ttExecute("ALTER TABLE tt_log CHANGE al_timestamp timestamp timestamp NOT NULL"); + ttExecute("ALTER TABLE tt_log CHANGE al_user_id user_id int(11) NOT NULL"); + ttExecute("ALTER TABLE tt_log CHANGE al_date date date NOT NULL"); + ttExecute("drop index al_date_idx on tt_log"); + ttExecute("create index date_idx on tt_log(date)"); + ttExecute("ALTER TABLE tt_log CHANGE al_from start time default NULL"); + ttExecute("ALTER TABLE tt_log CHANGE al_duration duration time default NULL"); + ttExecute("ALTER TABLE tt_log CHANGE al_project_id project_id int(11) NOT NULL"); + ttExecute("ALTER TABLE tt_log MODIFY project_id int(11) default NULL"); + ttExecute("ALTER TABLE tt_log CHANGE al_activity_id task_id int(11) default NULL"); + ttExecute("ALTER TABLE tt_log CHANGE al_comment comment text"); + ttExecute("ALTER TABLE tt_log CHANGE al_billable billable tinyint(4) default '0'"); + ttExecute("drop index al_user_id_idx on tt_log"); + ttExecute("drop index al_project_id_idx on tt_log"); + ttExecute("drop index al_activity_id_idx on tt_log"); + ttExecute("create index user_idx on tt_log(user_id)"); + ttExecute("create index project_idx on tt_log(project_id)"); + ttExecute("create index task_idx on tt_log(task_id)"); + ttExecute("ALTER TABLE tt_custom_field_log CHANGE al_id log_id bigint NOT NULL"); + ttExecute("RENAME TABLE sysconfig TO tt_config"); + ttExecute("ALTER TABLE tt_config DROP sysc_id"); + ttExecute("ALTER TABLE tt_config CHANGE sysc_id_u user_id int(11) NOT NULL"); + ttExecute("ALTER TABLE tt_config CHANGE sysc_name param_name varchar(32) NOT NULL"); + ttExecute("ALTER TABLE tt_config CHANGE sysc_value param_value varchar(80) default NULL"); + ttExecute("create unique index param_idx on tt_config(user_id, param_name)"); + ttExecute("ALTER TABLE tt_log ADD COLUMN invoice_id int(11) default NULL"); + ttExecute("ALTER TABLE tt_projects ADD COLUMN description varchar(255) default NULL"); + ttExecute("CREATE TABLE `tt_invoices` (`id` int(11) NOT NULL auto_increment, `team_id` int(11) NOT NULL, `number` varchar(20) default NULL, `client_name` varchar(255) default NULL, `client_addr` varchar(255) default NULL, `comment` varchar(255) default NULL, `tax` float(6,2) default '0.00', `discount` float(6,2) default '0.00', PRIMARY KEY (`id`))"); + ttExecute("ALTER TABLE tt_invoices drop number"); + ttExecute("ALTER TABLE tt_invoices drop client_name"); + ttExecute("ALTER TABLE tt_invoices drop client_addr"); + ttExecute("ALTER TABLE tt_invoices drop comment"); + ttExecute("ALTER TABLE tt_invoices drop tax"); + ttExecute("ALTER TABLE tt_invoices ADD COLUMN name varchar(80) NOT NULL"); + ttExecute("ALTER TABLE tt_invoices ADD COLUMN client_id int(11) NOT NULL"); + ttExecute("ALTER TABLE tt_invoices ADD COLUMN start_date date NOT NULL"); + ttExecute("ALTER TABLE tt_invoices ADD COLUMN end_date date NOT NULL"); + ttExecute("create unique index name_idx on tt_invoices(team_id, name)"); + ttExecute("drop index ub_id_u on tt_user_project_binds"); + ttExecute("create unique index bind_idx on tt_user_project_binds(user_id, project_id)"); + ttExecute("create index client_idx on tt_log(client_id)"); + ttExecute("create index invoice_idx on tt_log(invoice_id)"); } if ($_POST["convert1579to1600"]) { - setChange("ALTER TABLE tt_invoices ADD COLUMN date date NOT NULL"); - setChange("ALTER TABLE tt_teams ADD COLUMN custom_logo tinyint(4) default '0'"); - setChange("ALTER TABLE tt_tasks ADD COLUMN description varchar(255) default NULL"); - setChange("ALTER TABLE tt_projects MODIFY name varchar(80) COLLATE utf8_bin NOT NULL"); - setChange("ALTER TABLE tt_users MODIFY login varchar(50) COLLATE utf8_bin NOT NULL"); - setChange("ALTER TABLE tt_tasks MODIFY name varchar(80) COLLATE utf8_bin NOT NULL"); - setChange("ALTER TABLE tt_invoices MODIFY name varchar(80) COLLATE utf8_bin NOT NULL"); - setChange("ALTER TABLE tt_clients MODIFY name varchar(80) COLLATE utf8_bin NOT NULL"); - setChange("ALTER TABLE tt_clients ADD COLUMN projects text default NULL"); - setChange("ALTER TABLE tt_custom_field_log ADD COLUMN option_id int(11) default NULL"); - setChange("ALTER TABLE tt_teams ADD COLUMN tracking_mode smallint(2) NOT NULL DEFAULT '2'"); - setChange("ALTER TABLE tt_teams ADD COLUMN record_type smallint(2) NOT NULL DEFAULT '0'"); - setChange("ALTER TABLE tt_invoices DROP start_date"); - setChange("ALTER TABLE tt_invoices DROP end_date"); + ttExecute("ALTER TABLE tt_invoices ADD COLUMN date date NOT NULL"); + ttExecute("ALTER TABLE tt_teams ADD COLUMN custom_logo tinyint(4) default '0'"); + ttExecute("ALTER TABLE tt_tasks ADD COLUMN description varchar(255) default NULL"); + ttExecute("ALTER TABLE tt_projects MODIFY name varchar(80) COLLATE utf8_bin NOT NULL"); + ttExecute("ALTER TABLE tt_users MODIFY login varchar(50) COLLATE utf8_bin NOT NULL"); + ttExecute("ALTER TABLE tt_tasks MODIFY name varchar(80) COLLATE utf8_bin NOT NULL"); + ttExecute("ALTER TABLE tt_invoices MODIFY name varchar(80) COLLATE utf8_bin NOT NULL"); + ttExecute("ALTER TABLE tt_clients MODIFY name varchar(80) COLLATE utf8_bin NOT NULL"); + ttExecute("ALTER TABLE tt_clients ADD COLUMN projects text default NULL"); + ttExecute("ALTER TABLE tt_custom_field_log ADD COLUMN option_id int(11) default NULL"); + ttExecute("ALTER TABLE tt_teams ADD COLUMN tracking_mode smallint(2) NOT NULL DEFAULT '2'"); + ttExecute("ALTER TABLE tt_teams ADD COLUMN record_type smallint(2) NOT NULL DEFAULT '0'"); + ttExecute("ALTER TABLE tt_invoices DROP start_date"); + ttExecute("ALTER TABLE tt_invoices DROP end_date"); } // The update_clients function updates projects field in tt_clients table. @@ -677,93 +677,93 @@ function setChange($sql) { } if ($_POST["convert1600to11400"]) { - setChange("DROP TABLE IF EXISTS tt_invoice_headers"); - setChange("ALTER TABLE tt_fav_reports ADD COLUMN `client_id` int(11) default NULL"); - setChange("ALTER TABLE tt_fav_reports ADD COLUMN `cf_1_option_id` int(11) default NULL"); - setChange("ALTER TABLE tt_fav_reports ADD COLUMN `show_client` tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports ADD COLUMN `show_invoice` tinyint(4) NOT NULL default '0'"); - setChange("ALTER TABLE tt_fav_reports ADD COLUMN `group_by` varchar(20) default NULL"); - setChange("CREATE TABLE `tt_expense_items` (`id` bigint NOT NULL auto_increment, `date` date NOT NULL, `user_id` int(11) NOT NULL, `client_id` int(11) default NULL, `project_id` int(11) default NULL, `name` varchar(255) NOT NULL, `cost` decimal(10,2) default '0.00', `invoice_id` int(11) default NULL, PRIMARY KEY (`id`))"); - setChange("create index date_idx on tt_expense_items(date)"); - setChange("create index user_idx on tt_expense_items(user_id)"); - setChange("create index client_idx on tt_expense_items(client_id)"); - setChange("create index project_idx on tt_expense_items(project_id)"); - setChange("create index invoice_idx on tt_expense_items(invoice_id)"); - setChange("ALTER TABLE tt_fav_reports DROP sort_by"); - setChange("ALTER TABLE tt_fav_reports DROP show_empty_days"); - setChange("ALTER TABLE tt_invoices DROP discount"); - setChange("ALTER TABLE tt_users ADD COLUMN `client_id` int(11) default NULL"); - setChange("ALTER TABLE tt_teams ADD COLUMN `decimal_mark` char(1) NOT NULL default '.'"); - setChange("ALTER TABLE tt_fav_reports ADD COLUMN `invoice` tinyint(4) default NULL"); - setChange("CREATE TABLE `tt_cron` (`id` int(11) NOT NULL auto_increment, `cron_spec` varchar(255) NOT NULL, `last` int(11) default NULL, `next` int(11) default NULL, `report_id` int(11) default NULL, `email` varchar(100) default NULL, `status` tinyint(4) default '1', PRIMARY KEY (`id`))"); - setChange("ALTER TABLE tt_cron ADD COLUMN `team_id` int(11) NOT NULL"); - setChange("create index client_idx on tt_client_project_binds(client_id)"); - setChange("create index project_idx on tt_client_project_binds(project_id)"); - setChange("ALTER TABLE tt_log ADD COLUMN status tinyint(4) default '1'"); - setChange("ALTER TABLE tt_custom_field_log ADD COLUMN status tinyint(4) default '1'"); - setChange("ALTER TABLE tt_expense_items ADD COLUMN status tinyint(4) default '1'"); - 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"); - setChange("ALTER TABLE tt_teams DROP locktime"); - setChange("CREATE TABLE `tt_monthly_quota` (`team_id` int(11) NOT NULL, `year` smallint(5) UNSIGNED NOT NULL, `month` tinyint(3) UNSIGNED NOT NULL, `quota` smallint(5) UNSIGNED NOT NULL, PRIMARY KEY (`year`,`month`,`team_id`))"); - setChange("ALTER TABLE `tt_monthly_quota` ADD CONSTRAINT `FK_TT_TEAM_CONSTRAING` FOREIGN KEY (`team_id`) REFERENCES `tt_teams` (`id`) ON DELETE CASCADE ON UPDATE CASCADE"); - setChange("ALTER TABLE `tt_teams` ADD `workday_hours` SMALLINT NULL DEFAULT '8' AFTER `lock_spec`"); - setChange("RENAME TABLE tt_monthly_quota TO tt_monthly_quotas"); - setChange("ALTER TABLE tt_expense_items modify `name` text NOT NULL"); - setChange("ALTER TABLE `tt_teams` ADD `uncompleted_indicators` SMALLINT(2) NOT NULL DEFAULT '0' AFTER `record_type`"); - setChange("CREATE TABLE `tt_predefined_expenses` (`id` int(11) NOT NULL auto_increment, `team_id` int(11) NOT NULL, `name` varchar(255) NOT NULL, `cost` decimal(10,2) default '0.00', PRIMARY KEY (`id`))"); - setChange("ALTER TABLE `tt_teams` ADD `task_required` smallint(2) NOT NULL DEFAULT '0' AFTER `tracking_mode`"); - setChange("ALTER TABLE `tt_teams` ADD `project_required` smallint(2) NOT NULL DEFAULT '0' AFTER `tracking_mode`"); - setChange("ALTER TABLE `tt_cron` ADD `report_condition` varchar(255) default NULL AFTER `email`"); - setChange("ALTER TABLE `tt_fav_reports` ADD `status` tinyint(4) default '1'"); - setChange("ALTER TABLE `tt_teams` ADD `bcc_email` varchar(100) default NULL AFTER `uncompleted_indicators`"); - setChange("ALTER TABLE `tt_cron` ADD `cc` varchar(100) default NULL AFTER `email`"); - setChange("ALTER TABLE `tt_cron` ADD `subject` varchar(100) default NULL AFTER `cc`"); - setChange("ALTER TABLE `tt_log` ADD `paid` tinyint(4) NULL default '0' AFTER `billable`"); + ttExecute("DROP TABLE IF EXISTS tt_invoice_headers"); + ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `client_id` int(11) default NULL"); + ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `cf_1_option_id` int(11) default NULL"); + ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `show_client` tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `show_invoice` tinyint(4) NOT NULL default '0'"); + ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `group_by` varchar(20) default NULL"); + ttExecute("CREATE TABLE `tt_expense_items` (`id` bigint NOT NULL auto_increment, `date` date NOT NULL, `user_id` int(11) NOT NULL, `client_id` int(11) default NULL, `project_id` int(11) default NULL, `name` varchar(255) NOT NULL, `cost` decimal(10,2) default '0.00', `invoice_id` int(11) default NULL, PRIMARY KEY (`id`))"); + ttExecute("create index date_idx on tt_expense_items(date)"); + ttExecute("create index user_idx on tt_expense_items(user_id)"); + ttExecute("create index client_idx on tt_expense_items(client_id)"); + ttExecute("create index project_idx on tt_expense_items(project_id)"); + ttExecute("create index invoice_idx on tt_expense_items(invoice_id)"); + ttExecute("ALTER TABLE tt_fav_reports DROP sort_by"); + ttExecute("ALTER TABLE tt_fav_reports DROP show_empty_days"); + ttExecute("ALTER TABLE tt_invoices DROP discount"); + ttExecute("ALTER TABLE tt_users ADD COLUMN `client_id` int(11) default NULL"); + ttExecute("ALTER TABLE tt_teams ADD COLUMN `decimal_mark` char(1) NOT NULL default '.'"); + ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `invoice` tinyint(4) default NULL"); + ttExecute("CREATE TABLE `tt_cron` (`id` int(11) NOT NULL auto_increment, `cron_spec` varchar(255) NOT NULL, `last` int(11) default NULL, `next` int(11) default NULL, `report_id` int(11) default NULL, `email` varchar(100) default NULL, `status` tinyint(4) default '1', PRIMARY KEY (`id`))"); + ttExecute("ALTER TABLE tt_cron ADD COLUMN `team_id` int(11) NOT NULL"); + ttExecute("create index client_idx on tt_client_project_binds(client_id)"); + ttExecute("create index project_idx on tt_client_project_binds(project_id)"); + ttExecute("ALTER TABLE tt_log ADD COLUMN status tinyint(4) default '1'"); + ttExecute("ALTER TABLE tt_custom_field_log ADD COLUMN status tinyint(4) default '1'"); + ttExecute("ALTER TABLE tt_expense_items ADD COLUMN status tinyint(4) default '1'"); + ttExecute("ALTER TABLE tt_invoices ADD COLUMN status tinyint(4) default '1'"); + ttExecute("DROP INDEX name_idx on tt_invoices"); + ttExecute("create unique index name_idx on tt_invoices(team_id, name, status)"); + ttExecute("ALTER TABLE tt_teams ADD COLUMN lock_spec varchar(255) default NULL"); + ttExecute("ALTER TABLE tt_teams DROP locktime"); + ttExecute("CREATE TABLE `tt_monthly_quota` (`team_id` int(11) NOT NULL, `year` smallint(5) UNSIGNED NOT NULL, `month` tinyint(3) UNSIGNED NOT NULL, `quota` smallint(5) UNSIGNED NOT NULL, PRIMARY KEY (`year`,`month`,`team_id`))"); + ttExecute("ALTER TABLE `tt_monthly_quota` ADD CONSTRAINT `FK_TT_TEAM_CONSTRAING` FOREIGN KEY (`team_id`) REFERENCES `tt_teams` (`id`) ON DELETE CASCADE ON UPDATE CASCADE"); + ttExecute("ALTER TABLE `tt_teams` ADD `workday_hours` SMALLINT NULL DEFAULT '8' AFTER `lock_spec`"); + ttExecute("RENAME TABLE tt_monthly_quota TO tt_monthly_quotas"); + ttExecute("ALTER TABLE tt_expense_items modify `name` text NOT NULL"); + ttExecute("ALTER TABLE `tt_teams` ADD `uncompleted_indicators` SMALLINT(2) NOT NULL DEFAULT '0' AFTER `record_type`"); + ttExecute("CREATE TABLE `tt_predefined_expenses` (`id` int(11) NOT NULL auto_increment, `team_id` int(11) NOT NULL, `name` varchar(255) NOT NULL, `cost` decimal(10,2) default '0.00', PRIMARY KEY (`id`))"); + ttExecute("ALTER TABLE `tt_teams` ADD `task_required` smallint(2) NOT NULL DEFAULT '0' AFTER `tracking_mode`"); + ttExecute("ALTER TABLE `tt_teams` ADD `project_required` smallint(2) NOT NULL DEFAULT '0' AFTER `tracking_mode`"); + ttExecute("ALTER TABLE `tt_cron` ADD `report_condition` varchar(255) default NULL AFTER `email`"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `status` tinyint(4) default '1'"); + ttExecute("ALTER TABLE `tt_teams` ADD `bcc_email` varchar(100) default NULL AFTER `uncompleted_indicators`"); + ttExecute("ALTER TABLE `tt_cron` ADD `cc` varchar(100) default NULL AFTER `email`"); + ttExecute("ALTER TABLE `tt_cron` ADD `subject` varchar(100) default NULL AFTER `cc`"); + ttExecute("ALTER TABLE `tt_log` ADD `paid` tinyint(4) NULL default '0' AFTER `billable`"); } if ($_POST["convert11400to11744"]) { - setChange("ALTER TABLE `tt_teams` DROP `address`"); - setChange("ALTER TABLE `tt_fav_reports` ADD `report_spec` text default NULL AFTER `user_id`"); - setChange("ALTER TABLE `tt_fav_reports` ADD `paid_status` tinyint(4) default NULL AFTER `invoice`"); - setChange("ALTER TABLE `tt_fav_reports` ADD `show_paid` tinyint(4) NOT NULL DEFAULT '0' AFTER `show_invoice`"); - setChange("ALTER TABLE `tt_expense_items` ADD `paid` tinyint(4) NULL default '0' AFTER `invoice_id`"); - setChange("ALTER TABLE `tt_monthly_quotas` MODIFY `quota` decimal(5,2) NOT NULL"); - setChange("ALTER TABLE `tt_teams` MODIFY `workday_hours` decimal(5,2) DEFAULT '8.00'"); - setChange("ALTER TABLE `tt_teams` ADD `config` text default NULL AFTER `custom_logo`"); - setChange("ALTER TABLE `tt_monthly_quotas` ADD `minutes` int(11) DEFAULT NULL"); - setChange("ALTER TABLE `tt_teams` ADD `workday_minutes` smallint(4) DEFAULT '480' AFTER `workday_hours`"); - setChange("UPDATE `tt_teams` SET `workday_minutes` = 60 * `workday_hours`"); - setChange("ALTER TABLE `tt_teams` DROP `workday_hours`"); - setChange("UPDATE `tt_monthly_quotas` SET `minutes` = 60 * `quota`"); - setChange("ALTER TABLE `tt_monthly_quotas` DROP `quota`"); - setChange("ALTER TABLE `tt_teams` DROP `uncompleted_indicators`"); - setChange("ALTER TABLE `tt_users` MODIFY `timestamp` timestamp default CURRENT_TIMESTAMP"); - setChange("ALTER TABLE `tt_teams` MODIFY `timestamp` timestamp default CURRENT_TIMESTAMP"); - setChange("ALTER TABLE `tt_log` MODIFY `timestamp` timestamp default CURRENT_TIMESTAMP"); - setChange("ALTER TABLE `tt_tmp_refs` MODIFY `timestamp` timestamp default CURRENT_TIMESTAMP"); - setChange("CREATE TABLE `tt_roles` (`id` int(11) NOT NULL auto_increment, `team_id` int(11) NOT NULL, `name` varchar(80) default NULL, `rank` int(11) default 0, `rights` text default NULL, `status` tinyint(4) default 1, PRIMARY KEY (`id`))"); - setChange("create unique index role_idx on tt_roles(team_id, rank, status)"); - setChange("ALTER TABLE `tt_roles` ADD `description` varchar(255) default NULL AFTER `name`"); - setChange("ALTER TABLE `tt_users` ADD `role_id` int(11) default NULL AFTER `role`"); - setChange("CREATE TABLE `tt_site_config` (`param_name` varchar(32) NOT NULL, `param_value` text default NULL, `created` datetime default NULL, `updated` datetime default NULL, PRIMARY KEY (`param_name`))"); - setChange("INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.34', now())"); - setChange("INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site')"); - setChange("INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'data_entry,view_own_data,manage_own_settings,view_users,on_behalf_data_entry,view_data,override_punch_mode,swap_roles,approve_timesheets,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups')"); - setChange("UPDATE `tt_site_config` SET `param_value` = '1.17.35' where param_name = 'version_db'"); - setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set role_id = (select id from tt_roles where rank = 1024) where role = 1024"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = 'data_entry,view_own_reports,view_own_charts,view_own_invoices,manage_own_settings,view_users,on_behalf_data_entry,view_reports,view_charts,override_punch_mode,swap_roles,approve_timesheets,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups' where team_id = 0 and rank = 512"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = replace(rights, 'view_own_data', 'view_own_reports,view_own_charts') where team_id > 0"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = replace(rights, 'view_data', 'view_reports,view_charts') where team_id > 0"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = replace(rights, 'view_own_charts,manage_own_settings', 'view_own_charts,view_own_invoices,manage_own_settings') where team_id > 0 and rank = 16"); - setChange("UPDATE `tt_site_config` SET `param_value` = '1.17.40' where param_name = 'version_db'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.40') set rights = replace(rights, 'on_behalf_data_entry', 'track_time,track_expenses')"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.40') set rights = replace(rights, 'data_entry', 'track_own_time,track_own_expenses')"); - setChange("UPDATE `tt_site_config` SET `param_value` = '1.17.43' where param_name = 'version_db'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.43') set rights = replace(rights, 'override_punch_mode,swap_roles', 'override_punch_mode,override_date_lock,swap_roles')"); - setChange("UPDATE `tt_site_config` SET `param_value` = '1.17.44' where param_name = 'version_db'"); + ttExecute("ALTER TABLE `tt_teams` DROP `address`"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `report_spec` text default NULL AFTER `user_id`"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `paid_status` tinyint(4) default NULL AFTER `invoice`"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `show_paid` tinyint(4) NOT NULL DEFAULT '0' AFTER `show_invoice`"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `paid` tinyint(4) NULL default '0' AFTER `invoice_id`"); + ttExecute("ALTER TABLE `tt_monthly_quotas` MODIFY `quota` decimal(5,2) NOT NULL"); + ttExecute("ALTER TABLE `tt_teams` MODIFY `workday_hours` decimal(5,2) DEFAULT '8.00'"); + ttExecute("ALTER TABLE `tt_teams` ADD `config` text default NULL AFTER `custom_logo`"); + ttExecute("ALTER TABLE `tt_monthly_quotas` ADD `minutes` int(11) DEFAULT NULL"); + ttExecute("ALTER TABLE `tt_teams` ADD `workday_minutes` smallint(4) DEFAULT '480' AFTER `workday_hours`"); + ttExecute("UPDATE `tt_teams` SET `workday_minutes` = 60 * `workday_hours`"); + ttExecute("ALTER TABLE `tt_teams` DROP `workday_hours`"); + ttExecute("UPDATE `tt_monthly_quotas` SET `minutes` = 60 * `quota`"); + ttExecute("ALTER TABLE `tt_monthly_quotas` DROP `quota`"); + ttExecute("ALTER TABLE `tt_teams` DROP `uncompleted_indicators`"); + ttExecute("ALTER TABLE `tt_users` MODIFY `timestamp` timestamp default CURRENT_TIMESTAMP"); + ttExecute("ALTER TABLE `tt_teams` MODIFY `timestamp` timestamp default CURRENT_TIMESTAMP"); + ttExecute("ALTER TABLE `tt_log` MODIFY `timestamp` timestamp default CURRENT_TIMESTAMP"); + ttExecute("ALTER TABLE `tt_tmp_refs` MODIFY `timestamp` timestamp default CURRENT_TIMESTAMP"); + ttExecute("CREATE TABLE `tt_roles` (`id` int(11) NOT NULL auto_increment, `team_id` int(11) NOT NULL, `name` varchar(80) default NULL, `rank` int(11) default 0, `rights` text default NULL, `status` tinyint(4) default 1, PRIMARY KEY (`id`))"); + ttExecute("create unique index role_idx on tt_roles(team_id, rank, status)"); + ttExecute("ALTER TABLE `tt_roles` ADD `description` varchar(255) default NULL AFTER `name`"); + ttExecute("ALTER TABLE `tt_users` ADD `role_id` int(11) default NULL AFTER `role`"); + ttExecute("CREATE TABLE `tt_site_config` (`param_name` varchar(32) NOT NULL, `param_value` text default NULL, `created` datetime default NULL, `updated` datetime default NULL, PRIMARY KEY (`param_name`))"); + ttExecute("INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.34', now())"); + ttExecute("INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site')"); + ttExecute("INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'data_entry,view_own_data,manage_own_settings,view_users,on_behalf_data_entry,view_data,override_punch_mode,swap_roles,approve_timesheets,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups')"); + ttExecute("UPDATE `tt_site_config` SET `param_value` = '1.17.35' where param_name = 'version_db'"); + ttExecute("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set role_id = (select id from tt_roles where rank = 1024) where role = 1024"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = 'data_entry,view_own_reports,view_own_charts,view_own_invoices,manage_own_settings,view_users,on_behalf_data_entry,view_reports,view_charts,override_punch_mode,swap_roles,approve_timesheets,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups' where team_id = 0 and rank = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = replace(rights, 'view_own_data', 'view_own_reports,view_own_charts') where team_id > 0"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = replace(rights, 'view_data', 'view_reports,view_charts') where team_id > 0"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = replace(rights, 'view_own_charts,manage_own_settings', 'view_own_charts,view_own_invoices,manage_own_settings') where team_id > 0 and rank = 16"); + ttExecute("UPDATE `tt_site_config` SET `param_value` = '1.17.40' where param_name = 'version_db'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.40') set rights = replace(rights, 'on_behalf_data_entry', 'track_time,track_expenses')"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.40') set rights = replace(rights, 'data_entry', 'track_own_time,track_own_expenses')"); + ttExecute("UPDATE `tt_site_config` SET `param_value` = '1.17.43' where param_name = 'version_db'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.43') set rights = replace(rights, 'override_punch_mode,swap_roles', 'override_punch_mode,override_date_lock,swap_roles')"); + ttExecute("UPDATE `tt_site_config` SET `param_value` = '1.17.44' where param_name = 'version_db'"); } // The update_role_id function assigns a role_id to users, who don't have it. @@ -807,107 +807,107 @@ function setChange($sql) { } if ($_POST["convert11744to11797"]) { - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); - setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.49' where param_name = 'version_db' and param_value = '1.17.48'"); - setChange("ALTER TABLE `tt_users` drop role"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.50' where param_name = 'version_db' and param_value = '1.17.49'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.50') set rights = replace(rights, 'override_date_lock,swap_roles', 'override_date_lock,override_own_date_lock,swap_roles')"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.51' where param_name = 'version_db' and param_value = '1.17.50'"); - setChange("ALTER TABLE `tt_users` ADD `created` datetime default NULL AFTER `email`"); - setChange("ALTER TABLE `tt_users` ADD `created_ip` varchar(45) default NULL AFTER `created`"); - setChange("ALTER TABLE `tt_users` ADD `created_by` int(11) default NULL AFTER `created_ip`"); - setChange("ALTER TABLE `tt_users` ADD `modified` datetime default NULL AFTER `created_by`"); - setChange("ALTER TABLE `tt_users` ADD `modified_ip` varchar(45) default NULL AFTER `modified`"); - setChange("ALTER TABLE `tt_users` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); - setChange("ALTER TABLE `tt_users` ADD `accessed` datetime default NULL AFTER `modified_by`"); - setChange("ALTER TABLE `tt_users` ADD `accessed_ip` varchar(45) default NULL AFTER `accessed`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.52' where param_name = 'version_db' and param_value = '1.17.51'"); - setChange("ALTER TABLE `tt_site_config` CHANGE `updated` `modified` datetime default NULL"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.53', modified = now() where param_name = 'version_db' and param_value = '1.17.52'"); - setChange("ALTER TABLE `tt_log` ADD `created` datetime default NULL AFTER `paid`"); - setChange("ALTER TABLE `tt_log` ADD `created_ip` varchar(45) default NULL AFTER `created`"); - setChange("ALTER TABLE `tt_log` ADD `created_by` int(11) default NULL AFTER `created_ip`"); - setChange("ALTER TABLE `tt_log` ADD `modified` datetime default NULL AFTER `created_by`"); - setChange("ALTER TABLE `tt_log` ADD `modified_ip` varchar(45) default NULL AFTER `modified`"); - setChange("ALTER TABLE `tt_log` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.56', modified = now() where param_name = 'version_db' and param_value = '1.17.53'"); - setChange("ALTER TABLE `tt_expense_items` ADD `created` datetime default NULL AFTER `paid`"); - setChange("ALTER TABLE `tt_expense_items` ADD `created_ip` varchar(45) default NULL AFTER `created`"); - setChange("ALTER TABLE `tt_expense_items` ADD `created_by` int(11) default NULL AFTER `created_ip`"); - setChange("ALTER TABLE `tt_expense_items` ADD `modified` datetime default NULL AFTER `created_by`"); - setChange("ALTER TABLE `tt_expense_items` ADD `modified_ip` varchar(45) default NULL AFTER `modified`"); - setChange("ALTER TABLE `tt_expense_items` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.59', modified = now() where param_name = 'version_db' and param_value = '1.17.56'"); - setChange("ALTER TABLE `tt_fav_reports` ADD `show_ip` tinyint(4) NOT NULL DEFAULT '0' AFTER `show_paid`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.61', modified = now() where param_name = 'version_db' and param_value = '1.17.59'"); - setChange("update `tt_log` l inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.61') set l.created = l.timestamp where l.created is null"); - setChange("ALTER TABLE `tt_log` drop `timestamp`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.64', modified = now() where param_name = 'version_db' and param_value = '1.17.61'"); - setChange("ALTER TABLE `tt_teams` ADD `created` datetime default NULL AFTER `config`"); - setChange("ALTER TABLE `tt_teams` ADD `created_ip` varchar(45) default NULL AFTER `created`"); - setChange("ALTER TABLE `tt_teams` ADD `created_by` int(11) default NULL AFTER `created_ip`"); - setChange("ALTER TABLE `tt_teams` ADD `modified` datetime default NULL AFTER `created_by`"); - setChange("ALTER TABLE `tt_teams` ADD `modified_ip` varchar(45) default NULL AFTER `modified`"); - setChange("ALTER TABLE `tt_teams` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.65', modified = now() where param_name = 'version_db' and param_value = '1.17.64'"); - setChange("update `tt_teams` t inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.65') set t.created = t.timestamp where t.created is null"); - setChange("update `tt_users` u inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.65') set u.created = u.timestamp where u.created is null"); - setChange("ALTER TABLE `tt_teams` drop `timestamp`"); - setChange("ALTER TABLE `tt_users` drop `timestamp`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.66', modified = now() where param_name = 'version_db' and param_value = '1.17.65'"); - setChange("ALTER TABLE `tt_tmp_refs` ADD `created` datetime default NULL AFTER `timestamp`"); - setChange("ALTER TABLE `tt_tmp_refs` drop `timestamp`"); - setChange("delete from `tt_tmp_refs`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.67', modified = now() where param_name = 'version_db' and param_value = '1.17.66'"); - setChange("ALTER TABLE `tt_teams` ADD `parent_id` int(11) default NULL AFTER `id`"); - setChange("ALTER TABLE `tt_teams` ADD `org_id` int(11) default NULL AFTER `parent_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.76', modified = now() where param_name = 'version_db' and param_value = '1.17.67'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.76') set rights = replace(rights, ',manage_users', ',manage_own_account,manage_users')"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.77', modified = now() where param_name = 'version_db' and param_value = '1.17.76'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.77') set rights = replace(rights, 'manage_own_settings,view_users', 'manage_own_settings,view_projects,view_users')"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.78', modified = now() where param_name = 'version_db' and param_value = '1.17.77'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.78') set rights = replace(rights, 'manage_own_settings,view_projects,view_users', 'view_own_projects,manage_own_settings,view_users')"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.79', modified = now() where param_name = 'version_db' and param_value = '1.17.78'"); - setChange("RENAME TABLE `tt_teams` TO `tt_groups`"); - setChange("ALTER TABLE `tt_monthly_quotas` DROP FOREIGN KEY FK_TT_TEAM_CONSTRAING"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.80', modified = now() where param_name = 'version_db' and param_value = '1.17.79'"); - setChange("ALTER TABLE `tt_roles` CHANGE `team_id` `group_id` int(11) NOT NULL"); - setChange("ALTER TABLE `tt_users` CHANGE `team_id` `group_id` int(11) NOT NULL"); - setChange("ALTER TABLE `tt_projects` CHANGE `team_id` `group_id` int(11) NOT NULL"); - setChange("ALTER TABLE `tt_tasks` CHANGE `team_id` `group_id` int(11) NOT NULL"); - setChange("ALTER TABLE `tt_invoices` CHANGE `team_id` `group_id` int(11) NOT NULL"); - setChange("ALTER TABLE `tt_cron` CHANGE `team_id` `group_id` int(11) NOT NULL"); - setChange("ALTER TABLE `tt_clients` CHANGE `team_id` `group_id` int(11) NOT NULL"); - setChange("ALTER TABLE `tt_custom_fields` CHANGE `team_id` `group_id` int(11) NOT NULL"); - setChange("ALTER TABLE `tt_predefined_expenses` CHANGE `team_id` `group_id` int(11) NOT NULL"); - setChange("ALTER TABLE `tt_monthly_quotas` CHANGE `team_id` `group_id` int(11) NOT NULL"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.81', modified = now() where param_name = 'version_db' and param_value = '1.17.80'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.81') set rights = replace(rights, ',manage_invoices', ',manage_invoices,view_all_reports')"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.82', modified = now() where param_name = 'version_db' and param_value = '1.17.81'"); - setChange("ALTER TABLE `tt_groups` ADD `allow_ip` varchar(255) default NULL AFTER `bcc_email`"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.82') set rights = replace(rights, 'manage_invoices,view_all_reports', 'manage_invoices,override_allow_ip,view_all_reports')"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.83', modified = now() where param_name = 'version_db' and param_value = '1.17.82'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.83') set rights = replace(rights, 'view_own_projects,manage_own_settings', 'view_own_projects,view_own_tasks,manage_own_settings')"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.84', modified = now() where param_name = 'version_db' and param_value = '1.17.83'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.84') set rights = replace(rights, 'view_charts,override_punch_mode', 'view_charts,view_own_clients,override_punch_mode')"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.85', modified = now() where param_name = 'version_db' and param_value = '1.17.84'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.85') set rights = replace(rights, 'override_allow_ip,view_all_reports', 'override_allow_ip,manage_basic_settings,view_all_reports')"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.85') set rights = replace(rights, 'manage_features,manage_basic_setting,manage_advanced_settings', 'manage_features,manage_advanced_settings')"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.86', modified = now() where param_name = 'version_db' and param_value = '1.17.85'"); - setChange("ALTER TABLE `tt_groups` ADD `password_complexity` varchar(64) default NULL AFTER `allow_ip`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.87', modified = now() where param_name = 'version_db' and param_value = '1.17.86'"); - setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.87') set rights = replace(rights, 'manage_subgroups', 'manage_subgroups,delete_group') where rank = 512"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.88', modified = now() where param_name = 'version_db' and param_value = '1.17.87'"); - setChange("ALTER TABLE `tt_fav_reports` ADD `show_work_units` tinyint(4) NOT NULL DEFAULT '0' AFTER `show_custom_field_1`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.92', modified = now() where param_name = 'version_db' and param_value = '1.17.88'"); - setChange("ALTER TABLE `tt_log` ADD `group_id` int(11) default NULL AFTER `user_id`"); - setChange("ALTER TABLE `tt_expense_items` ADD `group_id` int(11) default NULL AFTER `user_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.96', modified = now() where param_name = 'version_db' and param_value = '1.17.92'"); - setChange("create index group_idx on tt_log(group_id)"); - setChange("create index group_idx on tt_expense_items(group_id)"); - setChange("UPDATE `tt_site_config` SET param_value = '1.17.97', modified = now() where param_name = 'version_db' and param_value = '1.17.96'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); + ttExecute("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.49' where param_name = 'version_db' and param_value = '1.17.48'"); + ttExecute("ALTER TABLE `tt_users` drop role"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.50' where param_name = 'version_db' and param_value = '1.17.49'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.50') set rights = replace(rights, 'override_date_lock,swap_roles', 'override_date_lock,override_own_date_lock,swap_roles')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.51' where param_name = 'version_db' and param_value = '1.17.50'"); + ttExecute("ALTER TABLE `tt_users` ADD `created` datetime default NULL AFTER `email`"); + ttExecute("ALTER TABLE `tt_users` ADD `created_ip` varchar(45) default NULL AFTER `created`"); + ttExecute("ALTER TABLE `tt_users` ADD `created_by` int(11) default NULL AFTER `created_ip`"); + ttExecute("ALTER TABLE `tt_users` ADD `modified` datetime default NULL AFTER `created_by`"); + ttExecute("ALTER TABLE `tt_users` ADD `modified_ip` varchar(45) default NULL AFTER `modified`"); + ttExecute("ALTER TABLE `tt_users` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); + ttExecute("ALTER TABLE `tt_users` ADD `accessed` datetime default NULL AFTER `modified_by`"); + ttExecute("ALTER TABLE `tt_users` ADD `accessed_ip` varchar(45) default NULL AFTER `accessed`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.52' where param_name = 'version_db' and param_value = '1.17.51'"); + ttExecute("ALTER TABLE `tt_site_config` CHANGE `updated` `modified` datetime default NULL"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.53', modified = now() where param_name = 'version_db' and param_value = '1.17.52'"); + ttExecute("ALTER TABLE `tt_log` ADD `created` datetime default NULL AFTER `paid`"); + ttExecute("ALTER TABLE `tt_log` ADD `created_ip` varchar(45) default NULL AFTER `created`"); + ttExecute("ALTER TABLE `tt_log` ADD `created_by` int(11) default NULL AFTER `created_ip`"); + ttExecute("ALTER TABLE `tt_log` ADD `modified` datetime default NULL AFTER `created_by`"); + ttExecute("ALTER TABLE `tt_log` ADD `modified_ip` varchar(45) default NULL AFTER `modified`"); + ttExecute("ALTER TABLE `tt_log` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.56', modified = now() where param_name = 'version_db' and param_value = '1.17.53'"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `created` datetime default NULL AFTER `paid`"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `created_ip` varchar(45) default NULL AFTER `created`"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `created_by` int(11) default NULL AFTER `created_ip`"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `modified` datetime default NULL AFTER `created_by`"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `modified_ip` varchar(45) default NULL AFTER `modified`"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.59', modified = now() where param_name = 'version_db' and param_value = '1.17.56'"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `show_ip` tinyint(4) NOT NULL DEFAULT '0' AFTER `show_paid`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.61', modified = now() where param_name = 'version_db' and param_value = '1.17.59'"); + ttExecute("update `tt_log` l inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.61') set l.created = l.timestamp where l.created is null"); + ttExecute("ALTER TABLE `tt_log` drop `timestamp`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.64', modified = now() where param_name = 'version_db' and param_value = '1.17.61'"); + ttExecute("ALTER TABLE `tt_teams` ADD `created` datetime default NULL AFTER `config`"); + ttExecute("ALTER TABLE `tt_teams` ADD `created_ip` varchar(45) default NULL AFTER `created`"); + ttExecute("ALTER TABLE `tt_teams` ADD `created_by` int(11) default NULL AFTER `created_ip`"); + ttExecute("ALTER TABLE `tt_teams` ADD `modified` datetime default NULL AFTER `created_by`"); + ttExecute("ALTER TABLE `tt_teams` ADD `modified_ip` varchar(45) default NULL AFTER `modified`"); + ttExecute("ALTER TABLE `tt_teams` ADD `modified_by` int(11) default NULL AFTER `modified_ip`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.65', modified = now() where param_name = 'version_db' and param_value = '1.17.64'"); + ttExecute("update `tt_teams` t inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.65') set t.created = t.timestamp where t.created is null"); + ttExecute("update `tt_users` u inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.65') set u.created = u.timestamp where u.created is null"); + ttExecute("ALTER TABLE `tt_teams` drop `timestamp`"); + ttExecute("ALTER TABLE `tt_users` drop `timestamp`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.66', modified = now() where param_name = 'version_db' and param_value = '1.17.65'"); + ttExecute("ALTER TABLE `tt_tmp_refs` ADD `created` datetime default NULL AFTER `timestamp`"); + ttExecute("ALTER TABLE `tt_tmp_refs` drop `timestamp`"); + ttExecute("delete from `tt_tmp_refs`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.67', modified = now() where param_name = 'version_db' and param_value = '1.17.66'"); + ttExecute("ALTER TABLE `tt_teams` ADD `parent_id` int(11) default NULL AFTER `id`"); + ttExecute("ALTER TABLE `tt_teams` ADD `org_id` int(11) default NULL AFTER `parent_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.76', modified = now() where param_name = 'version_db' and param_value = '1.17.67'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.76') set rights = replace(rights, ',manage_users', ',manage_own_account,manage_users')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.77', modified = now() where param_name = 'version_db' and param_value = '1.17.76'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.77') set rights = replace(rights, 'manage_own_settings,view_users', 'manage_own_settings,view_projects,view_users')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.78', modified = now() where param_name = 'version_db' and param_value = '1.17.77'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.78') set rights = replace(rights, 'manage_own_settings,view_projects,view_users', 'view_own_projects,manage_own_settings,view_users')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.79', modified = now() where param_name = 'version_db' and param_value = '1.17.78'"); + ttExecute("RENAME TABLE `tt_teams` TO `tt_groups`"); + ttExecute("ALTER TABLE `tt_monthly_quotas` DROP FOREIGN KEY FK_TT_TEAM_CONSTRAING"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.80', modified = now() where param_name = 'version_db' and param_value = '1.17.79'"); + ttExecute("ALTER TABLE `tt_roles` CHANGE `team_id` `group_id` int(11) NOT NULL"); + ttExecute("ALTER TABLE `tt_users` CHANGE `team_id` `group_id` int(11) NOT NULL"); + ttExecute("ALTER TABLE `tt_projects` CHANGE `team_id` `group_id` int(11) NOT NULL"); + ttExecute("ALTER TABLE `tt_tasks` CHANGE `team_id` `group_id` int(11) NOT NULL"); + ttExecute("ALTER TABLE `tt_invoices` CHANGE `team_id` `group_id` int(11) NOT NULL"); + ttExecute("ALTER TABLE `tt_cron` CHANGE `team_id` `group_id` int(11) NOT NULL"); + ttExecute("ALTER TABLE `tt_clients` CHANGE `team_id` `group_id` int(11) NOT NULL"); + ttExecute("ALTER TABLE `tt_custom_fields` CHANGE `team_id` `group_id` int(11) NOT NULL"); + ttExecute("ALTER TABLE `tt_predefined_expenses` CHANGE `team_id` `group_id` int(11) NOT NULL"); + ttExecute("ALTER TABLE `tt_monthly_quotas` CHANGE `team_id` `group_id` int(11) NOT NULL"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.81', modified = now() where param_name = 'version_db' and param_value = '1.17.80'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.81') set rights = replace(rights, ',manage_invoices', ',manage_invoices,view_all_reports')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.82', modified = now() where param_name = 'version_db' and param_value = '1.17.81'"); + ttExecute("ALTER TABLE `tt_groups` ADD `allow_ip` varchar(255) default NULL AFTER `bcc_email`"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.82') set rights = replace(rights, 'manage_invoices,view_all_reports', 'manage_invoices,override_allow_ip,view_all_reports')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.83', modified = now() where param_name = 'version_db' and param_value = '1.17.82'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.83') set rights = replace(rights, 'view_own_projects,manage_own_settings', 'view_own_projects,view_own_tasks,manage_own_settings')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.84', modified = now() where param_name = 'version_db' and param_value = '1.17.83'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.84') set rights = replace(rights, 'view_charts,override_punch_mode', 'view_charts,view_own_clients,override_punch_mode')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.85', modified = now() where param_name = 'version_db' and param_value = '1.17.84'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.85') set rights = replace(rights, 'override_allow_ip,view_all_reports', 'override_allow_ip,manage_basic_settings,view_all_reports')"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.85') set rights = replace(rights, 'manage_features,manage_basic_setting,manage_advanced_settings', 'manage_features,manage_advanced_settings')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.86', modified = now() where param_name = 'version_db' and param_value = '1.17.85'"); + ttExecute("ALTER TABLE `tt_groups` ADD `password_complexity` varchar(64) default NULL AFTER `allow_ip`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.87', modified = now() where param_name = 'version_db' and param_value = '1.17.86'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.87') set rights = replace(rights, 'manage_subgroups', 'manage_subgroups,delete_group') where rank = 512"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.88', modified = now() where param_name = 'version_db' and param_value = '1.17.87'"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `show_work_units` tinyint(4) NOT NULL DEFAULT '0' AFTER `show_custom_field_1`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.92', modified = now() where param_name = 'version_db' and param_value = '1.17.88'"); + ttExecute("ALTER TABLE `tt_log` ADD `group_id` int(11) default NULL AFTER `user_id`"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `group_id` int(11) default NULL AFTER `user_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.96', modified = now() where param_name = 'version_db' and param_value = '1.17.92'"); + ttExecute("create index group_idx on tt_log(group_id)"); + ttExecute("create index group_idx on tt_expense_items(group_id)"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.97', modified = now() where param_name = 'version_db' and param_value = '1.17.96'"); } // The update_group_id function updates group_id field in tt_log and tt_expense_items tables. @@ -958,88 +958,88 @@ function setChange($sql) { } if ($_POST["convert11797to11826"]) { - setChange("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); - setChange("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); - setChange("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.00', modified = now() where param_name = 'version_db' and param_value = '1.17.97'"); - setChange("create index log_idx on tt_custom_field_log(log_id)"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.05', modified = now() where param_name = 'version_db' and param_value = '1.18.00'"); - setChange("UPDATE `tt_groups` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.05') set org_id = id where org_id is null"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.06', modified = now() where param_name = 'version_db' and param_value = '1.18.05'"); - setChange("ALTER TABLE `tt_users` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.06') set org_id = group_id where org_id is null"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.07', modified = now() where param_name = 'version_db' and param_value = '1.18.06'"); - setChange("ALTER TABLE `tt_roles` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.07') set org_id = group_id where org_id is null"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.08', modified = now() where param_name = 'version_db' and param_value = '1.18.07'"); - setChange("ALTER TABLE `tt_clients` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.09', modified = now() where param_name = 'version_db' and param_value = '1.18.08'"); - setChange("UPDATE `tt_clients` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.09') set org_id = group_id where org_id is null"); - setChange("ALTER TABLE `tt_projects` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("ALTER TABLE `tt_tasks` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.10', modified = now() where param_name = 'version_db' and param_value = '1.18.09'"); - setChange("UPDATE `tt_projects` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.10') set org_id = group_id where org_id is null"); - setChange("UPDATE `tt_tasks` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.10') set org_id = group_id where org_id is null"); - setChange("ALTER TABLE `tt_log` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("ALTER TABLE `tt_invoices` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.11', modified = now() where param_name = 'version_db' and param_value = '1.18.10'"); - setChange("UPDATE `tt_log` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.11') set org_id = group_id where org_id is null"); - setChange("UPDATE `tt_invoices` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.11') set org_id = group_id where org_id is null"); - setChange("ALTER TABLE `tt_user_project_binds` ADD `group_id` int(11) default NULL AFTER `project_id`"); - setChange("ALTER TABLE `tt_user_project_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("ALTER TABLE `tt_project_task_binds` ADD `group_id` int(11) default NULL AFTER `task_id`"); - setChange("ALTER TABLE `tt_project_task_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.12', modified = now() where param_name = 'version_db' and param_value = '1.18.11'"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.13', modified = now() where param_name = 'version_db' and param_value = '1.18.12'"); - setChange("ALTER TABLE `tt_users` MODIFY `login` varchar(50) COLLATE utf8mb4_bin NOT NULL"); - setChange("ALTER TABLE `tt_projects` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); - setChange("ALTER TABLE `tt_tasks` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); - setChange("ALTER TABLE `tt_invoices` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); - setChange("ALTER TABLE `tt_clients` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.14', modified = now() where param_name = 'version_db' and param_value = '1.18.13'"); - setChange("ALTER TABLE `tt_monthly_quotas` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_monthly_quotas` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.14') set org_id = group_id where org_id is null"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.15', modified = now() where param_name = 'version_db' and param_value = '1.18.14'"); - setChange("ALTER TABLE `tt_predefined_expenses` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.16', modified = now() where param_name = 'version_db' and param_value = '1.18.15'"); - setChange("UPDATE `tt_predefined_expenses` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.16') set org_id = group_id where org_id is null"); - setChange("ALTER TABLE `tt_expense_items` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.17', modified = now() where param_name = 'version_db' and param_value = '1.18.16'"); - setChange("UPDATE `tt_expense_items` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') set org_id = group_id where org_id is null"); - setChange("update `tt_user_project_binds` upb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_users` u on u.id = upb.user_id set upb.group_id = u.group_id, upb.org_id = u.org_id where upb.org_id is null"); - setChange("update `tt_project_task_binds` ptb inner join tt_site_config sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_projects` p on p.id = ptb.project_id set ptb.group_id = p.group_id, ptb.org_id = p.org_id where ptb.org_id is null"); - setChange("create unique index project_task_idx on tt_project_task_binds(project_id, task_id)"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.18', modified = now() where param_name = 'version_db' and param_value = '1.18.17'"); - setChange("ALTER TABLE `tt_fav_reports` ADD `group_id` int(11) default NULL AFTER `user_id`"); - setChange("ALTER TABLE `tt_fav_reports` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.19', modified = now() where param_name = 'version_db' and param_value = '1.18.18'"); - setChange("update `tt_fav_reports` fr inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.19') inner join `tt_users` u on u.id = fr.user_id set fr.group_id = u.group_id, fr.org_id = u.org_id where fr.org_id is null"); - setChange("ALTER TABLE `tt_cron` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.20', modified = now() where param_name = 'version_db' and param_value = '1.18.19'"); - setChange("UPDATE `tt_cron` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.20') set org_id = group_id where org_id is null"); - setChange("ALTER TABLE `tt_client_project_binds` ADD `group_id` int(11) default NULL AFTER `project_id`"); - setChange("ALTER TABLE `tt_client_project_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("update `tt_client_project_binds` cpb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.20') inner join `tt_clients` c on c.id = cpb.client_id set cpb.group_id = c.group_id, cpb.org_id = c.org_id where cpb.org_id is null"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.21', modified = now() where param_name = 'version_db' and param_value = '1.18.20'"); - setChange("create unique index client_project_idx on tt_client_project_binds(client_id, project_id)"); - setChange("ALTER TABLE `tt_config` ADD `group_id` int(11) default NULL AFTER `user_id`"); - setChange("ALTER TABLE `tt_config` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.22', modified = now() where param_name = 'version_db' and param_value = '1.18.21'"); - setChange("update `tt_config` c inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.22') inner join `tt_users` u on u.id = c.user_id set c.group_id = u.group_id, c.org_id = u.org_id where c.org_id is null"); - setChange("ALTER TABLE `tt_custom_fields` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("ALTER TABLE `tt_custom_field_options` ADD `group_id` int(11) default NULL AFTER `id`"); - setChange("ALTER TABLE `tt_custom_field_options` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("ALTER TABLE `tt_custom_field_log` ADD `group_id` int(11) default NULL AFTER `id`"); - setChange("ALTER TABLE `tt_custom_field_log` ADD `org_id` int(11) default NULL AFTER `group_id`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.23', modified = now() where param_name = 'version_db' and param_value = '1.18.22'"); - setChange("UPDATE `tt_custom_fields` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') set org_id = group_id where org_id is null"); - setChange("update `tt_custom_field_options` cfo inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfo.field_id set cfo.group_id = cf.group_id, cfo.org_id = cf.org_id where cfo.org_id is null"); - setChange("update `tt_custom_field_log` cfl inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfl.field_id set cfl.group_id = cf.group_id, cfl.org_id = cf.org_id where cfl.org_id is null"); - setChange("ALTER TABLE `tt_custom_field_options` ADD `status` tinyint(4) default '1' after `value`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.24', modified = now() where param_name = 'version_db' and param_value = '1.18.23'"); - setChange("ALTER TABLE `tt_groups` ADD COLUMN `description` varchar(255) default NULL after `name`"); - setChange("UPDATE `tt_site_config` SET param_value = '1.18.26', modified = now() where param_name = 'version_db' and param_value = '1.18.24'"); - setChange("update `tt_client_project_binds` cpb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.26') inner join `tt_clients` c on c.id = cpb.client_id set cpb.group_id = c.group_id, cpb.org_id = c.org_id where cpb.org_id is null"); + ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.00', modified = now() where param_name = 'version_db' and param_value = '1.17.97'"); + ttExecute("create index log_idx on tt_custom_field_log(log_id)"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.05', modified = now() where param_name = 'version_db' and param_value = '1.18.00'"); + ttExecute("UPDATE `tt_groups` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.05') set org_id = id where org_id is null"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.06', modified = now() where param_name = 'version_db' and param_value = '1.18.05'"); + ttExecute("ALTER TABLE `tt_users` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.06') set org_id = group_id where org_id is null"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.07', modified = now() where param_name = 'version_db' and param_value = '1.18.06'"); + ttExecute("ALTER TABLE `tt_roles` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.07') set org_id = group_id where org_id is null"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.08', modified = now() where param_name = 'version_db' and param_value = '1.18.07'"); + ttExecute("ALTER TABLE `tt_clients` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.09', modified = now() where param_name = 'version_db' and param_value = '1.18.08'"); + ttExecute("UPDATE `tt_clients` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.09') set org_id = group_id where org_id is null"); + ttExecute("ALTER TABLE `tt_projects` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("ALTER TABLE `tt_tasks` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.10', modified = now() where param_name = 'version_db' and param_value = '1.18.09'"); + ttExecute("UPDATE `tt_projects` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.10') set org_id = group_id where org_id is null"); + ttExecute("UPDATE `tt_tasks` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.10') set org_id = group_id where org_id is null"); + ttExecute("ALTER TABLE `tt_log` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("ALTER TABLE `tt_invoices` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.11', modified = now() where param_name = 'version_db' and param_value = '1.18.10'"); + ttExecute("UPDATE `tt_log` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.11') set org_id = group_id where org_id is null"); + ttExecute("UPDATE `tt_invoices` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.11') set org_id = group_id where org_id is null"); + ttExecute("ALTER TABLE `tt_user_project_binds` ADD `group_id` int(11) default NULL AFTER `project_id`"); + ttExecute("ALTER TABLE `tt_user_project_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("ALTER TABLE `tt_project_task_binds` ADD `group_id` int(11) default NULL AFTER `task_id`"); + ttExecute("ALTER TABLE `tt_project_task_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.12', modified = now() where param_name = 'version_db' and param_value = '1.18.11'"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.13', modified = now() where param_name = 'version_db' and param_value = '1.18.12'"); + ttExecute("ALTER TABLE `tt_users` MODIFY `login` varchar(50) COLLATE utf8mb4_bin NOT NULL"); + ttExecute("ALTER TABLE `tt_projects` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); + ttExecute("ALTER TABLE `tt_tasks` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); + ttExecute("ALTER TABLE `tt_invoices` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); + ttExecute("ALTER TABLE `tt_clients` MODIFY `name` varchar(80) COLLATE utf8mb4_bin NOT NULL"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.14', modified = now() where param_name = 'version_db' and param_value = '1.18.13'"); + ttExecute("ALTER TABLE `tt_monthly_quotas` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_monthly_quotas` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.14') set org_id = group_id where org_id is null"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.15', modified = now() where param_name = 'version_db' and param_value = '1.18.14'"); + ttExecute("ALTER TABLE `tt_predefined_expenses` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.16', modified = now() where param_name = 'version_db' and param_value = '1.18.15'"); + ttExecute("UPDATE `tt_predefined_expenses` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.16') set org_id = group_id where org_id is null"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.17', modified = now() where param_name = 'version_db' and param_value = '1.18.16'"); + ttExecute("UPDATE `tt_expense_items` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') set org_id = group_id where org_id is null"); + ttExecute("update `tt_user_project_binds` upb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_users` u on u.id = upb.user_id set upb.group_id = u.group_id, upb.org_id = u.org_id where upb.org_id is null"); + ttExecute("update `tt_project_task_binds` ptb inner join tt_site_config sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.17') inner join `tt_projects` p on p.id = ptb.project_id set ptb.group_id = p.group_id, ptb.org_id = p.org_id where ptb.org_id is null"); + ttExecute("create unique index project_task_idx on tt_project_task_binds(project_id, task_id)"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.18', modified = now() where param_name = 'version_db' and param_value = '1.18.17'"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_id` int(11) default NULL AFTER `user_id`"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.19', modified = now() where param_name = 'version_db' and param_value = '1.18.18'"); + ttExecute("update `tt_fav_reports` fr inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.19') inner join `tt_users` u on u.id = fr.user_id set fr.group_id = u.group_id, fr.org_id = u.org_id where fr.org_id is null"); + ttExecute("ALTER TABLE `tt_cron` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.20', modified = now() where param_name = 'version_db' and param_value = '1.18.19'"); + ttExecute("UPDATE `tt_cron` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.20') set org_id = group_id where org_id is null"); + ttExecute("ALTER TABLE `tt_client_project_binds` ADD `group_id` int(11) default NULL AFTER `project_id`"); + ttExecute("ALTER TABLE `tt_client_project_binds` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("update `tt_client_project_binds` cpb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.20') inner join `tt_clients` c on c.id = cpb.client_id set cpb.group_id = c.group_id, cpb.org_id = c.org_id where cpb.org_id is null"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.21', modified = now() where param_name = 'version_db' and param_value = '1.18.20'"); + ttExecute("create unique index client_project_idx on tt_client_project_binds(client_id, project_id)"); + ttExecute("ALTER TABLE `tt_config` ADD `group_id` int(11) default NULL AFTER `user_id`"); + ttExecute("ALTER TABLE `tt_config` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.22', modified = now() where param_name = 'version_db' and param_value = '1.18.21'"); + ttExecute("update `tt_config` c inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.22') inner join `tt_users` u on u.id = c.user_id set c.group_id = u.group_id, c.org_id = u.org_id where c.org_id is null"); + ttExecute("ALTER TABLE `tt_custom_fields` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("ALTER TABLE `tt_custom_field_options` ADD `group_id` int(11) default NULL AFTER `id`"); + ttExecute("ALTER TABLE `tt_custom_field_options` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("ALTER TABLE `tt_custom_field_log` ADD `group_id` int(11) default NULL AFTER `id`"); + ttExecute("ALTER TABLE `tt_custom_field_log` ADD `org_id` int(11) default NULL AFTER `group_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.23', modified = now() where param_name = 'version_db' and param_value = '1.18.22'"); + ttExecute("UPDATE `tt_custom_fields` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') set org_id = group_id where org_id is null"); + ttExecute("update `tt_custom_field_options` cfo inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfo.field_id set cfo.group_id = cf.group_id, cfo.org_id = cf.org_id where cfo.org_id is null"); + ttExecute("update `tt_custom_field_log` cfl inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.23') inner join `tt_custom_fields` cf on cf.id = cfl.field_id set cfl.group_id = cf.group_id, cfl.org_id = cf.org_id where cfl.org_id is null"); + ttExecute("ALTER TABLE `tt_custom_field_options` ADD `status` tinyint(4) default '1' after `value`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.24', modified = now() where param_name = 'version_db' and param_value = '1.18.23'"); + ttExecute("ALTER TABLE `tt_groups` ADD COLUMN `description` varchar(255) default NULL after `name`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.26', modified = now() where param_name = 'version_db' and param_value = '1.18.24'"); + ttExecute("update `tt_client_project_binds` cpb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.26') inner join `tt_clients` c on c.id = cpb.client_id set cpb.group_id = c.group_id, cpb.org_id = c.org_id where cpb.org_id is null"); } if ($_POST["cleanup"]) { @@ -1054,30 +1054,30 @@ function setChange($sql) { $res = ttOrgHelper::deleteOrg($inactive_orgs[$i]); } - setChange("OPTIMIZE TABLE tt_client_project_binds"); - setChange("OPTIMIZE TABLE tt_clients"); - setChange("OPTIMIZE TABLE tt_config"); - setChange("OPTIMIZE TABLE tt_cron"); - setChange("OPTIMIZE TABLE tt_custom_field_log"); - setChange("OPTIMIZE TABLE tt_custom_field_options"); - setChange("OPTIMIZE TABLE tt_custom_fields"); - setChange("OPTIMIZE TABLE tt_expense_items"); - setChange("OPTIMIZE TABLE tt_fav_reports"); - setChange("OPTIMIZE TABLE tt_invoices"); - setChange("OPTIMIZE TABLE tt_log"); - setChange("OPTIMIZE TABLE tt_monthly_quotas"); - setChange("OPTIMIZE TABLE tt_predefined_expenses"); - setChange("OPTIMIZE TABLE tt_project_task_binds"); - setChange("OPTIMIZE TABLE tt_projects"); - setChange("OPTIMIZE TABLE tt_tasks"); - setChange("OPTIMIZE TABLE tt_groups"); - setChange("OPTIMIZE TABLE tt_tmp_refs"); - setChange("OPTIMIZE TABLE tt_user_project_binds"); - setChange("OPTIMIZE TABLE tt_users"); - setChange("OPTIMIZE TABLE tt_roles"); + ttExecute("OPTIMIZE TABLE tt_client_project_binds"); + ttExecute("OPTIMIZE TABLE tt_clients"); + ttExecute("OPTIMIZE TABLE tt_config"); + ttExecute("OPTIMIZE TABLE tt_cron"); + ttExecute("OPTIMIZE TABLE tt_custom_field_log"); + ttExecute("OPTIMIZE TABLE tt_custom_field_options"); + ttExecute("OPTIMIZE TABLE tt_custom_fields"); + ttExecute("OPTIMIZE TABLE tt_expense_items"); + ttExecute("OPTIMIZE TABLE tt_fav_reports"); + ttExecute("OPTIMIZE TABLE tt_invoices"); + ttExecute("OPTIMIZE TABLE tt_log"); + ttExecute("OPTIMIZE TABLE tt_monthly_quotas"); + ttExecute("OPTIMIZE TABLE tt_predefined_expenses"); + ttExecute("OPTIMIZE TABLE tt_project_task_binds"); + ttExecute("OPTIMIZE TABLE tt_projects"); + ttExecute("OPTIMIZE TABLE tt_tasks"); + ttExecute("OPTIMIZE TABLE tt_groups"); + ttExecute("OPTIMIZE TABLE tt_tmp_refs"); + ttExecute("OPTIMIZE TABLE tt_user_project_binds"); + ttExecute("OPTIMIZE TABLE tt_users"); + ttExecute("OPTIMIZE TABLE tt_roles"); } - print "done.
\n"; + print "Done.
\n"; } ?> From 03e3d32869aa0791e1d841be69cf5c0c84a5450f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 Dec 2018 16:43:13 +0000 Subject: [PATCH 0515/1848] More refactoring for subgroups. --- WEB-INF/lib/ttGroup.class.php | 2 +- WEB-INF/lib/ttUser.class.php | 9 +++-- WEB-INF/templates/expenses.tpl | 4 +-- WEB-INF/templates/footer.tpl | 2 +- charts.php | 5 +-- expenses.php | 60 +++++++++++++++++++--------------- 6 files changed, 48 insertions(+), 34 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index b0c50eef5..bb03845d8 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -97,8 +97,8 @@ function __construct($id, $org_id) { */ $this->currency = $val['currency']; $this->plugins = $val['plugins']; - /* $this->lock_spec = $val['lock_spec']; + /* $this->workday_minutes = $val['workday_minutes']; $this->custom_logo = $val['custom_logo']; */ diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 548d70ec7..05081c5ab 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -209,6 +209,11 @@ function getPlugins() { return ($this->behalfGroup ? $this->behalfGroup->plugins : $this->plugins); } + // getLockSpec returns lock specification for active group. + function getLockSpec() { + return ($this->behalfGroup ? $this->behalfGroup->lock_spec : $this->lock_spec); + } + // getConfig returns config string for active group. function getConfig() { return ($this->behalfGroup ? $this->behalfGroup->config : $this->config); @@ -329,7 +334,7 @@ function isDateLocked($date) if (!$this->isPluginEnabled('lk')) return false; // Locking feature is disabled. - if (!$this->lock_spec) + if (!$this->getLockSpec()) return false; // There is no lock specification. if (!$this->behalf_id && $this->can('override_own_date_lock')) @@ -342,7 +347,7 @@ function isDateLocked($date) require_once(LIBRARY_DIR.'/tdcron/class.tdcron.entry.php'); // Calculate the last occurrence of a lock. - $last = tdCron::getLastOccurrence($this->lock_spec, time()); + $last = tdCron::getLastOccurrence($this->getLockSpec(), time()); $lockdate = new DateAndTime(DB_DATEFORMAT, strftime('%Y-%m-%d', $last)); if ($date->before($lockdate)) return true; diff --git a/WEB-INF/templates/expenses.tpl b/WEB-INF/templates/expenses.tpl index 8e1ef0a8d..17b8c8fb5 100644 --- a/WEB-INF/templates/expenses.tpl +++ b/WEB-INF/templates/expenses.tpl @@ -117,10 +117,10 @@ function recalculateCost() {
-{if $on_behalf_control} +{if $user_dropdown} - + {/if} {if $user->isPluginEnabled('cl')} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d7903e75c..96fdee801 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.user}:{$forms.expensesForm.onBehalfUser.control}{$forms.expensesForm.user.control}
- {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} @@ -178,7 +178,7 @@ function recalculateCost() { {if $user->isPluginEnabled('cl')} {/if} - {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $show_project} {/if} @@ -190,7 +190,7 @@ function recalculateCost() { {if $user->isPluginEnabled('cl')} {/if} - {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $show_project} {/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 96fdee801..99e8d0eee 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4590 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4591 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/charts.php b/charts.php index adaa8ae52..6329e14f8 100644 --- a/charts.php +++ b/charts.php @@ -114,10 +114,11 @@ // User dropdown. Changes the user "on behalf" of whom we are working. if ($user->can('view_charts')) { + $rank = $user->getMaxRankForGroup($user->getGroup()); if ($user->can('view_own_charts')) - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_self'=>true,'self_first'=>true); + $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); else - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1); + $options = array('status'=>ACTIVE,'max_rank'=>$rank); $user_list = $user->getUsers($options); if (count($user_list) >= 1) { $chart_form->addInput(array('type'=>'combobox', diff --git a/expenses.php b/expenses.php index e459c37c5..fa844a22b 100644 --- a/expenses.php +++ b/expenses.php @@ -50,8 +50,26 @@ header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. exit(); } +if ($request->isPost() && $request->getParameter('user')) { + if (!$user->isUserValid($request->getParameter('user'))) { + header('Location: access_denied.php'); // Wrong user id on post. + exit(); + } +} // End of access checks. +// Determine user for which we display this page. +$userChanged = $request->getParameter('user_changed'); +if ($request->isPost() && $userChanged) { + $user_id = $request->getParameter('user'); + $user->setOnBehalfUser($user_id); +} else { + $user_id = $user->getUser(); + // Handle a situation for no users in on behalf group. + if ($user->behalfGroup && $user_id == $user->id) + $user_id = null; +} + // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); $selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); @@ -61,8 +79,10 @@ $cl_date = $selected_date->toString(DB_DATEFORMAT); $_SESSION['date'] = $cl_date; +$tracking_mode = $user->getTrackingMode(); +$show_project = MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode; + // Initialize variables. -$on_behalf_id = $request->getParameter('onBehalfUser', (isset($_SESSION['behalf_id']) ? $_SESSION['behalf_id'] : $user->id)); $cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); $_SESSION['client'] = $cl_client; $cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); @@ -74,25 +94,27 @@ $form = new Form('expensesForm'); if ($user->can('track_expenses')) { + $rank = $user->getMaxRankForGroup($user->getGroup()); if ($user->can('track_own_expenses')) - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_self'=>true,'self_first'=>true); + $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); else - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1); + $options = array('status'=>ACTIVE,'max_rank'=>$rank); $user_list = $user->getUsers($options); if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.submit();', - 'name'=>'onBehalfUser', + 'onchange'=>'this.form.user_changed.value=1;this.form.submit();', + 'name'=>'user', 'style'=>'width: 250px;', - 'value'=>$on_behalf_id, + 'value'=>$user_id, 'data'=>$user_list, 'datakeys'=>array('id','name'))); - $smarty->assign('on_behalf_control', 1); + $form->addInput(array('type'=>'hidden','name'=>'user_changed')); + $smarty->assign('user_dropdown', 1); } } // Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { +if (MODE_TIME == $tracking_mode && $user->isPluginEnabled('cl')) { $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', @@ -105,11 +127,10 @@ // Note: in other modes the client list is filtered to relevant clients only. See below. } -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { +if ($show_project) { // Dropdown for projects assigned to user. $project_list = $user->getAssignedProjects(); $form->addInput(array('type'=>'combobox', - // 'onchange'=>'fillTaskDropdown(this.value);', 'name'=>'project', 'style'=>'width: 250px;', 'value'=>$cl_project, @@ -169,14 +190,13 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) $err->add($i18n->get('error.client')); - if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } + if ($show_project && !$cl_project) + $err->add($i18n->get('error.project')); if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->getConfigOption('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); @@ -196,18 +216,6 @@ } else $err->add($i18n->get('error.db')); } - } elseif ($request->getParameter('onBehalfUser')) { - if($user->can('track_expenses')) { - unset($_SESSION['behalf_id']); - unset($_SESSION['behalf_name']); - - if($on_behalf_id != $user->id) { - $_SESSION['behalf_id'] = $on_behalf_id; - $_SESSION['behalf_name'] = ttUserHelper::getUserName($on_behalf_id); - } - header('Location: expenses.php'); - exit(); - } } } From 7b6cfb2cceac61a6e899590ac8ac9fa8cb326c6a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 Dec 2018 17:29:56 +0000 Subject: [PATCH 0516/1848] A bit more refactoring for subgroups. --- WEB-INF/templates/expenses.tpl | 6 +++--- WEB-INF/templates/footer.tpl | 2 +- expenses.php | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/expenses.tpl b/WEB-INF/templates/expenses.tpl index 17b8c8fb5..4eea0b8d6 100644 --- a/WEB-INF/templates/expenses.tpl +++ b/WEB-INF/templates/expenses.tpl @@ -129,7 +129,7 @@ function recalculateCost() { {$forms.expensesForm.client.control}
{$i18n.label.project} (*): {$forms.expensesForm.project.control}{$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$item.client|escape}{$item.project|escape}{$item.item|escape}
- {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} @@ -160,7 +160,7 @@ function recalculateCost() { - + {if ($user->can('manage_invoices') && $user->isPluginEnabled('ps'))} diff --git a/WEB-INF/templates/expenses.tpl b/WEB-INF/templates/expenses.tpl index 4eea0b8d6..45a8ef274 100644 --- a/WEB-INF/templates/expenses.tpl +++ b/WEB-INF/templates/expenses.tpl @@ -151,7 +151,7 @@ function recalculateCost() { - +
 Anuko Time Tracker 1.18.29.4591 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4592 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expenses.php b/expenses.php index fa844a22b..eb11e73a3 100644 --- a/expenses.php +++ b/expenses.php @@ -219,13 +219,14 @@ } } +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('show_project', $show_project); $smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); $smarty->assign('expense_items', ttExpenseHelper::getItems($cl_date)); $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('timestring', $selected_date->toString($user->date_format)); +$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); $smarty->assign('title', $i18n->get('title.expenses')); $smarty->assign('content_page_name', 'expenses.tpl'); $smarty->display('index.tpl'); From cb611bf2abbb4072459632155b11301ae6fe840b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 Dec 2018 19:31:43 +0000 Subject: [PATCH 0517/1848] Refactored regular expense pages for subgroups. --- WEB-INF/lib/common.lib.php | 2 +- WEB-INF/lib/ttExpenseHelper.class.php | 2 +- WEB-INF/lib/ttUserHelper.class.php | 2 +- WEB-INF/templates/expense_edit.tpl | 10 +++++----- WEB-INF/templates/expenses.tpl | 2 +- WEB-INF/templates/footer.tpl | 2 +- expense_edit.php | 5 +++-- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 4411fb585..0e9ff9e49 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -226,7 +226,7 @@ function ttValidFloat($val, $emptyValid = false) return ($emptyValid ? true : false); global $user; - $decimal = $user->decimal_mark; + $decimal = $user->getDecimalMark(); if (!preg_match('/^-?[0-9'.$decimal.']+$/', $val)) return false; diff --git a/WEB-INF/lib/ttExpenseHelper.class.php b/WEB-INF/lib/ttExpenseHelper.class.php index 0b202c6bf..40a3e88f0 100644 --- a/WEB-INF/lib/ttExpenseHelper.class.php +++ b/WEB-INF/lib/ttExpenseHelper.class.php @@ -60,12 +60,12 @@ static function update($fields) { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; $id = (int) $fields['id']; $date = $fields['date']; - $user_id = (int) $fields['user_id']; $client_id = $fields['client_id']; $project_id = $fields['project_id']; $name = $fields['name']; diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 1d1b178a6..0d628f6d0 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -189,7 +189,7 @@ static function update($user_id, $fields) { // otherwise de-activate the bind (set its status to inactive). This will keep the bind // and its rate in database for reporting. - $all_projects = ttTeamHelper::getAllProjects($user->group_id); + $all_projects = ttTeamHelper::getAllProjects($user->getGroup()); $assigned_projects = isset($fields['projects']) ? $fields['projects'] : array(); foreach($all_projects as $p) { diff --git a/WEB-INF/templates/expense_edit.tpl b/WEB-INF/templates/expense_edit.tpl index d3a27375c..850e6442a 100644 --- a/WEB-INF/templates/expense_edit.tpl +++ b/WEB-INF/templates/expense_edit.tpl @@ -98,7 +98,7 @@ function recalculateCost() { var comment_control = document.getElementById("item_name"); var cost_control = document.getElementById("cost"); - var replaceDecimalMark = ("." != "{$user->decimal_mark}"); + var replaceDecimalMark = ("." != "{$user->getDecimalMark()}"); // Calculate cost. var dropdown = document.getElementById("predefined_expense"); @@ -114,10 +114,10 @@ function recalculateCost() { else { var expenseCost = defined_expenses[dropdown.selectedIndex - 1][2]; if (replaceDecimalMark) - expenseCost = expenseCost.replace("{$user->decimal_mark}", "."); + expenseCost = expenseCost.replace("{$user->getDecimalMark()}", "."); var newCost = (quantity_control.value * expenseCost).toFixed(2); if (replaceDecimalMark) - newCost = newCost.replace(".", "{$user->decimal_mark}"); + newCost = newCost.replace(".", "{$user->getDecimalMark()}"); cost_control.value = newCost; } } @@ -138,7 +138,7 @@ function recalculateCost() { {$forms.expenseItemForm.client.control}
{$i18n.label.project} (*): {$forms.expenseItemForm.project.control}
{$i18n.label.cost}:{$forms.expenseItemForm.cost.control} {$user->currency|escape}{$forms.expenseItemForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.cost} (*):{$forms.expensesForm.cost.control} {$user->currency|escape}{$forms.expensesForm.cost.control} {$user->getCurrency()|escape}
- {if $user->isPluginEnabled('cl')} - + {/if} {if $show_project} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 14d272ea3..b2cdebb71 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4592 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4593 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expense_edit.php b/expense_edit.php index 667d03468..8eb7d4fe0 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -194,7 +194,7 @@ // Now, an update. if ($err->no()) { - if (ttExpenseHelper::update(array('id'=>$cl_id,'date'=>$new_date->toString(DB_DATEFORMAT),'user_id'=>$user->getUser(), + if (ttExpenseHelper::update(array('id'=>$cl_id,'date'=>$new_date->toString(DB_DATEFORMAT), 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'paid'=>$cl_paid))) { header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); exit(); @@ -229,11 +229,12 @@ $smarty->assign('confirm_save', true); $smarty->assign('entry_date', $cl_date); } +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('show_project', $show_project); $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_expense')); $smarty->assign('content_page_name', 'expense_edit.tpl'); $smarty->display('index.tpl'); From aeb30899d6ec142220d83b34fd8f6c68c05e8e90 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 Dec 2018 20:39:25 +0000 Subject: [PATCH 0518/1848] Refactored mobile expenses.php for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/expenses.tpl | 20 +++++----- mobile/expenses.php | 53 +++++++++++++++++++-------- 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 20a0db7cb..14d272ea3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- @@ -189,7 +189,7 @@ function recalculateCost() { {if $user->isPluginEnabled('cl')} {/if} - {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $show_project} {/if} @@ -200,7 +200,7 @@ function recalculateCost() { {if $user->isPluginEnabled('cl')} {/if} - {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $show_project} {/if} @@ -210,7 +210,7 @@ function recalculateCost() {
 Anuko Time Tracker 1.18.29.4593 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4594 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/expenses.tpl b/WEB-INF/templates/mobile/expenses.tpl index d8e8612da..a6aa66d99 100644 --- a/WEB-INF/templates/mobile/expenses.tpl +++ b/WEB-INF/templates/mobile/expenses.tpl @@ -86,7 +86,7 @@ function recalculateCost() { var comment_control = document.getElementById("item_name"); var cost_control = document.getElementById("cost"); - var replaceDecimalMark = ("." != "{$user->decimal_mark}"); + var replaceDecimalMark = ("." != "{$user->getDecimalMark()}"); // Calculate cost. var dropdown = document.getElementById("predefined_expense"); @@ -102,10 +102,10 @@ function recalculateCost() { else { var expenseCost = defined_expenses[dropdown.selectedIndex - 1][2]; if (replaceDecimalMark) - expenseCost = expenseCost.replace("{$user->decimal_mark}", "."); + expenseCost = expenseCost.replace("{$user->getDecimalMark()}", "."); var newCost = (quantity_control.value * expenseCost).toFixed(2); if (replaceDecimalMark) - newCost = newCost.replace(".", "{$user->decimal_mark}"); + newCost = newCost.replace(".", "{$user->getDecimalMark()}"); cost_control.value = newCost; } } @@ -126,10 +126,10 @@ function recalculateCost() {
-{if $on_behalf_control} +{if $user_dropdown} - + {/if} {if $user->isPluginEnabled('cl')} @@ -138,7 +138,7 @@ function recalculateCost() { {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} @@ -160,7 +160,7 @@ function recalculateCost() { - +
{$i18n.label.user}:{$forms.expensesForm.onBehalfUser.control}{$forms.expensesForm.user.control}
{$forms.expensesForm.client.control}
{$i18n.label.project} (*): {$forms.expensesForm.project.control}
{$i18n.label.cost} (*):{$forms.expensesForm.cost.control} {$user->currency|escape}{$forms.expensesForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$item.client|escape}{$item.project|escape}{if $item.invoice_id} {$item.item|escape} {else}{$item.item|escape}{/if}
- +
{$i18n.label.day_total}: {$user->currency|escape} {$day_total}{$i18n.label.day_total}: {$user->getCurrency()|escape} {$day_total}
{/if} diff --git a/mobile/expenses.php b/mobile/expenses.php index 84d29738a..eeece0035 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -50,6 +50,25 @@ header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. exit(); } +if ($request->isPost() && $request->getParameter('user')) { + if (!$user->isUserValid($request->getParameter('user'))) { + header('Location: access_denied.php'); // Wrong user id on post. + exit(); + } +} +// End of access checks. + +// Determine user for which we display this page. +$userChanged = $request->getParameter('user_changed'); +if ($request->isPost() && $userChanged) { + $user_id = $request->getParameter('user'); + $user->setOnBehalfUser($user_id); +} else { + $user_id = $user->getUser(); + // Handle a situation for no users in on behalf group. + if ($user->behalfGroup && $user_id == $user->id) + $user_id = null; +} // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -64,8 +83,10 @@ $prev_date = date('Y-m-d', strtotime('-1 day', strtotime($cl_date))); $next_date = date('Y-m-d', strtotime('+1 day', strtotime($cl_date))); +$tracking_mode = $user->getTrackingMode(); +$show_project = MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode; + // Initialize variables. -$on_behalf_id = $request->getParameter('onBehalfUser', (isset($_SESSION['behalf_id']) ? $_SESSION['behalf_id'] : $user->id)); $cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); $_SESSION['client'] = $cl_client; $cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); @@ -77,25 +98,27 @@ $form = new Form('expensesForm'); if ($user->can('track_expenses')) { + $rank = $user->getMaxRankForGroup($user->getGroup()); if ($user->can('track_own_expenses')) - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_self'=>true,'self_first'=>true); + $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); else - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1); + $options = array('status'=>ACTIVE,'max_rank'=>$rank); $user_list = $user->getUsers($options); if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.submit();', - 'name'=>'onBehalfUser', + 'onchange'=>'this.form.user_changed.value=1;this.form.submit();', + 'name'=>'user', 'style'=>'width: 250px;', - 'value'=>$on_behalf_id, + 'value'=>$user_id, 'data'=>$user_list, 'datakeys'=>array('id','name'))); - $smarty->assign('on_behalf_control', 1); + $form->addInput(array('type'=>'hidden','name'=>'user_changed')); + $smarty->assign('user_dropdown', 1); } } // Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { +if (MODE_TIME == $tracking_mode && $user->isPluginEnabled('cl')) { $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', @@ -108,7 +131,7 @@ // Note: in other modes the client list is filtered to relevant clients only. See below. } -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { +if ($show_project) { // Dropdown for projects assigned to user. $project_list = $user->getAssignedProjects(); $form->addInput(array('type'=>'combobox', @@ -172,14 +195,13 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) $err->add($i18n->get('error.client')); - if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } + if ($show_project && !$cl_project) + $err->add($i18n->get('error.project')); if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->getConfigOption('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); @@ -214,6 +236,8 @@ } } +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('show_project', $show_project); $smarty->assign('next_date', $next_date); $smarty->assign('prev_date', $prev_date); $smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); @@ -221,8 +245,7 @@ $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('timestring', $selected_date->toString($user->date_format)); +$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); $smarty->assign('title', $i18n->get('title.expenses')); $smarty->assign('content_page_name', 'mobile/expenses.tpl'); $smarty->display('mobile/index.tpl'); From bfc14fc0033335223de2268ecbd9c7a3e8d8aa21 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 Dec 2018 21:10:40 +0000 Subject: [PATCH 0519/1848] Finished refactoring mobile expense pages for subgroups. --- WEB-INF/templates/expense_delete.tpl | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/expense_delete.tpl | 2 +- WEB-INF/templates/mobile/expense_edit.tpl | 10 ++++----- mobile/expense_edit.php | 23 ++++++++++++--------- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/WEB-INF/templates/expense_delete.tpl b/WEB-INF/templates/expense_delete.tpl index e2c1b6710..6e5bf12c8 100644 --- a/WEB-INF/templates/expense_delete.tpl +++ b/WEB-INF/templates/expense_delete.tpl @@ -16,7 +16,7 @@
{$expense_item.client_name|escape}{$expense_item.client_name|escape}{$expense_item.project_name|escape}
- {if $user->isPluginEnabled('cl')} - + {/if} {if $show_project} diff --git a/WEB-INF/templates/mobile/expense_edit.tpl b/WEB-INF/templates/mobile/expense_edit.tpl index 971405079..708cc23c4 100644 --- a/WEB-INF/templates/mobile/expense_edit.tpl +++ b/WEB-INF/templates/mobile/expense_edit.tpl @@ -98,7 +98,7 @@ function recalculateCost() { var comment_control = document.getElementById("item_name"); var cost_control = document.getElementById("cost"); - var replaceDecimalMark = ("." != "{$user->decimal_mark}"); + var replaceDecimalMark = ("." != "{$user->getDecimalMark()}"); // Calculate cost. var dropdown = document.getElementById("predefined_expense"); @@ -114,10 +114,10 @@ function recalculateCost() { else { var expenseCost = defined_expenses[dropdown.selectedIndex - 1][2]; if (replaceDecimalMark) - expenseCost = expenseCost.replace("{$user->decimal_mark}", "."); + expenseCost = expenseCost.replace("{$user->getDecimalMark()}", "."); var newCost = (quantity_control.value * expenseCost).toFixed(2); if (replaceDecimalMark) - newCost = newCost.replace(".", "{$user->decimal_mark}"); + newCost = newCost.replace(".", "{$user->getDecimalMark()}"); cost_control.value = newCost; } } @@ -138,7 +138,7 @@ function recalculateCost() { {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} @@ -160,7 +160,7 @@ function recalculateCost() { - + diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index 0f657973c..4c183afd9 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -49,9 +49,12 @@ header('Location: access_denied.php'); exit(); } +// End of access checks. $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); $confirm_save = $user->getConfigOption('confirm_save'); +$trackingMode = $user->getTrackingMode(); +$show_project = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; // Initialize variables. $cl_date = $cl_client = $cl_project = $cl_item_name = $cl_cost = null; @@ -62,7 +65,7 @@ $cl_item_name = trim($request->getParameter('item_name')); $cl_cost = trim($request->getParameter('cost')); } else { - $cl_date = $item_date->toString($user->date_format); + $cl_date = $item_date->toString($user->getDateFormat()); $cl_client = $expense_item['client_id']; $cl_project = $expense_item['project_id']; $cl_item_name = $expense_item['name']; @@ -73,7 +76,7 @@ $form = new Form('expenseItemForm'); // Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { +if (MODE_TIME == $trackingMode && $user->isPluginEnabled('cl')) { $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', @@ -86,7 +89,7 @@ // Note: in other modes the client list is filtered to relevant clients only. See below. } -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { +if ($show_project) { // Dropdown for projects assigned to user. $project_list = $user->getAssignedProjects(); $form->addInput(array('type'=>'combobox', @@ -153,18 +156,17 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) $err->add($i18n->get('error.client')); - if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } + if ($show_project && !$cl_project) + $err->add($i18n->get('error.project')); if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); // This is a new date for the expense item. - $new_date = new DateAndTime($user->date_format, $cl_date); + $new_date = new DateAndTime($user->getDateFormat(), $cl_date); // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->getConfigOption('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); @@ -187,7 +189,7 @@ // Now, an update. if ($err->no()) { - if (ttExpenseHelper::update(array('id'=>$cl_id,'date'=>$new_date->toString(DB_DATEFORMAT),'user_id'=>$user->getUser(), + if (ttExpenseHelper::update(array('id'=>$cl_id,'date'=>$new_date->toString(DB_DATEFORMAT), 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost))) { header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); exit(); @@ -222,11 +224,12 @@ $smarty->assign('confirm_save', true); $smarty->assign('entry_date', $cl_date); } +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('show_project', $show_project); $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_expense')); $smarty->assign('content_page_name', 'mobile/expense_edit.tpl'); $smarty->display('mobile/index.tpl'); From a106b7a2db73b3e1fdab428b218212f6f38d7623 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 Dec 2018 13:39:13 +0000 Subject: [PATCH 0520/1848] Added conditional display of pages depending on subgroup active users. --- WEB-INF/lib/ttGroup.class.php | 15 +++++++++++++++ WEB-INF/lib/ttUser.class.php | 15 ++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 13 +++++++------ WEB-INF/templates/mobile/header.tpl | 8 ++++---- charts.php | 7 ++++--- expenses.php | 7 ++++--- mobile/expenses.php | 7 ++++--- mobile/projects.php | 2 +- mobile/tasks.php | 6 +++--- 10 files changed, 57 insertions(+), 25 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index bb03845d8..fe8c8a983 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -62,6 +62,9 @@ class ttGroup { var $first_unit_threshold = 0;// Threshold for 1st unit for Work units plugin. var $unit_totals_only = 0; // Totals only option for the Work units plugin. + var $active_users = 0; // Count of active users in group. + // We need a non-zero count to display some menus. + // Constructor. function __construct($id, $org_id) { $mdb2 = getConnection(); @@ -119,5 +122,17 @@ function __construct($id, $org_id) { } */ } + + // Determine active user count in a separate query. + // TODO: If performance becomes an issue, ivestigate combining 2 queries in one. + // At this time we only need to know if at least 1 active user exists. + $sql = "select count(*) as user_count from tt_users". + " where group_id = $id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) { + return; + } + $val = $res->fetchRow(); + $this->active_users = $val['user_count']; } } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 05081c5ab..7867ac8e8 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -810,7 +810,7 @@ function setOnBehalfGroup($group_id) { return; } - // setOnBehalfUser sets on behalf user both the object and the session. + // setOnBehalfUser sets on behalf user both the object and the session. function setOnBehalfUser($user_id) { // Unset things first. @@ -833,4 +833,17 @@ function setOnBehalfUser($user_id) { $this->behalf_name = $onBehalfUserName; return; } + + // The exists() function determines if an active user exists in context of a page. + // If we are working as self, true. + // If we are working in a subgroup with active users, true. + // If we are working in a subgroup without active users, false. + function exists() { + if (!$this->behalfGroup) + return true; // Working as self. + else if ($this->behalfGroup->active_users) + return true; // Subgroup has users. + + return false; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b2cdebb71..d59ff9e7d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4594 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4595 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/expense_delete.tpl b/WEB-INF/templates/mobile/expense_delete.tpl index cbd75aed4..bd14824e2 100644 --- a/WEB-INF/templates/mobile/expense_delete.tpl +++ b/WEB-INF/templates/mobile/expense_delete.tpl @@ -16,7 +16,7 @@
{$expense_item.client_name|escape}{$expense_item.client_name|escape}{$expense_item.project_name|escape}{$forms.expenseItemForm.client.control}
{$i18n.label.project} (*): {$forms.expenseItemForm.project.control}
{$i18n.label.cost}:{$forms.expenseItemForm.cost.control} {$user->currency|escape}{$forms.expenseItemForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.date}:
-
 Anuko Time Tracker 1.18.29.4595 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4596 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 57e842ee1..052702975 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -108,20 +108,21 @@
  - {if $user->can('track_own_time') || $user->can('track_time')} + {if $user->exists() && ($user->can('track_own_time') || $user->can('track_time'))} {$i18n.menu.time} {/if} - {if $user->isPluginEnabled('ex') && ($user->can('track_own_expenses') || $user->can('track_expenses'))} + {if $user->exists() && $user->isPluginEnabled('ex') && ($user->can('track_own_expenses') || $user->can('track_expenses'))} · {$i18n.menu.expenses} {/if} - {if $user->can('view_own_reports') || $user->can('view_reports')} + {if $user->exists() && ($user->can('view_own_reports') || $user->can('view_reports'))} · {$i18n.menu.reports} {/if} - {if $user->isPluginEnabled('iv') && ($user->can('view_own_invoices') || $user->can('manage_invoices'))} + {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('view_own_invoices') || $user->can('manage_invoices'))} · {$i18n.title.invoices} {/if} - {if ($user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts'))) && ($smarty.const.MODE_PROJECTS == $user->getTrackingMode() - || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() || $user->isPluginEnabled('cl'))} + {if ($user->exists() && $user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts'))) && + ($smarty.const.MODE_PROJECTS == $user->getTrackingMode() || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() || + $user->isPluginEnabled('cl'))} · {$i18n.menu.charts} {/if} {if ($user->can('view_own_projects') || $user->can('manage_projects')) && ($smarty.const.MODE_PROJECTS == $user->getTrackingMode() || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode())} diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index fdded891c..9e1c452da 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -73,16 +73,16 @@
  - {if $user->can('track_own_time') || $user->can('track_time')} + {if $user->exists() && ($user->can('track_own_time') || $user->can('track_time'))} {$i18n.menu.time} {/if} - {if $user->isPluginEnabled('ex') && ($user->can('track_own_expenses') || $user->can('track_expenses'))} + {if $user->exists() && $user->isPluginEnabled('ex') && ($user->can('track_own_expenses') || $user->can('track_expenses'))} · {$i18n.menu.expenses} {/if} - {if ($user->can('view_own_projects') || $user->can('manage_projects')) && ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if ($user->can('view_own_projects') || $user->can('manage_projects')) && ($smarty.const.MODE_PROJECTS == $user->getTrackingMode() || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode())} · {$i18n.menu.projects} {/if} - {if ($user->can('view_own_tasks') || $user->can('manage_tasks')) && $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode} + {if ($user->can('view_own_tasks') || $user->can('manage_tasks')) && $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()} · {$i18n.menu.tasks} {/if} {if $user->can('view_users') || $user->can('manage_users')} diff --git a/charts.php b/charts.php index 6329e14f8..862a2fad6 100644 --- a/charts.php +++ b/charts.php @@ -46,6 +46,10 @@ header('Location: feature_disabled.php'); exit(); } +if (!$user->exists()) { + header('Location: access_denied.php'); // Nobody to display a chart for. + exit(); +} if ($user->behalf_id && (!$user->can('view_charts') || !$user->checkBehalfId())) { header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. exit(); @@ -69,9 +73,6 @@ $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); - // Handle a situation for no users in on behalf group. - if ($user->behalfGroup && $user_id == $user->id) - $user_id = null; } $uc = new ttUserConfig(); diff --git a/expenses.php b/expenses.php index eb11e73a3..9a3454221 100644 --- a/expenses.php +++ b/expenses.php @@ -42,6 +42,10 @@ header('Location: feature_disabled.php'); exit(); } +if (!$user->exists()) { + header('Location: access_denied.php'); // Nobody to enter expenses for. + exit(); +} if ($user->behalf_id && (!$user->can('track_expenses') || !$user->checkBehalfId())) { header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. exit(); @@ -65,9 +69,6 @@ $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); - // Handle a situation for no users in on behalf group. - if ($user->behalfGroup && $user_id == $user->id) - $user_id = null; } // Initialize and store date in session. diff --git a/mobile/expenses.php b/mobile/expenses.php index eeece0035..ac565207b 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -42,6 +42,10 @@ header('Location: feature_disabled.php'); exit(); } +if (!$user->exists()) { + header('Location: access_denied.php'); // Nobody to enter expenses for. + exit(); +} if ($user->behalf_id && (!$user->can('track_expenses') || !$user->checkBehalfId())) { header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. exit(); @@ -65,9 +69,6 @@ $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); - // Handle a situation for no users in on behalf group. - if ($user->behalfGroup && $user_id == $user->id) - $user_id = null; } // Initialize and store date in session. diff --git a/mobile/projects.php b/mobile/projects.php index d244ae1b7..6a5ac572a 100644 --- a/mobile/projects.php +++ b/mobile/projects.php @@ -36,7 +36,7 @@ header('Location: access_denied.php'); exit(); } -if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +if (MODE_PROJECTS != $user->getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { header('Location: feature_disabled.php'); exit(); } diff --git a/mobile/tasks.php b/mobile/tasks.php index c45f9bf04..0667bc3bd 100644 --- a/mobile/tasks.php +++ b/mobile/tasks.php @@ -35,15 +35,15 @@ header('Location: access_denied.php'); exit(); } -if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +if (MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { header('Location: feature_disabled.php'); exit(); } // End of access checks. if($user->can('manage_tasks')) { - $active_tasks = ttTeamHelper::getActiveTasks($user->group_id); - $inactive_tasks = ttTeamHelper::getInactiveTasks($user->group_id); + $active_tasks = ttTeamHelper::getActiveTasks($user->getGroup()); + $inactive_tasks = ttTeamHelper::getInactiveTasks($user->getGroup()); } else $active_tasks = $user->getAssignedTasks(); From d368d8cfe50268648a7c9f94a031c9aa8f0f4549 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 Dec 2018 15:06:05 +0000 Subject: [PATCH 0521/1848] Fixed editing org by admin, added a comment for imported subgroups. --- WEB-INF/lib/ttAdmin.class.php | 13 +++++++++++-- WEB-INF/lib/ttGroup.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index 0e0532cee..383eb44c1 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -143,7 +143,7 @@ static function updateGroup($fields) { $password_part = ', password = md5('.$mdb2->quote($fields['password1']).')'; $name_part = ', name = '.$mdb2->quote($fields['user_name']); $email_part = ', email = '.$mdb2->quote($fields['email']); - $sql = 'update tt_users set '.$login_part.$password_part.$name_part.$email_part.$modified_part.'where id = '.$user_id; + $sql = 'update tt_users set '.$login_part.$password_part.$name_part.$email_part.$modified_part.' where id = '.$user_id; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -189,10 +189,19 @@ static function getOrgDetails($group_id) { $result = array(); $mdb2 = getConnection(); + // Note: current code works with properly set top manager (rank 512). + // However, we now allow export and import of subgroups, which seems to work well. + // In this situation, imported role is no longer "Top manager", and this call fails. + // Setting role id manually in database for top user to Top manager resolves the issue. + // + // TODO: assess whether it is safe / reasonable to promote role during export or import. + // The problem is that user having 'export_data' right is not necessarily top user. + // And if we do it by rank, what to do for multiple managers situation? First found? + // Leaving to manual fixing for now. $sql = "select g.name as group_name, u.id as manager_id, u.name as manager_name, u.login as manager_login, u.email as manager_email". " from tt_groups g". " inner join tt_users u on (u.group_id = g.id)". - " inner join tt_roles r on (r.id = u.role_id and r.rank = 512)". + " inner join tt_roles r on (r.id = u.role_id and r.rank = 512)". // Fails for partially imported org. See comment above. " where g.id = $group_id"; $res = $mdb2->query($sql); diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index fe8c8a983..1aa422c72 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -124,7 +124,7 @@ function __construct($id, $org_id) { } // Determine active user count in a separate query. - // TODO: If performance becomes an issue, ivestigate combining 2 queries in one. + // TODO: If performance becomes an issue, investigate combining 2 queries in one. // At this time we only need to know if at least 1 active user exists. $sql = "select count(*) as user_count from tt_users". " where group_id = $id and org_id = $org_id and status = 1"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d59ff9e7d..9d8323c4c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4596 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4597 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 3b59dadb0e60b3379dc2230ffd06c49eaa2e5ef3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 Dec 2018 19:22:54 +0000 Subject: [PATCH 0522/1848] Improvements to group editor - access checks and usability. --- WEB-INF/lib/ttGroupHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 2 +- group_delete.php | 18 ++-- group_edit.php | 132 +++++++++++++++------------- 5 files changed, 86 insertions(+), 70 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index e5288a096..1a32124cf 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -91,7 +91,7 @@ static function insertSubgroup($fields) { $name = $fields['name']; $description = $fields['description']; - // We need to inherit other attributes from the parent group. + // We need to inherit attributes from the parent group. $attrs = ttGroupHelper::getGroupAttrs($parent_id); $columns = '(parent_id, org_id, name, description, currency, decimal_mark, lang, date_format, time_format'. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9d8323c4c..e57d10e18 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4597 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4598 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index f839d7e93..bb83d3a3e 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -27,7 +27,7 @@ function handleTaskRequiredCheckbox() { {if isTrue($smarty.const.SUBGROUP_DEBUG)} -{if $user->can('manage_subgroups')} +{if $user->can('manage_subgroups') && $group_dropdown} diff --git a/group_delete.php b/group_delete.php index db24a4481..2865351a4 100644 --- a/group_delete.php +++ b/group_delete.php @@ -31,17 +31,21 @@ import('ttGroupHelper'); // Access checks. -if (!ttAccessAllowed('delete_group')) { +if (!(ttAccessAllowed('delete_group') || ttAccessAllowed('manage_subgroups'))) { header('Location: access_denied.php'); // No rights. exit(); } -if (!$user->isGroupValid($request->getParameter('id'))) { +$group_id = (int)$request->getParameter('id'); +if (!$user->isGroupValid($group_id)) { header('Location: access_denied.php'); // Wrong group id. exit(); } +if ($group_id == $user->group_id && !$user->can('delete_group')) { + header('Location: access_denied.php'); // Trying to delete home group without right. + exit(); +} // End of access checks. -$group_id = (int)$request->getParameter('id'); $group_name = ttGroupHelper::getGroupName($group_id); $form = new Form('groupForm'); @@ -53,7 +57,6 @@ if ($request->getParameter('btn_delete')) { $markedDeleted = ttGroupHelper::markGroupDeleted($group_id); if ($markedDeleted) { - // TODO: conditional redirects don't look nice. Any better ideas? if ($group_id == $user->group_id) { // We marked deleted our own group. Logout and redirect to login page. $auth->doLogout(); @@ -61,8 +64,10 @@ header('Location: login.php'); exit(); } else { - // We marked deleted a subgroup. Redirect to groups.pgp. - header('Location: groups.php'); + // We marked deleted a subgroup. + if ($user->behalfGroup && $user->behalfGroup->id == $group_id) + $user->setOnBehalfGroup($user->group_id); // Remove on behalf group from session. + header('Location: success.php'); exit(); } } else @@ -70,7 +75,6 @@ } if ($request->getParameter('btn_cancel')) { - // TODO: conditional redirects don't look nice. Any better ideas? if ($group_id == $user->group_id) { header('Location: group_edit.php'); exit(); diff --git a/group_edit.php b/group_edit.php index 44c5d7f9b..29bfd801b 100644 --- a/group_edit.php +++ b/group_edit.php @@ -33,32 +33,49 @@ import('ttConfigHelper'); // Access checks. -if (!(ttAccessAllowed('manage_basic_settings') || ttAccessAllowed('manage_advanced_settings'))) { - header('Location: access_denied.php'); - exit(); +// There are 4 distinct situations: +// 1) Editing home group in get or post. +// 2) Editing a subgroup in get or post. +// We'll check access separately as it is about different right checks. +if ($request->isGet()) { + $group_id = $request->getParameter('id') ? $request->getParameter('id') : $user->getGroup(); +} else { + $group_id = $request->getParameter('group'); } -$group_id = (int)$request->getParameter('id'); -if ($group_id && !$user->isGroupValid($group_id)) { - header('Location: access_denied.php'); - exit(); +$home_group = $user->group_id == $group_id; +if ($home_group) { + // Editing home group. + if (!(ttAccessAllowed('manage_basic_settings') || ttAccessAllowed('manage_advanced_settings'))) { + header('Location: access_denied.php'); // Not allowed to edit home group settings. + exit(); + } +} else { + // Editing a subgroup. + if (!ttAccessAllowed('manage_subgroups')) { + header('Location: access_denied.php'); // No right to manage subgroups. + exit(); + } + if (!$user->isSubgroupValid($group_id)) { + header('Location: access_denied.php'); // Wrong subgroup. + exit(); + } } // End of access checks. -if ($group_id) { - // We are passed a valid group_id. - // Set on behalf group accordingly. - $user->setOnBehalfGroup($group_id); +// Set on behalf group accordingly. +$groupChanged = $request->getParameter('group_changed'); +if ($request->isPost() && $groupChanged) { + $user->setOnBehalfGroup($group_id); } -if (!$group_id) $group_id = $user->getGroup(); $groups = $user->getGroupsForDropdown(); $group = ttGroupHelper::getGroupAttrs($group_id); $config = new ttConfigHelper($group['config']); -$advanced_settings = $user->can('manage_advanced_settings'); +$advanced_settings = $home_group ? $user->can('manage_advanced_settings') : true; if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); -if ($request->isPost()) { +if ($request->isPost() && !$groupChanged) { $cl_group = trim($request->getParameter('group_name')); $cl_description = trim($request->getParameter('description')); $cl_currency = trim($request->getParameter('currency')); @@ -208,13 +225,6 @@ $form->setValueByElement('group_changed',''); if ($request->isPost()) { - if ($request->getParameter('group_changed')) { - // User changed the group in dropdown. - $new_group_id = $request->getParameter('group'); - // Redirect to self. - header('Location: group_edit.php?id='.$new_group_id); - exit(); - } if ($request->getParameter('btn_delete')) { // Delete button pressed, redirect. @@ -222,47 +232,49 @@ exit(); } - // Validate user input. - if (!ttValidString($cl_group)) $err->add($i18n->get('error.field'), $i18n->get('label.group_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_currency, true)) $err->add($i18n->get('error.field'), $i18n->get('label.currency')); - if ($advanced_settings) { - if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.bcc')); - if (!ttValidIP($cl_allow_ip, true)) $err->add($i18n->get('error.field'), $i18n->get('form.group_edit.allow_ip')); - } - // Finished validating user input. + if ($request->getParameter('btn_save')) { + // Validate user input. + if (!ttValidString($cl_group)) $err->add($i18n->get('error.field'), $i18n->get('label.group_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_currency, true)) $err->add($i18n->get('error.field'), $i18n->get('label.currency')); + if ($advanced_settings) { + if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.bcc')); + if (!ttValidIP($cl_allow_ip, true)) $err->add($i18n->get('error.field'), $i18n->get('form.group_edit.allow_ip')); + } + // Finished validating user input. - if ($err->no()) { - // Update config. - $config->setDefinedValue('show_holidays', $cl_show_holidays); - $config->setDefinedValue('punch_mode', $cl_punch_mode); - $config->setDefinedValue('allow_overlap', $cl_allow_overlap); - $config->setDefinedValue('future_entries', $cl_future_entries); - $config->setDefinedValue('uncompleted_indicators', $cl_uncompleted_indicators); - $config->setDefinedValue('confirm_save', $cl_confirm_save); + if ($err->no()) { + // Update config. + $config->setDefinedValue('show_holidays', $cl_show_holidays); + $config->setDefinedValue('punch_mode', $cl_punch_mode); + $config->setDefinedValue('allow_overlap', $cl_allow_overlap); + $config->setDefinedValue('future_entries', $cl_future_entries); + $config->setDefinedValue('uncompleted_indicators', $cl_uncompleted_indicators); + $config->setDefinedValue('confirm_save', $cl_confirm_save); - if ($user->updateGroup(array( - 'group_id' => $group_id, - 'name' => $cl_group, - 'description' => $cl_description, - 'currency' => $cl_currency, - 'lang' => $cl_lang, - 'decimal_mark' => $cl_decimal_mark, - 'date_format' => $cl_date_format, - 'time_format' => $cl_time_format, - 'week_start' => $cl_start_week, - 'tracking_mode' => $cl_tracking_mode, - 'project_required' => $cl_project_required, - 'task_required' => $cl_task_required, - 'record_type' => $cl_record_type, - 'uncompleted_indicators' => $cl_uncompleted_indicators, - 'bcc_email' => $cl_bcc_email, - 'allow_ip' => $cl_allow_ip, - 'config' => $config->getConfig()))) { - header('Location: success.php'); - exit(); - } else - $err->add($i18n->get('error.db')); + if ($user->updateGroup(array( + 'group_id' => $group_id, + 'name' => $cl_group, + 'description' => $cl_description, + 'currency' => $cl_currency, + 'lang' => $cl_lang, + 'decimal_mark' => $cl_decimal_mark, + 'date_format' => $cl_date_format, + 'time_format' => $cl_time_format, + 'week_start' => $cl_start_week, + 'tracking_mode' => $cl_tracking_mode, + 'project_required' => $cl_project_required, + 'task_required' => $cl_task_required, + 'record_type' => $cl_record_type, + 'uncompleted_indicators' => $cl_uncompleted_indicators, + 'bcc_email' => $cl_bcc_email, + 'allow_ip' => $cl_allow_ip, + 'config' => $config->getConfig()))) { + header('Location: success.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } } } // isPost From e3df211bb657c8036e7c767eeee660fc402a357e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 Dec 2018 20:34:14 +0000 Subject: [PATCH 0523/1848] Work in progress on subgroups in invoices. --- WEB-INF/lib/ttGroupHelper.class.php | 34 +++++++++++++++++++++++++++++ WEB-INF/lib/ttTeamHelper.class.php | 32 --------------------------- WEB-INF/templates/footer.tpl | 2 +- invoices.php | 4 ++-- 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 1a32124cf..3ae408af9 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -389,4 +389,38 @@ static function getPredefinedExpenses() { } return false; } + + // The getActiveInvoices returns an array of active invoices for a group. + static function getActiveInvoices() + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $addPaidStatus = $user->isPluginEnabled('ps'); + $result = array(); + + if ($user->isClient()) + $client_part = "and i.client_id = $user->client_id"; + + $sql = "select i.id, i.name, i.date, i.client_id, i.status, c.name as client_name from tt_invoices i". + " left join tt_clients c on (c.id = i.client_id)". + " where i.status = 1 and i.group_id = $group_id and i.org_id = $org_id $client_part order by i.name"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + $dt = new DateAndTime(DB_DATEFORMAT); + while ($val = $res->fetchRow()) { + // Localize date. + $dt->parseVal($val['date']); + $val['date'] = $dt->toString($user->getDateFormat()); + if ($addPaidStatus) + $val['paid'] = ttInvoiceHelper::isPaid($val['id']); + $result[] = $val; + } + } + return $result; + } } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 1e6263131..16896ac58 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -363,38 +363,6 @@ static function getAllClients($group_id, $all_fields = false) { return false; } - // The getActiveInvoices returns an array of active invoices for a group. - static function getActiveInvoices($localizeDates = true) - { - global $user; - $addPaidStatus = $user->isPluginEnabled('ps'); - - $result = array(); - $mdb2 = getConnection(); - - if ($user->isClient()) - $client_part = " and i.client_id = $user->client_id"; - - $sql = "select i.id, i.name, i.date, i.client_id, i.status, c.name as client_name from tt_invoices i - left join tt_clients c on (c.id = i.client_id) - where i.status = 1 and i.group_id = $user->group_id $client_part order by i.name"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - $dt = new DateAndTime(DB_DATEFORMAT); - while ($val = $res->fetchRow()) { - if ($localizeDates) { - $dt->parseVal($val['date']); - $val['date'] = $dt->toString($user->date_format); - } - if ($addPaidStatus) - $val['paid'] = ttInvoiceHelper::isPaid($val['id']); - $result[] = $val; - } - } - return $result; - } - // The getAllInvoices returns an array of all invoices for a group. static function getAllInvoices() { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e57d10e18..dbb5b1c4b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.group}: {$forms.groupForm.group.control}
-
 Anuko Time Tracker 1.18.29.4598 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4599 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/invoices.php b/invoices.php index 1723a8d1d..eb89e0ea7 100644 --- a/invoices.php +++ b/invoices.php @@ -28,7 +28,7 @@ require_once('initialize.php'); import('form.Form'); -import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices'))) { @@ -40,7 +40,7 @@ exit(); } -$invoices = ttTeamHelper::getActiveInvoices(); +$invoices = ttGroupHelper::getActiveInvoices(); $smarty->assign('invoices', $invoices); $smarty->assign('title', $i18n->get('title.invoices')); From 005295b05a6f3418db5dc3fb79fe73e2c7d01d2f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 Dec 2018 20:54:00 +0000 Subject: [PATCH 0524/1848] More refactoring of invoices for subgroups. --- WEB-INF/lib/ttInvoiceHelper.class.php | 31 +++++++++++++++++---------- WEB-INF/templates/footer.tpl | 2 +- invoices.php | 1 + 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 042acd821..445c02c21 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -37,10 +37,13 @@ static function getInvoice($invoice_id) { global $user; $mdb2 = getConnection(); - if ($user->isClient()) $client_part = " and client_id = $user->client_id"; + $group_id = $user->getGroup(); + $org_id = $user->org_id; - $sql = "select * from tt_invoices where id = $invoice_id and group_id = ". - $user->getGroup()."$client_part and status = 1"; + if ($user->isClient()) $client_part = "and client_id = $user->client_id"; + + $sql = "select * from tt_invoices". + " where id = $invoice_id and group_id = $group_id and org_id = $org_id $client_part and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) @@ -51,12 +54,14 @@ static function getInvoice($invoice_id) { // The getInvoiceByName looks up an invoice by name. static function getInvoiceByName($invoice_name) { - - $mdb2 = getConnection(); global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; - $sql = "select id from tt_invoices where group_id = ". - $user->getGroup()." and name = ".$mdb2->quote($invoice_name)." and status = 1"; + $sql = "select id from tt_invoices where group_id = $group_id and org_id = $org_id". + " and name = ".$mdb2->quote($invoice_name)." and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -72,18 +77,22 @@ static function getInvoiceByName($invoice_name) { // Therefore, the paid status of the invoice is a calculated value. // This is because we maintain the paid status on individual item level. static function isPaid($invoice_id) { - - $mdb2 = getConnection(); global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; - $sql = "select count(*) as count from tt_log where invoice_id = $invoice_id and status = 1 and paid < 1"; + $sql = "select count(*) as count from tt_log". + " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id and status = 1 and paid < 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); if ($val['count'] > 0) return false; // A non-paid time item exists. } - $sql = "select count(*) as count from tt_expense_items where invoice_id = $invoice_id and status = 1 and paid < 1"; + $sql = "select count(*) as count from tt_expense_items". + " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id and status = 1 and paid < 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index dbb5b1c4b..39b3280fa 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4599 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4600 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/invoices.php b/invoices.php index eb89e0ea7..ba1cad462 100644 --- a/invoices.php +++ b/invoices.php @@ -39,6 +39,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. $invoices = ttGroupHelper::getActiveInvoices(); From 241fff8e23fee4caddf4038ad83df75e8146f1a2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 Dec 2018 21:52:32 +0000 Subject: [PATCH 0525/1848] Some more refactoring in invoices for subgroups. --- WEB-INF/lib/ttInvoiceHelper.class.php | 65 +++++++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 445c02c21..3e29e0e04 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -106,16 +106,20 @@ static function isPaid($invoice_id) { // markPaid marks invoice items as paid. static function markPaid($invoice_id, $mark_paid = true) { - global $user; $mdb2 = getConnection(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $paid_status = $mark_paid ? 1 : 0; - $sql = "update tt_log set paid = $paid_status where invoice_id = $invoice_id and status = 1"; + $sql = "update tt_log set paid = $paid_status". + " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id and status = 1"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $sql = "update tt_expense_items set paid = $paid_status where invoice_id = $invoice_id and status = 1"; + $sql = "update tt_expense_items set paid = $paid_status". + " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id and status = 1"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -127,43 +131,46 @@ static function getInvoiceItems($invoice_id) { global $user; $mdb2 = getConnection(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + // At this time only detailed invoice is supported. // It is anticipated to support "totals only" option later on. // Our query is different depending on tracking mode. if (MODE_TIME == $user->getTrackingMode()) { // In "time only" tracking mode there is a single user rate. - $sql = "select l.date as date, 1 as type, u.name as user_name, p.name as project_name, - t.name as task_name, l.comment as note, - time_format(l.duration, '%k:%i') as duration, - cast(l.billable * u.rate * time_to_sec(l.duration)/3600 as decimal(10, 2)) as cost, - l.paid as paid from tt_log l - inner join tt_users u on (l.user_id = u.id) - left join tt_projects p on (p.id = l.project_id) - left join tt_tasks t on (t.id = l.task_id) - where l.status = 1 and l.billable = 1 and l.invoice_id = $invoice_id order by l.date, u.name"; + $sql = "select l.date as date, 1 as type, u.name as user_name, p.name as project_name,". + " t.name as task_name, l.comment as note, time_format(l.duration, '%k:%i') as duration,". + " cast(l.billable * u.rate * time_to_sec(l.duration)/3600 as decimal(10, 2)) as cost,". + " l.paid as paid from tt_log l". + " inner join tt_users u on (l.user_id = u.id)". + " left join tt_projects p on (p.id = l.project_id)". + " left join tt_tasks t on (t.id = l.task_id)". + " where l.status = 1 and l.billable = 1 and l.invoice_id = $invoice_id". + " and l.group_id = $group_id and l.org_id = $org_id order by l.date, u.name"; } else { - $sql = "select l.date as date, 1 as type, u.name as user_name, p.name as project_name, - t.name as task_name, l.comment as note, - time_format(l.duration, '%k:%i') as duration, - cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2)) as cost, - l.paid as paid from tt_log l - inner join tt_users u on (l.user_id = u.id) - left join tt_projects p on (p.id = l.project_id) - left join tt_tasks t on (t.id = l.task_id) - left join tt_user_project_binds upb on (upb.user_id = l.user_id and upb.project_id = l.project_id) - where l.status = 1 and l.billable = 1 and l.invoice_id = $invoice_id order by l.date, u.name"; + $sql = "select l.date as date, 1 as type, u.name as user_name, p.name as project_name,". + " t.name as task_name, l.comment as note, time_format(l.duration, '%k:%i') as duration,". + " cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2)) as cost,". + " l.paid as paid from tt_log l". + " inner join tt_users u on (l.user_id = u.id)". + " left join tt_projects p on (p.id = l.project_id)". + " left join tt_tasks t on (t.id = l.task_id)". + " left join tt_user_project_binds upb on (upb.user_id = l.user_id and upb.project_id = l.project_id)". + " where l.status = 1 and l.billable = 1 and l.invoice_id = $invoice_id". + " and l.group_id = $group_id and l.org_id = $org_id order by l.date, u.name"; } // If we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table. if ($user->isPluginEnabled('ex')) { - $sql_for_expense_items = "select ei.date as date, 2 as type, u.name as user_name, p.name as project_name, - null as task_name, ei.name as note, - null as duration, ei.cost as cost, - ei.paid as paid from tt_expense_items ei - inner join tt_users u on (ei.user_id = u.id) - left join tt_projects p on (p.id = ei.project_id) - where ei.invoice_id = $invoice_id and ei.status = 1"; + $sql_for_expense_items = "select ei.date as date, 2 as type, u.name as user_name, p.name as project_name,". + " null as task_name, ei.name as note,". + " null as duration, ei.cost as cost,". + " ei.paid as paid from tt_expense_items ei". + " inner join tt_users u on (ei.user_id = u.id)". + " left join tt_projects p on (p.id = ei.project_id)". + " where ei.invoice_id = $invoice_id and ei.group_id = $group_id and ei.org_id = $org_id and ei.status = 1"; // Construct a union. $sql = "($sql) union all ($sql_for_expense_items)"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 39b3280fa..e78233847 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4600 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4601 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 57f7eb0666795f48f63f71eeb741af2eb7588427 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 Dec 2018 13:16:11 +0000 Subject: [PATCH 0526/1848] Resuming refactoring of invoices for subgroups. --- WEB-INF/lib/ttInvoiceHelper.class.php | 34 ++++++++++++++++++--------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 3e29e0e04..93d272b43 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -184,7 +184,7 @@ static function getInvoiceItems($invoice_id) { $dt = new DateAndTime(DB_DATEFORMAT); while ($val = $res->fetchRow()) { $dt->parseVal($val['date']); - $val['date'] = $dt->toString($user->date_format); + $val['date'] = $dt->toString($user->getDateFormat()); $result[] = $val; } } @@ -196,30 +196,42 @@ static function delete($invoice_id, $delete_invoice_items) { global $user; $mdb2 = getConnection(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + // Handle custom field log records. if ($delete_invoice_items) { - $sql = "update tt_custom_field_log set status = NULL where log_id in (select id from tt_log where invoice_id = $invoice_id and status = 1)"; + $sql = "update tt_custom_field_log set status = null". + " where log_id in". + " (select id from tt_log where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id and status = 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; } // Handle time records. - if ($delete_invoice_items) - $sql = "update tt_log set status = NULL where invoice_id = $invoice_id"; - else - $sql = "update tt_log set invoice_id = NULL where invoice_id = $invoice_id"; + if ($delete_invoice_items) { + $sql = "update tt_log set status = null". + " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id"; + } else { + $sql = "update tt_log set invoice_id = null". + " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id"; + } $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Handle expense items. - if ($delete_invoice_items) - $sql = "update tt_expense_items set status = NULL where invoice_id = $invoice_id"; - else - $sql = "update tt_expense_items set invoice_id = NULL where invoice_id = $invoice_id"; + if ($delete_invoice_items) { + $sql = "update tt_expense_items set status = null". + " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id"; + } else { + $sql = "update tt_expense_items set invoice_id = null". + " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id"; + } $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - $sql = "update tt_invoices set status = NULL where id = $invoice_id and group_id = ".$user->getGroup(); + $sql = "update tt_invoices set status = null". + " where id = $invoice_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e78233847..ffb82d9de 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4601 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4602 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 00b824b147ae7e63fcd8fc1c41e54c356d975a02 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 Dec 2018 13:41:43 +0000 Subject: [PATCH 0527/1848] More refactoring. --- WEB-INF/lib/ttInvoiceHelper.class.php | 36 +++++++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 93d272b43..78987b40f 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -238,9 +238,11 @@ static function delete($invoice_id, $delete_invoice_items) { // The invoiceableItemsExist determines whether invoiceable records exist in the specified period. static function invoiceableItemsExist($fields) { - - $mdb2 = getConnection(); global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; $client_id = (int) $fields['client_id']; @@ -255,21 +257,22 @@ static function invoiceableItemsExist($fields) { // Our query is different depending on tracking mode. if (MODE_TIME == $user->getTrackingMode()) { // In "time only" tracking mode there is a single user rate. - $sql = "select count(*) as num from tt_log l, tt_users u - where l.status = 1 and l.client_id = $client_id and l.invoice_id is NULL - and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end)." - and l.user_id = u.id - and l.billable = 1"; // l.billable * u.rate * time_to_sec(l.duration)/3600 > 0 // See explanation below. + $sql = "select count(*) as num from tt_log l, tt_users u". + " where l.status = 1 and l.client_id = $client_id and l.invoice_id is null". + " and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end). + " and l.user_id = u.id and l.group_id = $group_id and l.org_id = $org_id". + " and l.billable = 1"; // l.billable * u.rate * time_to_sec(l.duration)/3600 > 0 // See explanation below. } else { // sql part for project id. if ($project_id) $project_part = " and l.project_id = $project_id"; // When we have projects, rates are defined for each project in tt_user_project_binds table. - $sql = "select count(*) as num from tt_log l, tt_user_project_binds upb - where l.status = 1 and l.client_id = $client_id $project_part and l.invoice_id is NULL - and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end)." - and upb.user_id = l.user_id and upb.project_id = l.project_id - and l.billable = 1"; // l.billable * upb.rate * time_to_sec(l.duration)/3600 > 0 + $sql = "select count(*) as num from tt_log l, tt_user_project_binds upb". + " where l.status = 1 and l.client_id = $client_id $project_part and l.invoice_id is null". + " and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end). + " and l.group_id = $group_id and l.org_id = $org_id". + " and upb.user_id = l.user_id and upb.project_id = l.project_id". + " and l.billable = 1"; // l.billable * upb.rate * time_to_sec(l.duration)/3600 > 0 // Users with a lot of clients and projects (Jaro) may forget to set user rates properly. // Specifically, user rate may be set to 0 on a project, by mistake. This leads to error.no_invoiceable_items // and increased support cost. Commenting out allows us to include 0 cost items in invoices so that @@ -289,10 +292,11 @@ static function invoiceableItemsExist($fields) { // sql part for project id. if ($project_id) $project_part = " and ei.project_id = $project_id"; - $sql = "select count(*) as num from tt_expense_items ei - where ei.client_id = $client_id $project_part and ei.invoice_id is NULL - and ei.date >= ".$mdb2->quote($start)." and ei.date <= ".$mdb2->quote($end)." - and ei.cost <> 0 and ei.status = 1"; + $sql = "select count(*) as num from tt_expense_items ei". + " where ei.client_id = $client_id $project_part and ei.invoice_id is null". + " and ei.date >= ".$mdb2->quote($start)." and ei.date <= ".$mdb2->quote($end). + " and ei.group_id = $group_id and ei.org_id = $org_id". + " and ei.cost <> 0 and ei.status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ffb82d9de..fafccace1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4602 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4603 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6f6512e1d85460b13910a3ce0e081750ae9a5642 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 Dec 2018 14:02:20 +0000 Subject: [PATCH 0528/1848] A bit more refactoring in invoices. --- WEB-INF/lib/ttInvoiceHelper.class.php | 42 +++++++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 78987b40f..ff4a9f29b 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -311,9 +311,11 @@ static function invoiceableItemsExist($fields) { // createInvoice - marks items for invoice as belonging to it (with its reference number). static function createInvoice($fields) { - - $mdb2 = getConnection(); global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; $name = $fields['name']; if (!$name) return false; @@ -332,8 +334,8 @@ static function createInvoice($fields) { if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; // Create a new invoice record. - $sql = "insert into tt_invoices (group_id, org_id, name, date, client_id) values(". - $user->getGroup().", $user->org_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id)"; + $sql = "insert into tt_invoices (group_id, org_id, name, date, client_id)". + " values($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($date).", $client_id)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -343,23 +345,25 @@ static function createInvoice($fields) { // Our update sql is different depending on tracking mode. if (MODE_TIME == $user->getTrackingMode()) { // In "time only" tracking mode there is a single user rate. - $sql = "update tt_log l - left join tt_users u on (u.id = l.user_id) - set l.invoice_id = $last_id - where l.status = 1 and l.client_id = $client_id and l.invoice_id is NULL - and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end)." - and l.billable = 1"; // l.billable * u.rate * time_to_sec(l.duration)/3600 > 0"; // See explanation below. + $sql = "update tt_log l". + " left join tt_users u on (u.id = l.user_id)". + " set l.invoice_id = $last_id". + " where l.status = 1 and l.client_id = $client_id and l.invoice_id is null". + " and l.group_id = $group_id and l.org_id = $org_id". + " and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end). + " and l.billable = 1"; // l.billable * u.rate * time_to_sec(l.duration)/3600 > 0"; // See explanation below. } else { // sql part for project id. if ($project_id) $project_part = " and l.project_id = $project_id"; // When we have projects, rates are defined for each project in tt_user_project_binds. - $sql = "update tt_log l - left join tt_user_project_binds upb on (upb.user_id = l.user_id and upb.project_id = l.project_id) - set l.invoice_id = $last_id - where l.status = 1 and l.client_id = $client_id $project_part and l.invoice_id is NULL - and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end)." - and l.billable = 1"; // l.billable * upb.rate * time_to_sec(l.duration)/3600 > 0"; + $sql = "update tt_log l". + " left join tt_user_project_binds upb on (upb.user_id = l.user_id and upb.project_id = l.project_id)". + " set l.invoice_id = $last_id". + " where l.status = 1 and l.client_id = $client_id $project_part and l.invoice_id is null". + " and l.group_id = $group_id and l.org_id = $org_id". + " and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end). + " and l.billable = 1"; // l.billable * upb.rate * time_to_sec(l.duration)/3600 > 0"; // Users with a lot of clients and projects (Jaro) may forget to set user rates properly. // Specifically, user rate may be set to 0 on a project, by mistake. This leads to error.no_invoiceable_items // and increased support cost. Commenting out allows us to include 0 cost items in invoices so that @@ -374,8 +378,10 @@ static function createInvoice($fields) { // sql part for project id. if ($project_id) $project_part = " and project_id = $project_id"; - $sql = "update tt_expense_items set invoice_id = $last_id where client_id = $client_id $project_part and invoice_id is NULL - and date >= ".$mdb2->quote($start)." and date <= ".$mdb2->quote($end)." and cost <> 0 and status = 1"; + $sql = "update tt_expense_items set invoice_id = $last_id". + " where client_id = $client_id $project_part and invoice_id is null". + " and group_id = $group_id and org_id = $org_id". + " and date >= ".$mdb2->quote($start)." and date <= ".$mdb2->quote($end)." and cost <> 0 and status = 1"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fafccace1..1168961f1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4603 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4604 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 2578cc5eb4d64b7f785967ff895e810e0db5c1b3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 Dec 2018 14:25:55 +0000 Subject: [PATCH 0529/1848] Finished refactoring ttInvoiceHelper class for subgroups. --- WEB-INF/lib/ttInvoiceHelper.class.php | 13 ++++++++----- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index ff4a9f29b..becea87bc 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -392,6 +392,9 @@ static function prepareInvoiceBody($invoice_id, $comment) global $user; global $i18n; + $currency = $user->getCurrency(); + $decimalMark = $user->getDecimalMark(); + $invoice = ttInvoiceHelper::getInvoice($invoice_id); $client = ttClientHelper::getClient($invoice['client_id'], true); $invoice_items = ttInvoiceHelper::getInvoiceItems($invoice_id); @@ -412,13 +415,13 @@ static function prepareInvoiceBody($invoice_id, $comment) } $total = $subtotal + $tax; - $subtotal = htmlspecialchars($user->currency).' '.str_replace('.', $user->decimal_mark, sprintf('%8.2f', round($subtotal, 2))); - if ($tax) $tax = htmlspecialchars($user->currency).' '.str_replace('.', $user->decimal_mark, sprintf('%8.2f', round($tax, 2))); - $total = htmlspecialchars($user->currency).' '.str_replace('.', $user->decimal_mark, sprintf('%8.2f', round($total, 2))); + $subtotal = htmlspecialchars($currency).' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($subtotal, 2))); + if ($tax) $tax = htmlspecialchars($currency).' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($tax, 2))); + $total = htmlspecialchars($currency).' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($total, 2))); - if ('.' != $user->decimal_mark) { + if ('.' != $decimalMark) { foreach ($invoice_items as &$item) { - $item['cost'] = str_replace('.', $user->decimal_mark, $item['cost']); + $item['cost'] = str_replace('.', $decimalMark, $item['cost']); } unset($item); // Unset the reference. If we don't, the foreach loop below modifies the array while printing. // See http://stackoverflow.com/questions/8220399/php-foreach-pass-by-reference-last-element-duplicating-bug diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1168961f1..db006ef82 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4604 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4605 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 4153fc2584a62ab3949b182e42fb61c804925a08 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 Dec 2018 14:37:28 +0000 Subject: [PATCH 0530/1848] Fixed group_edit.php for no subgroups situation. --- WEB-INF/templates/footer.tpl | 2 +- group_edit.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index db006ef82..696890b6f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4605 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4606 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_edit.php b/group_edit.php index 29bfd801b..b16a15f09 100644 --- a/group_edit.php +++ b/group_edit.php @@ -40,7 +40,7 @@ if ($request->isGet()) { $group_id = $request->getParameter('id') ? $request->getParameter('id') : $user->getGroup(); } else { - $group_id = $request->getParameter('group'); + $group_id = $request->getParameter('group') ? $request->getParameter('group') : $user->getGroup(); } $home_group = $user->group_id == $group_id; if ($home_group) { From 3c60698710dfd998fd1488c674b944f5df9b0dce Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 Dec 2018 15:16:22 +0000 Subject: [PATCH 0531/1848] Adjusted invoice_view.php for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/invoice_view.tpl | 8 ++++---- invoice_view.php | 22 ++++++++++++++-------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 696890b6f..ca4c7a04a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $show_project} {/if} - {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $show_task} {/if} @@ -37,10 +37,10 @@ - {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $show_project} {/if} - {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $show_task} {/if} diff --git a/invoice_view.php b/invoice_view.php index 8168c3ad8..772500ef5 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -71,20 +71,24 @@ } $total = $subtotal + $tax; -$smarty->assign('subtotal', $user->currency.' '.str_replace('.', $user->decimal_mark, sprintf('%8.2f', round($subtotal, 2)))); -if ($tax) $smarty->assign('tax', $user->currency.' '.str_replace('.', $user->decimal_mark, sprintf('%8.2f', round($tax, 2)))); -$smarty->assign('total', $user->currency.' '.str_replace('.', $user->decimal_mark, sprintf('%8.2f', round($total, 2)))); +$currency = $user->getCurrency(); +$decimalMark = $user->getDecimalMark(); -if ('.' != $user->decimal_mark) { +$smarty->assign('subtotal', $currency.' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($subtotal, 2)))); +if ($tax) $smarty->assign('tax', $currency.' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($tax, 2)))); +$smarty->assign('total', $currency.' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($total, 2)))); + +if ('.' != $decimalMark) { foreach ($invoice_items as &$item) - $item['cost'] = str_replace('.', $user->decimal_mark, $item['cost']); + $item['cost'] = str_replace('.', $decimalMark, $item['cost']); } // Calculate colspan for invoice summary. $colspan = 4; -if (MODE_PROJECTS == $user->tracking_mode) +$trackingMode = $user->getTrackingMode(); +if (MODE_PROJECTS == $trackingMode) $colspan++; -elseif (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +elseif (MODE_PROJECTS_AND_TASKS == $trackingMode) $colspan += 2; $form = new Form('invoiceForm'); @@ -117,9 +121,11 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('invoice_id', $cl_invoice_id); $smarty->assign('invoice_name', $invoice['name']); -$smarty->assign('invoice_date', $invoice_date->toString($user->date_format)); +$smarty->assign('invoice_date', $invoice_date->toString($user->getDateFormat())); $smarty->assign('client_name', $client['name']); $smarty->assign('client_address', $client['address']); +$smarty->assign('show_project', MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode); +$smarty->assign('show_task', MODE_PROJECTS_AND_TASKS == $trackingMode); $smarty->assign('invoice_items', $invoice_items); $smarty->assign('colspan', $colspan); $smarty->assign('title', $i18n->get('title.view_invoice')); From aa0c3ca69e801da029d6ec90937dd8017186c91f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 Dec 2018 17:12:53 +0000 Subject: [PATCH 0532/1848] Updated Locking config to support subgroups. --- WEB-INF/lib/ttUser.class.php | 7 +------ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/invoice_add.tpl | 2 +- invoice_add.php | 4 +++- locking.php | 2 +- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 7867ac8e8..5c21879bf 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -594,15 +594,10 @@ function adjustBehalfId() { // updateGroup updates group information with new data. function updateGroup($fields) { - if (!($this->can('manage_basic_settings') || - $this->can('manage_advanced_settings') || - $this->can('manage_features'))) return false; - // TODO: update the above for subgroup updates. + $mdb2 = getConnection(); $group_id = $fields['group_id']; if ($group_id && !$this->isGroupValid($group_id)) return false; - - $mdb2 = getConnection(); if (!$group_id) $group_id = $this->getGroup(); if (isset($fields['name'])) $name_part = ', name = '.$mdb2->quote($fields['name']); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ca4c7a04a..cd126f2c8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4606 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4607 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/invoice_view.tpl b/WEB-INF/templates/invoice_view.tpl index 9faa3bb21..6441b44db 100644 --- a/WEB-INF/templates/invoice_view.tpl +++ b/WEB-INF/templates/invoice_view.tpl @@ -20,10 +20,10 @@
{$i18n.label.date} {$i18n.form.invoice.person}{$i18n.label.project}{$i18n.label.task}{$i18n.label.note}
{$invoice_item.date} {$invoice_item.user_name|escape}{$invoice_item.project_name|escape}{$invoice_item.task_name|escape}{$invoice_item.note|escape}
- -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} diff --git a/invoice_add.php b/invoice_add.php index e29de2eb6..273d761ef 100644 --- a/invoice_add.php +++ b/invoice_add.php @@ -61,7 +61,8 @@ $form->addInput(array('type'=>'combobox','name'=>'client','style'=>'width: 250px;','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->get('dropdown.select')))); } // Dropdown for projects. -if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { +$show_project = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); +if ($show_project) { $projects = ttGroupHelper::getActiveProjects(); $form->addInput(array('type'=>'combobox','name'=>'project','style'=>'width: 250px;','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_project,'empty'=>array(''=>$i18n->get('dropdown.all')))); } @@ -100,6 +101,7 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.invoiceForm.number.focus()"'); +$smarty->assign('show_project', $show_project); $smarty->assign('title', $i18n->get('title.add_invoice')); $smarty->assign('content_page_name', 'invoice_add.tpl'); $smarty->display('index.tpl'); diff --git a/locking.php b/locking.php index 4359f2197..9b23c876a 100644 --- a/locking.php +++ b/locking.php @@ -39,7 +39,7 @@ exit(); } -$cl_lock_spec = $request->isPost() ? $request->getParameter('lock_spec') : $user->lock_spec; +$cl_lock_spec = $request->isPost() ? $request->getParameter('lock_spec') : $user->getLockSpec(); $form = new Form('lockingForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'lock_spec','style'=>'width: 250px;','value'=>$cl_lock_spec)); From 30f870da6d0f5d73cd6f33ab284ff45559d1ee13 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 Dec 2018 17:48:04 +0000 Subject: [PATCH 0533/1848] Refactored ttNotificationHelper class for subgroups. --- WEB-INF/lib/ttGroupHelper.class.php | 23 +++++++++++ WEB-INF/lib/ttNotificationHelper.class.php | 44 +++++++++++++--------- WEB-INF/lib/ttTeamHelper.class.php | 19 ---------- WEB-INF/templates/footer.tpl | 2 +- notification_edit.php | 1 - notifications.php | 4 +- 6 files changed, 52 insertions(+), 41 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 3ae408af9..4ba7805e4 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -423,4 +423,27 @@ static function getActiveInvoices() } return $result; } + + // getNotifications - obtains notification descriptions for a group. + static function getNotifications() { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $result = array(); + $sql = "select c.id, c.cron_spec, c.email, c.report_condition, fr.name from tt_cron c". + " left join tt_fav_reports fr on (fr.id = c.report_id)". + " where c.group_id = $group_id and c.org_id = $org_id and c.status = 1 and fr.status = 1"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + return $result; + } + return false; + } } diff --git a/WEB-INF/lib/ttNotificationHelper.class.php b/WEB-INF/lib/ttNotificationHelper.class.php index c9f0a1e9c..8e5cb8aff 100644 --- a/WEB-INF/lib/ttNotificationHelper.class.php +++ b/WEB-INF/lib/ttNotificationHelper.class.php @@ -30,15 +30,16 @@ class ttNotificationHelper { // get - gets notification details. - static function get($id) - { + static function get($id) { global $user; - $mdb2 = getConnection(); - $sql = "select c.id, c.cron_spec, c.report_id, c.email, c.cc, c.subject, c.report_condition, c.status, fr.name from tt_cron c - left join tt_fav_reports fr on (fr.id = c.report_id) - where c.id = $id and c.group_id = ".$user->getGroup(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select c.id, c.cron_spec, c.report_id, c.email, c.cc, c.subject, c.report_condition, c.status, fr.name from tt_cron c". + " left join tt_fav_reports fr on (fr.id = c.report_id)". + " where c.id = $id and c.group_id = $group_id and c.org_id = $org_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -51,25 +52,27 @@ static function get($id) // delete - deletes a notification from tt_cron table. static function delete($id) { global $user; - $mdb2 = getConnection(); - - $sql = "delete from tt_cron where id = $id and group_id = ".$user->getGroup(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "delete from tt_cron where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; - return true; + return true; } // insert function inserts a new notification into database. - static function insert($fields) - { + static function insert($fields) { global $user; $mdb2 = getConnection(); $group_id = $user->getGroup(); $org_id = $user->org_id; + $cron_spec = $fields['cron_spec']; $next = (int) $fields['next']; $report_id = (int) $fields['report_id']; @@ -89,12 +92,14 @@ static function insert($fields) } // update function - updates a notification in database. - static function update($fields) - { + static function update($fields) { + global $user; $mdb2 = getConnection(); - + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $notification_id = (int) $fields['id']; - $group_id = (int) $fields['group_id']; $cron_spec = $fields['cron_spec']; $next = (int) $fields['next']; $report_id = (int) $fields['report_id']; @@ -104,8 +109,11 @@ static function update($fields) $report_condition = $fields['report_condition']; $status = $fields['status']; - $sql = "update tt_cron set cron_spec = ".$mdb2->quote($cron_spec).", next = $next, report_id = $report_id, email = ".$mdb2->quote($email).", cc = ".$mdb2->quote($cc).", subject = ".$mdb2->quote($subject).", report_condition = ".$mdb2->quote($report_condition).", status = ".$mdb2->quote($status). - " where id = $notification_id and group_id = $group_id"; + $sql = "update tt_cron". + " set cron_spec = ".$mdb2->quote($cron_spec).", next = $next, report_id = $report_id". + ", email = ".$mdb2->quote($email).", cc = ".$mdb2->quote($cc).", subject = ".$mdb2->quote($subject). + ", report_condition = ".$mdb2->quote($report_condition).", status = ".$mdb2->quote($status). + " where id = $notification_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 16896ac58..cf455405b 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -508,25 +508,6 @@ static function getExpenseItems($group_id) { return false; } - // getNotifications - obtains notification descriptions for a group. - static function getNotifications($group_id) { - $mdb2 = getConnection(); - - $result = array(); - $sql = "select c.id, c.cron_spec, c.email, c.report_condition, fr.name from tt_cron c - left join tt_fav_reports fr on (fr.id = c.report_id) - where c.group_id = $group_id and c.status = 1 and fr.status = 1"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - // getMonthlyQuotas - obtains monthly quotas for a group. static function getMonthlyQuotas($group_id) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index cd126f2c8..bdd2fd617 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4607 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4608 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/invoice_add.tpl b/WEB-INF/templates/invoice_add.tpl index e166b089f..f5211eeef 100644 --- a/WEB-INF/templates/invoice_add.tpl +++ b/WEB-INF/templates/invoice_add.tpl @@ -15,7 +15,7 @@ {$i18n.label.client} (*): {$forms.invoiceForm.client.control}
{$i18n.label.project}: {$forms.invoiceForm.project.control}
-
 Anuko Time Tracker 1.18.29.4608 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4609 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/notification_edit.php b/notification_edit.php index 69535815d..7442305a8 100644 --- a/notification_edit.php +++ b/notification_edit.php @@ -94,7 +94,6 @@ if (ttNotificationHelper::update(array( 'id' => $notification_id, - 'group_id' => $user->group_id, 'cron_spec' => $cl_cron_spec, 'next' => $next, 'report_id' => $cl_fav_report, diff --git a/notifications.php b/notifications.php index 23400beb4..d70f5b48b 100644 --- a/notifications.php +++ b/notifications.php @@ -28,7 +28,7 @@ require_once('initialize.php'); import('form.Form'); -import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_advanced_settings')) { @@ -50,7 +50,7 @@ } } else { $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - $notifications = ttTeamHelper::getNotifications($user->group_id); + $notifications = ttGroupHelper::getNotifications(); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); From 35a538725eb9bc8a651a012a7bccc546aa22e6b2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 Dec 2018 22:42:31 +0000 Subject: [PATCH 0534/1848] Improved access checks in notifications config. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/plugins.tpl | 2 +- notification_add.php | 18 +++++++++++++++--- notification_delete.php | 20 +++++++++++++------- notification_edit.php | 24 +++++++++++++++++++++--- notifications.php | 8 ++++++++ plugins.php | 1 + user_add.php | 8 +++++++- 8 files changed, 67 insertions(+), 16 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bdd2fd617..bf2c3a051 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + diff --git a/notification_add.php b/notification_add.php index e30970afa..f1221117a 100644 --- a/notification_add.php +++ b/notification_add.php @@ -42,11 +42,24 @@ header('Location: feature_disabled.php'); exit(); } +if (!$user->exists()) { + header('Location: access_denied.php'); // No users in subgroup. + exit(); +} +if ($request->isPost()) { + // TODO: improve this, perhaps by refactoring elsewhere. + $cl_fav_report = (int) $request->getParameter('fav_report'); + $fav_report = ttFavReportHelper::getReport($cl_fav_report); + if ($user->getUser() != $fav_report['user_id']) { + header('Location: access_denied.php'); // Invalid fav report id in post. + exit(); + } +} +// End of access checks. -$fav_reports = ttFavReportHelper::getReports($user->id); +$fav_reports = ttFavReportHelper::getReports($user->getUser()); if ($request->isPost()) { - $cl_fav_report = trim($request->getParameter('fav_report')); $cl_cron_spec = trim($request->getParameter('cron_spec')); $cl_email = trim($request->getParameter('email')); $cl_cc = trim($request->getParameter('cc')); @@ -86,7 +99,6 @@ $next = tdCron::getNextOccurrence($cl_cron_spec, mktime()); if (ttNotificationHelper::insert(array( - 'group_id' => $user->group_id, 'cron_spec' => $cl_cron_spec, 'next' => $next, 'report_id' => $cl_fav_report, diff --git a/notification_delete.php b/notification_delete.php index b18ac614f..c1f0785e2 100644 --- a/notification_delete.php +++ b/notification_delete.php @@ -39,9 +39,18 @@ header('Location: feature_disabled.php'); exit(); } - +if (!$user->exists()) { + header('Location: access_denied.php'); // No users in subgroup. + exit(); +} $cl_notification_id = (int)$request->getParameter('id'); $notification = ttNotificationHelper::get($cl_notification_id); +if (!$notification) { + header('Location: access_denied.php'); // Wrong notification id. + exit(); +} +// End of access checks. + $notification_to_delete = $notification['name']; $form = new Form('notificationDeleteForm'); @@ -51,12 +60,9 @@ if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if(ttNotificationHelper::get($cl_notification_id)) { - if (ttNotificationHelper::delete($cl_notification_id)) { - header('Location: notifications.php'); - exit(); - } else - $err->add($i18n->get('error.db')); + if (ttNotificationHelper::delete($cl_notification_id)) { + header('Location: notifications.php'); + exit(); } else $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { diff --git a/notification_edit.php b/notification_edit.php index 7442305a8..de09f75ea 100644 --- a/notification_edit.php +++ b/notification_edit.php @@ -42,12 +42,30 @@ header('Location: feature_disabled.php'); exit(); } +if (!$user->exists()) { + header('Location: access_denied.php'); // No users in subgroup. + exit(); +} +$notification_id = (int)$request->getParameter('id'); +$notification = ttNotificationHelper::get($notification_id); +if (!$notification) { + header('Location: access_denied.php'); // Wrong notification id. + exit(); +} +if ($request->isPost()) { + // TODO: improve this, perhaps by refactoring elsewhere. + $cl_fav_report = (int) $request->getParameter('fav_report'); + $fav_report = ttFavReportHelper::getReport($cl_fav_report); + if ($user->getUser() != $fav_report['user_id']) { + header('Location: access_denied.php'); // Invalid fav report id in post. + exit(); + } +} +// End of access checks. -$notification_id = (int) $request->getParameter('id'); -$fav_reports = ttFavReportHelper::getReports($user->id); +$fav_reports = ttFavReportHelper::getReports($user->getUser()); if ($request->isPost()) { - $cl_fav_report = trim($request->getParameter('fav_report')); $cl_cron_spec = trim($request->getParameter('cron_spec')); $cl_email = trim($request->getParameter('email')); $cl_cc = trim($request->getParameter('cc')); diff --git a/notifications.php b/notifications.php index d70f5b48b..7fe0e11d1 100644 --- a/notifications.php +++ b/notifications.php @@ -39,6 +39,14 @@ header('Location: feature_disabled.php'); exit(); } +if (!$user->exists()) { + header('Location: access_denied.php'); // No users in subgroup. + exit(); +} +// End of access checks. + +// TODO: extend and re-design notifications. +// Currently they only work with fav reports, which are bound to users. $form = new Form('notificationsForm'); diff --git a/plugins.php b/plugins.php index e036c1738..a19c1e128 100644 --- a/plugins.php +++ b/plugins.php @@ -174,6 +174,7 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="handlePluginCheckboxes();"'); +$smarty->assign('user_exists', $user->exists()); $smarty->assign('title', $i18n->get('title.plugins')); $smarty->assign('content_page_name', 'plugins.tpl'); $smarty->display('index.tpl'); diff --git a/user_add.php b/user_add.php index 8a507e9ee..9fa611294 100644 --- a/user_add.php +++ b/user_add.php @@ -157,7 +157,13 @@ function render(&$table, $value, $row, $column, $selected = false) { 'client_id' => $cl_client_id, 'projects' => $assigned_projects, 'email' => $cl_email); - if (ttUserHelper::insert($fields)) { + $user_id = ttUserHelper::insert($fields); + if ($user_id) { + if (!$user->exists()) { + // We added a user to an empty subgroup. Set new user as on behalf user. + // Needed for user-based things to work (such as notifications config). + $user->setOnBehalfUser($user_id); + } header('Location: users.php'); exit(); } else From 95c5359666f6dae7d0426f0a1fc41c925b996086 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 Dec 2018 14:13:54 +0000 Subject: [PATCH 0535/1848] Improved cron.php security-wise with a more specific sql. --- WEB-INF/templates/footer.tpl | 2 +- cron.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bf2c3a051..9c086022f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4609 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4610 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index d31bb841a..6b88725b9 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -123,7 +123,7 @@ function handlePluginCheckboxes() {
{$forms.pluginsForm.notifications.control} {$i18n.label.configure} {if $user_exists}{$i18n.label.configure}{/if}
{$forms.pluginsForm.locking.control}
-
 Anuko Time Tracker 1.18.29.4610 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4611 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cron.php b/cron.php index eabcaa05c..98c1456fe 100644 --- a/cron.php +++ b/cron.php @@ -47,10 +47,10 @@ $mdb2 = getConnection(); $now = time(); - $sql = "select c.id, c.cron_spec, c.report_id, c.email, c.cc, c.subject, c.report_condition from tt_cron c - left join tt_fav_reports fr on (c.report_id = fr.id) - where $now >= c.next and fr.status = 1 - and c.status = 1 and c.report_id is not null and c.email is not null"; + $sql = "select c.id, c.cron_spec, c.report_id, c.email, c.cc, c.subject, c.report_condition from tt_cron c". + " inner join tt_fav_reports fr on (c.report_id = fr.id and c.group_id = fr.group_id and c.org_id = fr.org_id)". + " where $now >= c.next and fr.status = 1". + " and c.status = 1 and c.report_id is not null and c.email is not null"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) exit(); From f32f30fa61a2937ea1bda8b28b748c854b997f15 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 Dec 2018 15:12:26 +0000 Subject: [PATCH 0536/1848] Starting refactoring ttFavReportHelper class for subgroups. --- WEB-INF/lib/ttFavReportHelper.class.php | 10 ++++++++-- WEB-INF/templates/footer.tpl | 2 +- notification_add.php | 2 +- notification_edit.php | 2 +- reports.php | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 36600e219..3625c9de0 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -32,11 +32,17 @@ class ttFavReportHelper { // getReports - returns an array of favorite reports for user. - static function getReports($user_id) { + static function getReports() { + global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $result = array(); - $sql = "select * from tt_fav_reports where user_id = $user_id and status = 1"; + $sql = "select * from tt_fav_reports". + " where user_id = $user_id and group_id = $group_id and org_id = $org_id and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9c086022f..8e93961ac 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4611 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4612 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/notification_add.php b/notification_add.php index f1221117a..e7f541bb9 100644 --- a/notification_add.php +++ b/notification_add.php @@ -57,7 +57,7 @@ } // End of access checks. -$fav_reports = ttFavReportHelper::getReports($user->getUser()); +$fav_reports = ttFavReportHelper::getReports(); if ($request->isPost()) { $cl_cron_spec = trim($request->getParameter('cron_spec')); diff --git a/notification_edit.php b/notification_edit.php index de09f75ea..5755e95cc 100644 --- a/notification_edit.php +++ b/notification_edit.php @@ -63,7 +63,7 @@ } // End of access checks. -$fav_reports = ttFavReportHelper::getReports($user->getUser()); +$fav_reports = ttFavReportHelper::getReports(); if ($request->isPost()) { $cl_cron_spec = trim($request->getParameter('cron_spec')); diff --git a/reports.php b/reports.php index 8310f5ddc..e617285c9 100644 --- a/reports.php +++ b/reports.php @@ -53,7 +53,7 @@ $form = new Form('reportForm'); // Get saved favorite reports for user. -$report_list = ttFavReportHelper::getReports($user->id); +$report_list = ttFavReportHelper::getReports(); $form->addInput(array('type'=>'combobox', 'name'=>'favorite_report', 'onchange'=>'document.reportForm.fav_report_changed.value=1;document.reportForm.submit();', From bfaedf194df864a24ea4a44c359435be68983909 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 Dec 2018 15:16:26 +0000 Subject: [PATCH 0537/1848] Refactoring. --- WEB-INF/templates/footer.tpl | 2 +- reports.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8e93961ac..7e5b94b1a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4612 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4613 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index e617285c9..f4306961e 100644 --- a/reports.php +++ b/reports.php @@ -56,7 +56,7 @@ $report_list = ttFavReportHelper::getReports(); $form->addInput(array('type'=>'combobox', 'name'=>'favorite_report', - 'onchange'=>'document.reportForm.fav_report_changed.value=1;document.reportForm.submit();', + 'onchange'=>'this.form.fav_report_changed.value=1;this.form.submit();', 'style'=>'width: 250px;', 'data'=>$report_list, 'datakeys'=>array('id','name'), From 63413a7d9e47dbd3d91de82e02f8c6d4ee4d4c21 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 Dec 2018 16:02:00 +0000 Subject: [PATCH 0538/1848] Some more refactoring in notification config. --- WEB-INF/lib/ttFavReportHelper.class.php | 23 +++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- notification_add.php | 12 +++++------- notification_edit.php | 14 ++++++-------- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 3625c9de0..a1f2b945d 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -53,7 +53,30 @@ static function getReports() { return false; } + // get - returns a report identified by its id for user. + static function get($id) { + global $user; + $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select * from tt_fav_reports". + " where id = $id and user_id = $user_id and group_id = $group_id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + if ($val = $res->fetchRow()) { + return $val; + } + } + return false; + } + // getReport - returns a report identified by its id. + // TODO: get rid of this function by encapsulating all cron related tasks in its own class. + // Because cron works for all orgs and we want this class to always work in context of + // a logged on user, for better security. static function getReport($id) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7e5b94b1a..eb75ce260 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4613 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4614 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/notification_add.php b/notification_add.php index e7f541bb9..05a095468 100644 --- a/notification_add.php +++ b/notification_add.php @@ -47,10 +47,8 @@ exit(); } if ($request->isPost()) { - // TODO: improve this, perhaps by refactoring elsewhere. - $cl_fav_report = (int) $request->getParameter('fav_report'); - $fav_report = ttFavReportHelper::getReport($cl_fav_report); - if ($user->getUser() != $fav_report['user_id']) { + $cl_fav_report_id = (int) $request->getParameter('fav_report'); + if (!ttFavReportHelper::get($cl_fav_report_id)) { header('Location: access_denied.php'); // Invalid fav report id in post. exit(); } @@ -73,7 +71,7 @@ $form->addInput(array('type'=>'combobox', 'name'=>'fav_report', 'style'=>'width: 250px;', - 'value'=>$cl_fav_report, + 'value'=>$cl_fav_report_id, 'data'=>$fav_reports, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')) @@ -87,7 +85,7 @@ if ($request->isPost()) { // Validate user input. - if (!$cl_fav_report) $err->add($i18n->get('error.report')); + if (!$cl_fav_report_id) $err->add($i18n->get('error.report')); if (!ttValidCronSpec($cl_cron_spec)) $err->add($i18n->get('error.field'), $i18n->get('label.schedule')); if (!ttValidEmail($cl_email)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); if (!ttValidEmail($cl_cc, true)) $err->add($i18n->get('error.field'), $i18n->get('label.cc')); @@ -101,7 +99,7 @@ if (ttNotificationHelper::insert(array( 'cron_spec' => $cl_cron_spec, 'next' => $next, - 'report_id' => $cl_fav_report, + 'report_id' => $cl_fav_report_id, 'email' => $cl_email, 'cc' => $cl_cc, 'subject' => $cl_subject, diff --git a/notification_edit.php b/notification_edit.php index 5755e95cc..90b84e5a3 100644 --- a/notification_edit.php +++ b/notification_edit.php @@ -53,10 +53,8 @@ exit(); } if ($request->isPost()) { - // TODO: improve this, perhaps by refactoring elsewhere. - $cl_fav_report = (int) $request->getParameter('fav_report'); - $fav_report = ttFavReportHelper::getReport($cl_fav_report); - if ($user->getUser() != $fav_report['user_id']) { + $cl_fav_report_id = (int) $request->getParameter('fav_report'); + if ($cl_fav_report_id && !ttFavReportHelper::get($cl_fav_report_id)) { header('Location: access_denied.php'); // Invalid fav report id in post. exit(); } @@ -73,7 +71,7 @@ $cl_report_condition = trim($request->getParameter('report_condition')); } else { $notification = ttNotificationHelper::get($notification_id); - $cl_fav_report = $notification['report_id']; + $cl_fav_report_id = $notification['report_id']; $cl_cron_spec = $notification['cron_spec']; $cl_email = $notification['email']; $cl_cc = $notification['cc']; @@ -86,7 +84,7 @@ $form->addInput(array('type'=>'combobox', 'name'=>'fav_report', 'style'=>'width: 250px;', - 'value'=>$cl_fav_report, + 'value'=>$cl_fav_report_id, 'data'=>$fav_reports, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); @@ -99,7 +97,7 @@ if ($request->isPost()) { // Validate user input. - if (!$cl_fav_report) $err->add($i18n->get('error.report')); + if (!$cl_fav_report_id) $err->add($i18n->get('error.report')); if (!ttValidCronSpec($cl_cron_spec)) $err->add($i18n->get('error.field'), $i18n->get('label.schedule')); if (!ttValidEmail($cl_email)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); if (!ttValidEmail($cl_cc, true)) $err->add($i18n->get('error.field'), $i18n->get('label.cc')); @@ -114,7 +112,7 @@ 'id' => $notification_id, 'cron_spec' => $cl_cron_spec, 'next' => $next, - 'report_id' => $cl_fav_report, + 'report_id' => $cl_fav_report_id, 'email' => $cl_email, 'cc' => $cl_cc, 'subject' => $cl_subject, From d537315bdd0072e25558ba006bfbfba13a84b8d2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 Dec 2018 18:56:53 +0000 Subject: [PATCH 0539/1848] A bit more refactoring. --- WEB-INF/lib/ttFavReportHelper.class.php | 1 - WEB-INF/templates/footer.tpl | 2 +- password_change.php | 31 ++++++++++++++----------- password_reset.php | 6 ++--- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index a1f2b945d..b056bd819 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -72,7 +72,6 @@ static function get($id) { } return false; } - // getReport - returns a report identified by its id. // TODO: get rid of this function by encapsulating all cron related tasks in its own class. // Because cron works for all orgs and we want this class to always work in context of diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index eb75ce260..63adffd9f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4614 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4615 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/password_change.php b/password_change.php index 2dce99f9a..b4e577557 100644 --- a/password_change.php +++ b/password_change.php @@ -33,27 +33,30 @@ $auth->doLogout(); +// Access checks. $cl_ref = $request->getParameter('ref'); if (!$cl_ref || $auth->isPasswordExternal()) { header('Location: login.php'); exit(); } - -// Get user ID. $user_id = ttUserHelper::getUserIdByTmpRef($cl_ref); -if ($user_id) { - $user = new ttUser(null, $user_id); // Note: reusing $user from initialize.php. - // In case user language is different - reload $i18n. - if ($i18n->lang != $user->lang) { - $i18n->load($user->lang); - $smarty->assign('i18n', $i18n->keys); - } - if ($user->custom_logo) { - $smarty->assign('custom_logo', 'images/'.$user->group_id.'.png'); - $smarty->assign('mobile_custom_logo', '../images/'.$user->group_id.'.png'); - } - $smarty->assign('user', $user); +if (!$user_id) { + header('Location: access_denied.php'); // No user found by provided reference. + exit(); +} +// End of access checks. + +$user = new ttUser(null, $user_id); // Note: reusing $user from initialize.php. +// In case user language is different - reload $i18n. +if ($i18n->lang != $user->lang) { + $i18n->load($user->lang); + $smarty->assign('i18n', $i18n->keys); +} +if ($user->custom_logo) { + $smarty->assign('custom_logo', 'images/'.$user->group_id.'.png'); + $smarty->assign('mobile_custom_logo', '../images/'.$user->group_id.'.png'); } +$smarty->assign('user', $user); $cl_password1 = $request->getParameter('password1'); $cl_password2 = $request->getParameter('password2'); diff --git a/password_reset.php b/password_reset.php index 1ee4711ed..4d4e24867 100644 --- a/password_reset.php +++ b/password_reset.php @@ -36,13 +36,13 @@ exit(); } +$cl_login = $request->getParameter('login'); + $form = new Form('resetPasswordForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','style'=>'width: 300px;')); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','style'=>'width: 300px;','value'=>$cl_login)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.reset_password'))); if ($request->isPost()) { - $cl_login = $request->getParameter('login'); - // Validate user input. if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); From 2469578bc42cdad7caf9ca05855726be8e953fbc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 Dec 2018 19:26:42 +0000 Subject: [PATCH 0540/1848] Removed group selector from plugins.php to keep things simple. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/plugins.tpl | 7 ------ plugins.php | 40 ++++------------------------------- 3 files changed, 5 insertions(+), 44 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 63adffd9f..507e6e5a1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4615 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4616 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index 6b88725b9..11514d16a 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -89,13 +89,6 @@ function handlePluginCheckboxes() {
-{if $group_dropdown} - - - - -
{$i18n.label.group}: {$forms.pluginsForm.group.control}
-{/if} diff --git a/plugins.php b/plugins.php index a19c1e128..5027420e0 100644 --- a/plugins.php +++ b/plugins.php @@ -34,24 +34,9 @@ header('Location: access_denied.php'); exit(); } -if ($request->isPost()) { - $groupChanged = $request->getParameter('group_changed'); // Reused in multiple places below. - if ($groupChanged && !($user->can('manage_subgroups') && $user->isGroupValid($request->getParameter('group')))) { - header('Location: access_denied.php'); // Group changed, but no rght or wrong group id. - exit(); - } -} // End of access checks. -// Determine group for which we display this page. -if ($request->isPost() && $groupChanged) { - $group_id = $request->getParameter('group'); - $user->setOnBehalfGroup($group_id); -} else { - $group_id = $user->getGroup(); -} - -if ($request->isPost() && $request->getParameter('btn_save')) { +if ($request->isPost()) { // Plugins that user wants to save for the current group. $cl_charts = $request->getParameter('charts'); $cl_clients = $request->getParameter('clients'); @@ -86,21 +71,7 @@ } $form = new Form('pluginsForm'); -// Group dropdown. -if ($user->can('manage_subgroups')) { - $groups = $user->getGroupsForDropdown(); - if (count($groups) > 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'document.pluginsForm.group_changed.value=1;document.pluginsForm.submit();', - 'name'=>'group', - 'style'=>'width: 250px;', - 'value'=>$group_id, - 'data'=>$groups, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'group_changed')); - $smarty->assign('group_dropdown', 1); - } -} + // Plugin checkboxes. $form->addInput(array('type'=>'checkbox','name'=>'charts','value'=>$cl_charts)); $form->addInput(array('type'=>'checkbox','name'=>'clients','value'=>$cl_clients,'onchange'=>'handlePluginCheckboxes()')); @@ -118,12 +89,9 @@ // Submit button. $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -if ($request->isPost() && $request->getParameter('btn_save')) { +if ($request->isPost()) { // Note: we get here when the Save button is clicked. - // We update plugin list for the currently selected group. - // - // We don't get here if group changed in post. - // In this case the page is simply re-displayed for new group. + // We update plugin list for the current group. // Prepare plugins string. if ($cl_charts) From 35727570b2274aca4f0d816372dabfc93d00cf2d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 Dec 2018 22:50:43 +0000 Subject: [PATCH 0541/1848] Refactored predefined expenses config for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/predefined_expense_add.tpl | 2 +- WEB-INF/templates/predefined_expense_edit.tpl | 2 +- predefined_expense_delete.php | 17 ++++++++++------- predefined_expense_edit.php | 8 ++++++-- predefined_expenses.php | 1 + 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 507e6e5a1..ed2a2f050 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$forms.pluginsForm.charts.control}
- - + diff --git a/WEB-INF/templates/predefined_expense_edit.tpl b/WEB-INF/templates/predefined_expense_edit.tpl index c9947aecf..f53b512ad 100644 --- a/WEB-INF/templates/predefined_expense_edit.tpl +++ b/WEB-INF/templates/predefined_expense_edit.tpl @@ -9,7 +9,7 @@ - + diff --git a/predefined_expense_delete.php b/predefined_expense_delete.php index 9b4450325..d8fc057fc 100644 --- a/predefined_expense_delete.php +++ b/predefined_expense_delete.php @@ -39,9 +39,15 @@ header('Location: feature_disabled.php'); exit(); } - $cl_predefined_expense_id = (int)$request->getParameter('id'); $predefined_expense = ttPredefinedExpenseHelper::get($cl_predefined_expense_id); +if (!$predefined_expense) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + + $predefined_expense_to_delete = $predefined_expense['name']; $form = new Form('predefinedExpenseDeleteForm'); @@ -51,12 +57,9 @@ if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if(ttPredefinedExpenseHelper::get($cl_predefined_expense_id)) { - if (ttPredefinedExpenseHelper::delete($cl_predefined_expense_id)) { - header('Location: predefined_expenses.php'); - exit(); - } else - $err->add($i18n->get('error.db')); + if (ttPredefinedExpenseHelper::delete($cl_predefined_expense_id)) { + header('Location: predefined_expenses.php'); + exit(); } else $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { diff --git a/predefined_expense_edit.php b/predefined_expense_edit.php index ab2299c0a..3f0cb0c8c 100644 --- a/predefined_expense_edit.php +++ b/predefined_expense_edit.php @@ -39,14 +39,18 @@ header('Location: feature_disabled.php'); exit(); } - $predefined_expense_id = (int) $request->getParameter('id'); +$predefined_expense = ttPredefinedExpenseHelper::get($predefined_expense_id); +if (!$predefined_expense) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_cost = trim($request->getParameter('cost')); } else { - $predefined_expense = ttPredefinedExpenseHelper::get($predefined_expense_id); $cl_name = $predefined_expense['name']; $cl_cost = $predefined_expense['cost']; } diff --git a/predefined_expenses.php b/predefined_expenses.php index 99c2c899f..e1c14d802 100644 --- a/predefined_expenses.php +++ b/predefined_expenses.php @@ -39,6 +39,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. $form = new Form('predefinedExpensesForm'); From a3eb3cd074e8b579c9948a6b12587f033ecb3c7e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Dec 2018 14:05:19 +0000 Subject: [PATCH 0542/1848] Refactored profile_edit.php for subgroups. --- WEB-INF/lib/ttUserHelper.class.php | 27 ++++++++++++++++++------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- predefined_expense_add.php | 1 + profile_edit.php | 32 ++++++++++++++++++++---------- 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 0d628f6d0..f91128e7e 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -146,16 +146,27 @@ static function update($user_id, $fields) { $mdb2 = getConnection(); // Check parameters. - if (!$user_id || !isset($fields['login'])) + if (!$user_id) return false; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + // Prepare query parts. + if (isset($fields['login'])) { + $login_part = ", login = ".$mdb2->quote($fields['login']); + } + if (isset($fields['password'])) $pass_part = ', password = md5('.$mdb2->quote($fields['password']).')'; - if (in_array('manage_users', $user->rights)) { + + if (isset($fields['name'])) + $name_part = ', name = '.$mdb2->quote($fields['name']); + + if ($user->can('manage_users')) { if (isset($fields['role_id'])) { $role_id = (int) $fields['role_id']; - $role_id_part = ", role_id = $role_id"; + $role_part = ", role_id = $role_id"; } if (array_key_exists('client_id', $fields)) // Could be NULL. $client_part = ", client_id = ".$mdb2->quote($fields['client_id']); @@ -167,17 +178,19 @@ static function update($user_id, $fields) { $rate_part = ", rate = ".$mdb2->quote($rate); } + if (isset($fields['email'])) + $email_part = ', email = '.$mdb2->quote($fields['email']); + if (isset($fields['status'])) { $status = (int) $fields['status']; $status_part = ", status = $status"; } $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; + $parts = ltrim($login_part.$pass_part.$name_part.$role_part.$client_part.$rate_part.$email_part.$modified_part.$status_part, ','); - $sql = "update tt_users set login = ".$mdb2->quote($fields['login']). - "$pass_part, name = ".$mdb2->quote($fields['name']). - "$role_id_part $client_part $rate_part $modified_part $status_part, email = ".$mdb2->quote($fields['email']). - " where id = $user_id"; + $sql = "update tt_users set $parts". + " where id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ed2a2f050..d703090c2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4616 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4617 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/predefined_expense_add.tpl b/WEB-INF/templates/predefined_expense_add.tpl index 1bb788df9..fd2983a70 100644 --- a/WEB-INF/templates/predefined_expense_add.tpl +++ b/WEB-INF/templates/predefined_expense_add.tpl @@ -9,7 +9,7 @@
{$i18n.label.cost} (*):{$forms.predefinedExpenseForm.cost.control} {$user->currency|escape}{$forms.predefinedExpenseForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.cost} (*):{$forms.predefinedExpenseForm.cost.control} {$user->currency|escape}{$forms.predefinedExpenseForm.cost.control} {$user->getCurrency()|escape}
-
 Anuko Time Tracker 1.18.29.4617 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4618 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 052702975..546fffaa1 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -83,7 +83,7 @@
  {$i18n.menu.logout} · - {if $user->can('manage_own_settings')} + {if $user->exists() && $user->can('manage_own_settings')} {$i18n.menu.profile} · {/if} {if $user->can('manage_basic_settings')} diff --git a/predefined_expense_add.php b/predefined_expense_add.php index 0bff7e051..2a0ab6be9 100644 --- a/predefined_expense_add.php +++ b/predefined_expense_add.php @@ -39,6 +39,7 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); diff --git a/profile_edit.php b/profile_edit.php index 9de1820ee..d0d3de5fe 100644 --- a/profile_edit.php +++ b/profile_edit.php @@ -36,9 +36,15 @@ header('Location: access_denied.php'); exit(); } +if (!$user->exists()) { + header('Location: access_denied.php'); // No users in subgroup. + exit(); +} // End of access checks. -$can_manage_account = $user->can('manage_own_account'); +$can_manage_account = $user->behalfGroup ? $user->can('manage_subgroups') : $user->can('manage_own_account'); +if ($user->behalf_id) $user_details = $user->getUserDetails($user->behalf_id); +$current_login = $user->behalf_id ? $user_details['login'] : $user->login; if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -49,9 +55,15 @@ } $cl_email = trim($request->getParameter('email')); } else { - $cl_name = $user->name; - $cl_login = $user->login; - $cl_email = $user->email; + if ($user->behalf_id) { + $cl_name = $user_details['name']; + $cl_login = $user_details['login']; + $cl_email = $user_details['email']; + } else { + $cl_name = $user->name; + $cl_login = $user->login; + $cl_email = $user->email; + } } $form = new Form('profileForm'); @@ -70,7 +82,7 @@ if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); // New login must be unique. - if ($cl_login != $user->login && ttUserHelper::getUserByLogin($cl_login)) + if ($cl_login != $current_login && ttUserHelper::getUserByLogin($cl_login)) $err->add($i18n->get('error.user_exists')); if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { @@ -83,12 +95,10 @@ // Finished validating user input. if ($err->no()) { - $update_result = ttUserHelper::update($user->id, array( - 'name' => $cl_name, - 'login' => $cl_login, - 'password' => $cl_password1, - 'email' => $cl_email, - 'status' => ACTIVE)); + $fields = $can_manage_account ? + array('name'=>$cl_name,'login'=>$cl_login,'password'=>$cl_password1,'email'=>$cl_email) : + array('password'=>$cl_password1); + $update_result = ttUserHelper::update($user->getUser(), $fields); if ($update_result) { header('Location: time.php'); exit(); From 337ae7c9f4cf2cabcbf20f6844a6e71562263500 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Dec 2018 14:23:25 +0000 Subject: [PATCH 0543/1848] Removed group selector from projects.php to keep things simple. --- WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/projects.tpl | 10 ---------- projects.php | 33 --------------------------------- 4 files changed, 2 insertions(+), 45 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 5c21879bf..e6f271df8 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -250,9 +250,9 @@ function getAssignedProjects() $result = array(); $mdb2 = getConnection(); + $user_id = $this->getUser(); $group_id = $this->getGroup(); $org_id = $this->org_id; - $user_id = $this->getUser(); // Do a query with inner join to get assigned projects. $sql = "select p.id, p.name, p.description, p.tasks, upb.rate from tt_projects p". diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d703090c2..d6037b025 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4618 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4619 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/projects.tpl b/WEB-INF/templates/projects.tpl index 09966a843..589993652 100644 --- a/WEB-INF/templates/projects.tpl +++ b/WEB-INF/templates/projects.tpl @@ -6,16 +6,6 @@
{if $user->can('manage_projects')} - {if $group_dropdown} -{$forms.projectsForm.open} {* projectsForm consists only of one dropdown group control *} - - - - -
{$i18n.label.group}: {$forms.projectsForm.group.control}
-{$forms.projectsForm.close} - {/if} - {if $inactive_projects} diff --git a/projects.php b/projects.php index 8b4537e79..5b562366e 100644 --- a/projects.php +++ b/projects.php @@ -28,7 +28,6 @@ require_once('initialize.php'); import('form.Form'); -import('ttTeamHelper'); import('ttGroupHelper'); // Access checks. @@ -40,46 +39,14 @@ header('Location: feature_disabled.php'); exit(); } -if ($request->isPost() && !$user->isGroupValid($request->getParameter('group'))) { - header('Location: access_denied.php'); // Wrong group id in post. - exit(); -} // End of access checks. -if ($request->isPost()) { - $group_id = $request->getParameter('group'); - $user->setOnBehalfGroup($group_id); - // Projects feature may not be available in new group, check and redirect. - if (MODE_PROJECTS != $user->getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); - } -} else { - $group_id = $user->getGroup(); -} - -$form = new Form('projectsForm'); -if ($user->can('manage_subgroups')) { - $groups = $user->getGroupsForDropdown(); - if (count($groups) > 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.submit();', - 'name'=>'group', - 'style'=>'width: 250px;', - 'value'=>$group_id, - 'data'=>$groups, - 'datakeys'=>array('id','name'))); - $smarty->assign('group_dropdown', 1); - } -} - if($user->can('manage_projects')) { $active_projects = ttGroupHelper::getActiveProjects(); $inactive_projects = ttGroupHelper::getInactiveProjects(); } else $active_projects = $user->getAssignedProjects(); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('active_projects', $active_projects); $smarty->assign('inactive_projects', $inactive_projects); $smarty->assign('title', $i18n->get('title.projects')); From 01654e65fdac375c1db8317a956b727987c98c04 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Dec 2018 14:51:25 +0000 Subject: [PATCH 0544/1848] Refactoring - ongoing. --- WEB-INF/lib/ttGroupHelper.class.php | 38 +++++++++++++++++++++++++++ WEB-INF/lib/ttProjectHelper.class.php | 3 ++- WEB-INF/lib/ttTeamHelper.class.php | 38 --------------------------- WEB-INF/templates/footer.tpl | 2 +- mobile/project_add.php | 3 ++- mobile/project_edit.php | 3 ++- mobile/users.php | 3 ++- project_add.php | 3 ++- project_edit.php | 3 ++- 9 files changed, 51 insertions(+), 45 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 4ba7805e4..8298627ac 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -446,4 +446,42 @@ static function getNotifications() { } return false; } + + // The getActiveUsers obtains all active users in a given group. + static function getActiveUsers($options = null) { + global $user; + global $i18n; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + if (isset($options['getAllFields'])) + $sql = "select u.*, r.name as role_name, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $group_id and u.org_id = $org_id and u.status = 1 order by upper(u.name)"; + else + $sql = "select id, name from tt_users where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)"; + $res = $mdb2->query($sql); + $user_list = array(); + if (is_a($res, 'PEAR_Error')) + return false; + while ($val = $res->fetchRow()) { + // Localize top manager role name, as it is not localized in db. + if ($val['rank'] == 512) + $val['role_name'] = $i18n->get('role.top_manager.label'); + $user_list[] = $val; + } + + if (isset($options['putSelfFirst'])) { + // Put own entry at the front. + $cnt = count($user_list); + for($i = 0; $i < $cnt; $i++) { + if ($user_list[$i]['id'] == $user->id) { + $self = $user_list[$i]; // Found self. + array_unshift($user_list, $self); // Put own entry at the front. + array_splice($user_list, $i+1, 1); // Remove duplicate. + } + } + } + return $user_list; + } } diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index b5fb74dc0..87d75c623 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -28,6 +28,7 @@ import('ttTeamHelper'); import('ttUserHelper'); +import('ttGroupHelper'); // Class ttProjectHelper is used to help with project related tasks. class ttProjectHelper { @@ -216,7 +217,7 @@ static function insert($fields) $last_id = $mdb2->lastInsertID('tt_projects', 'id'); // Bind the project to users. - $active_users = ttTeamHelper::getActiveUsers(array('getAllFields'=>true)); + $active_users = ttGroupHelper::getActiveUsers(array('getAllFields'=>true)); foreach ($active_users as $u) { if(in_array($u['id'], $users)) { $sql = "insert into tt_user_project_binds (project_id, user_id, group_id, org_id, status, rate) values( diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index cf455405b..2aab936a0 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -54,44 +54,6 @@ static function getUsersForClient() { return $user_list; } - // The getActiveUsers obtains all active users in a given group. - static function getActiveUsers($options = null) { - global $user; - global $i18n; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - if (isset($options['getAllFields'])) - $sql = "select u.*, r.name as role_name, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $group_id and u.org_id = $org_id and u.status = 1 order by upper(u.name)"; - else - $sql = "select id, name from tt_users where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)"; - $res = $mdb2->query($sql); - $user_list = array(); - if (is_a($res, 'PEAR_Error')) - return false; - while ($val = $res->fetchRow()) { - // Localize top manager role name, as it is not localized in db. - if ($val['rank'] == 512) - $val['role_name'] = $i18n->get('role.top_manager.label'); - $user_list[] = $val; - } - - if (isset($options['putSelfFirst'])) { - // Put own entry at the front. - $cnt = count($user_list); - for($i = 0; $i < $cnt; $i++) { - if ($user_list[$i]['id'] == $user->id) { - $self = $user_list[$i]; // Found self. - array_unshift($user_list, $self); // Put own entry at the front. - array_splice($user_list, $i+1, 1); // Remove duplicate. - } - } - } - return $user_list; - } - // The swapRolesWith swaps existing user role with that of another user. static function swapRolesWith($user_id) { global $user; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d6037b025..dff1dd795 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.projects.active_projects}
-
 Anuko Time Tracker 1.18.29.4619 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4620 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/project_add.php b/mobile/project_add.php index a7a540d05..a6ed2e8d9 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttProjectHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_projects')) { @@ -42,7 +43,7 @@ } // End of access checks. -$users = ttTeamHelper::getActiveUsers(); +$users = ttGroupHelper::getActiveUsers(); foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; diff --git a/mobile/project_edit.php b/mobile/project_edit.php index 887946154..ec8c53bab 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttProjectHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_projects')) { @@ -48,7 +49,7 @@ } // End of access checks. -$users = ttTeamHelper::getActiveUsers(); +$users = ttGroupHelper::getActiveUsers(); foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; diff --git a/mobile/users.php b/mobile/users.php index 874b07634..594fa5bf1 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -29,6 +29,7 @@ require_once('../initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); import('ttTimeHelper'); // Access checks. @@ -41,7 +42,7 @@ $uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); // Get users. -$active_users = ttTeamHelper::getActiveUsers(array('getAllFields'=>true)); +$active_users = ttGroupHelper::getActiveUsers(array('getAllFields'=>true)); if($user->can('manage_users')) { $can_delete_manager = (1 == count($active_users)); $inactive_users = ttTeamHelper::getInactiveUsers($user->group_id, true); diff --git a/project_add.php b/project_add.php index 9800b7215..53cad4bc7 100644 --- a/project_add.php +++ b/project_add.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttProjectHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_projects')) { @@ -42,7 +43,7 @@ } // End of access checks. -$users = ttTeamHelper::getActiveUsers(); +$users = ttGroupHelper::getActiveUsers(); foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; diff --git a/project_edit.php b/project_edit.php index 542fb4647..14f319e90 100644 --- a/project_edit.php +++ b/project_edit.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttProjectHelper'); import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!ttAccessAllowed('manage_projects')) { @@ -48,7 +49,7 @@ } // End of access checks. -$users = ttTeamHelper::getActiveUsers(); +$users = ttGroupHelper::getActiveUsers(); foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; From 38dd91dcf8a9ecf6b7ceb73a9aabf787b96b6f6e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Dec 2018 15:41:22 +0000 Subject: [PATCH 0545/1848] More refactoring for subgroups. --- WEB-INF/lib/ttGroupHelper.class.php | 21 +++++++++++++++++++++ WEB-INF/lib/ttTeamHelper.class.php | 17 ----------------- WEB-INF/templates/footer.tpl | 2 +- mobile/project_add.php | 3 +-- mobile/project_edit.php | 3 +-- mobile/tasks.php | 3 ++- mobile/time.php | 3 +-- mobile/time_edit.php | 3 +-- mobile/timer.php | 3 +-- project_add.php | 3 +-- project_edit.php | 3 +-- reports.php | 3 ++- tasks.php | 3 ++- time.php | 3 +-- time_edit.php | 3 +-- week.php | 3 +-- 16 files changed, 38 insertions(+), 41 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 8298627ac..801793ffd 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -484,4 +484,25 @@ static function getActiveUsers($options = null) { } return $user_list; } + + // getActiveTasks - returns an array of active tasks for a group. + static function getActiveTasks() + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, name, description from tt_tasks". + " where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 2aab936a0..6aa7b917d 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -157,23 +157,6 @@ static function getAllProjects($group_id, $all_fields = false) { return false; } - // getActiveTasks - returns an array of active tasks for a group. - static function getActiveTasks($group_id) - { - $result = array(); - $mdb2 = getConnection(); - - $sql = "select id, name, description from tt_tasks where group_id = $group_id and status = 1 order by upper(name)"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - } - return $result; - } - // getInactiveTasks - returns an array of inactive tasks for a group. static function getInactiveTasks($group_id) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index dff1dd795..60f6f55c9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4620 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4621 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/project_add.php b/mobile/project_add.php index a6ed2e8d9..aa3e40f73 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -29,7 +29,6 @@ require_once('../initialize.php'); import('form.Form'); import('ttProjectHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); // Access checks. @@ -47,7 +46,7 @@ foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; -$tasks = ttTeamHelper::getActiveTasks($user->group_id); +$tasks = ttGroupHelper::getActiveTasks(); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; diff --git a/mobile/project_edit.php b/mobile/project_edit.php index ec8c53bab..afe999536 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -29,7 +29,6 @@ require_once('../initialize.php'); import('form.Form'); import('ttProjectHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); // Access checks. @@ -53,7 +52,7 @@ foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; -$tasks = ttTeamHelper::getActiveTasks($user->group_id); +$tasks = ttGroupHelper::getActiveTasks(); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; diff --git a/mobile/tasks.php b/mobile/tasks.php index 0667bc3bd..67adab041 100644 --- a/mobile/tasks.php +++ b/mobile/tasks.php @@ -29,6 +29,7 @@ require_once('../initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!(ttAccessAllowed('view_own_tasks') || ttAccessAllowed('manage_tasks'))) { @@ -42,7 +43,7 @@ // End of access checks. if($user->can('manage_tasks')) { - $active_tasks = ttTeamHelper::getActiveTasks($user->getGroup()); + $active_tasks = ttGroupHelper::getActiveTasks(); $inactive_tasks = ttTeamHelper::getInactiveTasks($user->getGroup()); } else $active_tasks = $user->getAssignedTasks(); diff --git a/mobile/time.php b/mobile/time.php index 9e51633b2..6bacd0842 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -29,7 +29,6 @@ require_once('../initialize.php'); import('form.Form'); import('ttUserHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); @@ -147,7 +146,7 @@ } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->group_id); + $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 60a14e2c6..cdd507077 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -29,7 +29,6 @@ require_once('../initialize.php'); import('form.Form'); import('ttUserHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); @@ -164,7 +163,7 @@ } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->group_id); + $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/mobile/timer.php b/mobile/timer.php index 184e6274c..73035a395 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -29,7 +29,6 @@ require_once('../initialize.php'); import('form.Form'); import('ttUserHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); @@ -145,7 +144,7 @@ } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->group_id); + $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/project_add.php b/project_add.php index 53cad4bc7..e8f988834 100644 --- a/project_add.php +++ b/project_add.php @@ -29,7 +29,6 @@ require_once('initialize.php'); import('form.Form'); import('ttProjectHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); // Access checks. @@ -47,7 +46,7 @@ foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; -$tasks = ttTeamHelper::getActiveTasks($user->getGroup()); +$tasks = ttGroupHelper::getActiveTasks(); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; diff --git a/project_edit.php b/project_edit.php index 14f319e90..7f48c910c 100644 --- a/project_edit.php +++ b/project_edit.php @@ -29,7 +29,6 @@ require_once('initialize.php'); import('form.Form'); import('ttProjectHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); // Access checks. @@ -53,7 +52,7 @@ foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; -$tasks = ttTeamHelper::getActiveTasks($user->getGroup()); +$tasks = ttGroupHelper::getActiveTasks(); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; diff --git a/reports.php b/reports.php index f4306961e..31209995e 100644 --- a/reports.php +++ b/reports.php @@ -31,6 +31,7 @@ import('form.ActionForm'); import('DateAndTime'); import('ttTeamHelper'); +import('ttGroupHelper'); import('Period'); import('ttProjectHelper'); import('ttFavReportHelper'); @@ -106,7 +107,7 @@ 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.all')))); if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->group_id); + $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/tasks.php b/tasks.php index 6c79fd50d..49d126f01 100644 --- a/tasks.php +++ b/tasks.php @@ -29,6 +29,7 @@ require_once('initialize.php'); import('form.Form'); import('ttTeamHelper'); +import('ttGroupHelper'); // Access checks. if (!(ttAccessAllowed('view_own_tasks') || ttAccessAllowed('manage_tasks'))) { @@ -73,7 +74,7 @@ } if($user->can('manage_tasks')) { - $active_tasks = ttTeamHelper::getActiveTasks($group_id); + $active_tasks = ttGroupHelper::getActiveTasks(); $inactive_tasks = ttTeamHelper::getInactiveTasks($group_id); } else $active_tasks = $user->getAssignedTasks(); diff --git a/time.php b/time.php index a428b9a2b..066653100 100644 --- a/time.php +++ b/time.php @@ -30,7 +30,6 @@ import('form.Form'); import('ttUserHelper'); import('ttGroupHelper'); -import('ttTeamHelper'); import('ttClientHelper'); import('ttTimeHelper'); import('DateAndTime'); @@ -224,7 +223,7 @@ } if (MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { - $task_list = ttTeamHelper::getActiveTasks($group_id); + $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/time_edit.php b/time_edit.php index 4b3f4c2c0..16f69d2ab 100644 --- a/time_edit.php +++ b/time_edit.php @@ -29,7 +29,6 @@ require_once('initialize.php'); import('form.Form'); import('ttUserHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); @@ -167,7 +166,7 @@ } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->group_id); + $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', diff --git a/week.php b/week.php index 289d95127..edba8996e 100644 --- a/week.php +++ b/week.php @@ -32,7 +32,6 @@ import('form.Table'); import('form.TextField'); import('ttUserHelper'); -import('ttTeamHelper'); import('ttGroupHelper'); import('ttWeekViewHelper'); import('ttClientHelper'); @@ -299,7 +298,7 @@ function render(&$table, $value, $row, $column, $selected = false) { } if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { - $task_list = ttTeamHelper::getActiveTasks($user->group_id); + $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', From ef3d1adc569966ab70efa4c780e2165cccaaa205 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Dec 2018 15:54:42 +0000 Subject: [PATCH 0546/1848] Some more refactoring for subgroups. --- WEB-INF/lib/ttGroupHelper.class.php | 21 +++++++++++++++++++++ WEB-INF/lib/ttTeamHelper.class.php | 18 ------------------ WEB-INF/templates/footer.tpl | 2 +- mobile/tasks.php | 3 +-- tasks.php | 3 +-- 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 801793ffd..0e45110c0 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -505,4 +505,25 @@ static function getActiveTasks() } return $result; } + + // getInactiveTasks - returns an array of inactive tasks for a group. + static function getInactiveTasks() + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, name, description from tt_tasks". + " where group_id = $group_id and org_id = $org_id and status = 0 order by upper(name)"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 6aa7b917d..aa3893c65 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -157,24 +157,6 @@ static function getAllProjects($group_id, $all_fields = false) { return false; } - // getInactiveTasks - returns an array of inactive tasks for a group. - static function getInactiveTasks($group_id) - { - $result = array(); - $mdb2 = getConnection(); - - $sql = "select id, name, description from tt_tasks - where group_id = $group_id and status = 0 order by upper(name)"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - } - return $result; - } - // The getAllTasks obtains all tasks in a group. static function getAllTasks($group_id, $all_fields = false) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 60f6f55c9..96e605845 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4621 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4622 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/tasks.php b/mobile/tasks.php index 67adab041..2745df23a 100644 --- a/mobile/tasks.php +++ b/mobile/tasks.php @@ -28,7 +28,6 @@ require_once('../initialize.php'); import('form.Form'); -import('ttTeamHelper'); import('ttGroupHelper'); // Access checks. @@ -44,7 +43,7 @@ if($user->can('manage_tasks')) { $active_tasks = ttGroupHelper::getActiveTasks(); - $inactive_tasks = ttTeamHelper::getInactiveTasks($user->getGroup()); + $inactive_tasks = ttGroupHelper::getInactiveTasks(); } else $active_tasks = $user->getAssignedTasks(); diff --git a/tasks.php b/tasks.php index 49d126f01..ba91ed01c 100644 --- a/tasks.php +++ b/tasks.php @@ -28,7 +28,6 @@ require_once('initialize.php'); import('form.Form'); -import('ttTeamHelper'); import('ttGroupHelper'); // Access checks. @@ -75,7 +74,7 @@ if($user->can('manage_tasks')) { $active_tasks = ttGroupHelper::getActiveTasks(); - $inactive_tasks = ttTeamHelper::getInactiveTasks($group_id); + $inactive_tasks = ttGroupHelper::getInactiveTasks(); } else $active_tasks = $user->getAssignedTasks(); From 6ab97ede1a08afd9f703a713b0eb6addd560a589 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Dec 2018 17:34:37 +0000 Subject: [PATCH 0547/1848] A bit more refactoring for subgroups. --- WEB-INF/lib/ttProjectHelper.class.php | 5 +++-- WEB-INF/templates/footer.tpl | 2 +- mobile/project_add.php | 5 +---- mobile/project_edit.php | 5 +---- project_add.php | 5 +---- project_edit.php | 5 +---- 6 files changed, 8 insertions(+), 19 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 87d75c623..06dcd2866 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -196,10 +196,11 @@ static function delete($id) { // insert function inserts a new project into database. static function insert($fields) { + global $user; $mdb2 = getConnection(); - $group_id = (int) $fields['group_id']; - $org_id = (int) $fields['org_id']; + $group_id = $user->getGroup(); + $org_id = $user->org_id; $name = $fields['name']; $description = $fields['description']; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 96e605845..1cb0da709 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4622 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4623 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/project_add.php b/mobile/project_add.php index aa3e40f73..98f7c064b 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -77,10 +77,7 @@ if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'name' => $cl_name, + if (ttProjectHelper::insert(array('name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, 'tasks' => $cl_tasks, diff --git a/mobile/project_edit.php b/mobile/project_edit.php index afe999536..40728aaf7 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -118,10 +118,7 @@ if ($request->getParameter('btn_copy')) { if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'name' => $cl_name, + if (ttProjectHelper::insert(array('name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, 'tasks' => $cl_tasks, diff --git a/project_add.php b/project_add.php index e8f988834..e00a0316f 100644 --- a/project_add.php +++ b/project_add.php @@ -77,10 +77,7 @@ if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'name' => $cl_name, + if (ttProjectHelper::insert(array('name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, 'tasks' => $cl_tasks, diff --git a/project_edit.php b/project_edit.php index 7f48c910c..6fe082873 100644 --- a/project_edit.php +++ b/project_edit.php @@ -117,10 +117,7 @@ if ($request->getParameter('btn_copy')) { if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array( - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'name' => $cl_name, + if (ttProjectHelper::insert(array('name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, 'tasks' => $cl_tasks, From c059d4ceb33fc1a959028abd85808e33b910cf7e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Dec 2018 18:40:14 +0000 Subject: [PATCH 0548/1848] Added validation of checkbox group input on project config. --- WEB-INF/lib/ttGroupHelper.class.php | 38 +++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- mobile/project_add.php | 2 ++ mobile/project_edit.php | 2 ++ project_add.php | 2 ++ project_edit.php | 2 ++ 6 files changed, 47 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 0e45110c0..780e39ed6 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -526,4 +526,42 @@ static function getInactiveTasks() } return $result; } + + // validateCheckboxGroupInput - validates user input in a group of checkboxes + // in context of a specific database table. + // + // We need to make sure that input is a set of unique positive integers, and is + // "relevant" to the current group (entities exists in table). + // + // It is a safeguard against manipulation of data in posts. + static function validateCheckboxGroupInput($input, $table) { + // Empty input is valid. + if (!$input) return true; + + // Input containing duplicates is invalid. + if (count($input) !== count(array_unique($input))) return false; + + // Input containing anything but positive integers is invalid. + foreach ($input as $single_selection) { + if (!is_numeric($single_selection) || $single_selection <= 0) return false; + } + + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // Now check the table. It must contain all entities associated with current group and org. + $comma_separated = implode(',', $input); + $sql = "select count(*) as item_count from $table". + " where id in ($comma_separated) and group_id = $group_id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return false; + $val = $res->fetchRow(); + if (count($input) != $val['item_count']) + return false; // Number of entities in table is different. + + return true; // All is good. + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1cb0da709..4631c2ec0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4623 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4624 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/project_add.php b/mobile/project_add.php index 98f7c064b..6f6f452d4 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -74,6 +74,8 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); + if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { diff --git a/mobile/project_edit.php b/mobile/project_edit.php index 40728aaf7..8bccd1107 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -95,6 +95,8 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); + if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); if ($err->no()) { if ($request->getParameter('btn_save')) { diff --git a/project_add.php b/project_add.php index e00a0316f..70327eb36 100644 --- a/project_add.php +++ b/project_add.php @@ -74,6 +74,8 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); + if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { diff --git a/project_edit.php b/project_edit.php index 6fe082873..106e657bc 100644 --- a/project_edit.php +++ b/project_edit.php @@ -94,6 +94,8 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); + if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); if ($err->no()) { if ($request->getParameter('btn_save')) { From f4916707c8af136a72a12933d01a5fea1a4322ab Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 Dec 2018 20:04:40 +0000 Subject: [PATCH 0549/1848] Refactoring in ttProjectHelper class. --- WEB-INF/lib/ttProjectHelper.class.php | 84 ++++++++++++++------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 06dcd2866..455076fa7 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -34,17 +34,18 @@ class ttProjectHelper { // getAssignedProjects - returns an array of assigned projects. - static function getAssignedProjects($user_id) - { + static function getAssignedProjects($user_id) { global $user; - - $result = array(); $mdb2 = getConnection(); - + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $result = array(); // Do a query with inner join to get assigned projects. $sql = "select p.id, p.name, p.tasks, upb.rate from tt_projects p". " inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id and upb.status = 1)". - " where p.group_id = ".$user->getGroup()." and p.status = 1 order by p.name"; + " where p.group_id = $group_id and p.org_id = $org_id and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -55,20 +56,21 @@ static function getAssignedProjects($user_id) } // getRates - returns an array of project rates for user, including deassigned and deactivated projects. - static function getRates($user_id) - { + static function getRates($user_id) { global $user; - - $result = array(); $mdb2 = getConnection(); - + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $result = array(); $sql = "select p.id, upb.rate from tt_projects p". " inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id)". - " where group_id = ".$user->getGroup(); + " where p.group_id = $group_id and p.org_id = $org_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { - $val['rate'] = str_replace('.', $user->decimal_mark, $val['rate']); + $val['rate'] = str_replace('.', $user->getDecimalMark(), $val['rate']); $result[] = $val; } } @@ -76,16 +78,16 @@ static function getRates($user_id) } // getProjects - returns an array of active and inactive projects in group. - static function getProjects() - { + static function getProjects() { global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; $result = array(); - $mdb2 = getConnection(); - $sql = "select id, name, tasks from tt_projects". - " where group_id = ".$user->getGroup()." and (status = 0 or status = 1) order by name"; - + " where group_id = $group_id and org_id = $org_id and (status = 0 or status = 1) order by name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -96,16 +98,17 @@ static function getProjects() } // getProjectsForClient - returns an array of active and inactive projects in a group for a client. - static function getProjectsForClient() - { + static function getProjectsForClient() { global $user; - - $result = array(); $mdb2 = getConnection(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $result = array(); $sql = "select p.id, p.name, p.tasks from tt_projects p". " inner join tt_client_project_binds cpb on (cpb.client_id = $user->client_id and cpb.project_id = p.id)". - " where p.group_id = ".$user->getGroup()." and (p.status = 0 or p.status = 1)". + " where p.group_id = $group_id and p.org_id = $org_id and (p.status = 0 or p.status = 1)". " order by p.name"; $res = $mdb2->query($sql); @@ -116,34 +119,36 @@ static function getProjectsForClient() } return $result; } - - + // get - gets details of the project identified by its id. - static function get($id) - { + static function get($id) { global $user; - $mdb2 = getConnection(); - $sql = "select id, name, description, status, tasks from tt_projects where id = $id and group_id = ". - $user->getGroup()." and (status = 0 or status = 1)"; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, name, description, status, tasks from tt_projects". + " where id = $id and group_id = $group_id and org_id = $org_id and (status = 0 or status = 1)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - if ($val && $val['id']) + if ($val && $val['id']) return $val; } return false; } - + // The getProjectByName looks up a project by name. static function getProjectByName($name) { - - $mdb2 = getConnection(); global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; - $sql = "select id from tt_projects where group_id = ". - $user->getGroup()." and name = ".$mdb2->quote($name). + $sql = "select id from tt_projects". + " where group_id = $group_id and org_id = $org_id and name = ".$mdb2->quote($name). " and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -209,8 +214,8 @@ static function insert($fields) $comma_separated = implode(',', $tasks); // This is a comma-separated list of associated task ids. $status = $fields['status']; - $sql = "insert into tt_projects (group_id, org_id, name, description, tasks, status) - values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; + $sql = "insert into tt_projects (group_id, org_id, name, description, tasks, status)". + " values ($group_id, $org_id, ".$mdb2->quote($name).", ".$mdb2->quote($description).", ".$mdb2->quote($comma_separated).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -251,6 +256,7 @@ static function update($fields) { $group_id = $user->getGroup(); $org_id = $user->org_id; + $project_id = $fields['id']; // Project we are updating. $name = $fields['name']; // Project name. $description = $fields['description']; // Project description. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4631c2ec0..a5ede572e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4624 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4625 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c595ddbfdf0515e5fc91cc998bdf2bf92875c998 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 Dec 2018 12:12:36 +0000 Subject: [PATCH 0550/1848] A bit more refactoring ttProjectHelper class for subgroups. --- WEB-INF/lib/ttProjectHelper.class.php | 5 ++--- WEB-INF/lib/ttTeamHelper.class.php | 19 ------------------- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 455076fa7..fe033b9d4 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -26,7 +26,6 @@ // | https://www.anuko.com/time_tracker/credits.htm // +----------------------------------------------------------------------+ -import('ttTeamHelper'); import('ttUserHelper'); import('ttGroupHelper'); @@ -235,8 +234,8 @@ static function insert($fields) } // Bind the project to tasks in tt_project_task_binds table. - $all_tasks = ttTeamHelper::getAllTasks($group_id); - foreach ($all_tasks as $task) { + $active_tasks = ttGroupHelper::getActiveTasks(); + foreach ($active_tasks as $task) { if(in_array($task['id'], $tasks)) { $sql = "insert into tt_project_task_binds (project_id, task_id, group_id, org_id)". " values($last_id, ".$task['id'].", $group_id, $org_id)"; diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index aa3893c65..3fc06cc73 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -157,25 +157,6 @@ static function getAllProjects($group_id, $all_fields = false) { return false; } - // The getAllTasks obtains all tasks in a group. - static function getAllTasks($group_id, $all_fields = false) { - $mdb2 = getConnection(); - - if ($all_fields) - $sql = "select * from tt_tasks where group_id = $group_id order by status, upper(name)"; - else - $sql = "select id, name from tt_tasks where group_id = $group_id order by status, upper(name)"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - // getActiveRolesForUser - returns an array of relevant active roles for user with rank less than self. // "Relevant" means that client roles are filtered out if Client plugin is disabled. static function getActiveRolesForUser() diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a5ede572e..2ab232e46 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4625 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4626 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e295d86a05616ecdae11dd1212f25625424983c1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 Dec 2018 13:10:52 +0000 Subject: [PATCH 0551/1848] Finished refactoring ttProjectHelper class for subgroups. --- WEB-INF/lib/ttProjectHelper.class.php | 63 ++++++++------------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 20 insertions(+), 45 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index fe033b9d4..362a2b622 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -264,7 +264,10 @@ static function update($fields) { $status = $fields['status']; // Project status. // Update records in tt_user_project_binds table. - $sql = "select user_id, status from tt_user_project_binds where project_id = $project_id"; + // This logic is complicated because these binds have rates associated with them. + // We try to recover old rates if a bind existed before and is now reactivated. + $sql = "select user_id, status from tt_user_project_binds". + " where project_id = $project_id and group_id = $group_id and org_id = $org_id"; $all_users = array(); $users_to_update = array(); $res2 = $mdb2->query($sql); @@ -273,7 +276,7 @@ static function update($fields) { // Delete tt_user_project_binds record (safely). ttUserHelper::deleteBind($row['user_id'], $project_id); } elseif (!$row['status']) { - // If we are here, status of the bind is not active. Memorize such users to update their bind status. + // If we are here, status of the bind is not active. Memorize such users to activate their bind status. $users_to_update[] = $row['user_id']; // Users we need to update in tt_user_project_binds. } $all_users[] = $row['user_id']; // All users from tt_user_project_binds for project. @@ -281,7 +284,8 @@ static function update($fields) { // Insert records. $users_to_add = array_diff($users_to_bind, $all_users); // Users missing from tt_user_project_binds, that we need to insert. if(count($users_to_add) > 0) { - $sql = "select id, rate from tt_users where id in (".join(', ', $users_to_add).")"; + $sql = "select id, rate from tt_users". + " where id in (".join(', ', $users_to_add).") and group_id = $group_id and org_id = $org_id"; $res = $mdb2->query($sql); while ($row = $res->fetchRow()) { $user_rate[$row['id']] = $row['rate']; @@ -296,31 +300,22 @@ static function update($fields) { } // Update status (to active) in existing tt_user_project_binds records. if ($users_to_update) { - $sql = "update tt_user_project_binds set status = 1 where project_id = $project_id and user_id in (".join(', ', $users_to_update).")"; + $sql = "update tt_user_project_binds set status = 1". + " where project_id = $project_id and user_id in (".join(', ', $users_to_update).") and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; } // End of updating tt_user_project_binds table. - // Update records in tt_project_task_binds table. - // Obtain existing task binds. - $existing_task_binds = array(); - $sql = "select task_id from tt_project_task_binds where project_id = $project_id"; - $res = $mdb2->query($sql); - while ($val = $res->fetchRow()) { - $existing_task_binds[] = $val['task_id']; - } - // Determine which task binds to delete and which ones to add. - $task_binds_to_delete = array_diff($existing_task_binds, $tasks_to_bind); - $task_binds_to_add = array_diff($tasks_to_bind, $existing_task_binds); - foreach ($task_binds_to_delete as $task_id) { - $sql = "delete from tt_project_task_binds where project_id = $project_id and task_id = $task_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - } - foreach ($task_binds_to_add as $task_id) { + // Update records in tt_project_task_binds table by deleting and inserting. + $sql = "delete from tt_project_task_binds". + " where project_id = $project_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + foreach ($tasks_to_bind as $task_id) { $sql = "insert into tt_project_task_binds (project_id, task_id, group_id, org_id)". " values($project_id, $task_id, $group_id, $org_id)"; $affected = $mdb2->exec($sql); @@ -332,29 +327,9 @@ static function update($fields) { // Update project name, description, tasks and status in tt_projects table. $comma_separated = implode(",", $tasks_to_bind); // This is a comma-separated list of associated task ids. $sql = "update tt_projects set name = ".$mdb2->quote($name).", description = ".$mdb2->quote($description). - ", tasks = ".$mdb2->quote($comma_separated).", status = $status where id = $project_id and group_id = ".$user->getGroup(); + ", tasks = ".$mdb2->quote($comma_separated).", status = ".$mdb2->quote($status). + " where id = $project_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } - - /* - // getAssignedUsers - returns an array of user ids assigned to a project. - static function getAssignedUsers($project_id) - { - global $user; - - $result = array(); - $mdb2 = getConnection(); - - // Do a query with inner join to get assigned users. - $sql = "select id, name from tt_users u - inner join tt_user_project_binds ub on (ub.user_id = u.id and ub.project_id = $project_id and ub.status = 1)"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - } - return $result; - }*/ } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2ab232e46..9e1ca1404 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4626 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4627 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a0410750589c12e822f5f3d1f6ff7f020f41e0bf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 Dec 2018 13:30:57 +0000 Subject: [PATCH 0552/1848] Refactored project add for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/project_add.tpl | 5 +++-- WEB-INF/templates/project_add.tpl | 2 +- mobile/project_add.php | 5 ++++- project_add.php | 7 ++++--- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9e1ca1404..1903310b3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +{if $show_users} - -{if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{/if} +{if $show_tasks} diff --git a/WEB-INF/templates/project_add.tpl b/WEB-INF/templates/project_add.tpl index 2f2fb996e..d49b9a33e 100644 --- a/WEB-INF/templates/project_add.tpl +++ b/WEB-INF/templates/project_add.tpl @@ -18,7 +18,7 @@ {/if} -{if $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && $show_tasks} +{if $show_tasks} diff --git a/mobile/project_add.php b/mobile/project_add.php index 6f6f452d4..c8c661ed2 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -49,6 +49,7 @@ $tasks = ttGroupHelper::getActiveTasks(); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; +$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; if ($request->isPost()) { $cl_name = trim($request->getParameter('project_name')); @@ -66,7 +67,7 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); $form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +if ($show_tasks) $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); @@ -95,6 +96,8 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); +$smarty->assign('show_users', count($users) > 0); +$smarty->assign('show_tasks', $show_tasks); $smarty->assign('title', $i18n->get('title.add_project')); $smarty->assign('content_page_name', 'mobile/project_add.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/project_add.php b/project_add.php index 70327eb36..004168045 100644 --- a/project_add.php +++ b/project_add.php @@ -49,6 +49,7 @@ $tasks = ttGroupHelper::getActiveTasks(); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; +$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; if ($request->isPost()) { $cl_name = trim($request->getParameter('project_name')); @@ -66,7 +67,7 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if (MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) +if ($show_tasks) $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); @@ -94,9 +95,9 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', count($tasks) > 0); $smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); +$smarty->assign('show_users', count($users) > 0); +$smarty->assign('show_tasks', $show_tasks); $smarty->assign('title', $i18n->get('title.add_project')); $smarty->assign('content_page_name', 'project_add.tpl'); $smarty->display('index.tpl'); From ea116938e30f04a448b87956b7660baeec83876e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 Dec 2018 14:32:18 +0000 Subject: [PATCH 0553/1848] Refactored project edit for subgroups. --- WEB-INF/lib/ttProjectHelper.class.php | 19 +++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/project_edit.tpl | 4 +++- WEB-INF/templates/project_edit.tpl | 2 +- mobile/project_edit.php | 17 ++++++----------- project_edit.php | 17 +++++------------ 6 files changed, 35 insertions(+), 26 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 362a2b622..31a88ccc4 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -332,4 +332,23 @@ static function update($fields) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // getAssignedUsers - returns an array of user ids assigned to a project. + static function getAssignedUsers($project_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $result = array(); + $sql = "select user_id from tt_user_project_binds". + " where project_id = $project_id and group_id = $group_id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return false; + while ($row = $res->fetchRow()) { + $result[] = $row['user_id']; + } + return $result; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1903310b3..6209ab653 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4627 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4628 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/project_add.tpl b/WEB-INF/templates/mobile/project_add.tpl index 3aad22c20..d49b9a33e 100644 --- a/WEB-INF/templates/mobile/project_add.tpl +++ b/WEB-INF/templates/mobile/project_add.tpl @@ -11,13 +11,14 @@ {$i18n.label.description}: {$forms.projectForm.description.control}
 
{$i18n.label.users}: {$forms.projectForm.users.control}
 
{$i18n.label.tasks}:{$forms.projectForm.users.control}
 
{$i18n.label.tasks}:
- +{if $show_users} -{if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{/if} +{if $show_tasks} diff --git a/WEB-INF/templates/project_edit.tpl b/WEB-INF/templates/project_edit.tpl index bcabc37ac..2a2364f20 100644 --- a/WEB-INF/templates/project_edit.tpl +++ b/WEB-INF/templates/project_edit.tpl @@ -22,7 +22,7 @@ {/if} -{if $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && $show_tasks} +{if $show_tasks} diff --git a/mobile/project_edit.php b/mobile/project_edit.php index 8bccd1107..31da38903 100644 --- a/mobile/project_edit.php +++ b/mobile/project_edit.php @@ -36,7 +36,7 @@ header('Location: access_denied.php'); exit(); } -if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +if (MODE_PROJECTS != $user->getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { header('Location: feature_disabled.php'); exit(); } @@ -55,6 +55,7 @@ $tasks = ttGroupHelper::getActiveTasks(); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; +$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; if ($request->isPost()) { $cl_name = trim($request->getParameter('project_name')); @@ -66,15 +67,7 @@ $cl_name = $project['name']; $cl_description = $project['description']; $cl_status = $project['status']; - - $mdb2 = getConnection(); - $sql = "select user_id from tt_user_project_binds where status = 1 and project_id = $cl_project_id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) - die($res->getMessage()); - while ($row = $res->fetchRow()) - $cl_users[] = $row['user_id']; - + $cl_users = ttProjectHelper::getAssignedUsers($cl_project_id); $cl_tasks = explode(',', $project['tasks']); } @@ -85,7 +78,7 @@ $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +if ($show_tasks) $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); @@ -142,6 +135,8 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); +$smarty->assign('show_users', count($users) > 0); +$smarty->assign('show_tasks', $show_tasks); $smarty->assign('title', $i18n->get('title.edit_project')); $smarty->assign('content_page_name', 'mobile/project_edit.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/project_edit.php b/project_edit.php index 106e657bc..1402eb112 100644 --- a/project_edit.php +++ b/project_edit.php @@ -55,6 +55,7 @@ $tasks = ttGroupHelper::getActiveTasks(); foreach ($tasks as $task_item) $all_tasks[$task_item['id']] = $task_item['name']; +$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; if ($request->isPost()) { $cl_name = trim($request->getParameter('project_name')); @@ -66,15 +67,7 @@ $cl_name = $project['name']; $cl_description = $project['description']; $cl_status = $project['status']; - - $mdb2 = getConnection(); - $sql = "select user_id from tt_user_project_binds where status = 1 and project_id = $cl_project_id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) - die($res->getMessage()); - while ($row = $res->fetchRow()) - $cl_users[] = $row['user_id']; - + $cl_users = ttProjectHelper::getAssignedUsers($cl_project_id); $cl_tasks = explode(',', $project['tasks']); } @@ -85,7 +78,7 @@ $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if (MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) +if ($show_tasks) $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); @@ -135,9 +128,9 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', count($tasks) > 0); $smarty->assign('onload', 'onLoad="document.projectForm.name.focus()"'); +$smarty->assign('show_users', count($users) > 0); +$smarty->assign('show_tasks', $show_tasks); $smarty->assign('title', $i18n->get('title.edit_project')); $smarty->assign('content_page_name', 'project_edit.tpl'); $smarty->display('index.tpl'); From 45a82f93d80cf124930d1535d4dc7dd15c63e5de Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 Dec 2018 14:40:33 +0000 Subject: [PATCH 0554/1848] Finished refactoring project config for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- mobile/project_delete.php | 2 +- project_delete.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6209ab653..d68ab3dff 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4628 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4629 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/project_edit.tpl b/WEB-INF/templates/mobile/project_edit.tpl index 4a94bfeb9..871f5c1dc 100644 --- a/WEB-INF/templates/mobile/project_edit.tpl +++ b/WEB-INF/templates/mobile/project_edit.tpl @@ -15,12 +15,14 @@ {$i18n.label.status}: {$forms.projectForm.status.control}
 
{$i18n.label.users}: {$forms.projectForm.users.control}
 
{$i18n.label.tasks}:{$forms.projectForm.users.control}
 
{$i18n.label.tasks}:
-
 Anuko Time Tracker 1.18.29.4629 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4630 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/project_delete.php b/mobile/project_delete.php index 5785496aa..ac957e249 100644 --- a/mobile/project_delete.php +++ b/mobile/project_delete.php @@ -35,7 +35,7 @@ header('Location: access_denied.php'); exit(); } -if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +if (MODE_PROJECTS != $user->getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { header('Location: feature_disabled.php'); exit(); } diff --git a/project_delete.php b/project_delete.php index 450241e79..3b165a33d 100644 --- a/project_delete.php +++ b/project_delete.php @@ -35,7 +35,7 @@ header('Location: access_denied.php'); exit(); } -if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +if (MODE_PROJECTS != $user->getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { header('Location: feature_disabled.php'); exit(); } From aa8ffdcec75ded579362d1274e985b4b35a9ac95 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 Dec 2018 16:00:40 +0000 Subject: [PATCH 0555/1848] Refactored monthly quota config for subgroups. --- WEB-INF/lib/ttGroup.class.php | 2 +- WEB-INF/lib/ttTimeHelper.class.php | 17 ++++++++++------- WEB-INF/lib/ttUser.class.php | 5 +++++ WEB-INF/templates/footer.tpl | 2 +- plugins/MonthlyQuota.class.php | 19 +++++++++++-------- quotas.php | 4 ++-- 6 files changed, 30 insertions(+), 19 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index 1aa422c72..f85f90971 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -101,8 +101,8 @@ function __construct($id, $org_id) { $this->currency = $val['currency']; $this->plugins = $val['plugins']; $this->lock_spec = $val['lock_spec']; - /* $this->workday_minutes = $val['workday_minutes']; + /* $this->custom_logo = $val['custom_logo']; */ $this->config = $val['config']; diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 6ddedc456..f48ecc8a0 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -147,9 +147,9 @@ static function postedDurationToMinutes($duration, $max = 1440) { // Handle localized fractional hours. global $user; - $localizedPattern = '/^(\d{1,3})?['.$user->decimal_mark.'][0-9]{1,4}h?$/'; + $localizedPattern = '/^(\d{1,3})?['.$user->getDecimalMark().'][0-9]{1,4}h?$/'; if (preg_match($localizedPattern, $duration )) { // decimal values like .5, 1.25h, ... .. 999.9999h (or with comma) - if ($user->decimal_mark == ',') + if ($user->getDecimalMark() == ',') $duration = str_replace (',', '.', $duration); $minutes = (int)round(60 * floatval($duration)); @@ -691,13 +691,15 @@ static function getAllRecords($user_id) { // getRecords - returns time records for a user for a given date. static function getRecords($user_id, $date) { global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $sql_time_format = "'%k:%i'"; // 24 hour format. - if ('%I:%M %p' == $user->time_format) + if ('%I:%M %p' == $user->getTimeFormat()) $sql_time_format = "'%h:%i %p'"; // 12 hour format for MySQL TIME_FORMAT function. - $result = array(); - $mdb2 = getConnection(); - $client_field = null; if ($user->isPluginEnabled('cl')) $client_field = ", c.name as client"; @@ -707,12 +709,13 @@ static function getRecords($user_id, $date) { if ($user->isPluginEnabled('cl')) $left_joins .= " left join tt_clients c on (l.client_id = c.id)"; + $result = array(); $sql = "select l.id as id, TIME_FORMAT(l.start, $sql_time_format) as start, TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), $sql_time_format) as finish, TIME_FORMAT(l.duration, '%k:%i') as duration, p.name as project, t.name as task, l.comment, l.billable, l.invoice_id $client_field from tt_log l $left_joins - where l.date = '$date' and l.user_id = $user_id and l.status = 1 + where l.date = '$date' and l.user_id = $user_id and l.group_id = $group_id and l.org_id = $org_id and l.status = 1 order by l.start, l.id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index e6f271df8..5a3289171 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -214,6 +214,11 @@ function getLockSpec() { return ($this->behalfGroup ? $this->behalfGroup->lock_spec : $this->lock_spec); } + // getWorkdayMinutes returns workday_minutes for active group. + function getWorkdayMinutes() { + return ($this->behalfGroup ? $this->behalfGroup->workday_minutes : $this->workday_minutes); + } + // getConfig returns config string for active group. function getConfig() { return ($this->behalfGroup ? $this->behalfGroup->config : $this->config); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d68ab3dff..98e8e1c98 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4630 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4631 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/plugins/MonthlyQuota.class.php b/plugins/MonthlyQuota.class.php index 36f2d8cb4..29d8cfb7b 100644 --- a/plugins/MonthlyQuota.class.php +++ b/plugins/MonthlyQuota.class.php @@ -44,10 +44,11 @@ function __construct() { // update - deletes a quota, then inserts a new one. public function update($year, $month, $minutes) { - $deleteSql = "DELETE FROM tt_monthly_quotas WHERE year = $year AND month = $month AND group_id = $this->group_id"; + $deleteSql = "delete from tt_monthly_quotas". + " where year = $year and month = $month and group_id = $this->group_id and org_id = $this->org_id"; $this->db->exec($deleteSql); if ($minutes){ - $insertSql = "INSERT INTO tt_monthly_quotas (group_id, org_id, year, month, minutes)". + $insertSql = "insert into tt_monthly_quotas (group_id, org_id, year, month, minutes)". " values ($this->group_id, $this->org_id, $year, $month, $minutes)"; $affected = $this->db->exec($insertSql); return (!is_a($affected, 'PEAR_Error')); @@ -66,7 +67,8 @@ public function get($year, $month = null) { // getSingle - obtains a quota for a single month. private function getSingle($year, $month) { - $sql = "SELECT minutes FROM tt_monthly_quotas WHERE year = $year AND month = $month AND group_id = $this->group_id"; + $sql = "select minutes from tt_monthly_quotas". + " where year = $year and month = $month and group_id = $this->group_id and org_id = $this->org_id"; $reader = $this->db->query($sql); if (is_a($reader, 'PEAR_Error')) { return false; @@ -79,12 +81,13 @@ private function getSingle($year, $month) { // If we did not find a record, return a calculated monthly quota. $numWorkdays = $this->getNumWorkdays($month, $year); global $user; - return $numWorkdays * $user->workday_minutes; + return $numWorkdays * $user->getWorkdayMinutes(); } // getMany - returns an array of quotas for a given year for group. private function getMany($year){ - $sql = "SELECT month, minutes FROM tt_monthly_quotas WHERE year = $year AND group_id = $this->group_id"; + $sql = "select month, minutes from tt_monthly_quotas". + " where year = $year and group_id = $this->group_id and org_id = $this->org_id"; $result = array(); $res = $this->db->query($sql); if (is_a($res, 'PEAR_Error')) { @@ -128,7 +131,7 @@ public function isValidQuota($value) { } global $user; - $localizedPattern = '/^([0-9]{1,3})?['.$user->decimal_mark.'][0-9]{1,4}h?$/'; + $localizedPattern = '/^([0-9]{1,3})?['.$user->getDecimalMark().'][0-9]{1,4}h?$/'; if (preg_match($localizedPattern, $value )) { // decimal values like 000.5, 999.25h, ... .. 999.9999h (or with comma) return true; } @@ -149,11 +152,11 @@ public function quotaToFloat($value) { } global $user; - $localizedPattern = '/^([0-9]{1,3})?['.$user->decimal_mark.'][0-9]{1,4}h?$/'; + $localizedPattern = '/^([0-9]{1,3})?['.$user->getDecimalMark().'][0-9]{1,4}h?$/'; if (preg_match($localizedPattern, $value )) { // decimal values like 000.5, 999.25h, ... .. 999.9999h (or with comma) // Strip optional h in the end. $value = trim($value, 'h'); - if ($user->decimal_mark == ',') + if ($user->getDecimalMark() == ',') $value = str_replace(',', '.', $value); return (float) $value; } diff --git a/quotas.php b/quotas.php index 8381c3b6a..1f376190e 100644 --- a/quotas.php +++ b/quotas.php @@ -88,7 +88,7 @@ // Handle workday hours. $workday_minutes = ttTimeHelper::postedDurationToMinutes($request->getParameter('workdayHours')); - if ($workday_minutes != $user->workday_minutes) { + if ($workday_minutes != $user->getWorkdayMinutes()) { if (!$user->updateGroup(array('workday_minutes'=>$workday_minutes))) $err->add($i18n->get('error.db')); } @@ -111,7 +111,7 @@ // Get monthly quotas for the entire year. $monthsData = $quota->get($selectedYear); -$workdayHours = ttTimeHelper::toAbsDuration($user->workday_minutes, true); +$workdayHours = ttTimeHelper::toAbsDuration($user->getWorkdayMinutes(), true); $form = new Form('monthlyQuotasForm'); $form->addInput(array('type'=>'text', 'name'=>'workdayHours', 'value'=>$workdayHours, 'style'=>'width:60px')); From 0bc24003fa4ca271427a082b85ebd6edd4219c55 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 11 Dec 2018 14:33:21 +0000 Subject: [PATCH 0556/1848] Work in progress refactoring reports for subgroups. --- WEB-INF/lib/ttUser.class.php | 9 +++++++++ WEB-INF/templates/footer.tpl | 2 +- reports.php | 27 +++++++++++++++++---------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 5a3289171..d320e3815 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -29,6 +29,8 @@ import('ttConfigHelper'); import('ttGroupHelper'); import('ttGroup'); +import('form.Form'); +import('form.ActionForm'); class ttUser { var $login = null; // User login. @@ -787,6 +789,13 @@ function setOnBehalfGroup($group_id) { unset($_SESSION['behalf_id']); unset($_SESSION['behalf_name']); + // Destroy report bean if it was set in session. + $form = new Form('dummyForm'); + $bean = new ActionForm('reportBean', $form, $request); + if ($bean->isSaved()) { + $bean->destroyBean(); + } + // Do not do anything if we don't have rights. if (!$this->can('manage_subgroups')) return; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 98e8e1c98..9f603c43e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4631 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4632 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 31209995e..e6334f9b6 100644 --- a/reports.php +++ b/reports.php @@ -43,6 +43,13 @@ header('Location: access_denied.php'); exit(); } +if (!$user->exists()) { + header('Location: access_denied.php'); // No users in subgroup. + exit(); +} +// End of access checks. + +$trackingMode = $user->getTrackingMode(); // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { @@ -97,7 +104,7 @@ } elseif ($user->isClient()) { $project_list = ttProjectHelper::getProjectsForClient(); } else { - $project_list = ttProjectHelper::getAssignedProjects($user->id); + $project_list = ttProjectHelper::getAssignedProjects($user->getUser()); } $form->addInput(array('type'=>'combobox', 'onchange'=>'fillTaskDropdown(this.value);selectAssignedUsers(this.value);', @@ -106,7 +113,7 @@ 'data'=>$project_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.all')))); -if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { +if (MODE_PROJECTS_AND_TASKS == $trackingMode) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', @@ -149,7 +156,7 @@ if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { // Prepare user and assigned projects arrays. if ($user->can('view_reports') || $user->can('view_all_reports')) { - $max_rank = $user->rank-1; + $rank = $user->getMaxRankForGroup($user->getGroup()); if ($user->can('view_all_reports')) $max_rank = MAX_RANK; if ($user->can('view_own_reports')) $options = array('max_rank'=>$max_rank,'include_self'=>true); @@ -202,11 +209,11 @@ $form->addInput(array('type'=>'checkbox','name'=>'chpaid')); if ($user->can('view_reports') || $user->can('view_all_reports')) $form->addInput(array('type'=>'checkbox','name'=>'chip')); -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +if (MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode) $form->addInput(array('type'=>'checkbox','name'=>'chproject')); -if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +if (MODE_PROJECTS_AND_TASKS == $trackingMode) $form->addInput(array('type'=>'checkbox','name'=>'chtask')); -if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { +if ((TYPE_START_FINISH == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) { $form->addInput(array('type'=>'checkbox','name'=>'chstart')); $form->addInput(array('type'=>'checkbox','name'=>'chfinish')); } @@ -226,9 +233,9 @@ $group_by_options['user'] = $i18n->get('form.reports.group_by_user'); if ($user->isPluginEnabled('cl') && !($user->isClient() && $user->client_id)) $group_by_options['client'] = $i18n->get('form.reports.group_by_client'); -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +if (MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode) $group_by_options['project'] = $i18n->get('form.reports.group_by_project'); -if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) +if (MODE_PROJECTS_AND_TASKS == $trackingMode) $group_by_options['task'] = $i18n->get('form.reports.group_by_task'); if ($custom_fields && $custom_fields->fields[0] && $custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { $group_by_options['cf_1'] = $custom_fields->fields[0]['label']; @@ -253,7 +260,7 @@ if ($request->isGet() && !$bean->isSaved()) { // No previous form data were found in session. Use the following default values. $form->setValueByElement('users', array_keys($user_list)); - $period = new Period(INTERVAL_THIS_MONTH, new DateAndTime($user->date_format)); + $period = new Period(INTERVAL_THIS_MONTH, new DateAndTime($user->getDateFormat())); $form->setValueByElement('start_date', $period->getStartDate()); $form->setValueByElement('end_date', $period->getEndDate()); $form->setValueByElement('chclient', '1'); @@ -283,7 +290,7 @@ // User changed favorite report. We need to load new values into the form. if ($bean->getAttribute('favorite_report')) { // This loads new favorite report options into the bean (into our form). - ttFavReportHelper::loadReport($user->id, $bean); + ttFavReportHelper::loadReport($user->getUser(), $bean); // If user selected no favorite report - mark all user checkboxes (most probable scenario). if ($bean->getAttribute('favorite_report') == -1) From b8d9247f09f3dfbd35a724ba5ac1b8e433dc1fd1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 11 Dec 2018 15:00:07 +0000 Subject: [PATCH 0557/1848] Fixed saving fav report in a subgroup. --- WEB-INF/lib/ttFavReportHelper.class.php | 14 ++++++++------ WEB-INF/templates/footer.tpl | 2 +- reports.php | 6 +++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index b056bd819..d37830090 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -181,8 +181,9 @@ function updateReport($fields) { } // saveReport - saves report options in the database. - static function saveReport($user_id, $bean) { + static function saveReport($bean) { global $user; + $user_id = $user->getUser(); // Set default value of 0 for not set checkboxes (in bean). // Later in this function we use it to construct $fields array to update database. @@ -206,11 +207,11 @@ static function saveReport($user_id, $bean) { $users = join(',', $users_in_bean); } if ($bean->getAttribute('start_date')) { - $dt = new DateAndTime($user->date_format, $bean->getAttribute('start_date')); + $dt = new DateAndTime($user->getDateFormat(), $bean->getAttribute('start_date')); $from = $dt->toString(DB_DATEFORMAT); } if ($bean->getAttribute('end_date')) { - $dt = new DateAndTime($user->date_format, $bean->getAttribute('end_date')); + $dt = new DateAndTime($user->getDateFormat(), $bean->getAttribute('end_date')); $to = $dt->toString(DB_DATEFORMAT); } @@ -268,8 +269,9 @@ static function deleteReport($id) { } // loadReport - loads report options from database into a bean. - static function loadReport($user_id, &$bean) { + static function loadReport(&$bean) { global $user; + $user_id = $user->getUser(); $val = ttFavReportHelper::getReport($bean->getAttribute('favorite_report')); if ($val) { @@ -284,11 +286,11 @@ static function loadReport($user_id, &$bean) { $bean->setAttribute('period', $val['period']); if ($val['period_start']) { $dt = new DateAndTime(DB_DATEFORMAT, $val['period_start']); - $bean->setAttribute('start_date', $dt->toString($user->date_format)); + $bean->setAttribute('start_date', $dt->toString($user->getDateFormat())); } if ($val['period_end']) { $dt = new DateAndTime(DB_DATEFORMAT, $val['period_end']); - $bean->setAttribute('end_date', $dt->toString($user->date_format)); + $bean->setAttribute('end_date', $dt->toString($user->getDateFormat())); } $bean->setAttribute('chclient', $val['show_client']); $bean->setAttribute('chinvoice', $val['show_invoice']); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9f603c43e..c49c2e568 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4632 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4633 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index e6334f9b6..7c7ac0119 100644 --- a/reports.php +++ b/reports.php @@ -290,7 +290,7 @@ // User changed favorite report. We need to load new values into the form. if ($bean->getAttribute('favorite_report')) { // This loads new favorite report options into the bean (into our form). - ttFavReportHelper::loadReport($user->getUser(), $bean); + ttFavReportHelper::loadReport($bean); // If user selected no favorite report - mark all user checkboxes (most probable scenario). if ($bean->getAttribute('favorite_report') == -1) @@ -306,7 +306,7 @@ if (!ttValidString($bean->getAttribute('new_fav_report'))) $err->add($i18n->get('error.field'), $i18n->get('form.reports.save_as_favorite')); if ($err->no()) { - $id = ttFavReportHelper::saveReport($user->id, $bean); // TODO: review "on behalf" situations (both user and group), redesign if needed. + $id = ttFavReportHelper::saveReport($bean); if (!$id) $err->add($i18n->get('error.db')); if ($err->no()) { @@ -323,7 +323,7 @@ // Load default report. $bean->setAttribute('favorite_report',''); $bean->setAttribute('new_fav_report', $report_list[0]['name']); - ttFavReportHelper::loadReport($user->id, $bean); + ttFavReportHelper::loadReport($bean); $form->setValueByElement('users', array_keys($user_list)); $bean->saveBean(); header('Location: reports.php'); From 24759567f66e185d193d48b81acef9b842d96c84 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 11 Dec 2018 16:12:33 +0000 Subject: [PATCH 0558/1848] More refactoring in reports for subgroups. --- WEB-INF/lib/ttFavReportHelper.class.php | 43 +++++++++++++++++++------ WEB-INF/lib/ttGroupHelper.class.php | 19 +++++++++++ WEB-INF/lib/ttReportHelper.class.php | 2 +- WEB-INF/lib/ttTeamHelper.class.php | 15 --------- WEB-INF/templates/footer.tpl | 2 +- reports.php | 4 +-- 6 files changed, 56 insertions(+), 29 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index d37830090..165f42a3c 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -90,10 +90,16 @@ static function getReport($id) { } // getReportByName - returns a report identified by its name. - static function getReportByName($user_id, $report_name) { + static function getReportByName($report_name) { + global $user; $mdb2 = getConnection(); - $sql = "select * from tt_fav_reports where user_id = $user_id and status = 1 and name = ".$mdb2->quote($report_name); + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id from tt_fav_reports". + " where user_id = $user_id and group_id = $group_id and org_id = $org_id and status = 1 and name = ".$mdb2->quote($report_name); $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) { @@ -108,6 +114,7 @@ static function insertReport($fields) { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; @@ -119,7 +126,7 @@ static function insertReport($fields) { " show_task, show_end, show_note, show_custom_field_1, show_work_units,". " group_by1, group_by2, group_by3, show_totals_only)". " values(". - $mdb2->quote($fields['name']).", ".$fields['user_id'].", $group_id, $org_id, ". + $mdb2->quote($fields['name']).", $user_id, $group_id, $org_id, ". $mdb2->quote($fields['client']).", ".$mdb2->quote($fields['option']).", ". $mdb2->quote($fields['project']).", ".$mdb2->quote($fields['task']).", ". $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['invoice']).", ". @@ -140,8 +147,14 @@ static function insertReport($fields) { } // updateReport - updates report options in the database. - function updateReport($fields) { + static function updateReport($fields) { + global $user; $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $sql = "update tt_fav_reports set ". "name = ".$mdb2->quote($fields['name']).", ". "client_id = ".$mdb2->quote($fields['client']).", ". @@ -172,7 +185,7 @@ function updateReport($fields) { "group_by2 = ".$mdb2->quote($fields['group_by2']).", ". "group_by3 = ".$mdb2->quote($fields['group_by3']).", ". "show_totals_only = ".$fields['chtotalsonly']. - " where id = ".$fields['id']; + " where id = ".$fields['id']." and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -183,7 +196,6 @@ function updateReport($fields) { // saveReport - saves report options in the database. static function saveReport($bean) { global $user; - $user_id = $user->getUser(); // Set default value of 0 for not set checkboxes (in bean). // Later in this function we use it to construct $fields array to update database. @@ -247,12 +259,11 @@ static function saveReport($bean) { 'chtotalsonly'=>$bean->getAttribute('chtotalsonly')); $id = false; - $report = ttFavReportHelper::getReportByName($user_id, $fields['name']); + $report = ttFavReportHelper::getReportByName($fields['name']); if ($report) { $fields['id'] = $report['id']; $id = ttFavReportHelper::updateReport($fields); } else { - $fields['user_id'] = $user_id; $id = ttFavReportHelper::insertReport($fields); } @@ -261,9 +272,21 @@ static function saveReport($bean) { // deleteReport - deletes a favorite report. static function deleteReport($id) { + global $user; $mdb2 = getConnection(); - $sql = "delete from tt_fav_reports where id = $id"; + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "delete from tt_cron". + " where report_id = $id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + $sql = "delete from tt_fav_reports". + " where id = $id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -273,7 +296,7 @@ static function loadReport(&$bean) { global $user; $user_id = $user->getUser(); - $val = ttFavReportHelper::getReport($bean->getAttribute('favorite_report')); + $val = ttFavReportHelper::get($bean->getAttribute('favorite_report')); if ($val) { $bean->setAttribute('client', $val['client_id']); $bean->setAttribute('option', $val['cf_1_option_id']); diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 780e39ed6..ad2316756 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -564,4 +564,23 @@ static function validateCheckboxGroupInput($input, $table) { return true; // All is good. } + + // The getUsers obtains all active and inactive (but not deleted) users in a group. + static function getUsers() { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, name from tt_users where group_id = $group_id and org_id = $org_id and (status = 1 or status = 0) order by upper(name)"; + $res = $mdb2->query($sql); + $user_list = array(); + if (is_a($res, 'PEAR_Error')) + return false; + while ($val = $res->fetchRow()) { + $user_list[] = $val; + } + return $user_list; + } } diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 0d99ce88a..13226ca44 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1010,7 +1010,7 @@ static function verifyBean($bean) { // Check users. $users_in_bean = $bean->getAttribute('users'); if (is_array($users_in_bean)) { - $users_in_group = ttTeamHelper::getUsers(); + $users_in_group = ttGroupHelper::getUsers(); foreach ($users_in_group as $user_in_group) { $valid_ids[] = $user_in_group['id']; } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 3fc06cc73..4dd2f9aaa 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -104,21 +104,6 @@ static function getUsersForSwap() { return $user_list; } - // The getUsers obtains all active and inactive (but not deleted) users in a group. - static function getUsers() { - global $user; - $mdb2 = getConnection(); - $sql = "select id, name from tt_users where group_id = $user->group_id and (status = 1 or status = 0) order by upper(name)"; - $res = $mdb2->query($sql); - $user_list = array(); - if (is_a($res, 'PEAR_Error')) - return false; - while ($val = $res->fetchRow()) { - $user_list[] = $val; - } - return $user_list; - } - // The getInactiveUsers obtains all inactive users in a group. static function getInactiveUsers($group_id, $all_fields = false) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c49c2e568..244dc3137 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4633 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4634 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 7c7ac0119..c3bb88096 100644 --- a/reports.php +++ b/reports.php @@ -332,12 +332,12 @@ } else { // Generate button pressed. Check some values. if (!$bean->getAttribute('period')) { - $start_date = new DateAndTime($user->date_format, $bean->getAttribute('start_date')); + $start_date = new DateAndTime($user->getDateFormat(), $bean->getAttribute('start_date')); if ($start_date->isError() || !$bean->getAttribute('start_date')) $err->add($i18n->get('error.field'), $i18n->get('label.start_date')); - $end_date = new DateAndTime($user->date_format, $bean->getAttribute('end_date')); + $end_date = new DateAndTime($user->getDateFormat(), $bean->getAttribute('end_date')); if ($end_date->isError() || !$bean->getAttribute('end_date')) $err->add($i18n->get('error.field'), $i18n->get('label.end_date')); From 29d6481a7dc9e1538be50a942e4891db17467ec4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 12 Dec 2018 14:40:21 +0000 Subject: [PATCH 0559/1848] Failed attempt to write ttCronJobHelper, some improvements to cron.php. --- WEB-INF/lib/ttCronJobHelper.class.php | 111 ++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- cron.php | 19 +++-- 3 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 WEB-INF/lib/ttCronJobHelper.class.php diff --git a/WEB-INF/lib/ttCronJobHelper.class.php b/WEB-INF/lib/ttCronJobHelper.class.php new file mode 100644 index 000000000..5dcc0b69b --- /dev/null +++ b/WEB-INF/lib/ttCronJobHelper.class.php @@ -0,0 +1,111 @@ += c.next and fr.status = 1". // Due now. + " and c.status = 1 and c.report_id is not null and c.email is not null"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return; + while ($val = $res->fetchRow()) { + $this->reports[] = $val; + } + } + + // exec - processes reports one at a time by sending each out. + function exec() { + foreach ($this->reports as $report) { + // Get favorite report details. + $options = $this->getReportOptions($report['report_id']); + if (!$options) continue; // Skip not found report. + + // Recycle global $user object, as user settings are specific for each report. + unset($user); + $user = new ttUser(null, $options['user_id']); + if (!$user->id) continue; // Skip not found user. + + // Avoid complications with impersonated users, possibly from subgroups. + // Note: this may happen when cron.php is called by a browser who already impersonates. + // This is not supposed to happen in automatic cron job. + if ($user->behalf_id) + continue; // Skip processing on behalf situations entirely. + + // TODO: coding ongoing here. Not finished. Add other processing when ready. + + } + } + + // getReportOptions - returns an array of fav report options from database data. + private function getReportOptions($id) { + $mdb2 = getConnection(); + + $sql = "select * from tt_fav_reports where id = $id and status = 1"; + $res = $mdb2->query($sql); + if (is_a(res, 'PEAR_Error')) return false; + + $val = $res->fetchRow(); + if (!$val) return false; + + // Drop things we don't need. + unset($val['id']); + unset($val['report_spec']); + unset($val['status']); + + return $val; + } +} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 244dc3137..1caa6b555 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4634 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4635 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cron.php b/cron.php index 98c1456fe..19384df40 100644 --- a/cron.php +++ b/cron.php @@ -47,10 +47,12 @@ $mdb2 = getConnection(); $now = time(); - $sql = "select c.id, c.cron_spec, c.report_id, c.email, c.cc, c.subject, c.report_condition from tt_cron c". - " inner join tt_fav_reports fr on (c.report_id = fr.id and c.group_id = fr.group_id and c.org_id = fr.org_id)". - " where $now >= c.next and fr.status = 1". - " and c.status = 1 and c.report_id is not null and c.email is not null"; +$sql = "select c.id, c.cron_spec, c.report_id, c.email, c.cc, c.subject, c.report_condition from tt_cron c". + " inner join tt_fav_reports fr on". + " (c.report_id = fr.id and c.group_id = fr.group_id and c.org_id = fr.org_id)". // Report for a correct group. + " inner join tt_users u on (u.id = fr.user_id and u.status = 1)". // Report for an active user. + " where $now >= c.next and fr.status = 1". // Due now. + " and c.status = 1 and c.report_id is not null and c.email is not null"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) exit(); @@ -66,6 +68,12 @@ $user = new ttUser(null, $options['user_id']); if (!$user->id) continue; // Skip not found user. + // Avoid complications with impersonated users, possibly from subgroups. + // Note: this may happen when cron.php is called by a browser who already impersonates. + // This is not supposed to happen in automatic cron job. + if ($user->behalf_id) + continue; // Skip processing on behalf situations entirely. + // TODO: write a new function ttFavReportHelper::adjustOptions that will use // a $user object recycled above. Put user handling below into it. // Also adjust remaining options for potentially changed user access rights and group properties. @@ -93,9 +101,8 @@ } // Calculate next execution time. - $next = tdCron::getNextOccurrence($val['cron_spec'], $now + 60); // +60 sec is here to get us correct $next when $now is close to existing "next". + $next = tdCron::getNextOccurrence($val['cron_spec'], $now + 60); // +60 sec is here to get us correct $next when $now is close to existing "next"./// // This is because the accuracy of tdcron class appears to be 1 minute. - // Update last and next values in tt_cron. $sql = "update tt_cron set last = $now, next = $next where id = ".$val['id']; $affected = $mdb2->exec($sql); From 59368101167c11a1a7dc80050fcf3262e99d87aa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 12 Dec 2018 14:44:51 +0000 Subject: [PATCH 0560/1848] Cosmetic. --- cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cron.php b/cron.php index 19384df40..337f96aef 100644 --- a/cron.php +++ b/cron.php @@ -101,7 +101,7 @@ } // Calculate next execution time. - $next = tdCron::getNextOccurrence($val['cron_spec'], $now + 60); // +60 sec is here to get us correct $next when $now is close to existing "next"./// + $next = tdCron::getNextOccurrence($val['cron_spec'], $now + 60); // +60 sec is here to get us correct $next when $now is close to existing "next". // This is because the accuracy of tdcron class appears to be 1 minute. // Update last and next values in tt_cron. $sql = "update tt_cron set last = $now, next = $next where id = ".$val['id']; From fafb0ae8f7098ffafa6799627891bd40f4811a52 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 12 Dec 2018 17:24:33 +0000 Subject: [PATCH 0561/1848] Excluded clients from getActiveUsers call. --- WEB-INF/lib/ttFavReportHelper.class.php | 6 ++-- WEB-INF/lib/ttGroupHelper.class.php | 43 +++++++++++++++++-------- WEB-INF/lib/ttTeamHelper.class.php | 21 ------------ WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- mobile/project_add.php | 2 +- mobile/users.php | 15 ++++++--- reports.php | 3 +- users.php | 2 +- 9 files changed, 47 insertions(+), 49 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 165f42a3c..30bfc235f 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -26,7 +26,7 @@ // | https://www.anuko.com/time_tracker/credits.htm // +----------------------------------------------------------------------+ -import('ttTeamHelper'); +import('ttGroupHelper'); // Class ttFavReportHelper is used to help with favorite report related tasks. class ttFavReportHelper { @@ -407,7 +407,7 @@ static function adjustOptions($options) { $user_options = array('max_rank'=>$max_rank); $users = $user->getUsers($user_options); // Active and inactive users. } elseif ($user->isClient()) { - $users = ttTeamHelper::getUsersForClient(); // Active and inactive users for clients. + $users = ttGroupHelper::getUsersForClient(); // Active and inactive users for clients. } foreach ($users as $single_user) { $user_ids[] = $single_user['id']; @@ -417,7 +417,7 @@ static function adjustOptions($options) { } else { $users_to_adjust = explode(',', $options['users']); // Users to adjust. if ($user->isClient()) { - $users = ttTeamHelper::getUsersForClient(); // Active and inactive users for clients. + $users = ttGroupHelper::getUsersForClient(); // Active and inactive users for clients. foreach ($users as $single_user) { $user_ids[] = $single_user['id']; } diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index ad2316756..fb895c460 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -447,7 +447,7 @@ static function getNotifications() { return false; } - // The getActiveUsers obtains all active users in a given group. + // The getActiveUsers obtains all active users excluding clients in a given group. static function getActiveUsers($options = null) { global $user; global $i18n; @@ -456,10 +456,12 @@ static function getActiveUsers($options = null) { $group_id = $user->getGroup(); $org_id = $user->org_id; + $client_part = " and u.client_id is null"; + if (isset($options['getAllFields'])) - $sql = "select u.*, r.name as role_name, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $group_id and u.org_id = $org_id and u.status = 1 order by upper(u.name)"; + $sql = "select u.*, r.name as role_name, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $group_id and u.org_id = $org_id and u.status = 1 $client_part order by upper(u.name)"; else - $sql = "select id, name from tt_users where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)"; + $sql = "select u.id, u.name from tt_users u where u.group_id = $group_id and u.org_id = $org_id and u.status = 1 $client_part order by upper(u.name)"; $res = $mdb2->query($sql); $user_list = array(); if (is_a($res, 'PEAR_Error')) @@ -471,17 +473,6 @@ static function getActiveUsers($options = null) { $user_list[] = $val; } - if (isset($options['putSelfFirst'])) { - // Put own entry at the front. - $cnt = count($user_list); - for($i = 0; $i < $cnt; $i++) { - if ($user_list[$i]['id'] == $user->id) { - $self = $user_list[$i]; // Found self. - array_unshift($user_list, $self); // Put own entry at the front. - array_splice($user_list, $i+1, 1); // Remove duplicate. - } - } - } return $user_list; } @@ -583,4 +574,28 @@ static function getUsers() { } return $user_list; } + + // The getUsersForClient obtains all active and inactive users in a group that are relevant to a client. + static function getUsersForClient() { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select u.id, u.name from tt_user_project_binds upb". + " inner join tt_client_project_binds cpb on (upb.project_id = cpb.project_id and cpb.client_id = $user->client_id)". + " inner join tt_users u on (u.id = upb.user_id and u.group_id = $group_id and u.org_id = $org_id)". + " where (u.status = 1 or u.status = 0)". + " group by u.id". + " order by upper(u.name)"; + $res = $mdb2->query($sql); + $user_list = array(); + if (is_a($res, 'PEAR_Error')) + return false; + while ($val = $res->fetchRow()) { + $user_list[] = $val; + } + return $user_list; + } } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 4dd2f9aaa..720708778 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -33,27 +33,6 @@ // Class ttTeamHelper - contains helper functions that operate with groups. class ttTeamHelper { - // The getUsersForClient obtains all active and inactive users in a group that are relevant to a client. - static function getUsersForClient() { - global $user; - $mdb2 = getConnection(); - - $sql = "select u.id, u.name from tt_user_project_binds upb". - " inner join tt_client_project_binds cpb on (upb.project_id = cpb.project_id and cpb.client_id = $user->client_id)". - " inner join tt_users u on (u.id = upb.user_id)". - " where (u.status = 1 or u.status = 0)". - " group by u.id". - " order by upper(u.name)"; - $res = $mdb2->query($sql); - $user_list = array(); - if (is_a($res, 'PEAR_Error')) - return false; - while ($val = $res->fetchRow()) { - $user_list[] = $val; - } - return $user_list; - } - // The swapRolesWith swaps existing user role with that of another user. static function swapRolesWith($user_id) { global $user; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index d320e3815..c00bd9f42 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -113,9 +113,9 @@ function __construct($login, $id = null) { $this->role_id = $val['role_id']; $this->role_name = $val['role_name']; $this->rights = explode(',', $val['rights']); - $this->is_client = !in_array('track_own_time', $this->rights); $this->rank = $val['rank']; $this->client_id = $val['client_id']; + $this->is_client = $this->client_id && !in_array('track_own_time', $this->rights); $this->email = $val['email']; $this->lang = $val['lang']; $this->decimal_mark = $val['decimal_mark']; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1caa6b555..d2754e7d4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4635 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4636 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/project_add.php b/mobile/project_add.php index c8c661ed2..c152006f3 100644 --- a/mobile/project_add.php +++ b/mobile/project_add.php @@ -36,7 +36,7 @@ header('Location: access_denied.php'); exit(); } -if (MODE_PROJECTS != $user->tracking_mode && MODE_PROJECTS_AND_TASKS != $user->tracking_mode) { +if (MODE_PROJECTS != $user->getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { header('Location: feature_disabled.php'); exit(); } diff --git a/mobile/users.php b/mobile/users.php index 594fa5bf1..0c54751de 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -39,15 +39,20 @@ } // End of access checks. -$uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); +// Prepare a list of active users. +if ($user->can('view_users')) + $options = array('status'=>ACTIVE,'include_clients'=>true,'include_login'=>true,'include_role'=>true); +else /* if ($user->can('manage_users')) */ + $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_clients'=>true,'include_self'=>true,'include_login'=>true,'include_role'=>true); +$active_users = $user->getUsers($options); -// Get users. -$active_users = ttGroupHelper::getActiveUsers(array('getAllFields'=>true)); +// Prepare a list of inactive users. if($user->can('manage_users')) { - $can_delete_manager = (1 == count($active_users)); - $inactive_users = ttTeamHelper::getInactiveUsers($user->group_id, true); + $options = array('status'=>INACTIVE,'max_rank'=>$user->rank-1,'include_clients'=>true,'include_login'=>true,'include_role'=>true); + $inactive_users = $user->getUsers($options); } +$uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); if ($uncompleted_indicators) { // Check each active user if they have an uncompleted time entry. foreach ($active_users as $key => $user) { diff --git a/reports.php b/reports.php index c3bb88096..ee82a64f3 100644 --- a/reports.php +++ b/reports.php @@ -30,7 +30,6 @@ import('form.Form'); import('form.ActionForm'); import('DateAndTime'); -import('ttTeamHelper'); import('ttGroupHelper'); import('Period'); import('ttProjectHelper'); @@ -165,7 +164,7 @@ $users = $user->getUsers($options); // Active and inactive users. } elseif ($user->isClient()) - $users = ttTeamHelper::getUsersForClient(); // Active and inactive users for clients. + $users = ttGroupHelper::getUsersForClient(); // Active and inactive users for clients. foreach ($users as $single_user) { $user_list[$single_user['id']] = $single_user['name']; diff --git a/users.php b/users.php index 47ec0145a..77b7e5525 100644 --- a/users.php +++ b/users.php @@ -50,7 +50,6 @@ } else { $group_id = $user->getGroup(); } -$uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); $form = new Form('usersForm'); if ($user->can('manage_subgroups')) { @@ -80,6 +79,7 @@ $inactive_users = $user->getUsers($options); } +$uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); if ($uncompleted_indicators) { // Check each active user if they have an uncompleted time entry. foreach ($active_users as $key => $user) { From f9e5e8956921839e6742a85db2067ddc6ef5b2b8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 12 Dec 2018 17:40:36 +0000 Subject: [PATCH 0562/1848] Removed group selector from users.php page to keep things simple. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/users.tpl | 10 ---------- users.php | 29 ----------------------------- 3 files changed, 1 insertion(+), 40 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d2754e7d4..d7560f930 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4636 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4637 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/users.tpl b/WEB-INF/templates/users.tpl index 4faf1249d..236475c19 100644 --- a/WEB-INF/templates/users.tpl +++ b/WEB-INF/templates/users.tpl @@ -6,16 +6,6 @@
{if $user->can('manage_users')} - {if $group_dropdown} -{$forms.usersForm.open} {* usersForm consists only of one dropdown group control *} - - - - -
{$i18n.label.group}: {$forms.usersForm.group.control}
-{$forms.usersForm.close} - {/if} - {if $inactive_users} diff --git a/users.php b/users.php index 77b7e5525..d19ba7de6 100644 --- a/users.php +++ b/users.php @@ -36,36 +36,8 @@ header('Location: access_denied.php'); exit(); } -if ($request->isPost() && !$user->isGroupValid($request->getParameter('group'))) { - header('Location: access_denied.php'); // Wrong group id in post. - exit(); -} -// Note: we don't use "manage_subgroups" in access check, because when user cannot -// "manage_users" or "view_users" they do not belong here. // End of access checks. -if ($request->isPost()) { - $group_id = $request->getParameter('group'); - $user->setOnBehalfGroup($group_id); -} else { - $group_id = $user->getGroup(); -} - -$form = new Form('usersForm'); -if ($user->can('manage_subgroups')) { - $groups = $user->getGroupsForDropdown(); - if (count($groups) > 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.submit();', - 'name'=>'group', - 'style'=>'width: 250px;', - 'value'=>$group_id, - 'data'=>$groups, - 'datakeys'=>array('id','name'))); - $smarty->assign('group_dropdown', 1); - } -} - // Prepare a list of active users. if ($user->can('view_users')) $options = array('status'=>ACTIVE,'include_clients'=>true,'include_login'=>true,'include_role'=>true); @@ -88,7 +60,6 @@ $smarty->assign('uncompleted_indicators', true); } -$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('active_users', $active_users); $smarty->assign('inactive_users', $inactive_users); $smarty->assign('title', $i18n->get('title.users')); From bd5a201697a949a00738c890b227eda0948c0bf2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 12 Dec 2018 18:48:35 +0000 Subject: [PATCH 0563/1848] A few fixes to users pages for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/users.tpl | 4 ++-- mobile/users.php | 5 +++-- users.php | 5 +++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d7560f930..51675b024 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.users.active_users}
-
 Anuko Time Tracker 1.18.29.4637 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4638 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/users.tpl b/WEB-INF/templates/mobile/users.tpl index ae04bd448..b3af8e206 100644 --- a/WEB-INF/templates/mobile/users.tpl +++ b/WEB-INF/templates/mobile/users.tpl @@ -22,7 +22,7 @@ {if $uncompleted_indicators} {/if} - {if $u.rank < $user->rank || ($u.rank == $user->rank && $u.id == $user->id)} + {if $u.group_id != $user->group_id || $u.rank < $user->rank || ($u.rank == $user->rank && $u.id == $user->id)} {$u.name|escape} {else} {$u.name|escape} @@ -54,7 +54,7 @@ {foreach $inactive_users as $u}
- {if $u.rank < $user->rank} + {if $u.group_id != $user->group_id || $u.rank < $user->rank} {$u.name|escape} {else} {$u.name|escape} diff --git a/mobile/users.php b/mobile/users.php index 0c54751de..d6d08457a 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -40,15 +40,16 @@ // End of access checks. // Prepare a list of active users. +$rank = $user->getMaxRankForGroup($user->getGroup()); if ($user->can('view_users')) $options = array('status'=>ACTIVE,'include_clients'=>true,'include_login'=>true,'include_role'=>true); else /* if ($user->can('manage_users')) */ - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_clients'=>true,'include_self'=>true,'include_login'=>true,'include_role'=>true); + $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_self'=>true,'include_login'=>true,'include_role'=>true); $active_users = $user->getUsers($options); // Prepare a list of inactive users. if($user->can('manage_users')) { - $options = array('status'=>INACTIVE,'max_rank'=>$user->rank-1,'include_clients'=>true,'include_login'=>true,'include_role'=>true); + $options = array('status'=>INACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_login'=>true,'include_role'=>true); $inactive_users = $user->getUsers($options); } diff --git a/users.php b/users.php index d19ba7de6..fd9e7593f 100644 --- a/users.php +++ b/users.php @@ -39,15 +39,16 @@ // End of access checks. // Prepare a list of active users. +$rank = $user->getMaxRankForGroup($user->getGroup()); if ($user->can('view_users')) $options = array('status'=>ACTIVE,'include_clients'=>true,'include_login'=>true,'include_role'=>true); else /* if ($user->can('manage_users')) */ - $options = array('status'=>ACTIVE,'max_rank'=>$user->rank-1,'include_clients'=>true,'include_self'=>true,'include_login'=>true,'include_role'=>true); + $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_self'=>true,'include_login'=>true,'include_role'=>true); $active_users = $user->getUsers($options); // Prepare a list of inactive users. if($user->can('manage_users')) { - $options = array('status'=>INACTIVE,'max_rank'=>$user->rank-1,'include_clients'=>true,'include_login'=>true,'include_role'=>true); + $options = array('status'=>INACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_login'=>true,'include_role'=>true); $inactive_users = $user->getUsers($options); } From ff088165333067ad603805039778e9bc56671b89 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 12 Dec 2018 19:35:53 +0000 Subject: [PATCH 0564/1848] Refactored getRecentInvoices and moved to another class. --- WEB-INF/lib/ttGroupHelper.class.php | 23 +++++++++++++++++++++++ WEB-INF/lib/ttTeamHelper.class.php | 23 ----------------------- WEB-INF/templates/footer.tpl | 2 +- report.php | 4 ++-- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index fb895c460..762fffb69 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -598,4 +598,27 @@ static function getUsersForClient() { } return $user_list; } + + // The getRecentInvoices returns an array of recent invoices (max 3) for a client. + static function getRecentInvoices($client_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select i.id, i.name from tt_invoices i". + " left join tt_clients c on (c.id = i.client_id)". + " where i.group_id = $group_id and i.org_id = $org_id and i.status = 1 and c.id = $client_id". + " order by i.id desc limit 3"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + $dt = new DateAndTime(DB_DATEFORMAT); + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } } diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 720708778..6c058c5d1 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -255,29 +255,6 @@ static function getAllInvoices() return $result; } - // The getRecentInvoices returns an array of recent invoices (max 3) for a client. - static function getRecentInvoices($group_id, $client_id) - { - global $user; - - $result = array(); - $mdb2 = getConnection(); - - $sql = "select i.id, i.name from tt_invoices i - left join tt_clients c on (c.id = i.client_id) - where i.group_id = $group_id and i.status = 1 and c.id = $client_id - order by i.id desc limit 3"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - $dt = new DateAndTime(DB_DATEFORMAT); - while ($val = $res->fetchRow()) { - $result[] = $val; - } - } - return $result; - } - // getUserToProjectBinds - obtains all user to project binds for a group. static function getUserToProjectBinds($group_id) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 51675b024..2a14a1fa8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4638 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4639 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index 1a8ce63cc..924c7801a 100644 --- a/report.php +++ b/report.php @@ -30,7 +30,7 @@ import('form.Form'); import('form.ActionForm'); import('ttReportHelper'); -import('ttTeamHelper'); +import('ttGroupHelper'); // Access check. if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports'))) { @@ -94,7 +94,7 @@ if ($user->can('manage_invoices') && ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by1')) && !$user->isClient())) { // Client is selected and we are displaying the invoice column. - $recent_invoices = ttTeamHelper::getRecentInvoices($user->group_id, $client_id); + $recent_invoices = ttGroupHelper::getRecentInvoices($client_id); if ($recent_invoices) { $assign_invoice_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); $form->addInput(array('type'=>'combobox', From a08292683b29da0946e2099e3fd94bc2d19688f3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 12 Dec 2018 19:55:03 +0000 Subject: [PATCH 0565/1848] Some more refactoring of reports for subgroups. --- WEB-INF/lib/ttReportHelper.class.php | 26 ++++++++++++++++++-------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 13226ca44..38da98791 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -564,35 +564,45 @@ static function getTotals($options) } // The assignToInvoice assigns a set of records to a specific invoice. - static function assignToInvoice($invoice_id, $time_log_ids, $expense_item_ids) - { + static function assignToInvoice($invoice_id, $time_log_ids, $expense_item_ids) { + global $user; $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + if ($time_log_ids) { $sql = "update tt_log set invoice_id = ".$mdb2->quote($invoice_id). - " where id in(".join(', ', $time_log_ids).")"; + " where id in(".join(', ', $time_log_ids).") and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); } if ($expense_item_ids) { $sql = "update tt_expense_items set invoice_id = ".$mdb2->quote($invoice_id). - " where id in(".join(', ', $expense_item_ids).")"; + " where id in(".join(', ', $expense_item_ids).") and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); } } // The markPaid marks a set of records as either paid or unpaid. - static function markPaid($time_log_ids, $expense_item_ids, $paid = true) - { + static function markPaid($time_log_ids, $expense_item_ids, $paid = true) { + global $user; $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $paid_val = (int) $paid; if ($time_log_ids) { - $sql = "update tt_log set paid = $paid_val where id in(".join(', ', $time_log_ids).")"; + $sql = "update tt_log set paid = $paid_val". + " where id in(".join(', ', $time_log_ids).") and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); } if ($expense_item_ids) { - $sql = "update tt_expense_items set paid = $paid_val where id in(".join(', ', $expense_item_ids).")"; + $sql = "update tt_expense_items set paid = $paid_val". + " where id in(".join(', ', $expense_item_ids).") and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2a14a1fa8..490d773c6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.29.4639 | Copyright © Anuko | +  Anuko Time Tracker 1.18.29.4640 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c1aacad4a4123391e6aae4352963f33b6895d66c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 13:08:59 +0000 Subject: [PATCH 0566/1848] Fixed update link for version 1.17.44 to 1.17.97. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 490d773c6..21f8a94ab 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + From 2da2031951c852b4620c173e21c24f148fdf4999 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 15:10:55 +0000 Subject: [PATCH 0567/1848] Cosmetic. --- WEB-INF/templates/footer.tpl | 2 +- mobile/login.php | 2 +- mobile/user_add.php | 2 +- register.php | 4 ++++ user_add.php | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 21f8a94ab..29e2eea32 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.29.4640 | Copyright © Anuko | +  Anuko Time Tracker 1.18.30.4641 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 55d09be0a..197c43b0b 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1128,7 +1128,7 @@ function ttExecute($sql) {
Update database structure (v1.17.44 to v1.17.97)

-
 Anuko Time Tracker 1.18.30.4641 | Copyright © Anuko | +  Anuko Time Tracker 1.18.30.4642 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/login.php b/mobile/login.php index 243aa5781..59fc6000f 100644 --- a/mobile/login.php +++ b/mobile/login.php @@ -52,7 +52,7 @@ if ($err->no()) { // Use the "limit" plugin if we have one. Ignore include errors. - // The "limit" plugin is not required for normal operation of the Time Tracker. + // The "limit" plugin is not required for normal operation of Time Tracker. @include('../plugins/limit/access_check.php'); if ($auth->doLogin($cl_login, $cl_password)) { diff --git a/mobile/user_add.php b/mobile/user_add.php index fbd82835f..ab6f5e2da 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -42,7 +42,7 @@ // End of access checks. // Use the "limit" plugin if we have one. Ignore include errors. -// The "limit" plugin is not required for normal operation of the Time Tracker. +// The "limit" plugin is not required for normal operation of Time Tracker. @include('../plugins/limit/user_add.php'); if ($user->isPluginEnabled('cl')) diff --git a/register.php b/register.php index 298f2818f..0a8e6d156 100644 --- a/register.php +++ b/register.php @@ -34,6 +34,10 @@ exit(); } +// Use the "limit" plugin if we have one. Ignore include errors. +// The "limit" plugin is not required for normal operation of Time Tracker. +@include('plugins/limit/register.php'); + $auth->doLogout(); if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); diff --git a/user_add.php b/user_add.php index 9fa611294..28baa2cf5 100644 --- a/user_add.php +++ b/user_add.php @@ -43,7 +43,7 @@ // End of access checks. // Use the "limit" plugin if we have one. Ignore include errors. -// The "limit" plugin is not required for normal operation of the Time Tracker. +// The "limit" plugin is not required for normal operation of Time Tracker. @include('plugins/limit/user_add.php'); if ($user->isPluginEnabled('cl')) From 83e5b07e961d0060f759dd8c59ef2c26d66b0c97 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 16:00:06 +0000 Subject: [PATCH 0568/1848] A bit of cleanup in report.php. --- WEB-INF/templates/footer.tpl | 2 +- report.php | 25 ++++--------------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 29e2eea32..e031d3832 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.30.4642 | Copyright © Anuko | +  Anuko Time Tracker 1.18.30.4643 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index 924c7801a..cb563b9b0 100644 --- a/report.php +++ b/report.php @@ -170,49 +170,32 @@ } } // isPost -$group_by = $bean->getAttribute('group_by1'); - $options = ttReportHelper::getReportOptions($bean); -$group_by_tag = ttReportHelper::makeGroupByXmlTag($options); $report_items = ttReportHelper::getItems($options); // Store record ids in session in case user wants to act on records such as marking them all paid. if ($request->isGet() && $user->isPluginEnabled('ps')) ttReportHelper::putInSession($report_items); -if (ttReportHelper::grouping($options)) +if (ttReportHelper::grouping($options)) { $subtotals = ttReportHelper::getSubtotals($options); + $smarty->assign('group_by_header', ttReportHelper::makeGroupByHeader($options)); +} $totals = ttReportHelper::getTotals($options); // Assign variables that are used to print subtotals. -if ($report_items && 'no_grouping' != $group_by1) { +if ($report_items) { $smarty->assign('print_subtotals', true); $smarty->assign('first_pass', true); - $smarty->assign('group_by1', $group_by1); $smarty->assign('prev_grouped_by', ''); $smarty->assign('cur_grouped_by', ''); } -// Determine group by header. -if ('no_grouping' != $group_by) { - /* - if ('cf_1' == $group_by) - $smarty->assign('group_by_header', $custom_fields->fields[0]['label']); - else { - $key = 'label.'.$group_by; - $smarty->assign('group_by_header', $i18n->get($key)); - } */ - $smarty->assign('group_by_header', ttReportHelper::makeGroupByHeader($options)); -} - -$smarty->assign('group_by', $group_by_tag); // Assign variables that are used to alternate color of rows for different dates. $smarty->assign('prev_date', ''); $smarty->assign('cur_date', ''); $smarty->assign('report_row_class', 'rowReportItem'); - $smarty->assign('forms', array($form->getName()=>$form->toArray())); - $smarty->assign('report_items', $report_items); $smarty->assign('subtotals', $subtotals); $smarty->assign('totals', $totals); From 06f5163f4a234e89b5d761e7f537160f40d4a2e8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 17:11:47 +0000 Subject: [PATCH 0569/1848] Some more refactoring for subgroups. --- WEB-INF/lib/ttReportHelper.class.php | 14 +++++++++----- WEB-INF/lib/ttTimeHelper.class.php | 10 ++++++++-- WEB-INF/templates/footer.tpl | 2 +- mobile/time.php | 2 +- mobile/timer.php | 2 +- time.php | 2 +- 6 files changed, 21 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 38da98791..26478c3b7 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -40,6 +40,9 @@ class ttReportHelper { static function getWhere($options) { global $user; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + // Prepare dropdown parts. $dropdown_parts = ''; if ($options['client_id']) @@ -61,17 +64,18 @@ static function getWhere($options) { if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and l.user_id in ($userlist)"; else - $user_list_part = " and l.user_id = ".$user->id; - $user_list_part .= " and l.group_id = ".$user->getGroup(); + $user_list_part = " and l.user_id = ".$user->getUser(); + $user_list_part .= " and l.group_id = $group_id and l.org_id = $org_id"; // Prepare sql query part for where. + $dateFormat = $user->getDateFormat(); if ($options['period']) - $period = new Period($options['period'], new DateAndTime($user->date_format)); + $period = new Period($options['period'], new DateAndTime($dateFormat)); else { $period = new Period(); $period->setPeriod( - new DateAndTime($user->date_format, $options['period_start']), - new DateAndTime($user->date_format, $options['period_end'])); + new DateAndTime($dateFormat, $options['period_start']), + new DateAndTime($dateFormat, $options['period_end'])); } $where = " where l.status = 1 and l.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". " $user_list_part $dropdown_parts"; diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index f48ecc8a0..5eeed1f04 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -530,10 +530,16 @@ static function delete($id) { } // getTimeForDay - gets total time for a user for a specific date. - static function getTimeForDay($user_id, $date) { + static function getTimeForDay($date) { + global $user; $mdb2 = getConnection(); - $sql = "select sum(time_to_sec(duration)) as sm from tt_log where user_id = $user_id and date = '$date' and status = 1"; + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select sum(time_to_sec(duration)) as sm from tt_log". + " where user_id = $user_id and group_id = $group_id and org_id = $org_id and date = '$date' and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e031d3832..861431d99 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.30.4643 | Copyright © Anuko | +  Anuko Time Tracker 1.18.30.4644 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/time.php b/mobile/time.php index 6bacd0842..80049a9cb 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -286,7 +286,7 @@ $smarty->assign('next_date', $next_date); $smarty->assign('prev_date', $prev_date); $smarty->assign('time_records', ttTimeHelper::getRecords($user_id, $cl_date)); -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($user_id, $cl_date)); +$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); diff --git a/mobile/timer.php b/mobile/timer.php index 73035a395..682634c87 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -291,7 +291,7 @@ $smarty->assign('time_records', ttTimeHelper::getRecords($user->getUser(), $cl_date)); -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($user->getUser(), $cl_date)); +$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); diff --git a/time.php b/time.php index 066653100..b85cad0ef 100644 --- a/time.php +++ b/time.php @@ -398,7 +398,7 @@ $smarty->assign('selected_date', $selected_date); $smarty->assign('week_total', $week_total); -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($user_id, $cl_date)); +$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('time_records', ttTimeHelper::getRecords($user_id, $cl_date)); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); From 1ca0df080b44b700872bec9216d8405b1f90bc11 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 17:19:52 +0000 Subject: [PATCH 0570/1848] A bit more refactoring for subgroups. --- WEB-INF/lib/ttTimeHelper.class.php | 11 +++++++++-- WEB-INF/templates/footer.tpl | 2 +- mobile/timer.php | 2 +- time.php | 2 +- week.php | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 5eeed1f04..a8bde9872 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -549,12 +549,19 @@ static function getTimeForDay($date) { } // getTimeForWeek - gets total time for a user for a given week. - static function getTimeForWeek($user_id, $date) { + static function getTimeForWeek($date) { + global $user; import('Period'); $mdb2 = getConnection(); + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $period = new Period(INTERVAL_THIS_WEEK, $date); - $sql = "select sum(time_to_sec(duration)) as sm from tt_log where user_id = $user_id and date >= '".$period->getStartDate(DB_DATEFORMAT)."' and date <= '".$period->getEndDate(DB_DATEFORMAT)."' and status = 1"; + $sql = "select sum(time_to_sec(duration)) as sm from tt_log". + " where user_id = $user_id and group_id = $group_id and org_id = $org_id". + " and date >= '".$period->getStartDate(DB_DATEFORMAT)."' and date <= '".$period->getEndDate(DB_DATEFORMAT)."' and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 861431d99..2b6eb7913 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.30.4644 | Copyright © Anuko | +  Anuko Time Tracker 1.18.30.4645 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/timer.php b/mobile/timer.php index 682634c87..c754740a6 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -283,7 +283,7 @@ } } // isPost -$week_total = ttTimeHelper::getTimeForWeek($user->getUser(), $cl_date); +$week_total = ttTimeHelper::getTimeForWeek($cl_date); $smarty->assign('week_total', $week_total); $smarty->assign('uncompleted', $uncompleted); diff --git a/time.php b/time.php index b85cad0ef..462389af8 100644 --- a/time.php +++ b/time.php @@ -394,7 +394,7 @@ } } // isPost -$week_total = ttTimeHelper::getTimeForWeek($user_id, $selected_date); +$week_total = ttTimeHelper::getTimeForWeek($selected_date); $smarty->assign('selected_date', $selected_date); $smarty->assign('week_total', $week_total); diff --git a/week.php b/week.php index edba8996e..bf2378537 100644 --- a/week.php +++ b/week.php @@ -494,7 +494,7 @@ function render(&$table, $value, $row, $column, $selected = false) { } } // isPost -$week_total = ttTimeHelper::getTimeForWeek($user->getUser(), $selected_date); +$week_total = ttTimeHelper::getTimeForWeek($selected_date); $smarty->assign('selected_date', $selected_date); $smarty->assign('week_total', $week_total); From 8f1159deac6c05f4d864cd140d9c66f007601e7e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 17:33:21 +0000 Subject: [PATCH 0571/1848] Cosmetic, changed return values. --- WEB-INF/lib/ttTimeHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index a8bde9872..70844eebb 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -567,7 +567,7 @@ static function getTimeForWeek($date) { $val = $res->fetchRow(); return sec_to_time_fmt_hm($val['sm']); } - return 0; + return false; } // getTimeForMonth - gets total time for a user for a given month. @@ -582,7 +582,7 @@ static function getTimeForMonth($user_id, $date){ $val = $res->fetchRow(); return sec_to_time_fmt_hm($val['sm']); } - return 0; + return false; } // getUncompleted - retrieves an uncompleted record for user, if one exists. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2b6eb7913..5e51061b6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.30.4645 | Copyright © Anuko | +  Anuko Time Tracker 1.18.30.4646 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 54bb71ed8e6b7f79e3b26bc1c8a70a95793950c8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 17:37:51 +0000 Subject: [PATCH 0572/1848] More refactoring for subgroups. --- WEB-INF/lib/ttTimeHelper.class.php | 11 +++++++++-- WEB-INF/templates/footer.tpl | 2 +- time.php | 2 +- week.php | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 70844eebb..4e10f4ed7 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -571,12 +571,19 @@ static function getTimeForWeek($date) { } // getTimeForMonth - gets total time for a user for a given month. - static function getTimeForMonth($user_id, $date){ + static function getTimeForMonth($date) { + global $user; import('Period'); $mdb2 = getConnection(); + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $period = new Period(INTERVAL_THIS_MONTH, $date); - $sql = "select sum(time_to_sec(duration)) as sm from tt_log where user_id = $user_id and date >= '".$period->getStartDate(DB_DATEFORMAT)."' and date <= '".$period->getEndDate(DB_DATEFORMAT)."' and status = 1"; + $sql = "select sum(time_to_sec(duration)) as sm from tt_log". + " where user_id = $user_id and group_id = $group_id and org_id = $org_id". + " and date >= '".$period->getStartDate(DB_DATEFORMAT)."' and date <= '".$period->getEndDate(DB_DATEFORMAT)."' and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5e51061b6..a7e4b134a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.30.4646 | Copyright © Anuko | +  Anuko Time Tracker 1.18.30.4647 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/time.php b/time.php index 462389af8..7e4e8adce 100644 --- a/time.php +++ b/time.php @@ -96,7 +96,7 @@ require_once('plugins/MonthlyQuota.class.php'); $quota = new MonthlyQuota(); $month_quota_minutes = $quota->get($selected_date->mYear, $selected_date->mMonth); - $month_total = ttTimeHelper::getTimeForMonth($user_id, $selected_date); + $month_total = ttTimeHelper::getTimeForMonth($selected_date); $minutes_left = $month_quota_minutes - ttTimeHelper::toMinutes($month_total); $smarty->assign('month_total', $month_total); diff --git a/week.php b/week.php index bf2378537..c1c76f9de 100644 --- a/week.php +++ b/week.php @@ -92,7 +92,7 @@ require_once('plugins/MonthlyQuota.class.php'); $quota = new MonthlyQuota(); $month_quota = $quota->get($selected_date->mYear, $selected_date->mMonth); - $month_total = ttTimeHelper::getTimeForMonth($user->getUser(), $selected_date); + $month_total = ttTimeHelper::getTimeForMonth($selected_date); $minutes_left = round(60*$month_quota) - ttTimeHelper::toMinutes($month_total); $smarty->assign('month_total', $month_total); From bacdf3405307cfc27832db00b09bbf52d4b9f72c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 18:42:32 +0000 Subject: [PATCH 0573/1848] A bit more refactoring for subgroups. --- WEB-INF/lib/ttReportHelper.class.php | 32 +++++++++++++++++----------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 26478c3b7..d3c7b7ce3 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -86,6 +86,9 @@ static function getWhere($options) { static function getExpenseWhere($options) { global $user; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + // Prepare dropdown parts. $dropdown_parts = ''; if ($options['client_id']) @@ -103,17 +106,18 @@ static function getExpenseWhere($options) { if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and ei.user_id in ($userlist)"; else - $user_list_part = " and ei.user_id = ".$user->id; - $user_list_part .= " and ei.group_id = ".$user->getGroup(); + $user_list_part = " and ei.user_id = ".$user->getUser(); + $user_list_part .= " and ei.group_id = $group_id and ei.org_id = $org_id"; // Prepare sql query part for where. + $dateFormat = $user->getDateFormat(); if ($options['period']) - $period = new Period($options['period'], new DateAndTime($user->date_format)); + $period = new Period($options['period'], new DateAndTime($dateFormat)); else { $period = new Period(); $period->setPeriod( - new DateAndTime($user->date_format, $options['period_start']), - new DateAndTime($user->date_format, $options['period_end'])); + new DateAndTime($dateFormat, $options['period_start']), + new DateAndTime($dateFormat, $options['period_end'])); } $where = " where ei.status = 1 and ei.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and ei.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". " $user_list_part $dropdown_parts"; @@ -140,7 +144,9 @@ static function getItems($options) { $grouping_by_user = ttReportHelper::groupingBy('user', $options); $grouping_by_cf_1 = ttReportHelper::groupingBy('cf_1', $options); } - $convertTo12Hour = ('%I:%M %p' == $user->time_format) && ($options['show_start'] || $options['show_end']); + $convertTo12Hour = ('%I:%M %p' == $user->getTimeFormat()) && ($options['show_start'] || $options['show_end']); + $trackingMode = $user->getTrackingMode(); + $decimalMark = $user->getDecimalMark(); // Prepare a query for time items in tt_log table. $fields = array(); // An array of fields for database query. @@ -182,7 +188,7 @@ static function getItems($options) { array_push($fields, "TIME_FORMAT(l.duration, '%k:%i') as duration"); // Add work units. if ($options['show_work_units']) { - if ($user->unit_totals_only) + if ($user->getConfigOption('unit_totals_only')) array_push($fields, "null as units"); else array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); @@ -193,7 +199,7 @@ static function getItems($options) { // Handle cost. $includeCost = $options['show_cost']; if ($includeCost) { - if (MODE_TIME == $user->tracking_mode) + if (MODE_TIME == $trackingMode) array_push($fields, "cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use default user rate. else array_push($fields, "cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use project rate for user. @@ -233,7 +239,7 @@ static function getItems($options) { " left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)"; } } - if ($includeCost && MODE_TIME != $user->tracking_mode) + if ($includeCost && MODE_TIME != $trackingMode) $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; $where = ttReportHelper::getWhere($options); @@ -343,12 +349,12 @@ static function getItems($options) { $val['finish'] = ttTimeHelper::to12HourFormat($val['finish']); } if (isset($val['cost'])) { - if ('.' != $user->decimal_mark) - $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); + if ('.' != $decimalMark) + $val['cost'] = str_replace('.', $decimalMark, $val['cost']); } if (isset($val['expense'])) { - if ('.' != $user->decimal_mark) - $val['expense'] = str_replace('.', $user->decimal_mark, $val['expense']); + if ('.' != $decimalMark) + $val['expense'] = str_replace('.', $decimalMark, $val['expense']); } if ($grouping) $val['grouped_by'] = ttReportHelper::makeGroupByKey($options, $val); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a7e4b134a..95df44bc7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.30.4647 | Copyright © Anuko | +  Anuko Time Tracker 1.18.30.4648 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 77dc69032fb4b318c4fb92c3fe54e0e1b03dae4e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 20:46:30 +0000 Subject: [PATCH 0574/1848] Removed group selector from tasks.php to keep things simple. --- WEB-INF/lib/ttUser.class.php | 5 ++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/tasks.tpl | 10 ---------- tasks.php | 32 -------------------------------- 4 files changed, 5 insertions(+), 44 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index c00bd9f42..2d7f1c985 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -294,8 +294,11 @@ function getAssignedTasks() $mdb2 = getConnection(); $tasks = implode(',', $task_ids); // This is a comma-separated list of task ids. + $group_id = $this->getGroup(); + $org_id = $this->org_id; + $sql = "select id, name, description from tt_tasks". - " where group_id = $this->group_id and status = 1 and id in ($tasks) order by name"; + " where group_id = $group_id and org_id = $org_id and status = 1 and id in ($tasks) order by name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 95df44bc7..ce84ca07f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.30.4648 | Copyright © Anuko | +  Anuko Time Tracker 1.18.30.4649 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/tasks.tpl b/WEB-INF/templates/tasks.tpl index 9db99069c..647a6a787 100644 --- a/WEB-INF/templates/tasks.tpl +++ b/WEB-INF/templates/tasks.tpl @@ -6,16 +6,6 @@
{if $user->can('manage_tasks')} - {if $group_dropdown} -{$forms.tasksForm.open} {* tasksForm consists only of one dropdown group control *} - - - - -
{$i18n.label.group}: {$forms.tasksForm.group.control}
-{$forms.tasksForm.close} - {/if} - {if $inactive_tasks} diff --git a/tasks.php b/tasks.php index ba91ed01c..7b5f99790 100644 --- a/tasks.php +++ b/tasks.php @@ -39,46 +39,14 @@ header('Location: feature_disabled.php'); exit(); } -if ($request->isPost() && !$user->isGroupValid($request->getParameter('group'))) { - header('Location: access_denied.php'); // Wrong group id in post. - exit(); -} // End of access checks. -if ($request->isPost()) { - $group_id = $request->getParameter('group'); - $user->setOnBehalfGroup($group_id); - // Tasks feature may not be available in new group, check and redirect. - if (MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); - } -} else { - $group_id = $user->getGroup(); -} - -$form = new Form('tasksForm'); -if ($user->can('manage_subgroups')) { - $groups = $user->getGroupsForDropdown(); - if (count($groups) > 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.submit();', - 'name'=>'group', - 'style'=>'width: 250px;', - 'value'=>$group_id, - 'data'=>$groups, - 'datakeys'=>array('id','name'))); - $smarty->assign('group_dropdown', 1); - } -} - if($user->can('manage_tasks')) { $active_tasks = ttGroupHelper::getActiveTasks(); $inactive_tasks = ttGroupHelper::getInactiveTasks(); } else $active_tasks = $user->getAssignedTasks(); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('active_tasks', $active_tasks); $smarty->assign('inactive_tasks', $inactive_tasks); $smarty->assign('title', $i18n->get('title.tasks')); From a079c840acbc147af950bff07ba7b7dac0de6131 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 21:06:08 +0000 Subject: [PATCH 0575/1848] Removed group selector from time.php to keep things simple. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time.tpl | 8 +------- time.php | 31 +++---------------------------- 3 files changed, 5 insertions(+), 36 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ce84ca07f..f550c35f5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.tasks.active_tasks}
-
 Anuko Time Tracker 1.18.30.4649 | Copyright © Anuko | +  Anuko Time Tracker 1.18.30.4650 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index bb8628713..76338706d 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -18,12 +18,6 @@
-{if $group_dropdown} - - - - -{/if} {if $user_dropdown} @@ -72,7 +66,7 @@ {if (($smarty.const.TYPE_DURATION == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))} - + {/if}
{$i18n.label.group}:{$forms.timeRecordForm.group.control}
{$i18n.label.user}:
{$i18n.label.duration}:{$forms.timeRecordForm.duration.control} {if $user->decimal_mark == ','}{str_replace('.', ',', $i18n.form.time.duration_format)}{else}{$i18n.form.time.duration_format}{/if}{$forms.timeRecordForm.duration.control} {if $user->getDecimalMark() == ','}{str_replace('.', ',', $i18n.form.time.duration_format)}{else}{$i18n.form.time.duration_format}{/if}
diff --git a/time.php b/time.php index 7e4e8adce..013f15ca6 100644 --- a/time.php +++ b/time.php @@ -48,11 +48,6 @@ exit(); } if ($request->isPost()) { - $groupChanged = $request->getParameter('group_changed'); // Reused in multiple places below. - if ($groupChanged && !($user->can('manage_subgroups') && $user->isGroupValid($request->getParameter('group')))) { - header('Location: access_denied.php'); // Group changed, but no rght or wrong group id. - exit(); - } $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { header('Location: access_denied.php'); // Group changed, but no rght or wrong user id. @@ -61,13 +56,6 @@ } // End of access checks. -// Determine group for which we display this page. -if ($request->isPost() && $groupChanged) { - $group_id = $request->getParameter('group'); - $user->setOnBehalfGroup($group_id); -} else { - $group_id = $user->getGroup(); -} // Determine user for which we display this page. if ($request->isPost() && $userChanged) { $user_id = $request->getParameter('user'); @@ -76,6 +64,8 @@ $user_id = $user->getUser(); } +$group_id = $user->getGroup(); + // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); $selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); @@ -132,21 +122,6 @@ // Elements of timeRecordForm. $form = new Form('timeRecordForm'); -// Group dropdown. -if ($user->can('manage_subgroups')) { - $groups = $user->getGroupsForDropdown(); - if (count($groups) > 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'document.timeRecordForm.group_changed.value=1;document.timeRecordForm.submit();', - 'name'=>'group', - 'style'=>'width: 250px;', - 'value'=>$group_id, - 'data'=>$groups, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'group_changed')); - $smarty->assign('group_dropdown', 1); - } -} if ($user->can('track_time')) { $rank = $user->getMaxRankForGroup($group_id); if ($user->can('track_own_time')) @@ -405,7 +380,7 @@ $smarty->assign('task_list', $task_list); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="fillDropdowns()"'); -$smarty->assign('timestring', $selected_date->toString($user->date_format)); +$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); $smarty->assign('title', $i18n->get('title.time')); $smarty->assign('content_page_name', 'time.tpl'); $smarty->display('index.tpl'); From fb37b1b49aedfe40651dcc57883ddbe9c605374d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 13 Dec 2018 21:14:03 +0000 Subject: [PATCH 0576/1848] Initial release of subgroups for testing. Some issues remain, but the functionality is there. --- WEB-INF/config.php.dist | 3 --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 2 -- WEB-INF/templates/header.tpl | 2 -- 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 17b4d087d..d8bfe0c10 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -197,6 +197,3 @@ define('AUTH_MODULE', 'db'); // Height in pixels for the note input field in time.php. Defaults to 40. // define('NOTE_INPUT_HEIGHT', 100); - -// A temporary config option while development of subgroup support is ongoing. To be removed later. -// define('SUBGROUP_DEBUG', false); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f550c35f5..627a23317 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.30.4650 | Copyright © Anuko | +  Anuko Time Tracker 1.18.31.4651 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index bb83d3a3e..0565d763e 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -26,14 +26,12 @@ function handleTaskRequiredCheckbox() {
-{if isTrue($smarty.const.SUBGROUP_DEBUG)} {if $user->can('manage_subgroups') && $group_dropdown} {/if} -{/if} {if $user->can('manage_basic_settings')} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 546fffaa1..8555447b5 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -89,11 +89,9 @@ {if $user->can('manage_basic_settings')} {$i18n.menu.group} · {/if} -{if isTrue($smarty.const.SUBGROUP_DEBUG)} {if $user->can('manage_subgroups')} {$i18n.menu.subgroups} · {/if} -{/if} {if $user->can('manage_features')} {$i18n.menu.plugins} · {/if} From 7dc611a9564d114fd401c19f72c2525bc0e7494a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 14 Dec 2018 16:09:51 +0000 Subject: [PATCH 0577/1848] Wrote ttUser::getConfigInt and started to use it. --- WEB-INF/lib/ttReportHelper.class.php | 7 +++++-- WEB-INF/lib/ttUser.class.php | 6 ++++++ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index d3c7b7ce3..90a4a98c3 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -190,8 +190,11 @@ static function getItems($options) { if ($options['show_work_units']) { if ($user->getConfigOption('unit_totals_only')) array_push($fields, "null as units"); - else - array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit)) as units"); + else { + $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold'); + $minutesInUnit = $user->getConfigInt('minutes_in_unit'); + array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit)) as units"); + } } // Add note. if ($options['show_note']) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 2d7f1c985..a95fa72ef 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -235,6 +235,12 @@ function getConfigOption($name) { return $config->getDefinedValue($name); } + // getConfigInt retruns an integer value defined in a group, or false. + function getConfigInt($name) { + $config = new ttConfigHelper($this->getConfig()); + return $config->getIntValue($name); + } + // can - determines whether user has a right to do something. function can($do_something) { return in_array($do_something, $this->rights); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 627a23317..98ba14a61 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.group}: {$forms.groupForm.group.control}
{$i18n.label.group_name} (*):
-
 Anuko Time Tracker 1.18.31.4651 | Copyright © Anuko | +  Anuko Time Tracker 1.18.31.4652 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b0bb9205ed7aeeee700ab27ee4c76d196406e5fc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 14 Dec 2018 17:36:55 +0000 Subject: [PATCH 0578/1848] Fixed work units config for subgroups. --- WEB-INF/templates/footer.tpl | 2 +- work_units.php | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 98ba14a61..e94e90fa3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.31.4652 | Copyright © Anuko | +  Anuko Time Tracker 1.18.31.4653 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work_units.php b/work_units.php index b2373adab..84ef37e0d 100644 --- a/work_units.php +++ b/work_units.php @@ -39,17 +39,18 @@ header('Location: feature_disabled.php'); exit(); } +// End of access checks. -$config = new ttConfigHelper($user->config); +$config = new ttConfigHelper($user->getConfig()); if ($request->isPost()) { $cl_minutes_in_unit = $request->getParameter('minutes_in_unit'); $cl_1st_unit_threshold = $request->getParameter('1st_unit_threshold'); $cl_totals_only = $request->getParameter('totals_only'); } else { - $cl_minutes_in_unit = $user->minutes_in_unit; - $cl_1st_unit_threshold = $user->first_unit_threshold; - $cl_totals_only = $user->unit_totals_only; + $cl_minutes_in_unit = $user->getConfigInt('minutes_in_unit'); + $cl_1st_unit_threshold = $user->getConfigInt('1st_unit_threshold'); + $cl_totals_only = $user->getConfigOption('unit_totals_only'); } $form = new Form('workUnitsForm'); @@ -60,7 +61,7 @@ if ($request->isPost()){ // Validate user input. - if (!ttValidInteger($cl_minutes_in_unit)) $err->add($i18n->get('error.field'), $i18n->get('form.work_units.minutes_in_unit')); + if (!ttValidInteger($cl_minutes_in_unit) || $cl_minutes_in_unit == 0) $err->add($i18n->get('error.field'), $i18n->get('form.work_units.minutes_in_unit')); if (!ttValidInteger($cl_1st_unit_threshold, true) ||($cl_minutes_in_unit && $cl_1st_unit_threshold > $cl_minutes_in_unit)) $err->add($i18n->get('error.field'), $i18n->get('form.work_units.1st_unit_threshold')); // Finished validating user input. From d0c39073f009db09baa980ef6e1c2f1e71500a58 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 15 Dec 2018 13:41:44 +0000 Subject: [PATCH 0579/1848] Some refactoring of work units for subgroups. --- WEB-INF/lib/ttConfigHelper.class.php | 4 +-- WEB-INF/lib/ttGroup.class.php | 2 -- WEB-INF/lib/ttReportHelper.class.php | 42 +++++++++++++++++----------- WEB-INF/lib/ttUser.class.php | 6 ++-- WEB-INF/templates/footer.tpl | 2 +- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/WEB-INF/lib/ttConfigHelper.class.php b/WEB-INF/lib/ttConfigHelper.class.php index 6790e2140..33e94e513 100644 --- a/WEB-INF/lib/ttConfigHelper.class.php +++ b/WEB-INF/lib/ttConfigHelper.class.php @@ -73,7 +73,7 @@ function setDefinedValue($name, $set = true) { } // The getIntValue parses an integer value from the source config array. - function getIntValue($name) { + function getIntValue($name, $defaultVal = 0) { $name_with_colon = $name.':'; $len = strlen($name_with_colon); @@ -87,7 +87,7 @@ function getIntValue($name) { } } } - return false; + return $defaultVal; } // The setIntValue sets an integer value into config array. diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index f85f90971..f450a4ec4 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -116,8 +116,6 @@ function __construct($id, $org_id) { if ($this->isPluginEnabled('wu')) { $minutes_in_unit = $config->getIntValue('minutes_in_unit'); if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit; - $first_unit_threshold = $config->getIntValue('1st_unit_threshold'); - if ($first_unit_threshold) $this->first_unit_threshold = $first_unit_threshold; $this->unit_totals_only = $config->getDefinedValue('unit_totals_only'); } */ diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 90a4a98c3..8e8b312e4 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -407,7 +407,6 @@ static function getFromSession() { // With expenses, it becomes a select with group by from a combined set of records obtained with "union all". static function getSubtotals($options) { global $user; - $mdb2 = getConnection(); $concat_part = ttReportHelper::makeConcatPart($options); @@ -415,15 +414,23 @@ static function getSubtotals($options) { $where = ttReportHelper::getWhere($options); $group_by_part = ttReportHelper::makeGroupByPart($options); if ($options['show_cost']) { - if (MODE_TIME == $user->tracking_mode) { + + $workUnits = $options['show_work_units']; + if ($workUnits) { + $unitTotalsOnly = $user->getConfigOption('unit_totals_only'); + $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold'); + $minutesInUnit = $user->getConfigInt('minutes_in_unit', 15); + } + + if (MODE_TIME == $user->getTrackingMode()) { if (!ttReportHelper::groupingBy('user', $options)) $left_join = 'left join tt_users u on (l.user_id = u.id)'; $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time"; - if ($options['show_work_units']) { - if ($user->unit_totals_only) - $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + if ($workUnits) { + if ($unitTotalsOnly) + $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $firstUnitThreshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$minutesInUnit))) as units"; else - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; } $sql .= ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, null as expenses from tt_log l @@ -431,11 +438,11 @@ static function getSubtotals($options) { } else { // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time"; - if ($options['show_work_units']) { - if ($user->unit_totals_only) - $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + if ($workUnits) { + if ($unitTotalsOnly) + $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $firstUnitThreshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$minutesInUnit))) as units"; else - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; } $sql .= ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l @@ -445,11 +452,11 @@ static function getSubtotals($options) { } else { // $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time"; - if ($options['show_work_units']) { - if ($user->unit_totals_only) - $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $user->first_unit_threshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + if ($workUnits) { + if ($unitTotalsOnly) + $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $firstUnitThreshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$minutesInUnit))) as units"; else - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; } $sql .= ", null as expenses from tt_log l $join_part $where $group_by_part"; @@ -482,9 +489,10 @@ static function getSubtotals($options) { $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; $rowLabel = ttReportHelper::makeGroupByLabel($val['group_field'], $options); if ($options['show_cost']) { - if ('.' != $user->decimal_mark) { - $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']); - $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']); + $decimalMark = $user->getDecimalMark(); + if ('.' != $decimalMark) { + $val['cost'] = str_replace('.', $decimalMark, $val['cost']); + $val['expenses'] = str_replace('.', $decimalMark, $val['expenses']); } $subtotals[$val['group_field']] = array('name'=>$rowLabel,'user'=>$val['user'],'project'=>$val['project'],'task'=>$val['task'],'client'=>$val['client'],'cf_1'=>$val['cf_1'],'time'=>$time,'units'=> $val['units'],'cost'=>$val['cost'],'expenses'=>$val['expenses']); } else diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index a95fa72ef..9de260b84 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -144,7 +144,7 @@ function __construct($login, $id = null) { $this->allow_overlap = $config->getDefinedValue('allow_overlap'); $this->future_entries = $config->getDefinedValue('future_entries'); if ($this->isPluginEnabled('wu')) { - $minutes_in_unit = $config->getIntValue('minutes_in_unit'); + $minutes_in_unit = $config->getIntValue('minutes_in_unit', 15); if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit; $first_unit_threshold = $config->getIntValue('1st_unit_threshold'); if ($first_unit_threshold) $this->first_unit_threshold = $first_unit_threshold; @@ -236,9 +236,9 @@ function getConfigOption($name) { } // getConfigInt retruns an integer value defined in a group, or false. - function getConfigInt($name) { + function getConfigInt($name, $defaultVal) { $config = new ttConfigHelper($this->getConfig()); - return $config->getIntValue($name); + return $config->getIntValue($name, $defaultVal); } // can - determines whether user has a right to do something. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e94e90fa3..63b1c9ccd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.31.4653 | Copyright © Anuko | +  Anuko Time Tracker 1.18.31.4654 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From ccaee9cc6abdbf1684b25e771b0dca35659e4a55 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 15 Dec 2018 14:17:03 +0000 Subject: [PATCH 0580/1848] Some more refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 47 ++++++++++------------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 8e8b312e4..068ae9db6 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -411,53 +411,40 @@ static function getSubtotals($options) { $concat_part = ttReportHelper::makeConcatPart($options); $join_part = ttReportHelper::makeJoinPart($options); + + // TODO: Consider moving this block out into a separate function. + $workUnits = $options['show_work_units']; + if ($workUnits) { + $unitTotalsOnly = $user->getConfigOption('unit_totals_only'); + $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold'); + $minutesInUnit = $user->getConfigInt('minutes_in_unit', 15); + if ($unitTotalsOnly) + $work_unit_part = ", if (sum(l.billable * time_to_sec(l.duration)/60) < $firstUnitThreshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$minutesInUnit))) as units"; + else + $work_unit_part = ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; + } + // End of TODO. + $where = ttReportHelper::getWhere($options); $group_by_part = ttReportHelper::makeGroupByPart($options); if ($options['show_cost']) { - - $workUnits = $options['show_work_units']; - if ($workUnits) { - $unitTotalsOnly = $user->getConfigOption('unit_totals_only'); - $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold'); - $minutesInUnit = $user->getConfigInt('minutes_in_unit', 15); - } - if (MODE_TIME == $user->getTrackingMode()) { if (!ttReportHelper::groupingBy('user', $options)) $left_join = 'left join tt_users u on (l.user_id = u.id)'; - $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time"; - if ($workUnits) { - if ($unitTotalsOnly) - $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $firstUnitThreshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$minutesInUnit))) as units"; - else - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; - } + $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time".$work_unit_part; $sql .= ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, null as expenses from tt_log l $join_part $left_join $where $group_by_part"; } else { // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. - $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time"; - if ($workUnits) { - if ($unitTotalsOnly) - $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $firstUnitThreshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$minutesInUnit))) as units"; - else - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; - } + $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time".$work_unit_part; $sql .= ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses from tt_log l $join_part left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where $group_by_part"; } } else { - // $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time"; - $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time"; - if ($workUnits) { - if ($unitTotalsOnly) - $sql .= ", if (sum(l.billable * time_to_sec(l.duration)/60) < $firstUnitThreshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$minutesInUnit))) as units"; - else - $sql .= ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; - } + $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time".$work_unit_part; $sql .= ", null as expenses from tt_log l $join_part $where $group_by_part"; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 63b1c9ccd..ae8c6333c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.31.4654 | Copyright © Anuko | +  Anuko Time Tracker 1.18.31.4655 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a97edb0f5cfcf62419cd98eb3cc0fc415eaab319 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 15 Dec 2018 15:28:07 +0000 Subject: [PATCH 0581/1848] Simplified conditional logic in ttReportHelper::getSubtotals. --- WEB-INF/lib/ttReportHelper.class.php | 76 +++++++++++++++------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 068ae9db6..2265f0dac 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -410,44 +410,14 @@ static function getSubtotals($options) { $mdb2 = getConnection(); $concat_part = ttReportHelper::makeConcatPart($options); + $work_unit_part = ttReportHelper::makeWorkUnitPart($options); $join_part = ttReportHelper::makeJoinPart($options); - - // TODO: Consider moving this block out into a separate function. - $workUnits = $options['show_work_units']; - if ($workUnits) { - $unitTotalsOnly = $user->getConfigOption('unit_totals_only'); - $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold'); - $minutesInUnit = $user->getConfigInt('minutes_in_unit', 15); - if ($unitTotalsOnly) - $work_unit_part = ", if (sum(l.billable * time_to_sec(l.duration)/60) < $firstUnitThreshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$minutesInUnit))) as units"; - else - $work_unit_part = ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; - } - // End of TODO. - + $cost_part = ttReportHelper::makeCostPart($options); $where = ttReportHelper::getWhere($options); $group_by_part = ttReportHelper::makeGroupByPart($options); - if ($options['show_cost']) { - if (MODE_TIME == $user->getTrackingMode()) { - if (!ttReportHelper::groupingBy('user', $options)) - $left_join = 'left join tt_users u on (l.user_id = u.id)'; - $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time".$work_unit_part; - $sql .= ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost, - null as expenses from tt_log l - $join_part $left_join $where $group_by_part"; - } else { - // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table. - $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time".$work_unit_part; - $sql .= ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, - null as expenses from tt_log l - $join_part - left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where $group_by_part"; - } - } else { - $sql = "select $concat_part, sum(time_to_sec(l.duration)) as time".$work_unit_part; - $sql .= ", null as expenses from tt_log l - $join_part $where $group_by_part"; - } + + $parts = "$concat_part, sum(time_to_sec(l.duration)) as time, null as expenses".$work_unit_part.$cost_part; + $sql = "select $parts from tt_log l $join_part $where $group_by_part"; // By now we have sql for time items. // However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table. @@ -1465,7 +1435,8 @@ static function makeCombinedSelectPart($options) { static function makeJoinPart($options) { global $user; - if (ttReportHelper::groupingBy('user', $options)) { + $trackingMode = $user->getTrackingMode(); + if (ttReportHelper::groupingBy('user', $options) || MODE_TIME == $trackingMode) { $join .= ' left join tt_users u on (l.user_id = u.id)'; } if (ttReportHelper::groupingBy('client', $options)) { @@ -1484,9 +1455,42 @@ static function makeJoinPart($options) { elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) $join .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)'; } + if ($options['show_cost'] && $trackingMode != MODE_TIME) { + $join .= ' left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)'; + } return $join; } + // makeWorkUnitPart builds an sql part for work units for time items. + static function makeWorkUnitPart($options) { + global $user; + + $workUnits = $options['show_work_units']; + if ($workUnits) { + $unitTotalsOnly = $user->getConfigOption('unit_totals_only'); + $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold'); + $minutesInUnit = $user->getConfigInt('minutes_in_unit', 15); + if ($unitTotalsOnly) + $work_unit_part = ", if (sum(l.billable * time_to_sec(l.duration)/60) < $firstUnitThreshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$minutesInUnit))) as units"; + else + $work_unit_part = ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; + } + return $work_unit_part; + } + + // makeCostPart builds a cost part for time items. + static function makeCostPart($options) { + global $user; + + if ($options['show_cost']) { + if (MODE_TIME == $user->getTrackingMode()) + $cost_part = ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost"; + else + $cost_part .= ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost"; + } + return $cost_part; + } + // makeJoinExpensesPart builds a left join part for getSubtotals query for expense items. static function makeJoinExpensesPart($options) { if (ttReportHelper::groupingBy('user', $options)) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ae8c6333c..84526cfb4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.31.4655 | Copyright © Anuko | +  Anuko Time Tracker 1.18.31.4656 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9763bf0359b70369021d6f9b12b6e6cc9c0939f5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 15 Dec 2018 16:12:59 +0000 Subject: [PATCH 0582/1848] Fixed work unit config. --- WEB-INF/lib/ttReportHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- work_units.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 2265f0dac..d46319dbe 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -191,8 +191,8 @@ static function getItems($options) { if ($user->getConfigOption('unit_totals_only')) array_push($fields, "null as units"); else { - $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold'); - $minutesInUnit = $user->getConfigInt('minutes_in_unit'); + $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold', 0); + $minutesInUnit = $user->getConfigInt('minutes_in_unit', 15); array_push($fields, "if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit)) as units"); } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 84526cfb4..de22892ff 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.31.4656 | Copyright © Anuko | +  Anuko Time Tracker 1.18.31.4658 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work_units.php b/work_units.php index 84ef37e0d..e4d198d5c 100644 --- a/work_units.php +++ b/work_units.php @@ -48,8 +48,8 @@ $cl_1st_unit_threshold = $request->getParameter('1st_unit_threshold'); $cl_totals_only = $request->getParameter('totals_only'); } else { - $cl_minutes_in_unit = $user->getConfigInt('minutes_in_unit'); - $cl_1st_unit_threshold = $user->getConfigInt('1st_unit_threshold'); + $cl_minutes_in_unit = $user->getConfigInt('minutes_in_unit', 15); + $cl_1st_unit_threshold = $user->getConfigInt('1st_unit_threshold', 0); $cl_totals_only = $user->getConfigOption('unit_totals_only'); } From 58057bc7a8634917640cc660971bfc3c8440a687 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 17 Dec 2018 14:03:24 +0000 Subject: [PATCH 0583/1848] Fixed quota output for week view. --- WEB-INF/templates/footer.tpl | 2 +- week.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index de22892ff..55c2266b6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.31.4658 | Copyright © Anuko | +  Anuko Time Tracker 1.18.32.4659 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/week.php b/week.php index c1c76f9de..1dd6e56a5 100644 --- a/week.php +++ b/week.php @@ -91,9 +91,9 @@ if ($user->isPluginEnabled('mq')){ require_once('plugins/MonthlyQuota.class.php'); $quota = new MonthlyQuota(); - $month_quota = $quota->get($selected_date->mYear, $selected_date->mMonth); + $month_quota_minutes = $quota->get($selected_date->mYear, $selected_date->mMonth); $month_total = ttTimeHelper::getTimeForMonth($selected_date); - $minutes_left = round(60*$month_quota) - ttTimeHelper::toMinutes($month_total); + $minutes_left = $month_quota_minutes - ttTimeHelper::toMinutes($month_total); $smarty->assign('month_total', $month_total); $smarty->assign('over_quota', $minutes_left < 0); From 8cfd24a3f3529a3a8eabe0d7cb53f4331d9dec6f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 17 Dec 2018 14:22:22 +0000 Subject: [PATCH 0584/1848] Holidays adjusted for German language. --- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 80c78537b..3775315ca 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -34,7 +34,7 @@ $i18n_weekdays = array('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'); $i18n_weekdays_short = array('So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'); // format mm/dd -$i18n_holidays = array('01/01', '04/02', '05/01', '05/10', '05/21', '10/03', '12/25', '12/26'); +$i18n_holidays = array('01/01', '03/30', '04/02', '05/01', '05/21', '05/31', '10/03', '11/01', '12/24','12/25', '12/26'); $i18n_key_words = array( diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 55c2266b6..bbb21ee9e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.32.4659 | Copyright © Anuko | +  Anuko Time Tracker 1.18.32.4660 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 1dc4d7237116ebf149921a5988be96ab2cf40f3c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 17 Dec 2018 19:25:30 +0000 Subject: [PATCH 0585/1848] A small fix for export. --- WEB-INF/lib/ttTeamHelper.class.php | 4 +++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 6c058c5d1..b94f6434c 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -260,7 +260,9 @@ static function getUserToProjectBinds($group_id) { $mdb2 = getConnection(); $result = array(); - $sql = "select * from tt_user_project_binds where user_id in (select id from tt_users where group_id = $group_id) order by user_id, status, project_id"; + $sql = "select * from tt_user_project_binds". + " where user_id in (select id from tt_users where group_id = $group_id)". + " and group_id = $group_id order by user_id, status, project_id"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bbb21ee9e..86ae44cbc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.32.4660 | Copyright © Anuko | +  Anuko Time Tracker 1.18.32.4661 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From f64edab52483034571128ed287ce10996498f0dc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 18 Dec 2018 19:21:30 +0000 Subject: [PATCH 0586/1848] Added a TODO comment about RAM issue. --- WEB-INF/lib/ttGroupExportHelper.class.php | 4 ++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index d2ee6413d..c5600fd8b 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -335,6 +335,10 @@ function writeData() { } // Write time log entries and build logMap at the same time. + // TODO: big data sets get us out of memory error. + // We need to optimize this by working on smaller result sets at a time. + // tt_log is one potentially large table, but so may be others. + // Refactor this during next round of work here. $records = $this->getRecordsFromTable('tt_log'); if (count($records) > 0) { fwrite($this->file, $this->indentation." \n"); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 86ae44cbc..38267b688 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.32.4661 | Copyright © Anuko | +  Anuko Time Tracker 1.18.32.4662 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6fc6c28b9eed8a9316a630185e327a53bb0d9e0c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 18 Dec 2018 20:14:23 +0000 Subject: [PATCH 0587/1848] Improved import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index ff3376d32..626408f28 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -551,11 +551,11 @@ function importXml() { $this->firstPass = false; // We are done with 1st pass. xml_parser_free($parser); if ($file) fclose($file); - if (!$this->canImport) { + if ($this->errors->yes()) { + // Remove the file and exit if we have errors. unlink($filename); return; } - if ($this->errors->yes()) return; // Exit if we have errors. // Now we can do a second pass, where real work is done. $parser = xml_parser_create(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 38267b688..176d71420 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.32.4662 | Copyright © Anuko | +  Anuko Time Tracker 1.18.32.4663 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 19e9b9abac0144d500df9fe1d4ce555a30b4c676 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 19 Dec 2018 15:00:15 +0000 Subject: [PATCH 0588/1848] Improved handlng of import. --- WEB-INF/lib/ttOrgImportHelper.class.php | 5 +++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 626408f28..e95b836de 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -499,6 +499,11 @@ function endElement($parser, $name) { function importXml() { global $i18n; + if (!$_FILES['xmlfile']['name']) { + $this->errors->add($i18n->get('error.upload')); + return; // There is nothing to do if we don't have a file. + } + // Do we have a compressed file? $compressed = false; $file_ext = substr($_FILES['xmlfile']['name'], strrpos($_FILES['xmlfile']['name'], '.') + 1); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 176d71420..c8933865c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.32.4663 | Copyright © Anuko | +  Anuko Time Tracker 1.18.32.4664 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 323f03bd2d9179fbb923e4518853324d8bda1b95 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 19 Dec 2018 16:11:23 +0000 Subject: [PATCH 0589/1848] Added a comment about vertical tab problem. --- WEB-INF/lib/ttOrgImportHelper.class.php | 22 +++++++++++++++++++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index e95b836de..099cb58f9 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -493,9 +493,25 @@ function endElement($parser, $name) { } } - // importXml - uncompresses the file, reads and parses its content. During parsing, - // startElement, endElement, and dataElement functions are called as many times as necessary. - // Actual import occurs in the endElement handler. + // importXml - uncompresses the file, reads and parses its content. + // It goes through the file 2 times. + // + // During 1st pass, it determines whether we can import data. + // In 1st pass, startElement function is called as many times as necessary. + // + // Actual import occurs during 2nd pass. + // In 2nd pass, startElement and endElement are called many times. + // We only use endElement to finish current group processing. + // + // The above allows us to export/import complex orgs with nested groups, + // while by design all data are in attributes of the elements (no CDATA). + // + // There is currently at least one problem with keeping all data in attributes: + // a vertical tab character 0xB anywhere breaks parsing, making import impossible. + // See https://github.com/sparklemotion/nokogiri/issues/1581 - looks like + // an XML standard thing. Apparently, other invalid characters break parsing too. + // This problem needs to be addressed at some point but how exactly without + // complicating export-import too much with CDATA and dataElement processing? function importXml() { global $i18n; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c8933865c..ee01f47fe 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.32.4664 | Copyright © Anuko | +  Anuko Time Tracker 1.18.32.4665 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e489a39d1dd1ad0293c45d887433d47b7734979f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 19 Dec 2018 18:53:27 +0000 Subject: [PATCH 0590/1848] A fix for work units in totals only report. --- WEB-INF/lib/ttReportHelper.class.php | 7 +++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index d46319dbe..237e39e9d 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -471,7 +471,10 @@ static function getTotals($options) // Prepare parts. $time_part = "sum(time_to_sec(l.duration)) as time"; if ($options['show_work_units']) { - $units_part = $user->unit_totals_only ? ", null as units" : ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(l.duration)/60/$user->minutes_in_unit))) as units"; + $unitTotalsOnly = $user->getConfigOption('unit_totals_only'); + $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold', 0); + $minutesInUnit = $user->getConfigInt('minutes_in_unit', 15); + $units_part = $unitTotalsOnly ? ", null as units" : ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; } if ($options['show_cost']) { if (MODE_TIME == $user->tracking_mode) @@ -1468,7 +1471,7 @@ static function makeWorkUnitPart($options) { $workUnits = $options['show_work_units']; if ($workUnits) { $unitTotalsOnly = $user->getConfigOption('unit_totals_only'); - $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold'); + $firstUnitThreshold = $user->getConfigInt('1st_unit_threshold', 0); $minutesInUnit = $user->getConfigInt('minutes_in_unit', 15); if ($unitTotalsOnly) $work_unit_part = ", if (sum(l.billable * time_to_sec(l.duration)/60) < $firstUnitThreshold, 0, ceil(sum(l.billable * time_to_sec(l.duration)/60/$minutesInUnit))) as units"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ee01f47fe..295fc064d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.32.4665 | Copyright © Anuko | +  Anuko Time Tracker 1.18.33.4666 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 76afe042736b2e08bf3d5b8a4112d15a93073e0b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 19 Dec 2018 19:13:00 +0000 Subject: [PATCH 0591/1848] Fixed date format for a subgroup report. --- WEB-INF/lib/ttReportHelper.class.php | 24 +++++++++++++----------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 237e39e9d..686283bcf 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -463,9 +463,10 @@ static function getSubtotals($options) { static function getTotals($options) { global $user; - $mdb2 = getConnection(); + $trackingMode = $user->getTrackingMode(); + $decimalMark = $user->getDecimalMark(); $where = ttReportHelper::getWhere($options); // Prepare parts. @@ -477,7 +478,7 @@ static function getTotals($options) $units_part = $unitTotalsOnly ? ", null as units" : ", sum(if(l.billable = 0 or time_to_sec(l.duration)/60 < $firstUnitThreshold, 0, ceil(time_to_sec(l.duration)/60/$minutesInUnit))) as units"; } if ($options['show_cost']) { - if (MODE_TIME == $user->tracking_mode) + if (MODE_TIME == $trackingMode) $cost_part = ", sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses"; else $cost_part = ", sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost, null as expenses"; @@ -485,7 +486,7 @@ static function getTotals($options) $cost_part = ", null as cost, null as expenses"; } if ($options['show_cost']) { - if (MODE_TIME == $user->tracking_mode) { + if (MODE_TIME == $trackingMode) { $left_joins = "left join tt_users u on (l.user_id = u.id)"; } else { $left_joins = "left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; @@ -517,21 +518,22 @@ static function getTotals($options) if ($options['show_cost']) { $total_cost = $val['cost']; if (!$total_cost) $total_cost = '0.00'; - if ('.' != $user->decimal_mark) - $total_cost = str_replace('.', $user->decimal_mark, $total_cost); + if ('.' != $decimalMark) + $total_cost = str_replace('.', $decimalMark, $total_cost); $total_expenses = $val['expenses']; if (!$total_expenses) $total_expenses = '0.00'; - if ('.' != $user->decimal_mark) - $total_expenses = str_replace('.', $user->decimal_mark, $total_expenses); + if ('.' != $decimalMark) + $total_expenses = str_replace('.', $decimalMark, $total_expenses); } + $dateFormat = $user->getDateFormat(); if ($options['period']) - $period = new Period($options['period'], new DateAndTime($user->date_format)); + $period = new Period($options['period'], new DateAndTime($dateFormat)); else { $period = new Period(); $period->setPeriod( - new DateAndTime($user->date_format, $options['period_start']), - new DateAndTime($user->date_format, $options['period_end'])); + new DateAndTime($dateFormat, $options['period_start']), + new DateAndTime($dateFormat, $options['period_end'])); } $totals['start_date'] = $period->getStartDate(); @@ -1596,7 +1598,7 @@ static function makeGroupByLabel($key, $options) { return $key; // No need to format. global $user; - if ($user->date_format == DB_DATEFORMAT) + if ($user->getDateFormat() == DB_DATEFORMAT) return $key; // No need to format. $label = $key; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 295fc064d..920d241ba 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.33.4666 | Copyright © Anuko | +  Anuko Time Tracker 1.18.33.4668 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 5d1a946b7e54074b7a9ae0b85b73bd573ffe236b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 19 Dec 2018 19:19:27 +0000 Subject: [PATCH 0592/1848] A bit of cleanup. --- WEB-INF/lib/ttGroup.class.php | 10 ---------- WEB-INF/lib/ttUser.class.php | 10 ---------- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index f450a4ec4..5ef258cae 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -58,9 +58,6 @@ class ttGroup { var $custom_logo = 0; // Whether to use a custom logo for group. var $lock_spec = null; // Cron specification for record locking. var $workday_minutes = 480; // Number of work minutes in a regular day. - var $minutes_in_unit = 15; // Number of minutes in unit for Work units plugin. - var $first_unit_threshold = 0;// Threshold for 1st unit for Work units plugin. - var $unit_totals_only = 0; // Totals only option for the Work units plugin. var $active_users = 0; // Count of active users in group. // We need a non-zero count to display some menus. @@ -112,13 +109,6 @@ function __construct($id, $org_id) { $this->punch_mode = $config->getDefinedValue('punch_mode'); $this->allow_overlap = $config->getDefinedValue('allow_overlap'); $this->future_entries = $config->getDefinedValue('future_entries'); - /* - if ($this->isPluginEnabled('wu')) { - $minutes_in_unit = $config->getIntValue('minutes_in_unit'); - if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit; - $this->unit_totals_only = $config->getDefinedValue('unit_totals_only'); - } - */ } // Determine active user count in a separate query. diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 9de260b84..ab2b4bcee 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -72,9 +72,6 @@ class ttUser { var $workday_minutes = 480; // Number of work minutes in a regular day. var $rights = array(); // An array of user rights such as 'track_own_time', etc. var $is_client = false; // Whether user is a client as determined by missing 'track_own_time' right. - var $minutes_in_unit = 15; // Number of minutes in unit for Work units plugin. - var $first_unit_threshold = 0;// Threshold for 1st unit for Work units plugin. - var $unit_totals_only = 0; // Totals only option for the Work units plugin. var $behalfGroup = null; // A ttGroup instance with on behalf group attributes. @@ -143,13 +140,6 @@ function __construct($login, $id = null) { $this->punch_mode = $config->getDefinedValue('punch_mode'); $this->allow_overlap = $config->getDefinedValue('allow_overlap'); $this->future_entries = $config->getDefinedValue('future_entries'); - if ($this->isPluginEnabled('wu')) { - $minutes_in_unit = $config->getIntValue('minutes_in_unit', 15); - if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit; - $first_unit_threshold = $config->getIntValue('1st_unit_threshold'); - if ($first_unit_threshold) $this->first_unit_threshold = $first_unit_threshold; - $this->unit_totals_only = $config->getDefinedValue('unit_totals_only'); - } // Set "on behalf" id and name (user). if (isset($_SESSION['behalf_id'])) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 920d241ba..c2f3151aa 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.33.4668 | Copyright © Anuko | +  Anuko Time Tracker 1.18.33.4669 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 906338007f1d45fe1ec40b19b1ff3106898a98fb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 19 Dec 2018 20:34:49 +0000 Subject: [PATCH 0593/1848] Introduced quota_percent field in tt_users table for quota work. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c2f3151aa..496a9fb29 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.33.4669 | Copyright © Anuko | +  Anuko Time Tracker 1.18.34.4670 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 197c43b0b..ea177e978 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11826"]) { + if ($_POST["convert11797to11834"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1040,6 +1040,8 @@ function ttExecute($sql) { ttExecute("ALTER TABLE `tt_groups` ADD COLUMN `description` varchar(255) default NULL after `name`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.26', modified = now() where param_name = 'version_db' and param_value = '1.18.24'"); ttExecute("update `tt_client_project_binds` cpb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.26') inner join `tt_clients` c on c.id = cpb.client_id set cpb.group_id = c.group_id, cpb.org_id = c.org_id where cpb.org_id is null"); + ttExecute("ALTER TABLE `tt_users` ADD COLUMN `quota_percent` float(6,2) default NULL after `rate`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.34', modified = now() where param_name = 'version_db' and param_value = '1.18.26'"); } if ($_POST["cleanup"]) { @@ -1087,7 +1089,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.26) + Create database structure (v1.18.34)
(applies only to new installations, do not execute when updating)
@@ -1132,8 +1134,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.26)Update database structure (v1.17.97 to v1.18.34)
diff --git a/mysql.sql b/mysql.sql index 0f3f00c9b..fb2ebe174 100644 --- a/mysql.sql +++ b/mysql.sql @@ -91,6 +91,7 @@ CREATE TABLE `tt_users` ( `role_id` int(11) default NULL, # role id `client_id` int(11) default NULL, # client id for "client" user role `rate` float(6,2) NOT NULL default '0.00', # default hourly rate + `quota_percent` float(6,2) default NULL, # percent of time quota `email` varchar(100) default NULL, # user email `created` datetime default NULL, # creation timestamp `created_ip` varchar(45) default NULL, # creator ip @@ -488,4 +489,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.26', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.34', now()); # TODO: change when structure changes. From d74142948db5d27a3bf144a8ee485318cc1330c3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 20 Dec 2018 17:43:55 +0000 Subject: [PATCH 0594/1848] Introduced ttBehalfUser class for quote percent work. --- WEB-INF/lib/ttBehalfUser.class.php | 61 ++++++++++++++++++++++++++++++ WEB-INF/lib/ttGroup.class.php | 2 + WEB-INF/lib/ttUser.class.php | 19 +++++++--- WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 WEB-INF/lib/ttBehalfUser.class.php diff --git a/WEB-INF/lib/ttBehalfUser.class.php b/WEB-INF/lib/ttBehalfUser.class.php new file mode 100644 index 000000000..7f7a5ffa9 --- /dev/null +++ b/WEB-INF/lib/ttBehalfUser.class.php @@ -0,0 +1,61 @@ +query($sql); + if (is_a($res, 'PEAR_Error')) return; + + $val = $res->fetchRow(); + if ($val['id'] > 0) { + $this->name = $val['name']; + $this->id = $val['id']; + if ($val['quota_percent']) $this->quota_percent = $val['quota_percent']; + } + } +} diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index 5ef258cae..9c12e95b6 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -63,6 +63,8 @@ class ttGroup { // We need a non-zero count to display some menus. // Constructor. + // Note: org_id is needed because we construct an object in ttUser constructor, + // when global $user object does not yet exist. function __construct($id, $org_id) { $mdb2 = getConnection(); diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index ab2b4bcee..4145f6030 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -28,6 +28,7 @@ import('ttConfigHelper'); import('ttGroupHelper'); +import('ttBehalfUser'); import('ttGroup'); import('form.Form'); import('form.ActionForm'); @@ -42,6 +43,7 @@ class ttUser { var $role_name = null; // Role name. var $rank = null; // User role rank. var $client_id = null; // Client id for client user role. + var $quota_percent = 100.0; // Time quota percent for quotas plugin. var $behalf_id = null; // User id, on behalf of whom we are working. var $behalf_group_id = null; // Group id, on behalf of which we are working. var $behalf_name = null; // User name, on behalf of whom we are working. @@ -73,6 +75,7 @@ class ttUser { var $rights = array(); // An array of user rights such as 'track_own_time', etc. var $is_client = false; // Whether user is a client as determined by missing 'track_own_time' right. + var $behalfUser = null; // A ttBehalfUser instance with on behalf user attributes. var $behalfGroup = null; // A ttGroup instance with on behalf group attributes. // Constructor. @@ -84,11 +87,11 @@ function __construct($login, $id = null) { $mdb2 = getConnection(); - $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id, u.email, - g.org_id, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format, g.time_format, g.week_start, - g.tracking_mode, g.project_required, g.task_required, g.record_type, - g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.workday_minutes, g.custom_logo - FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; + $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id,". + " u.quota_percent, u.email, g.org_id, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format,". + " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.task_required, g.record_type,". + " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.workday_minutes, g.custom_logo". + " FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; if ($id) $sql .= "u.id = $id"; else @@ -113,6 +116,7 @@ function __construct($login, $id = null) { $this->rank = $val['rank']; $this->client_id = $val['client_id']; $this->is_client = $this->client_id && !in_array('track_own_time', $this->rights); + if ($val['quota_percent']) $this->quota_percent = $val['quota_percent']; $this->email = $val['email']; $this->lang = $val['lang']; $this->decimal_mark = $val['decimal_mark']; @@ -145,6 +149,8 @@ function __construct($login, $id = null) { if (isset($_SESSION['behalf_id'])) { $this->behalf_id = $_SESSION['behalf_id']; $this->behalf_name = $_SESSION['behalf_name']; + + $this->behalfUser = new ttBehalfUser($this->behalf_id, $this->org_id); } // Set "on behalf" id and name (group). if (isset($_SESSION['behalf_group_id'])) { @@ -824,6 +830,7 @@ function setOnBehalfUser($user_id) { // Unset things first. $this->behalf_id = null; $this->behalf_name = null; + unset($this->behalfUser); unset($_SESSION['behalf_id']); unset($_SESSION['behalf_name']); @@ -839,6 +846,8 @@ function setOnBehalfUser($user_id) { $_SESSION['behalf_name'] = $onBehalfUserName; $this->behalf_id = $user_id; $this->behalf_name = $onBehalfUserName; + + $this->behalfUser = new ttBehalfUser($this->behalf_id, $this->org_id); return; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 496a9fb29..7d3abc65b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.34.4670 | Copyright © Anuko | +  Anuko Time Tracker 1.18.34.4671 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 0f6454bb20d223018d0f969ab5e1d46f4ce14b96 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 20 Dec 2018 19:13:18 +0000 Subject: [PATCH 0595/1848] Started using quota percent for users if defined. --- WEB-INF/lib/ttUser.class.php | 9 +++++++-- WEB-INF/templates/footer.tpl | 2 +- plugins/MonthlyQuota.class.php | 10 ++++++++++ time.php | 2 +- week.php | 2 +- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 4145f6030..7d6ee6dee 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -162,9 +162,14 @@ function __construct($login, $id = null) { } } - // The getUser returns user id on behalf of whom the current user is operating. + // getUser returns user id on behalf of whom the current user is operating. function getUser() { - return ($this->behalf_id ? $this->behalf_id : $this->id); + return ($this->behalfUser ? $this->behalfUser->id : $this->id); + } + + // getQuotaPercent returns quota percent for active user. + function getQuotaPercent() { + return ($this->behalfUser ? $this->behalfUser->quota_percent : $this->quota_percent); } // The getGroup returns group id on behalf of which the current user is operating. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7d3abc65b..a0c889c83 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.34.4671 | Copyright © Anuko | +  Anuko Time Tracker 1.18.34.4672 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/plugins/MonthlyQuota.class.php b/plugins/MonthlyQuota.class.php index 29d8cfb7b..a1c1b5d09 100644 --- a/plugins/MonthlyQuota.class.php +++ b/plugins/MonthlyQuota.class.php @@ -84,6 +84,16 @@ private function getSingle($year, $month) { return $numWorkdays * $user->getWorkdayMinutes(); } + // getUserQuota - obtains a quota for user for a single month. + // This quota is adjusted by quota_percent value for user. + public function getUserQuota($year, $month) { + global $user; + + $minutes = $this->getSingle($year, $month); + $userMinutes = (int) $minutes * $user->getQuotaPercent() / 100; + return $userMinutes; + } + // getMany - returns an array of quotas for a given year for group. private function getMany($year){ $sql = "select month, minutes from tt_monthly_quotas". diff --git a/time.php b/time.php index 013f15ca6..ac6b69b5f 100644 --- a/time.php +++ b/time.php @@ -85,7 +85,7 @@ if ($user->isPluginEnabled('mq')){ require_once('plugins/MonthlyQuota.class.php'); $quota = new MonthlyQuota(); - $month_quota_minutes = $quota->get($selected_date->mYear, $selected_date->mMonth); + $month_quota_minutes = $quota->getUserQuota($selected_date->mYear, $selected_date->mMonth); $month_total = ttTimeHelper::getTimeForMonth($selected_date); $minutes_left = $month_quota_minutes - ttTimeHelper::toMinutes($month_total); diff --git a/week.php b/week.php index 1dd6e56a5..f18817d7d 100644 --- a/week.php +++ b/week.php @@ -91,7 +91,7 @@ if ($user->isPluginEnabled('mq')){ require_once('plugins/MonthlyQuota.class.php'); $quota = new MonthlyQuota(); - $month_quota_minutes = $quota->get($selected_date->mYear, $selected_date->mMonth); + $month_quota_minutes = $quota->getUserQuota($selected_date->mYear, $selected_date->mMonth); $month_total = ttTimeHelper::getTimeForMonth($selected_date); $minutes_left = $month_quota_minutes - ttTimeHelper::toMinutes($month_total); From 448c3e07930dbf902c97c93f252a474cb0931e23 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 20 Dec 2018 22:09:50 +0000 Subject: [PATCH 0596/1848] Initial attempt to implement quota percent for users. --- WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/lib/ttUserHelper.class.php | 12 +++++++++--- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/user_add.tpl | 8 +++++++- WEB-INF/templates/user_edit.tpl | 8 +++++++- user_add.php | 15 +++++++++++++-- user_edit.php | 16 ++++++++++++++-- 7 files changed, 52 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 7d6ee6dee..f163e5814 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -542,7 +542,7 @@ function getUserDetails($user_id) { // then rank restriction does not apply. $max_rank = $this->behalfGroup ? MAX_RANK : $this->rank; - $sql = "select u.id, u.name, u.login, u.role_id, u.client_id, u.status, u.rate, u.email from tt_users u". + $sql = "select u.id, u.name, u.login, u.role_id, u.client_id, u.status, u.rate, u.quota_percent, u.email from tt_users u". " left join tt_roles r on (u.role_id = r.id)". " where u.id = $user_id and u.group_id = $group_id and u.org_id = $org_id and u.status is not null". " and (r.rank < $max_rank or (r.rank = $max_rank and u.id = $this->id))"; // Users with lesser roles or self. diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index f91128e7e..26ced938a 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -104,6 +104,7 @@ static function insert($fields, $hash = true) { $group_id = (int) $fields['group_id']; $org_id = (int) $fields['org_id']; $rate = str_replace(',', '.', isset($fields['rate']) ? $fields['rate'] : 0); + $quota_percent = str_replace(',', '.', isset($fields['quota_percent']) ? $fields['quota_percent'] : 100); if($rate == '') $rate = 0; if (array_key_exists('status', $fields)) { // Key exists and may be NULL during migration of deleted acounts. @@ -113,9 +114,9 @@ static function insert($fields, $hash = true) { $created_ip_v = ', '.$mdb2->quote($_SERVER['REMOTE_ADDR']); $created_by_v = ', '.$user->id; - $sql = "insert into tt_users (name, login, password, group_id, org_id, role_id, client_id, rate, email, created, created_ip, created_by $status_f) values (". + $sql = "insert into tt_users (name, login, password, group_id, org_id, role_id, client_id, rate, quota_percent, email, created, created_ip, created_by $status_f) values (". $mdb2->quote($fields['name']).", ".$mdb2->quote($fields['login']). - ", $password, $group_id, $org_id, ".$mdb2->quote($fields['role_id']).", ".$mdb2->quote($fields['client_id']).", $rate, ".$mdb2->quote($email).", now() $created_ip_v $created_by_v $status_v)"; + ", $password, $group_id, $org_id, ".$mdb2->quote($fields['role_id']).", ".$mdb2->quote($fields['client_id']).", $rate, $quota_percent, ".$mdb2->quote($email).", now() $created_ip_v $created_by_v $status_v)"; $affected = $mdb2->exec($sql); // Now deal with project assignment. @@ -178,6 +179,11 @@ static function update($user_id, $fields) { $rate_part = ", rate = ".$mdb2->quote($rate); } + if (array_key_exists('quota_percent', $fields)) { + $quota_percent = str_replace(',', '.', isset($fields['quota_percent']) ? $fields['quota_percent'] : 100); + $quota_percent_part = ", quota_percent = ".$mdb2->quote($quota_percent); + } + if (isset($fields['email'])) $email_part = ', email = '.$mdb2->quote($fields['email']); @@ -187,7 +193,7 @@ static function update($user_id, $fields) { } $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; - $parts = ltrim($login_part.$pass_part.$name_part.$role_part.$client_part.$rate_part.$email_part.$modified_part.$status_part, ','); + $parts = ltrim($login_part.$pass_part.$name_part.$role_part.$client_part.$rate_part.$quota_percent_part.$email_part.$modified_part.$status_part, ','); $sql = "update tt_users set $parts". " where id = $user_id and group_id = $group_id and org_id = $org_id"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a0c889c83..b1c606f4f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- -{if ($smarty.const.MODE_PROJECTS == $user->getTrackingMode() || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && $show_projects} +{if $show_quota} + + + + +{/if} +{if $show_projects} diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index 0c24a0113..b1026f2c1 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -115,7 +115,13 @@ function handleClientControl() { -{if ($smarty.const.MODE_PROJECTS == $user->getTrackingMode() || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && $show_projects} +{if $show_quota} + + + + +{/if} +{if $show_projects} diff --git a/user_add.php b/user_add.php index 28baa2cf5..6f1e02c11 100644 --- a/user_add.php +++ b/user_add.php @@ -46,6 +46,7 @@ // The "limit" plugin is not required for normal operation of Time Tracker. @include('plugins/limit/user_add.php'); +$show_quota = $user->isPluginEnabled('mq'); if ($user->isPluginEnabled('cl')) $clients = ttGroupHelper::getActiveClients(); @@ -61,6 +62,7 @@ $cl_role_id = $request->getParameter('role'); $cl_client_id = $request->getParameter('client'); $cl_rate = $request->getParameter('rate'); + $cl_quota_percent = $request->getParameter('quota_percent'); $cl_projects = $request->getParameter('projects'); if (is_array($cl_projects)) { foreach ($cl_projects as $p) { @@ -90,8 +92,14 @@ $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); +if ($show_quota) + $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); -$projects = ttGroupHelper::getActiveProjects(); +$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); +if ($show_projects) { + $projects = ttGroupHelper::getActiveProjects(); + if (count($projects) == 0) $show_projects = false; +} // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { @@ -143,6 +151,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Require selection of a client for a client role. if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); + if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('form.quota.quota')); if ($err->no()) { if (!ttUserHelper::getUserByLogin($cl_login)) { @@ -151,6 +160,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'login' => $cl_login, 'password' => $cl_password1, 'rate' => $cl_rate, + 'quota_percent' => $cl_quota_percent, 'group_id' => $user->getGroup(), 'org_id' => $user->org_id, 'role_id' => $cl_role_id, @@ -176,7 +186,8 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('active_roles', $active_roles); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', count($projects) > 0); +$smarty->assign('show_quota', $show_quota); +$smarty->assign('show_projects', $show_projects); $smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); $smarty->assign('title', $i18n->get('title.add_user')); $smarty->assign('content_page_name', 'user_add.tpl'); diff --git a/user_edit.php b/user_edit.php index 531d2efec..c3910db3e 100644 --- a/user_edit.php +++ b/user_edit.php @@ -49,10 +49,15 @@ } // End of access checks. +$show_quota = $user->isPluginEnabled('mq'); if ($user->isPluginEnabled('cl')) $clients = ttGroupHelper::getActiveClients(); -$projects = ttGroupHelper::getActiveProjects(); +$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); +if ($show_projects) { + $projects = ttGroupHelper::getActiveProjects(); + if (count($projects) == 0) $show_projects = false; +} $assigned_projects = array(); if ($request->isPost()) { @@ -67,6 +72,7 @@ $cl_client_id = $request->getParameter('client'); $cl_status = $request->getParameter('status'); $cl_rate = $request->getParameter('rate'); + $cl_quota_percent = $request->getParameter('quota_percent'); $cl_projects = $request->getParameter('projects'); if (is_array($cl_projects)) { foreach ($cl_projects as $p) { @@ -84,6 +90,7 @@ $cl_login = $user_details['login']; $cl_email = $user_details['email']; $cl_rate = str_replace('.', $user->getDecimalMark(), $user_details['rate']); + $cl_quota_percent = str_replace('.', $user->getDecimalMark(), $user_details['quota_percent']); $cl_role_id = $user_details['role_id']; $cl_client_id = $user_details['client_id']; $cl_status = $user_details['status']; @@ -111,6 +118,8 @@ $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); +if ($show_quota) + $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { @@ -164,6 +173,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Require selection of a client for a client role. if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); + if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('form.quota.quota')); if ($err->no()) { $existing_user = ttUserHelper::getUserByLogin($cl_login); @@ -176,6 +186,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'email' => $cl_email, 'status' => $cl_status, 'rate' => $cl_rate, + 'quota_percent' => $cl_quota_percent, 'projects' => $assigned_projects); if (in_array('manage_users', $user->rights) && $cl_role_id) { $fields['role_id'] = $cl_role_id; @@ -228,7 +239,8 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('active_roles', $active_roles); $smarty->assign('can_swap', $can_swap); -$smarty->assign('show_projects', count($projects) > 0); +$smarty->assign('show_quota', $show_quota); +$smarty->assign('show_projects', $show_projects); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); $smarty->assign('user_id', $user_id); From d4834198f5649729ae58b220ba2fce6e11734607 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 21 Dec 2018 14:56:58 +0000 Subject: [PATCH 0597/1848] Added what is it links explaining quota percent. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/user_add.tpl | 2 +- WEB-INF/templates/user_edit.tpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b1c606f4f..157422404 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.34.4672 | Copyright © Anuko | +  Anuko Time Tracker 1.18.34.4673 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/user_add.tpl b/WEB-INF/templates/user_add.tpl index 29218d866..ea4809f1f 100644 --- a/WEB-INF/templates/user_add.tpl +++ b/WEB-INF/templates/user_add.tpl @@ -81,7 +81,13 @@ function handleClientControl() { {$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00): {$forms.userForm.rate.control}
{$i18n.form.quota.quota} (%):{$forms.userForm.quota_percent.control}
 
{$i18n.label.projects}:{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00): {$forms.userForm.rate.control}
{$i18n.form.quota.quota} (%):{$forms.userForm.quota_percent.control}
 
{$i18n.label.projects}:
- - + {/if} {if $show_projects} diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index b1026f2c1..d7e7b54c8 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -118,7 +118,7 @@ function handleClientControl() { {if $show_quota} - + {/if} {if $show_projects} From fec361583dcdb716abd921ca19f68c9d6e98b9f0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 21 Dec 2018 15:31:47 +0000 Subject: [PATCH 0598/1848] Added quota percent on mobile user add page. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/user_add.tpl | 8 +++++++- mobile/user_add.php | 16 ++++++++++++++-- user_add.php | 2 +- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 157422404..637457139 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.34.4673 | Copyright © Anuko | +  Anuko Time Tracker 1.18.34.4674 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/user_add.tpl b/WEB-INF/templates/user_add.tpl index ea4809f1f..0398749cb 100644 --- a/WEB-INF/templates/user_add.tpl +++ b/WEB-INF/templates/user_add.tpl @@ -84,7 +84,7 @@ function handleClientControl() { {if $show_quota}
{$i18n.form.quota.quota} (%):{$forms.userForm.quota_percent.control}{$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
{$i18n.form.quota.quota} (%):{$forms.userForm.quota_percent.control}{$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
- -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_quota} + + + + +{/if} +{if $show_projects} diff --git a/mobile/user_add.php b/mobile/user_add.php index ab6f5e2da..3ffaa01a3 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -45,6 +45,7 @@ // The "limit" plugin is not required for normal operation of Time Tracker. @include('../plugins/limit/user_add.php'); +$show_quota = $user->isPluginEnabled('mq'); if ($user->isPluginEnabled('cl')) $clients = ttGroupHelper::getActiveClients(); @@ -60,6 +61,7 @@ $cl_role_id = $request->getParameter('role'); $cl_client_id = $request->getParameter('client'); $cl_rate = $request->getParameter('rate'); + $cl_quota_percent = $request->getParameter('quota_percent'); $cl_projects = $request->getParameter('projects'); if (is_array($cl_projects)) { foreach ($cl_projects as $p) { @@ -89,8 +91,14 @@ $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); +if ($show_quota) + $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); -$projects = ttGroupHelper::getActiveProjects(); +$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); +if ($show_projects) { + $projects = ttGroupHelper::getActiveProjects(); + if (count($projects) == 0) $show_projects = false; +} // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { @@ -140,6 +148,7 @@ function render(&$table, $value, $row, $column, $selected = false) { } if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); + if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('form.quota.quota')); if ($err->no()) { if (!ttUserHelper::getUserByLogin($cl_login)) { @@ -148,7 +157,8 @@ function render(&$table, $value, $row, $column, $selected = false) { 'login' => $cl_login, 'password' => $cl_password1, 'rate' => $cl_rate, - 'group_id' => $user->group_id, + 'quota_percent' => $cl_quota_percent, + 'group_id' => $user->getGroup(), 'role_id' => $cl_role_id, 'client_id' => $cl_client_id, 'projects' => $assigned_projects, @@ -167,6 +177,8 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('active_roles', $active_roles); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); +$smarty->assign('show_quota', $show_quota); +$smarty->assign('show_projects', $show_projects); $smarty->assign('title', $i18n->get('title.add_user')); $smarty->assign('content_page_name', 'mobile/user_add.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/user_add.php b/user_add.php index 6f1e02c11..afe0a846c 100644 --- a/user_add.php +++ b/user_add.php @@ -186,9 +186,9 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('active_roles', $active_roles); $smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); $smarty->assign('show_quota', $show_quota); $smarty->assign('show_projects', $show_projects); -$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); $smarty->assign('title', $i18n->get('title.add_user')); $smarty->assign('content_page_name', 'user_add.tpl'); $smarty->display('index.tpl'); From 55c33b542216912d3a3f05b5c9c90528eb768cbe Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 21 Dec 2018 15:59:43 +0000 Subject: [PATCH 0599/1848] Fixed mobile user add. --- WEB-INF/templates/footer.tpl | 2 +- mobile/user_add.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 637457139..17042163c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.34.4674 | Copyright © Anuko | +  Anuko Time Tracker 1.18.34.4675 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/user_add.tpl b/WEB-INF/templates/mobile/user_add.tpl index e1a053502..9fe22314c 100644 --- a/WEB-INF/templates/mobile/user_add.tpl +++ b/WEB-INF/templates/mobile/user_add.tpl @@ -81,7 +81,13 @@ function handleClientControl() { {$i18n.form.users.default_rate} (0{$user->decimal_mark}00): {$forms.userForm.rate.control}
{$i18n.form.quota.quota} (%):{$forms.userForm.quota_percent.control}
{$i18n.label.projects}: {$forms.userForm.projects.control}
-
 Anuko Time Tracker 1.18.34.4675 | Copyright © Anuko | +  Anuko Time Tracker 1.18.34.4676 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/user_add.php b/mobile/user_add.php index 3ffaa01a3..ce11ecc2d 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -159,6 +159,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'rate' => $cl_rate, 'quota_percent' => $cl_quota_percent, 'group_id' => $user->getGroup(), + 'org_id' => $user->org_id, 'role_id' => $cl_role_id, 'client_id' => $cl_client_id, 'projects' => $assigned_projects, From a4ecfaf39d301762cb6332da5d72978b60846092 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 21 Dec 2018 16:27:20 +0000 Subject: [PATCH 0600/1848] Added quota percent on mobile user edit page. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/user_edit.tpl | 8 +++++++- mobile/user_edit.php | 19 ++++++++++++++++--- user_edit.php | 4 ++-- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 17042163c..d68b7cb62 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_quota} + + + + +{/if} +{if $show_projects} diff --git a/mobile/user_edit.php b/mobile/user_edit.php index df184fcfb..d79a1f270 100644 --- a/mobile/user_edit.php +++ b/mobile/user_edit.php @@ -48,10 +48,15 @@ } // End of access checks. +$show_quota = $user->isPluginEnabled('mq'); if ($user->isPluginEnabled('cl')) $clients = ttGroupHelper::getActiveClients(); -$projects = ttGroupHelper::getActiveProjects(); +$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); +if ($show_projects) { + $projects = ttGroupHelper::getActiveProjects(); + if (count($projects) == 0) $show_projects = false; +} $assigned_projects = array(); if ($request->isPost()) { @@ -66,6 +71,7 @@ $cl_client_id = $request->getParameter('client'); $cl_status = $request->getParameter('status'); $cl_rate = $request->getParameter('rate'); + $cl_quota_percent = $request->getParameter('quota_percent'); $cl_projects = $request->getParameter('projects'); if (is_array($cl_projects)) { foreach ($cl_projects as $p) { @@ -82,7 +88,8 @@ $cl_name = $user_details['name']; $cl_login = $user_details['login']; $cl_email = $user_details['email']; - $cl_rate = str_replace('.', $user->decimal_mark, $user_details['rate']); + $cl_rate = str_replace('.', $user->getDecimalMark(), $user_details['rate']); + $cl_quota_percent = str_replace('.', $user->getDecimalMark(), $user_details['quota_percent']); $cl_role_id = $user_details['role_id']; $cl_client_id = $user_details['client_id']; $cl_status = $user_details['status']; @@ -110,6 +117,8 @@ $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); +if ($show_quota) + $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { @@ -162,7 +171,8 @@ function render(&$table, $value, $row, $column, $selected = false) { } if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - + if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('form.quota.quota')); + if ($err->no()) { $existing_user = ttUserHelper::getUserByLogin($cl_login); if (!$existing_user || ($user_id == $existing_user['id'])) { @@ -174,6 +184,7 @@ function render(&$table, $value, $row, $column, $selected = false) { 'email' => $cl_email, 'status' => $cl_status, 'rate' => $cl_rate, + 'quota_percent' => $cl_quota_percent, 'projects' => $assigned_projects); if (in_array('manage_users', $user->rights)) { $fields['role_id'] = $cl_role_id; @@ -226,6 +237,8 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('active_roles', $active_roles); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); +$smarty->assign('show_quota', $show_quota); +$smarty->assign('show_projects', $show_projects); $smarty->assign('user_id', $user_id); $smarty->assign('title', $i18n->get('title.edit_user')); $smarty->assign('content_page_name', 'mobile/user_edit.tpl'); diff --git a/user_edit.php b/user_edit.php index c3910db3e..af6180a3b 100644 --- a/user_edit.php +++ b/user_edit.php @@ -239,10 +239,10 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('active_roles', $active_roles); $smarty->assign('can_swap', $can_swap); -$smarty->assign('show_quota', $show_quota); -$smarty->assign('show_projects', $show_projects); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); +$smarty->assign('show_quota', $show_quota); +$smarty->assign('show_projects', $show_projects); $smarty->assign('user_id', $user_id); $smarty->assign('title', $i18n->get('title.edit_user')); $smarty->assign('content_page_name', 'user_edit.tpl'); From 1567369ac1fb744b704cacbe77542f55e410d61b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 21 Dec 2018 17:08:57 +0000 Subject: [PATCH 0601/1848] A bit of refactoring in translation files. --- WEB-INF/resources/ca.lang.php | 3 ++- WEB-INF/resources/cs.lang.php | 3 ++- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/en.lang.php | 2 +- WEB-INF/resources/es.lang.php | 3 ++- WEB-INF/resources/et.lang.php | 3 ++- WEB-INF/resources/fa.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 3 ++- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 3 ++- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 3 ++- WEB-INF/resources/ko.lang.php | 3 ++- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 3 ++- WEB-INF/resources/pt-br.lang.php | 3 ++- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 3 ++- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 3 ++- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 3 ++- WEB-INF/resources/sv.lang.php | 2 +- WEB-INF/resources/tr.lang.php | 3 ++- WEB-INF/resources/zh-cn.lang.php | 2 +- WEB-INF/resources/zh-tw.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/user_add.tpl | 2 +- WEB-INF/templates/mobile/user_edit.tpl | 2 +- WEB-INF/templates/quotas.tpl | 2 +- WEB-INF/templates/user_add.tpl | 2 +- WEB-INF/templates/user_edit.tpl | 2 +- mobile/user_add.php | 2 +- mobile/user_edit.php | 2 +- user_add.php | 2 +- user_edit.php | 2 +- 40 files changed, 54 insertions(+), 40 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 68c6e6a96..549241b06 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -258,6 +258,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Només totals', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -552,7 +554,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index bcda74010..d66af403e 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -268,6 +268,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Pouze součty', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -566,7 +568,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 45cf377ee..061b1fb61 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -243,6 +243,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Kun Total', +'label.quota' => 'Kvota', // Form titles. 'title.error' => 'Fejl', @@ -514,7 +515,6 @@ // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'År', 'form.quota.month' => 'Måned', -'form.quota.quota' => 'Kvota', 'form.quota.workday_hours' => 'Timer på en arbejdsdag', 'form.quota.hint' => 'Hvis værdierne er tomme, beregnes kvoter automatisk baseret på arbejdsdage og helligdage.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 3775315ca..82599a628 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -231,6 +231,7 @@ 'label.work_units' => 'Arbeitseinheiten', 'label.work_units_short' => 'Einheiten', 'label.totals_only' => 'Nur Gesamtstunden', +'label.quota' => 'Quote', // Form titles. 'title.error' => 'Fehler', @@ -485,7 +486,6 @@ // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Jahr', 'form.quota.month' => 'Monat', -'form.quota.quota' => 'Quote', 'form.quota.workday_hours' => 'Arbeitsstunden pro Tag', 'form.quota.hint' => 'Wenn leergelassen wird die Quote automatisch berechnet (Basierend auf Arbeitsstunden pro Tag und Feiertagen)', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index fee9fdbf0..5d2acd565 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -225,6 +225,7 @@ 'label.work_units' => 'Work units', 'label.work_units_short' => 'Units', 'label.totals_only' => 'Totals only', +'label.quota' => 'Quota', // Form titles. 'title.error' => 'Error', @@ -482,7 +483,6 @@ // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Year', 'form.quota.month' => 'Month', -'form.quota.quota' => 'Quota', 'form.quota.workday_hours' => 'Hours in work day', 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index aa6425547..684d60a35 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -261,6 +261,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Solo totales', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. // TODO: Translate the following. @@ -567,7 +569,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index a61a13056..97b92fc73 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -265,6 +265,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Ainult summad', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -563,7 +565,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 86f3930de..4e298f3b8 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -254,6 +254,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', +// 'label.quota' => 'Quota', // Form titles. 'title.error' => 'خطا', @@ -538,7 +539,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 4687e6f53..7322bf90e 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -247,6 +247,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Vain yhteissummat', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. 'title.error' => 'Virhe', @@ -522,7 +524,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index ad77095c2..7584f9c6e 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -241,6 +241,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Totaux uniquement', +'label.quota' => 'Quota', // Form titles. 'title.error' => 'Erreur', @@ -510,7 +511,6 @@ // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Année', 'form.quota.month' => 'Mois', -'form.quota.quota' => 'Quota', 'form.quota.workday_hours' => 'Heures journée de travail', 'form.quota.hint' => 'Si les valeurs sont vides, les quotas sont calculés automatiquement selon les heures des journées de travail et des congés.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index f4859df7f..c354b28a6 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -234,6 +234,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Σύνολα μόνο', +'label.quota' => 'Ποσοστό', // Form titles. 'title.error' => 'Σφάλμα', @@ -495,7 +496,6 @@ // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Χρόνος', 'form.quota.month' => 'Μήνας', -'form.quota.quota' => 'Ποσοστό', 'form.quota.workday_hours' => 'Ώρες ανά ημέρα εργασίας', 'form.quota.hint' => 'Εάν οι τιμές είναι κενές, οι ποσοστώσεις υπολογίζονται αυτόματα με βάση τις ώρες της εργάσιμης ημέρας και τις αργίες.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index d7abe002d..d81832cce 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -264,6 +264,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'labl.totals_only' => 'סיכומים בלבד', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. 'title.error' => 'שגיאה', @@ -546,7 +548,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 0e0e4522f..2097f9908 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -263,6 +263,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', +// 'label.quota' => 'Quota', // Form titles. // TODO: Translate the following. @@ -557,7 +558,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ce1ab88cc..77581731a 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -238,6 +238,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Solo i totali', +'label.quota' => 'Quota', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -510,7 +511,6 @@ // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Anno', 'form.quota.month' => 'Mese', -'form.quota.quota' => 'Quota', 'form.quota.workday_hours' => 'Ore lavorative in un giorno', 'form.quota.hint' => 'Se i valori sono vuoti, le quote vengono calcolate automaticamente basandosi su ore giornaliere e vacanze.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 431915fd8..3cb26d69c 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -268,6 +268,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => '全体だけ', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. // TODO: Translate the following. @@ -560,7 +562,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 7ac2dd4ef..dc5a1a415 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -268,6 +268,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => '오직 전체만', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. // TODO: Translate the following. @@ -558,7 +560,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 3cad307be..99cab30c4 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -228,6 +228,7 @@ 'label.work_units' => 'Werk eenheid', 'label.work_units_short' => 'Eenheid', 'label.totals_only' => 'Alleen totalen', +'label.quota' => 'Quota', // Form titles. 'title.error' => 'Fout', @@ -486,7 +487,6 @@ // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Jaar', 'form.quota.month' => 'Maand', -'form.quota.quota' => 'Quota', 'form.quota.workday_hours' => 'Werkuren per dag', 'form.quota.hint' => 'Als de velden leeg worden gelaten, dan zullen de doelen worden berekend op bassis van het aantal werkuren per dag en vakantiedagen.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index d7847c153..e3273ca07 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -265,6 +265,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', +// 'label.quota' => 'Quota' // Form titles. // TODO: Translate the following. @@ -556,7 +557,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index a36b06c14..461e65611 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -248,6 +248,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Tylko sumy', +// TODO: translate the following. +// 'label.quota' => 'Quota' // Form titles. 'title.error' => 'Błąd', @@ -524,7 +526,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 7bfb95529..241f4544b 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -245,6 +245,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Somente totais', +// TODO: translate the following. +// 'label.quota' => 'Quota' // Form titles. 'title.error' => 'Erro', @@ -519,7 +521,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index bdb1c3753..dad9124a4 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -254,6 +254,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', +// 'label.quota' => 'Quota' // Form titles. // TODO: Translate the following. @@ -540,7 +541,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index e1c24e2de..c3a6077ba 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -265,6 +265,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Numai totaluri', +// TODO: translate the following. +// 'label.quota' => 'Quota' // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -561,7 +563,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 5710cbb36..727ff51ee 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -224,6 +224,7 @@ 'label.work_units' => 'Единицы работы', 'label.work_units_short' => 'Единицы', 'label.totals_only' => 'Только итоги', +'label.quota' => 'Квота', // Form titles. 'title.error' => 'Ошибка', @@ -479,7 +480,6 @@ // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'Год', 'form.quota.month' => 'Месяц', -'form.quota.quota' => 'Квота', 'form.quota.workday_hours' => 'Количество часов в рабочем дне', 'form.quota.hint' => 'При пустых значениях квоты автоматически определяются из длительности рабочего дня и праздников.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 0097e09b7..1a87dd808 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -254,6 +254,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Iba celkové', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. 'title.error' => 'Chyba', @@ -537,7 +539,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index dfc9fd32a..5b036edd6 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -249,6 +249,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', +// 'label.quota' => 'Quota', // Form titles. // TODO: Translate the following. @@ -536,7 +537,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 1c59de37e..a8d2bf8f4 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -246,6 +246,8 @@ // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', 'label.totals_only' => 'Samo zbirno', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. 'title.error' => 'Greška', @@ -522,7 +524,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in a work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index a20aed921..e009c0c57 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -242,6 +242,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Visa endast summeringar', +'label.quota' => 'Kvot', // Rubriker för formulär 'title.error' => 'Fel', @@ -518,7 +519,6 @@ // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. 'form.quota.year' => 'År', 'form.quota.month' => 'Månad', -'form.quota.quota' => 'Kvot', 'form.quota.workday_hours' => 'Arbetstimmar per dag', 'form.quota.hint' => 'Om fälten lämnas tomma räknas kvoterna automatiskt ut baserat på arbetstimmar per dag och helgdagar.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 771ccb904..48359a941 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -272,6 +272,8 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Sadece toplamlar', +// TODO: translate the following. +// 'label.quota' => 'Quota', // Form titles. // Form titles. @@ -574,7 +576,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 190cf5a48..e753c32c3 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -256,6 +256,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', +// 'label.quota' => 'Quota', // Form titles. // TODO: Translate the following. @@ -543,7 +544,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 7b1bcdba0..b9951b1ce 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -264,6 +264,7 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', +// 'label.quota' => 'Quota', // Form titles. // TODO: Translate the following. @@ -552,7 +553,6 @@ // TODO: translate the following. // 'form.quota.year' => 'Year', // 'form.quota.month' => 'Month', -// 'form.quota.quota' => 'Quota', // 'form.quota.workday_hours' => 'Hours in work day', // 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d68b7cb62..aaf04fa05 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.34.4676 | Copyright © Anuko | +  Anuko Time Tracker 1.18.34.4677 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/user_edit.tpl b/WEB-INF/templates/mobile/user_edit.tpl index ecbff5993..6c5e12e7c 100644 --- a/WEB-INF/templates/mobile/user_edit.tpl +++ b/WEB-INF/templates/mobile/user_edit.tpl @@ -109,7 +109,13 @@ function handleClientControl() { {$i18n.form.users.default_rate} (0{$user->decimal_mark}00): {$forms.userForm.rate.control}
{$i18n.form.quota.quota} (%):{$forms.userForm.quota_percent.control}
{$i18n.label.projects}: {$forms.userForm.projects.control}
- {if $show_quota} - + {/if} diff --git a/WEB-INF/templates/mobile/user_edit.tpl b/WEB-INF/templates/mobile/user_edit.tpl index 6c5e12e7c..0d7f47e6c 100644 --- a/WEB-INF/templates/mobile/user_edit.tpl +++ b/WEB-INF/templates/mobile/user_edit.tpl @@ -111,7 +111,7 @@ function handleClientControl() { {if $show_quota} - + {/if} diff --git a/WEB-INF/templates/quotas.tpl b/WEB-INF/templates/quotas.tpl index 67707d38a..1dba4f239 100644 --- a/WEB-INF/templates/quotas.tpl +++ b/WEB-INF/templates/quotas.tpl @@ -28,7 +28,7 @@
 Anuko Time Tracker 1.18.34.4677 | Copyright © Anuko | +  Anuko Time Tracker 1.18.34.4678 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/user_add.tpl b/WEB-INF/templates/mobile/user_add.tpl index 9fe22314c..71901fb05 100644 --- a/WEB-INF/templates/mobile/user_add.tpl +++ b/WEB-INF/templates/mobile/user_add.tpl @@ -83,7 +83,7 @@ function handleClientControl() {
{$i18n.form.quota.quota} (%):{$i18n.label.quota} (%): {$forms.userForm.quota_percent.control}
{$i18n.form.quota.quota} (%):{$i18n.label.quota} (%): {$forms.userForm.quota_percent.control}
- + {foreach $months as $month} diff --git a/WEB-INF/templates/user_add.tpl b/WEB-INF/templates/user_add.tpl index 0398749cb..39575db0c 100644 --- a/WEB-INF/templates/user_add.tpl +++ b/WEB-INF/templates/user_add.tpl @@ -83,7 +83,7 @@ function handleClientControl() { {if $show_quota} - + {/if} diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index d7e7b54c8..7475c6efb 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -117,7 +117,7 @@ function handleClientControl() { {if $show_quota} - + {/if} diff --git a/mobile/user_add.php b/mobile/user_add.php index ce11ecc2d..b1d155aa0 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -148,7 +148,7 @@ function render(&$table, $value, $row, $column, $selected = false) { } if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('form.quota.quota')); + if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); if ($err->no()) { if (!ttUserHelper::getUserByLogin($cl_login)) { diff --git a/mobile/user_edit.php b/mobile/user_edit.php index d79a1f270..1e0845e1a 100644 --- a/mobile/user_edit.php +++ b/mobile/user_edit.php @@ -171,7 +171,7 @@ function render(&$table, $value, $row, $column, $selected = false) { } if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('form.quota.quota')); + if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); if ($err->no()) { $existing_user = ttUserHelper::getUserByLogin($cl_login); diff --git a/user_add.php b/user_add.php index afe0a846c..a99951912 100644 --- a/user_add.php +++ b/user_add.php @@ -151,7 +151,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Require selection of a client for a client role. if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('form.quota.quota')); + if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); if ($err->no()) { if (!ttUserHelper::getUserByLogin($cl_login)) { diff --git a/user_edit.php b/user_edit.php index af6180a3b..582452d9a 100644 --- a/user_edit.php +++ b/user_edit.php @@ -173,7 +173,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Require selection of a client for a client role. if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('form.quota.quota')); + if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); if ($err->no()) { $existing_user = ttUserHelper::getUserByLogin($cl_login); From 30634c0b3869d459552df1da06ec264fb1e6b086 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 21 Dec 2018 22:09:59 +0000 Subject: [PATCH 0602/1848] Added quota column on the users page. --- WEB-INF/lib/common.lib.php | 8 ++++++++ WEB-INF/lib/ttUser.class.php | 21 ++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/users.tpl | 20 ++++++++++++++++---- users.php | 1 + 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 0e9ff9e49..f483b3d4c 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -391,6 +391,14 @@ function ttStartsWith($string, $startString) return (substr($string, 0, $len) === $startString); } +// ttEndsWith functions checks if a string ends with a given substring. +function ttEndsWith($string, $endString) +{ + $len = strlen($endString); + if ($len == 0) return true; + return (substr($string, -$len) === $endString); +} + // ttDateToUserFormat converts a date from database format to user format. function ttDateToUserFormat($date) { diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index f163e5814..73ec7a1e9 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -395,7 +395,16 @@ function getUsers($options) { $includeSelf = isset($options['include_self']); $select_part = 'select u.id, u.group_id, u.name'; - if (isset($options['include_login'])) $select_part .= ', u.login'; + if (isset($options['include_login'])) { + $select_part .= ', u.login'; + // Piggy-back on include_login to see if we must also include quota_percent. + $include_quota = $this->isPluginEnabled('mq'); + if ($include_quota) { + $decimal_mark = $this->getDecimalMark(); + $replaceDecimalMark = ('.' != $decimal_mark); + $select_part .= ', u.quota_percent'; + } + } if (!isset($options['include_clients'])) $select_part .= ', r.rights'; if (isset($options['include_role'])) $select_part .= ', r.name as role_name, r.rank'; @@ -430,6 +439,16 @@ function getUsers($options) { if ($isClient) continue; // Skip adding clients. } + if ($include_quota) { + $quota = $val['quota_percent']; + if (null == $quota) + $quota = '100'; // Null means 100%. Perhaps enforce not NULLs in db and eliminate this check. + elseif (ttEndsWith($quota, '.00')) + $quota = substr($quota, 0, strlen($quota)-3); // Trim trailing ".00"; + elseif ($replaceDecimalMark) + $quota = str_replace('.', $decimal_mark, $quota); + $val['quota_percent'] = $quota.'%'; + } $user_list[] = $val; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index aaf04fa05..19832de86 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.quota.month}{$i18n.form.quota.quota}{$i18n.label.quota}
{$i18n.form.quota.quota} (%):{$i18n.label.quota} (%): {$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
{$i18n.form.quota.quota} (%):{$i18n.label.quota} (%): {$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
- - - + {if $show_quota} + + {/if} + + {if $active_users} {foreach $active_users as $u} @@ -28,6 +31,9 @@ + {if $show_quota} + + {/if} {if $u.group_id != $user->group_id || $u.rank < $user->rank || ($u.rank == $user->rank && $u.id == $user->id)} {if $u.id != $user->id}{else}{/if} @@ -55,14 +61,20 @@ - - + {if $show_quota} + + {/if} + + {foreach $inactive_users as $u} + {if $show_quota} + + {/if} {if $u.group_id != $user->group_id || $u.rank < $user->rank} diff --git a/users.php b/users.php index fd9e7593f..aa7f44402 100644 --- a/users.php +++ b/users.php @@ -63,6 +63,7 @@ $smarty->assign('active_users', $active_users); $smarty->assign('inactive_users', $inactive_users); +$smarty->assign('show_quota', $user->isPluginEnabled('mq')); $smarty->assign('title', $i18n->get('title.users')); $smarty->assign('content_page_name', 'users.tpl'); $smarty->display('index.tpl'); From da39950fb8192f48ad40f6777ff3c5cd52459bcd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 22 Dec 2018 14:58:30 +0000 Subject: [PATCH 0603/1848] Introduced balance output for monthly quotas. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 3 +++ WEB-INF/resources/de.lang.php | 3 +++ WEB-INF/resources/en.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 3 +++ WEB-INF/resources/gr.lang.php | 3 +++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 3 +++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 3 +++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 3 +++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time.tpl | 12 ++++++++++-- plugins/MonthlyQuota.class.php | 19 +++++++++++++++++++ time.php | 7 ++++++- 34 files changed, 103 insertions(+), 4 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 549241b06..b4d869930 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -405,6 +405,8 @@ // 'form.time.uncompleted' => 'Uncompleted', // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Aquest historial s\\\'ha guardat únicament amb l\\\'hora d\\\'inici. Aixó no és un error.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d66af403e..d12be155e 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -415,6 +415,8 @@ // 'form.time.uncompleted' => 'Uncompleted', // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Záznam byl uložen pouze s časem zahájení. Není to chyba.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 061b1fb61..c49745130 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -376,6 +376,9 @@ 'form.time.uncompleted' => 'Uafsluttet', 'form.time.remaining_quota' => 'Resterende kvota', 'form.time.over_quota' => 'Over kvota', +// TODO: translate the following. +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Denne post blev kun gemt med starttidspunkt. Det er ikke en fejl.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 82599a628..eab807e85 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -357,6 +357,9 @@ 'form.time.uncompleted' => 'Unvollständig', 'form.time.remaining_quota' => 'Verbleibende Quote', 'form.time.over_quota' => 'Über der Quote', +// TODO: translate the following. +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Dieser Eintrag wurde ohne Startzeit gespeichert. Dies ist kein Fehler.', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 5d2acd565..aadf6f5ac 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -355,6 +355,8 @@ 'form.time.uncompleted' => 'Uncompleted', 'form.time.remaining_quota' => 'Remaining quota', 'form.time.over_quota' => 'Over quota', +'form.time.remaining_balance' => 'Remaining balance', +'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'This record was saved with only start time. It is not an error.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 684d60a35..cc4fe0347 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -418,6 +418,8 @@ // 'form.time.uncompleted' => 'Uncompleted', // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Este historial fue guardado solamente con la hora de Inicio. Esto no es un error.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 97b92fc73..a29929afd 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -414,6 +414,8 @@ // 'form.time.uncompleted' => 'Uncompleted', // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Kanne salvestati ainult alguse ajaga. See ei ole viga.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 4e298f3b8..f1a37b4f5 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -398,6 +398,8 @@ // TODO: translate the following. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). // TODO: translate form.time_edit.uncompleted. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 7322bf90e..065f71c1c 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -384,6 +384,8 @@ // TODO: translate the following. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Vain aloitusaika tallennettiin tietueeseen. Kyseessä ei ole virhe.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 7584f9c6e..4c6d76749 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -373,6 +373,9 @@ 'form.time.uncompleted' => 'Non terminée', 'form.time.remaining_quota' => 'Quota restant', 'form.time.over_quota' => 'Quota dépassé', +// TODO: translate the following. +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Cet enregistrement a été sauvegardé avec une heure de début seulement. Il ne s\\\'agit pas d\\\'une erreur.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index c354b28a6..6be29a04b 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -365,6 +365,9 @@ 'form.time.uncompleted' => 'Μη ολοκληρωμένο', 'form.time.remaining_quota' => 'Υπολειπόμενη ποσόστωση', 'form.time.over_quota' => 'Πάνω από το όριο', +// TODO: translate the following. +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Η καταχώρηση αποθηκεύτηκε μόνο με ώρα έναρξης. Δεν είναι λάθος.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index d81832cce..d27edb8c7 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -405,6 +405,8 @@ // TODO: translate the following. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'רישום זה נשמר עם שעת התחלה בלבד. זאת איננה טעות.', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 2097f9908..27642b478 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -407,6 +407,8 @@ // 'form.time.uncompleted' => 'Uncompleted', // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 77581731a..8f35a78ec 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -378,6 +378,9 @@ 'form.time.uncompleted' => 'Incompleti', 'form.time.remaining_quota' => 'Quota rimanente', 'form.time.over_quota' => 'Sopra quota', +// TODO: translate the following. +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Questo record è stato salvato con la sola ora di inzio attività. Non è un errore.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 3cb26d69c..ea158793a 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -414,6 +414,8 @@ // TODO: translate the following. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'このレコードは開始時間だけで保存されました。これはエラーではありません。', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index dc5a1a415..27cbe6692 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -413,6 +413,8 @@ // TODO: translate the following. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => '이 기록은 시작 시간으로만 저장되었습니다. 이것은 오류는 아닙니다.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 99cab30c4..b0ada311d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -358,6 +358,9 @@ 'form.time.uncompleted' => 'Onvolledig', 'form.time.remaining_quota' => 'Te werken uren voor de doelstelling', 'form.time.over_quota' => 'Meer gewerkte uren dan de doelstelling', +// TODO: translate the following. +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Dit tijdrecord is opgeslagen met alleen een starttijd. Dit is geen fout.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index e3273ca07..34f4f6d30 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -410,6 +410,8 @@ // TODO: translate the following. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Denne oppføringen ble lagret kun med starttid. Det er ikke en feil.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 461e65611..a9220c4eb 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -386,6 +386,8 @@ // TODO: translate the following. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Ten wpis ma określony jedynie czas rozpoczęcia. To nie jest błąd.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 241f4544b..ee699e11b 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -381,6 +381,8 @@ // TODO: translate the following. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Eesta entrada foi salva somente com hora de início. Não é um erro.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index dad9124a4..8a96bc882 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -392,6 +392,8 @@ // 'form.time.uncompleted' => 'Uncompleted', // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index c3a6077ba..4f027f6b0 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -415,6 +415,8 @@ // 'form.time.uncompleted' => 'Uncompleted', // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Aceasta inregistrare a fost salvata numei cu timpul de inceput. Nu este o eroare.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 727ff51ee..466f7cd1e 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -352,6 +352,8 @@ 'form.time.uncompleted' => 'Не завершено', 'form.time.remaining_quota' => 'Доступная квота', 'form.time.over_quota' => 'Превышение квоты', +'form.time.remaining_balance' => 'Доступный баланс', +'form.time.over_balance' => 'Превышение баланса', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Эта запись сохранена только со временем начала. Это не ошибка.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 1a87dd808..0077e713d 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -396,6 +396,8 @@ // TODO: translate the folllowing. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Tento záznam bol uložený iba s časom začiatku. Nie je to chyba.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 5b036edd6..9be563c42 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -388,6 +388,8 @@ // 'form.time.uncompleted' => 'Uncompleted', // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index a8d2bf8f4..270984d45 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -384,6 +384,8 @@ // TODO: translate the folllowing. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Izmena vremenske forme. Pogledajte primer na https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Ovaj zapis je sačuvan sa početnim vremenom i nije greška.', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index e009c0c57..815ad80e1 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -380,6 +380,9 @@ 'form.time.uncompleted' => 'Oavslutad', 'form.time.remaining_quota' => 'Återstående kvot', 'form.time.over_quota' => 'Kvoten överstigen', +// TODO: translate the following. +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Den här tidsregistreringen har sparats utan sluttid. Fyll i en sluttid och klicka på Spara för att avsluta.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 48359a941..720475be6 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -425,6 +425,8 @@ // 'form.time.uncompleted' => 'Uncompleted', // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Bu kayıt sadece başlangıç zamanıyla silindi. Bu hata değildir.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index e753c32c3..aa9e7dea8 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -397,6 +397,8 @@ // TODO: translate the following. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => '该记录只保存了开始时间。这不是错误。', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index b9951b1ce..7346c9ad1 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -406,6 +406,8 @@ // TODO: translate the following. // 'form.time.remaining_quota' => 'Remaining quota', // 'form.time.over_quota' => 'Over quota', +// 'form.time.remaining_balance' => 'Remaining balance', +// 'form.time.over_balance' => 'Over balance', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => '該記錄只保存了開始時間。這不是錯誤。', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 19832de86..44b5b1800 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.34.4678 | Copyright © Anuko | +  Anuko Time Tracker 1.18.34.4679 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/users.tpl b/WEB-INF/templates/users.tpl index 236475c19..d3fadad93 100644 --- a/WEB-INF/templates/users.tpl +++ b/WEB-INF/templates/users.tpl @@ -14,8 +14,11 @@ {$i18n.label.person_name} {$i18n.label.login} {$i18n.form.users.role}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.quota}{$i18n.label.edit}{$i18n.label.delete}
{$u.login|escape} {$u.role_name|escape}{$u.quota_percent}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.person_name} {$i18n.label.login} {$i18n.form.users.role}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.quota}{$i18n.label.edit}{$i18n.label.delete}
{$u.name|escape} {$u.login|escape} {$u.role_name|escape}{$u.quota_percent}{$i18n.label.edit} {$i18n.label.delete}
-
 Anuko Time Tracker 1.18.34.4679 | Copyright © Anuko | +  Anuko Time Tracker 1.18.35.4680 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index 76338706d..7a360800b 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -149,7 +149,7 @@
-{if $time_records} + @@ -158,6 +158,14 @@ {if $user->isPluginEnabled('mq')} + {if $over_balance} + + {else} + + {/if} + + + {if $over_quota} {else} @@ -166,5 +174,5 @@ {/if}
{$i18n.label.week_total}: {$week_total}
{$i18n.label.month_total}: {$month_total}{$i18n.form.time.over_balance}: {$balance_remaining}{$i18n.form.time.remaining_balance}: {$balance_remaining}
{$i18n.form.time.over_quota}: {$quota_remaining}
-{/if} + {$forms.timeRecordForm.close} diff --git a/plugins/MonthlyQuota.class.php b/plugins/MonthlyQuota.class.php index a1c1b5d09..21854672b 100644 --- a/plugins/MonthlyQuota.class.php +++ b/plugins/MonthlyQuota.class.php @@ -94,6 +94,25 @@ public function getUserQuota($year, $month) { return $userMinutes; } + // getUserQuotaFrom1st - obtains a quota for user + // from 1st of the month up to and inclusive of $selected_date. + public function getUserQuotaFrom1st($selected_date) { + // TODO: we may need a better algorithm here. Review. + $monthQuotaMinutes = $this->getUserQuota($selected_date->mYear, $selected_date->mMonth); + $workdaysInMonth = $this->getNumWorkdays($selected_date->mMonth, $selected_date->mYear); + + // Iterate from 1st up to selected date. + $workdaysFrom1st = 0; + for ($i = 1; $i <= $selected_date->mDate; $i++) { + $date = "$selected_date->mYear-$selected_date->mMonth-$i"; + if (!ttTimeHelper::isWeekend($date) && !ttTimeHelper::isHoliday($date)) { + $workdaysFrom1st++; + } + } + $quotaMinutesFrom1st = (int) ($monthQuotaMinutes * $workdaysFrom1st / $workdaysInMonth); + return $quotaMinutesFrom1st; + } + // getMany - returns an array of quotas for a given year for group. private function getMany($year){ $sql = "select month, minutes from tt_monthly_quotas". diff --git a/time.php b/time.php index ac6b69b5f..8dbffecfb 100644 --- a/time.php +++ b/time.php @@ -86,10 +86,15 @@ require_once('plugins/MonthlyQuota.class.php'); $quota = new MonthlyQuota(); $month_quota_minutes = $quota->getUserQuota($selected_date->mYear, $selected_date->mMonth); + $quota_minutes_from_1st = $quota->getUserQuotaFrom1st($selected_date); $month_total = ttTimeHelper::getTimeForMonth($selected_date); - $minutes_left = $month_quota_minutes - ttTimeHelper::toMinutes($month_total); + $month_total_minutes = ttTimeHelper::toMinutes($month_total); + $balance_left = $quota_minutes_from_1st - $month_total_minutes; + $minutes_left = $month_quota_minutes - $month_total_minutes; $smarty->assign('month_total', $month_total); + $smarty->assign('over_balance', $balance_left < 0); + $smarty->assign('balance_remaining', ttTimeHelper::toAbsDuration($balance_left)); $smarty->assign('over_quota', $minutes_left < 0); $smarty->assign('quota_remaining', ttTimeHelper::toAbsDuration($minutes_left)); } From 1c962161585180f8a9f963d05a2a87b78a5a37a5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 22 Dec 2018 15:24:19 +0000 Subject: [PATCH 0604/1848] Added quota output on time.php. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time.tpl | 2 +- time.php | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 44b5b1800..e9a9414d3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + {if $over_quota} {else} diff --git a/time.php b/time.php index 8dbffecfb..7252f476f 100644 --- a/time.php +++ b/time.php @@ -93,6 +93,7 @@ $minutes_left = $month_quota_minutes - $month_total_minutes; $smarty->assign('month_total', $month_total); + $smarty->assign('month_quota', ttTimeHelper::toAbsDuration($month_quota_minutes)); $smarty->assign('over_balance', $balance_left < 0); $smarty->assign('balance_remaining', ttTimeHelper::toAbsDuration($balance_left)); $smarty->assign('over_quota', $minutes_left < 0); From 32acd0caf0385a9fb7014af70d1a0ad438191dd7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 22 Dec 2018 15:35:25 +0000 Subject: [PATCH 0605/1848] Made quota_percent not null and default to 100 in db. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e9a9414d3..3246cac22 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.35.4680 | Copyright © Anuko | +  Anuko Time Tracker 1.18.35.4681 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index 7a360800b..bf28c5091 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -165,7 +165,7 @@ {/if}
{$i18n.label.quota}: {$month_quota}{$i18n.form.time.over_quota}: {$quota_remaining}
- - - + +
 Anuko Time Tracker 1.18.35.4681 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4682 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index ea177e978..74d566cc7 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -957,7 +957,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11834"]) { + if ($_POST["convert11797to11836"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1042,6 +1042,8 @@ function ttExecute($sql) { ttExecute("update `tt_client_project_binds` cpb inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.26') inner join `tt_clients` c on c.id = cpb.client_id set cpb.group_id = c.group_id, cpb.org_id = c.org_id where cpb.org_id is null"); ttExecute("ALTER TABLE `tt_users` ADD COLUMN `quota_percent` float(6,2) default NULL after `rate`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.34', modified = now() where param_name = 'version_db' and param_value = '1.18.26'"); + ttExecute("update `tt_users` u inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.34') set u.quota_percent = 100.00 where u.quota_percent is null"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.36', modified = now() where param_name = 'version_db' and param_value = '1.18.34'"); } if ($_POST["cleanup"]) { @@ -1089,7 +1091,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.34) + Create database structure (v1.18.36)
(applies only to new installations, do not execute when updating)
@@ -1134,8 +1136,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.34)Update database structure (v1.17.97 to v1.18.36)
diff --git a/mysql.sql b/mysql.sql index fb2ebe174..5dd41e061 100644 --- a/mysql.sql +++ b/mysql.sql @@ -91,7 +91,7 @@ CREATE TABLE `tt_users` ( `role_id` int(11) default NULL, # role id `client_id` int(11) default NULL, # client id for "client" user role `rate` float(6,2) NOT NULL default '0.00', # default hourly rate - `quota_percent` float(6,2) default NULL, # percent of time quota + `quota_percent` float(6,2) NOT NULL default '100.00', # percent of time quota `email` varchar(100) default NULL, # user email `created` datetime default NULL, # creation timestamp `created_ip` varchar(45) default NULL, # creator ip @@ -489,4 +489,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.34', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.36', now()); # TODO: change when structure changes. From dff61baa6b8f972c0a74119258b81e6884a9191f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 22 Dec 2018 15:56:01 +0000 Subject: [PATCH 0606/1848] Simplified ttUser::getUsers a bit. --- WEB-INF/lib/ttUser.class.php | 4 +--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 73ec7a1e9..1bfd6f440 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -441,9 +441,7 @@ function getUsers($options) { } if ($include_quota) { $quota = $val['quota_percent']; - if (null == $quota) - $quota = '100'; // Null means 100%. Perhaps enforce not NULLs in db and eliminate this check. - elseif (ttEndsWith($quota, '.00')) + if (ttEndsWith($quota, '.00')) $quota = substr($quota, 0, strlen($quota)-3); // Trim trailing ".00"; elseif ($replaceDecimalMark) $quota = str_replace('.', $decimal_mark, $quota); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3246cac22..91370d82c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4682 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4683 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From bd631018a913ebc4ecce9f9ded7c2d2e85482b5b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 22 Dec 2018 16:19:06 +0000 Subject: [PATCH 0607/1848] Fixed users.php for uncompleted indicators and monthly quotas situation. --- WEB-INF/templates/footer.tpl | 2 +- mobile/users.php | 4 ++-- users.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 91370d82c..83eb9084d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4683 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4684 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/users.php b/mobile/users.php index d6d08457a..d51cafcab 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -56,8 +56,8 @@ $uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); if ($uncompleted_indicators) { // Check each active user if they have an uncompleted time entry. - foreach ($active_users as $key => $user) { - $active_users[$key]['has_uncompleted_entry'] = (bool) ttTimeHelper::getUncompleted($user['id']); + foreach ($active_users as $key => $active_user) { + $active_users[$key]['has_uncompleted_entry'] = (bool) ttTimeHelper::getUncompleted($active_user['id']); } $smarty->assign('uncompleted_indicators', true); } diff --git a/users.php b/users.php index aa7f44402..2fbcb5d20 100644 --- a/users.php +++ b/users.php @@ -55,8 +55,8 @@ $uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); if ($uncompleted_indicators) { // Check each active user if they have an uncompleted time entry. - foreach ($active_users as $key => $user) { - $active_users[$key]['has_uncompleted_entry'] = (bool) ttTimeHelper::getUncompleted($user['id']); + foreach ($active_users as $key => $active_user) { + $active_users[$key]['has_uncompleted_entry'] = (bool) ttTimeHelper::getUncompleted($active_user['id']); } $smarty->assign('uncompleted_indicators', true); } From d91fe5d8b53fe26e8b6c5bdadb27a5178652813d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 23 Dec 2018 14:22:44 +0000 Subject: [PATCH 0608/1848] Fixed export-import for quota percent. --- WEB-INF/lib/ttGroupExportHelper.class.php | 1 + WEB-INF/lib/ttOrgImportHelper.class.php | 4 +++- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index c5600fd8b..1ab501eab 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -288,6 +288,7 @@ function writeData() { $user_part .= " role_id=\"".$role_id."\""; $user_part .= " client_id=\"".$this->clientMap[$user_item['client_id']]."\""; $user_part .= " rate=\"".$user_item['rate']."\""; + $user_part .= " quota_percent=\"".$user_item['quota_percent']."\""; $user_part .= " email=\"".$user_item['email']."\""; $user_part .= " status=\"".$user_item['status']."\""; $user_part .= ">\n"; diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 099cb58f9..b33901b2e 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -247,6 +247,7 @@ function startElement($parser, $name, $attrs) { 'login' => $attrs['LOGIN'], 'password' => $attrs['PASSWORD'], 'rate' => $attrs['RATE'], + 'quota_percent' => $attrs['QUOTA_PERCENT'], 'email' => $attrs['EMAIL'], 'status' => $attrs['STATUS']), false); if ($user_id) { @@ -775,7 +776,7 @@ private function insertUser($fields) { $group_id = (int) $fields['group_id']; $org_id = (int) $fields['org_id']; - $columns = '(login, password, name, group_id, org_id, role_id, client_id, rate, email, created, created_ip, created_by, status)'; + $columns = '(login, password, name, group_id, org_id, role_id, client_id, rate, quota_percent, email, created, created_ip, created_by, status)'; $values = 'values ('; $values .= $mdb2->quote($fields['login']); @@ -786,6 +787,7 @@ private function insertUser($fields) { $values .= ', '.(int)$fields['role_id']; $values .= ', '.$mdb2->quote($fields['client_id']); $values .= ', '.$mdb2->quote($fields['rate']); + $values .= ', '.$mdb2->quote($fields['quota_percent']); $values .= ', '.$mdb2->quote($fields['email']); $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$user->id; $values .= ', '.$mdb2->quote($fields['status']); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 83eb9084d..0290a9f77 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4684 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4685 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 11cef71c5608efdf93d400622140ef48f08b18f6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 23 Dec 2018 14:42:04 +0000 Subject: [PATCH 0609/1848] Fixed dbinstall.php for not null quota_percent. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0290a9f77..57e94258b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4685 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4686 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 74d566cc7..76a257cab 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1044,6 +1044,8 @@ function ttExecute($sql) { ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.34', modified = now() where param_name = 'version_db' and param_value = '1.18.26'"); ttExecute("update `tt_users` u inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.34') set u.quota_percent = 100.00 where u.quota_percent is null"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.36', modified = now() where param_name = 'version_db' and param_value = '1.18.34'"); + ttExecute("update `tt_users` u inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.36') set u.quota_percent = 100.00 where u.quota_percent is null"); + ttExecute("ALTER TABLE `tt_users` modify `quota_percent` float(6,2) NOT NULL default '100.00'"); } if ($_POST["cleanup"]) { From 367baa10353d5f679e6e3c795ae9d35a275a24d9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 24 Dec 2018 15:01:49 +0000 Subject: [PATCH 0610/1848] Introduced handling of max user count. --- WEB-INF/lib/ttUserHelper.class.php | 18 ++++++++++++++++++ WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- mobile/user_add.php | 1 + user_add.php | 1 + 34 files changed, 52 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 26ced938a..b3a5e3603 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -386,4 +386,22 @@ static function updateLastAccess() { $sql = "update tt_users set accessed = now(), accessed_ip = $accessed_ip where id = $user->id"; $mdb2->exec($sql); } + + // canAdd determines if we can add a user in case there is a limit. + static function canAdd() { + $mdb2 = getConnection(); + $sql = "select param_value from tt_site_config where param_name = 'max_users'"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + if (!$val) return true; // No limit. + + $max_count = $val['param_value']; + $sql = "select count(*) as user_count from tt_users where status is not null"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + if ($val['user_count'] < $max_count) + return true; // Limit not reached. + + return false; + } } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index b4d869930..f38bcabd2 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -116,6 +116,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d12be155e..baf085b51 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -118,6 +118,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index c49745130..051b6f8c2 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -110,6 +110,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index eab807e85..6c75c7e31 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -104,6 +104,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index aadf6f5ac..687f19daf 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -101,6 +101,7 @@ 'error.xml' => 'Error in XML file at line %d: %s.', 'error.cannot_import' => 'Cannot import: %s.', 'error.format' => 'Invalid file format.', +'error.user_count' => 'Limit on user count.', // Warning messages. 'warn.sure' => 'Are you sure?', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index cc4fe0347..fbf7076aa 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -114,6 +114,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index a29929afd..860b8cd93 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -119,6 +119,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f1a37b4f5..3ec01e23e 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -117,6 +117,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 065f71c1c..4895713b5 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -112,6 +112,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 4c6d76749..5e0036654 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -110,6 +110,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 6be29a04b..6e7b32ef0 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -105,6 +105,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index d27edb8c7..daedb00be 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -127,6 +127,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 27642b478..fcd4c2566 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -116,6 +116,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 8f35a78ec..36f8ab3da 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -109,6 +109,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index ea158793a..4cb224fb5 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -120,6 +120,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 27cbe6692..2c0a898e0 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -119,6 +119,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index b0ada311d..d98188f48 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -101,6 +101,8 @@ 'error.xml' => 'Fout in XML bestand in regel line %d: %s.', 'error.cannot_import' => 'Kan het volgende niet importeren: %s.', 'error.format' => 'Bestandsformaat niet valide.', +// TODO: translate the following. +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 34f4f6d30..650957eda 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -119,6 +119,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index a9220c4eb..11b6c4b42 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -114,6 +114,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index ee699e11b..3e36200ea 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -111,6 +111,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 8a96bc882..c3ef6c5c3 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -113,6 +113,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 4f027f6b0..01ecded5d 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -120,6 +120,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 466f7cd1e..f68e0631c 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -100,6 +100,7 @@ 'error.xml' => 'Ошибка в файле XML на строке %d: %s.', 'error.cannot_import' => 'Невозможно импортировать: %s.', 'error.format' => 'Неверный формат файла.', +'error.user_count' => 'Ограничение на количество пользователей.', // Warning messages. 'warn.sure' => 'Вы уверены?', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 0077e713d..33622c990 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -116,6 +116,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 9be563c42..6b3881a13 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -110,6 +110,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 270984d45..3b12961d6 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -111,6 +111,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 815ad80e1..5ddd55d1f 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -109,6 +109,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 720475be6..fafeeaaf2 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -123,6 +123,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index aa9e7dea8..656eb4516 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -111,6 +111,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 7346c9ad1..0bdb2e05d 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -117,6 +117,7 @@ // 'error.xml' => 'Error in XML file at line %d: %s.', // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', +// 'error.user_count' => 'Limit on user count.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 57e94258b..d163b71dc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4686 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4687 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/user_add.php b/mobile/user_add.php index b1d155aa0..c821c7d4f 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -149,6 +149,7 @@ function render(&$table, $value, $row, $column, $selected = false) { if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); + if (!ttUserHelper::canAdd()) $err->add($i18n->get('error.user_count')); if ($err->no()) { if (!ttUserHelper::getUserByLogin($cl_login)) { diff --git a/user_add.php b/user_add.php index a99951912..cf233d5b5 100644 --- a/user_add.php +++ b/user_add.php @@ -152,6 +152,7 @@ function render(&$table, $value, $row, $column, $selected = false) { if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); + if (!ttUserHelper::canAdd()) $err->add($i18n->get('error.user_count')); if ($err->no()) { if (!ttUserHelper::getUserByLogin($cl_login)) { From a468ccc781de1988967194b2bf89e6b7a404e716 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 24 Dec 2018 15:24:05 +0000 Subject: [PATCH 0611/1848] Fixed ttRegistrator class. --- WEB-INF/lib/ttRegistrator.class.php | 8 ++++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index 77ffb6b57..1664461b8 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -26,6 +26,9 @@ // | https://www.anuko.com/time_tracker/credits.htm // +----------------------------------------------------------------------+ +import('ttUserHelper'); +import('ttRoleHelper'); + // ttRegistrator class is used to register a user in Time Tracker. class ttRegistrator { var $user_name = null; // User name. @@ -83,6 +86,8 @@ function validate() { $this->err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); if (!ttValidEmail($this->email, true)) $this->err->add($i18n->get('error.field'), $i18n->get('label.email')); + if (!ttUserHelper::canAdd()) + $this->err->add($i18n->get('error.user_count')); } // The register function registers a user in Time Tracker. @@ -115,7 +120,6 @@ function register() { return false; } - import('ttRoleHelper'); if (!ttRoleHelper::createPredefinedRoles($this->group_id, $this->lang)) { $err->add($i18n->get('error.db')); return false; @@ -124,7 +128,7 @@ function register() { $this->user_id = $this->createUser(); if (!$this->user_id) { - $err->add($i18n->get('error.db')); + $this->err->add($i18n->get('error.db')); return false; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d163b71dc..6cac932b4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4687 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4688 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 87dff6fdf1e60ff60fb429290488cb1c9bf778d9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 24 Dec 2018 16:02:43 +0000 Subject: [PATCH 0612/1848] Fixed handling user limit for admin. --- WEB-INF/lib/ttOrgImportHelper.class.php | 6 ++++++ WEB-INF/lib/ttUserHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- admin_group_add.php | 2 ++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index b33901b2e..251cb3ea6 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -31,6 +31,7 @@ class ttOrgImportHelper { var $errors = null; // Errors go here. Set in constructor by reference. var $schema_version = null; // Database schema version from XML file we import from. + var $num_users = 0; // A number of active and inactive users we are importing. var $conflicting_logins = null; // A comma-separated list of logins we cannot import. var $canImport = true; // False if we cannot import data due to a conflict such as login collision. var $firstPass = true; // True during first pass through the file. @@ -81,6 +82,7 @@ function startElement($parser, $name, $attrs) { // In first pass we check user logins for potential collisions with existing. if ($name == 'USER' && $this->canImport) { $login = $attrs['LOGIN']; + if ('' != $attrs['STATUS']) $this->num_users++; if ('' != $attrs['STATUS'] && $this->loginExists($login)) { // We have a login collision. Append colliding login to a list of things we cannot import. $this->conflicting_logins .= ($this->conflicting_logins ? ", $login" : $login); @@ -569,6 +571,10 @@ function importXml() { $this->errors->add($i18n->get('error.user_exists')); $this->errors->add(sprintf($i18n->get('error.cannot_import'), $this->conflicting_logins)); } + if (!ttUserHelper::canAdd($this->num_users)) { + $this->canImport = false; + $this->errors->add($i18n->get('error.user_count')); + } $this->firstPass = false; // We are done with 1st pass. xml_parser_free($parser); diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index b3a5e3603..538a2fc40 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -388,7 +388,7 @@ static function updateLastAccess() { } // canAdd determines if we can add a user in case there is a limit. - static function canAdd() { + static function canAdd($num_users = 1) { $mdb2 = getConnection(); $sql = "select param_value from tt_site_config where param_name = 'max_users'"; $res = $mdb2->query($sql); @@ -399,7 +399,7 @@ static function canAdd() { $sql = "select count(*) as user_count from tt_users where status is not null"; $res = $mdb2->query($sql); $val = $res->fetchRow(); - if ($val['user_count'] < $max_count) + if ($val['user_count'] < $max_count - $num_users) // TODO: test this. return true; // Limit not reached. return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6cac932b4..f33967268 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4688 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4689 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_group_add.php b/admin_group_add.php index 52b4134f1..c42644f09 100644 --- a/admin_group_add.php +++ b/admin_group_add.php @@ -99,6 +99,8 @@ $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); if (!ttValidEmail($cl_manager_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); + if (!ttUserHelper::canAdd()) + $err->add($i18n->get('error.user_count')); if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); From c819d80227f056f8b98e6a5e27884db1e40c930a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 25 Dec 2018 13:12:55 +0000 Subject: [PATCH 0613/1848] Improved user count check. --- WEB-INF/lib/ttUserHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 538a2fc40..d0a09ced8 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -396,10 +396,10 @@ static function canAdd($num_users = 1) { if (!$val) return true; // No limit. $max_count = $val['param_value']; - $sql = "select count(*) as user_count from tt_users where status is not null"; + $sql = "select count(*) as user_count from tt_users where group_id > 0 and status is not null"; $res = $mdb2->query($sql); $val = $res->fetchRow(); - if ($val['user_count'] < $max_count - $num_users) // TODO: test this. + if ($val['user_count'] <= $max_count - $num_users) return true; // Limit not reached. return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f33967268..3c38d4335 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4689 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4690 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From be392a30bbf092816a39b59d11d38b10b9353d0b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 27 Dec 2018 13:11:47 +0000 Subject: [PATCH 0614/1848] Added December 31 as a holiday to German file. --- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 6c75c7e31..469ef0563 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -34,7 +34,7 @@ $i18n_weekdays = array('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'); $i18n_weekdays_short = array('So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'); // format mm/dd -$i18n_holidays = array('01/01', '03/30', '04/02', '05/01', '05/21', '05/31', '10/03', '11/01', '12/24','12/25', '12/26'); +$i18n_holidays = array('01/01', '03/30', '04/02', '05/01', '05/21', '05/31', '10/03', '11/01', '12/24','12/25', '12/26', '12/31'); $i18n_key_words = array( diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3c38d4335..5ace796ff 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4690 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4691 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From f3467d6ea5f38cd295dd4b2bdfe201b792b1a224 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 27 Dec 2018 13:37:16 +0000 Subject: [PATCH 0615/1848] An improvement in German translation. --- WEB-INF/resources/de.lang.php | 5 ++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 469ef0563..39e472154 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -358,9 +358,8 @@ 'form.time.uncompleted' => 'Unvollständig', 'form.time.remaining_quota' => 'Verbleibende Quote', 'form.time.over_quota' => 'Über der Quote', -// TODO: translate the following. -// 'form.time.remaining_balance' => 'Remaining balance', -// 'form.time.over_balance' => 'Over balance', +'form.time.remaining_balance' => 'Minusstunden', +'form.time.over_balance' => 'Mehrstunden', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Dieser Eintrag wurde ohne Startzeit gespeichert. Dies ist kein Fehler.', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5ace796ff..585152881 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4691 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4692 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 3262206d3cda17048d2010de8dec165c8f5bf052 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 28 Dec 2018 16:22:15 +0000 Subject: [PATCH 0616/1848] Added an environment check for enabled libxml to address issue #67. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 585152881..fd999f83f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4692 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4693 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 76a257cab..a3cdd9cc5 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -131,6 +131,11 @@ function ttExecute($sql) { } } + // Check is libxml is enabled (which is a PHP default). + if (!function_exists('libxml_clear_errors')) { + echo('Error: libxml is not enabled. It is required for import group operation (to parse XML).
'); + } + // Check database access. require_once('MDB2.php'); $conn = MDB2::connect(DSN); From cb09c742b72be7025fc5e6640d89966de30bc14f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 28 Dec 2018 18:00:52 +0000 Subject: [PATCH 0617/1848] Added a Dockerfile for app only as first step to containerization. See also PR#68. --- Dockerfile | 29 +++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..37cf6bfe0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM php:7.2-apache + +# Use the default production configuration. +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +# Override with custom settings. +# COPY config/php_tt.ini $PHP_INI_DIR/conf.d/ + +# Install mysqli extension. +RUN docker-php-ext-install mysqli + +# Install gd extension. +RUN apt-get update && apt-get install libpng-dev -y \ + && docker-php-ext-install gd + +# Install ldap extension. +RUN apt-get install libldap2-dev -y \ + && docker-php-ext-install ldap +# TODO: check if ldap works, as the above is missing this step: +# && docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ && \ + +# Cleanup. The intention was to keep image size down. +# RUN rm -rf /var/lib/apt/lists/* +# +# The above does not work. Files are removed, but +# image files (zipped or not) are not getting smaller. Why? + +COPY . /var/www/html/ + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fd999f83f..9a62b1453 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4693 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4694 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 2f28666efaac80c4cd7e9f6d879dc4c20803e9a6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 29 Dec 2018 18:22:42 +0000 Subject: [PATCH 0618/1848] Initial work done on Docker composition of TT and MariaDB together. --- Dockerfile | 8 +++++++- WEB-INF/templates/footer.tpl | 2 +- docker-compose.yml | 26 ++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile index 37cf6bfe0..1cbf6afc2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,5 +25,11 @@ RUN apt-get install libldap2-dev -y \ # The above does not work. Files are removed, but # image files (zipped or not) are not getting smaller. Why? +# Copy application source code to /var/www/html/. COPY . /var/www/html/ - +# Create configuration file. +RUN cp /var/www/html/WEB-INF/config.php.dist /var/www/html/WEB-INF/config.php +# Replace DSN value to something connectable to a Docker container running mariadb. +RUN sed -i "s|mysqli://root:no@localhost/dbname|mysqli://anuko_user:anuko_pw@anuko_sql/timetracker|g" /var/www/html/WEB-INF/config.php +# Note that db is defined as anuko_sql/timetracker where anuko_sql is service name and timetracker is db name. +# See docker-compose.yml for details. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9a62b1453..f2ab255e2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4694 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4695 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..b5ecef924 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,26 @@ +version: '3.7' + +services: + # anuko_tt is a web application built as per Dockerfile specification. + anuko_tt: + build: . + image: anuko_timetracker:dev + container_name: anuko-timetracker + # Use localhost:8080 to connect to timetracker via browser. + ports: + - "8080:80" + + # anuko_sql is a mariadb instance to which timetracker connects. + # Connect parameters are also specified in timetracker Dockerfile after + # creation of its configuration file. Specifically, we replace + # user name, password, service name (aka resolvable to IP server name + # where mariadb runs), and database name there from the defaults. + # Apparently, these two sets of credentials must match for successful connect. + anuko_sql: + image: "mariadb:latest" + container_name: anuko-sql + environment: + MYSQL_RANDOM_ROOT_PASSWORD: "yes" + MYSQL_DATABASE: timetracker + MYSQL_USER: anuko_user + MYSQL_PASSWORD: anuko_pw From f317cf23f526833481163a2d3130e37beac11d54 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 29 Dec 2018 20:50:46 +0000 Subject: [PATCH 0619/1848] Added a volume to persist db data in Docker. --- WEB-INF/templates/footer.tpl | 2 +- docker-compose.yml | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f2ab255e2..5d77a19aa 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4695 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4696 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/docker-compose.yml b/docker-compose.yml index b5ecef924..e516fada7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,7 +15,7 @@ services: # creation of its configuration file. Specifically, we replace # user name, password, service name (aka resolvable to IP server name # where mariadb runs), and database name there from the defaults. - # Apparently, these two sets of credentials must match for successful connect. + # These two sets of credentials must match for a successful connect. anuko_sql: image: "mariadb:latest" container_name: anuko-sql @@ -24,3 +24,8 @@ services: MYSQL_DATABASE: timetracker MYSQL_USER: anuko_user MYSQL_PASSWORD: anuko_pw + volumes: + - db-data:/var/lib/mysql + +volumes: + db-data: \ No newline at end of file From 6b81cfb401a9ca7fa3e963c5e71ff3f5a0c1b01a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 30 Dec 2018 14:00:53 +0000 Subject: [PATCH 0620/1848] Added comments to docker files. --- Dockerfile | 1 + WEB-INF/templates/footer.tpl | 2 +- docker-compose.yml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1cbf6afc2..4b86f2a21 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,4 @@ +# This file is for development work. Not suitable for production. FROM php:7.2-apache # Use the default production configuration. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5d77a19aa..645a8c469 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4696 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4697 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/docker-compose.yml b/docker-compose.yml index e516fada7..0182a95ad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,4 @@ +# This file is for development work. Not suitable for production. version: '3.7' services: From c3feccfa60f8970ea2c2891d22549b2913a9561f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 30 Dec 2018 17:29:05 +0000 Subject: [PATCH 0621/1848] Added database creation step to docker composition. --- .gitignore | 1 + docker-compose.yml | 19 ++++++++++++------- dockerfile-db | 9 +++++++++ Dockerfile => dockerfile-tt | 4 ++-- 4 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 dockerfile-db rename Dockerfile => dockerfile-tt (87%) diff --git a/.gitignore b/.gitignore index d73d85537..e346fd3a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ config.php +populate.sql WEB-INF/templates_c/*.* WEB-INF/templates_c/import_* WEB-INF/templates_c/tt* diff --git a/docker-compose.yml b/docker-compose.yml index 0182a95ad..b4f3b4b67 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,29 +4,34 @@ version: '3.7' services: # anuko_tt is a web application built as per Dockerfile specification. anuko_tt: - build: . + build: + context: . + dockerfile: dockerfile-tt image: anuko_timetracker:dev container_name: anuko-timetracker # Use localhost:8080 to connect to timetracker via browser. ports: - "8080:80" - # anuko_sql is a mariadb instance to which timetracker connects. + # anuko_db is a mariadb instance to which timetracker connects. # Connect parameters are also specified in timetracker Dockerfile after # creation of its configuration file. Specifically, we replace # user name, password, service name (aka resolvable to IP server name # where mariadb runs), and database name there from the defaults. # These two sets of credentials must match for a successful connect. - anuko_sql: - image: "mariadb:latest" - container_name: anuko-sql + anuko_db: + build: + context: . + dockerfile: dockerfile-db + image: "anuko_database:dev" + container_name: anuko-database environment: MYSQL_RANDOM_ROOT_PASSWORD: "yes" MYSQL_DATABASE: timetracker MYSQL_USER: anuko_user MYSQL_PASSWORD: anuko_pw volumes: - - db-data:/var/lib/mysql + - database:/var/lib/mysql volumes: - db-data: \ No newline at end of file + database: \ No newline at end of file diff --git a/dockerfile-db b/dockerfile-db new file mode 100644 index 000000000..b13673952 --- /dev/null +++ b/dockerfile-db @@ -0,0 +1,9 @@ +# This file is for development work. Not suitable for production. +FROM mariadb:latest + +# Copy database creation script. +COPY mysql.sql /docker-entrypoint-initdb.d/ + +# Copy database population script, if available. +# TODO: design a better directory structure. +COPY populate.sql /docker-entrypoint-initdb.d/ diff --git a/Dockerfile b/dockerfile-tt similarity index 87% rename from Dockerfile rename to dockerfile-tt index 4b86f2a21..8902cbf7e 100644 --- a/Dockerfile +++ b/dockerfile-tt @@ -31,6 +31,6 @@ COPY . /var/www/html/ # Create configuration file. RUN cp /var/www/html/WEB-INF/config.php.dist /var/www/html/WEB-INF/config.php # Replace DSN value to something connectable to a Docker container running mariadb. -RUN sed -i "s|mysqli://root:no@localhost/dbname|mysqli://anuko_user:anuko_pw@anuko_sql/timetracker|g" /var/www/html/WEB-INF/config.php -# Note that db is defined as anuko_sql/timetracker where anuko_sql is service name and timetracker is db name. +RUN sed -i "s|mysqli://root:no@localhost/dbname|mysqli://anuko_user:anuko_pw@anuko_db/timetracker|g" /var/www/html/WEB-INF/config.php +# Note that db is defined as anuko_db/timetracker where anuko_db is service name and timetracker is db name. # See docker-compose.yml for details. From 646bcbf30417f95252d8b36c009dbb040af62b66 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 30 Dec 2018 19:47:44 +0000 Subject: [PATCH 0622/1848] Cosmetic. --- docker-compose.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index b4f3b4b67..e621c4105 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.7' services: - # anuko_tt is a web application built as per Dockerfile specification. + # anuko_tt is a web application built as per dockerfile specification. anuko_tt: build: context: . @@ -14,7 +14,7 @@ services: - "8080:80" # anuko_db is a mariadb instance to which timetracker connects. - # Connect parameters are also specified in timetracker Dockerfile after + # Connect parameters are also specified in timetracker dockerfile after # creation of its configuration file. Specifically, we replace # user name, password, service name (aka resolvable to IP server name # where mariadb runs), and database name there from the defaults. @@ -31,7 +31,7 @@ services: MYSQL_USER: anuko_user MYSQL_PASSWORD: anuko_pw volumes: - - database:/var/lib/mysql + - anuko_db:/var/lib/mysql volumes: - database: \ No newline at end of file + anuko_db: \ No newline at end of file From 41bb577927a2b54d6a2cbc97ccc63e2935f7604b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 30 Dec 2018 21:50:21 +0000 Subject: [PATCH 0623/1848] Added user selector on mobile time.php. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/time.tpl | 10 +++-- mobile/time.php | 66 +++++++++++++++++++++++++------ time.php | 8 ++-- 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 645a8c469..1354a1e3d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4697 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4698 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/time.tpl b/WEB-INF/templates/mobile/time.tpl index 3b8b0f8b4..35242e2f3 100644 --- a/WEB-INF/templates/mobile/time.tpl +++ b/WEB-INF/templates/mobile/time.tpl @@ -48,12 +48,16 @@
+{if $user_dropdown} + + +{/if} {if $user->isPluginEnabled('cl')} - - + + {/if} {if $user->isPluginEnabled('iv')} - + {/if} {if ($custom_fields && $custom_fields->fields[0])} diff --git a/mobile/time.php b/mobile/time.php index 80049a9cb..107a72c7f 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -39,9 +39,32 @@ header('Location: access_denied.php'); exit(); } +if ($user->behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { + header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. + exit(); +} +if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. + exit(); +} +if ($request->isPost()) { + $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + header('Location: access_denied.php'); // Group changed, but no rght or wrong user id. + exit(); + } +} // End of access checks. -$user_id = $user->getUser(); +// Determine user for which we display this page. +if ($request->isPost() && $userChanged) { + $user_id = $request->getParameter('user'); + $user->setOnBehalfUser($user_id); +} else { + $user_id = $user->getUser(); +} + +$group_id = $user->getGroup(); // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -89,9 +112,28 @@ // Elements of timeRecordForm. $form = new Form('timeRecordForm'); +if ($user->can('track_time')) { + $rank = $user->getMaxRankForGroup($group_id); + if ($user->can('track_own_time')) + $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); + else + $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank); + $user_list = $user->getUsers($options); + if (count($user_list) >= 1) { + $form->addInput(array('type'=>'combobox', + 'onchange'=>'document.timeRecordForm.user_changed.value=1;document.timeRecordForm.submit();', + 'name'=>'user', + 'style'=>'width: 250px;', + 'value'=>$user_id, + 'data'=>$user_list, + 'datakeys'=>array('id','name'))); + $form->addInput(array('type'=>'hidden','name'=>'user_changed')); + $smarty->assign('user_dropdown', 1); + } +} // Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { +if (MODE_TIME == $user->getTrackingMode() && $user->isPluginEnabled('cl')) { $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', @@ -104,7 +146,7 @@ // Note: in other modes the client list is filtered to relevant clients only. See below. } -if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { +if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { // Dropdown for projects assigned to user. $project_list = $user->getAssignedProjects(); $form->addInput(array('type'=>'combobox', @@ -145,7 +187,7 @@ } } -if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { +if (MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', @@ -155,7 +197,7 @@ 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); } -if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { +if ((TYPE_START_FINISH == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) { $form->addInput(array('type'=>'text','name'=>'start','value'=>$cl_start,'onchange'=>"formDisable('start');")); $form->addInput(array('type'=>'text','name'=>'finish','value'=>$cl_finish,'onchange'=>"formDisable('finish');")); if ($user->punch_mode && !$user->canOverridePunchMode()) { @@ -164,7 +206,7 @@ $form->getElement('finish')->setEnabled(false); } } -if ((TYPE_DURATION == $user->record_type) || (TYPE_ALL == $user->record_type)) +if ((TYPE_DURATION == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); $form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height: 60px;','value'=>$cl_note)); if ($user->isPluginEnabled('iv')) @@ -196,10 +238,10 @@ if ($custom_fields) { if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); } - if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { + if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode && $user->task_required) { + if (MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && $user->task_required) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (strlen($cl_duration) == 0) { @@ -213,11 +255,11 @@ $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); } } else { - if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { + if ((TYPE_START_FINISH == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) { $err->add($i18n->get('error.empty'), $i18n->get('label.start')); $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); } - if ((TYPE_DURATION == $user->record_type) || (TYPE_ALL == $user->record_type)) + if ((TYPE_DURATION == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); } } else { @@ -254,7 +296,7 @@ $id = ttTimeHelper::insert(array( 'date' => $cl_date, 'user_id' => $user_id, - 'group_id' => $user->getGroup(), + 'group_id' => $group_id, 'org_id' => $user->org_id, 'client' => $cl_client, 'project' => $cl_project, @@ -292,7 +334,7 @@ $smarty->assign('task_list', $task_list); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="fillDropdowns()"'); -$smarty->assign('timestring', $selected_date->toString($user->date_format)); +$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); $smarty->assign('title', $i18n->get('title.time')); $smarty->assign('content_page_name', 'mobile/time.tpl'); $smarty->display('mobile/index.tpl'); diff --git a/time.php b/time.php index 7252f476f..0431c2bec 100644 --- a/time.php +++ b/time.php @@ -259,10 +259,10 @@ if ($custom_fields) { if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); } - if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { + if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode && $user->task_required) { + if (MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && $user->task_required) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (strlen($cl_duration) == 0) { @@ -276,11 +276,11 @@ $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); } } else { - if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { + if ((TYPE_START_FINISH == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) { $err->add($i18n->get('error.empty'), $i18n->get('label.start')); $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); } - if ((TYPE_DURATION == $user->record_type) || (TYPE_ALL == $user->record_type)) + if ((TYPE_DURATION == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); } } else { From 624d2811d204264914442a71c560adce8ca97d20 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 31 Dec 2018 15:42:12 +0000 Subject: [PATCH 0624/1848] Improved .gitignore. --- .gitignore | 1 + WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e346fd3a3..0dba767f9 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ upload/ Thumbs.db *.DS_Store *~ +.idea/ diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1354a1e3d..6217c35c6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.user}:
{$forms.timeRecordForm.user.control}
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$custom_fields->fields[0]['label']|escape}:
-
 Anuko Time Tracker 1.18.36.4698 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4699 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c0f70b9c3c416d20ac3a5528d756e4783c88927c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 2 Jan 2019 15:04:31 +0000 Subject: [PATCH 0625/1848] Added audit info on user delete. --- WEB-INF/lib/ttUser.class.php | 3 ++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 1bfd6f440..36f9163f1 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -695,7 +695,8 @@ function markUserDeleted($user_id) { return false; // Mark user as deleted. - $sql = "update tt_users set status = NULL where id = $user_id". + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($this->id); + $sql = "update tt_users set status = null $modified_part where id = $user_id". " and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6217c35c6..b1acfc012 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4699 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4700 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From d528413f57480455efce71f40082eb682f2d8d48 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 3 Jan 2019 13:37:06 +0000 Subject: [PATCH 0626/1848] German holidays corrected. --- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 39e472154..6eaa77f70 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -34,7 +34,7 @@ $i18n_weekdays = array('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'); $i18n_weekdays_short = array('So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'); // format mm/dd -$i18n_holidays = array('01/01', '03/30', '04/02', '05/01', '05/21', '05/31', '10/03', '11/01', '12/24','12/25', '12/26', '12/31'); +$i18n_holidays = array('01/01', '04/19', '04/22', '05/01', '05/30', '06/10', '06/20', '10/03', '11/01', '12/24','12/25', '12/26', '12/31'); $i18n_key_words = array( diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b1acfc012..bf9a81c0c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4700 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4701 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 903dae76e54a4e0c081532a8113c00ef1b56a1b5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 9 Jan 2019 18:12:48 +0000 Subject: [PATCH 0627/1848] Added handling of expiration dates. --- WEB-INF/lib/ttTimeHelper.class.php | 14 ++++++++++++++ WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- expense_edit.php | 3 +++ expenses.php | 2 ++ mobile/expense_edit.php | 3 +++ mobile/expenses.php | 2 ++ mobile/time.php | 1 + mobile/time_edit.php | 1 + time.php | 1 + time_edit.php | 1 + 40 files changed, 59 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 4e10f4ed7..a66652b70 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -748,4 +748,18 @@ static function getRecords($user_id, $date) { return $result; } + + // canAdd determines if we can add a record in case there is a limit. + static function canAdd() { + $mdb2 = getConnection(); + $sql = "select param_value from tt_site_config where param_name = 'exp_date'"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + if (!$val) return true; // No expiration date. + + if (strtotime($val['param_value']) > time()) + return true; // Expiration date exists but not reached. + + return false; + } } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index f38bcabd2..7b5a5d62f 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -117,6 +117,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index baf085b51..8c875b92b 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -119,6 +119,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 051b6f8c2..7b9faf3b7 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -111,6 +111,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 6eaa77f70..2c21205d7 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -105,6 +105,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 687f19daf..2db7e2d90 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -102,6 +102,7 @@ 'error.cannot_import' => 'Cannot import: %s.', 'error.format' => 'Invalid file format.', 'error.user_count' => 'Limit on user count.', +'error.expired' => 'Expiration date reached.', // Warning messages. 'warn.sure' => 'Are you sure?', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index fbf7076aa..0f8bc123c 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -115,6 +115,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 860b8cd93..1387bea36 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -120,6 +120,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 3ec01e23e..dfb010500 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -118,6 +118,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 4895713b5..1bd098221 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -113,6 +113,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 5e0036654..430c5b1c6 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -111,6 +111,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 6e7b32ef0..88dad80f7 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -106,6 +106,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index daedb00be..1420500bb 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -128,6 +128,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index fcd4c2566..6d4698e68 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -117,6 +117,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 36f8ab3da..c14d770e5 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -110,6 +110,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 4cb224fb5..d7e2dcf9a 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -121,6 +121,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 2c0a898e0..1866dd54b 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -120,6 +120,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index d98188f48..823035ce0 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -103,6 +103,7 @@ 'error.format' => 'Bestandsformaat niet valide.', // TODO: translate the following. // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 650957eda..8a698d1de 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -120,6 +120,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 11b6c4b42..2922a3421 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -115,6 +115,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 3e36200ea..8691f9383 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -112,6 +112,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index c3ef6c5c3..bc5d8386b 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -114,6 +114,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 01ecded5d..6eb221121 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -121,6 +121,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index f68e0631c..4b524b82d 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -101,6 +101,7 @@ 'error.cannot_import' => 'Невозможно импортировать: %s.', 'error.format' => 'Неверный формат файла.', 'error.user_count' => 'Ограничение на количество пользователей.', +'error.expired' => 'Достигнута дата экспирации.', // Warning messages. 'warn.sure' => 'Вы уверены?', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 33622c990..726c78e80 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -117,6 +117,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 6b3881a13..18ddd37f9 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -111,6 +111,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 3b12961d6..c20cc43fc 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -112,6 +112,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 5ddd55d1f..d1a106483 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -110,6 +110,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index fafeeaaf2..38b4a4b29 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -124,6 +124,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 656eb4516..fd4e2b88c 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -112,6 +112,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 0bdb2e05d..4112fa159 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -118,6 +118,7 @@ // 'error.cannot_import' => 'Cannot import: %s.', // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', +// 'error.expired' => 'Expiration date reached.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bf9a81c0c..35fc2a5d3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4701 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4702 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expense_edit.php b/expense_edit.php index 8eb7d4fe0..b1115f1e3 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttGroupHelper'); import('DateAndTime'); +import('ttTimeHelper'); import('ttExpenseHelper'); // Access checks. @@ -176,6 +177,8 @@ if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); } + if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); + // Finished validating user input. // Save record. if ($request->getParameter('btn_save')) { diff --git a/expenses.php b/expenses.php index 9a3454221..e1eaeddae 100644 --- a/expenses.php +++ b/expenses.php @@ -31,6 +31,7 @@ import('ttUserHelper'); import('ttGroupHelper'); import('DateAndTime'); +import('ttTimeHelper'); import('ttExpenseHelper'); // Access checks. @@ -202,6 +203,7 @@ if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); } + if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); // Finished validating input data. // Prohibit creating entries in locked range. diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index 4c183afd9..e9e1ca63a 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttGroupHelper'); import('DateAndTime'); +import('ttTimeHelper'); import('ttExpenseHelper'); // Access checks. @@ -171,6 +172,8 @@ if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); } + if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); + // Finished validating input data. // Save record. if ($request->getParameter('btn_save')) { diff --git a/mobile/expenses.php b/mobile/expenses.php index ac565207b..1b8f7cda9 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -31,6 +31,7 @@ import('ttUserHelper'); import('ttGroupHelper'); import('DateAndTime'); +import('ttTimeHelper'); import('ttExpenseHelper'); // Access checks. @@ -207,6 +208,7 @@ if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); } + if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); // Finished validating input data. // Prohibit creating entries in locked range. diff --git a/mobile/time.php b/mobile/time.php index 107a72c7f..364379f4f 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -267,6 +267,7 @@ $err->add($i18n->get('error.field'), $i18n->get('label.duration')); } if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); + if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); // Finished validating user input. // Prohibit creating entries in future. diff --git a/mobile/time_edit.php b/mobile/time_edit.php index cdd507077..803ca4e4f 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -252,6 +252,7 @@ } if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); + if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); // Finished validating user input. // This is a new date for the time record. diff --git a/time.php b/time.php index 0431c2bec..5a9b5210d 100644 --- a/time.php +++ b/time.php @@ -288,6 +288,7 @@ $err->add($i18n->get('error.field'), $i18n->get('label.duration')); } if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); + if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); // Finished validating user input. // Prohibit creating entries in future. diff --git a/time_edit.php b/time_edit.php index 16f69d2ab..3bd52e6f5 100644 --- a/time_edit.php +++ b/time_edit.php @@ -257,6 +257,7 @@ } if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); + if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); // Finished validating user input. // This is a new date for the time record. From 47a80e5f3693888437a7a75721334c726b62af9e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 9 Jan 2019 23:47:25 +0000 Subject: [PATCH 0628/1848] Improved JavaScript for better handling of non-client users. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/user_add.tpl | 4 +++- WEB-INF/templates/mobile/user_edit.tpl | 4 +++- WEB-INF/templates/user_add.tpl | 4 +++- WEB-INF/templates/user_edit.tpl | 4 +++- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 35fc2a5d3..27b17d576 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4702 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4703 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/user_add.tpl b/WEB-INF/templates/mobile/user_add.tpl index 71901fb05..d23dcf932 100644 --- a/WEB-INF/templates/mobile/user_add.tpl +++ b/WEB-INF/templates/mobile/user_add.tpl @@ -40,8 +40,10 @@ function handleClientControl() { var isClient = roles[i][1]; if (isClient == 1) clientControl.style.visibility = "visible"; - else + else { + clientControl.value = ''; clientControl.style.visibility = "hidden"; + } break; } } diff --git a/WEB-INF/templates/mobile/user_edit.tpl b/WEB-INF/templates/mobile/user_edit.tpl index 0d7f47e6c..9929e7272 100644 --- a/WEB-INF/templates/mobile/user_edit.tpl +++ b/WEB-INF/templates/mobile/user_edit.tpl @@ -62,8 +62,10 @@ function handleClientControl() { var isClient = roles[i][1]; if (isClient == 1) clientControl.style.visibility = "visible"; - else + else { + clientControl.value = ''; clientControl.style.visibility = "hidden"; + } break; } } diff --git a/WEB-INF/templates/user_add.tpl b/WEB-INF/templates/user_add.tpl index 39575db0c..0741dc3e9 100644 --- a/WEB-INF/templates/user_add.tpl +++ b/WEB-INF/templates/user_add.tpl @@ -40,8 +40,10 @@ function handleClientControl() { var isClient = roles[i][1]; if (isClient == 1) clientControl.style.visibility = "visible"; - else + else { + clientControl.value = ''; clientControl.style.visibility = "hidden"; + } break; } } diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index 7475c6efb..32947545d 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -62,8 +62,10 @@ function handleClientControl() { var isClient = roles[i][1]; if (isClient == 1) clientControl.style.visibility = "visible"; - else + else { + clientControl.value = ''; clientControl.style.visibility = "hidden"; + } break; } } From 8f04c2f5411caf7a0d940f465bc5eb9c061764fe Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 14 Jan 2019 22:44:18 +0000 Subject: [PATCH 0629/1848] Added a comment explaining balance labels. --- WEB-INF/resources/en.lang.php | 6 ++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 2db7e2d90..3ef26b89d 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -357,6 +357,12 @@ 'form.time.uncompleted' => 'Uncompleted', 'form.time.remaining_quota' => 'Remaining quota', 'form.time.over_quota' => 'Over quota', +// Note for translators. "Balance" below means accumulated quota for user since 1st of the month +// until and icluding a selected day. If a quota is 8 hours a day, then the balance +// is 8 hours multiplied by a number of work days. "Remaining balance" and "Over balance" are +// balance differences with logged hours. +// The term looks confusing, if you have a better idea how to name these things, let us know. +// For example, a German could use: Minusstunden and Mehrstunden. 'form.time.remaining_balance' => 'Remaining balance', 'form.time.over_balance' => 'Over balance', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 27b17d576..4b4fc4465 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4703 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4704 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 5bf1b81030c3ce115f01fcbfeffbbe6defe93d45 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 14 Jan 2019 22:48:05 +0000 Subject: [PATCH 0630/1848] Improved a comment. --- WEB-INF/resources/en.lang.php | 1 - 1 file changed, 1 deletion(-) diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 3ef26b89d..c5ce3dc26 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -362,7 +362,6 @@ // is 8 hours multiplied by a number of work days. "Remaining balance" and "Over balance" are // balance differences with logged hours. // The term looks confusing, if you have a better idea how to name these things, let us know. -// For example, a German could use: Minusstunden and Mehrstunden. 'form.time.remaining_balance' => 'Remaining balance', 'form.time.over_balance' => 'Over balance', From 84ebf6e6d0d84b21a7b4be11c60d16c84d4dd3ef Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 14 Jan 2019 22:53:01 +0000 Subject: [PATCH 0631/1848] Cosmetic typo fix. --- WEB-INF/resources/en.lang.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index c5ce3dc26..101a5b71e 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -358,7 +358,7 @@ 'form.time.remaining_quota' => 'Remaining quota', 'form.time.over_quota' => 'Over quota', // Note for translators. "Balance" below means accumulated quota for user since 1st of the month -// until and icluding a selected day. If a quota is 8 hours a day, then the balance +// until and including a selected day. If a quota is 8 hours a day, then the balance // is 8 hours multiplied by a number of work days. "Remaining balance" and "Over balance" are // balance differences with logged hours. // The term looks confusing, if you have a better idea how to name these things, let us know. From eff9ca439795bffd16af8a9e339879d5704e5875 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Jan 2019 14:49:18 +0000 Subject: [PATCH 0632/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 42 ++++++++++++++--------------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 823035ce0..ed304b5ab 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -56,8 +56,7 @@ 'menu.tasks' => 'Taken', 'menu.users' => 'Medewerkers', 'menu.groups' => 'Groepen', -// TODO: translate the following. -// 'menu.subgroups' => 'Subgroups', +'menu.subgroups' => 'Subgroepen', 'menu.export' => 'Exporteren', 'menu.clients' => 'Klanten', 'menu.options' => 'Opties', @@ -101,18 +100,15 @@ 'error.xml' => 'Fout in XML bestand in regel line %d: %s.', 'error.cannot_import' => 'Kan het volgende niet importeren: %s.', 'error.format' => 'Bestandsformaat niet valide.', -// TODO: translate the following. -// 'error.user_count' => 'Limit on user count.', -// 'error.expired' => 'Expiration date reached.', +'error.user_count' => 'Limiet op aantal gebruikers.', +'error.expired' => 'Verloop datum is bereikt.', // Warning messages. -// TODO: translate the following. -// 'warn.sure' => 'Are you sure?', -// 'warn.confirm_save' => 'Date has changed. Confirm saving, not copying this item.', +'warn.sure' => 'Ben je er zeker van?', +'warn.confirm_save' => 'De datum is veranderd. Bevestig dat je dit item wilt opslaan en niet wilt kopiëren.', // Success messages. -// TODO: translate the following. -// 'msg.success' => 'Operation completed successfully.', +'msg.success' => 'De bewerking is succesvol uitgevoerd.', // Labels for buttons. 'button.login' => 'Aanmelden', @@ -154,8 +150,7 @@ 'label.user' => 'Medewerker', 'label.users' => 'Medewerkers', 'label.group' => 'Groep', -// TODO: translate the following. -// 'label.subgroups' => 'Subgroups', +'label.subgroups' => 'Subgroepen', 'label.roles' => 'Rollen', 'label.client' => 'Klant', 'label.clients' => 'Klanten', @@ -231,17 +226,15 @@ 'label.work_units' => 'Werk eenheid', 'label.work_units_short' => 'Eenheid', 'label.totals_only' => 'Alleen totalen', -'label.quota' => 'Quota', +'label.quota' => 'Maanddoel', // Form titles. 'title.error' => 'Fout', -// TODO: Translate the following. -// 'title.success' => 'Success', +'title.success' => 'Succes', 'title.login' => 'Aanmelden', 'title.groups' => 'Groepen', -// TODO: translate the following. -// 'title.subgroups' => 'Subgroups', -// 'title.add_group' => 'Adding Group', +'title.subgroups' => 'Subgroepen', +'title.add_group' => 'Groep toevoegen', 'title.edit_group' => 'Groep bewerken', 'title.delete_group' => 'Groep aan het verwijderen', 'title.reset_password' => 'Wachtwoord herstellen', @@ -359,11 +352,11 @@ 'form.time.duration_format' => '(uu:mm of 0.0u)', 'form.time.billable' => 'Factureerbaar', 'form.time.uncompleted' => 'Onvolledig', -'form.time.remaining_quota' => 'Te werken uren voor de doelstelling', -'form.time.over_quota' => 'Meer gewerkte uren dan de doelstelling', -// TODO: translate the following. -// 'form.time.remaining_balance' => 'Remaining balance', -// 'form.time.over_balance' => 'Over balance', +// TODO: The following 4 strings may need to be shorter for mobile apps. +'form.time.remaining_quota' => 'Nog te werken uren voor de doelstelling deze maand', +'form.time.over_quota' => 'Meer gewerkte uren dan de doelstelling deze maand', +'form.time.remaining_balance' => 'Minder gewerkte uren dan de doelstelling in ratio met de verstreken dagen', +'form.time.over_balance' => 'Meer gewerkte uren dan de doelstelling in ratio met de verstreken dagen', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Dit tijdrecord is opgeslagen met alleen een starttijd. Dit is geen fout.', @@ -475,8 +468,7 @@ 'form.group_edit.allow_overlap' => 'Sta overlapping van tijden toe', 'form.group_edit.future_entries' => 'Toevoegingen toestaan in de toekomst', 'form.group_edit.uncompleted_indicators' => 'Onvolledige indicatoren', -// TODO: translate the following. -// 'form.group_edit.confirm_save' => 'Confirm saving', +'form.group_edit.confirm_save' => 'Bevestig dat je wilt opslaan', 'form.group_edit.allow_ip' => 'Toegestane IP adressen', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4b4fc4465..d7ec5d2b7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4704 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4705 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e40a312eb20155b967a0ffdd1b3f6b36398a5944 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 16 Jan 2019 00:40:16 +0000 Subject: [PATCH 0633/1848] Removed populate.sql from dockerfile. --- .gitignore | 1 - WEB-INF/templates/footer.tpl | 2 +- dockerfile-db | 4 ---- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 0dba767f9..92e2728c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ config.php -populate.sql WEB-INF/templates_c/*.* WEB-INF/templates_c/import_* WEB-INF/templates_c/tt* diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d7ec5d2b7..d49ca6d73 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4705 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4706 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dockerfile-db b/dockerfile-db index b13673952..757aa0b30 100644 --- a/dockerfile-db +++ b/dockerfile-db @@ -3,7 +3,3 @@ FROM mariadb:latest # Copy database creation script. COPY mysql.sql /docker-entrypoint-initdb.d/ - -# Copy database population script, if available. -# TODO: design a better directory structure. -COPY populate.sql /docker-entrypoint-initdb.d/ From 6079edfe4444d2d0bc2f220f8823d6fcc57f2dd5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 19 Jan 2019 10:22:32 +0000 Subject: [PATCH 0634/1848] Imporoved isTrue function to get rid of PHP warnings. --- WEB-INF/lib/Auth.class.php | 6 +++--- WEB-INF/lib/auth/Auth_db.class.php | 2 +- WEB-INF/lib/auth/Auth_ldap.class.php | 24 ++++++++++++------------ WEB-INF/lib/common.lib.php | 2 +- WEB-INF/lib/mail/Mailer.class.php | 6 +++--- WEB-INF/templates/footer.tpl | 2 +- login.php | 2 +- mobile/login.php | 2 +- register.php | 2 +- tofile.php | 8 ++++---- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/WEB-INF/lib/Auth.class.php b/WEB-INF/lib/Auth.class.php index d57a0c4a3..96ea86926 100644 --- a/WEB-INF/lib/Auth.class.php +++ b/WEB-INF/lib/Auth.class.php @@ -64,7 +64,7 @@ function isPasswordExternal() function doLogin($login, $password) { $auth = $this->authenticate($login, $password); - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '
'; var_dump($auth); echo '
'; } @@ -77,13 +77,13 @@ function doLogin($login, $password) { $sql = "SELECT id FROM tt_users WHERE login = ".$mdb2->quote($login)." AND status = 1"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) { - if (isTrue(AUTH_DEBUG)) + if (isTrue('AUTH_DEBUG')) echo 'db error!
'; return false; } $val = $res->fetchRow(); if (!$val['id']) { - if (isTrue(AUTH_DEBUG)) + if (isTrue('AUTH_DEBUG')) echo 'login "'.$login.'" does not exist in Time Tracker database.
'; return false; } diff --git a/WEB-INF/lib/auth/Auth_db.class.php b/WEB-INF/lib/auth/Auth_db.class.php index bdde007a9..a7ae0d3fa 100644 --- a/WEB-INF/lib/auth/Auth_db.class.php +++ b/WEB-INF/lib/auth/Auth_db.class.php @@ -57,7 +57,7 @@ function authenticate($login, $password) return array('login'=>$login,'id'=>$val['id']); } else { // If the OLD_PASSWORDS option is defined - set it. - if (isTrue(OLD_PASSWORDS)) { + if (isTrue('OLD_PASSWORDS')) { $sql = "SET SESSION old_passwords = 1"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/lib/auth/Auth_ldap.class.php b/WEB-INF/lib/auth/Auth_ldap.class.php index 23ea127e6..52d4fabe3 100644 --- a/WEB-INF/lib/auth/Auth_ldap.class.php +++ b/WEB-INF/lib/auth/Auth_ldap.class.php @@ -96,7 +96,7 @@ function authenticate($login, $password) $lc = ldap_connect($this->params['server']); - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '
'; echo '$lc='; var_dump($lc); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; @@ -106,7 +106,7 @@ function authenticate($login, $password) ldap_set_option($lc, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($lc, LDAP_OPT_REFERRALS, 0); - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { ldap_set_option($lc, LDAP_OPT_DEBUG_LEVEL, 7); } @@ -119,13 +119,13 @@ function authenticate($login, $password) $login .= '@' . $this->params['default_domain']; } - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '$login='; var_dump($login); echo '
'; } $lb = @ldap_bind($lc, $login, $password); - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '$lb='; var_dump($lb); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -142,7 +142,7 @@ function authenticate($login, $password) $fields = array('memberof'); $sr = @ldap_search($lc, $this->params['base_dn'], $filter, $fields); - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '$sr='; var_dump($sr); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -154,7 +154,7 @@ function authenticate($login, $password) $entries = @ldap_get_entries($lc, $sr); - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '$entries='; var_dump($entries); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -173,7 +173,7 @@ function authenticate($login, $password) $groups[] = substr($grp_fields[0], 3); } - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '$member_of'; var_dump($member_of); echo '
'; }; @@ -195,7 +195,7 @@ function authenticate($login, $password) // Assuming OpenLDAP server. $login_oldap = 'uid='.$login.','.$this->params['base_dn']; - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '$login_oldap='; var_dump($login_oldap); echo '
'; } @@ -207,7 +207,7 @@ function authenticate($login, $password) $lb = @ldap_bind($lc, $login_oldap, $password); - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '$lb='; var_dump($lb); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -225,7 +225,7 @@ function authenticate($login, $password) $fields = array('samaccountname', 'mail', 'memberof', 'department', 'displayname', 'telephonenumber', 'primarygroupid'); $sr = @ldap_search($lc, $this->params['base_dn'], $filter, $fields); - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '$sr='; var_dump($sr); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -238,7 +238,7 @@ function authenticate($login, $password) $entries = @ldap_get_entries($lc, $sr); - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '$entries='; var_dump($entries); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -258,7 +258,7 @@ function authenticate($login, $password) $groups[] = substr($grp_fields[0], 3); } - if (isTrue(AUTH_DEBUG)) { + if (isTrue('AUTH_DEBUG')) { echo '$member_of'; var_dump($member_of); echo '
'; } diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index f483b3d4c..6526d730c 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -165,7 +165,7 @@ function check_extension($ext) // isTrue is a helper function to return correct false for older config.php values defined as a string 'false'. function isTrue($val) { - return ($val === true); + return (defined($val) && constant($val) === true); } // ttValidString is used to check user input to validate a string. diff --git a/WEB-INF/lib/mail/Mailer.class.php b/WEB-INF/lib/mail/Mailer.class.php index 68142028e..30f0ffb64 100644 --- a/WEB-INF/lib/mail/Mailer.class.php +++ b/WEB-INF/lib/mail/Mailer.class.php @@ -104,8 +104,8 @@ function send($subject, $data) { $port = defined('MAIL_SMTP_PORT') ? MAIL_SMTP_PORT : '25'; $username = defined('MAIL_SMTP_USER') ? MAIL_SMTP_USER : null; $password = defined('MAIL_SMTP_PASSWORD') ? MAIL_SMTP_PASSWORD : null; - $auth = isTrue(MAIL_SMTP_AUTH); - $debug = isTrue(MAIL_SMTP_DEBUG); + $auth = isTrue('MAIL_SMTP_AUTH'); + $debug = isTrue('MAIL_SMTP_DEBUG'); $mail = Mail::factory('smtp', array ('host' => $host, 'port' => $port, @@ -116,7 +116,7 @@ function send($subject, $data) { break; } - if (isTrue(MAIL_SMTP_DEBUG)) + if (isTrue('MAIL_SMTP_DEBUG')) PEAR::setErrorHandling(PEAR_ERROR_PRINT); $res = $mail->send($recipients, $headers, $data); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d49ca6d73..013c87a7e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4706 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4707 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/login.php b/login.php index e7254152c..68a80678f 100644 --- a/login.php +++ b/login.php @@ -75,7 +75,7 @@ } } // isPost -if(!isTrue(MULTITEAM_MODE) && !ttOrgHelper::getOrgs()) +if(!isTrue('MULTITEAM_MODE') && !ttOrgHelper::getOrgs()) $err->add($i18n->get('error.no_groups')); // Determine whether to show login hint. It is currently used only for Windows LDAP authentication. diff --git a/mobile/login.php b/mobile/login.php index 59fc6000f..26b75db46 100644 --- a/mobile/login.php +++ b/mobile/login.php @@ -80,7 +80,7 @@ } } // isPost -if(!isTrue(MULTITEAM_MODE) && !ttOrgHelper::getOrgs()) +if(!isTrue('MULTITEAM_MODE') && !ttOrgHelper::getOrgs()) $err->add($i18n->get('error.no_groups')); // Determine whether to show login hint. It is currently used only for Windows LDAP authentication. diff --git a/register.php b/register.php index 0a8e6d156..4c923c730 100644 --- a/register.php +++ b/register.php @@ -29,7 +29,7 @@ require_once('initialize.php'); import('form.Form'); -if (!isTrue(MULTITEAM_MODE) || $auth->isPasswordExternal()) { +if (!isTrue('MULTITEAM_MODE') || $auth->isPasswordExternal()) { header('Location: login.php'); exit(); } diff --git a/tofile.php b/tofile.php index 990b8a555..3934471de 100644 --- a/tofile.php +++ b/tofile.php @@ -94,7 +94,7 @@ print "\t<".$group_by_tag.">\n"; if ($bean->getAttribute('chduration')) { $val = $subtotal['time']; - if($val && isTrue(EXPORT_DECIMAL_DURATION)) + if($val && isTrue('EXPORT_DECIMAL_DURATION')) $val = time_to_decimal($val); print "\t\n"; } @@ -126,7 +126,7 @@ if ($bean->getAttribute('chfinish')) print "\t\n"; if ($bean->getAttribute('chduration')) { $duration = $item['duration']; - if($duration && isTrue(EXPORT_DECIMAL_DURATION)) + if($duration && isTrue('EXPORT_DECIMAL_DURATION')) $duration = time_to_decimal($duration); print "\t\n"; } @@ -179,7 +179,7 @@ print '"'.$subtotal['name'].'"'; if ($bean->getAttribute('chduration')) { $val = $subtotal['time']; - if($val && isTrue(EXPORT_DECIMAL_DURATION)) + if($val && isTrue('EXPORT_DECIMAL_DURATION')) $val = time_to_decimal($val); print ',"'.$val.'"'; } @@ -223,7 +223,7 @@ if ($bean->getAttribute('chfinish')) print ',"'.$item['finish'].'"'; if ($bean->getAttribute('chduration')) { $val = $item['duration']; - if($val && isTrue(EXPORT_DECIMAL_DURATION)) + if($val && isTrue('EXPORT_DECIMAL_DURATION')) $val = time_to_decimal($val); print ',"'.$val.'"'; } From 25ca552776a80fedd587231f56c8bc13c1836390 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 19 Jan 2019 10:38:34 +0000 Subject: [PATCH 0635/1848] Fixed header. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 013c87a7e..62e2c4fdb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4707 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4708 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 8555447b5..a30669f2c 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -149,7 +149,7 @@
  {$i18n.menu.login} · - {if isTrue($smarty.const.MULTITEAM_MODE) && $smarty.const.AUTH_MODULE == 'db'} + {if $smarty.const.MULTITEAM_MODE && $smarty.const.AUTH_MODULE == 'db'} {$i18n.menu.create_group} · {/if} {$i18n.menu.forum} · From 78fd633e9c800e3f9b53b0dcff2ac47c8bfbad4a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 19 Jan 2019 22:46:52 +0000 Subject: [PATCH 0636/1848] A better fix for header. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 62e2c4fdb..01e40bce1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4708 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4709 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index a30669f2c..86bc619ce 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -149,7 +149,7 @@
  {$i18n.menu.login} · - {if $smarty.const.MULTITEAM_MODE && $smarty.const.AUTH_MODULE == 'db'} + {if isTrue('MULTITEAM_MODE') && $smarty.const.AUTH_MODULE == 'db'} {$i18n.menu.create_group} · {/if} {$i18n.menu.forum} · From 57539cbc8f8094151cbf9a042635f11962968435 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 24 Jan 2019 17:08:13 +0000 Subject: [PATCH 0637/1848] Work in progress integrating Estonian translation as per PR#71. --- WEB-INF/resources/et.lang.php | 272 ++++++++++++++++------------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 130 insertions(+), 144 deletions(-) diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 1387bea36..38d2e3a7d 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -36,226 +36,212 @@ $i18n_weekdays = array('Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'); $i18n_weekdays_short = array('P', 'E', 'T', 'K', 'N', 'R', 'L'); // format mm/dd -$i18n_holidays = array('01/01', '02/24', '04/10', '04/12', '05/01', '05/31', '06/23', '06/24', '08/20', '12/24', '12/25', '12/26'); +$i18n_holidays = array('01/01', '02/24', '04/19', '04/21', '05/01', '06/09', '06/23', '06/24', '08/20', '12/24', '12/25', '12/26'); $i18n_key_words = array( // Menus - short selection strings that are displayed on top of application web pages. // Example: https://timetracker.anuko.com (black menu on top). -'menu.login' => 'Login', -'menu.logout' => 'Logout', -// TODO: translate the following. -// 'menu.forum' => 'Forum', +'menu.login' => 'Sisene', +'menu.logout' => 'Välju', +'menu.forum' => 'Foorum', 'menu.help' => 'Abiinfo', -// TODO: translate the following. -// 'menu.create_group' => 'Create Group', -'menu.profile' => 'Profiili', -// TODO: translate the following. -// 'menu.group' => 'Group', -// 'menu.plugins' => 'Plugins', -'menu.time' => 'Aeg', -// TODO: translate the following. -// 'menu.expenses' => 'Expenses', +'menu.create_group' => 'Loo grupp', +'menu.profile' => 'Profiil', +'menu.group' => 'Grupp', +'menu.plugins' => 'Lisad', +'menu.time' => 'Ajaarvestus', +'menu.expenses' => 'Kulud', 'menu.reports' => 'Raportid', -// TODO: translate the following. -// 'menu.charts' => 'Charts', +'menu.charts' => 'Diagrammid', 'menu.projects' => 'Projektid', -// TODO: translate the following. -// 'menu.tasks' => 'Tasks', +'menu.tasks' => 'Tööülesanded', 'menu.users' => 'Kasutajad', -// TODO: translate the following. -// 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', -// 'menu.export' => 'Export', +'menu.groups' => 'Grupid', +'menu.subgroups' => 'Alamgrupid', +'menu.export' => 'Eksport', // TODO: is this a correct term as an opposite of "Import"? 'menu.clients' => 'Kliendid', 'menu.options' => 'Suvandid', // Footer - strings on the bottom of most pages. -// TODO: translate the following. -// 'footer.contribute_msg' => 'You can contribute to Time Tracker in different ways.', -// 'footer.credits' => 'Credits', -// 'footer.license' => 'License', -// 'footer.improve' => 'Contribute', // Translators: this could mean "Improve", if it makes better sense in your language. - // This is a link to a webpage that describes how to contribute to the project. +'footer.contribute_msg' => 'Sul on võimalik mitmeti panustada Time Tracker\\\'i arendamisse.', +'footer.credits' => 'Tunnustused', +'footer.license' => 'Litsents', +'footer.improve' => 'Panusta', // Error messages. -// TODO: translate the following. -// 'error.access_denied' => 'Access denied.', -// 'error.sys' => 'System error.', +'error.access_denied' => 'Puudub ligipääs.', +'error.sys' => 'Rakenduse viga.', 'error.db' => 'Andmebaasi viga.', -// TODO: translate the following. -// 'error.feature_disabled' => 'Feature is disabled.', -'error.field' => 'Valed "{0}" andmed.', +'error.feature_disabled' => 'Rakenduse funktsionaalsus on välja lülitatud.', +'error.field' => 'Välja "{0}" andmed ei vasta nõutele.', 'error.empty' => 'Väli "{0}" on tühi.', 'error.not_equal' => 'Väli "{0}" ei ole väljaga "{1}" võrdne.', -// TODO: translate the following. -// 'error.interval' => 'Field "{0}" must be greater than "{1}".', +'error.interval' => 'Välja "{0}" väärtus peab olema suurem kui välja "{1}" väärtus.', 'error.project' => 'Vali projekt.', -// TODO: translate the following. -// 'error.task' => 'Select task.', +'error.task' => 'Vali tööülesanne.', 'error.client' => 'Vali klient.', -// TODO: translate the following. -// 'error.report' => 'Select report.', -// 'error.record' => 'Select record.', -'error.auth' => 'Vale login või salasõna.', -// TODO: translate the following. -// 'error.user_exists' => 'User with this login already exists.', -// 'error.object_exists' => 'Object with this name already exists.', -// 'error.invoice_exists' => 'Invoice with this number already exists.', +'error.report' => 'Vali raport.', +'error.record' => 'Vali kirje.', +'error.auth' => 'Autentimine ebaõnnestus.', +'error.user_exists' => 'Selle nimega kasutaja on juba kasutusel.', +'error.object_exists' => 'Sellise nimega objekt on juba olemas.', +'error.invoice_exists' => 'Arve number on juba kasutusel.', + +// TODO: Improve translation of error.role_exists. // 'error.role_exists' => 'Role with this rank already exists.', +// It is displayed when user tries to add a role with an already existing RANK. +// There is no indication of RANK collision in this translation. +// 'error.role_exists' => 'Kasutaja roll on juba kasutusel.', + +// TODO: Improve translation of error.no_invoiceable_items. // 'error.no_invoiceable_items' => 'There are no invoiceable items.', -// 'error.no_login' => 'No user with this login.', -'error.no_groups' => 'Sinu andmebaas on tühi. Logi adminina sisse ja loo uus meeskond.', // TODO: replace "team" with "group". +// This error shows up when user tries to ctreate a new invoice, +// but there are no billable records such time or expenses to include. +// Google auto-translates below as "No billable invoices found." which seems wrong. +// 'error.no_invoiceable_items' => 'Arveldatavaid arveid ei leitud.', + +'error.no_login' => 'Sellise tunnusega kasutajat ei ole.', + +// TODO: Improve translation of error.no_groups. Replace meeskond with grupp? +// Why? Before supporting subgroups, Time Tracker organized users in "teams". +// Now we have "groups" with "subgroups", renamed from original "team". +// Meeskond below is a glimpse from earlier versions, before renaming occurred. +'error.no_groups' => 'Sinu andmebaas on tühi. Logi administraatorina sisse ja loo uus meeskond.', + 'error.upload' => 'Viga faili vastuvõtmisel.', -// TODO: translate the following. -// 'error.range_locked' => 'Date range is locked.', -// 'error.mail_send' => 'Error sending mail. Use MAIL_SMTP_DEBUG for diagnostics.', -// 'error.no_email' => 'No email associated with this login.', -// 'error.uncompleted_exists' => 'Uncompleted entry already exists. Close or delete it.', -// 'error.goto_uncompleted' => 'Go to uncompleted entry.', -// 'error.overlap' => 'Time interval overlaps with existing records.', -// 'error.future_date' => 'Date is in future.', -// TODO: translate the following. -// 'error.xml' => 'Error in XML file at line %d: %s.', -// 'error.cannot_import' => 'Cannot import: %s.', -// 'error.format' => 'Invalid file format.', -// 'error.user_count' => 'Limit on user count.', -// 'error.expired' => 'Expiration date reached.', +'error.range_locked' => 'Kuupäevavahemik on lukus.', +'error.mail_send' => 'E-posti saatmisel tekkis viga. Vea tuvastamiseks kasuta MAIL_SMTP_DEBUG muutujat.', +'error.no_email' => 'Kasutajaga pole ühtegi e-posti seotud.', +'error.uncompleted_exists' => 'Leiti varasemalt lõpetamata kirje. Sulge või kustuta see.', +'error.goto_uncompleted' => 'Ava lõpetamata kirje.', +'error.overlap' => 'Ajavahemik kattub varasema kirjega.', +'error.future_date' => 'Kuupäev on tulevikus.', +'error.xml' => 'Viga XML failis, real %d: %s.', +'error.cannot_import' => 'Ebaõnnestunud import: %s.', +'error.format' => 'Faili formaat on vale.', +'error.user_count' => 'Kasutajate arvu piirang.', +'error.expired' => 'Kehtivusaeg on lõppenud.', // Warning messages. -// TODO: translate the following. -// 'warn.sure' => 'Are you sure?', -// 'warn.confirm_save' => 'Date has changed. Confirm saving, not copying this item.', +'warn.sure' => 'Oled kindel?', +'warn.confirm_save' => 'Kuupäeva on muudetud. Muudatuse kinnitamisel ei varundata esialgset kirjet, vaid muudetakse seda. Kinnitad muudatuse?', // Success messages. -// TODO: translate the following. -// 'msg.success' => 'Operation completed successfully.', +'msg.success' => 'Tegevus oli edukas.', // Labels for buttons. -'button.login' => 'Login', -'button.now' => 'Kohe', +'button.login' => 'Sisene', +'button.now' => 'Nüüd', 'button.save' => 'Salvesta', -// TODO: translate the following. -// 'button.copy' => 'Copy', +'button.copy' => 'Kopeeri', 'button.cancel' => 'Tühista', 'button.submit' => 'Postita', 'button.add' => 'Lisa', 'button.delete' => 'Kustuta', 'button.generate' => 'Loo', -'button.reset_password' => 'Tühjenda salasõna', +'button.reset_password' => 'Lähtesta salasõna', 'button.send' => 'Saada', -'button.send_by_email' => 'Saada e-mailiga', -'button.create_group' => 'Loo meeskond', // TODO: replace "team" with "group". -'button.export' => 'Ekspordi meeskond', // TODO: replace "team" with "group". -'button.import' => 'Impordi meeskond', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.close' => 'Close', -// 'button.stop' => 'Stop', +'button.send_by_email' => 'Saada e-postiga', +'button.create_group' => 'Loo grupp', +'button.export' => 'Ekspordi grupp', +'button.import' => 'Impordi grupp', +'button.close' => 'Sulge', +'button.stop' => 'Stopp', // Labels for controls on forms. Labels in this section are used on multiple forms. -// TODO: translate the following. -// 'label.group_name' => 'Group name', -// 'label.address' => 'Address', +'label.group_name' => 'Grupi nimi', +'label.address' => 'Aadress', 'label.currency' => 'Valuuta', -// TODO: translate the following. -// 'label.manager_name' => 'Manager name', -// 'label.manager_login' => 'Manager login', +'label.manager_name' => 'Halduri nimi', +'label.manager_login' => 'Halduri sisenemine', 'label.person_name' => 'Nimi', 'label.thing_name' => 'Nimi', -'label.login' => 'Login', +'label.login' => 'Kasutajanimi', 'label.password' => 'Salasõna', 'label.confirm_password' => 'Kinnita salasõna', -// TODO: translate the following. -// 'label.email' => 'Email', +'label.email' => 'E-post', 'label.cc' => 'Cc', -// TODO: translate the following. -// 'label.bcc' => 'Bcc', +'label.bcc' => 'Bcc', 'label.subject' => 'Teema', 'label.date' => 'Kuupäev', -'label.start_date' => 'Algab kuupäevast', -'label.end_date' => 'Lõpeb kuupäeval', +'label.start_date' => 'Algus kuupäev', +'label.end_date' => 'Lõpu kuupäev', 'label.user' => 'Kasutaja', 'label.users' => 'Kasutajad', -// TODO: translate the following. -// 'label.group' => 'Group', -// 'label.subgroups' => 'Subgroups', -// 'label.roles' => 'Roles', +'label.group' => 'Grupp', +'label.subgroups' => 'Alamgrupid', +'label.roles' => 'Rollid', 'label.client' => 'Klient', 'label.clients' => 'Kliendid', -// TODO: translate the following. -// 'label.option' => 'Option', +'label.option' => 'Valik', 'label.invoice' => 'Arve', 'label.project' => 'Projekt', 'label.projects' => 'Projektid', -// TODO: translate the following. -// 'label.task' => 'Task', -// 'label.tasks' => 'Tasks', -// 'label.description' => 'Description', +'label.task' => 'Tööülesanne', +'label.tasks' => 'Tööülesanded', +'label.description' => 'Kirjeldus', 'label.start' => 'Algus', 'label.finish' => 'Lõpp', 'label.duration' => 'Kestus', 'label.note' => 'Märkus', 'label.notes' => 'Märkused', -// TODO: translate the following. -// 'label.item' => 'Item', -// 'label.cost' => 'Cost', -// 'label.ip' => 'IP', -// 'label.day_total' => 'Day total', -'label.week_total' => 'Nädalane summa', -// TODO: translate the following. -// 'label.month_total' => 'Month total', +'label.item' => 'Ese', +'label.cost' => 'Hind', +'label.ip' => 'IP', +'label.day_total' => 'Päeva summa', +'label.week_total' => 'Nädala summa', +'label.month_total' => 'Kuu summa', 'label.today' => 'Täna', -// TODO: translate the following. -// 'label.view' => 'View', +'label.view' => 'Vaata', 'label.edit' => 'Muuda', 'label.delete' => 'Kustuta', -'label.configure' => 'Konfigureeri', +'label.configure' => 'Seadista', 'label.select_all' => 'Vali kõik', 'label.select_none' => 'Märgi kõik mittevalituks', -// TODO: translate the following. -// 'label.day_view' => 'Day view', -// 'label.week_view' => 'Week view', +'label.day_view' => 'Päeva vaade', +'label.week_view' => 'Nädala vaade', 'label.id' => 'ID', -// TODO: translate the following. -// 'label.language' => 'Language', -// 'label.decimal_mark' => 'Decimal mark', -// 'label.date_format' => 'Date format', -// 'label.time_format' => 'Time format', -// 'label.week_start' => 'First day of week', +'label.language' => 'Keel', +'label.decimal_mark' => 'Koma märk', +'label.date_format' => 'Kuupäeva formaat', +'label.time_format' => 'Kella formaat', +'label.week_start' => 'Nädala alguspäev', 'label.comment' => 'Kommentaar', 'label.status' => 'Seisund', -'label.tax' => 'Maks', +'label.tax' => 'Maksud', 'label.subtotal' => 'Vahesumma', 'label.total' => 'Kokku', -// TODO: translate the following. -// 'label.client_name' => 'Client name', -// 'label.client_address' => 'Client address', +'label.client_name' => 'Kliendi nimi', +'label.client_address' => 'Kliendi aadress', 'label.or' => 'või', -// TODO: translate the following. -// 'label.error' => 'Error', -// 'label.ldap_hint' => 'Type your Windows login and password in the fields below.', +'label.error' => 'Viga', +'label.ldap_hint' => 'Kasuta allolevas tabelis oma Windows\\\'i kasutajatunnuseid.', 'label.required_fields' => '* nõutud väljad', -// TODO: translate the following. +// TODO: Translate label.on_behalf, perhaps trying as "instead of". // 'label.on_behalf' => 'on behalf of', 'label.role_manager' => '(haldur)', 'label.role_comanager' => '(kaashaldur)', 'label.role_admin' => '(administraator)', -// TODO: translate the following. -// 'label.page' => 'Page', -// 'label.condition' => 'Condition', -// 'label.yes' => 'yes', -// 'label.no' => 'no', +'label.page' => 'Lehekülg', +'label.condition' => 'Tingimus', +'label.yes' => 'jah', +'label.no' => 'ei', // Labels for plugins (extensions to Time Tracker that provide additional features). -// TODO: translate the following. -// 'label.custom_fields' => 'Custom fields', -// 'label.monthly_quotas' => 'Monthly quotas', -// 'label.type' => 'Type', -// 'label.type_dropdown' => 'dropdown', -// 'label.type_text' => 'text', -// 'label.required' => 'Required', +'label.custom_fields' => 'Eriväljad', +'label.monthly_quotas' => 'Kuu kvoot', +'label.type' => 'Tüüp', +'label.type_dropdown' => 'rippmenüü', +'label.type_text' => 'tekst', +'label.required' => 'Kohustuslik', 'label.fav_report' => 'Lemmikraport', -// TODO: translate the following. + +// TODO: translate label.schedule. +// The meaning of this is "cron schedule" - or a spec for Unix "cron" program. +// See config pages for Locking and Notifications plugin, where it is used. // 'label.schedule' => 'Schedule', + +// TODO: translate the following. // 'label.what_is_it' => 'What is it?', // 'label.expense' => 'Expense', // 'label.quantity' => 'Quantity', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 01e40bce1..090111b5e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4709 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4710 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e58cee63708a69bf369c7ade35b015e2ba6e8dfd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 24 Jan 2019 18:54:11 +0000 Subject: [PATCH 0638/1848] A bit more work in progress integrating Estonian translation improvements as per PR#71. --- WEB-INF/resources/et.lang.php | 151 +++++++++++++++------------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 67 insertions(+), 86 deletions(-) diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 38d2e3a7d..b34ec1230 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -235,116 +235,97 @@ 'label.type_text' => 'tekst', 'label.required' => 'Kohustuslik', 'label.fav_report' => 'Lemmikraport', - -// TODO: translate label.schedule. -// The meaning of this is "cron schedule" - or a spec for Unix "cron" program. -// See config pages for Locking and Notifications plugin, where it is used. -// 'label.schedule' => 'Schedule', - -// TODO: translate the following. -// 'label.what_is_it' => 'What is it?', -// 'label.expense' => 'Expense', -// 'label.quantity' => 'Quantity', -// 'label.paid_status' => 'Paid status', -// 'label.paid' => 'Paid', -// 'label.mark_paid' => 'Mark paid', -// 'label.week_note' => 'Week note', -// 'label.week_list' => 'Week list', -// 'label.work_units' => 'Work units', -// 'label.work_units_short' => 'Units', +'label.schedule' => 'Ajakava', +'label.what_is_it' => 'Mis see on?', +'label.expense' => 'Kulu', +'label.quantity' => 'Kogus', +'label.paid_status' => 'Makse olek', +'label.paid' => 'Makstud', +'label.mark_paid' => 'Märgi makstuks', +'label.week_note' => 'Nädala märge', +'label.week_list' => 'Nädala nimekiri', +'label.work_units' => 'Töö ühikud', +'label.work_units_short' => 'Ühikud', 'label.totals_only' => 'Ainult summad', -// TODO: translate the following. -// 'label.quota' => 'Quota', +'label.quota' => 'Kvoot', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. // Compare with English file to see how it is done there and do Estonian titles similarly. // Specifically: lisamine vs lisa, etc. -// TODO: Translate the following. -// 'title.error' => 'Error', -// 'title.success' => 'Success', -'title.login' => 'Login', -'title.groups' => 'Meeskonnad', // TODO: change "teams" to "groups". -// TODO: translate the following. -// 'title.subgroups' => 'Subgroups', -// 'title.add_group' => 'Adding Group', -// 'title.edit_group' => 'Editing Group', -'title.delete_group' => 'Kustuta meeskond', // TODO: change "team" to "group". +'title.error' => 'Viga', +'title.success' => 'Õnnestumine', +'title.login' => 'Sisene', +'title.groups' => 'Grupid', +'title.subgroups' => 'Alamgrupid', +'title.add_group' => 'Lisa grupp', +'title.edit_group' => 'Muuda gruppi', +'title.delete_group' => 'Kustuta grupp', 'title.reset_password' => 'Tühjenda salasõna', -// TODO: translate the following. -// 'title.change_password' => 'Changing Password', -'title.time' => 'Aeg', +'title.change_password' => 'Muuda salasõna', +'title.time' => 'Ajaarvestus', 'title.edit_time_record' => 'Ajakande muutmine', 'title.delete_time_record' => 'Ajakande kustutamine', -// TODO: translate the following. -// 'title.expenses' => 'Expenses', -// 'title.edit_expense' => 'Editing Expense Item', -// 'title.delete_expense' => 'Deleting Expense Item', -// 'title.predefined_expenses' => 'Predefined Expenses', -// 'title.add_predefined_expense' => 'Adding Predefined Expense', -// 'title.edit_predefined_expense' => 'Editing Predefined Expense', -// 'title.delete_predefined_expense' => 'Deleting Predefined Expense', +'title.expenses' => 'Kulud', +'title.edit_expense' => 'Kulukirje muutmine', +'title.delete_expense' => 'Kulukirje kustutamine', +'title.predefined_expenses' => 'Eelmääratud kulukirje', +'title.add_predefined_expense' => 'Lisa eelmääratud kulukirje', +'title.edit_predefined_expense' => 'Muuda eelmääratut kulukirjet', +'title.delete_predefined_expense' => 'Kustuta eelmääratud kulukirje', 'title.reports' => 'Raportid', -// TODO: translate the following. -// 'title.report' => 'Report', -// 'title.send_report' => 'Sending Report', +'title.report' => 'Raport', +'title.send_report' => 'Saadan raportit', 'title.invoice' => 'Arve', -// TODO: translate the following. -// 'title.send_invoice' => 'Sending Invoice', -// 'title.charts' => 'Charts', +'title.send_invoice' => 'Saada arve', +'title.charts' => 'Diagrammid', 'title.projects' => 'Projektid', 'title.add_project' => 'Projekti lisamine', 'title.edit_project' => 'Projekti muutmine', 'title.delete_project' => 'Projekti kustutamine', -// TODO: translate the following. -// 'title.tasks' => 'Tasks', -// 'title.add_task' => 'Adding Task', -// 'title.edit_task' => 'Editing Task', -// 'title.delete_task' => 'Deleting Task', +'title.tasks' => 'Tööülesanded', +'title.add_task' => 'Lisa tööülesanne', +'title.edit_task' => 'Muuda tööülesannet', +'title.delete_task' => 'Kustuta tööülesanne', 'title.users' => 'Kasutajad', -'title.add_user' => 'Kasutaja lisamine', // TODO: is this correct? +'title.add_user' => 'Kasutaja lisamine', 'title.edit_user' => 'Kasutaja muutmine', 'title.delete_user' => 'Kasutaja kustutamine', -// TODO: translate the following. -// 'title.roles' => 'Roles', -// 'title.add_role' => 'Adding Role', -// 'title.edit_role' => 'Editing Role', -// 'title.delete_role' => 'Deleting Role', +'title.roles' => 'Rollid', +'title.add_role' => 'Rolli lisamine', +'title.edit_role' => 'Rolli muutmine', +'title.delete_role' => 'Rolli kustutamine', 'title.clients' => 'Kliendid', 'title.add_client' => 'Lisa klient', 'title.edit_client' => 'Muuda klienti', 'title.delete_client' => 'Kustuta klient', 'title.invoices' => 'Arved', -// TODO: translate the following. -// 'title.add_invoice' => 'Adding Invoice', -// 'title.view_invoice' => 'Viewing Invoice', -// 'title.delete_invoice' => 'Deleting Invoice', -// 'title.notifications' => 'Notifications', -// 'title.add_notification' => 'Adding Notification', -// 'title.edit_notification' => 'Editing Notification', -// 'title.delete_notification' => 'Deleting Notification', -// 'title.monthly_quotas' => 'Monthly Quotas', -// 'title.export' => 'Exporting Group Data', -// 'title.import' => 'Importing Group Data', +'title.add_invoice' => 'Arve lisamine', +'title.view_invoice' => 'Arve vaatamine', +'title.delete_invoice' => 'Arve kustutamine', +'title.notifications' => 'Teated', +'title.add_notification' => 'Teate lisamine', +'title.edit_notification' => 'Teate muutmine', +'title.delete_notification' => 'Teate kustutamine', +'title.monthly_quotas' => 'Kuu kvoot', +'title.export' => 'Grupi andmete alla laadimine', +'title.import' => 'Grupi andmete üles laadimine', 'title.options' => 'Suvandid', -'title.profile' => 'Profiili', -// TODO: translate the following. -// 'title.plugins' => 'Plugins', -// 'title.cf_custom_fields' => 'Custom Fields', -// 'title.cf_add_custom_field' => 'Adding Custom Field', -// 'title.cf_edit_custom_field' => 'Editing Custom Field', -// 'title.cf_delete_custom_field' => 'Deleting Custom Field', -// 'title.cf_dropdown_options' => 'Dropdown Options', -// 'title.cf_add_dropdown_option' => 'Adding Option', -// 'title.cf_edit_dropdown_option' => 'Editing Option', -// 'title.cf_delete_dropdown_option' => 'Deleting Option', -// NOTE TO TRANSLATORS: Locking is a feature to lock records from modifications (ex: weekly on Mondays we lock all previous weeks). -// It is also a name for the Locking plugin on the group settings page. -// 'title.locking' => 'Locking', -// 'title.week_view' => 'Week View', -// 'title.swap_roles' => 'Swapping Roles', -// 'title.work_units' => 'Work Units', +'title.profile' => 'Profiil', +'title.plugins' => 'Lisad', +'title.cf_custom_fields' => 'Eriväljad', +'title.cf_add_custom_field' => 'Lisa eriväli', +'title.cf_edit_custom_field' => 'Muuda erivälja', +'title.cf_delete_custom_field' => 'Kustuta eriväli', +'title.cf_dropdown_options' => 'Rippmenüü valikud', +'title.cf_add_dropdown_option' => 'Lisa valik', +'title.cf_edit_dropdown_option' => 'Muuda valikut', +'title.cf_delete_dropdown_option' => 'Kustuta valik', +'title.locking' => 'Lukustamine', +'title.week_view' => 'Nädala vaade', +'title.swap_roles' => 'Rollivahetus', +'title.work_units' => 'Töö ühikud', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 090111b5e..c4390a2df 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4710 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4711 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From cb50b63fc48f417f17c88cd104c41942f02d2080 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 24 Jan 2019 20:06:53 +0000 Subject: [PATCH 0639/1848] A bit more work in progress on the Estonian file. --- WEB-INF/resources/et.lang.php | 157 ++++++++++++++++------------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 73 insertions(+), 86 deletions(-) diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index b34ec1230..b68296826 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -340,88 +340,82 @@ 'dropdown.current_month' => 'käesolev kuu', 'dropdown.previous_month' => 'eelmine kuu', 'dropdown.selected_month' => 'kuu', -// TODO: translate the following. -// 'dropdown.current_year' => 'this year', -// 'dropdown.previous_year' => 'previous year', -// 'dropdown.selected_year' => 'year', -'dropdown.all_time' => 'kõik ajad', +'dropdown.current_year' => 'käesolev aasta', +'dropdown.previous_year' => 'eelmine aasta', +'dropdown.selected_year' => 'aasta', +'dropdown.all_time' => 'kõik ajavahemikud', 'dropdown.projects' => 'projektid', -// TODO: translate the following. -// 'dropdown.tasks' => 'tasks', +'dropdown.tasks' => 'tööülesanded', 'dropdown.clients' => 'kliendid', -// TODO: translate the following. -// 'dropdown.select' => '--- select ---', -// 'dropdown.select_invoice' => '--- select invoice ---', +'dropdown.select' => '--- vali ---', +'dropdown.select_invoice' => '--- vali arve ---', 'dropdown.status_active' => 'aktiivne', -// TODO: translate the following. -// 'dropdown.status_inactive' => 'inactive', -// 'dropdown.delete' => 'delete', -// 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.paid' => 'paid', -// 'dropdown.not_paid' => 'not paid', +'dropdown.status_inactive' => 'mitte aktiivne', +'dropdown.delete' => 'kustuta', +'dropdown.do_not_delete' => 'ära kustuta', +'dropdown.paid' => 'makstud', +'dropdown.not_paid' => 'mitte makstud', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Unustasid salasõna?', -// TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +'form.login.about' => 'Anuko Time Tracker on lihtne, lihtsalt kasutatav ja avatud lähtekoodiga ajaarvestussüsteem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. -'form.reset_password.message' => 'Salasõna tühjendamise käsk edastatud.', // TODO: add "by email" to match the English string. -// TODO: translate the following. -// 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.message' => 'Salasõna tühistamise teade on saadetud e-postile.', +'form.reset_password.email_subject' => 'Anuko Time Tracker, parooli tühistamise nõue', +'form.reset_password.email_body' => "Lugupeetud Kasutaja,\n\nIP-lt %s on nõutud Teie salasõna lähtestamist. Palun avage allolev link, kui soovite oma parooli lähtestada.\n\n%s\n\nAnuko Time Tracker on lihtne, lihtsalt kasutatav ja avatud lähtekoodiga ajaarvestussüsteem. Lisainfo saamiseks külastage https://www.anuko.com lehekülge.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. -// TODO: translate the following. -// 'form.change_password.tip' => 'Type new password and click on Save.', +'form.change_password.tip' => 'Kirjuta siia oma uus parool ja salvesta.', // Time form. See example at https://timetracker.anuko.com/time.php. -// TODO: translate the following. -// 'form.time.duration_format' => '(hh:mm or 0.0h)', -'form.time.billable' => 'Arvestatav', -// TODO: translate the following. -// 'form.time.uncompleted' => 'Uncompleted', -// 'form.time.remaining_quota' => 'Remaining quota', -// 'form.time.over_quota' => 'Over quota', -// 'form.time.remaining_balance' => 'Remaining balance', -// 'form.time.over_balance' => 'Over balance', +'form.time.duration_format' => '(hh:mm or 0.0h)', +'form.time.billable' => 'Arveldatav', +'form.time.uncompleted' => 'Lõpetamata', +'form.time.remaining_quota' => 'Allesolev kvoot', +'form.time.over_quota' => 'Üle kvoodi', +// Note for translators. "Balance" below means accumulated quota for user since 1st of the month +// until and including a selected day. If a quota is 8 hours a day, then the balance +// is 8 hours multiplied by a number of work days. "Remaining balance" and "Over balance" are +// balance differences with logged hours. +// The term looks confusing, if you have a better idea how to name these things, let us know. +'form.time.remaining_balance' => 'Järelejäänud kontoseis', // TODO: check as per above comment. +'form.time.over_balance' => 'Üle piirmäära', // // TODO: check as per above comment. // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Kanne salvestati ainult alguse ajaga. See ei ole viga.', // Week view form. See example at https://timetracker.anuko.com/week.php. -// TODO: translate the following. -// 'form.week.new_entry' => 'New entry', +'form.week.new_entry' => 'Uus kirje', // Reports form. See example at https://timetracker.anuko.com/reports.php 'form.reports.save_as_favorite' => 'Salvesta lemmikuna', -// TODO: translate the following. -// 'form.reports.confirm_delete' => 'Are you sure you want to delete this favorite report?', -'form.reports.include_billable' => 'arvestatav', -'form.reports.include_not_billable' => 'mittearvestatav', -// TODO: translate the following. -// 'form.reports.include_invoiced' => 'invoiced', -// 'form.reports.include_not_invoiced' => 'not invoiced', +'form.reports.confirm_delete' => 'Oled kindel, et soovid kustutada oma lemmik raportid?', +'form.reports.include_billable' => 'arveldatav', +'form.reports.include_not_billable' => 'mittearveldatav', + +// TODO: Check if translation of form.reports.include_invoiced and form.reports.include_not_invoiced is correct. +// "Invoiced" means that an invoice was issued to client, but may not be necessarily "paid" (yet). +// For paid status there is a plugin called "Paid status", that allows you to mark invoice items as "paid". +// Our concern is that Google auto-translates "arveldamata" as unpaid. Therefore, we may need a fix here. +// 'form.reports.include_invoiced' => 'arveldatud', // TODO: fix as per the above comment, if needed. +// 'form.reports.include_not_invoiced' => 'arveldamata', // TODO: fix as per the above comment, if needed. + 'form.reports.select_period' => 'Vali ajaperiood', 'form.reports.set_period' => 'või märgi kuupäevad', 'form.reports.show_fields' => 'Näita välju', 'form.reports.group_by' => 'Grupeeri', -'form.reports.group_by_no' => '--- ilma grupeerimata ---', +'form.reports.group_by_no' => '--- grupeerimata ---', 'form.reports.group_by_date' => 'kuupäev', 'form.reports.group_by_user' => 'kasutaja', -// TODO: translate the following. -// 'form.reports.group_by_client' => 'client', +'form.reports.group_by_client' => 'klient', 'form.reports.group_by_project' => 'projekt', -// TODO: translate the following. -// 'form.reports.group_by_task' => 'task', +'form.reports.group_by_task' => 'tööülesanne', // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). -'form.report.export' => 'Eksportimine', // TODO: is this correct? We want a verb as in "Export XML" - see report export options. - // The current combined English string is "Export PDF, XML or CSV". - // Meaning: user can have a displayed report in these formats. -// TODO: translate the following. -// 'form.report.assign_to_invoice' => 'Assign to invoice', +'form.report.export' => 'Eksport', +'form.report.assign_to_invoice' => 'Lisa arvele', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). @@ -429,30 +423,26 @@ 'form.invoice.person' => 'Isik', // Deleting Invoice form. See example at https://timetracker.anuko.com/invoice_delete.php -// 'form.invoice.invoice_to_delete' => 'Invoice to delete', -// 'form.invoice.invoice_entries' => 'Invoice entries', -// 'form.invoice.confirm_deleting_entries' => 'Please confirm deleting invoice entries from Time Tracker.', +'form.invoice.invoice_to_delete' => 'Kustutatav arve', +'form.invoice.invoice_entries' => 'Arve kirjed', +'form.invoice.confirm_deleting_entries' => 'Palun kinnita oma Time Tracker\\\'i arve kirjete kustutamise soovi.', // Charts form. See example at https://timetracker.anuko.com/charts.php -// TODO: translate the following. -// 'form.charts.interval' => 'Interval', -// 'form.charts.chart' => 'Chart', +'form.charts.interval' => 'Ajavahemik', +'form.charts.chart' => 'Diagramm', // Projects form. See example at https://timetracker.anuko.com/projects.php -// TODO: translate the following. -// 'form.projects.active_projects' => 'Active Projects', -// 'form.projects.inactive_projects' => 'Inactive Projects', +'form.projects.active_projects' => 'Aktiivsed projektid', +'form.projects.inactive_projects' => 'Mitteaktiivsed projektid', // Tasks form. See example at https://timetracker.anuko.com/tasks.php -// TODO: translate the following. -// 'form.tasks.active_tasks' => 'Active Tasks', -// 'form.tasks.inactive_tasks' => 'Inactive Tasks', +'form.tasks.active_tasks' => 'Aktiivsed tööülesanded', +'form.tasks.inactive_tasks' => 'Mitteaktiivsed tööülesanded', // Users form. See example at https://timetracker.anuko.com/users.php -// TODO: translate the following. -// 'form.users.active_users' => 'Active Users', -// 'form.users.inactive_users' => 'Inactive Users', -// 'form.users.uncompleted_entry' => 'User has an uncompleted time entry', +'form.users.active_users' => 'Aktiivsed kasutajad', +'form.users.inactive_users' => 'Mitteaktiivsed kasutajad', +'form.users.uncompleted_entry' => 'Kasutajal on lõpetamata aja kanne', 'form.users.role' => 'Roll', 'form.users.manager' => 'Haldur', 'form.users.comanager' => 'Kaashaldur', @@ -460,34 +450,31 @@ 'form.users.default_rate' => 'Vaikimisi tunni hind', // Editing User form. See example at https://timetracker.anuko.com/user_edit.php -// TODO: translate the following. -// 'form.user_edit.swap_roles' => 'Swap roles', +'form.user_edit.swap_roles' => 'Rollivahetus', // Roles form. See example at https://timetracker.anuko.com/roles.php -// TODO: translate the following. +// TODO: translate the following. Proposed 'Aktiivne roll' and 'Mitteaktiivne roll' seem problematic, +// as they apper to refer to a singulr role (while we need multiple roles, similar to form.projects.active_projects). // 'form.roles.active_roles' => 'Active Roles', // 'form.roles.inactive_roles' => 'Inactive Roles', -// 'form.roles.rank' => 'Rank', -// 'form.roles.rights' => 'Rights', -// 'form.roles.assigned' => 'Assigned', -// 'form.roles.not_assigned' => 'Not assigned', +'form.roles.rank' => 'Seisus', +'form.roles.rights' => 'Õigused', +'form.roles.assigned' => 'Määratud', +'form.roles.not_assigned' => 'Määramata', // Clients form. See example at https://timetracker.anuko.com/clients.php -// TODO: translate the following. -// 'form.clients.active_clients' => 'Active Clients', -// 'form.clients.inactive_clients' => 'Inactive Clients', +'form.clients.active_clients' => 'Aktiivsed kliendid', +'form.clients.inactive_clients' => 'Mitteaktiivsed kliendid', // Deleting Client form. See example at https://timetracker.anuko.com/client_delete.php -// TODO: translate the following. -// 'form.client.client_to_delete' => 'Client to delete', -// 'form.client.client_entries' => 'Client entries', +'form.client.client_to_delete' => 'Kustutatav klient', +'form.client.client_entries' => 'Kliendi kirjed', // Exporting Group Data form. See example at https://timetracker.anuko.com/export.php -// TODO: replace "team" with "group" in the string below. -'form.export.hint' => 'Võid kogu meeskonna andmed eksportida xml-faili. Sellest võib olla kasu kui vahetad serverit.', +// TODO: replace "meeskonna" with "grupp" in the string below. +'form.export.hint' => 'Võid kogu meeskonna andmed eksportida XML faili. Sellest võib olla kasu, kui vahetad serverit.', 'form.export.compression' => 'Pakkimine', -// TODO: translate the following. -// 'form.export.compression_none' => 'none', +'form.export.compression_none' => 'puudub', 'form.export.compression_bzip' => 'bzip', // Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c4390a2df..091683449 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4711 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4712 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 52d3501fd52f4d655efb72ee843828feaaba60fa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 24 Jan 2019 21:34:33 +0000 Subject: [PATCH 0640/1848] Initial work done intergating Estonian language imporvement as per PR#71. --- WEB-INF/resources/et.lang.php | 115 ++++++++++++++++------------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 55 insertions(+), 62 deletions(-) diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index b68296826..74be760ee 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -478,85 +478,78 @@ 'form.export.compression_bzip' => 'bzip', // Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). -'form.import.hint' => 'Impordi meeskonna andmed xml-failist.', // TODO: replace "team" with "group". +'form.import.hint' => 'Impordi grupi andmed XML failist.', 'form.import.file' => 'Vali fail', -'form.import.success' => 'Andmed imporditud.', +'form.import.success' => 'Andmete importimine õnnestus.', // Groups form. See example at https://timetracker.anuko.com/admin_groups.php (login as admin first). -// TODO: translate the following. -// 'form.groups.hint' => 'Create a new group by creating a new group manager account.
You can also import group data from an xml file from another Anuko Time Tracker server (no login collisions are allowed).', +'form.groups.hint' => 'Uue grupi lisamiseks loo esmalt grupi haldur.
Lisaks on võimalik importida grupi andmed XML failist (kasutaja tunnused ei tohi korduda).', // Group Settings form. See example at https://timetracker.anuko.com/group_edit.php. -// TODO: translate the following. -// 'form.group_edit.12_hours' => '12 hours', -// 'form.group_edit.24_hours' => '24 hours', -// 'form.group_edit.show_holidays' => 'Show holidays', -// 'form.group_edit.tracking_mode' => 'Tracking mode', -// 'form.group_edit.mode_time' => 'time', -// 'form.group_edit.mode_projects' => 'projects', -// 'form.group_edit.mode_projects_and_tasks' => 'projects and tasks', -// 'form.group_edit.record_type' => 'Record type', -// 'form.group_edit.type_all' => 'all', -// 'form.group_edit.type_start_finish' => 'start and finish', -// 'form.group_edit.type_duration' => 'duration', -// 'form.group_edit.punch_mode' => 'Punch mode', -// 'form.group_edit.allow_overlap' => 'Allow overlap', -// 'form.group_edit.future_entries' => 'Future entries', -// 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', +'form.group_edit.12_hours' => '12 tundi', +'form.group_edit.24_hours' => '24 tundi', +'form.group_edit.show_holidays' => 'Näita pühi', +'form.group_edit.tracking_mode' => 'Jälgimise režiim', +'form.group_edit.mode_time' => 'ajaarvestus', +'form.group_edit.mode_projects' => 'projektid', +'form.group_edit.mode_projects_and_tasks' => 'projektid ja tööülesanded', +'form.group_edit.record_type' => 'Kirje tüüp', +'form.group_edit.type_all' => 'kõik', +'form.group_edit.type_start_finish' => 'algus ja lõpp', +'form.group_edit.type_duration' => 'vahemik', +'form.group_edit.punch_mode' => 'Kellast-kellani režiim', +'form.group_edit.allow_overlap' => 'Luba ajaline ülekate', +'form.group_edit.future_entries' => 'Tuleviku kirjed', +'form.group_edit.uncompleted_indicators' => 'Lõpetamata kirjete indikaator', // TODO: Fix this. Indicators (plural), not indicator. +'form.group_edit.confirm_save' => 'Kinnita salvestamine', +'form.group_edit.allow_ip' => 'Luba IP', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php -// TODO: translate the following. -// 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', +'form.group_delete.hint' => 'Oled kindel, et soovid kogu gruppi kustutada?', // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.from' => 'Kellelt', 'form.mail.to' => 'Kellele', -// TODO: translate the following. -// 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', -// 'form.mail.report_sent' => 'Report sent.', -'form.mail.invoice_sent' => 'Arve saadetud.', +'form.mail.report_subject' => 'Time Tracker raport', +'form.mail.footer' => 'Anuko Time Tracker on lihtne, lihtsalt kasutatav ja avatud lähtekoodiga
ajaarvestussüsteem. Lisainfo saamiseks külastage www.anuko.com lehekülge.', +'form.mail.report_sent' => 'Raport on saadetud.', +'form.mail.invoice_sent' => 'Arve on saadetud.', // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. -// TODO: translate the following. -// 'form.quota.year' => 'Year', -// 'form.quota.month' => 'Month', -// 'form.quota.workday_hours' => 'Hours in work day', -// 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', +'form.quota.year' => 'Aasta', +'form.quota.month' => 'Kuu', +'form.quota.workday_hours' => 'Töötunde päevas', +'form.quota.hint' => 'Tühjade väljade korral arvutatakse töötamise kvoodid tööpäevade ja pühade põhjal.', // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. -// TODO: translate the following. -// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', -// 'form.swap.swap_with' => 'Swap roles with', +'form.swap.hint' => 'Rolli muutmiseks muuda oma kasutajat. Rollivahetust ei saa tagasi võtta.', +'form.swap.swap_with' => 'Vaheta kasutajaga roll', // Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. -// TODO: translate the following. -// 'form.work_units.minutes_in_unit' => 'Minutes in unit', -// 'form.work_units.1st_unit_threshold' => '1st unit threshold', +'form.work_units.minutes_in_unit' => 'Minuteid ühikus', +'form.work_units.1st_unit_threshold' => 'Esimese ühiku piirmäär', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. -// TODO: translate the following. -// 'role.user.label' => 'User', -// 'role.user.low_case_label' => 'user', +'role.user.label' => 'Tavakasutaja', +'role.user.low_case_label' => 'tavakasutaja', +// TODO: Translate role.user.description. "Haldusõigustega tavakasutaja." auto-translates with an opposite meaning. // 'role.user.description' => 'A regular member without management rights.', -// 'role.client.label' => 'Client', -// 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', -// 'role.supervisor.label' => 'Supervisor', -// 'role.supervisor.low_case_label' => 'supervisor', -// 'role.supervisor.description' => 'A person with a small set of management rights.', -// 'role.comanager.label' => 'Co-manager', -// 'role.comanager.low_case_label' => 'co-manager', -// 'role.comanager.description' => 'A person with a big set of management functions.', -// 'role.manager.label' => 'Manager', -// 'role.manager.low_case_label' => 'manager', -// 'role.manager.description' => 'Group manager. Can do most of things for a group.', -// 'role.top_manager.label' => 'Top manager', -// 'role.top_manager.low_case_label' => 'top manager', -// 'role.top_manager.description' => 'Top group manager. Can do everything in a tree of groups.', -// 'role.admin.label' => 'Administrator', -// 'role.admin.low_case_label' => 'administrator', -// 'role.admin.description' => 'Site adminsitrator.', +'role.client.label' => 'Klient', +'role.client.low_case_label' => 'klient', +'role.client.description' => 'Kliendil on lubatud vaadata oma raporteid, diagramme ja arveid.', +'role.supervisor.label' => 'Ülevaataja', +'role.supervisor.low_case_label' => 'ülevaataja', +'role.supervisor.description' => 'Mõningate lisaõigustega kasutaja.', +'role.comanager.label' => 'Kaashaldur', +'role.comanager.low_case_label' => 'kaashaldur', +'role.comanager.description' => 'Mitmete halduri õigustega kasutja.', +'role.manager.label' => 'Haldur', +'role.manager.low_case_label' => 'haldur', +'role.manager.description' => 'Grupihaldur, kellel on lubatud enamik grupiga soetud tegevusi.', +'role.top_manager.label' => 'Juht', +'role.top_manager.low_case_label' => 'juht', +'role.top_manager.description' => 'Ettevõtte juht, kellel on lubatud hallata mitut gruppi.', +'role.admin.label' => 'Administraator', +'role.admin.low_case_label' => 'administraator', +'role.admin.description' => 'Rakenduse administraator.', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 091683449..56a207c68 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.36.4712 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4713 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 5c2ac5c8736e763fd878d619e6283b57b2d2aab0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 24 Jan 2019 21:51:29 +0000 Subject: [PATCH 0641/1848] A small impovement to the Estonian translation. --- WEB-INF/resources/et.lang.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 74be760ee..0d07da392 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -154,7 +154,7 @@ 'label.address' => 'Aadress', 'label.currency' => 'Valuuta', 'label.manager_name' => 'Halduri nimi', -'label.manager_login' => 'Halduri sisenemine', +'label.manager_login' => 'Halduri kasutajanimi', 'label.person_name' => 'Nimi', 'label.thing_name' => 'Nimi', 'label.login' => 'Kasutajanimi', @@ -483,7 +483,7 @@ 'form.import.success' => 'Andmete importimine õnnestus.', // Groups form. See example at https://timetracker.anuko.com/admin_groups.php (login as admin first). -'form.groups.hint' => 'Uue grupi lisamiseks loo esmalt grupi haldur.
Lisaks on võimalik importida grupi andmed XML failist (kasutaja tunnused ei tohi korduda).', +'form.groups.hint' => 'Uue grupi lisamiseks loo esmalt grupi haldur.
Lisaks on võimalik importida grupi andmed XML failist (kasutajatunnused ei tohi korduda).', // Group Settings form. See example at https://timetracker.anuko.com/group_edit.php. 'form.group_edit.12_hours' => '12 tundi', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 56a207c68..f6ad5a368 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + From 7d33cc17bc343f43f81756a1008d6658a9ebb714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anti=20R=C3=A4is?= Date: Sun, 27 Jan 2019 14:57:25 +0200 Subject: [PATCH 0643/1848] Create CONTRIBUTING.md (#73) --- CONTRIBUTING.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..66920189e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,28 @@ +# Short Links to Important Resources + +* [docs](https://www.anuko.com/time_tracker/features.htm) - detailed documentation about this project can be found here +* [bugs](https://github.com/anuko/timetracker/issues) - report bugs and issues here +* [forum](https://www.anuko.com/forum/viewforum.php?f=4) - for general discussion + +# Reporting Bugs + +Create a [new issue](https://github.com/anuko/timetracker/issues). + +# Reporting Security Issues + +**#TODO** + +# Setting up a dev environment + +Use docker to run dev instance: +```bash +docker-compose up +``` + +and then navigate to: http://localhost:8080. Default credentials for initial login are: +``` +usr: admin +psw: secret +``` + +Full installation and setup guide can be found [here](https://www.anuko.com/time_tracker/install_guide/index.htm). From 57c9a22d01acebf278f818d1882f3b0dbad84845 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 27 Jan 2019 18:33:53 +0000 Subject: [PATCH 0644/1848] Updated CONTRIBUTING.md. --- CONTRIBUTING.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 66920189e..64e6259a9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,28 +1,34 @@ -# Short Links to Important Resources +# Resources + +* [docs](https://www.anuko.com/time_tracker/features.htm) - detailed documentation about this project can be found here (needs updating). +* [forum](https://www.anuko.com/forum/viewforum.php?f=4) - for general discussion. -* [docs](https://www.anuko.com/time_tracker/features.htm) - detailed documentation about this project can be found here -* [bugs](https://github.com/anuko/timetracker/issues) - report bugs and issues here -* [forum](https://www.anuko.com/forum/viewforum.php?f=4) - for general discussion # Reporting Bugs -Create a [new issue](https://github.com/anuko/timetracker/issues). +* GitHub users: create a [new issue](https://github.com/anuko/timetracker/issues). +* Forum users: use [forum](https://www.anuko.com/forum/viewforum.php?f=4). +* Or, [send a message](https://www.anuko.com/contact.htm). + # Reporting Security Issues -**#TODO** +* Use the [contact form](https://www.anuko.com/contact.htm) to report a vulnerability. +* Or send encrypted email to security_at_anuko_dot_com. Public key to be published soon. + + +# Setting up a Dev Environment -# Setting up a dev environment +Docker users: install both docker and docker-compose, then run a dev instance: -Use docker to run dev instance: ```bash docker-compose up ``` -and then navigate to: http://localhost:8080. Default credentials for initial login are: +To use Time Tracker, navigate to: http://localhost:8080. Default credentials for initial login are: ``` usr: admin psw: secret ``` -Full installation and setup guide can be found [here](https://www.anuko.com/time_tracker/install_guide/index.htm). +Without docker, perform a manual install of a web server, php, database server, and Time Tracker. Full installation and setup guide can be found [here](https://www.anuko.com/time_tracker/install_guide/index.htm). From 33fa22f70db177ed8193cebecbdc5fc7e408c8bf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 27 Jan 2019 18:44:33 +0000 Subject: [PATCH 0645/1848] Cosmetic text improvements. --- CONTRIBUTING.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 64e6259a9..3cd91185c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,31 +1,29 @@ # Resources * [docs](https://www.anuko.com/time_tracker/features.htm) - detailed documentation about this project can be found here (needs updating). -* [forum](https://www.anuko.com/forum/viewforum.php?f=4) - for general discussion. +* [forum](https://www.anuko.com/forum/viewforum.php?f=4) - general discussion. # Reporting Bugs -* GitHub users: create a [new issue](https://github.com/anuko/timetracker/issues). -* Forum users: use [forum](https://www.anuko.com/forum/viewforum.php?f=4). -* Or, [send a message](https://www.anuko.com/contact.htm). +* GitHub users: create a [new issue](https://github.com/anuko/timetracker/issues) here. +* Forum users: post a new topic [here](https://www.anuko.com/forum/viewforum.php?f=4). +* Or, send us a [message](https://www.anuko.com/contact.htm). # Reporting Security Issues * Use the [contact form](https://www.anuko.com/contact.htm) to report a vulnerability. -* Or send encrypted email to security_at_anuko_dot_com. Public key to be published soon. +* Or send an encrypted email to security_at_anuko_dot_com. Public key to be published soon. # Setting up a Dev Environment Docker users: install both docker and docker-compose, then run a dev instance: - ```bash docker-compose up ``` - -To use Time Tracker, navigate to: http://localhost:8080. Default credentials for initial login are: +Navigate to: http://localhost:8080 to use Time Tracker. Default credentials for initial login are: ``` usr: admin psw: secret From 781ff98c576d8738d162d0d59ef3c3bc197b09bf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 27 Jan 2019 18:54:06 +0000 Subject: [PATCH 0646/1848] Cosmetic. --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3cd91185c..5354bd044 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,13 @@ # Resources -* [docs](https://www.anuko.com/time_tracker/features.htm) - detailed documentation about this project can be found here (needs updating). +* [docs](https://www.anuko.com/time_tracker/features.htm) - detailed documentation about this project (needs updating). * [forum](https://www.anuko.com/forum/viewforum.php?f=4) - general discussion. # Reporting Bugs * GitHub users: create a [new issue](https://github.com/anuko/timetracker/issues) here. -* Forum users: post a new topic [here](https://www.anuko.com/forum/viewforum.php?f=4). +* Forum users: post a [new topic](https://www.anuko.com/forum/viewforum.php?f=4 here. * Or, send us a [message](https://www.anuko.com/contact.htm). From a115da22ff8284a961e5853333f65f5768db1de1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 27 Jan 2019 18:55:30 +0000 Subject: [PATCH 0647/1848] Fixed broken link. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5354bd044..b7311238a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ # Reporting Bugs * GitHub users: create a [new issue](https://github.com/anuko/timetracker/issues) here. -* Forum users: post a [new topic](https://www.anuko.com/forum/viewforum.php?f=4 here. +* Forum users: post a [new topic](https://www.anuko.com/forum/viewforum.php?f=4) here. * Or, send us a [message](https://www.anuko.com/contact.htm). From 7c9f391d66e4e984a1d23632811ca885d7266676 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 11 Feb 2019 18:20:28 +0000 Subject: [PATCH 0648/1848] Added a check for a writable PHP session path. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f6ad5a368..693dc292c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.36.4713 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4714 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 2303cf628260b28f67190b164ba2894c328f4a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anti=20R=C3=A4is?= Date: Fri, 25 Jan 2019 00:05:34 +0200 Subject: [PATCH 0642/1848] fix invalid label target element in plugin page (#72) --- WEB-INF/templates/plugins.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index 11514d16a..c064d18bb 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -132,7 +132,7 @@ function handlePluginCheckboxes() {
{$forms.pluginsForm.work_units.control} {$i18n.label.configure} {$i18n.label.configure}
 
-
 Anuko Time Tracker 1.18.36.4714 | Copyright © Anuko | +  Anuko Time Tracker 1.18.36.4715 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index a3cdd9cc5..d39871f88 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -92,6 +92,11 @@ function ttExecute($sql) { echo('Error: PHP version is not high enough: '.phpversion().'. Required: '.$required_version.'.
'); } + // Check is PHP session path is writeable. + if (!is_writable(session_save_path())) { + echo('Error: PHP session path '.session_save_path().' is not writable.
'); + } + // Depending on DSN, require either mysqli or mysql extensions. if (strrpos(DSN, 'mysqli://', -strlen(DSN)) !== FALSE) { if (extension_loaded('mysqli')) { From 2a76f4497cf158ca7e81b6b3ae1998ea28e45044 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 11 Feb 2019 18:22:27 +0000 Subject: [PATCH 0649/1848] Fixed a typo. --- dbinstall.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbinstall.php b/dbinstall.php index d39871f88..e32df0ed0 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -92,7 +92,7 @@ function ttExecute($sql) { echo('Error: PHP version is not high enough: '.phpversion().'. Required: '.$required_version.'.
'); } - // Check is PHP session path is writeable. + // Check if PHP session path is writeable. if (!is_writable(session_save_path())) { echo('Error: PHP session path '.session_save_path().' is not writable.
'); } From 45d4d5858d47fd71a65bf642c0eddd31ddf9a83f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 13 Feb 2019 17:29:19 +0000 Subject: [PATCH 0650/1848] Work started on timesheet approval workflow. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 13 +++++++++---- mysql.sql | 31 ++++++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 693dc292c..d1dfd5c23 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.36.4715 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4716 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index e32df0ed0..64e4cac04 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -967,7 +967,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11836"]) { + if ($_POST["convert11797to11837"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1056,6 +1056,11 @@ function ttExecute($sql) { ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.36', modified = now() where param_name = 'version_db' and param_value = '1.18.34'"); ttExecute("update `tt_users` u inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.36') set u.quota_percent = 100.00 where u.quota_percent is null"); ttExecute("ALTER TABLE `tt_users` modify `quota_percent` float(6,2) NOT NULL default '100.00'"); + ttExecute("CREATE TABLE `tt_timesheets` (`id` int(11) NOT NULL auto_increment, `user_id` int(11) NOT NULL, `group_id` int(11) default NULL, `org_id` int(11) default NULL, `client_id` int(11) default NULL, `name` varchar(80) COLLATE utf8mb4_bin NOT NULL, `submit_status` tinyint(4) default NULL, `submitter_comment` text, `approval_status` tinyint(4) default NULL, `manager_comment` text, `created` datetime default NULL, `created_ip` varchar(45) default NULL, `created_by` int(11) default NULL, `modified` datetime default NULL, `modified_ip` varchar(45) default NULL, `modified_by` int(11) default NULL, `status` tinyint(4) default 1, PRIMARY KEY (`id`))"); + ttExecute("ALTER TABLE `tt_log` ADD `timesheet_id` int(11) default NULL AFTER `task_id`"); + ttExecute("create index timesheet_idx on tt_log(timesheet_id)"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `timesheet_id` int(11) default NULL AFTER `project_id`"); + ttExecute("create index timesheet_idx on tt_expense_items(timesheet_id)"); } if ($_POST["cleanup"]) { @@ -1103,7 +1108,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.36) + Create database structure (v1.18.37)
(applies only to new installations, do not execute when updating)
@@ -1148,8 +1153,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.36)Update database structure (v1.17.97 to v1.18.37)
diff --git a/mysql.sql b/mysql.sql index 5dd41e061..113f5dfb1 100644 --- a/mysql.sql +++ b/mysql.sql @@ -197,6 +197,7 @@ CREATE TABLE `tt_log` ( `client_id` int(11) default NULL, # client id `project_id` int(11) default NULL, # project id `task_id` int(11) default NULL, # task id + `timesheet_id` int(11) default NULL, # timesheet id `invoice_id` int(11) default NULL, # invoice id `comment` text, # user provided comment for time record `billable` tinyint(4) default 0, # whether the record is billable or not @@ -219,6 +220,7 @@ create index client_idx on tt_log(client_id); create index invoice_idx on tt_log(invoice_id); create index project_idx on tt_log(project_id); create index task_idx on tt_log(task_id); +create index timesheet_idx on tt_log(timesheet_id); # @@ -425,6 +427,7 @@ CREATE TABLE `tt_expense_items` ( `org_id` int(11) default NULL, # organization id `client_id` int(11) default NULL, # client id `project_id` int(11) default NULL, # project id + `timesheet_id` int(11) default NULL, # timesheet id `name` text NOT NULL, # expense item name (what is an expense for) `cost` decimal(10,2) default '0.00', # item cost (including taxes, etc.) `invoice_id` int(11) default NULL, # invoice id @@ -445,6 +448,7 @@ create index user_idx on tt_expense_items(user_id); create index group_idx on tt_expense_items(group_id); create index client_idx on tt_expense_items(client_id); create index project_idx on tt_expense_items(project_id); +create index timesheet_idx on tt_expense_items(timesheet_id); create index invoice_idx on tt_expense_items(invoice_id); @@ -476,6 +480,31 @@ CREATE TABLE `tt_monthly_quotas` ( ); +# +# Structure for table tt_timesheets. This table keeps timesheet related information. +# +CREATE TABLE `tt_timesheets` ( + `id` int(11) NOT NULL auto_increment, # timesheet id + `user_id` int(11) NOT NULL, # user id + `group_id` int(11) default NULL, # group id + `org_id` int(11) default NULL, # organization id + `client_id` int(11) default NULL, # client id + `name` varchar(80) COLLATE utf8mb4_bin NOT NULL, # timesheet name + `submit_status` tinyint(4) default NULL, # submit status + `submitter_comment` text, # submitter comment + `approval_status` tinyint(4) default NULL, # approval status + `manager_comment` text, # manager comment + `created` datetime default NULL, # creation timestamp + `created_ip` varchar(45) default NULL, # creator ip + `created_by` int(11) default NULL, # creator user_id + `modified` datetime default NULL, # modification timestamp + `modified_ip` varchar(45) default NULL, # modifier ip + `modified_by` int(11) default NULL, # modifier user_id + `status` tinyint(4) default 1, # timesheet status + PRIMARY KEY (`id`) +); + + # # Structure for table tt_site_config. This table stores configuration data # for Time Tracker site as a whole. @@ -489,4 +518,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.36', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.37', now()); # TODO: change when structure changes. From 2995ff2439adb92ded267c1fb15c24f6001db648 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 13 Feb 2019 17:39:49 +0000 Subject: [PATCH 0651/1848] Fixed db version update. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d1dfd5c23..090e872b4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4716 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4717 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 64e4cac04..d1b67d89d 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1061,6 +1061,7 @@ function ttExecute($sql) { ttExecute("create index timesheet_idx on tt_log(timesheet_id)"); ttExecute("ALTER TABLE `tt_expense_items` ADD `timesheet_id` int(11) default NULL AFTER `project_id`"); ttExecute("create index timesheet_idx on tt_expense_items(timesheet_id)"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.37', modified = now() where param_name = 'version_db' and param_value = '1.18.36'"); } if ($_POST["cleanup"]) { From 16e71d9c6e94475534579b79a53f7c2ee0de4192 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 13 Feb 2019 22:59:26 +0000 Subject: [PATCH 0652/1848] Removed unreliable PHP session path check, added cookies check instead. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 090e872b4..d99e7789b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4717 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4718 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index d1b67d89d..a8c0d0b23 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -50,6 +50,16 @@ function ttExecute($sql) { if ($request->isGet()) { echo('

Environment Checks

'); + // Determine if cookies are enabled in browser. + // session_start(); // already called in initialize.php. + $session_id1 = session_id(); + session_destroy(); + session_start(); + $session_id2 = session_id(); + if ($session_id1 != $session_id2) { + echo('Error: browser cookies are off.
'); + } + // Check if WEB-INF/templates_c dir is writable. if (is_writable(APP_DIR.'/WEB-INF/templates_c/')) { echo('WEB-INF/templates_c/ directory is writable.
'); @@ -92,11 +102,6 @@ function ttExecute($sql) { echo('Error: PHP version is not high enough: '.phpversion().'. Required: '.$required_version.'.
'); } - // Check if PHP session path is writeable. - if (!is_writable(session_save_path())) { - echo('Error: PHP session path '.session_save_path().' is not writable.
'); - } - // Depending on DSN, require either mysqli or mysql extensions. if (strrpos(DSN, 'mysqli://', -strlen(DSN)) !== FALSE) { if (extension_loaded('mysqli')) { From 51bfb0ed88ef0656437b306486bfc56d4f88fa2b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 14 Feb 2019 14:37:56 +0000 Subject: [PATCH 0653/1848] Resuming work on timesheets. --- WEB-INF/lib/ttOrgHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index f77d1eb6e..beb523378 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -101,6 +101,7 @@ static function deleteOrg($org_id) { 'tt_custom_field_options', 'tt_custom_fields', 'tt_log', + 'tt_timesheets', // TODO: check if order is correct. After doing export. 'tt_invoices', 'tt_user_project_binds', 'tt_users', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d99e7789b..de0c021a0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4718 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4719 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index a8c0d0b23..407a290f6 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1085,6 +1085,7 @@ function ttExecute($sql) { ttExecute("OPTIMIZE TABLE tt_clients"); ttExecute("OPTIMIZE TABLE tt_config"); ttExecute("OPTIMIZE TABLE tt_cron"); + ttExecute("OPTIMIZE TABLE tt_timesheets"); ttExecute("OPTIMIZE TABLE tt_custom_field_log"); ttExecute("OPTIMIZE TABLE tt_custom_field_options"); ttExecute("OPTIMIZE TABLE tt_custom_fields"); From bbf886e62dc4746fdbae813cfb80536228f77626 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 14 Feb 2019 15:07:12 +0000 Subject: [PATCH 0654/1848] Added Timeheets plugin checkbox. --- WEB-INF/resources/en.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/plugins.tpl | 6 ++++++ plugins.php | 5 +++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 101a5b71e..ef63eb635 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -52,6 +52,7 @@ 'menu.time' => 'Time', 'menu.expenses' => 'Expenses', 'menu.reports' => 'Reports', +'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Charts', 'menu.projects' => 'Projects', 'menu.tasks' => 'Tasks', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index de0c021a0..8ed3563b0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +{if isTrue('TIMESHEET_DEBUG')} + + + + +{/if} diff --git a/plugins.php b/plugins.php index 5027420e0..64615aa25 100644 --- a/plugins.php +++ b/plugins.php @@ -51,6 +51,7 @@ $cl_quotas = $request->getParameter('quotas'); $cl_week_view = $request->getParameter('week_view'); $cl_work_units = $request->getParameter('work_units'); + $cl_timesheets = $request->getParameter('timesheets'); } else { // Note: we get here in get, and also in post when group changes. // Which plugins do we have enabled in currently selected group? @@ -68,6 +69,7 @@ $cl_quotas = in_array('mq', $plugins); $cl_week_view = in_array('wv', $plugins); $cl_work_units = in_array('wu', $plugins); + $cl_timesheets = in_array('ts', $plugins); } $form = new Form('pluginsForm'); @@ -86,6 +88,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'quotas','value'=>$cl_quotas,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'checkbox','name'=>'week_view','value'=>$cl_week_view,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'checkbox','name'=>'work_units','value'=>$cl_work_units,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'timesheets','value'=>$cl_timesheets)); // Submit button. $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); @@ -120,6 +123,8 @@ $plugins .= ',wv'; if ($cl_work_units) $plugins .= ',wu'; + if ($cl_timesheets) + $plugins .= ',ts'; // Recycle week view plugin options as they are not configured on this page. $existing_plugins = explode(',', $user->getPlugins()); From 45091225a5cbc958f96c38e99228eee98f0b7ca8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 14 Feb 2019 15:19:25 +0000 Subject: [PATCH 0655/1848] Added menu.timesheets to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 3 ++- WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 3 ++- WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 49 insertions(+), 3 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 7b5a5d62f..ba4f4c881 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -56,6 +56,7 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Informes', // TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', // 'menu.charts' => 'Charts', 'menu.projects' => 'Projectes', // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 8c875b92b..22788ed76 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -57,6 +57,7 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Sestavy', // TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', // 'menu.charts' => 'Charts', 'menu.projects' => 'Projekty', // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 7b9faf3b7..bd65501d4 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -53,6 +53,8 @@ 'menu.time' => 'Tid', 'menu.expenses' => 'Udgifter', 'menu.reports' => 'Rapporter', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Diagrammer', 'menu.projects' => 'Projekter', 'menu.tasks' => 'Opgaver', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 2c21205d7..7ca42cb58 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -51,6 +51,8 @@ 'menu.time' => 'Zeiten', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Berichte', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Diagramme', 'menu.projects' => 'Projekte', 'menu.tasks' => 'Aufgaben', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 0f8bc123c..0af7a3cc0 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -55,6 +55,7 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Reportes', // TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', // 'menu.charts' => 'Charts', 'menu.projects' => 'Proyectos', // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 0d07da392..cfd075af6 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -53,6 +53,8 @@ 'menu.time' => 'Ajaarvestus', 'menu.expenses' => 'Kulud', 'menu.reports' => 'Raportid', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Diagrammid', 'menu.projects' => 'Projektid', 'menu.tasks' => 'Tööülesanded', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index dfb010500..a515e0494 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -54,6 +54,8 @@ 'menu.time' => 'زمان', 'menu.expenses' => 'هزينه ها', 'menu.reports' => 'گزارشات', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'نمودارها', 'menu.projects' => 'پروژه ها', 'menu.tasks' => 'وظايف', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 1bd098221..03810cb8c 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -53,6 +53,8 @@ 'menu.time' => 'Tunnit', 'menu.expenses' => 'Kulut', 'menu.reports' => 'Raportit', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Kaaviot', 'menu.projects' => 'Projektit', 'menu.tasks' => 'Tehtävät', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 430c5b1c6..25d2c8235 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -53,6 +53,8 @@ 'menu.time' => 'Temps', 'menu.expenses' => 'Dépenses', 'menu.reports' => 'Rapports', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Graphiques', 'menu.projects' => 'Projets', 'menu.tasks' => 'Tâches', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 88dad80f7..c35ca9717 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -51,6 +51,8 @@ 'menu.time' => 'Χρόνος', 'menu.expenses' => 'Έξοδα', 'menu.reports' => 'Αναφορές', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Διαγράμματα', 'menu.projects' => 'Έργα', 'menu.tasks' => 'Εργασίες', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 1420500bb..45f25bf91 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -55,6 +55,8 @@ // TODO: translate the following. // 'menu.expenses' => 'Expenses', 'menu.reports' => 'דוחות', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'תרשימים', 'menu.projects' => 'פרוייקטים', 'menu.tasks' => 'משימות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 6d4698e68..d54483496 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -56,6 +56,7 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Riportok', // TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', // 'menu.charts' => 'Charts', 'menu.projects' => 'Projektek', // 'menu.tasks' => 'Tasks', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index c14d770e5..abb63ffaa 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -53,6 +53,8 @@ 'menu.time' => 'Tempo', 'menu.expenses' => 'Spese', 'menu.reports' => 'Rapporti', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Grafici', 'menu.projects' => 'Progetti', 'menu.tasks' => 'Compiti', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index d7e2dcf9a..4e46adacb 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -56,6 +56,7 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => 'レポート', // TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', // 'menu.charts' => 'Charts', 'menu.projects' => 'プロジェクト', // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 1866dd54b..fbeae2836 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -56,6 +56,7 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => '보고서', // TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', // 'menu.charts' => 'Charts', 'menu.projects' => '프로젝트', // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index ed304b5ab..643dc2c1a 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -51,6 +51,8 @@ 'menu.time' => 'Tijden', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Rapporten', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Grafieken', 'menu.projects' => 'Projecten', 'menu.tasks' => 'Taken', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 8a698d1de..885da7006 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -56,6 +56,8 @@ // TODO: translate the following. // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Rapporter', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Diagrammer', 'menu.projects' => 'Prosjekter', // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 2922a3421..6366b3120 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -53,6 +53,8 @@ 'menu.time' => 'Czas', 'menu.expenses' => 'Wydatki', 'menu.reports' => 'Raporty', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Statystyki', // TODO: is this correct translation for Charts? 'menu.projects' => 'Projekty', 'menu.tasks' => 'Zadania', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 8691f9383..b9b83b6cf 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -53,6 +53,8 @@ 'menu.time' => 'Tempo', 'menu.expenses' => 'Gastos', 'menu.reports' => 'Relatórios', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Gráficos', 'menu.projects' => 'Projetos', 'menu.tasks' => 'Tarefas', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index bc5d8386b..cf61597b6 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -58,7 +58,8 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Relatórios', // TODO: translate the following. -'menu.charts' => 'Charts', +// 'menu.timesheets' => 'Timesheets', +// 'menu.charts' => 'Charts', 'menu.projects' => 'Projetos', // TODO: translate the following. // 'menu.tasks' => 'Tasks', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 6eb221121..83c50b719 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -58,6 +58,7 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Rapoarte', // TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', // 'menu.charts' => 'Charts', 'menu.projects' => 'Proiecte', // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 4b524b82d..75c6c08ec 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -51,6 +51,7 @@ 'menu.time' => 'Время', 'menu.expenses' => 'Расходы', 'menu.reports' => 'Отчёты', +'menu.timesheets' => 'Табели', 'menu.charts' => 'Диаграммы', 'menu.projects' => 'Проекты', 'menu.tasks' => 'Задачи', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 726c78e80..9eef14259 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -54,6 +54,8 @@ // TODO: translate the following. // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Zostavy', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Grafy', 'menu.projects' => 'Projekty', 'menu.tasks' => 'Úlohy', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 18ddd37f9..2c0274ae0 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -57,7 +57,8 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Poročila', // TODO: translate the following. -'menu.charts' => 'Charts', +// 'menu.timesheets' => 'Timesheets', +// 'menu.charts' => 'Charts', 'menu.projects' => 'Projekti', // TODO: translate the following. // 'menu.tasks' => 'Tasks', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index c20cc43fc..453020856 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -53,6 +53,8 @@ 'menu.time' => 'Vreme', 'menu.expenses' => 'Troškovi', 'menu.reports' => 'Izveštaji', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Grafikoni', 'menu.projects' => 'Projekti', 'menu.tasks' => 'Zadaci', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index d1a106483..c3af8af77 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -51,6 +51,8 @@ 'menu.time' => 'Tider', 'menu.expenses' => 'Kostnader', 'menu.reports' => 'Rapporter', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => 'Diagram', 'menu.projects' => 'Projekt', 'menu.tasks' => 'Arbetsuppgifter', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 38b4a4b29..af40dd4bb 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -58,6 +58,7 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => 'Raporlar', // TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', // 'menu.charts' => 'Charts', 'menu.projects' => 'Projeler', // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index fd4e2b88c..844b4aac7 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -53,6 +53,8 @@ 'menu.time' => '时间记录', 'menu.expenses' => '费用', 'menu.reports' => '报告', +// TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', 'menu.charts' => '图表', 'menu.projects' => '项目', 'menu.tasks' => '任务', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 4112fa159..ac838daaa 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -54,6 +54,7 @@ // 'menu.expenses' => 'Expenses', 'menu.reports' => '報告', // TODO: translate the following. +// 'menu.timesheets' => 'Timesheets', // 'menu.charts' => 'Charts', 'menu.projects' => '項目', // TODO: translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8ed3563b0..c38efe91b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.37.4719 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4720 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index c064d18bb..9ab38ab91 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -134,6 +134,12 @@ function handlePluginCheckboxes() { {$forms.pluginsForm.work_units.control} {$i18n.label.configure}
{$forms.pluginsForm.timesheets.control}
 
-
 Anuko Time Tracker 1.18.37.4720 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4721 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 74992a9fa9cdac627ba3c672b5799812ac974268 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 14 Feb 2019 15:46:13 +0000 Subject: [PATCH 0656/1848] Added 2 more strings in translation files for timesheets. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 3 +++ WEB-INF/resources/de.lang.php | 3 +++ WEB-INF/resources/en.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 3 +++ WEB-INF/resources/fa.lang.php | 3 +++ WEB-INF/resources/fi.lang.php | 3 +++ WEB-INF/resources/fr.lang.php | 3 +++ WEB-INF/resources/gr.lang.php | 3 +++ WEB-INF/resources/he.lang.php | 3 +++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 3 +++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 3 +++ WEB-INF/resources/no.lang.php | 3 +++ WEB-INF/resources/pl.lang.php | 3 +++ WEB-INF/resources/pt-br.lang.php | 3 +++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 3 +++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 3 +++ WEB-INF/resources/sv.lang.php | 3 +++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/plugins.tpl | 2 +- 32 files changed, 78 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index ba4f4c881..2ae15aa5b 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -297,6 +297,8 @@ 'title.report' => 'Informe', // TODO: translate the following. // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Factura', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 22788ed76..8a698dbe6 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -307,6 +307,8 @@ // TODO: translate the following. // 'title.report' => 'Report', // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Faktura', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index bd65501d4..37a33e909 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -275,6 +275,9 @@ 'title.reports' => 'Rapporter', 'title.report' => 'Rapport', 'title.send_report' => 'Sender Rapport', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Faktura', 'title.send_invoice' => 'Sender Faktura', 'title.charts' => 'Diagrammer', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 7ca42cb58..fd73ad7e3 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -259,6 +259,9 @@ 'title.reports' => 'Berichte', 'title.report' => 'Bericht', 'title.send_report' => 'Bericht senden', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Rechnung', 'title.send_invoice' => 'Rechnung senden', 'title.charts' => 'Diagramme', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index ef63eb635..7b2ee3950 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -254,6 +254,8 @@ 'title.reports' => 'Reports', 'title.report' => 'Report', 'title.send_report' => 'Sending Report', +'title.timesheets' => 'Timesheets', +'title.timesheet' => 'Timesheet', 'title.invoice' => 'Invoice', 'title.send_invoice' => 'Sending Invoice', 'title.charts' => 'Charts', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 0af7a3cc0..6f6c82fca 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -296,6 +296,8 @@ // TODO: translate the following. // 'title.report' => 'Report', // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Factura', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index cfd075af6..3aeaef4d4 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -279,6 +279,9 @@ 'title.reports' => 'Raportid', 'title.report' => 'Raport', 'title.send_report' => 'Saadan raportit', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Arve', 'title.send_invoice' => 'Saada arve', 'title.charts' => 'Diagrammid', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index a515e0494..ef0f326b8 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -282,6 +282,9 @@ 'title.reports' => 'گزارشات', 'title.report' => 'گزارش', 'title.send_report' => 'ارسال گزارش', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'فاکتور', 'title.send_invoice' => 'ارسال فاکتور', 'title.charts' => 'نمودارها', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 03810cb8c..06e618959 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -276,6 +276,9 @@ 'title.reports' => 'Raportit', 'title.report' => 'Raportti', 'title.send_report' => 'Raportin lähetys', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Lasku', 'title.send_invoice' => 'Laskun lähetys', 'title.charts' => 'Kaaviot', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 25d2c8235..53dbd941a 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -269,6 +269,9 @@ 'title.reports' => 'Rapports', 'title.report' => 'Rapport', 'title.send_report' => 'Envoi du rapport', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Facture', 'title.send_invoice' => 'Envoi de la facture', 'title.charts' => 'Graphiques', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index c35ca9717..167bbda8f 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -266,6 +266,9 @@ 'title.reports' => 'Αναφορές', 'title.report' => 'Αναφορά', 'title.send_report' => 'Αποστολή αναφοράς', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Τιμολόγιο', 'title.send_invoice' => 'Αποστολή τιμολόγιου', 'title.charts' => 'Γραφήματα', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 45f25bf91..eb3402727 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -294,6 +294,9 @@ 'title.reports' => 'דוחות', 'title.report' => 'דוח', 'title.send_report' => 'שליחת דוח', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'חשבונית', 'title.send_invoice' => 'שליחת חשבונית', 'title.charts' => 'תרשימים', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index d54483496..ff1e21113 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -296,6 +296,8 @@ // TODO: translate the following. // 'title.report' => 'Report', // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Számla', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index abb63ffaa..236044c0d 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -274,6 +274,9 @@ 'title.reports' => 'Rapporti', 'title.report' => 'Rapporto', 'title.send_report' => 'Invio Rapporto', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Fattura', 'title.send_invoice' => 'Invia fattura', 'title.charts' => 'Grafici', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 4e46adacb..35fb7859e 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -303,6 +303,8 @@ 'title.report' => 'レポート', // TODO: translate the following. // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => '送り状', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index fbeae2836..c74aec927 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -303,6 +303,8 @@ 'title.report' => '보고서', // TODO: translate the following. // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => '송장', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 643dc2c1a..a461192b8 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -254,6 +254,9 @@ 'title.reports' => 'Rapporten', 'title.report' => 'Rapport', 'title.send_report' => 'Rapport aan het versturen', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Factuur', 'title.send_invoice' => 'Factuur verzenden', 'title.charts' => 'Grafieken', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 885da7006..45156f8e6 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -298,7 +298,10 @@ // 'title.delete_predefined_expense' => 'Deleting Predefined Expense', 'title.reports' => 'Rapporter', 'title.report' => 'Rapport', +// TODO: Translate the following. // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Faktura', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 6366b3120..55176d19c 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -277,6 +277,9 @@ 'title.reports' => 'Raporty', 'title.report' => 'Raport', 'title.send_report' => 'Wysyłanie raportu', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Faktura', 'title.send_invoice' => 'Wysyłanie faktury', 'title.charts' => 'Statystyki', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index b9b83b6cf..e6b569786 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -274,6 +274,9 @@ 'title.reports' => 'Relatórios', 'title.report' => 'Report', 'title.send_report' => 'Enviando relatório', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Fatura', 'title.send_invoice' => 'Enviando fatura', 'title.charts' => 'Gráficos', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index cf61597b6..7a794ce2a 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -286,6 +286,8 @@ 'title.report' => 'Relatório', // TODO: translate the following. // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', // 'title.invoice' => 'Invoice', // 'title.send_invoice' => 'Sending Invoice', // 'title.charts' => 'Charts', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 83c50b719..cf4556595 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -303,6 +303,8 @@ 'title.report' => 'Raport', // TODO: translate the following. // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Factura', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 75c6c08ec..0202eb203 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -253,6 +253,8 @@ 'title.reports' => 'Отчёты', 'title.report' => 'Отчёт', 'title.send_report' => 'Отсылка отчёта', +'title.timesheets' => 'Табели учёта', +'title.timesheet' => 'Табель учёта', 'title.invoice' => 'Счёт', 'title.send_invoice' => 'Отсылка счёта', 'title.charts' => 'Диаграммы', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 9eef14259..66695484b 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -284,6 +284,9 @@ 'title.reports' => 'Zostavy', 'title.report' => 'Zostava', 'title.send_report' => 'Odosielanie zostavy', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Faktúra', 'title.send_invoice' => 'Odosielanie faktúry', 'title.charts' => 'Grafy', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 2c0274ae0..deba2e667 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -281,6 +281,8 @@ // 'title.reports' => 'Reports', // 'title.report' => 'Report', // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', // 'title.invoice' => 'Invoice', // 'title.send_invoice' => 'Sending Invoice', // 'title.charts' => 'Charts', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 453020856..4c40077cc 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -275,6 +275,9 @@ 'title.reports' => 'Izveštaji', 'title.report' => 'Izveštaj', 'title.send_report' => 'Slanje izveštaja', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Račun', 'title.send_invoice' => 'Slanje računa', 'title.charts' => 'Grafikoni', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index c3af8af77..ed6a0ac80 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -274,6 +274,9 @@ 'title.reports' => 'Rapporter', 'title.report' => 'Rapport', 'title.send_report' => 'Skicka rapport', +// TODO: Translate the following. +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Faktura', 'title.send_invoice' => 'Skicka faktura', 'title.charts' => 'Diagram', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index af40dd4bb..df6f464ae 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -312,6 +312,8 @@ 'title.report' => 'Rapor', // TODO: translate the following. // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => 'Fatura', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 844b4aac7..72d0ed58a 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -291,6 +291,8 @@ 'title.report' => '报告', // TODO: translate the following. // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => '发票', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index ac838daaa..2be5446f7 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -298,6 +298,8 @@ 'title.report' => '報告', // TODO: translate the following. // 'title.send_report' => 'Sending Report', +// 'title.timesheets' => 'Timesheets', +// 'title.timesheet' => 'Timesheet', 'title.invoice' => '發票', // TODO: translate the following. // 'title.send_invoice' => 'Sending Invoice', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c38efe91b..bde1df99d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + {/if} From ca3b5fef452a65d3c4f134676c8d960d10f3ab05 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 15 Feb 2019 15:09:15 +0000 Subject: [PATCH 0657/1848] Adjusting rights for timesheets plugin. --- WEB-INF/lib/ttRoleHelper.class.php | 6 ++-- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 6 ++++ mysql.sql | 4 +-- timesheets.php | 54 ++++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 timesheets.php diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index c324d6805..02b22cdf9 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -189,9 +189,9 @@ static function createPredefinedRoles($group_id, $lang) $mdb2 = getConnection(); - $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings'; - $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; - $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; + $rights_client = 'view_own_reports,view_own_timesheets,view_own_charts,view_own_invoices,manage_own_settings'; + $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; + $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; $rights_manager = $rights_comanager.',manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bde1df99d..4ad2ae4b1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.37.4721 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4722 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index 9ab38ab91..e252e32a9 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -137,7 +137,7 @@ function handlePluginCheckboxes() { {if isTrue('TIMESHEET_DEBUG')}
{$forms.pluginsForm.timesheets.control}
-
 Anuko Time Tracker 1.18.37.4722 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4723 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 407a290f6..69a09ec59 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1067,6 +1067,12 @@ function ttExecute($sql) { ttExecute("ALTER TABLE `tt_expense_items` ADD `timesheet_id` int(11) default NULL AFTER `project_id`"); ttExecute("create index timesheet_idx on tt_expense_items(timesheet_id)"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.37', modified = now() where param_name = 'version_db' and param_value = '1.18.36'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups,delete_group' where rank = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'view_own_reports,view_own_charts', 'view_own_reports,view_own_timesheets,view_own_charts') where rank = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'view_own_reports,view_own_charts', 'view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts') where rank = 4 or rank = 12 or rank = 68 or rank = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'view_reports,view_charts', 'view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts') where rank = 12 or rank = 68 or rank = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'swap_roles,approve_timesheets', 'swap_roles') where rank = 12 or rank = 68 or rank = 324"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.38', modified = now() where param_name = 'version_db' and param_value = '1.18.37'"); } if ($_POST["cleanup"]) { diff --git a/mysql.sql b/mysql.sql index 113f5dfb1..1ff8a7daa 100644 --- a/mysql.sql +++ b/mysql.sql @@ -75,7 +75,7 @@ create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups,delete_group'); # @@ -518,4 +518,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.37', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.38', now()); # TODO: change when structure changes. diff --git a/timesheets.php b/timesheets.php new file mode 100644 index 000000000..fb513bee8 --- /dev/null +++ b/timesheets.php @@ -0,0 +1,54 @@ +isPluginEnabled('ts_NEVER_ENABLED')) { // Work in progress... + header('Location: feature_disabled.php'); + exit(); +} +// End of access checks. + +//$invoices = ttGroupHelper::getActiveInvoices(); + +//$smarty->assign('invoices', $invoices); +$smarty->assign('title', $i18n->get('title.timesheets')); +$smarty->assign('content_page_name', 'invoices.tpl'); // TODO: fix this, too. +$smarty->display('index.tpl'); From cc12768e670e4a553593a6c41bec7ccc568102d4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 15 Feb 2019 15:36:32 +0000 Subject: [PATCH 0658/1848] Added timesheets menu. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4ad2ae4b1..5ac739bfc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4723 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4724 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 86bc619ce..b5f122dbe 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -114,7 +114,11 @@ {/if} {if $user->exists() && ($user->can('view_own_reports') || $user->can('view_reports'))} · {$i18n.menu.reports} - {/if} + {/if} + {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('manage_own_timesheets') || + $user->can('view_timesheets') || $user->can('manage_timesheets') || $user->can('approve_timesheets'))} + · {$i18n.menu.timesheets} + {/if} {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('view_own_invoices') || $user->can('manage_invoices'))} · {$i18n.title.invoices} {/if} From 710003ecf2838c254c075fd9898034e267915e46 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 15 Feb 2019 16:26:23 +0000 Subject: [PATCH 0659/1848] A bit more work in progress on timesheets. --- WEB-INF/lib/ttUser.class.php | 5 ++++ WEB-INF/resources/ca.lang.php | 4 +++ WEB-INF/resources/cs.lang.php | 4 +++ WEB-INF/resources/da.lang.php | 4 +++ WEB-INF/resources/de.lang.php | 4 +++ WEB-INF/resources/en.lang.php | 3 ++ WEB-INF/resources/es.lang.php | 4 +++ WEB-INF/resources/et.lang.php | 4 +++ WEB-INF/resources/fa.lang.php | 4 +++ WEB-INF/resources/fi.lang.php | 4 +++ WEB-INF/resources/fr.lang.php | 4 +++ WEB-INF/resources/gr.lang.php | 4 +++ WEB-INF/resources/he.lang.php | 4 +++ WEB-INF/resources/hu.lang.php | 4 +++ WEB-INF/resources/it.lang.php | 4 +++ WEB-INF/resources/ja.lang.php | 4 +++ WEB-INF/resources/ko.lang.php | 4 +++ WEB-INF/resources/nl.lang.php | 4 +++ WEB-INF/resources/no.lang.php | 4 +++ WEB-INF/resources/pl.lang.php | 4 +++ WEB-INF/resources/pt-br.lang.php | 4 +++ WEB-INF/resources/pt.lang.php | 4 +++ WEB-INF/resources/ro.lang.php | 4 +++ WEB-INF/resources/ru.lang.php | 3 ++ WEB-INF/resources/sk.lang.php | 4 +++ WEB-INF/resources/sl.lang.php | 4 +++ WEB-INF/resources/sr.lang.php | 4 +++ WEB-INF/resources/sv.lang.php | 4 +++ WEB-INF/resources/tr.lang.php | 4 +++ WEB-INF/resources/zh-cn.lang.php | 4 +++ WEB-INF/resources/zh-tw.lang.php | 4 +++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheets.tpl | 47 ++++++++++++++++++++++++++++++++ timesheets.php | 8 +++--- 34 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 WEB-INF/templates/timesheets.tpl diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 36f9163f1..5309dd8ad 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -886,4 +886,9 @@ function exists() { return false; } + + // getTimesheets obtains timesheets for user. + function getTimesheets() { + return null; // Not implemented. + } } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 2ae15aa5b..1e4b299e2 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -448,6 +448,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Número de factura', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 8a698dbe6..08480f525 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -458,6 +458,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Faktura číslo', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 37a33e909..560126347 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -418,6 +418,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Fakturanummer', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index fd73ad7e3..8c6318477 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -396,6 +396,10 @@ 'form.report.export' => 'Exportiere', 'form.report.assign_to_invoice' => 'Zu Rechnung hinzufügen', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Rechnungsnummer', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 7b2ee3950..ce580485e 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -397,6 +397,9 @@ 'form.report.export' => 'Export', 'form.report.assign_to_invoice' => 'Assign to invoice', + // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +'form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Invoice number', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 6f6c82fca..53b429131 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -461,6 +461,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Número de factura', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 3aeaef4d4..70d6d441c 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -422,6 +422,10 @@ 'form.report.export' => 'Eksport', 'form.report.assign_to_invoice' => 'Lisa arvele', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Arve number', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index ef0f326b8..75db18011 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -438,6 +438,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'شماره فاکتور', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 06e618959..9aee3a260 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -425,6 +425,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Laskun numero', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 53dbd941a..17d43b091 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -415,6 +415,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Numéro de facture', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 167bbda8f..4e82d825e 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -405,6 +405,10 @@ 'form.report.export' => 'Εξαγωγή', 'form.report.assign_to_invoice' => 'Ανάθεση στο τιμολόγιο', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Αριθμός τιμολογίου', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index eb3402727..2c4cbc066 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -448,6 +448,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'מספר חשבונית', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index ff1e21113..5dafe96d7 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -451,6 +451,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Számla azonosító száma', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 236044c0d..32e3b84a0 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -418,6 +418,10 @@ 'form.report.export' => 'Esporta', 'form.report.assign_to_invoice' => 'Assegna alla fattura', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Numero fattura', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 35fb7859e..2574d3154 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -457,6 +457,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => '送り状の番号', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index c74aec927..4403f9f17 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -455,6 +455,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => '송장 번호', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index a461192b8..9c88ca063 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -392,6 +392,10 @@ 'form.report.export' => 'Exporteer', 'form.report.assign_to_invoice' => 'Voeg toe aan factuur', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Factuur nummer', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 45156f8e6..a08aeffe0 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -453,6 +453,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Fakturanummer', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 55176d19c..a1f4bfa76 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -427,6 +427,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Numer faktury', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index e6b569786..639092d83 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -422,6 +422,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Número da fatura', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 7a794ce2a..fcd31a447 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -433,6 +433,10 @@ // 'form.report.export' => 'Export', // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index cf4556595..1747b81f4 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -456,6 +456,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Numar factura', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 0202eb203..42dfc9c9f 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -389,6 +389,9 @@ 'form.report.export' => 'Экспортировать', 'form.report.assign_to_invoice' => 'Включить в счёт', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +'form.timesheets.hint' => 'Используйте отчёты для добавления новых табелей.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Номер счёта', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 66695484b..587575f37 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -439,6 +439,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Číslo faktúry', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index deba2e667..b0b23677d 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -430,6 +430,10 @@ // 'form.report.export' => 'Export', // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 4c40077cc..d5c4fff70 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -425,6 +425,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Forma izveštaja. Pogledajte primer na https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Broj računa', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index ed6a0ac80..b3fc0929d 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -422,6 +422,10 @@ // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Fakturanummer', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index df6f464ae..b85773744 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -468,6 +468,10 @@ // 'form.report.export' => 'Export', // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Fatura numarası', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 72d0ed58a..5820ab3a2 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -440,6 +440,10 @@ // 'form.report.export' => 'Export', // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => '发票号码', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 2be5446f7..59ce3716e 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -448,6 +448,10 @@ // 'form.report.export' => 'Export', // 'form.report.assign_to_invoice' => 'Assign to invoice', +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// TODO: translate the following. +// form.timesheets.hint' => 'Use reports to add new timesheets.', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => '發票號碼', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5ac739bfc..0594b17b4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4724 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4725 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl new file mode 100644 index 000000000..2b7990a88 --- /dev/null +++ b/WEB-INF/templates/timesheets.tpl @@ -0,0 +1,47 @@ + + + + + + +
+{if $user->can('manage_invoices') || $user->can('view_own_invoices')} + + + + + + + {if $user->isPluginEnabled('ps')} + + {/if} + + {if !$user->isClient()} + + {/if} + + {foreach $invoices as $invoice} + + + + + {if $user->isPluginEnabled('ps')} + + {/if} + + {if !$user->isClient()} + + {/if} + + {/foreach} +
{$i18n.form.timesheets.hint}
{$i18n.label.invoice}{$i18n.label.client}{$i18n.label.date}{$i18n.label.paid}{$i18n.label.view}{$i18n.label.delete}
{$invoice.name|escape}{$invoice.client_name|escape}{$invoice.date}{if $invoice.paid}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}{$i18n.label.delete}
+ + {if !$user->isClient()} + + +

+ {/if} +{/if} +
diff --git a/timesheets.php b/timesheets.php index fb513bee8..b2c64e636 100644 --- a/timesheets.php +++ b/timesheets.php @@ -40,15 +40,15 @@ exit(); } -if (!$user->isPluginEnabled('ts_NEVER_ENABLED')) { // Work in progress... +if (!$user->isPluginEnabled('ts')) { header('Location: feature_disabled.php'); exit(); } // End of access checks. -//$invoices = ttGroupHelper::getActiveInvoices(); +$timesheets = $user->getTimesheets(); -//$smarty->assign('invoices', $invoices); +$smarty->assign('timesheets', $timesheets); $smarty->assign('title', $i18n->get('title.timesheets')); -$smarty->assign('content_page_name', 'invoices.tpl'); // TODO: fix this, too. +$smarty->assign('content_page_name', 'timesheets.tpl'); $smarty->display('index.tpl'); From 53dd9ed078fdb70af2f24564145873e2346e5f28 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 15 Feb 2019 17:14:50 +0000 Subject: [PATCH 0660/1848] Added 2 labels for timesheets in translation files. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 3 +++ WEB-INF/resources/de.lang.php | 3 +++ WEB-INF/resources/en.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 3 +++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 3 +++ WEB-INF/resources/gr.lang.php | 3 +++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 3 +++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 3 +++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 4 +++- WEB-INF/resources/pt-br.lang.php | 4 +++- WEB-INF/resources/pt.lang.php | 4 +++- WEB-INF/resources/ro.lang.php | 4 +++- WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 3 +++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/timesheets.tpl | 15 ++++++--------- 31 files changed, 78 insertions(+), 13 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 1e4b299e2..c4822d38b 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -263,6 +263,8 @@ 'label.totals_only' => 'Només totals', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 08480f525..3ec87f3c5 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -273,6 +273,8 @@ 'label.totals_only' => 'Pouze součty', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 560126347..d5087b8df 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -248,6 +248,9 @@ // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Kun Total', 'label.quota' => 'Kvota', +// TODO: translate the following. +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'Fejl', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 8c6318477..076bfae1a 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -236,6 +236,9 @@ 'label.work_units_short' => 'Einheiten', 'label.totals_only' => 'Nur Gesamtstunden', 'label.quota' => 'Quote', +// TODO: translate the following. +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'Fehler', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index ce580485e..7797a8d8e 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -229,6 +229,8 @@ 'label.work_units_short' => 'Units', 'label.totals_only' => 'Totals only', 'label.quota' => 'Quota', +'label.submitted' => 'Submitted', +'label.approved' => 'Approved', // Form titles. 'title.error' => 'Error', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 53b429131..1b3073007 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -266,6 +266,8 @@ 'label.totals_only' => 'Solo totales', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 70d6d441c..10beccf82 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -250,6 +250,9 @@ 'label.work_units_short' => 'Ühikud', 'label.totals_only' => 'Ainult summad', 'label.quota' => 'Kvoot', +// TODO: translate the following. +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 75db18011..9c6ef591c 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -259,6 +259,8 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'خطا', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 9aee3a260..71515dfff 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -253,6 +253,8 @@ 'label.totals_only' => 'Vain yhteissummat', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'Virhe', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 17d43b091..5132326fe 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -246,6 +246,9 @@ // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Totaux uniquement', 'label.quota' => 'Quota', +// TODO: translate the following. +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'Erreur', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 4e82d825e..77a7833ab 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -239,6 +239,9 @@ // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Σύνολα μόνο', 'label.quota' => 'Ποσοστό', +// TODO: translate the following. +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'Σφάλμα', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2c4cbc066..ac4bbfd2e 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -270,6 +270,8 @@ 'labl.totals_only' => 'סיכומים בלבד', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'שגיאה', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 5dafe96d7..8549700d9 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -267,6 +267,8 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 32e3b84a0..87f899ffd 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -243,6 +243,9 @@ // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Solo i totali', 'label.quota' => 'Quota', +// TODO: translate the following. +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 2574d3154..a54f25f78 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -273,6 +273,8 @@ 'label.totals_only' => '全体だけ', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 4403f9f17..4d0e0f292 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -273,6 +273,8 @@ 'label.totals_only' => '오직 전체만', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 9c88ca063..336bed5a9 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -229,6 +229,9 @@ 'label.work_units_short' => 'Eenheid', 'label.totals_only' => 'Alleen totalen', 'label.quota' => 'Maanddoel', +// TODO: translate the following. +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'Fout', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index a08aeffe0..5cb49d345 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -270,6 +270,8 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota' +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index a1f4bfa76..3e2e97c54 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -253,7 +253,9 @@ // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Tylko sumy', // TODO: translate the following. -// 'label.quota' => 'Quota' +// 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'Błąd', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 639092d83..db9ef805e 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -250,7 +250,9 @@ // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Somente totais', // TODO: translate the following. -// 'label.quota' => 'Quota' +// 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'Erro', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index fcd31a447..1d7a99563 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -257,7 +257,9 @@ // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', -// 'label.quota' => 'Quota' +// 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 1747b81f4..3fa54ace8 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -269,7 +269,9 @@ // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Numai totaluri', // TODO: translate the following. -// 'label.quota' => 'Quota' +// 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 42dfc9c9f..1c046857e 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -228,6 +228,8 @@ 'label.work_units_short' => 'Единицы', 'label.totals_only' => 'Только итоги', 'label.quota' => 'Квота', +'label.submitted' => 'Подано', +'label.approved' => 'Одобрено', // Form titles. 'title.error' => 'Ошибка', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 587575f37..c8eede8af 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -260,6 +260,8 @@ 'label.totals_only' => 'Iba celkové', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'Chyba', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index b0b23677d..3adbda815 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -253,6 +253,8 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index d5c4fff70..3dae77abe 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -252,6 +252,8 @@ 'label.totals_only' => 'Samo zbirno', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. 'title.error' => 'Greška', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index b3fc0929d..0f4faac3f 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -247,6 +247,9 @@ // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Visa endast summeringar', 'label.quota' => 'Kvot', +// TODO: translate the following. +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Rubriker för formulär 'title.error' => 'Fel', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index b85773744..8c6f2154f 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -277,6 +277,8 @@ 'label.totals_only' => 'Sadece toplamlar', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // Form titles. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5820ab3a2..f4912f1d9 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -261,6 +261,8 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 59ce3716e..5b04d348b 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -268,6 +268,8 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.submitted' => 'Submitted', +// 'label.approved' => 'Approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index 2b7990a88..626065846 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -9,18 +9,15 @@ - + + {if $user->isPluginEnabled('cl')} - - {if $user->isPluginEnabled('ps')} - {/if} + + - {if !$user->isClient()} - - {/if} - {foreach $invoices as $invoice} + {foreach $timesheets as $timesheet} @@ -38,7 +35,7 @@ {if !$user->isClient()}
{$i18n.form.timesheets.hint}
{$i18n.label.invoice}{$i18n.label.thing_name}{$i18n.label.client}{$i18n.label.date}{$i18n.label.paid}{$i18n.label.submitted}{$i18n.label.approved} {$i18n.label.view}{$i18n.label.delete}
{$invoice.name|escape} {$invoice.client_name|escape}
- +


{/if} {/if} From e447782c5838a9715a7443a028d403aadf52a479 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 15 Feb 2019 21:58:24 +0000 Subject: [PATCH 0661/1848] A bit more work in progress on timesheets. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 3 +++ WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 8 ++++++++ reports.php | 10 ++++++++++ 33 files changed, 51 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index c4822d38b..2ecfb0b06 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -263,6 +263,7 @@ 'label.totals_only' => 'Només totals', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 3ec87f3c5..8e8f3c021 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -273,6 +273,7 @@ 'label.totals_only' => 'Pouze součty', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index d5087b8df..bde6d33d0 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -249,6 +249,7 @@ 'label.totals_only' => 'Kun Total', 'label.quota' => 'Kvota', // TODO: translate the following. +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 076bfae1a..0ef54dcaa 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -237,6 +237,7 @@ 'label.totals_only' => 'Nur Gesamtstunden', 'label.quota' => 'Quote', // TODO: translate the following. +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 7797a8d8e..a6be48642 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -229,6 +229,7 @@ 'label.work_units_short' => 'Units', 'label.totals_only' => 'Totals only', 'label.quota' => 'Quota', +'label.timesheet' => 'Timesheet', 'label.submitted' => 'Submitted', 'label.approved' => 'Approved', @@ -383,6 +384,8 @@ 'form.reports.include_not_billable' => 'not billable', 'form.reports.include_invoiced' => 'invoiced', 'form.reports.include_not_invoiced' => 'not invoiced', +'form.reports.include_assigned' => 'assigned', +'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Select time period', 'form.reports.set_period' => 'or set dates', 'form.reports.show_fields' => 'Show fields', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 1b3073007..bd5594126 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -266,6 +266,7 @@ 'label.totals_only' => 'Solo totales', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 10beccf82..4410d9c44 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -251,6 +251,7 @@ 'label.totals_only' => 'Ainult summad', 'label.quota' => 'Kvoot', // TODO: translate the following. +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 9c6ef591c..2637158b0 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -259,6 +259,7 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 71515dfff..1e8c7df4d 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -253,6 +253,7 @@ 'label.totals_only' => 'Vain yhteissummat', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 5132326fe..4dc045c9a 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -247,6 +247,7 @@ 'label.totals_only' => 'Totaux uniquement', 'label.quota' => 'Quota', // TODO: translate the following. +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 77a7833ab..5dbac6163 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -240,6 +240,7 @@ 'label.totals_only' => 'Σύνολα μόνο', 'label.quota' => 'Ποσοστό', // TODO: translate the following. +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index ac4bbfd2e..a9f45b3b1 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -270,6 +270,7 @@ 'labl.totals_only' => 'סיכומים בלבד', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 8549700d9..ee04db57e 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -267,6 +267,7 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 87f899ffd..b64c7d5e1 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -244,6 +244,7 @@ 'label.totals_only' => 'Solo i totali', 'label.quota' => 'Quota', // TODO: translate the following. +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index a54f25f78..c4da31e87 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -273,6 +273,7 @@ 'label.totals_only' => '全体だけ', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 4d0e0f292..f954100c7 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -273,6 +273,7 @@ 'label.totals_only' => '오직 전체만', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 336bed5a9..621db3b38 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -230,6 +230,7 @@ 'label.totals_only' => 'Alleen totalen', 'label.quota' => 'Maanddoel', // TODO: translate the following. +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 5cb49d345..40d229547 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -270,6 +270,7 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota' +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 3e2e97c54..c4218e4be 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -254,6 +254,7 @@ 'label.totals_only' => 'Tylko sumy', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index db9ef805e..1f1d6ccf0 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -251,6 +251,7 @@ 'label.totals_only' => 'Somente totais', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 1d7a99563..e325d8050 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -258,6 +258,7 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 3fa54ace8..09c220e8b 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -270,6 +270,7 @@ 'label.totals_only' => 'Numai totaluri', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 1c046857e..a2a9009c2 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -228,6 +228,7 @@ 'label.work_units_short' => 'Единицы', 'label.totals_only' => 'Только итоги', 'label.quota' => 'Квота', +'label.timesheet' => 'Табель учёта', 'label.submitted' => 'Подано', 'label.approved' => 'Одобрено', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index c8eede8af..8e847d732 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -259,6 +259,7 @@ // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Iba celkové', // TODO: translate the following. +// 'label.timesheet' => 'Timesheet', // 'label.quota' => 'Quota', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 3adbda815..6e353c280 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -253,6 +253,7 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 3dae77abe..bd2415dd2 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -252,6 +252,7 @@ 'label.totals_only' => 'Samo zbirno', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 0f4faac3f..2634c6847 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -248,6 +248,7 @@ 'label.totals_only' => 'Visa endast summeringar', 'label.quota' => 'Kvot', // TODO: translate the following. +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 8c6f2154f..cfdadbba4 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -277,6 +277,7 @@ 'label.totals_only' => 'Sadece toplamlar', // TODO: translate the following. // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index f4912f1d9..c4efbbf9e 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -261,6 +261,7 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 5b04d348b..2b6357fb9 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -268,6 +268,7 @@ // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', // 'label.quota' => 'Quota', +// 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0594b17b4..fc40cb207 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + {if $user->isPluginEnabled('ts')} + + {/if} + + {if $user->isPluginEnabled('ts')} + + {/if} {/if} {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()} diff --git a/reports.php b/reports.php index ee82a64f3..1e7b4b994 100644 --- a/reports.php +++ b/reports.php @@ -151,6 +151,16 @@ )); } +// TODO: check rights. +if ($user->isPluginEnabled('ts')) { + $form->addInput(array('type'=>'combobox', + 'name'=>'timesheet', + 'style'=>'width: 250px;', + 'data'=>array('1'=>$i18n->get('form.reports.include_assigned'),'2'=>$i18n->get('form.reports.include_not_assigned')), + 'empty'=>array(''=>$i18n->get('dropdown.all')) + )); +} + $user_list = array(); if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { // Prepare user and assigned projects arrays. From 7a53b9001847ebb7a1fa1fb118d25b9329c44d42 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 15 Feb 2019 22:18:32 +0000 Subject: [PATCH 0662/1848] Added a couple more strings to translation files. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 3 +++ WEB-INF/resources/de.lang.php | 3 +++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 5 +++++ WEB-INF/resources/fi.lang.php | 3 +++ WEB-INF/resources/fr.lang.php | 3 +++ WEB-INF/resources/gr.lang.php | 3 +++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 3 +++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 3 +++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 3 +++ WEB-INF/resources/pt-br.lang.php | 3 +++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 3 +++ WEB-INF/resources/sv.lang.php | 3 +++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 73 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 2ecfb0b06..cc9e1a345 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -432,6 +432,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Seleccionar període de temps', 'form.reports.set_period' => 'o establir dates', 'form.reports.show_fields' => 'Mostrar camps', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 8e8f3c021..017960967 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -442,6 +442,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Výberte období', 'form.reports.set_period' => 'nebo určete dny', 'form.reports.show_fields' => 'Zobrazit pole', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index bde6d33d0..def9e45f9 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -405,6 +405,9 @@ 'form.reports.include_not_billable' => 'Ikke fakturerbar', 'form.reports.include_invoiced' => 'Faktureret', 'form.reports.include_not_invoiced' => 'Ikke faktureret', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Vælg en periode', 'form.reports.set_period' => 'eller sæt datoer', 'form.reports.show_fields' => 'Vis felter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 0ef54dcaa..bb9d0cf4b 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -384,6 +384,9 @@ 'form.reports.include_not_billable' => 'nicht in Rechnung stellen', 'form.reports.include_invoiced' => 'berechnet', 'form.reports.include_not_invoiced' => 'nicht berechnet', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Zeitraum auswählen', 'form.reports.set_period' => 'oder Datum eingeben', 'form.reports.show_fields' => 'Felder anzeigen', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index bd5594126..6ed57b724 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -445,6 +445,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Seleccionar período de tiempo', 'form.reports.set_period' => 'o establecer fechas', 'form.reports.show_fields' => 'Mostrar campos', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 4410d9c44..c65e3b212 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -409,6 +409,8 @@ // Our concern is that Google auto-translates "arveldamata" as unpaid. Therefore, we may need a fix here. // 'form.reports.include_invoiced' => 'arveldatud', // TODO: fix as per the above comment, if needed. // 'form.reports.include_not_invoiced' => 'arveldamata', // TODO: fix as per the above comment, if needed. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Vali ajaperiood', 'form.reports.set_period' => 'või märgi kuupäevad', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 2637158b0..78e173225 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -424,6 +424,11 @@ 'form.reports.confirm_delete' => 'آیا می خواهید گزارش برگزیده حذف شود؟', 'form.reports.include_billable' => 'قابل پرداخت', 'form.reports.include_not_billable' => 'غیرقابل پرداخت', +// TODO: translate the following. +// 'form.reports.include_invoiced' => 'invoiced', +// 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'انتخاب بازه زمانی', 'form.reports.set_period' => 'یا تعیین تاریخ', 'form.reports.show_fields' => 'نمایش فیلدها', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 1e8c7df4d..3b8e34d4d 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -411,6 +411,9 @@ 'form.reports.include_not_billable' => 'ei-laskutettavat', 'form.reports.include_invoiced' => 'laskutettu', 'form.reports.include_not_invoiced' => 'laskuttamatta', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Valitse ajanjakso', 'form.reports.set_period' => 'tai aseta päivät', 'form.reports.show_fields' => 'Näytä kentät', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 4dc045c9a..de4cb46c6 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -402,6 +402,9 @@ 'form.reports.include_not_billable' => 'non facturables', 'form.reports.include_invoiced' => 'facturé', 'form.reports.include_not_invoiced' => 'non facturé', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Sélectionner la période de temps', 'form.reports.set_period' => 'ou dates indiquées', 'form.reports.show_fields' => 'Afficher les champs', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 5dbac6163..1396d5f51 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -393,6 +393,9 @@ 'form.reports.include_not_billable' => 'μη χρεώσιμο', 'form.reports.include_invoiced' => 'τιμολόγηση', 'form.reports.include_not_invoiced' => 'χωρίς τιμολόγηση', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Επιλογή χρονικής περιόδου', 'form.reports.set_period' => 'ή εύρος ημερομηνιών', 'form.reports.show_fields' => 'Εμφάνιση πεδίων', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index a9f45b3b1..829260333 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -433,6 +433,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'בחר תקופת זמן', 'form.reports.set_period' => 'או הגדר תאריכים', 'form.reports.show_fields' => 'הראה שדות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index ee04db57e..ca9f2bb13 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -434,6 +434,8 @@ // 'form.reports.include_not_billable' => 'not billable', // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Jelölj meg egy időszakot', 'form.reports.set_period' => 'vagy állíts be konkrét dátumot', // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index b64c7d5e1..e3ceb037d 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -406,6 +406,9 @@ 'form.reports.include_not_billable' => 'non fatturabile', 'form.reports.include_invoiced' => 'fatturato', 'form.reports.include_not_invoiced' => 'non fatturato', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Seleziona il periodo di tempo', 'form.reports.set_period' => 'oppure setta le date', 'form.reports.show_fields' => 'Mostra i campi', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index c4da31e87..646739c5f 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -441,6 +441,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => '時間期間の選択', 'form.reports.set_period' => 'あるいは日付を設定', 'form.reports.show_fields' => 'フィールドの表示', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index f954100c7..f34bb9c26 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -439,6 +439,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => '시간 기간을 선택', 'form.reports.set_period' => '혹은 날짜를 설정', 'form.reports.show_fields' => '필드들을 보기', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 621db3b38..d08150cca 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -380,6 +380,9 @@ 'form.reports.include_not_billable' => 'niet factureerbaar', 'form.reports.include_invoiced' => 'gefactureerd', 'form.reports.include_not_invoiced' => 'niet gefactureerd', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Kies periode', 'form.reports.set_period' => 'of stel datums in', 'form.reports.show_fields' => 'Toon velden', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 40d229547..829e75a3e 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -438,6 +438,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Velg tidsperiode', 'form.reports.set_period' => 'eller sett dato', 'form.reports.show_fields' => 'Vis feltene', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index c4218e4be..f615a792e 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -413,6 +413,9 @@ 'form.reports.include_not_billable' => 'bezpłatne', 'form.reports.include_invoiced' => 'fakturowane', 'form.reports.include_not_invoiced' => 'nie fakturowane', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Wybierz okres', 'form.reports.set_period' => 'lub ustaw daty', 'form.reports.show_fields' => 'Pokaż pola', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 1f1d6ccf0..d50deaf39 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -408,6 +408,9 @@ 'form.reports.include_not_billable' => 'não faturável', 'form.reports.include_invoiced' => 'faturado', 'form.reports.include_not_invoiced' => 'não faturado', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index e325d8050..923870875 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -419,6 +419,8 @@ // 'form.reports.include_not_billable' => 'not billable', // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 09c220e8b..57e75a5c6 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -441,6 +441,8 @@ // 'form.reports.include_not_billable' => 'not billable', // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Alege perioada', 'form.reports.set_period' => 'sau introdu intervalul de date', 'form.reports.show_fields' => 'Arata campuri', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index a2a9009c2..aa3e03d8b 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -376,6 +376,8 @@ 'form.reports.include_not_billable' => 'не включаемые в счёт', 'form.reports.include_invoiced' => 'внесённые в счёт', 'form.reports.include_not_invoiced' => 'не внесённые в счёт', +'form.reports.include_assigned' => 'присвоена', +'form.reports.include_not_assigned' => 'не присвоена', 'form.reports.select_period' => 'Выберите интервал времени', 'form.reports.set_period' => 'или укажите даты', 'form.reports.show_fields' => 'Показывать поля', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 8e847d732..45afda9cc 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -424,6 +424,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Vyberte časový rozsah', 'form.reports.set_period' => 'alebo nastavte dátumy', 'form.reports.show_fields' => 'Zobraziť polia', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 6e353c280..c0acbf08d 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -415,6 +415,8 @@ // 'form.reports.include_not_billable' => 'not billable', // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.select_period' => 'Select time period', // 'form.reports.set_period' => 'or set dates', // 'form.reports.show_fields' => 'Show fields', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index bd2415dd2..ccfd332ed 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -411,6 +411,9 @@ 'form.reports.include_not_billable' => 'ne naplativo', 'form.reports.include_invoiced' => 'obračunato', 'form.reports.include_not_invoiced' => 'nije obračunato', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Odaberi vremenski raspon', 'form.reports.set_period' => 'ili podesi datum', 'form.reports.show_fields' => 'Prikaži polja u izveštaju', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 2634c6847..4b0883902 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -409,6 +409,9 @@ 'form.reports.include_not_billable' => 'Icke debiterbar tid', 'form.reports.include_invoiced' => 'Fakturerad tid', 'form.reports.include_not_invoiced' => 'Icke fakturerad tid', +// TODO: translate the following. +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Välj intervall', 'form.reports.set_period' => 'eller ställ in datum', 'form.reports.show_fields' => 'Visa fält', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index cfdadbba4..7340c3c49 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -452,6 +452,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => 'Zaman aralığını seç', 'form.reports.set_period' => 'ya da tarihleri belirle', 'form.reports.show_fields' => 'Alanları göster', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index c4efbbf9e..5822b7b44 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -424,6 +424,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => '选择时间段', 'form.reports.set_period' => '或设定日期', 'form.reports.show_fields' => '显示栏目', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 2b6357fb9..5a0f3d21a 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -432,6 +432,8 @@ // TODO: translate the following. // 'form.reports.include_invoiced' => 'invoiced', // 'form.reports.include_not_invoiced' => 'not invoiced', +// 'form.reports.include_assigned' => 'assigned', +// 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.select_period' => '選擇時間段', 'form.reports.set_period' => '或設定日期', 'form.reports.show_fields' => '顯示欄目', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fc40cb207..9cb2a052c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.37.4725 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4726 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 95b4a4364..08cc2edb2 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -229,9 +229,17 @@ function handleCheckboxes() { {if ($user->can('manage_invoices') && $user->isPluginEnabled('ps'))}
{$i18n.label.paid_status} {$i18n.label.timesheet}
{$forms.reportForm.paid_status.control} {$forms.reportForm.timesheet.control}
-
 Anuko Time Tracker 1.18.37.4726 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4727 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e35084bc1a01504480461fef87e6a6e4eff6880d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 16 Feb 2019 14:00:21 +0000 Subject: [PATCH 0663/1848] Started refactoring reports.php for timesheets. --- WEB-INF/templates/footer.tpl | 2 +- reports.php | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9cb2a052c..03db7b7cc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4727 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4728 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 1e7b4b994..f938872b6 100644 --- a/reports.php +++ b/reports.php @@ -49,12 +49,15 @@ // End of access checks. $trackingMode = $user->getTrackingMode(); +$showClient = $user->isPluginEnabled('cl') && !$user->isClient(); // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); $custom_fields = new CustomFields(); $smarty->assign('custom_fields', $custom_fields); + $showCustomFieldCheckbox = $custom_fields->fields[0]; + $showCustomFieldDropdown = $custom_fields->fields[0] && $custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN; } $form = new Form('reportForm'); @@ -74,7 +77,7 @@ $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'),'onclick'=>"return confirm('".$i18n->get('form.reports.confirm_delete')."')")); // Dropdown for clients if the clients plugin is enabled. -if ($user->isPluginEnabled('cl') && !$user->isClient()) { +if ($showClient) { if ($user->can('view_reports') || $user->can('view_all_reports')) { $client_list = ttClientHelper::getClients(); // TODO: improve getClients for "view_reports" // by filtering out not relevant clients. @@ -88,13 +91,13 @@ 'empty'=>array(''=>$i18n->get('dropdown.all')))); } -// If we have a TYPE_DROPDOWN custom field - add control to select an option. -if ($custom_fields && $custom_fields->fields[0] && $custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>'option', - 'style'=>'width: 250px;', - 'value'=>$cl_cf_1, - 'data'=>$custom_fields->options, - 'empty'=>array(''=>$i18n->get('dropdown.all')))); +// If we have a TYPE_DROPDOWN custom field - add a control to select an option. +if ($showCustomFieldDropdown) { + $form->addInput(array('type'=>'combobox','name'=>'option', + 'style'=>'width: 250px;', + 'value'=>$cl_cf_1, + 'data'=>$custom_fields->options, + 'empty'=>array(''=>$i18n->get('dropdown.all')))); } // Add controls for projects and tasks. @@ -210,7 +213,7 @@ $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'end_date')); // Add checkboxes for fields. -if ($user->isPluginEnabled('cl')) +if ($showClient) $form->addInput(array('type'=>'checkbox','name'=>'chclient')); if (($user->can('manage_invoices') || $user->isClient()) && $user->isPluginEnabled('iv')) $form->addInput(array('type'=>'checkbox','name'=>'chinvoice')); @@ -372,6 +375,7 @@ } } // isPost +$smarty->assign('show_client', $showClient); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); $smarty->assign('assigned_projects', $assigned_projects); From 93dc9c1832b4035167d53796db9fac88bf90a2b6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 16 Feb 2019 18:25:30 +0000 Subject: [PATCH 0664/1848] Refactored reports.php for timesheets. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 188 ++++++++++++++++------------------ reports.php | 138 +++++++++++++++++-------- 3 files changed, 184 insertions(+), 144 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 03db7b7cc..cc092d175 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4728 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4729 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 08cc2edb2..821352782 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -180,69 +180,50 @@ function handleCheckboxes() {
-{if (($user->isPluginEnabled('cl') && !($user->isClient() && $user->client_id)) || ($custom_fields && $custom_fields->fields[0] && $custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN))} - {if $user->isPluginEnabled('cl') && !($user->isClient() && $user->client_id)}{else}{/if} - - {if ($custom_fields && $custom_fields->fields[0] && $custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN)}{else}{/if} - - - - - - + + + + +{if $show_users} @@ -269,56 +250,65 @@ function handleCheckboxes() { - - - + + diff --git a/reports.php b/reports.php index f938872b6..10df36483 100644 --- a/reports.php +++ b/reports.php @@ -49,7 +49,6 @@ // End of access checks. $trackingMode = $user->getTrackingMode(); -$showClient = $user->isPluginEnabled('cl') && !$user->isClient(); // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { @@ -58,6 +57,8 @@ $smarty->assign('custom_fields', $custom_fields); $showCustomFieldCheckbox = $custom_fields->fields[0]; $showCustomFieldDropdown = $custom_fields->fields[0] && $custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN; + if ($showCustomFieldDropdown) + $showCustomFieldDropdown &= count($custom_fields->options) > 0; } $form = new Form('reportForm'); @@ -77,12 +78,16 @@ $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'),'onclick'=>"return confirm('".$i18n->get('form.reports.confirm_delete')."')")); // Dropdown for clients if the clients plugin is enabled. +$showClient = $user->isPluginEnabled('cl') && !$user->isClient(); if ($showClient) { if ($user->can('view_reports') || $user->can('view_all_reports')) { $client_list = ttClientHelper::getClients(); // TODO: improve getClients for "view_reports" // by filtering out not relevant clients. } else $client_list = ttClientHelper::getClientsForUser(); + if (count($client_list) == 0) $showClient = false; +} +if ($showClient) { $form->addInput(array('type'=>'combobox', 'name'=>'client', 'style'=>'width: 250px;', @@ -100,23 +105,35 @@ 'empty'=>array(''=>$i18n->get('dropdown.all')))); } -// Add controls for projects and tasks. -if ($user->can('view_reports') || $user->can('view_all_reports')) { - $project_list = ttProjectHelper::getProjects(); // All active and inactive projects. -} elseif ($user->isClient()) { - $project_list = ttProjectHelper::getProjectsForClient(); -} else { - $project_list = ttProjectHelper::getAssignedProjects($user->getUser()); +// Add project dropdown. +$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showProject) { + if ($user->can('view_reports') || $user->can('view_all_reports')) { + $project_list = ttProjectHelper::getProjects(); // All active and inactive projects. + } elseif ($user->isClient()) { + $project_list = ttProjectHelper::getProjectsForClient(); + } else { + $project_list = ttProjectHelper::getAssignedProjects($user->getUser()); + } + if (count($project_list) == 0) $showProject = false; } -$form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);selectAssignedUsers(this.value);', - 'name'=>'project', - 'style'=>'width: 250px;', - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.all')))); -if (MODE_PROJECTS_AND_TASKS == $trackingMode) { +if ($showProject) { + $form->addInput(array('type'=>'combobox', + 'onchange'=>'fillTaskDropdown(this.value);selectAssignedUsers(this.value);', + 'name'=>'project', + 'style'=>'width: 250px;', + 'data'=>$project_list, + 'datakeys'=>array('id','name'), + 'empty'=>array(''=>$i18n->get('dropdown.all')))); +} + +// Add task dropdown. +$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) { $task_list = ttGroupHelper::getActiveTasks(); + if (count($task_list) == 0) $showTask = false; +} +if ($showTask) { $form->addInput(array('type'=>'combobox', 'name'=>'task', 'style'=>'width: 250px;', @@ -125,17 +142,21 @@ 'empty'=>array(''=>$i18n->get('dropdown.all')))); } -// Add include records control. -$include_options = array('1'=>$i18n->get('form.reports.include_billable'), - '2'=>$i18n->get('form.reports.include_not_billable')); -$form->addInput(array('type'=>'combobox', - 'name'=>'include_records', - 'style'=>'width: 250px;', - 'data'=>$include_options, - 'empty'=>array(''=>$i18n->get('dropdown.all')))); +// Add billable dropdown. +$showBillable = $user->isPluginEnabled('iv'); +if ($showBillable) { + $include_options = array('1'=>$i18n->get('form.reports.include_billable'), + '2'=>$i18n->get('form.reports.include_not_billable')); + $form->addInput(array('type'=>'combobox', + 'name'=>'include_records', // TODO: how about a better name here? + 'style'=>'width: 250px;', + 'data'=>$include_options, + 'empty'=>array(''=>$i18n->get('dropdown.all')))); +} // Add invoiced / not invoiced selector. -if ($user->can('manage_invoices')) { +$showInvoiceDropdown = $user->isPluginEnabled('iv') && $user->can('manage_invoices'); +if ($showInvoiceDropdown) { $invoice_options = array('1'=>$i18n->get('form.reports.include_invoiced'), '2'=>$i18n->get('form.reports.include_not_invoiced')); $form->addInput(array('type'=>'combobox', @@ -144,8 +165,11 @@ 'data'=>$invoice_options, 'empty'=>array(''=>$i18n->get('dropdown.all')))); } +$showInvoiceCheckbox = $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->isClient()); -if ($user->can('manage_invoices') && $user->isPluginEnabled('ps')) { +// Add paid status selector. +$showPaidStatus = $user->isPluginEnabled('ps') && $user->can('manage_invoices'); +if ($showPaidStatus) { $form->addInput(array('type'=>'combobox', 'name'=>'paid_status', 'style'=>'width: 250px;', @@ -154,18 +178,23 @@ )); } -// TODO: check rights. -if ($user->isPluginEnabled('ts')) { +// Add timesheet assignment selector. +$showTimesheet = $user->isPluginEnabled('ts') && + ($user->can('view_own_timesheets') || $user->can('manage_own_timesheets') || + $user->can('view_timesheets') || $user->can('manage_timesheets') || $user->can('approve_timesheets')); +if ($showTimesheet) { $form->addInput(array('type'=>'combobox', 'name'=>'timesheet', 'style'=>'width: 250px;', 'data'=>array('1'=>$i18n->get('form.reports.include_assigned'),'2'=>$i18n->get('form.reports.include_not_assigned')), 'empty'=>array(''=>$i18n->get('dropdown.all')) - )); + )); } +// Add user table. +$showUsers = $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient(); $user_list = array(); -if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { +if ($showUsers) { // Prepare user and assigned projects arrays. if ($user->can('view_reports') || $user->can('view_all_reports')) { $rank = $user->getMaxRankForGroup($user->getGroup()); @@ -212,31 +241,37 @@ $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start_date')); $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'end_date')); -// Add checkboxes for fields. +// Add checkboxes for "Show fields" block. if ($showClient) $form->addInput(array('type'=>'checkbox','name'=>'chclient')); -if (($user->can('manage_invoices') || $user->isClient()) && $user->isPluginEnabled('iv')) +if ($showProject) + $form->addInput(array('type'=>'checkbox','name'=>'chproject')); +if ($showTask) + $form->addInput(array('type'=>'checkbox','name'=>'chtask')); +if ($showCustomFieldCheckbox) + $form->addInput(array('type'=>'checkbox','name'=>'chcf_1')); +if ($showInvoiceCheckbox) $form->addInput(array('type'=>'checkbox','name'=>'chinvoice')); -if ($user->can('manage_invoices') && $user->isPluginEnabled('ps')) +if ($showPaidStatus) $form->addInput(array('type'=>'checkbox','name'=>'chpaid')); -if ($user->can('view_reports') || $user->can('view_all_reports')) +$showIP = $user->can('view_reports') || $user->can('view_all_reports'); +if ($showIP) $form->addInput(array('type'=>'checkbox','name'=>'chip')); -if (MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode) - $form->addInput(array('type'=>'checkbox','name'=>'chproject')); -if (MODE_PROJECTS_AND_TASKS == $trackingMode) - $form->addInput(array('type'=>'checkbox','name'=>'chtask')); -if ((TYPE_START_FINISH == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) { +$recordType = $user->getRecordType(); +$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; +$showFinish = $showStart; +if ($showStart) $form->addInput(array('type'=>'checkbox','name'=>'chstart')); +if ($showFinish) $form->addInput(array('type'=>'checkbox','name'=>'chfinish')); -} $form->addInput(array('type'=>'checkbox','name'=>'chduration')); $form->addInput(array('type'=>'checkbox','name'=>'chnote')); $form->addInput(array('type'=>'checkbox','name'=>'chcost')); -// If we have a custom field - add a checkbox for it. -if ($custom_fields && $custom_fields->fields[0]) - $form->addInput(array('type'=>'checkbox','name'=>'chcf_1')); -if ($user->isPluginEnabled('wu')) +$showWorkUnits = $user->isPluginEnabled('wu'); +if ($showWorkUnits) $form->addInput(array('type'=>'checkbox','name'=>'chunits')); +if ($showTimesheet) + $form->addInput(array('type'=>'checkbox','name'=>'chtimesheet')); // Add group by control. $group_by_options['no_grouping'] = $i18n->get('form.reports.group_by_no'); @@ -288,6 +323,7 @@ $form->setValueByElement('chnote', '1'); $form->setValueByElement('chcf_1', '0'); $form->setValueByElement('chunits', '0'); + $form->setValueByElement('chtimesheet', '0'); $form->setValueByElement('chtotalsonly', '0'); } @@ -376,6 +412,20 @@ } // isPost $smarty->assign('show_client', $showClient); +$smarty->assign('show_cf_1_dropdown', $showCustomFieldDropdown); +$smarty->assign('show_cf_1_checkbox', $showCustomFieldCheckbox); +$smarty->assign('show_project', $showProject); +$smarty->assign('show_task', $showTask); +$smarty->assign('show_billable', $showBillable); +$smarty->assign('show_invoice_dropdown', $showInvoiceDropdown); +$smarty->assign('show_invoice_checkbox', $showInvoiceCheckbox); +$smarty->assign('show_paid_status', $showPaidStatus); +$smarty->assign('show_timesheet', $showTimesheet); +$smarty->assign('show_users', $showUsers); +$smarty->assign('show_start', $showStart); +$smarty->assign('show_finish', $showFinish); +$smarty->assign('show_work_units', $showWorkUnits); +$smarty->assign('show_ip', $showIP); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); $smarty->assign('assigned_projects', $assigned_projects); From 1ed162514b774ef5d2f9858efa2436b19d99d484 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 16 Feb 2019 22:11:19 +0000 Subject: [PATCH 0665/1848] Added button.create_timesheet to translation files. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- report.php | 3 +++ 32 files changed, 56 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index cc9e1a345..7526cdbaa 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -144,6 +144,8 @@ 'button.send' => 'Enviar', 'button.send_by_email' => 'Enviar per correu', 'button.create_group' => 'Crear grup', +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportar grup', 'button.import' => 'Importar grup', // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 017960967..e1dae902a 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -146,6 +146,8 @@ 'button.send' => 'Poslat', 'button.send_by_email' => 'Poslat e-mailem', 'button.create_group' => 'Vytvořit tým', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportovat tým', // TODO: replace "team" with "group". 'button.import' => 'Importovat tým', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index def9e45f9..ba4068c9b 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -138,6 +138,8 @@ 'button.send' => 'Send', 'button.send_by_email' => 'Send som e-mail', 'button.create_group' => 'Lav et team', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Eksporter team', // TODO: replace "team" with "group". 'button.import' => 'Importer team', // TODO: replace "team" with "group". 'button.close' => 'Luk', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index bb9d0cf4b..eead92b03 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -132,6 +132,8 @@ 'button.send' => 'Senden', 'button.send_by_email' => 'Als E-Mail senden', 'button.create_group' => 'Gruppe erstellen', +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Gruppe exportieren', 'button.import' => 'Gruppe importieren', 'button.close' => 'Schließen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index a6be48642..ef776cdf8 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -126,6 +126,7 @@ 'button.send' => 'Send', 'button.send_by_email' => 'Send by e-mail', 'button.create_group' => 'Create group', +'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Export group', 'button.import' => 'Import group', 'button.close' => 'Close', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 6ed57b724..74fc90361 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -143,6 +143,8 @@ 'button.send' => 'Enviar', 'button.send_by_email' => 'Enviar por correo', 'button.create_group' => 'Crear grupo', +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportar grupo', 'button.import' => 'Importar grupo', // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index c65e3b212..60cf19afb 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -146,6 +146,8 @@ 'button.send' => 'Saada', 'button.send_by_email' => 'Saada e-postiga', 'button.create_group' => 'Loo grupp', +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Ekspordi grupp', 'button.import' => 'Impordi grupp', 'button.close' => 'Sulge', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 78e173225..e47538221 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -145,6 +145,8 @@ 'button.send' => 'ارسال', 'button.send_by_email' => 'ارسال به ایمیل', 'button.create_group' => 'ایجاد تیم', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'ایجاد پشتیبان از تیم', // TODO: replace "team" with "group". 'button.import' => 'وارد کردن تیم', // TODO: replace "team" with "group". 'button.close' => 'بستن', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 3b8e34d4d..2c1af6a56 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -140,6 +140,8 @@ 'button.send' => 'Lähetä', 'button.send_by_email' => 'Lähetä sähköpostilla', 'button.create_group' => 'Luo tiimi', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Vie tiimi', // TODO: replace "team" with "group". 'button.import' => 'Tuo tiimi', // TODO: replace "team" with "group". 'button.close' => 'Sulje', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index de4cb46c6..e02ccbe72 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -138,6 +138,8 @@ 'button.send' => 'Envoyer', 'button.send_by_email' => 'Envoyer par courriel', 'button.create_group' => 'Créer une équipe', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exporter l\\\'équipe', // TODO: replace "team" with "group". 'button.import' => 'Importer une équipe', // TODO: replace "team" with "group". 'button.close' => 'Fermer', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 1396d5f51..12b31464d 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -133,6 +133,8 @@ 'button.send' => 'Αποστολή', 'button.send_by_email' => 'Αποστολή μέσω email', 'button.create_group' => 'Δημιουργία ομάδας', +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Εξαγωγη ομάδας', 'button.import' => 'Εισαγωγή ομάδας', 'button.close' => 'Κλείσιμο', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 829260333..5dce3e0bc 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -155,6 +155,8 @@ 'button.send' => 'שלח', 'button.send_by_email' => 'שלח בדואר אלקטרוני', 'button.create_group' => 'צור צוות', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'ייצא צוות', // TODO: replace "team" with "group". 'button.import' => 'ייבא צוות', // TODO: replace "team" with "group". 'button.close' => 'סגור', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index ca9f2bb13..3d29edce1 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -145,6 +145,8 @@ 'button.send' => 'Küld', 'button.send_by_email' => 'Küldés e-mail-ben', 'button.create_group' => 'Csoport létrehozása', +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Csoport exportálása', 'button.import' => 'Csoport importálása', // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index e3ceb037d..97c14e0c1 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -137,6 +137,8 @@ 'button.send' => 'Invia', 'button.send_by_email' => 'Invia tramite e-mail', 'button.create_group' => 'Crea gruppo', +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Esporta gruppo', 'button.import' => 'Importa gruppo', 'button.close' => 'Chiudi', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 646739c5f..b7764ba33 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -150,6 +150,7 @@ 'button.send_by_email' => 'Eメールの送信', // TODO: translate the following. // 'button.create_group' => 'Create group', +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'チームのエクスポート', // TODO: replace "team" with "group". 'button.import' => 'チームのインポート', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index f34bb9c26..f2efa455f 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -149,6 +149,7 @@ 'button.send_by_email' => '이메일로 송신', // TODO: translate the following. // 'button.create_group' => 'Create group', +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => '팀 익스포트', // TODO: replace "team" with "group". 'button.import' => '팀 임포트', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index d08150cca..564b79a4c 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -126,6 +126,8 @@ 'button.send' => 'Verzenden', 'button.send_by_email' => 'Verzend per e-mail', 'button.create_group' => 'Maak groep', +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Groep exporteren', 'button.import' => 'Groep importeren', 'button.close' => 'Sluiten', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 829e75a3e..35b9dc05c 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -149,6 +149,8 @@ 'button.send' => 'Send', 'button.send_by_email' => 'Send som e-post', 'button.create_group' => 'Opprett team', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Eksport team', // TODO: replace "team" with "group". 'button.import' => 'Importer team', // TODO: replace "team" with "group". 'button.close' => 'Lukk', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index f615a792e..dedbd1fb8 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -142,6 +142,8 @@ 'button.send' => 'Wyślij', 'button.send_by_email' => 'Wyślij e-mail', 'button.create_group' => 'Stwórz zespół', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Eksportuj zespół', // TODO: replace "team" with "group". 'button.import' => 'Importuj zespół', // TODO: replace "team" with "group". 'button.close' => 'Zamknij', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index d50deaf39..af3661403 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -139,6 +139,8 @@ 'button.send' => 'Enviar', 'button.send_by_email' => 'Enviar por e-mail', 'button.create_group' => 'Criar equipe', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportar equipe', // TODO: replace "team" with "group". 'button.import' => 'Importar equipe', // TODO: replace "team" with "group". 'button.close' => 'Fechar', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 923870875..f55e42263 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -143,6 +143,7 @@ 'button.send_by_email' => 'Enviar por e-mail', // TODO: translate the following. // 'button.create_group' => 'Create group', +// 'button.create_timesheet' => 'Create timesheet', // 'button.export' => 'Export group', // 'button.import' => 'Import group', // 'button.close' => 'Close', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 57e75a5c6..9cc731f95 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -149,6 +149,8 @@ 'button.send' => 'Trimite', 'button.send_by_email' => 'Trimite pe e-mail', 'button.create_group' => 'Adauga echipa', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exporta echipa', // TODO: replace "team" with "group". 'button.import' => 'Importa echipa', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index aa3e03d8b..e184ed66a 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -125,6 +125,7 @@ 'button.send' => 'Отправить', 'button.send_by_email' => 'Отправить по e-mail', 'button.create_group' => 'Создать группу', +'button.create_timesheet' => 'Создать табель', 'button.export' => 'Экспортировать группу', 'button.import' => 'Импортировать группу', 'button.close' => 'Закрыть', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 45afda9cc..dac0f5cab 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -145,6 +145,8 @@ 'button.send' => 'Odoslať', 'button.send_by_email' => 'Odoslať na e-mail', 'button.create_group' => 'Vytvoriť tím', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportovať tím', // TODO: replace "team" with "group". 'button.import' => 'Importovať tím', // TODO: replace "team" with "group". 'button.close' => 'Zatvoriť', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index c0acbf08d..4c3ba08b9 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -139,6 +139,8 @@ 'button.send' => 'Pošlji', 'button.send_by_email' => 'Pošlji preko elektronske pošte', 'button.create_group' => 'Ustvari tim', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Izvozi tim', // TODO: replace "team" with "group". 'button.import' => 'Uvozi tim', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index ccfd332ed..a10d95df6 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -139,6 +139,8 @@ 'button.send' => 'Pošalji', 'button.send_by_email' => 'Pošalji mejlom', 'button.create_group' => 'Napravi tim', // TODO: replace "team" with "group". +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Izvezi tim', // TODO: replace "team" with "group". 'button.import' => 'Uvezi tim', // TODO: replace "team" with "group". 'button.close' => 'Zatvori', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 4b0883902..bfa5e8dd2 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -137,6 +137,8 @@ 'button.send' => 'Skicka', 'button.send_by_email' => 'Skicka som e-post', 'button.create_group' => 'Skapa grupp', +// TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportera grupp', 'button.import' => 'Importera grupp', 'button.close' => 'Stäng', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 7340c3c49..73b8774a6 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -153,6 +153,7 @@ 'button.send_by_email' => 'E-posta ile gönder', 'button.create_group' => 'Ekip yarat', // TODO: replace "team" with "group". // TODO: translate the following. +// 'button.create_timesheet' => 'Create timesheet', // 'button.export' => 'Export group', 'button.import' => 'Ekibi içeri aktar', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5822b7b44..b0e63cfe2 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -141,6 +141,7 @@ 'button.send_by_email' => '通过邮件发送', // TODO: translate the following. // 'button.create_group' => 'Create group', +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => '导出团队信息', // TODO: replace "team" with "group". 'button.import' => '导入团队信息', // TODO: replace "team" with "group". 'button.close' => '关闭', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 5a0f3d21a..067b515fb 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -146,6 +146,7 @@ 'button.send_by_email' => '通過郵件發送', // TODO: translate the following. // 'button.create_group' => 'Create group', +// 'button.create_timesheet' => 'Create timesheet', 'button.export' => '輸出團隊資訊', // TODO: replace "team" with "group". 'button.import' => '輸入團隊資訊', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index cc092d175..b252d6f85 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.client}  {$i18n.label.option} 
{$forms.reportForm.client.control} {$forms.reportForm.option.control}
+ +{if $show_client} + + {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} - - - - {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} - - {/if} - +{if $show_project} + + {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} - - - - {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} - - {/if} - +{if $show_billable} + + {/if} -{if $user->isPluginEnabled('iv')} - - - - {if $user->can('manage_invoices')} - - {/if} - - - - - {if $user->can('manage_invoices')} - - - {/if} +{if $show_paid_status} + + {/if} -{if ($user->can('manage_invoices') && $user->isPluginEnabled('ps'))} - - - - {if $user->isPluginEnabled('ts')} - - {/if} - - - - - {if $user->isPluginEnabled('ts')} - - {/if} - +
{$i18n.label.client}
{$forms.reportForm.client.control}
{$i18n.label.project} {$i18n.label.task}
{$i18n.label.project}
{$forms.reportForm.project.control}
{$forms.reportForm.project.control} {$forms.reportForm.task.control}
{$i18n.form.time.billable}
{$forms.reportForm.include_records.control}
{$i18n.form.time.billable} {$i18n.label.invoice}
{$forms.reportForm.include_records.control} {$forms.reportForm.invoice.control}
{$i18n.label.paid_status}
{$forms.reportForm.paid_status.control}
{$i18n.label.paid_status} {$i18n.label.timesheet}
{$forms.reportForm.paid_status.control} {$forms.reportForm.timesheet.control}
+
+ +{if $show_cf_1_dropdown} + + +{/if} +{if $show_task} + + +{/if} +{if $show_invoice_dropdown} + + +{/if} +{if $show_timesheet} + + {/if} -{if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()} +
{$i18n.label.option}
{$forms.reportForm.option.control}
{$i18n.label.task}
{$forms.reportForm.task.control}
{$i18n.label.invoice}
{$forms.reportForm.invoice.control}
{$i18n.label.timesheet}
{$forms.reportForm.timesheet.control}
+
{$i18n.label.users}
-{if $user->can('view_reports') || $user->can('view_all_reports') || $user->isPluginEnabled('cl') || $user->isPluginEnabled('iv') || $user->isPluginEnabled('ps')} - {if $user->isPluginEnabled('cl')} - - {/if} - {if ($user->can('manage_invoices') || $user->isClient()) && $user->isPluginEnabled('iv')} - - {/if} - {if ($user->can('manage_invoices') && $user->isPluginEnabled('ps'))} - - {/if} - {if $user->can('view_reports') || $user->can('view_all_reports')} - - {/if} - + + + + +
+ +{if $show_client} + {/if} - - - - -{if ($user->can('manage_invoices') || $user->isClient()) || $user->isPluginEnabled('ex')} - -{else} - +{if $show_project} + {/if} - - - - - -{if ($custom_fields && $custom_fields->fields[0])} - -{else} - +{if $show_timesheet} + {/if} - -{if $user->isPluginEnabled('wu')} - - - - - - +{if $show_cf_1_checkbox} + +{/if} +
{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}{/if}{if (($smarty.const.TYPE_START_FINISH == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))}{/if}
{if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}{/if}{if (($smarty.const.TYPE_START_FINISH == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))}{/if}
+
+ +{if $show_start} + +{/if} +{if $show_task} + +{/if} +{if $show_ip} + +{/if} +{if $show_work_units} + +{/if} +
+
+ +{if $show_finish} + {/if} + +{if $show_invoice_checkbox} + +{/if} +
+
+ + + +{if $show_paid_status} + +{/if} +
+
{$i18n.form.reports.group_by}
{$i18n.form.reports.group_by}
{$forms.reportForm.group_by1.control} {$forms.reportForm.group_by2.control}
-
 Anuko Time Tracker 1.18.37.4729 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4730 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index cb563b9b0..d094df86e 100644 --- a/report.php +++ b/report.php @@ -183,6 +183,9 @@ } $totals = ttReportHelper::getTotals($options); +// TODO: Determine if we can create a timesheet out of this report. +// There must be only one user, and nothing assigned to existing timesheets. + // Assign variables that are used to print subtotals. if ($report_items) { $smarty->assign('print_subtotals', true); From 90437750e88c95b0412c3f171617d96d4ce87bb8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 17 Feb 2019 13:05:55 +0000 Subject: [PATCH 0666/1848] Refactoring ttReportHelper for timesheets. --- WEB-INF/lib/ttReportHelper.class.php | 26 ++++++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 686283bcf..1b5fc6f10 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -150,9 +150,10 @@ static function getItems($options) { // Prepare a query for time items in tt_log table. $fields = array(); // An array of fields for database query. - array_push($fields, 'l.id as id'); + array_push($fields, 'l.id'); + array_push($fields, 'l.user_id'); array_push($fields, '1 as type'); // Type 1 is for tt_log entries. - array_push($fields, 'l.date as date'); + array_push($fields, 'l.date'); if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. @@ -210,13 +211,13 @@ static function getItems($options) { } // Add paid status. if ($canViewReports && $options['show_paid']) - array_push($fields, 'l.paid as paid'); + array_push($fields, 'l.paid'); // Add IP address. if ($canViewReports && $options['show_ip']) { - array_push($fields, 'l.created as created'); - array_push($fields, 'l.created_ip as created_ip'); - array_push($fields, 'l.modified as modified'); - array_push($fields, 'l.modified_ip as modified_ip'); + array_push($fields, 'l.created'); + array_push($fields, 'l.created_ip'); + array_push($fields, 'l.modified'); + array_push($fields, 'l.modified_ip'); } // Add invoice name if it is selected. if (($canViewReports || $isClient) && $options['show_invoice']) @@ -257,6 +258,7 @@ static function getItems($options) { $fields = array(); // An array of fields for database query. array_push($fields, 'ei.id'); + array_push($fields, 'ei.user_id'); array_push($fields, '2 as type'); // Type 2 is for tt_expense_items entries. array_push($fields, 'ei.date'); if($canViewReports || $isClient) @@ -288,13 +290,13 @@ static function getItems($options) { array_push($fields, 'ei.cost as expense'); // Add paid status. if ($canViewReports && $options['show_paid']) - array_push($fields, 'ei.paid as paid'); + array_push($fields, 'ei.paid'); // Add IP address. if ($canViewReports && $options['show_ip']) { - array_push($fields, 'ei.created as created'); - array_push($fields, 'ei.created_ip as created_ip'); - array_push($fields, 'ei.modified as modified'); - array_push($fields, 'ei.modified_ip as modified_ip'); + array_push($fields, 'ei.created'); + array_push($fields, 'ei.created_ip'); + array_push($fields, 'ei.modified'); + array_push($fields, 'ei.modified_ip'); } // Add invoice name if it is selected. if (($canViewReports || $isClient) && $options['show_invoice']) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b252d6f85..8ef58558c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4730 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4731 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 0ae87b2b2eeb7710e1d169f63708c6c5dc2e2452 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 17 Feb 2019 14:17:06 +0000 Subject: [PATCH 0667/1848] Added Create timesheet button on report.php. --- WEB-INF/lib/ttReportHelper.class.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 3 +++ report.php | 29 ++++++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 1b5fc6f10..c3656ad6f 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -154,6 +154,7 @@ static function getItems($options) { array_push($fields, 'l.user_id'); array_push($fields, '1 as type'); // Type 1 is for tt_log entries. array_push($fields, 'l.date'); + array_push($fields, 'l.timesheet_id'); if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. @@ -261,6 +262,7 @@ static function getItems($options) { array_push($fields, 'ei.user_id'); array_push($fields, '2 as type'); // Type 2 is for tt_expense_items entries. array_push($fields, 'ei.date'); + array_push($fields, 'ei.timesheet_id'); if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8ef58558c..e3d319ac9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/report.php b/report.php index d094df86e..7ecabcc57 100644 --- a/report.php +++ b/report.php @@ -185,6 +185,34 @@ // TODO: Determine if we can create a timesheet out of this report. // There must be only one user, and nothing assigned to existing timesheets. +$canCreateTimesheet = false; +if ($user->isPluginEnabled('ts') && count($report_items) > 0 && + ($user->can('manage_own_timesheets') || $user->can('manage_timesheets'))) { + + $canCreateTimesheet = true; // Start with true and reset if we can't. + $first_user_id = null; + foreach ($report_items as $report_item) { + // Check user id. + if (!$first_user_id) + $first_user_id = $report_item['user_id']; + else { + if ($report_item['user_id'] != $first_user_id) { + // We have items for multiple users. + $canCreateTimesheet = false; + break; + } + } + // Check timesheet id. + if ($report_item['timesheet_id']) { + // We have an item already assigned to a timesheet. + $canCreateTimesheet = false; + break; + } + } + + // TODO: Improve this for "view_all_reports" situation. + // We may need to add "manage_all_timesheets" right. +} // Assign variables that are used to print subtotals. if ($report_items) { @@ -202,6 +230,7 @@ $smarty->assign('report_items', $report_items); $smarty->assign('subtotals', $subtotals); $smarty->assign('totals', $totals); +$smarty->assign('can_create_timesheet', $canCreateTimesheet); $smarty->assign('bean', $bean); $smarty->assign('title', $i18n->get('title.report').": ".$totals['start_date']." - ".$totals['end_date']); $smarty->assign('content_page_name', 'report.tpl'); From e9a0449fe594cca8fa7645f02ae5365402d96259 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 17 Feb 2019 14:58:45 +0000 Subject: [PATCH 0668/1848] Work in progress on adding timesheets. --- WEB-INF/resources/ca.lang.php | 3 ++ WEB-INF/resources/cs.lang.php | 3 ++ WEB-INF/resources/da.lang.php | 4 ++ WEB-INF/resources/de.lang.php | 4 ++ WEB-INF/resources/en.lang.php | 3 ++ WEB-INF/resources/es.lang.php | 3 ++ WEB-INF/resources/et.lang.php | 4 ++ WEB-INF/resources/fa.lang.php | 3 ++ WEB-INF/resources/fi.lang.php | 3 ++ WEB-INF/resources/fr.lang.php | 4 ++ WEB-INF/resources/gr.lang.php | 4 ++ WEB-INF/resources/he.lang.php | 3 ++ WEB-INF/resources/hu.lang.php | 3 ++ WEB-INF/resources/it.lang.php | 4 ++ WEB-INF/resources/ja.lang.php | 3 ++ WEB-INF/resources/ko.lang.php | 3 ++ WEB-INF/resources/nl.lang.php | 4 ++ WEB-INF/resources/no.lang.php | 3 ++ WEB-INF/resources/pl.lang.php | 4 ++ WEB-INF/resources/pt-br.lang.php | 4 ++ WEB-INF/resources/pt.lang.php | 3 ++ WEB-INF/resources/ro.lang.php | 3 ++ WEB-INF/resources/ru.lang.php | 3 ++ WEB-INF/resources/sk.lang.php | 3 ++ WEB-INF/resources/sl.lang.php | 3 ++ WEB-INF/resources/sr.lang.php | 4 ++ WEB-INF/resources/sv.lang.php | 4 ++ WEB-INF/resources/tr.lang.php | 3 ++ WEB-INF/resources/zh-cn.lang.php | 3 ++ WEB-INF/resources/zh-tw.lang.php | 3 ++ WEB-INF/templates/timesheet_add.tpl | 29 +++++++++++ timesheet_add.php | 80 +++++++++++++++++++++++++++++ 32 files changed, 210 insertions(+) create mode 100644 WEB-INF/templates/timesheet_add.tpl create mode 100644 timesheet_add.php diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 7526cdbaa..f129c9b3b 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -339,6 +339,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index e1dae902a..d722cb92a 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -350,6 +350,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index ba4068c9b..976d9f3fc 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -316,6 +316,10 @@ 'title.add_notification' => 'Tilføj Meddelelse', 'title.edit_notification' => 'Redigér Meddelelse', 'title.delete_notification' => 'Slet Meddelelse', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', 'title.monthly_quotas' => 'Månedlig Kvota', 'title.export' => 'Eksporter Team Data', // TODO: replace "team" with "group". 'title.import' => 'Importer Team Data', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index eead92b03..6ac1c0345 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -299,6 +299,10 @@ 'title.add_notification' => 'Benachrichtigung hinzufügen', 'title.edit_notification' => 'Benachrichtigung bearbeiten', 'title.delete_notification' => 'Benachrichtigung löschen', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', 'title.monthly_quotas' => 'Monatliche Quoten', 'title.export' => 'Daten exportieren', 'title.import' => 'Daten importieren', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index ef776cdf8..5da77cb21 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -291,6 +291,9 @@ 'title.add_notification' => 'Adding Notification', 'title.edit_notification' => 'Editing Notification', 'title.delete_notification' => 'Deleting Notification', +'title.add_timesheet' => 'Adding Timesheet', +'title.edit_timesheet' => 'Editing Timesheet', +'title.delete_timesheet' => 'Deleting Timesheet', 'title.monthly_quotas' => 'Monthly Quotas', 'title.export' => 'Exporting Group Data', 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 74fc90361..124bfed7b 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -338,6 +338,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', 'title.export' => 'Exportar datos', // TODO: Consider changing to exportando for consistency with other titles. 'title.import' => 'Importar datos', // TODO: Consider changing to importando for consistency with other titles. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 60cf19afb..864fb91eb 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -319,6 +319,10 @@ 'title.add_notification' => 'Teate lisamine', 'title.edit_notification' => 'Teate muutmine', 'title.delete_notification' => 'Teate kustutamine', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', 'title.monthly_quotas' => 'Kuu kvoot', 'title.export' => 'Grupi andmete alla laadimine', 'title.import' => 'Grupi andmete üles laadimine', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index e47538221..501d9572a 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -323,6 +323,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', 'title.export' => 'پشتیانی گرفتن از اطلاعات تیم', // TODO: replace "team" with "group". 'title.import' => 'وارد کردن اطلاعات تیم', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 2c1af6a56..e400a9418 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -317,6 +317,9 @@ 'title.edit_notification' => 'Ilmoituksen muokkaus', 'title.delete_notification' => 'Ilmoituksen poisto', // TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', 'title.export' => 'Tiimitietojen vienti', // TODO: replace "team" with "group". 'title.import' => 'Tiimitietojen tunti', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index e02ccbe72..3f411e9fd 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -310,6 +310,10 @@ 'title.add_notification' => 'Ajout d\\\'une notification', 'title.edit_notification' => 'Modification d\\\'une notification', 'title.delete_notification' => 'Suppression d\\\'une notification', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', 'title.monthly_quotas' => 'Quotas mensuels', 'title.export' => 'Exportation des données', 'title.import' => 'Importation des données', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 12b31464d..60b312a02 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -306,6 +306,10 @@ 'title.add_notification' => 'Προσθήκη ειδοποίησης', 'title.edit_notification' => 'Επεξεργασία ειδοποίησης', 'title.delete_notification' => 'Διαγραφή ειδοποίησης', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', 'title.monthly_quotas' => 'Μηνιαίες ποσοστώσεις', 'title.export' => 'Εξαγωγή δεδομένων ομάδας', 'title.import' => 'Εισαγωγή δεδομένων ομάδας', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 5dce3e0bc..5cfe3f202 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -335,6 +335,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', 'title.export' => 'ייצוא נתוני צוות', // TODO: replace "team" with "group". 'title.import' => 'ייבוא נתוני צוות', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 3d29edce1..46d0bd6c4 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -337,6 +337,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 97c14e0c1..5215f7f6b 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -315,6 +315,10 @@ 'title.add_notification' => 'Aggiunta notifica', 'title.edit_notification' => 'Modifica notifica', 'title.delete_notification' => 'Eliminazione notifica', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', 'title.monthly_quotas' => 'Quote mensili', 'title.export' => 'Esporta i dati del gruppo', 'title.import' => 'Importa i dati del gruppo', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index b7764ba33..9c01727b0 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -344,6 +344,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index f2efa455f..8d5aa443a 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -345,6 +345,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 564b79a4c..1e7146f6a 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -294,6 +294,10 @@ 'title.add_notification' => 'Notificatie toevoegen', 'title.edit_notification' => 'Notificatie bewerken', 'title.delete_notification' => 'Notificatie verwijderen', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', 'title.monthly_quotas' => 'Doelen per maand', 'title.export' => 'Exporteer groepsgegevens', 'title.import' => 'Importeer groepsgegevens', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 35b9dc05c..6a38cb2a6 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -342,6 +342,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index dedbd1fb8..40167912e 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -317,6 +317,10 @@ 'title.add_notification' => 'Dodawanie powiadomienia', 'title.edit_notification' => 'Edytowanie powiadomienia', 'title.delete_notification' => 'Usuwanie powiadomienia', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', 'title.export' => 'Eksport danych zespołu', // TODO: replace "team" with "group". 'title.import' => 'Import danych zespołu', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index af3661403..61f06f35a 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -314,6 +314,10 @@ 'title.add_notification' => 'Adicionando notificação', 'title.edit_notification' => 'Editando notificação', 'title.delete_notification' => 'Apagando notificação', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', 'title.export' => 'Exportando dados de equipe', // TODO: replace "team" with "group". 'title.import' => 'Importando dados de equipe', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index f55e42263..09aa8b52e 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -325,6 +325,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 9cc731f95..f8d711f35 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -345,6 +345,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index e184ed66a..6c172c338 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -290,6 +290,9 @@ 'title.add_notification' => 'Добавление уведомления', 'title.edit_notification' => 'Редактирование уведомления', 'title.delete_notification' => 'Удаление уведомления', +'title.add_timesheet' => 'Добавление табеля', +'title.edit_timesheet' => 'Редактирование табеля', +'title.delete_timesheet' => 'Удаление табеля', 'title.monthly_quotas' => 'Месячные квоты', 'title.export' => 'Экспортирование данных группы', 'title.import' => 'Импортирование данных группы', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index dac0f5cab..d79db8431 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -325,6 +325,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', 'title.export' => 'Exportovanie údajov o tíme', // TODO: replace "team" with "group". 'title.import' => 'Importovanie údajov o tíme', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 4c3ba08b9..d720907db 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -320,6 +320,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index a10d95df6..e5be1d816 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -315,6 +315,10 @@ 'title.add_notification' => 'Dodavanje napomene', 'title.edit_notification' => 'Izmena napomene', 'title.delete_notification' => 'Brisanje napomene', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', 'title.export' => 'Izvoz podataka tim-a', // TODO: replace "team" with "group". 'title.import' => 'Uvoz podataka tim-a', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index bfa5e8dd2..75a258ddd 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -315,6 +315,10 @@ 'title.add_notification' => 'Lägg till avisering', 'title.edit_notification' => 'Redigera avisering', 'title.delete_notification' => 'Ta bort avisering', +// TODO: translate the following. +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', 'title.monthly_quotas' => 'Månadskvoter', 'title.export' => 'Exportera grupp', 'title.import' => 'Importera grupp', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 73b8774a6..b6b3aeb6a 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -353,6 +353,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index b0e63cfe2..5eb65a7fe 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -332,6 +332,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 067b515fb..68e505620 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -339,6 +339,9 @@ // 'title.add_notification' => 'Adding Notification', // 'title.edit_notification' => 'Editing Notification', // 'title.delete_notification' => 'Deleting Notification', +// 'title.add_timesheet' => 'Adding Timesheet', +// 'title.edit_timesheet' => 'Editing Timesheet', +// 'title.delete_timesheet' => 'Deleting Timesheet', // 'title.monthly_quotas' => 'Monthly Quotas', // 'title.export' => 'Exporting Group Data', // 'title.import' => 'Importing Group Data', diff --git a/WEB-INF/templates/timesheet_add.tpl b/WEB-INF/templates/timesheet_add.tpl new file mode 100644 index 000000000..b475af0ea --- /dev/null +++ b/WEB-INF/templates/timesheet_add.tpl @@ -0,0 +1,29 @@ +{$forms.timesheetForm.open} +
 Anuko Time Tracker 1.18.37.4731 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4732 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 0c98951f7..4212431b0 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -186,6 +186,9 @@ +{if $can_create_timesheet} + +{/if}
+ + + +
+ + + + + + + + + + + + + + + + + + + + +
{$i18n.label.thing_name} (*):{$forms.timesheetForm.timesheet_name.control}
{$i18n.label.comment}:{$forms.timesheetForm.submitter_comment.control}
{$i18n.label.required_fields}
 
{$forms.timesheetForm.btn_add.control}
+
+{$forms.timesheetForm.close} diff --git a/timesheet_add.php b/timesheet_add.php new file mode 100644 index 000000000..c52fea6a8 --- /dev/null +++ b/timesheet_add.php @@ -0,0 +1,80 @@ +isPluginEnabled('ts')) { + header('Location: feature_disabled.php'); + exit(); +} +// End of access checks. + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('timesheet_name')); + $cl_comment = trim($request->getParameter('submitter_comment')); +} + +$form = new Form('timesheetForm'); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'timesheet_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'submitter_comment','style'=>'width: 250px; height: 40px;','value'=>$cl_comment)); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); + + if ($err->no()) { + /* + if (!ttProjectHelper::getProjectByName($cl_name)) { + if (ttProjectHelper::insert(array('name' => $cl_name, + 'description' => $cl_description, + 'users' => $cl_users, + 'tasks' => $cl_tasks, + 'status' => ACTIVE))) { + header('Location: projects.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } else + $err->add($i18n->get('error.object_exists')); + */ + } +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.timesheetForm.timmesheet_name.focus()"'); +$smarty->assign('title', $i18n->get('title.add_timesheet')); +$smarty->assign('content_page_name', 'timesheet_add.tpl'); +$smarty->display('index.tpl'); From eb300930267977a1caac0355200467e4bdf8b655 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 17 Feb 2019 18:45:40 +0000 Subject: [PATCH 0669/1848] More progress on creating a new timesheet. --- WEB-INF/lib/form/ActionForm.class.php | 14 +++++ WEB-INF/lib/ttTimesheetHelper.class.php | 81 +++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 8 +-- report.php | 6 +- reports.php | 4 ++ timesheet_add.php | 23 ++++--- 7 files changed, 121 insertions(+), 17 deletions(-) create mode 100644 WEB-INF/lib/ttTimesheetHelper.class.php diff --git a/WEB-INF/lib/form/ActionForm.class.php b/WEB-INF/lib/form/ActionForm.class.php index 97c9219c0..8e2ad8af4 100644 --- a/WEB-INF/lib/form/ActionForm.class.php +++ b/WEB-INF/lib/form/ActionForm.class.php @@ -166,6 +166,20 @@ function saveBean() { } //print_r($_SESSION); } + + // saveDetachedAttribute saves a "detached" from form named attributed in session. + // There is no element in the form for it. + // Intended use is to add something to the session, when a form bean created on one page + // is used on other pages (ex.: reportForm). + // For example, to generate a timesheet we need a user_id, which is determined when a report + // is generated on report.php, using a bean created in reports.php. + function saveDetachedAttribute($name, $value) { + $_SESSION[$this->mSessionCell .'_'.$name] = $value; + } + + function getDetachedAttribute($name) { + return $_SESSION[$this->mSessionCell.'_'.$name]; + } function loadBean() { $el_list = @$_SESSION[$this->mSessionCell . "session_store_elements"]; diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php new file mode 100644 index 000000000..a8276b55a --- /dev/null +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -0,0 +1,81 @@ +getGroup(); + $org_id = $user->org_id; + + $sql = "select id from tt_timesheets". + " where group_id = $group_id and org_id = $org_id and user_id = $user_id and name = ".$mdb2->quote($name). + " and (status = 1 or status = 0)"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if ($val && $val['id']) + return $val; + } + return false; + } + + // insert function inserts a new timesheet into database. + static function insert($fields) + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $user_id = $fields['user_id']; + $client_id = $fields['client_id']; + $name = $fields['name']; + $submitter_comment = $fields['comment']; + + $sql = "insert into tt_timesheets (user_id, group_id, org_id, client_id, name, submitter_comment)". + " values ($user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($name).", ".$mdb2->quote($submitter_comment).")"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + $last_id = $mdb2->lastInsertID('tt_timesheets', 'id'); + + // TODO: Associate report items with new timesheet. + + return $last_id; + } +} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e3d319ac9..8b988eaf2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4732 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4733 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 4212431b0..3cd8e40ec 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -2,7 +2,7 @@ function chLocation(newLocation) { document.location = newLocation; } -{$forms.reportForm.open} +{$forms.reportViewForm.open}
@@ -162,7 +162,7 @@ @@ -171,14 +171,14 @@ {/if}
- +
{$i18n.label.mark_paid}: {$forms.reportForm.mark_paid_select_options.control} {$forms.reportForm.mark_paid_action_options.control} {$forms.reportForm.btn_mark_paid.control}
{$i18n.label.mark_paid}: {$forms.reportViewForm.mark_paid_select_options.control} {$forms.reportViewForm.mark_paid_action_options.control} {$forms.reportViewForm.btn_mark_paid.control}
- +
{$i18n.form.report.assign_to_invoice}: {$forms.reportForm.assign_invoice_select_options.control} {$forms.reportForm.recent_invoice.control} {$forms.reportForm.btn_assign.control}
{$i18n.form.report.assign_to_invoice}: {$forms.reportViewForm.assign_invoice_select_options.control} {$forms.reportViewForm.recent_invoice.control} {$forms.reportViewForm.btn_assign.control}
{/if} -{$forms.reportForm.close} +{$forms.reportViewForm.close} diff --git a/report.php b/report.php index 7ecabcc57..65d98e4e6 100644 --- a/report.php +++ b/report.php @@ -58,10 +58,10 @@ $smarty->assign('custom_fields', $custom_fields); } -$form = new Form('reportForm'); +$form = new Form('reportViewForm'); // Report settings are stored in session bean before we get here from reports.php. -$bean = new ActionForm('reportBean', $form, $request); +$bean = new ActionForm('reportBean', new Form('reportForm'), $request); // If we are in post, load the bean from session, as the constructor does it only in get. if ($request->isPost()) $bean->loadBean(); @@ -209,6 +209,8 @@ break; } } + // Save user_id in session. + $bean->saveDetachedAttribute('timesheet_user_id', $first_user_id); // TODO: Improve this for "view_all_reports" situation. // We may need to add "manage_all_timesheets" right. diff --git a/reports.php b/reports.php index 10df36483..892b117ea 100644 --- a/reports.php +++ b/reports.php @@ -273,6 +273,10 @@ if ($showTimesheet) $form->addInput(array('type'=>'checkbox','name'=>'chtimesheet')); +// Add a hidden control for timesheet_user_id (who to generate a timesheet for). +if ($showTimesheet) + $form->addInput(array('type'=>'hidden','name'=>'timesheet_user_id')); + // Add group by control. $group_by_options['no_grouping'] = $i18n->get('form.reports.group_by_no'); $group_by_options['date'] = $i18n->get('form.reports.group_by_date'); diff --git a/timesheet_add.php b/timesheet_add.php index c52fea6a8..fa32ca7ff 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -28,6 +28,7 @@ require_once('initialize.php'); import('form.Form'); +import('ttTimesheetHelper'); // Access checks. if (!(ttAccessAllowed('manage_own_timesheets') || ttAccessAllowed('manage_timesheets'))) { @@ -43,6 +44,10 @@ if ($request->isPost()) { $cl_name = trim($request->getParameter('timesheet_name')); $cl_comment = trim($request->getParameter('submitter_comment')); + + // Report settings are stored in session bean before we get here. + $bean = new ActionForm('reportBean', new Form('reportForm'), $request); + $bean->loadBean(); } $form = new Form('timesheetForm'); @@ -56,25 +61,23 @@ if (!ttValidString($cl_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); if ($err->no()) { - /* - if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array('name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE))) { - header('Location: projects.php'); + $user_id = $bean->getDetachedAttribute('timesheet_user_id'); + if (!ttTimesheetHelper::getTimesheetByName($cl_name, $user_id)) { + if (ttTimesheetHelper::insert(array('user_id' => $user_id, + // 'client_id' => ? + 'name' => $cl_name, + 'comment' => $cl_comment))) { + header('Location: timesheets.php'); exit(); } else $err->add($i18n->get('error.db')); } else $err->add($i18n->get('error.object_exists')); - */ } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.timesheetForm.timmesheet_name.focus()"'); +$smarty->assign('onload', 'onLoad="document.timesheetForm.timesheet_name.focus()"'); $smarty->assign('title', $i18n->get('title.add_timesheet')); $smarty->assign('content_page_name', 'timesheet_add.tpl'); $smarty->display('index.tpl'); From 8e930ac814c5ac5946d0a6c1124c61d7e2883cd1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 17 Feb 2019 22:13:38 +0000 Subject: [PATCH 0670/1848] Added client_id to timesheet insert. --- WEB-INF/templates/footer.tpl | 2 +- timesheet_add.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8b988eaf2..8e33a4874 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index 6a5269b58..45a67645d 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -27,7 +27,6 @@ {/if} - {foreach $active_timesheets as $timesheet} @@ -44,7 +43,6 @@ {if !$user->isClient()} - {/if} {/foreach} @@ -72,7 +70,6 @@ {/if} - {foreach $inactive_timesheets as $timesheet} @@ -89,7 +86,6 @@ {if !$user->isClient()} - {/if} {/foreach} diff --git a/timesheet_edit.php b/timesheet_edit.php index 50d2a44d4..1708bdf7c 100644 --- a/timesheet_edit.php +++ b/timesheet_edit.php @@ -64,17 +64,18 @@ $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); - if ($err->no()) { - if ($request->getParameter('btn_save')) { + if ($request->getParameter('btn_save')) { + if ($err->no()) { $existing_timesheet = ttTimesheetHelper::getTimesheetByName($cl_name, $timesheet['user_id']); if (!$existing_timesheet || ($cl_timesheet_id == $existing_timesheet['id'])) { - // Update project information. + // Update timesheet information. if (ttTimesheetHelper::update(array( 'id' => $cl_timesheet_id, 'name' => $cl_name, @@ -88,6 +89,11 @@ $err->add($i18n->get('error.object_exists')); } } + + if ($request->getParameter('btn_delete')) { + header("Location: timesheet_delete.php?id=$cl_timesheet_id"); + exit(); + } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); From 6d72b9b2a73391e8e6b2a3586b4972c1a2e8160d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 19 Feb 2019 15:28:59 +0000 Subject: [PATCH 0678/1848] Renamed client access rights for clarity. --- WEB-INF/lib/ttRoleHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 4 ++-- WEB-INF/templates/invoices.tpl | 2 +- dbinstall.php | 14 ++++++++++---- invoice_send.php | 2 +- invoice_view.php | 2 +- invoices.php | 2 +- mysql.sql | 4 ++-- report.php | 2 +- reports.php | 2 +- tofile.php | 2 +- topdf.php | 2 +- 13 files changed, 24 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 02b22cdf9..000f7cebe 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -189,7 +189,7 @@ static function createPredefinedRoles($group_id, $lang) $mdb2 = getConnection(); - $rights_client = 'view_own_reports,view_own_timesheets,view_own_charts,view_own_invoices,manage_own_settings'; + $rights_client = 'view_client_reports,view_client_timesheets,view_client_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d8ce9770c..6ed36219d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.37.4733 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4734 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_add.php b/timesheet_add.php index fa32ca7ff..fa8ec4f89 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -64,7 +64,7 @@ $user_id = $bean->getDetachedAttribute('timesheet_user_id'); if (!ttTimesheetHelper::getTimesheetByName($cl_name, $user_id)) { if (ttTimesheetHelper::insert(array('user_id' => $user_id, - // 'client_id' => ? + 'client_id' => $bean->getAttribute('client'), 'name' => $cl_name, 'comment' => $cl_comment))) { header('Location: timesheets.php'); From b33cf8ebaf54882a2238b660ba07936301077695 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 18 Feb 2019 14:19:48 +0000 Subject: [PATCH 0671/1848] More progress on timesheets. --- WEB-INF/lib/ttTimesheetHelper.class.php | 32 +++++++++++++++++++++++++ WEB-INF/lib/ttUser.class.php | 5 ---- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheets.tpl | 4 ++-- timesheets.php | 4 ++-- 35 files changed, 97 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index a8276b55a..f7cae6765 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -78,4 +78,36 @@ static function insert($fields) return $last_id; } + + // The getTimesheets obtains timesheets for user. + static function getTimesheets($user_id) + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // $addPaidStatus = $user->isPluginEnabled('ps'); + $result = array(); + + if ($user->isClient()) + $client_part = "and ts.client_id = $user->client_id"; + + $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name from tt_timesheets ts". + " left join tt_clients c on (c.id = ts.client_id)". + " where ts.status = 1 and ts.group_id = $group_id and ts.org_id = $org_id and ts.user_id = $user_id". + " $client_part order by ts.name"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + $dt = new DateAndTime(DB_DATEFORMAT); + while ($val = $res->fetchRow()) { + //if ($addPaidStatus) + // $val['paid'] = ttTimesheetHelper::isPaid($val['id']); + $result[] = $val; + } + } + return $result; + } } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 5309dd8ad..36f9163f1 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -886,9 +886,4 @@ function exists() { return false; } - - // getTimesheets obtains timesheets for user. - function getTimesheets() { - return null; // Not implemented. - } } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index f129c9b3b..2faa0a105 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -461,6 +461,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d722cb92a..b5a5cdc2d 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -471,6 +471,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 976d9f3fc..ba43617cb 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -434,6 +434,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 6ac1c0345..fc8f262d0 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -412,6 +412,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 5da77cb21..f65f93238 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -408,6 +408,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php 'form.timesheets.hint' => 'Use reports to add new timesheets.', +'form.timesheets.active_timesheets' => 'Active Timesheets', +'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 124bfed7b..3cb20b86a 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -474,6 +474,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 864fb91eb..c489a56a1 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -437,6 +437,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 501d9572a..8c3907cea 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -454,6 +454,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index e400a9418..647b8f583 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -439,6 +439,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 3f411e9fd..d6ee165ef 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -431,6 +431,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 60b312a02..1d048d2ba 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -421,6 +421,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 5cfe3f202..291425ef8 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -461,6 +461,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 46d0bd6c4..ea0d73630 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -464,6 +464,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 5215f7f6b..b5faa5a8c 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -434,6 +434,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 9c01727b0..5b4aad614 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -469,6 +469,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 8d5aa443a..74d3a8dd7 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -467,6 +467,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 1e7146f6a..e4b775047 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -408,6 +408,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 6a38cb2a6..b1c315e99 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -466,6 +466,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 40167912e..a41c703be 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -442,6 +442,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 61f06f35a..62676f99c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -437,6 +437,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 09aa8b52e..f305c28c3 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -445,6 +445,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index f8d711f35..1cbc40911 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -469,6 +469,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 6c172c338..02042912b 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -400,6 +400,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php 'form.timesheets.hint' => 'Используйте отчёты для добавления новых табелей.', +'form.timesheets.active_timesheets' => 'Активные табели', +'form.timesheets.inactive_timesheets' => 'Неактивные табели', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d79db8431..1ae854c2e 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -452,6 +452,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index d720907db..5e92e7164 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -443,6 +443,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index e5be1d816..c2b9033bb 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -440,6 +440,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Forma izveštaja. Pogledajte primer na https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 75a258ddd..bce576ae6 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -438,6 +438,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index b6b3aeb6a..4c8c2ad81 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -480,6 +480,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5eb65a7fe..1840f7b30 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -452,6 +452,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 68e505620..f78a36fd8 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -460,6 +460,8 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. // form.timesheets.hint' => 'Use reports to add new timesheets.', +// 'form.timesheets.active_timesheets' => 'Active Timesheets', +// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8e33a4874..a91fdab4a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {foreach $timesheets as $timesheet} - - + + {if $user->isPluginEnabled('ps')} diff --git a/timesheets.php b/timesheets.php index b2c64e636..4a4eb66fe 100644 --- a/timesheets.php +++ b/timesheets.php @@ -28,7 +28,7 @@ require_once('initialize.php'); import('form.Form'); -import('ttGroupHelper'); +import('ttTimesheetHelper'); // Access checks. if (!(ttAccessAllowed('view_own_timesheets') || @@ -46,7 +46,7 @@ } // End of access checks. -$timesheets = $user->getTimesheets(); +$timesheets = ttTimesheetHelper::getTimesheets($user->getUser()); $smarty->assign('timesheets', $timesheets); $smarty->assign('title', $i18n->get('title.timesheets')); From a64a8d017c37bec34585e0c345a0c139ac3b43a0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 18 Feb 2019 16:23:41 +0000 Subject: [PATCH 0672/1848] Implemented deleting a timesheet. --- WEB-INF/lib/ttTimesheetHelper.class.php | 85 ++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_delete.tpl | 18 ++++++ WEB-INF/templates/timesheets.tpl | 38 +++++++---- invoice_delete.php | 9 +-- timesheet_delete.php | 75 ++++++++++++++++++++++ timesheets.php | 15 ++++- 7 files changed, 219 insertions(+), 23 deletions(-) create mode 100644 WEB-INF/templates/timesheet_delete.tpl create mode 100644 timesheet_delete.php diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index f7cae6765..df654e074 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -79,8 +79,8 @@ static function insert($fields) return $last_id; } - // The getTimesheets obtains timesheets for user. - static function getTimesheets($user_id) + // The getActiveTimesheets obtains active timesheets for a user. + static function getActiveTimesheets($user_id) { global $user; $mdb2 = getConnection(); @@ -94,7 +94,7 @@ static function getTimesheets($user_id) if ($user->isClient()) $client_part = "and ts.client_id = $user->client_id"; - $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name from tt_timesheets ts". + $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name, ts.submit_status, ts.approval_status from tt_timesheets ts". " left join tt_clients c on (c.id = ts.client_id)". " where ts.status = 1 and ts.group_id = $group_id and ts.org_id = $org_id and ts.user_id = $user_id". " $client_part order by ts.name"; @@ -110,4 +110,83 @@ static function getTimesheets($user_id) } return $result; } + + // The getInactiveTimesheets obtains inactive timesheets for a user. + static function getInactiveTimesheets($user_id) + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // $addPaidStatus = $user->isPluginEnabled('ps'); + $result = array(); + + if ($user->isClient()) + $client_part = "and ts.client_id = $user->client_id"; + + $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name, ts.submit_status, ts.approval_status from tt_timesheets ts". + " left join tt_clients c on (c.id = ts.client_id)". + " where ts.status = 0 and ts.group_id = $group_id and ts.org_id = $org_id and ts.user_id = $user_id". + " $client_part order by ts.name"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + $dt = new DateAndTime(DB_DATEFORMAT); + while ($val = $res->fetchRow()) { + //if ($addPaidStatus) + // $val['paid'] = ttTimesheetHelper::isPaid($val['id']); + $result[] = $val; + } + } + return $result; + } + + // getTimesheet - obtains timesheet data from the database. + static function getTimesheet($timesheet_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + if ($user->isClient()) $client_part = "and client_id = $user->client_id"; + + $sql = "select * from tt_timesheets". + " where id = $timesheet_id and group_id = $group_id and org_id = $org_id $client_part and status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + if ($val = $res->fetchRow()) + return $val; + } + return false; + } + + // delete - deletes timesheet from the database. + static function delete($timesheet_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // Handle time records. + $sql = "update tt_log set timesheet_id = null". + " where timesheet_id = $timesheet_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // Handle expense items. + $sql = "update tt_expense_items set timesheet_id = null". + " where timesheet_id = $timesheet_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // Delete timesheet. + $sql = "update tt_timesheets set status = null". + " where id = $timesheet_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a91fdab4a..5e19420d1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.37.4734 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4735 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index 626065846..796f27207 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -19,8 +19,8 @@
{$invoice.name|escape}{$invoice.client_name|escape}{$timesheet.name|escape}{$timesheet.client_name|escape} {$invoice.date}{if $invoice.paid}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
-
 Anuko Time Tracker 1.18.37.4735 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4736 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_delete.tpl b/WEB-INF/templates/timesheet_delete.tpl new file mode 100644 index 000000000..87928052e --- /dev/null +++ b/WEB-INF/templates/timesheet_delete.tpl @@ -0,0 +1,18 @@ +{$forms.timesheetDeleteForm.open} + + + + +
+ + + + + + + + + +
{$timesheet_to_delete|escape}
 
{$forms.timesheetDeleteForm.btn_delete.control}  {$forms.timesheetDeleteForm.btn_cancel.control}
+
+{$forms.timesheetDeleteForm.close} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index 796f27207..0ba8fd7cf 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -5,29 +5,46 @@
-{if $user->can('manage_invoices') || $user->can('view_own_invoices')} + + {if $inactive_timesheets} + + {/if} - {if $user->isPluginEnabled('cl')} + {if $show_client} {/if} - - + {if $show_submit_status} + + {/if} + {if $show_approval_status} + + {/if} + + - {foreach $timesheets as $timesheet} + {foreach $active_timesheets as $timesheet} + {if $show_client} - - {if $user->isPluginEnabled('ps')} - {/if} - + {if $show_submit_status} + + {/if} + {if $show_approval_status} + + {/if} + + + + {if !$user->isClient()} - + + {/if} {/foreach} @@ -38,7 +55,6 @@
{$i18n.form.timesheets.hint}
 
{$i18n.form.timesheets.active_timesheets}
{$i18n.label.thing_name}{$i18n.label.client}{$i18n.label.submitted}{$i18n.label.approved}{$i18n.label.submitted}{$i18n.label.approved}{$i18n.label.view}{$i18n.label.edit}{$i18n.label.delete}
{$timesheet.name|escape}{$timesheet.client_name|escape}{$invoice.date}{if $invoice.paid}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}

{/if} -{/if}
diff --git a/invoice_delete.php b/invoice_delete.php index ffdcf2c17..89ea372a3 100644 --- a/invoice_delete.php +++ b/invoice_delete.php @@ -60,12 +60,9 @@ if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if (ttInvoiceHelper::getInvoice($cl_invoice_id)) { - if (ttInvoiceHelper::delete($cl_invoice_id, $request->getParameter('delete_invoice_entries'))) { - header('Location: invoices.php'); - exit(); - } else - $err->add($i18n->get('error.db')); + if (ttInvoiceHelper::delete($cl_invoice_id, $request->getParameter('delete_invoice_entries'))) { + header('Location: invoices.php'); + exit(); } else $err->add($i18n->get('error.db')); } elseif ($request->getParameter('btn_cancel')) { diff --git a/timesheet_delete.php b/timesheet_delete.php new file mode 100644 index 000000000..e4bf453c5 --- /dev/null +++ b/timesheet_delete.php @@ -0,0 +1,75 @@ +isPluginEnabled('ts')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_timesheet_id = (int)$request->getParameter('id'); +$timesheet = ttTimesheetHelper::getTimesheet($cl_timesheet_id); +if (!$timesheet) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$timesheet_to_delete = $timesheet['name']; + +$form = new Form('timesheetDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_timesheet_id)); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_delete')) { + if (ttTimesheetHelper::delete($cl_timesheet_id)) { + header('Location: timesheets.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } elseif ($request->getParameter('btn_cancel')) { + header('Location: timesheets.php'); + exit(); + } +} // isPost + +$smarty->assign('timesheet_to_delete', $timesheet_to_delete); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.invoiceDeleteForm.btn_cancel.focus()"'); +$smarty->assign('title', $i18n->get('title.delete_timesheet')); +$smarty->assign('content_page_name', 'timesheet_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/timesheets.php b/timesheets.php index 4a4eb66fe..191f7492b 100644 --- a/timesheets.php +++ b/timesheets.php @@ -46,9 +46,20 @@ } // End of access checks. -$timesheets = ttTimesheetHelper::getTimesheets($user->getUser()); +// TODO: determine user properly, using a dropdown. +$user_id = $user->getUser(); + +// TODO: fix this for client access. +$active_timesheets = ttTimesheetHelper::getActiveTimesheets($user_id); +$inactive_timesheets = ttTimesheetHelper::getInactiveTimesheets($user_id); +$show_client = $user->isPluginEnabled('cl') && !$user->isClient(); + +$smarty->assign('active_timesheets', $active_timesheets); +$smarty->assign('inactive_timesheets', $inactive_timesheets); +$smarty->assign('show_client', $show_client); +$smarty->assign('show_submit_status', !$user->isClient()); +$smarty->assign('show_approval_status', !$user->isClient()); -$smarty->assign('timesheets', $timesheets); $smarty->assign('title', $i18n->get('title.timesheets')); $smarty->assign('content_page_name', 'timesheets.tpl'); $smarty->display('index.tpl'); From 5d4953bb5ec09e6e79a114c71f53f410c6064f2e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 18 Feb 2019 17:04:48 +0000 Subject: [PATCH 0673/1848] Work in progress on timesheet edit. --- WEB-INF/templates/timesheet_edit.tpl | 33 +++++++++ project_edit.php | 2 +- timesheet_edit.php | 103 +++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/templates/timesheet_edit.tpl create mode 100644 timesheet_edit.php diff --git a/WEB-INF/templates/timesheet_edit.tpl b/WEB-INF/templates/timesheet_edit.tpl new file mode 100644 index 000000000..500bb55b4 --- /dev/null +++ b/WEB-INF/templates/timesheet_edit.tpl @@ -0,0 +1,33 @@ +{$forms.timesheetForm.open} + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.thing_name} (*):{$forms.timesheetForm.timesheet_name.control}
{$i18n.label.comment}:{$forms.timesheetForm.comment.control}
{$i18n.label.status}:{$forms.timesheetForm.status.control}
{$i18n.label.required_fields}
 
{$forms.timesheetForm.btn_save.control}
+
+{$forms.timesheetForm.close} diff --git a/project_edit.php b/project_edit.php index 1402eb112..a2b27925e 100644 --- a/project_edit.php +++ b/project_edit.php @@ -128,7 +128,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectForm.name.focus()"'); +$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); $smarty->assign('show_users', count($users) > 0); $smarty->assign('show_tasks', $show_tasks); $smarty->assign('title', $i18n->get('title.edit_project')); diff --git a/timesheet_edit.php b/timesheet_edit.php new file mode 100644 index 000000000..844615466 --- /dev/null +++ b/timesheet_edit.php @@ -0,0 +1,103 @@ +isPluginEnabled('ts')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_timesheet_id = (int)$request->getParameter('id'); +$timesheet = ttTimesheetHelper::getTimesheet($cl_timesheet_id); +if (!$timesheet) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('timesheet_name')); + $cl_comment = trim($request->getParameter('comment')); + $cl_status = $request->getParameter('status'); +} else { + $cl_name = $timesheet['name']; + $cl_comment = $timesheet['submitter_comment']; + $cl_status = $timesheet['status']; +} + +$form = new Form('timesheetForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_timesheet_id)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'timesheet_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'comment','style'=>'width: 250px; height: 40px;','value'=>$cl_comment)); +$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); + + if ($err->no()) { + /* + // TODO: coding ongoing down from here. + if ($request->getParameter('btn_save')) { + $existing_project = ttProjectHelper::getProjectByName($cl_name); + if (!$existing_project || ($cl_project_id == $existing_project['id'])) { + // Update project information. + if (ttProjectHelper::update(array( + 'id' => $cl_project_id, + 'name' => $cl_name, + 'description' => $cl_description, + 'status' => $cl_status, + 'users' => $cl_users, + 'tasks' => $cl_tasks))) { + header('Location: projects.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } else + $err->add($i18n->get('error.object_exists')); + }*/ + } +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.timesheetForm.timesheet_name.focus()"'); +$smarty->assign('show_users', count($users) > 0); +$smarty->assign('show_tasks', $show_tasks); +$smarty->assign('title', $i18n->get('title.edit_timesheet')); +$smarty->assign('content_page_name', 'timesheet_edit.tpl'); +$smarty->display('index.tpl'); From fc8a4455218bc71e17697f33c111b9dbc55f8047 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 18 Feb 2019 19:56:29 +0000 Subject: [PATCH 0674/1848] Added rights to view, manage, and approve all timesheets. --- WEB-INF/lib/ttTimesheetHelper.class.php | 20 ++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 12 ++++++++---- mysql.sql | 4 ++-- timesheet_edit.php | 20 ++++++++------------ 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index df654e074..64c73741c 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -189,4 +189,24 @@ static function delete($timesheet_id) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // update function - updates the timesheet in database. + static function update($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $timesheet_id = $fields['id']; // Timesheet we are updating. + $name = $fields['name']; // Timesheet name. + $submitter_comment = $fields['submitter_comment']; + $status = $fields['status']; // Project status. + + $sql = "update tt_timesheets set name = ".$mdb2->quote($name).", submitter_comment = ".$mdb2->quote($submitter_comment). + ", status = ".$mdb2->quote($status). + " where id = $timesheet_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5e19420d1..8a1626961 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.37.4736 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4737 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 69a09ec59..994509636 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11837"]) { + if ($_POST["convert11797to11839"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1073,6 +1073,10 @@ function ttExecute($sql) { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'view_reports,view_charts', 'view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts') where rank = 12 or rank = 68 or rank = 324"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'swap_roles,approve_timesheets', 'swap_roles') where rank = 12 or rank = 68 or rank = 324"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.38', modified = now() where param_name = 'version_db' and param_value = '1.18.37'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group' where rank = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = replace(rights, 'view_all_reports', 'view_all_reports,view_all_timesheets,manage_all_timesheets') where rank = 68 or rank = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = replace(rights, 'export_data,manage_subgroups', 'export_data,approve_all_timesheets,manage_subgroups') where rank = 324"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.39', modified = now() where param_name = 'version_db' and param_value = '1.18.38'"); } if ($_POST["cleanup"]) { @@ -1121,7 +1125,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.37) + Create database structure (v1.18.39)
(applies only to new installations, do not execute when updating)
@@ -1166,8 +1170,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.37)Update database structure (v1.17.97 to v1.18.39)
diff --git a/mysql.sql b/mysql.sql index 1ff8a7daa..bd8a67e7d 100644 --- a/mysql.sql +++ b/mysql.sql @@ -75,7 +75,7 @@ create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group'); # @@ -518,4 +518,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.38', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.39', now()); # TODO: change when structure changes. diff --git a/timesheet_edit.php b/timesheet_edit.php index 844615466..e98d824f3 100644 --- a/timesheet_edit.php +++ b/timesheet_edit.php @@ -71,26 +71,22 @@ if (!ttValidString($cl_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); if ($err->no()) { - /* - // TODO: coding ongoing down from here. if ($request->getParameter('btn_save')) { - $existing_project = ttProjectHelper::getProjectByName($cl_name); - if (!$existing_project || ($cl_project_id == $existing_project['id'])) { + $existing_timesheet = ttTimesheetHelper::getTimesheetByName($cl_name); + if (!$existing_timesheet || ($cl_timesheet_id == $existing_timesheet['id'])) { // Update project information. - if (ttProjectHelper::update(array( - 'id' => $cl_project_id, + if (ttTimesheetHelper::update(array( + 'id' => $cl_timesheet_id, 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'users' => $cl_users, - 'tasks' => $cl_tasks))) { - header('Location: projects.php'); + 'submitter_comment' => $cl_comment, + 'status' => $cl_status))) { + header('Location: timesheets.php'); exit(); } else $err->add($i18n->get('error.db')); } else $err->add($i18n->get('error.object_exists')); - }*/ + } } } // isPost From f490a9f5e080c426f54502d1004f8ab444d26469 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 18 Feb 2019 21:38:27 +0000 Subject: [PATCH 0675/1848] A bit more progress with timesheets. --- WEB-INF/templates/timesheets.tpl | 8 ++++-- timesheet_edit.php | 2 +- timesheets.php | 46 +++++++++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index 0ba8fd7cf..8c3acc95e 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -2,12 +2,15 @@ function chLocation(newLocation) { document.location = newLocation; } +{$forms.timesheetsForm.open} + +{if $user_dropdown} + +{/if} + {/if} + + {if !$user->isClient()} + + + {/if} + + {/foreach} +
{$i18n.form.timesheets.hint}
{$i18n.label.user}: {$forms.timesheetsForm.user.control}
- - {if $inactive_timesheets} {/if} @@ -58,3 +61,4 @@
{$i18n.form.timesheets.hint}
 
{$i18n.form.timesheets.active_timesheets}
+{$forms.timesheetsForm.close} diff --git a/timesheet_edit.php b/timesheet_edit.php index e98d824f3..50d2a44d4 100644 --- a/timesheet_edit.php +++ b/timesheet_edit.php @@ -72,7 +72,7 @@ if ($err->no()) { if ($request->getParameter('btn_save')) { - $existing_timesheet = ttTimesheetHelper::getTimesheetByName($cl_name); + $existing_timesheet = ttTimesheetHelper::getTimesheetByName($cl_name, $timesheet['user_id']); if (!$existing_timesheet || ($cl_timesheet_id == $existing_timesheet['id'])) { // Update project information. if (ttTimesheetHelper::update(array( diff --git a/timesheets.php b/timesheets.php index 191f7492b..fcdd401bb 100644 --- a/timesheets.php +++ b/timesheets.php @@ -39,15 +39,53 @@ header('Location: access_denied.php'); exit(); } - if (!$user->isPluginEnabled('ts')) { header('Location: feature_disabled.php'); exit(); } +if ($request->isPost()) { + $userChanged = $request->getParameter('user_changed'); + if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + header('Location: access_denied.php'); // Group changed, but no rght or wrong user id. + exit(); + } +} // End of access checks. -// TODO: determine user properly, using a dropdown. -$user_id = $user->getUser(); +// Determine user for whom we display this page. +if ($request->isPost() && $userChanged) { + $user_id = $request->getParameter('user'); +} else { + $user_id = $user->getUser(); +} + +$group_id = $user->getGroup(); + +// Elements of timesheetsForm. +$form = new Form('timesheetsForm'); + +if ($user->can('view_timesheets') || $user->can('view_all_timesheets') || $user->can('manage_timesheets') || $user->can('manage_all_timesheets')) { + $rank = $user->getMaxRankForGroup($group_id); + if ($user->can('track_own_time')) + $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); + else + $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank); + $user_list = $user->getUsers($options); + if (count($user_list) >= 1) { + $form->addInput(array('type'=>'combobox', + 'onchange'=>'document.timesheetsForm.user_changed.value=1;document.timesheetsForm.submit();', + 'name'=>'user', + 'style'=>'width: 250px;', + 'value'=>$user_id, + 'data'=>$user_list, + 'datakeys'=>array('id','name'))); + $form->addInput(array('type'=>'hidden','name'=>'user_changed')); + $smarty->assign('user_dropdown', 1); + } +} + + + // TODO: fix this for client access. $active_timesheets = ttTimesheetHelper::getActiveTimesheets($user_id); @@ -59,7 +97,7 @@ $smarty->assign('show_client', $show_client); $smarty->assign('show_submit_status', !$user->isClient()); $smarty->assign('show_approval_status', !$user->isClient()); - +$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.timesheets')); $smarty->assign('content_page_name', 'timesheets.tpl'); $smarty->display('index.tpl'); From 46f39c48caaac4dcc65266c3ca12acfd5706360d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 19 Feb 2019 12:51:00 +0000 Subject: [PATCH 0676/1848] Added inactive timesheets to timesheets.php display. --- WEB-INF/lib/ttTimesheetHelper.class.php | 2 +- WEB-INF/templates/timesheets.tpl | 46 +++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 64c73741c..1d43f1527 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -154,7 +154,7 @@ static function getTimesheet($timesheet_id) { if ($user->isClient()) $client_part = "and client_id = $user->client_id"; $sql = "select * from tt_timesheets". - " where id = $timesheet_id and group_id = $group_id and org_id = $org_id $client_part and status = 1"; + " where id = $timesheet_id and group_id = $group_id and org_id = $org_id $client_part and status is not null"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index 8c3acc95e..6a5269b58 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -40,10 +40,52 @@ {/if} {if $show_approval_status}
{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}{$i18n.label.edit}{$i18n.label.delete}
+ {if !$user->isClient()} + + +

{/if} +{if $inactive_timesheets} + - + + + + {if $show_client} + + {/if} + {if $show_submit_status} + + {/if} + {if $show_approval_status} + + {/if} + + + + + {foreach $inactive_timesheets as $timesheet} + + + {if $show_client} + + {/if} + {if $show_submit_status} + + {/if} + {if $show_approval_status} + + {/if} {if !$user->isClient()} @@ -52,12 +94,12 @@ {/foreach}
{$i18n.form.timesheets.inactive_timesheets}
{$i18n.label.thing_name}{$i18n.label.client}{$i18n.label.submitted}{$i18n.label.approved}{$i18n.label.view}{$i18n.label.edit}{$i18n.label.delete}
{$timesheet.name|escape}{$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}{$i18n.label.edit}
- {if !$user->isClient()}

{/if} +{/if}
From 351514c0823db572768c8f4d7f9dbb4fad81447c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 19 Feb 2019 13:12:17 +0000 Subject: [PATCH 0677/1848] Moved Delete to timesheet_edit.php to have room for paid status column. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_edit.tpl | 3 ++- WEB-INF/templates/timesheets.tpl | 4 ---- timesheet_edit.php | 12 +++++++++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8a1626961..d8ce9770c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + +
 Anuko Time Tracker 1.18.37.4737 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4738 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_edit.tpl b/WEB-INF/templates/timesheet_edit.tpl index 500bb55b4..5848c5710 100644 --- a/WEB-INF/templates/timesheet_edit.tpl +++ b/WEB-INF/templates/timesheet_edit.tpl @@ -24,7 +24,8 @@  
{$forms.timesheetForm.btn_save.control}{$forms.timesheetForm.btn_save.control} {$forms.timesheetForm.btn_delete.control}
{$i18n.label.view} {$i18n.label.edit}{$i18n.label.delete}
{$i18n.label.view}{$i18n.label.edit}{$i18n.label.delete}
{$i18n.label.view} {$i18n.label.edit}{$i18n.label.delete}
{$i18n.label.view}{$i18n.label.edit}{$i18n.label.delete}
-
 Anuko Time Tracker 1.18.37.4738 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4739 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index b5f122dbe..aab851bf2 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -112,14 +112,14 @@ {if $user->exists() && $user->isPluginEnabled('ex') && ($user->can('track_own_expenses') || $user->can('track_expenses'))} · {$i18n.menu.expenses} {/if} - {if $user->exists() && ($user->can('view_own_reports') || $user->can('view_reports'))} + {if $user->exists() && ($user->can('view_own_reports') || $user->can('view_reports') || $user->can('view_all_reports') || $user->can('view_client_reports'))} · {$i18n.menu.reports} {/if} {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('manage_own_timesheets') || $user->can('view_timesheets') || $user->can('manage_timesheets') || $user->can('approve_timesheets'))} · {$i18n.menu.timesheets} {/if} - {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('view_own_invoices') || $user->can('manage_invoices'))} + {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->can('view_client_invoices'))} · {$i18n.title.invoices} {/if} {if ($user->exists() && $user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts'))) && diff --git a/WEB-INF/templates/invoices.tpl b/WEB-INF/templates/invoices.tpl index b966f9e24..86e7e5255 100644 --- a/WEB-INF/templates/invoices.tpl +++ b/WEB-INF/templates/invoices.tpl @@ -5,7 +5,7 @@ - - + +
-{if $user->can('manage_invoices') || $user->can('view_own_invoices')} +{if $user->can('manage_invoices') || $user->can('view_client_invoices')} diff --git a/dbinstall.php b/dbinstall.php index 994509636..e40d4be67 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11839"]) { + if ($_POST["convert11797to11840"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1077,6 +1077,12 @@ function ttExecute($sql) { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = replace(rights, 'view_all_reports', 'view_all_reports,view_all_timesheets,manage_all_timesheets') where rank = 68 or rank = 324"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = replace(rights, 'export_data,manage_subgroups', 'export_data,approve_all_timesheets,manage_subgroups') where rank = 324"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.39', modified = now() where param_name = 'version_db' and param_value = '1.18.38'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group' where rank = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_reports', 'view_client_reports') where rank = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_charts,', '') where rank = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_timesheets', 'view_client_timesheets') where rank = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_invoices', 'view_client_invoices') where rank = 16"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.40', modified = now() where param_name = 'version_db' and param_value = '1.18.39'"); } if ($_POST["cleanup"]) { @@ -1125,7 +1131,7 @@ function ttExecute($sql) {

DB Install

{$i18n.label.invoice}
-
Create database structure (v1.18.39) + Create database structure (v1.18.40)
(applies only to new installations, do not execute when updating)
@@ -1170,8 +1176,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.39)Update database structure (v1.17.97 to v1.18.40)
diff --git a/invoice_send.php b/invoice_send.php index c86cebb53..e94e8050f 100644 --- a/invoice_send.php +++ b/invoice_send.php @@ -32,7 +32,7 @@ import('ttUserConfig'); // Access checks. -if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices'))) { +if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_client_invoices'))) { header('Location: access_denied.php'); exit(); } diff --git a/invoice_view.php b/invoice_view.php index 772500ef5..64831798b 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -33,7 +33,7 @@ import('form.Form'); // Access checks. -if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices'))) { +if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_client_invoices'))) { header('Location: access_denied.php'); exit(); } diff --git a/invoices.php b/invoices.php index ba1cad462..de51b5366 100644 --- a/invoices.php +++ b/invoices.php @@ -31,7 +31,7 @@ import('ttGroupHelper'); // Access checks. -if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_own_invoices'))) { +if (!(ttAccessAllowed('manage_invoices') || ttAccessAllowed('view_client_invoices'))) { header('Location: access_denied.php'); exit(); } diff --git a/mysql.sql b/mysql.sql index bd8a67e7d..0218cf750 100644 --- a/mysql.sql +++ b/mysql.sql @@ -75,7 +75,7 @@ create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group'); # @@ -518,4 +518,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.39', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.40', now()); # TODO: change when structure changes. diff --git a/report.php b/report.php index 65d98e4e6..93720cb27 100644 --- a/report.php +++ b/report.php @@ -33,7 +33,7 @@ import('ttGroupHelper'); // Access check. -if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports'))) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports') || ttAccessAllowed('view_client_reports'))) { header('Location: access_denied.php'); exit(); } diff --git a/reports.php b/reports.php index 892b117ea..05d7e5f26 100644 --- a/reports.php +++ b/reports.php @@ -38,7 +38,7 @@ import('ttReportHelper'); // Access check. -if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports'))) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports') || ttAccessAllowed('view_client_reports'))) { header('Location: access_denied.php'); exit(); } diff --git a/tofile.php b/tofile.php index 3934471de..3ddce979c 100644 --- a/tofile.php +++ b/tofile.php @@ -32,7 +32,7 @@ import('ttReportHelper'); // Access checks. -if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports') || ttAccessAllowed('view_client_reports'))) { header('Location: access_denied.php'); exit(); } diff --git a/topdf.php b/topdf.php index fd3016e55..181dec692 100644 --- a/topdf.php +++ b/topdf.php @@ -36,7 +36,7 @@ import('ttReportHelper'); // Access checks. -if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports'))) { +if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports') || ttAccessAllowed('view_client_reports'))) { header('Location: access_denied.php'); exit(); } From e6c2803587988e0d14c78b739dda47bbcf8670a2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 19 Feb 2019 15:56:44 +0000 Subject: [PATCH 0679/1848] Fixes to translations. --- WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/cs.lang.php | 2 +- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 4 +++- WEB-INF/resources/en.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 4 +++- WEB-INF/resources/fa.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 4 +++- WEB-INF/resources/he.lang.php | 2 +- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 4 +++- WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 +- WEB-INF/resources/sv.lang.php | 2 +- WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- WEB-INF/resources/zh-tw.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 39 insertions(+), 31 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 2faa0a105..6dd031c23 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -597,7 +597,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index b5a5cdc2d..771a0f297 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -611,7 +611,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index ba43617cb..702958d41 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -564,7 +564,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index fc8f262d0..257ab7e91 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -531,7 +531,9 @@ 'role.user.description' => 'Ein normaler Benutzer ohne Administrationsrechte.', 'role.client.label' => 'Kunde', 'role.client.low_case_label' => 'Kunde', -'role.client.description' => 'Ein Kunde kann zu ihm gehörende Berichte, Diagramme und Rechnungen ansehen.', +// TODO: translate the following. +// 'role.client.description' => 'A client can view its own data.', +'role.client.description' => 'Ein Kunde kann zu ihm gehörende Berichte und Rechnungen ansehen.', 'role.supervisor.label' => 'Dienstvorgesetzter', 'role.supervisor.low_case_label' => 'Dienstvorgesetzter', 'role.supervisor.description' => 'Eine Person mit ein paar Administrationsrechten.', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index f65f93238..7621a83d5 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -526,7 +526,7 @@ 'role.user.description' => 'A regular member without management rights.', 'role.client.label' => 'Client', 'role.client.low_case_label' => 'client', -'role.client.description' => 'A client can view its own reports, charts, and invoices.', +'role.client.description' => 'A client can view its own data.', 'role.supervisor.label' => 'Supervisor', 'role.supervisor.low_case_label' => 'supervisor', 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 3cb20b86a..19a8ed515 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -612,7 +612,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index c489a56a1..170c447a8 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -559,7 +559,9 @@ // 'role.user.description' => 'A regular member without management rights.', 'role.client.label' => 'Klient', 'role.client.low_case_label' => 'klient', -'role.client.description' => 'Kliendil on lubatud vaadata oma raporteid, diagramme ja arveid.', +// TODO: translate the following. +// 'role.client.description' => 'A client can view its own data.', +'role.client.description' => 'Kliendil on lubatud vaadata oma raporteid ja arveid.', 'role.supervisor.label' => 'Ülevaataja', 'role.supervisor.low_case_label' => 'ülevaataja', 'role.supervisor.description' => 'Mõningate lisaõigustega kasutaja.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 8c3907cea..783a1b5a3 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -587,7 +587,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 647b8f583..175c993e4 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -570,7 +570,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index d6ee165ef..9d7a7c7e4 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -560,7 +560,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 1d048d2ba..9e22079e2 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -544,7 +544,9 @@ 'role.user.description' => 'Μέλος χωρίς δικαιώματα διαχείρισης.', 'role.client.label' => 'Πελάτης', 'role.client.low_case_label' => 'πελάτης', -'role.client.description' => 'Ο πελάτης μπορεί να δει τις δικές του αναφορές, διαγράμματα και τιμολόγια.', +// TODO: translate the following. +// 'role.client.description' => 'A client can view its own data.', +'role.client.description' => 'Ο πελάτης μπορεί να δει τις δικές του αναφορές και τιμολόγια.', 'role.supervisor.label' => 'Επόπτης', 'role.supervisor.low_case_label' => 'επόπτης', 'role.supervisor.description' => 'Άτομο με μικρό σύνολο δικαιωμάτων διαχείρισης.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 291425ef8..3418d106d 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -593,7 +593,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index ea0d73630..9157dd68b 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -601,7 +601,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index b5faa5a8c..51768b0d3 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -560,7 +560,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 5b4aad614..e19c4a4ba 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -604,7 +604,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 74d3a8dd7..3999a097b 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -602,7 +602,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index e4b775047..58fdd7205 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -526,7 +526,9 @@ 'role.user.description' => 'Een gebruiker zonder beheer rechten.', 'role.client.label' => 'Klant', 'role.client.low_case_label' => 'klant', -'role.client.description' => 'Een klant kan zijn eigen rapporten, grafieken en facturen inzien.', +// TODO: translate the following. +// 'role.client.description' => 'A client can view its own data.', +'role.client.description' => 'Een klant kan zijn eigen rapporten en facturen inzien.', 'role.supervisor.label' => 'Supervisor', 'role.supervisor.low_case_label' => 'supervisor', 'role.supervisor.description' => 'Een persoon met beperkte beheer rechten.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index b1c315e99..1a88ce308 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -602,7 +602,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index a41c703be..8af61cf8b 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -573,7 +573,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 62676f99c..018c7717c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -568,7 +568,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index f305c28c3..d8f1611c4 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -583,7 +583,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 1cbc40911..47ae568c5 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -606,7 +606,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 02042912b..97cab56c5 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -518,7 +518,7 @@ 'role.user.description' => 'Обычный член группы, не имеющий прав управления.', 'role.client.label' => 'Клиент', 'role.client.low_case_label' => 'клиент', -'role.client.description' => 'Клиент может смотреть свои отчёты, диаграммы и счета.', +'role.client.description' => 'Клиент может смотреть свои данные.', 'role.supervisor.label' => 'Руководитель', 'role.supervisor.low_case_label' => 'руководитель', 'role.supervisor.description' => 'Член группы, имеющий небольшие полномочия по управлению.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 1ae854c2e..fa0df1d5d 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -584,7 +584,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 5e92e7164..620a8b840 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -580,7 +580,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index c2b9033bb..8163a8087 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -571,7 +571,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index bce576ae6..8ddf01adc 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -568,7 +568,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 4c8c2ad81..4f82410f6 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -618,7 +618,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 1840f7b30..41e4acdfc 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -587,7 +587,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index f78a36fd8..5e582399c 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -595,7 +595,7 @@ // 'role.user.description' => 'A regular member without management rights.', // 'role.client.label' => 'Client', // 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own reports, charts, and invoices.', +// 'role.client.description' => 'A client can view its own data.', // 'role.supervisor.label' => 'Supervisor', // 'role.supervisor.low_case_label' => 'supervisor', // 'role.supervisor.description' => 'A person with a small set of management rights.', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6ed36219d..175c87c7b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4739 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4740 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 069fad4865cadc18340589bc2d2d681d2e0616a6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 19 Feb 2019 16:12:47 +0000 Subject: [PATCH 0680/1848] A bit more timesheet work. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 3 +-- timesheets.php | 6 +----- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 175c87c7b..252e32273 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4740 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4741 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index aab851bf2..0b9e290a1 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -115,8 +115,7 @@ {if $user->exists() && ($user->can('view_own_reports') || $user->can('view_reports') || $user->can('view_all_reports') || $user->can('view_client_reports'))} · {$i18n.menu.reports} {/if} - {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('manage_own_timesheets') || - $user->can('view_timesheets') || $user->can('manage_timesheets') || $user->can('approve_timesheets'))} + {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets') || $user->can('view_client_timesheets'))} · {$i18n.menu.timesheets} {/if} {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->can('view_client_invoices'))} diff --git a/timesheets.php b/timesheets.php index fcdd401bb..9dc0d2c89 100644 --- a/timesheets.php +++ b/timesheets.php @@ -31,11 +31,7 @@ import('ttTimesheetHelper'); // Access checks. -if (!(ttAccessAllowed('view_own_timesheets') || - ttAccessAllowed('manage_own_timesheets') || - ttAccessAllowed('view_timesheets') || - ttAccessAllowed('manage_timesheets') || - ttAccessAllowed('approve_timesheets'))) { +if (!(ttAccessAllowed('view_own_timesheets') || ttAccessAllowed('view_timesheets') || ttAccessAllowed('view_all_timesheets') || ttAccessAllowed('view_client_timesheets'))) { header('Location: access_denied.php'); exit(); } From 3ad837214ca361fdaac5363d9e702d3d40d04b17 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 20 Feb 2019 15:37:47 +0000 Subject: [PATCH 0681/1848] Fixed user edit to hide projects for client roles. --- WEB-INF/lib/ttTimesheetHelper.class.php | 24 +++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheets.tpl | 2 ++ WEB-INF/templates/user_edit.tpl | 23 +++++++++++++++++----- timesheets.php | 26 +++++++++++++++++++------ user_edit.php | 2 +- 6 files changed, 66 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 1d43f1527..3e44c8c34 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -209,4 +209,28 @@ static function update($fields) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // isUserValid function is used during access checks and determines whether user id, passed in post, is valid + // in current context. + static function isUserValid($user_id) { + // We have to cover several situations. + // + // 1) User is a client. + // 2) User with view_all_timesheets rights. + // 3) User with view_timesheets rights. + + global $user; + + // Step 1. + // A client must have view_client_timesheets and + // aser must be assigned to one of client projects. + if ($user->isClient()) { + if (!$user->can('view_client_timesheets')) + return false; + $valid_users = ttGroupHelper::getUsersForClient($user->client_id); + $v = 2; + } + + return true; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 252e32273..8b2787ff2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- -{if defined('CUSTOM_TRANSLATION_DEBUG')} -{/if}
 Anuko Time Tracker 1.18.37.4741 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4742 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index 45a67645d..dc5c81557 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -4,7 +4,9 @@ {$forms.timesheetsForm.open} +{if $show_hint} +{/if} {if $user_dropdown} {/if} diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index 32947545d..f9ec23347 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -51,20 +51,31 @@ function setRate(element) { } } -// handleClientControl - controls visibility of the client dropdown depending on the selected user role. -// We need to show it only when the "Client" user role is selected. +// handleClientControl - controls visibility of the client dropdown depending on the selected user role, +// also hides and unselects projects when "Client" user role is selected. function handleClientControl() { var selectedRoleId = document.getElementById("role").value; var clientControl = document.getElementById("client"); + var projectsControl = document.getElementById("projects_control"); + var len = roles.length; for (var i = 0; i < len; i++) { if (selectedRoleId == roles[i][0]) { var isClient = roles[i][1]; - if (isClient == 1) + if (isClient == 1) { clientControl.style.visibility = "visible"; - else { - clientControl.value = ''; + projectsControl.style.display = "none"; + + // Uncheck all project checkboxes. + var checkboxes = document.getElementsByName("projects[]"); + var j; + for (j = 0; j < checkboxes.length; j++) { + checkboxes[j].checked = false; + } + } else { + clientControl.value = ""; clientControl.style.visibility = "hidden"; + projectsControl.style.display = ""; } break; } @@ -125,10 +136,12 @@ function handleClientControl() { {/if} {if $show_projects} + + {/if} diff --git a/timesheets.php b/timesheets.php index 9dc0d2c89..82a830745 100644 --- a/timesheets.php +++ b/timesheets.php @@ -28,6 +28,7 @@ require_once('initialize.php'); import('form.Form'); +import('ttGroupHelper'); import('ttTimesheetHelper'); // Access checks. @@ -39,22 +40,34 @@ header('Location: feature_disabled.php'); exit(); } +if ($user->isClient()) { + $users_for_client = ttGroupHelper::getUsersForClient($user->client_id); + if (count($users_for_client) == 0) { + header('Location: access_denied.php'); // There are no users for client. + exit(); + } +} if ($request->isPost()) { $userChanged = $request->getParameter('user_changed'); - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { - header('Location: access_denied.php'); // Group changed, but no rght or wrong user id. + if ($userChanged && !(ttTimesheetHelper::isUserValid($request->getParameter('user')))) { + header('Location: access_denied.php'); // Wrong user id. exit(); } } // End of access checks. // Determine user for whom we display this page. +$notClient = !$user->isClient(); if ($request->isPost() && $userChanged) { $user_id = $request->getParameter('user'); } else { - $user_id = $user->getUser(); + if ($notClient) + $user_id = $user->getUser(); + else + $user_id = $users_for_client[0]['id']; // First found user for a client. } + $group_id = $user->getGroup(); // Elements of timesheetsForm. @@ -86,13 +99,14 @@ // TODO: fix this for client access. $active_timesheets = ttTimesheetHelper::getActiveTimesheets($user_id); $inactive_timesheets = ttTimesheetHelper::getInactiveTimesheets($user_id); -$show_client = $user->isPluginEnabled('cl') && !$user->isClient(); +$show_client = $user->isPluginEnabled('cl') && $notClient; $smarty->assign('active_timesheets', $active_timesheets); $smarty->assign('inactive_timesheets', $inactive_timesheets); $smarty->assign('show_client', $show_client); -$smarty->assign('show_submit_status', !$user->isClient()); -$smarty->assign('show_approval_status', !$user->isClient()); +$smarty->assign('show_hint', $notClient); +$smarty->assign('show_submit_status', $notClient); +$smarty->assign('show_approval_status', $notClient); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.timesheets')); $smarty->assign('content_page_name', 'timesheets.tpl'); diff --git a/user_edit.php b/user_edit.php index 582452d9a..cda9ab2d0 100644 --- a/user_edit.php +++ b/user_edit.php @@ -147,7 +147,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Create projects table. $table = new Table('projects'); $table->setIAScript('setRate'); -$table->setTableOptions(array('width'=>'100%','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); +$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); $table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); $table->setData($projects); $table->setKeyField('id'); From 768cd79f51628c223a55a8d8e85269bad4d8a105 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 20 Feb 2019 15:53:01 +0000 Subject: [PATCH 0682/1848] Fixed user add to hide projects for client role. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/user_add.tpl | 23 ++++++++++++++++++----- WEB-INF/templates/user_edit.tpl | 2 +- user_add.php | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8b2787ff2..5d4037a57 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.timesheets.hint}
{$i18n.label.user}: {$forms.timesheetsForm.user.control}
 
{$i18n.label.projects}: {$forms.userForm.projects.control}
{$i18n.label.required_fields}
- {/if} {if $show_projects} + + {/if} diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index f9ec23347..2bba1842d 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -135,8 +135,8 @@ function handleClientControl() { {/if} {if $show_projects} - + diff --git a/user_add.php b/user_add.php index cf233d5b5..5696d28fa 100644 --- a/user_add.php +++ b/user_add.php @@ -126,7 +126,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Create projects table. $table = new Table('projects'); $table->setIAScript('setDefaultRate'); -$table->setTableOptions(array('width'=>'100%','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); +$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); $table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); $table->setData($projects); $table->setKeyField('id'); From 2c7be66d72e7f745903e08f49f8d9ab12def1c2d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 20 Feb 2019 16:09:57 +0000 Subject: [PATCH 0683/1848] Fixed mobile user pages for client role. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/user_add.tpl | 23 ++++++++++++++++++----- WEB-INF/templates/mobile/user_edit.tpl | 23 ++++++++++++++++++----- mobile/user_add.php | 2 +- mobile/user_edit.php | 2 +- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5d4037a57..751fe2e23 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.37.4742 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4743 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/user_add.tpl b/WEB-INF/templates/user_add.tpl index 0741dc3e9..c6dbaa7bb 100644 --- a/WEB-INF/templates/user_add.tpl +++ b/WEB-INF/templates/user_add.tpl @@ -29,20 +29,31 @@ function setDefaultRate(element) { } } -// handleClientControl - controls visibility of the client dropdown depending on the selected user role. -// We need to show it only when the "Client" user role is selected. +// handleClientControl - controls visibility of the client dropdown depending on the selected user role, +// also hides and unselects projects when "Client" user role is selected. function handleClientControl() { var selectedRoleId = document.getElementById("role").value; var clientControl = document.getElementById("client"); + var projectsControl = document.getElementById("projects_control"); + var len = roles.length; for (var i = 0; i < len; i++) { if (selectedRoleId == roles[i][0]) { var isClient = roles[i][1]; - if (isClient == 1) + if (isClient == 1) { clientControl.style.visibility = "visible"; - else { - clientControl.value = ''; + projectsControl.style.display = "none"; + + // Uncheck all project checkboxes. + var checkboxes = document.getElementsByName("projects[]"); + var j; + for (j = 0; j < checkboxes.length; j++) { + checkboxes[j].checked = false; + } + } else { + clientControl.value = ""; clientControl.style.visibility = "hidden"; + projectsControl.style.display = ""; } break; } @@ -90,11 +101,13 @@ function handleClientControl() {
 
{$i18n.label.projects}: {$forms.userForm.projects.control}
{$i18n.label.required_fields}
 
 
{$i18n.label.projects}: {$forms.userForm.projects.control}
- {/if} {if $show_projects} + @@ -97,6 +109,7 @@ function handleClientControl() { + {/if} diff --git a/WEB-INF/templates/mobile/user_edit.tpl b/WEB-INF/templates/mobile/user_edit.tpl index 9929e7272..6bddbb99f 100644 --- a/WEB-INF/templates/mobile/user_edit.tpl +++ b/WEB-INF/templates/mobile/user_edit.tpl @@ -51,20 +51,31 @@ function setRate(element) { } } -// handleClientControl - controls visibility of the client dropdown depending on the selected user role. -// We need to show it only when the "Client" user role is selected. +// handleClientControl - controls visibility of the client dropdown depending on the selected user role, +// also hides and unselects projects when "Client" user role is selected. function handleClientControl() { var selectedRoleId = document.getElementById("role").value; var clientControl = document.getElementById("client"); + var projectsControl = document.getElementById("projects_control"); + var len = roles.length; for (var i = 0; i < len; i++) { if (selectedRoleId == roles[i][0]) { var isClient = roles[i][1]; - if (isClient == 1) + if (isClient == 1) { clientControl.style.visibility = "visible"; - else { - clientControl.value = ''; + projectsControl.style.display = "none"; + + // Uncheck all project checkboxes. + var checkboxes = document.getElementsByName("projects[]"); + var j; + for (j = 0; j < checkboxes.length; j++) { + checkboxes[j].checked = false; + } + } else { + clientControl.value = ""; clientControl.style.visibility = "hidden"; + projectsControl.style.display = ""; } break; } @@ -118,10 +129,12 @@ function handleClientControl() { {/if} {if $show_projects} + + {/if} diff --git a/mobile/user_add.php b/mobile/user_add.php index c821c7d4f..ed017de8a 100644 --- a/mobile/user_add.php +++ b/mobile/user_add.php @@ -125,7 +125,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Create projects table. $table = new Table('projects'); $table->setIAScript('setDefaultRate'); -$table->setTableOptions(array('width'=>'100%','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); +$table->setTableOptions(array('width'=>'250','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); $table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); $table->setData($projects); $table->setKeyField('id'); diff --git a/mobile/user_edit.php b/mobile/user_edit.php index 1e0845e1a..411586bda 100644 --- a/mobile/user_edit.php +++ b/mobile/user_edit.php @@ -145,7 +145,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Create projects table. $table = new Table('projects'); $table->setIAScript('setRate'); -$table->setTableOptions(array('width'=>'100%','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); +$table->setTableOptions(array('width'=>'250','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); $table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); $table->setData($projects); $table->setKeyField('id'); From a3ec528f0b31400a9cdda44211ae495a6512c648 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 20 Feb 2019 17:00:53 +0000 Subject: [PATCH 0684/1848] Some fixes to timesheets.php page. --- WEB-INF/templates/footer.tpl | 2 +- timesheets.php | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 751fe2e23..ae33f1578 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.37.4743 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4744 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/user_add.tpl b/WEB-INF/templates/mobile/user_add.tpl index d23dcf932..1bde81b18 100644 --- a/WEB-INF/templates/mobile/user_add.tpl +++ b/WEB-INF/templates/mobile/user_add.tpl @@ -29,20 +29,31 @@ function setDefaultRate(element) { } } -// handleClientControl - controls visibility of the client dropdown depending on the selected user role. -// We need to show it only when the "Client" user role is selected. +// handleClientControl - controls visibility of the client dropdown depending on the selected user role, +// also hides and unselects projects when "Client" user role is selected. function handleClientControl() { var selectedRoleId = document.getElementById("role").value; var clientControl = document.getElementById("client"); + var projectsControl = document.getElementById("projects_control"); + var len = roles.length; for (var i = 0; i < len; i++) { if (selectedRoleId == roles[i][0]) { var isClient = roles[i][1]; - if (isClient == 1) + if (isClient == 1) { clientControl.style.visibility = "visible"; - else { - clientControl.value = ''; + projectsControl.style.display = "none"; + + // Uncheck all project checkboxes. + var checkboxes = document.getElementsByName("projects[]"); + var j; + for (j = 0; j < checkboxes.length; j++) { + checkboxes[j].checked = false; + } + } else { + clientControl.value = ""; clientControl.style.visibility = "hidden"; + projectsControl.style.display = ""; } break; } @@ -90,6 +101,7 @@ function handleClientControl() {
{$i18n.label.projects}: {$forms.userForm.projects.control}
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
{$i18n.label.projects}: {$forms.userForm.projects.control}
{$i18n.label.required_fields}
- +{if defined('CUSTOM_TRANSLATION_DEBUG')} + + + + + +{/if}
 Anuko Time Tracker 1.18.37.4744 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4745 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheets.php b/timesheets.php index 82a830745..0a926d916 100644 --- a/timesheets.php +++ b/timesheets.php @@ -66,20 +66,23 @@ else $user_id = $users_for_client[0]['id']; // First found user for a client. } - - $group_id = $user->getGroup(); // Elements of timesheetsForm. $form = new Form('timesheetsForm'); -if ($user->can('view_timesheets') || $user->can('view_all_timesheets') || $user->can('manage_timesheets') || $user->can('manage_all_timesheets')) { - $rank = $user->getMaxRankForGroup($group_id); - if ($user->can('track_own_time')) - $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); +if ($user->can('view_timesheets') || $user->can('view_all_timesheets') || $user->can('view_client_timesheets')) { + // Prepare user list for dropdown. + if ($notClient) { + $rank = $user->can('view_all_timesheets') ? MAX_RANK : $user->getMaxRankForGroup($group_id); + if ($user->can('view_own_timesheets')) + $options = array('max_rank'=>$rank,'include_self'=>true,'self_first'=>true); + else + $options = array('max_rank'=>$rank); + $user_list = $user->getUsers($options); + } else + $user_list = $users_for_client; // Obtained above. + if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'document.timesheetsForm.user_changed.value=1;document.timesheetsForm.submit();', From f935dc9ad6911207122e22003f23ade7b62f8167 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 20 Feb 2019 17:05:54 +0000 Subject: [PATCH 0685/1848] Another fix for timesheets.php. --- WEB-INF/templates/footer.tpl | 2 +- timesheets.php | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ae33f1578..ae04c10aa 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - -
 Anuko Time Tracker 1.18.37.4745 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4746 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheets.php b/timesheets.php index 0a926d916..63a1bb348 100644 --- a/timesheets.php +++ b/timesheets.php @@ -96,12 +96,10 @@ } } - - - -// TODO: fix this for client access. $active_timesheets = ttTimesheetHelper::getActiveTimesheets($user_id); -$inactive_timesheets = ttTimesheetHelper::getInactiveTimesheets($user_id); +if ($notClient) + $inactive_timesheets = ttTimesheetHelper::getInactiveTimesheets($user_id); + $show_client = $user->isPluginEnabled('cl') && $notClient; $smarty->assign('active_timesheets', $active_timesheets); From decf7058c3d2cc57fa2f814f33e7c09b264ff854 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 20 Feb 2019 17:11:12 +0000 Subject: [PATCH 0686/1848] Remove unused parameter. --- WEB-INF/templates/footer.tpl | 2 +- mobile/time.php | 4 ++-- time.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ae04c10aa..5fb91bf7b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index dc5c81557..845a94f27 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -40,7 +40,11 @@ {/if} {if $show_approval_status} + {if $timesheet.approval_status == null} + + {else} + {/if} {/if} {if !$user->isClient()} diff --git a/timesheet_view.php b/timesheet_view.php index 136c7f118..5cbd3cfcf 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -47,27 +47,7 @@ // TODO: add other checks here for timesheet being appropriate for user role. // End of access checks. -$invoice_date = new DateAndTime(DB_DATEFORMAT, $invoice['date']); -$client = ttClientHelper::getClient($invoice['client_id'], true); -if (!$client) // In case client was deleted. - $client = ttClientHelper::getDeletedClient($invoice['client_id']); - -$invoice_items = ttInvoiceHelper::getInvoiceItems($cl_invoice_id); -$tax_percent = $client['tax']; - -$subtotal = 0; -$tax = 0; -foreach($invoice_items as $item) - $subtotal += $item['cost']; -if ($tax_percent > 0) { - $tax_expenses = $user->isPluginEnabled('et'); - foreach($invoice_items as $item) { - if ($item['type'] == 2 && !$tax_expenses) - continue; - $tax += round($item['cost'] * $tax_percent / 100, 2); - } -} -$total = $subtotal + $tax; +// $timesheet_items = ttTimesheetHelper::getTimesheetItems($timesheet_id); $currency = $user->getCurrency(); $decimalMark = $user->getDecimalMark(); @@ -118,8 +98,7 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('invoice_id', $cl_invoice_id); -$smarty->assign('timesheet_name', $timesheet['name']); -$smarty->assign('invoice_date', $invoice_date->toString($user->getDateFormat())); +$smarty->assign('timesheet', $timesheet); $smarty->assign('client_name', $client['name']); $smarty->assign('client_address', $client['address']); $smarty->assign('show_project', MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode); From bc7836c64252d104495878af3c005210cb977072 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 21 Feb 2019 17:11:44 +0000 Subject: [PATCH 0690/1848] Implemented timesheet view. --- WEB-INF/lib/ttReportHelper.class.php | 12 ++++ WEB-INF/lib/ttTimesheetHelper.class.php | 27 +++++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_view.tpl | 87 ++++++------------------- timesheet_view.php | 62 ++---------------- 5 files changed, 65 insertions(+), 125 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index c3656ad6f..1f537bbb0 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -43,6 +43,12 @@ static function getWhere($options) { $group_id = $user->getGroup(); $org_id = $user->org_id; + // A shortcut for timesheets. + if ($options['timesheet_id']) { + $where = " where l.timesheet_id = ".$options['timesheet_id']." and l.group_id = $group_id and l.org_id = $org_id"; + return $where; + } + // Prepare dropdown parts. $dropdown_parts = ''; if ($options['client_id']) @@ -89,6 +95,12 @@ static function getExpenseWhere($options) { $group_id = $user->getGroup(); $org_id = $user->org_id; + // A shortcut for timesheets. + if ($options['timesheet_id']) { + $where = " where ei.timesheet_id = ".$options['timesheet_id']." and ei.group_id = $group_id and ei.org_id = $org_id"; + return $where; + } + // Prepare dropdown parts. $dropdown_parts = ''; if ($options['client_id']) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 49808359a..94b9beff2 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -214,7 +214,8 @@ static function getTimesheet($timesheet_id) { if ($user->isClient()) $client_part = "and ts.client_id = $user->client_id"; - $sql = "select ts.id, ts.user_id, u.name as user_name, ts.client_id, c.name as client_name, ts.name from tt_timesheets ts". + $sql = "select ts.id, ts.user_id, u.name as user_name, ts.client_id, c.name as client_name,". + " ts.name, ts.submitter_comment from tt_timesheets ts". " left join tt_users u on (u.id = ts.user_id)". " left join tt_clients c on (c.id = ts.client_id)". " where ts.id = $timesheet_id and ts.group_id = $group_id and ts.org_id = $org_id $client_part and ts.status is not null"; @@ -296,4 +297,28 @@ static function isUserValid($user_id) { return true; } + + // getReportOptions prepares $options array to be used with ttReportHelper + // to obtain items for timesheet view. + static function getReportOptions($timesheet) { + global $user; + $group_by_client = $user->isPluginEnabled('cl') && !$timesheet['client_id']; + $trackingMode = $user->getTrackingMode(); + $group_by_project = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; + + $options['timesheet_id'] = $timesheet['id']; + $options['client_id'] = $timesheet['client_id']; + $options['users'] = $timesheet['user_id']; + $options['show_durarion'] = 1; + $options['show_cost'] = 1; // To include expenses. + $options['show_totals_only'] = 1; + $options['group_by1'] = 'date'; + if ($group_by_client || $group_by_project) { + $options['group_by2'] = $group_by_client ? 'client' : 'project'; + } + if ($options['group_by2'] && $options['group_by2'] != 'project' && $group_by_project) { + $options['group_by3'] = 'project'; + } + return $options; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7d43e77d1..df96c6a12 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.37.4746 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4747 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/time.php b/mobile/time.php index 364379f4f..fe723da58 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -115,9 +115,9 @@ if ($user->can('track_time')) { $rank = $user->getMaxRankForGroup($group_id); if ($user->can('track_own_time')) - $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); + $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); else - $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank); + $options = array('status'=>ACTIVE,'max_rank'=>$rank); $user_list = $user->getUsers($options); if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', diff --git a/time.php b/time.php index 5a9b5210d..e4547a949 100644 --- a/time.php +++ b/time.php @@ -131,9 +131,9 @@ if ($user->can('track_time')) { $rank = $user->getMaxRankForGroup($group_id); if ($user->can('track_own_time')) - $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); + $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); else - $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>$rank); + $options = array('status'=>ACTIVE,'max_rank'=>$rank); $user_list = $user->getUsers($options); if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', From a3d07d9fe0c01738c69c6ea37220f3feb4395912 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 20 Feb 2019 18:29:34 +0000 Subject: [PATCH 0687/1848] Added associating items with a timesheet upon its creation. --- WEB-INF/lib/ttTimesheetHelper.class.php | 63 ++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- timesheet_add.php | 2 +- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 3e44c8c34..056fc6859 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -28,6 +28,8 @@ import('ttUserHelper'); import('ttGroupHelper'); +import('form.ActionForm'); +import('ttReportHelper'); // Class ttTimesheetHelper is used to help with project related tasks. class ttTimesheetHelper { @@ -55,6 +57,49 @@ static function getTimesheetByName($name, $user_id) { // insert function inserts a new timesheet into database. static function insert($fields) { + // First, we obtain report items. + + // Obtain session bean with report attributes. + $bean = new ActionForm('reportBean', new Form('reportForm')); + $options = ttReportHelper::getReportOptions($bean); + $report_items = ttReportHelper::getItems($options); + + // Prepare ids for time and expense items, at the same time checking + // if we can proceed with creating a timesheet. + $canCreateTimesheet = true; + $first_user_id = null; + + foreach ($report_items as $report_item) { + // Check user id. + if (!$first_user_id) + $first_user_id = $report_item['user_id']; + else { + if ($report_item['user_id'] != $first_user_id) { + // We have items for multiple users. + $canCreateTimesheet = false; + break; + } + } + // Check timesheet id. + if ($report_item['timesheet_id']) { + // We have an item already assigned to a timesheet. + $canCreateTimesheet = false; + break; + } + if ($report_item['type'] == 1) + $time_ids[] = $report_item['id']; + elseif ($report_item['type'] == 2) + $expense_ids[] = $report_item['id']; + } + if (!$canCreateTimesheet) return false; + + // Make comma-seperated lists of ids for sql. + if ($time_ids) + $comma_separated_time_ids = implode(',', $time_ids); + if ($expense_ids) + $comma_separated_expense_ids = implode(',', $expense_ids); + + // Create a new timesheet entry. global $user; $mdb2 = getConnection(); @@ -74,7 +119,23 @@ static function insert($fields) $last_id = $mdb2->lastInsertID('tt_timesheets', 'id'); - // TODO: Associate report items with new timesheet. + // Associate time items with timesheet. + if ($comma_separated_time_ids) { + $sql = "update tt_log set timesheet_id = $last_id". + " where id in ($comma_separated_time_ids) and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + } + + // Associate expense items with timesheet. + if ($comma_separated_expense_ids) { + $sql = "update tt_expense_items set timesheet_id = $last_id". + " where id in ($comma_separated_expense_ids) and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + } return $last_id; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5fb91bf7b..7d43e77d1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} {if $bean->getAttribute('chip')}{/if} {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} {foreach $report_items as $item} @@ -76,6 +77,7 @@ {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} {if $use_checkboxes}{/if} @@ -102,6 +104,7 @@ {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} {if $use_checkboxes} {if 1 == $item.type}{/if} {if 2 == $item.type}{/if} @@ -128,6 +131,7 @@ {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} {if $use_checkboxes}{/if} {/if} @@ -149,6 +153,7 @@ {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} {if $use_checkboxes}{/if} {/if} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl new file mode 100644 index 000000000..736d65b0c --- /dev/null +++ b/WEB-INF/templates/timesheet_view.tpl @@ -0,0 +1,90 @@ + + +
 Anuko Time Tracker 1.18.37.4747 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4748 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_add.php b/timesheet_add.php index fa8ec4f89..9e6b9acd0 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -31,7 +31,7 @@ import('ttTimesheetHelper'); // Access checks. -if (!(ttAccessAllowed('manage_own_timesheets') || ttAccessAllowed('manage_timesheets'))) { +if (!(ttAccessAllowed('manage_own_timesheets') || ttAccessAllowed('manage_timesheets') || ttAccessAllowed('manage_all_timesheets'))) { header('Location: access_denied.php'); exit(); } From 1b984b0c5f3ac0977c993d5bcff456bbd372f5bf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 21 Feb 2019 13:32:57 +0000 Subject: [PATCH 0688/1848] Starting work on timesheet view. --- WEB-INF/templates/report.tpl | 5 + WEB-INF/templates/timesheet_view.tpl | 90 ++++++++++++++++++ invoice_view.php | 2 +- timesheet_view.php | 131 +++++++++++++++++++++++++++ 4 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/templates/timesheet_view.tpl create mode 100644 timesheet_view.php diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 3cd8e40ec..b603dd27c 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -53,6 +53,7 @@ {if $bean->getAttribute('chpaid')}{$i18n.label.paid}{$i18n.label.ip}{$i18n.label.invoice}{$i18n.label.timesheet}
 
{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{/if} {if $bean->getAttribute('chip')}{if $item.modified}{$item.modified_ip} {$item.modified}{else}{$item.created_ip} {$item.created}{/if}{/if} {if $bean->getAttribute('chinvoice')}{$item.invoice|escape}{$item.timesheet_id|escape}
+ + + + + + + +
+ + + + + +
{$timesheet_name|escape}
{$i18n.label.date}: {$invoice_date}
{$i18n.label.client}: {$client_name|escape}
{$i18n.label.client_address}: {$client_address|escape}
+
+{if $invoice_items} + + + + + {if $show_project} + + {/if} + {if $show_task} + + {/if} + + + + {if $user->isPluginEnabled('ps')} + + {/if} + + {foreach $invoice_items as $invoice_item} + + + + {if $show_project} + + {/if} + {if $show_task} + + {/if} + + + + {if $user->isPluginEnabled('ps')} + + {/if} + + {/foreach} + + {if $tax} + + + + + + + + + {/if} + + + + +
{$i18n.label.date}{$i18n.form.invoice.person}{$i18n.label.project}{$i18n.label.task}{$i18n.label.note}{$i18n.label.duration}{$i18n.label.cost}{$i18n.label.paid}
{$invoice_item.date}{$invoice_item.user_name|escape}{$invoice_item.project_name|escape}{$invoice_item.task_name|escape}{$invoice_item.note|escape}{$invoice_item.duration}{$invoice_item.cost}{if $invoice_item.paid}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
 
{$i18n.label.subtotal}:{$subtotal|escape}
{$i18n.label.tax}:{$tax|escape}
{$i18n.label.total}:{$total|escape}
+ + {$forms.invoiceForm.open} + {if $user->isPluginEnabled('ps')} + + + + +
+ + +
{$i18n.label.mark_paid}: {$forms.invoiceForm.mark_paid_action_options.control} {$forms.invoiceForm.btn_mark_paid.control}
+
+ {/if} + {$forms.invoiceForm.close} +{/if} +

+ +
diff --git a/invoice_view.php b/invoice_view.php index 64831798b..605a53020 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -69,7 +69,7 @@ $tax += round($item['cost'] * $tax_percent / 100, 2); } } -$total = $subtotal + $tax; +$total = $subtotal + $tax; $currency = $user->getCurrency(); $decimalMark = $user->getDecimalMark(); diff --git a/timesheet_view.php b/timesheet_view.php new file mode 100644 index 000000000..136c7f118 --- /dev/null +++ b/timesheet_view.php @@ -0,0 +1,131 @@ +isPluginEnabled('ts')) { + header('Location: feature_disabled.php'); + exit(); +} +$timesheet_id = (int)$request->getParameter('id'); +$timesheet = ttTimesheetHelper::getTimesheet($timesheet_id); +if (!$timesheet) { + header('Location: access_denied.php'); + exit(); +} +// TODO: add other checks here for timesheet being appropriate for user role. +// End of access checks. + +$invoice_date = new DateAndTime(DB_DATEFORMAT, $invoice['date']); +$client = ttClientHelper::getClient($invoice['client_id'], true); +if (!$client) // In case client was deleted. + $client = ttClientHelper::getDeletedClient($invoice['client_id']); + +$invoice_items = ttInvoiceHelper::getInvoiceItems($cl_invoice_id); +$tax_percent = $client['tax']; + +$subtotal = 0; +$tax = 0; +foreach($invoice_items as $item) + $subtotal += $item['cost']; +if ($tax_percent > 0) { + $tax_expenses = $user->isPluginEnabled('et'); + foreach($invoice_items as $item) { + if ($item['type'] == 2 && !$tax_expenses) + continue; + $tax += round($item['cost'] * $tax_percent / 100, 2); + } +} +$total = $subtotal + $tax; + +$currency = $user->getCurrency(); +$decimalMark = $user->getDecimalMark(); + +$smarty->assign('subtotal', $currency.' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($subtotal, 2)))); +if ($tax) $smarty->assign('tax', $currency.' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($tax, 2)))); +$smarty->assign('total', $currency.' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($total, 2)))); + +if ('.' != $decimalMark) { + foreach ($invoice_items as &$item) + $item['cost'] = str_replace('.', $decimalMark, $item['cost']); +} + +// Calculate colspan for invoice summary. +$colspan = 4; +$trackingMode = $user->getTrackingMode(); +if (MODE_PROJECTS == $trackingMode) + $colspan++; +elseif (MODE_PROJECTS_AND_TASKS == $trackingMode) + $colspan += 2; + +$form = new Form('invoiceForm'); +// Hidden control for invoice id. +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_invoice_id)); +// invoiceForm only contains controls for "Mark paid" block below invoice table. +if ($user->isPluginEnabled('ps')) { + $mark_paid_action_options = array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')); + $form->addInput(array('type'=>'combobox', + 'name'=>'mark_paid_action_options', + 'data'=>$mark_paid_action_options, + 'value'=>$cl_mark_paid_action_option)); + $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->get('button.submit'))); +} + +if ($request->isPost()) { + if ($request->getParameter('btn_mark_paid')) { + // User clicked the "Mark paid" button to mark all invoice items either paid or not paid. + + // Determine user action. + $mark_paid = $request->getParameter('mark_paid_action_options') == 1 ? true : false; + ttInvoiceHelper::markPaid($cl_invoice_id, $mark_paid); + + // Re-display this form. + header('Location: invoice_view.php?id='.$cl_invoice_id); + exit(); + } +} + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('invoice_id', $cl_invoice_id); +$smarty->assign('timesheet_name', $timesheet['name']); +$smarty->assign('invoice_date', $invoice_date->toString($user->getDateFormat())); +$smarty->assign('client_name', $client['name']); +$smarty->assign('client_address', $client['address']); +$smarty->assign('show_project', MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode); +$smarty->assign('show_task', MODE_PROJECTS_AND_TASKS == $trackingMode); +$smarty->assign('invoice_items', $invoice_items); +$smarty->assign('colspan', $colspan); +$smarty->assign('title', $i18n->get('title.timesheet')); +$smarty->assign('content_page_name', 'timesheet_view.tpl'); +$smarty->display('index.tpl'); From bc06bc6aacd3a6ecde7d55980a2702809fc26c49 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 21 Feb 2019 14:13:34 +0000 Subject: [PATCH 0689/1848] A bit more work in progress on timesheet view. --- WEB-INF/lib/ttTimesheetHelper.class.php | 8 +++++--- WEB-INF/templates/timesheet_view.tpl | 9 +++++---- WEB-INF/templates/timesheets.tpl | 4 ++++ timesheet_view.php | 25 ++----------------------- 4 files changed, 16 insertions(+), 30 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 056fc6859..49808359a 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -212,10 +212,12 @@ static function getTimesheet($timesheet_id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - if ($user->isClient()) $client_part = "and client_id = $user->client_id"; + if ($user->isClient()) $client_part = "and ts.client_id = $user->client_id"; - $sql = "select * from tt_timesheets". - " where id = $timesheet_id and group_id = $group_id and org_id = $org_id $client_part and status is not null"; + $sql = "select ts.id, ts.user_id, u.name as user_name, ts.client_id, c.name as client_name, ts.name from tt_timesheets ts". + " left join tt_users u on (u.id = ts.user_id)". + " left join tt_clients c on (c.id = ts.client_id)". + " where ts.id = $timesheet_id and ts.group_id = $group_id and ts.org_id = $org_id $client_part and ts.status is not null"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl index 736d65b0c..79ce95a37 100644 --- a/WEB-INF/templates/timesheet_view.tpl +++ b/WEB-INF/templates/timesheet_view.tpl @@ -6,10 +6,11 @@
- - - - + + +{if $timesheet['client_id']} + +{/if}
{$timesheet_name|escape}
{$i18n.label.date}: {$invoice_date}
{$i18n.label.client}: {$client_name|escape}
{$i18n.label.client_address}: {$client_address|escape}
{$timesheet['name']|escape}
{$i18n.label.user}: {$timesheet['user_name']|escape}
{$i18n.label.client}: {$timesheet['client_name']|escape}
{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}
- {if $timesheet['client_id']} +{/if} +{if $timesheet['submitter_comment']} + {/if}
 Anuko Time Tracker 1.18.37.4748 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4749 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl index 79ce95a37..dbdd42de7 100644 --- a/WEB-INF/templates/timesheet_view.tpl +++ b/WEB-INF/templates/timesheet_view.tpl @@ -10,82 +10,35 @@
{$i18n.label.user}: {$timesheet['user_name']|escape}
{$i18n.label.client}: {$timesheet['client_name']|escape}
{$i18n.label.comment}: {$timesheet['submitter_comment']|escape}
-{if $invoice_items} - - - - {if $show_project} - - {/if} - {if $show_task} - - {/if} - - - - {if $user->isPluginEnabled('ps')} - - {/if} - - {foreach $invoice_items as $invoice_item} - - - - {if $show_project} - - {/if} - {if $show_task} - - {/if} - - - - {if $user->isPluginEnabled('ps')} - - {/if} - + + + + + + {foreach $subtotals as $subtotal} + + + + + {/foreach} - - {if $tax} - - - - - - - - - {/if} - - - - -
{$i18n.label.date}{$i18n.form.invoice.person}{$i18n.label.project}{$i18n.label.task}{$i18n.label.note}{$i18n.label.duration}{$i18n.label.cost}{$i18n.label.paid}
{$invoice_item.date}{$invoice_item.user_name|escape}{$invoice_item.project_name|escape}{$invoice_item.task_name|escape}{$invoice_item.note|escape}{$invoice_item.duration}{$invoice_item.cost}{if $invoice_item.paid}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$group_by_header|escape}{$i18n.label.duration}{$i18n.label.cost}
{if $subtotal['name']}{$subtotal['name']|escape}{else} {/if}{$subtotal['time']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotal['cost']}{else}{$subtotal['expenses']}{/if}
 
{$i18n.label.subtotal}:{$subtotal|escape}
{$i18n.label.tax}:{$tax|escape}
{$i18n.label.total}:{$total|escape}
- - {$forms.invoiceForm.open} - {if $user->isPluginEnabled('ps')} - - - -
- - + + + + + +
{$i18n.label.mark_paid}: {$forms.invoiceForm.mark_paid_action_options.control} {$forms.invoiceForm.btn_mark_paid.control}
 
{$i18n.label.total}{$totals['time']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
- {/if} - {$forms.invoiceForm.close} -{/if} -

- -
diff --git a/timesheet_view.php b/timesheet_view.php index 5cbd3cfcf..bbac161ca 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -47,64 +47,14 @@ // TODO: add other checks here for timesheet being appropriate for user role. // End of access checks. -// $timesheet_items = ttTimesheetHelper::getTimesheetItems($timesheet_id); +$options = ttTimesheetHelper::getReportOptions($timesheet); +$subtotals = ttReportHelper::getSubtotals($options); +$totals = ttReportHelper::getTotals($options); -$currency = $user->getCurrency(); -$decimalMark = $user->getDecimalMark(); - -$smarty->assign('subtotal', $currency.' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($subtotal, 2)))); -if ($tax) $smarty->assign('tax', $currency.' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($tax, 2)))); -$smarty->assign('total', $currency.' '.str_replace('.', $decimalMark, sprintf('%8.2f', round($total, 2)))); - -if ('.' != $decimalMark) { - foreach ($invoice_items as &$item) - $item['cost'] = str_replace('.', $decimalMark, $item['cost']); -} - -// Calculate colspan for invoice summary. -$colspan = 4; -$trackingMode = $user->getTrackingMode(); -if (MODE_PROJECTS == $trackingMode) - $colspan++; -elseif (MODE_PROJECTS_AND_TASKS == $trackingMode) - $colspan += 2; - -$form = new Form('invoiceForm'); -// Hidden control for invoice id. -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_invoice_id)); -// invoiceForm only contains controls for "Mark paid" block below invoice table. -if ($user->isPluginEnabled('ps')) { - $mark_paid_action_options = array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')); - $form->addInput(array('type'=>'combobox', - 'name'=>'mark_paid_action_options', - 'data'=>$mark_paid_action_options, - 'value'=>$cl_mark_paid_action_option)); - $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->get('button.submit'))); -} - -if ($request->isPost()) { - if ($request->getParameter('btn_mark_paid')) { - // User clicked the "Mark paid" button to mark all invoice items either paid or not paid. - - // Determine user action. - $mark_paid = $request->getParameter('mark_paid_action_options') == 1 ? true : false; - ttInvoiceHelper::markPaid($cl_invoice_id, $mark_paid); - - // Re-display this form. - header('Location: invoice_view.php?id='.$cl_invoice_id); - exit(); - } -} - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('invoice_id', $cl_invoice_id); +$smarty->assign('group_by_header', ttReportHelper::makeGroupByHeader($options)); $smarty->assign('timesheet', $timesheet); -$smarty->assign('client_name', $client['name']); -$smarty->assign('client_address', $client['address']); -$smarty->assign('show_project', MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode); -$smarty->assign('show_task', MODE_PROJECTS_AND_TASKS == $trackingMode); -$smarty->assign('invoice_items', $invoice_items); -$smarty->assign('colspan', $colspan); +$smarty->assign('subtotals', $subtotals); +$smarty->assign('totals', $totals); $smarty->assign('title', $i18n->get('title.timesheet')); $smarty->assign('content_page_name', 'timesheet_view.tpl'); $smarty->display('index.tpl'); From 73f1ed8b4fb4888b8251b3575ba1d94cf1a68a4e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 21 Feb 2019 22:44:01 +0000 Subject: [PATCH 0691/1848] Some fixes on timesheets.php for clients. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheets.tpl | 62 ++++++++++++++++---------------- timesheets.php | 11 +++--- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index df96c6a12..37f3de1ec 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.37.4749 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4750 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index 845a94f27..f9b89d792 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -4,7 +4,7 @@ {$forms.timesheetsForm.open} -{if $show_hint} +{if $not_client} {/if} {if $user_dropdown} @@ -13,33 +13,31 @@ diff --git a/timesheet_view.php b/timesheet_view.php index bbac161ca..80b3b77ac 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -50,7 +50,9 @@ $options = ttTimesheetHelper::getReportOptions($timesheet); $subtotals = ttReportHelper::getSubtotals($options); $totals = ttReportHelper::getTotals($options); +$notClient = !$user->isClient(); +$smarty->assign('not_client', $notClient); $smarty->assign('group_by_header', ttReportHelper::makeGroupByHeader($options)); $smarty->assign('timesheet', $timesheet); $smarty->assign('subtotals', $subtotals); From c7d73ed8f6e2deade801bedaeb3af934ba69bf88 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 22 Feb 2019 16:16:25 +0000 Subject: [PATCH 0693/1848] Started to work on timesheet approval workflow. --- WEB-INF/lib/ttTimesheetHelper.class.php | 25 +++++++++++++++++++++++++ WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/lib/ttUserHelper.class.php | 17 +++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- timesheet_view.php | 3 +++ 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 07f02f861..0d4556bc7 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -321,4 +321,29 @@ static function getReportOptions($timesheet) { } return $options; } + + // getApprovers obtains a list of users who can approve a timesheet for a given user + // and also have an email to receive a notification about it. + static function getApprovers($user_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $approvers = array(); + $rank = ttUserHelper::getUserRank($user_id); + $sql = "select u.id, u.name, u.email". + " from tt_users u". + " left join tt_roles r on (r.id = u.role_id)". + " where u.status = 1 and u.email is not null". + " and (r.rights like '%approve_all_timesheets%' or (r.rank > $rank and r.rights like '%approve_timesheets%'))"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $approvers[] = $val; + } + } + return $approvers; + } } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 36f9163f1..28eeebcfd 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -592,7 +592,7 @@ function checkBehalfId() { return false; // So far, so good. Check user now. - $options = array('group_id'=>$group_id,'status'=>ACTIVE,'max_rank'=>MAX_RANK); + $options = array('status'=>ACTIVE,'max_rank'=>MAX_RANK); $users = $this->getUsers($options); foreach($users as $one_user) { if ($one_user['id'] == $this->behalf_id) diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index d0a09ced8..17ef08c23 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -404,4 +404,21 @@ static function canAdd($num_users = 1) { return false; } + + // getUserRank - obtains a rank for a given user. + static function getUserRank($user_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select r.rank from tt_users u". + " left join tt_roles r on (u.role_id = r.id)". + " where u.id = $user_id and u.group_id = $group_id and u.org_id = $org_id"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return 0; + $val = $res->fetchRow(); + return $val['rank']; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 86ccb33ff..a84e3246e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.timesheets.hint}
- {if $inactive_timesheets} +{if $inactive_timesheets} - {/if} +{/if} - {if $show_client} +{if $show_client} - {/if} - {if $show_submit_status} +{/if} +{if $not_client} - {/if} - {if $show_approval_status} - {/if} +{/if} +{if $can_edit} +{/if} - {foreach $active_timesheets as $timesheet} +{foreach $active_timesheets as $timesheet} {if $show_client} {/if} - {if $show_submit_status} + {if $not_client} - {/if} - {if $show_approval_status} {if $timesheet.approval_status == null} {else} @@ -47,17 +45,17 @@ {/if} {/if} - {if !$user->isClient()} + {if $can_edit} {/if} - {/foreach} +{/foreach}
{$i18n.form.timesheets.active_timesheets}
{$i18n.label.thing_name}{$i18n.label.client}{$i18n.label.submitted}{$i18n.label.approved}{$i18n.label.view}{$i18n.label.edit}
{$timesheet.name|escape}{$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}{$i18n.label.edit}
- {if !$user->isClient()} +{if $not_client}

- {/if} +{/if} {if $inactive_timesheets} @@ -68,35 +66,37 @@ {if $show_client} {/if} - {if $show_submit_status} + {if $not_client} - {/if} - {if $show_approval_status} {/if} + {if $can_edit} + {/if} - {foreach $inactive_timesheets as $timesheet} + {foreach $inactive_timesheets as $timesheet} - {if $show_client} + {if $show_client} - {/if} - {if $show_submit_status} + {/if} + {if $not_client} - {/if} - {if $show_approval_status} + {if $timesheet.approval_status == null} + + {else} - {/if} + {/if} + {/if} - {if !$user->isClient()} + {if $can_edit} - {/if} + {/if} - {/foreach} + {/foreach}
{$i18n.label.client}{$i18n.label.submitted}{$i18n.label.approved}{$i18n.label.view}{$i18n.label.edit}
{$timesheet.name|escape}{$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}{$i18n.label.edit}
- {if !$user->isClient()} + {if $not_client}

diff --git a/timesheets.php b/timesheets.php index 63a1bb348..672e85974 100644 --- a/timesheets.php +++ b/timesheets.php @@ -100,14 +100,15 @@ if ($notClient) $inactive_timesheets = ttTimesheetHelper::getInactiveTimesheets($user_id); -$show_client = $user->isPluginEnabled('cl') && $notClient; +$showClient = $user->isPluginEnabled('cl') && $notClient; +$canEdit = $notClient && ($user->can('manage_own_timesheets') || + $user->can('manage_timesheets') || $user->can('manage_all_timesheets')); $smarty->assign('active_timesheets', $active_timesheets); $smarty->assign('inactive_timesheets', $inactive_timesheets); -$smarty->assign('show_client', $show_client); -$smarty->assign('show_hint', $notClient); -$smarty->assign('show_submit_status', $notClient); -$smarty->assign('show_approval_status', $notClient); +$smarty->assign('show_client', $showClient); +$smarty->assign('not_client', $notClient); +$smarty->assign('can_edit', $canEdit); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.timesheets')); $smarty->assign('content_page_name', 'timesheets.tpl'); From 887a005ea99f044d266f489632b0a94a4acc99b2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 21 Feb 2019 23:16:53 +0000 Subject: [PATCH 0692/1848] Some more work in progress on timesheets. --- WEB-INF/lib/ttTimesheetHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_view.tpl | 5 ++++- timesheet_view.php | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 94b9beff2..07f02f861 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -215,7 +215,7 @@ static function getTimesheet($timesheet_id) { if ($user->isClient()) $client_part = "and ts.client_id = $user->client_id"; $sql = "select ts.id, ts.user_id, u.name as user_name, ts.client_id, c.name as client_name,". - " ts.name, ts.submitter_comment from tt_timesheets ts". + " ts.name, ts.submitter_comment, ts.submit_status from tt_timesheets ts". " left join tt_users u on (u.id = ts.user_id)". " left join tt_clients c on (c.id = ts.client_id)". " where ts.id = $timesheet_id and ts.group_id = $group_id and ts.org_id = $org_id $client_part and ts.status is not null"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 37f3de1ec..86ccb33ff 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} -{if $timesheet['submitter_comment']} +{if $not_client} + + {if $timesheet['submitter_comment']} + {/if} {/if}
 Anuko Time Tracker 1.18.37.4750 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4751 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl index dbdd42de7..c22df7ac8 100644 --- a/WEB-INF/templates/timesheet_view.tpl +++ b/WEB-INF/templates/timesheet_view.tpl @@ -11,8 +11,11 @@ {if $timesheet['client_id']}
{$i18n.label.client}: {$timesheet['client_name']|escape}
{$i18n.label.submitted}: {if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.comment}: {$timesheet['submitter_comment']|escape}
- @@ -42,6 +48,32 @@
 Anuko Time Tracker 1.18.37.4751 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4752 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_view.php b/timesheet_view.php index 80b3b77ac..bd97a52a5 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -52,6 +52,9 @@ $totals = ttReportHelper::getTotals($options); $notClient = !$user->isClient(); +// Determine managers we can submit this timesheet for approval to. +$approvers = ttTimesheetHelper::getApprovers($timesheet['user_id']); + $smarty->assign('not_client', $notClient); $smarty->assign('group_by_header', ttReportHelper::makeGroupByHeader($options)); $smarty->assign('timesheet', $timesheet); From 8fd871c1242b3309b8a374a97969ab74d5375069 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 22 Feb 2019 21:38:50 +0000 Subject: [PATCH 0694/1848] More progress on timesheet approval workflow. --- WEB-INF/lib/ttTimesheetHelper.class.php | 25 +++++++++++++- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 3 ++ WEB-INF/resources/de.lang.php | 3 ++ WEB-INF/resources/en.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 4 +++ WEB-INF/resources/fa.lang.php | 3 ++ WEB-INF/resources/fi.lang.php | 3 ++ WEB-INF/resources/fr.lang.php | 3 ++ WEB-INF/resources/gr.lang.php | 3 ++ WEB-INF/resources/he.lang.php | 3 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 3 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 3 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 3 ++ WEB-INF/resources/pt-br.lang.php | 3 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 3 ++ WEB-INF/resources/sv.lang.php | 3 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_view.tpl | 32 ++++++++++++++++++ timesheet_view.php | 45 +++++++++++++++++++++++-- 34 files changed, 175 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 0d4556bc7..df1e4e484 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -215,7 +215,7 @@ static function getTimesheet($timesheet_id) { if ($user->isClient()) $client_part = "and ts.client_id = $user->client_id"; $sql = "select ts.id, ts.user_id, u.name as user_name, ts.client_id, c.name as client_name,". - " ts.name, ts.submitter_comment, ts.submit_status from tt_timesheets ts". + " ts.name, ts.submitter_comment, ts.submit_status, ts.approval_status, ts.manager_comment from tt_timesheets ts". " left join tt_users u on (u.id = ts.user_id)". " left join tt_clients c on (c.id = ts.client_id)". " where ts.id = $timesheet_id and ts.group_id = $group_id and ts.org_id = $org_id $client_part and ts.status is not null"; @@ -346,4 +346,27 @@ static function getApprovers($user_id) { } return $approvers; } + + // submitTimesheet marks a timesheet as submitted and sends an email to an approver. + static function submitTimesheet($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // First, mark a timesheet as submitted. + // Even if mail part below does not work, this will get us a functioning workflow + // (without email notifications). + $timesheet_id = $fields['timesheet_id']; + $sql = "update tt_timesheets set submit_status = 1". + " where id = $timesheet_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // TODO: send email to approver here... + // $approver_id = $fields['approver_id']; + + return true; + } } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 6dd031c23..4830b0e72 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -151,6 +151,8 @@ // TODO: translate the following. // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 771a0f297..9cbdba5eb 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -153,6 +153,8 @@ // TODO: translate the following. // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 702958d41..1d39ffbf5 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -144,6 +144,9 @@ 'button.import' => 'Importer team', // TODO: replace "team" with "group". 'button.close' => 'Luk', 'button.stop' => 'Stop', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Team navn', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 257ab7e91..6a967bd4b 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -138,6 +138,9 @@ 'button.import' => 'Gruppe importieren', 'button.close' => 'Schließen', 'button.stop' => 'Stop', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Gruppenname', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 7621a83d5..0534e60b0 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -131,6 +131,8 @@ 'button.import' => 'Import group', 'button.close' => 'Close', 'button.stop' => 'Stop', +'button.approve' => 'Approve', +'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Group name', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 19a8ed515..02d621541 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -150,6 +150,8 @@ // TODO: translate the following. // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 170c447a8..a5b4319c2 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -152,6 +152,10 @@ 'button.import' => 'Impordi grupp', 'button.close' => 'Sulge', 'button.stop' => 'Stopp', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', + // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Grupi nimi', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 783a1b5a3..e4983f402 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -151,6 +151,9 @@ 'button.import' => 'وارد کردن تیم', // TODO: replace "team" with "group". 'button.close' => 'بستن', 'button.stop' => 'توقف', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'نام تیم', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 175c993e4..2dc50b616 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -146,6 +146,9 @@ 'button.import' => 'Tuo tiimi', // TODO: replace "team" with "group". 'button.close' => 'Sulje', 'button.stop' => 'Lopeta', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Tiimin nimi', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 9d7a7c7e4..a26bba753 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -144,6 +144,9 @@ 'button.import' => 'Importer une équipe', // TODO: replace "team" with "group". 'button.close' => 'Fermer', 'button.stop' => 'Arrêter', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Nom équipe', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 9e22079e2..0159ff293 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -139,6 +139,9 @@ 'button.import' => 'Εισαγωγή ομάδας', 'button.close' => 'Κλείσιμο', 'button.stop' => 'Τέλος', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Όνομα ομάδας', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 3418d106d..ab5d1b023 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -161,6 +161,9 @@ 'button.import' => 'ייבא צוות', // TODO: replace "team" with "group". 'button.close' => 'סגור', 'button.stop' => 'עצור', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'שם הצוות', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 9157dd68b..521b42e5f 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -152,6 +152,8 @@ // TODO: translate the following. // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 51768b0d3..ca39ee64e 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -143,6 +143,9 @@ 'button.import' => 'Importa gruppo', 'button.close' => 'Chiudi', 'button.stop' => 'Stop', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Nome del gruppo', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index e19c4a4ba..f85d3ef14 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -156,6 +156,8 @@ // TODO: translate the following. // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 3999a097b..ba9b4e021 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -155,6 +155,8 @@ // TODO: translate the following. // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 58fdd7205..a416da5e3 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -132,6 +132,9 @@ 'button.import' => 'Groep importeren', 'button.close' => 'Sluiten', 'button.stop' => 'Stop', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Groepsnaam', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 1a88ce308..3973be838 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -156,6 +156,8 @@ 'button.close' => 'Lukk', // TODO: translate the following. // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 8af61cf8b..0b867ff34 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -148,6 +148,9 @@ 'button.import' => 'Importuj zespół', // TODO: replace "team" with "group". 'button.close' => 'Zamknij', 'button.stop' => 'Zatrzymaj', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Nazwa zespołu', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 018c7717c..3a48deccf 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -145,6 +145,9 @@ 'button.import' => 'Importar equipe', // TODO: replace "team" with "group". 'button.close' => 'Fechar', 'button.stop' => 'Parar', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Nome da equipe', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d8f1611c4..6ee9363b2 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -148,6 +148,8 @@ // 'button.import' => 'Import group', // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 47ae568c5..f2bd2e956 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -156,6 +156,8 @@ // TODO: translate the following. // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 97cab56c5..b30765a01 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -130,6 +130,8 @@ 'button.import' => 'Импортировать группу', 'button.close' => 'Закрыть', 'button.stop' => 'Завершить', +'button.approve' => 'Одобрить', +'button.disapprove' => 'Не одобрить', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Название группы', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index fa0df1d5d..f6a0a0687 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -152,6 +152,8 @@ 'button.close' => 'Zatvoriť', // TODO: translate the following. // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Názov tímu', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 620a8b840..0e602e426 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -146,6 +146,8 @@ // TODO: translate the following. // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 8163a8087..cfc2dac50 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -145,6 +145,9 @@ 'button.import' => 'Uvezi tim', // TODO: replace "team" with "group". 'button.close' => 'Zatvori', 'button.stop' => 'Stani', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Naziv tim-a', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 8ddf01adc..24072b0e8 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -143,6 +143,9 @@ 'button.import' => 'Importera grupp', 'button.close' => 'Stäng', 'button.stop' => 'Avsluta', +// TODO: translate the following. +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => 'Namn på grupp', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 4f82410f6..cccf336c2 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -159,6 +159,8 @@ // TODO: translate the following. // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 41e4acdfc..6f4f6389f 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -147,6 +147,8 @@ 'button.close' => '关闭', // TODO: translate the following. // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.group_name' => '团队名称', // TODO: replace "team" with "group". diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 5e582399c..49bfb85da 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -152,6 +152,8 @@ // TODO: translate the following. // 'button.close' => 'Close', // 'button.stop' => 'Stop', +// 'button.approve' => 'Approve', +// 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a84e3246e..71d49f2e4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} + {if $timesheet['submit_status']} + {/if} + {/if} + {if $timesheet['manager_comment']} + + {/if} {/if}
 Anuko Time Tracker 1.18.37.4752 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4753 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl index c22df7ac8..171144394 100644 --- a/WEB-INF/templates/timesheet_view.tpl +++ b/WEB-INF/templates/timesheet_view.tpl @@ -16,6 +16,12 @@ {if $timesheet['submitter_comment']}
{$i18n.label.comment}: {$timesheet['submitter_comment']|escape}
{$i18n.label.approved}: {if $timesheet.approval_status != null}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.note}: {$timesheet['manager_comment']|escape}
{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
+ +{$forms.timesheetForm.open} + {if $show_submit} + + + + +
+ + +
{$i18n.form.mail.to}: {$forms.timesheetForm.approver.control} {$forms.timesheetForm.btn_submit.control}
+
+ {/if} + {if $show_approve} + + + + +
+ + +
{$forms.timesheetForm.btn_approve.control} {$forms.timesheetForm.btn_disapprove.control}
+
+ {/if} +{$forms.timesheetForm.close} +
diff --git a/timesheet_view.php b/timesheet_view.php index bd97a52a5..0e9a7ea96 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -45,6 +45,7 @@ exit(); } // TODO: add other checks here for timesheet being appropriate for user role. +// TODO: if this is a timeheet submit, validate approver id, too. // End of access checks. $options = ttTimesheetHelper::getReportOptions($timesheet); @@ -52,14 +53,54 @@ $totals = ttReportHelper::getTotals($options); $notClient = !$user->isClient(); -// Determine managers we can submit this timesheet for approval to. -$approvers = ttTimesheetHelper::getApprovers($timesheet['user_id']); +// Determine which controls to show and obtain date for them. +$showSubmit = $notClient && !$timesheet['submit_status']; +if ($showSubmit) $approvers = ttTimesheetHelper::getApprovers($timesheet['user_id']); +$canApprove = $user->can('approve_timesheets') || $user_>can('approve_all_timesheets'); +$showApprove = $notClient && $timesheet['submit_status'] && !$timesheet['approval_status']; + +// Add a form with controls. +$form = new Form('timesheetForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$timesheet['id'])); + +if ($showSubmit) { + if (count($approvers) >= 1) { + $form->addInput(array('type'=>'combobox', + 'name'=>'approver', + 'style'=>'width: 200px;', + 'data'=>$approvers, + 'datakeys'=>array('id','name'))); + } + $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); +} + +if ($showApprove) { + $form->addInput(array('type'=>'submit','name'=>'btn_approve','value'=>$i18n->get('button.approve'))); + $form->addInput(array('type'=>'submit','name'=>'btn_disapprove','value'=>$i18n->get('button.disapprove'))); +} + +// Submit. +if ($request->isPost()) { + if ($request->getParameter('btn_submit')) { + $fields = array('timesheet_id' => $timesheet['id'], + 'approver_id' => $approver_id); // TODO: obtain (and check) approver id above during access checks. + if (ttTimesheetHelper::submitTimesheet($fields)) { + // Redirect to self. + header('Location: timesheet_view.php?id='.$timesheet['id']); + exit(); + } else + $err->add($i18n->get('error.db')); + } +} $smarty->assign('not_client', $notClient); $smarty->assign('group_by_header', ttReportHelper::makeGroupByHeader($options)); $smarty->assign('timesheet', $timesheet); $smarty->assign('subtotals', $subtotals); $smarty->assign('totals', $totals); +$smarty->assign('show_submit', $showSubmit); +$smarty->assign('show_approve', $showApprove); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.timesheet')); $smarty->assign('content_page_name', 'timesheet_view.tpl'); $smarty->display('index.tpl'); From e5486346ac0574517a4fd118f03616ec455df9a9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 22 Feb 2019 22:13:15 +0000 Subject: [PATCH 0695/1848] Implemented timesheet approval in initial form. --- WEB-INF/lib/ttTimesheetHelper.class.php | 46 +++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_view.tpl | 4 ++- timesheet_view.php | 29 +++++++++++++++- 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index df1e4e484..21e75a96d 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -369,4 +369,50 @@ static function submitTimesheet($fields) { return true; } + + // approveTimesheet marks a timesheet as approved and sends an email to submitter. + static function approveTimesheet($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // First, mark a timesheet as approved. + // Even if mail part below does not work, this will get us a functioning workflow + // (without email notifications). + $timesheet_id = $fields['timesheet_id']; + $manager_comment = $fields['comment']; + + $sql = "update tt_timesheets set approval_status = 1, manager_comment = ".$mdb2->quote($manager_comment). + " where id = $timesheet_id and submit_status = 1 and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // TODO: send email to submitter here... + return true; + } + + // disapproveTimesheet marks a timesheet as approved and sends an email to submitter. + static function disapproveTimesheet($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // First, mark a timesheet as disapproved. + // Even if mail part below does not work, this will get us a functioning workflow + // (without email notifications). + $timesheet_id = $fields['timesheet_id']; + $manager_comment = $fields['comment']; + + $sql = "update tt_timesheets set approval_status = 0, manager_comment = ".$mdb2->quote($manager_comment). + " where id = $timesheet_id and submit_status = 1 and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + // TODO: send email to submitter here... + return true; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 71d49f2e4..024e05d38 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/timesheet_view.php b/timesheet_view.php index 0e9a7ea96..70ab3357d 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -48,6 +48,10 @@ // TODO: if this is a timeheet submit, validate approver id, too. // End of access checks. +if ($request->isPost()) { + $cl_comment = trim($request->getParameter('comment')); +} + $options = ttTimesheetHelper::getReportOptions($timesheet); $subtotals = ttReportHelper::getSubtotals($options); $totals = ttReportHelper::getTotals($options); @@ -57,7 +61,7 @@ $showSubmit = $notClient && !$timesheet['submit_status']; if ($showSubmit) $approvers = ttTimesheetHelper::getApprovers($timesheet['user_id']); $canApprove = $user->can('approve_timesheets') || $user_>can('approve_all_timesheets'); -$showApprove = $notClient && $timesheet['submit_status'] && !$timesheet['approval_status']; +$showApprove = $notClient && $timesheet['submit_status'] && $timesheet['approval_status'] == null; // Add a form with controls. $form = new Form('timesheetForm'); @@ -75,6 +79,7 @@ } if ($showApprove) { + $form->addInput(array('type'=>'textarea','name'=>'comment','maxlength'=>'250','style'=>'width: 300px; height: 60px;')); $form->addInput(array('type'=>'submit','name'=>'btn_approve','value'=>$i18n->get('button.approve'))); $form->addInput(array('type'=>'submit','name'=>'btn_disapprove','value'=>$i18n->get('button.disapprove'))); } @@ -91,6 +96,28 @@ } else $err->add($i18n->get('error.db')); } + + if ($request->getParameter('btn_approve')) { + $fields = array('timesheet_id' => $timesheet['id'], + 'comment' => $cl_comment); + if (ttTimesheetHelper::approveTimesheet($fields)) { + // Redirect to self. + header('Location: timesheet_view.php?id='.$timesheet['id']); + exit(); + } else + $err->add($i18n->get('error.db')); + } + + if ($request->getParameter('btn_disapprove')) { + $fields = array('timesheet_id' => $timesheet['id'], + 'comment' => $cl_comment); + if (ttTimesheetHelper::disapproveTimesheet($fields)) { + // Redirect to self. + header('Location: timesheet_view.php?id='.$timesheet['id']); + exit(); + } else + $err->add($i18n->get('error.db')); + } } $smarty->assign('not_client', $notClient); From db55bdb7b1dd2bcfa793437fe97a6777eb9d93a6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 13:58:42 +0000 Subject: [PATCH 0696/1848] Fixed menu display for client role. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- timesheet_view.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 024e05d38..8ee0d3825 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.37.4753 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4754 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl index 171144394..97591fe0b 100644 --- a/WEB-INF/templates/timesheet_view.tpl +++ b/WEB-INF/templates/timesheet_view.tpl @@ -66,7 +66,9 @@
- + + +
{$forms.timesheetForm.btn_approve.control} {$forms.timesheetForm.btn_disapprove.control}
{$i18n.label.comment}:
{$forms.timesheetForm.comment.control}
{$forms.timesheetForm.btn_approve.control} {$forms.timesheetForm.btn_disapprove.control}
- - - + +
 Anuko Time Tracker 1.18.37.4754 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4755 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 0b9e290a1..385f8a85b 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -113,7 +113,7 @@ · {$i18n.menu.expenses} {/if} {if $user->exists() && ($user->can('view_own_reports') || $user->can('view_reports') || $user->can('view_all_reports') || $user->can('view_client_reports'))} - · {$i18n.menu.reports} + {if !$user->isClient()}·{/if} {$i18n.menu.reports} {/if} {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets') || $user->can('view_client_timesheets'))} · {$i18n.menu.timesheets} diff --git a/timesheet_view.php b/timesheet_view.php index 70ab3357d..5079fe7b7 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -45,7 +45,7 @@ exit(); } // TODO: add other checks here for timesheet being appropriate for user role. -// TODO: if this is a timeheet submit, validate approver id, too. +// TODO: if this is a timesheet submit, validate approver id, too. // End of access checks. if ($request->isPost()) { From 4453de30f591a32c3de8fd71f5b5ad9558d3878e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 14:44:39 +0000 Subject: [PATCH 0697/1848] Added timesheet name to report output. --- WEB-INF/lib/ttReportHelper.class.php | 12 ++++++++++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 1f537bbb0..6b84f4c71 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -166,7 +166,6 @@ static function getItems($options) { array_push($fields, 'l.user_id'); array_push($fields, '1 as type'); // Type 1 is for tt_log entries. array_push($fields, 'l.date'); - array_push($fields, 'l.timesheet_id'); if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. @@ -235,6 +234,9 @@ static function getItems($options) { // Add invoice name if it is selected. if (($canViewReports || $isClient) && $options['show_invoice']) array_push($fields, 'i.name as invoice'); + // Add timesheet name if it is selected. + if ($options['show_timesheet']) + array_push($fields, 'ts.name as timesheet_name'); // Prepare sql query part for left joins. $left_joins = null; @@ -258,6 +260,8 @@ static function getItems($options) { } if ($includeCost && MODE_TIME != $trackingMode) $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; + if ($options['show_timesheet']) + $left_joins .= " left join tt_timesheets ts on (l.timesheet_id = ts.id)"; $where = ttReportHelper::getWhere($options); @@ -274,7 +278,6 @@ static function getItems($options) { array_push($fields, 'ei.user_id'); array_push($fields, '2 as type'); // Type 2 is for tt_expense_items entries. array_push($fields, 'ei.date'); - array_push($fields, 'ei.timesheet_id'); if($canViewReports || $isClient) array_push($fields, 'u.name as user'); // Add client name if it is selected. @@ -315,6 +318,8 @@ static function getItems($options) { // Add invoice name if it is selected. if (($canViewReports || $isClient) && $options['show_invoice']) array_push($fields, 'i.name as invoice'); + if ($options['show_timesheet']) + array_push($fields, 'ts.name as timesheet_name'); // Prepare sql query part for left joins. $left_joins = null; @@ -326,6 +331,8 @@ static function getItems($options) { $left_joins .= " left join tt_projects p on (p.id = ei.project_id)"; if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; + if ($options['show_timesheet']) + $left_joins .= " left join tt_timesheets ts on (ei.timesheet_id = ts.id)"; $where = ttReportHelper::getExpenseWhere($options); @@ -1005,6 +1012,7 @@ static function getReportOptions($bean) { $options['show_note'] = $bean->getAttribute('chnote'); $options['show_custom_field_1'] = $bean->getAttribute('chcf_1'); $options['show_work_units'] = $bean->getAttribute('chunits'); + $options['show_timesheet'] = $bean->getAttribute('chtimesheet'); $options['show_totals_only'] = $bean->getAttribute('chtotalsonly'); $options['group_by1'] = $bean->getAttribute('group_by1'); $options['group_by2'] = $bean->getAttribute('group_by2'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8ee0d3825..049d1f37f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} - {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} {if $use_checkboxes} {if 1 == $item.type}{/if} {if 2 == $item.type}{/if} From eba5280c22e659f7144ccb5129424f645bada9ab Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 14:57:01 +0000 Subject: [PATCH 0698/1848] Fixed display of Timesheet checkbox for clients. --- WEB-INF/templates/footer.tpl | 2 +- reports.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 049d1f37f..951bba177 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.37.4755 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4756 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index b603dd27c..f62929f9f 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -104,7 +104,7 @@ {if $bean->getAttribute('chpaid')}{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{/if} {if $bean->getAttribute('chip')}{if $item.modified}{$item.modified_ip} {$item.modified}{else}{$item.created_ip} {$item.created}{/if}{/if} {if $bean->getAttribute('chinvoice')}{$item.invoice|escape}{$item.timesheet_id|escape}{$item.timesheet_name|escape}
- {/if} -{if isTrue('FILTER_BY_NOTES_DEBUG')} -{/if}
 Anuko Time Tracker 1.18.37.4756 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4757 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 05d7e5f26..264e5645c 100644 --- a/reports.php +++ b/reports.php @@ -180,8 +180,8 @@ // Add timesheet assignment selector. $showTimesheet = $user->isPluginEnabled('ts') && - ($user->can('view_own_timesheets') || $user->can('manage_own_timesheets') || - $user->can('view_timesheets') || $user->can('manage_timesheets') || $user->can('approve_timesheets')); + ($user->can('view_own_timesheets') || $user->can('view_timesheets') || + $user->can('view_all_timesheets') || $user->can('view_client_timesheets')); if ($showTimesheet) { $form->addInput(array('type'=>'combobox', 'name'=>'timesheet', From 0f3dceb9c5fd515d2e1bd39a480345d71ad6a113 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 15:10:00 +0000 Subject: [PATCH 0699/1848] Fixed report filter by timesheet assignment. --- WEB-INF/lib/ttReportHelper.class.php | 13 +++++++++---- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 6b84f4c71..c96f0f4dc 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -60,8 +60,10 @@ static function getWhere($options) { if ($options['task_id']) $dropdown_parts .= ' and l.task_id = '.$options['task_id']; if ($options['billable']=='1') $dropdown_parts .= ' and l.billable = 1'; if ($options['billable']=='2') $dropdown_parts .= ' and l.billable = 0'; - if ($options['invoice']=='1') $dropdown_parts .= ' and l.invoice_id is not NULL'; - if ($options['invoice']=='2') $dropdown_parts .= ' and l.invoice_id is NULL'; + if ($options['invoice']=='1') $dropdown_parts .= ' and l.invoice_id is not null'; + if ($options['invoice']=='2') $dropdown_parts .= ' and l.invoice_id is null'; + if ($options['timesheet']=='1') $dropdown_parts .= ' and l.timesheet_id is not null'; + if ($options['timesheet']=='2') $dropdown_parts .= ' and l.timesheet_id is null'; if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; @@ -108,8 +110,10 @@ static function getExpenseWhere($options) { elseif ($user->isClient() && $user->client_id) $dropdown_parts .= ' and ei.client_id = '.$user->client_id; if ($options['project_id']) $dropdown_parts .= ' and ei.project_id = '.$options['project_id']; - if ($options['invoice']=='1') $dropdown_parts .= ' and ei.invoice_id is not NULL'; - if ($options['invoice']=='2') $dropdown_parts .= ' and ei.invoice_id is NULL'; + if ($options['invoice']=='1') $dropdown_parts .= ' and ei.invoice_id is not null'; + if ($options['invoice']=='2') $dropdown_parts .= ' and ei.invoice_id is null'; + if ($options['timesheet']=='1') $dropdown_parts .= ' and ei.timesheet_id is not null'; + if ($options['timesheet']=='2') $dropdown_parts .= ' and ei.timesheet_id is null'; if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; @@ -995,6 +999,7 @@ static function getReportOptions($bean) { $options['billable'] = $bean->getAttribute('include_records'); $options['invoice'] = $bean->getAttribute('invoice'); $options['paid_status'] = $bean->getAttribute('paid_status'); + $options['timesheet'] = $bean->getAttribute('timesheet'); if (is_array($bean->getAttribute('users'))) $options['users'] = join(',', $bean->getAttribute('users')); $options['period'] = $bean->getAttribute('period'); $options['period_start'] = $bean->getAttribute('start_date'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 951bba177..22f28353c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.37.4757 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4758 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 18ecb507a76c7960dd3d8d2c64264e1f4f4b8952 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 15:30:54 +0000 Subject: [PATCH 0700/1848] Added timesheet output to CSV, XML, and PDF reports. --- WEB-INF/templates/footer.tpl | 2 +- tofile.php | 3 +++ topdf.php | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 22f28353c..494d7e182 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- '; } if ($bean->getAttribute('chip')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chinvoice')) { $colspan++; $html .= ''; } + if ($bean->getAttribute('chtimesheet')) { $colspan++; $html .= ''; } $html .= ''; $html .= ''; @@ -211,6 +212,7 @@ if ($bean->getAttribute('chpaid')) $html .= ''; if ($bean->getAttribute('chip')) $html .= ''; if ($bean->getAttribute('chinvoice')) $html .= ''; + if ($bean->getAttribute('chtimesheet')) $html .= ''; $html .= ''; $html .= ''; } @@ -249,6 +251,7 @@ $html .= ''; } if ($bean->getAttribute('chinvoice')) $html .= ''; + if ($bean->getAttribute('chtimesheet')) $html .= ''; $html .= ''; $prev_date = $item['date']; @@ -300,6 +303,7 @@ if ($bean->getAttribute('chpaid')) $html .= ''; if ($bean->getAttribute('chip')) $html .= ''; if ($bean->getAttribute('chinvoice')) $html .= ''; + if ($bean->getAttribute('chtimesheet')) $html .= ''; $html .= ''; } @@ -328,6 +332,7 @@ if ($bean->getAttribute('chpaid')) $html .= ''; if ($bean->getAttribute('chip')) $html .= ''; if ($bean->getAttribute('chinvoice')) $html .= ''; + if ($bean->getAttribute('chtimesheet')) $html .= ''; $html .= ''; $html .= '
 Anuko Time Tracker 1.18.37.4758 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4759 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/tofile.php b/tofile.php index 3ddce979c..f4d5b29e8 100644 --- a/tofile.php +++ b/tofile.php @@ -146,6 +146,7 @@ print "\t\n"; } if ($bean->getAttribute('chinvoice')) print "\t\n"; + if ($bean->getAttribute('chtimesheet')) print "\t\n"; print "\n"; } @@ -209,6 +210,7 @@ if ($bean->getAttribute('chpaid')) print ',"'.$i18n->get('label.paid').'"'; if ($bean->getAttribute('chip')) print ',"'.$i18n->get('label.ip').'"'; if ($bean->getAttribute('chinvoice')) print ',"'.$i18n->get('label.invoice').'"'; + if ($bean->getAttribute('chtimesheet')) print ',"'.$i18n->get('label.timesheet').'"'; print "\n"; // Print items. @@ -241,6 +243,7 @@ print ',"'.$ip.'"'; } if ($bean->getAttribute('chinvoice')) print ',"'.str_replace('"','""',$item['invoice']).'"'; + if ($bean->getAttribute('chtimesheet')) print ',"'.str_replace('"','""',$item['timesheet_name']).'"'; print "\n"; } } diff --git a/topdf.php b/topdf.php index 181dec692..a0be19ec4 100644 --- a/topdf.php +++ b/topdf.php @@ -159,6 +159,7 @@ if ($bean->getAttribute('chpaid')) { $colspan++; $html .= "".$i18n->get('label.paid').'".$i18n->get('label.ip').''.$i18n->get('label.invoice').''.$i18n->get('label.timesheet').'
 
'.htmlspecialchars($item['invoice']).''.htmlspecialchars($item['timesheet_name']).'
'; } From 140a791657742bcc0f1692a11e1e8e25caac1620 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 15:51:48 +0000 Subject: [PATCH 0701/1848] Added 2 strings to translation files. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 4 +++- WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 62 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 4830b0e72..e303805ea 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -441,6 +441,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Seleccionar període de temps', 'form.reports.set_period' => 'o establir dates', 'form.reports.show_fields' => 'Mostrar camps', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 9cbdba5eb..e85a73971 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -451,6 +451,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Výberte období', 'form.reports.set_period' => 'nebo určete dny', 'form.reports.show_fields' => 'Zobrazit pole', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 1d39ffbf5..3946cd5cf 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -417,6 +417,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Vælg en periode', 'form.reports.set_period' => 'eller sæt datoer', 'form.reports.show_fields' => 'Vis felter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 6a967bd4b..3a10a7070 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -396,6 +396,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Zeitraum auswählen', 'form.reports.set_period' => 'oder Datum eingeben', 'form.reports.show_fields' => 'Felder anzeigen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 0534e60b0..4e6a8efa5 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -234,7 +234,7 @@ 'label.quota' => 'Quota', 'label.timesheet' => 'Timesheet', 'label.submitted' => 'Submitted', -'label.approved' => 'Approved', +'label.form' => 'Approved', // Form titles. 'title.error' => 'Error', @@ -392,6 +392,8 @@ 'form.reports.include_not_invoiced' => 'not invoiced', 'form.reports.include_assigned' => 'assigned', 'form.reports.include_not_assigned' => 'not assigned', +'form.reports.include_approved' => 'approved', +'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Select time period', 'form.reports.set_period' => 'or set dates', 'form.reports.show_fields' => 'Show fields', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 02d621541..87aff87cb 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -454,6 +454,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Seleccionar período de tiempo', 'form.reports.set_period' => 'o establecer fechas', 'form.reports.show_fields' => 'Mostrar campos', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index a5b4319c2..cf2151af7 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -421,6 +421,8 @@ // 'form.reports.include_not_invoiced' => 'arveldamata', // TODO: fix as per the above comment, if needed. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Vali ajaperiood', 'form.reports.set_period' => 'või märgi kuupäevad', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index e4983f402..1f4fd0ed4 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -437,6 +437,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'انتخاب بازه زمانی', 'form.reports.set_period' => 'یا تعیین تاریخ', 'form.reports.show_fields' => 'نمایش فیلدها', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 2dc50b616..442ce1570 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -422,6 +422,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Valitse ajanjakso', 'form.reports.set_period' => 'tai aseta päivät', 'form.reports.show_fields' => 'Näytä kentät', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a26bba753..37d0a0f45 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -414,6 +414,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Sélectionner la période de temps', 'form.reports.set_period' => 'ou dates indiquées', 'form.reports.show_fields' => 'Afficher les champs', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 0159ff293..ecaea1c15 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -405,6 +405,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Επιλογή χρονικής περιόδου', 'form.reports.set_period' => 'ή εύρος ημερομηνιών', 'form.reports.show_fields' => 'Εμφάνιση πεδίων', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index ab5d1b023..4c24586df 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -443,6 +443,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'בחר תקופת זמן', 'form.reports.set_period' => 'או הגדר תאריכים', 'form.reports.show_fields' => 'הראה שדות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 521b42e5f..50ba1b3e2 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -443,6 +443,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Jelölj meg egy időszakot', 'form.reports.set_period' => 'vagy állíts be konkrét dátumot', // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ca39ee64e..3a4777422 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -418,6 +418,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Seleziona il periodo di tempo', 'form.reports.set_period' => 'oppure setta le date', 'form.reports.show_fields' => 'Mostra i campi', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index f85d3ef14..55b8ee09d 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -449,6 +449,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '時間期間の選択', 'form.reports.set_period' => 'あるいは日付を設定', 'form.reports.show_fields' => 'フィールドの表示', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index ba9b4e021..d50f8170e 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -447,6 +447,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '시간 기간을 선택', 'form.reports.set_period' => '혹은 날짜를 설정', 'form.reports.show_fields' => '필드들을 보기', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index a416da5e3..8f4954052 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -392,6 +392,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Kies periode', 'form.reports.set_period' => 'of stel datums in', 'form.reports.show_fields' => 'Toon velden', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 3973be838..95bf5e2bf 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -447,6 +447,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Velg tidsperiode', 'form.reports.set_period' => 'eller sett dato', 'form.reports.show_fields' => 'Vis feltene', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 0b867ff34..2b63f06bd 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -425,6 +425,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Wybierz okres', 'form.reports.set_period' => 'lub ustaw daty', 'form.reports.show_fields' => 'Pokaż pola', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 3a48deccf..964c55d9b 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -420,6 +420,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 6ee9363b2..c51af296a 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -427,6 +427,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index f2bd2e956..2e1d2f273 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -450,6 +450,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Alege perioada', 'form.reports.set_period' => 'sau introdu intervalul de date', 'form.reports.show_fields' => 'Arata campuri', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index b30765a01..77c90653f 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -384,6 +384,8 @@ 'form.reports.include_not_invoiced' => 'не внесённые в счёт', 'form.reports.include_assigned' => 'присвоена', 'form.reports.include_not_assigned' => 'не присвоена', +'form.reports.include_approved' => 'одобрена', +'form.reports.include_not_approved' => 'не одобрена', 'form.reports.select_period' => 'Выберите интервал времени', 'form.reports.set_period' => 'или укажите даты', 'form.reports.show_fields' => 'Показывать поля', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index f6a0a0687..bd6202002 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -433,6 +433,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Vyberte časový rozsah', 'form.reports.set_period' => 'alebo nastavte dátumy', 'form.reports.show_fields' => 'Zobraziť polia', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 0e602e426..66992c49b 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -424,6 +424,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', // 'form.reports.select_period' => 'Select time period', // 'form.reports.set_period' => 'or set dates', // 'form.reports.show_fields' => 'Show fields', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index cfc2dac50..73966ca86 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -423,6 +423,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Odaberi vremenski raspon', 'form.reports.set_period' => 'ili podesi datum', 'form.reports.show_fields' => 'Prikaži polja u izveštaju', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 24072b0e8..410a64f5c 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -421,6 +421,8 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Välj intervall', 'form.reports.set_period' => 'eller ställ in datum', 'form.reports.show_fields' => 'Visa fält', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index cccf336c2..e5387283e 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -460,6 +460,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Zaman aralığını seç', 'form.reports.set_period' => 'ya da tarihleri belirle', 'form.reports.show_fields' => 'Alanları göster', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 6f4f6389f..4406831d8 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -432,6 +432,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '选择时间段', 'form.reports.set_period' => '或设定日期', 'form.reports.show_fields' => '显示栏目', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 49bfb85da..47d2cfbc6 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -440,6 +440,8 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_approved' => 'approved', +// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '選擇時間段', 'form.reports.set_period' => '或設定日期', 'form.reports.show_fields' => '顯示欄目', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 494d7e182..7bd156421 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + - + {/if} +{if isTrue('FILTER_BY_NOTES_DEBUG')} + + + + + + +{/if}
 Anuko Time Tracker 1.18.37.4759 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4760 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a4a45a19de0987b40ea0452fea3cd50647756a22 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 18:45:44 +0000 Subject: [PATCH 0702/1848] Some more work in progress on timesheet reporting. --- WEB-INF/lib/ttReportHelper.class.php | 78 +++++++++++++++++++++++----- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 3 +- WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- reports.php | 6 ++- 33 files changed, 103 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index c96f0f4dc..a14313b35 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -33,6 +33,14 @@ require_once(dirname(__FILE__).'/../../plugins/CustomFields.class.php'); +// Definitions of types for timesheet dropdown. +define('TIMESHEET_ALL', 0); // Include all records. +define('TIMESHEET_NOT_ASSIGNED', 1); // Include records not assigned to timesheets. +define('TIMESHEET_ASSIGNED', 2); // Include records assigned to timesheets. +define('TIMESHEET_PENDING', 3); // Include records in submitted timesheets that are pending manager approval. +define('TIMESHEET_APPROVED', 4); // Include records in approved timesheets. +define('TIMESHEET_NOT_APPROVED', 5); // Include records in disapproved timesheets. + // Class ttReportHelper is used for help with reports. class ttReportHelper { @@ -62,8 +70,8 @@ static function getWhere($options) { if ($options['billable']=='2') $dropdown_parts .= ' and l.billable = 0'; if ($options['invoice']=='1') $dropdown_parts .= ' and l.invoice_id is not null'; if ($options['invoice']=='2') $dropdown_parts .= ' and l.invoice_id is null'; - if ($options['timesheet']=='1') $dropdown_parts .= ' and l.timesheet_id is not null'; - if ($options['timesheet']=='2') $dropdown_parts .= ' and l.timesheet_id is null'; + if ($options['timesheet']==TIMESHEET_NOT_ASSIGNED) $dropdown_parts .= ' and l.timesheet_id is null'; + if ($options['timesheet']==TIMESHEET_ASSIGNED) $dropdown_parts .= ' and l.timesheet_id is not null'; if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; @@ -112,8 +120,8 @@ static function getExpenseWhere($options) { if ($options['project_id']) $dropdown_parts .= ' and ei.project_id = '.$options['project_id']; if ($options['invoice']=='1') $dropdown_parts .= ' and ei.invoice_id is not null'; if ($options['invoice']=='2') $dropdown_parts .= ' and ei.invoice_id is null'; - if ($options['timesheet']=='1') $dropdown_parts .= ' and ei.timesheet_id is not null'; - if ($options['timesheet']=='2') $dropdown_parts .= ' and ei.timesheet_id is null'; + if ($options['timesheet']==TIMESHEET_NOT_ASSIGNED) $dropdown_parts .= ' and ei.timesheet_id is null'; + if ($options['timesheet']==TIMESHEET_ASSIGNED) $dropdown_parts .= ' and ei.timesheet_id is not null'; if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; @@ -264,13 +272,25 @@ static function getItems($options) { } if ($includeCost && MODE_TIME != $trackingMode) $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; - if ($options['show_timesheet']) - $left_joins .= " left join tt_timesheets ts on (l.timesheet_id = ts.id)"; + + // Prepare sql query part for inner joins. + $inner_joins = null; + if ($user->isPluginEnabled('ts')) { + $timesheet_option = $options['timesheet']; + if ($timesheet_option == TIMESHEET_PENDING) + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + else if ($timesheet_option == TIMESHEET_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 1)"; + else if ($timesheet_option == TIMESHEET_NOT_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 0)"; + else if ($options['show_timesheet']) + $inner_joins .= " left join tt_timesheets ts on (l.timesheet_id = ts.id)"; // Left join for timesheet nme. + } $where = ttReportHelper::getWhere($options); // Construct sql query for tt_log items. - $sql = "select ".join(', ', $fields)." from tt_log l $left_joins $where"; + $sql = "select ".join(', ', $fields)." from tt_log l $left_joins $inner_joins $where"; // If we don't have expense items (such as when the Expenses plugin is disabled), the above is all sql we need, // with an exception of sorting part, that is added in the end. @@ -335,13 +355,25 @@ static function getItems($options) { $left_joins .= " left join tt_projects p on (p.id = ei.project_id)"; if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; - if ($options['show_timesheet']) - $left_joins .= " left join tt_timesheets ts on (ei.timesheet_id = ts.id)"; + + // Prepare sql query part for inner joins. + $inner_joins = null; + if ($user->isPluginEnabled('ts')) { + $timesheet_option = $options['timesheet']; + if ($timesheet_option == TIMESHEET_PENDING) + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + else if ($timesheet_option == TIMESHEET_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 1)"; + else if ($timesheet_option == TIMESHEET_NOT_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 0)"; + else if ($options['show_timesheet']) + $inner_joins .= " left join tt_timesheets ts on (ei.timesheet_id = ts.id)"; // Left join for timesheet name. + } $where = ttReportHelper::getExpenseWhere($options); // Construct sql query for expense items. - $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $where"; + $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $inner_joins $where"; // Construct a union. $sql = "($sql) union all ($sql_for_expense_items)"; @@ -519,15 +551,37 @@ static function getTotals($options) $left_joins = "left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; } } + // Prepare sql query part for inner joins. + $inner_joins = null; + if ($user->isPluginEnabled('ts') && $options['timesheet']) { + $timesheet_option = $options['timesheet']; + if ($timesheet_option == TIMESHEET_PENDING) + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + else if ($timesheet_option == TIMESHEET_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 1)"; + else if ($timesheet_option == TIMESHEET_NOT_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 0)"; + } // Prepare a query for time items. - $sql = "select $time_part $units_part $cost_part from tt_log l $left_joins $where"; + $sql = "select $time_part $units_part $cost_part from tt_log l $left_joins $inner_joins $where"; // If we have expenses, query becomes a bit more complex. if ($options['show_cost'] && $user->isPluginEnabled('ex')) { + // Prepare sql query part for inner joins. + $inner_joins = null; + if ($user->isPluginEnabled('ts') && $options['timesheet']) { + $timesheet_option = $options['timesheet']; + if ($timesheet_option == TIMESHEET_PENDING) + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + else if ($timesheet_option == TIMESHEET_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 1)"; + else if ($timesheet_option == TIMESHEET_NOT_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 0)"; + } $where = ttReportHelper::getExpenseWhere($options); $sql_for_expenses = "select null as time"; if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; - $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; + $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $inner_joins $where"; // Create a combined query. $combined = "select sum(time) as time"; diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index e303805ea..8b3d5d6f7 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -441,6 +441,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Seleccionar període de temps', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index e85a73971..17ea3e261 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -451,6 +451,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Výberte období', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 3946cd5cf..2a786b143 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -417,6 +417,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Vælg en periode', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 3a10a7070..5e72116ba 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -396,6 +396,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Zeitraum auswählen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 4e6a8efa5..1fdd6111a 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -234,7 +234,7 @@ 'label.quota' => 'Quota', 'label.timesheet' => 'Timesheet', 'label.submitted' => 'Submitted', -'label.form' => 'Approved', +'label.approved' => 'Approved', // Form titles. 'title.error' => 'Error', @@ -392,6 +392,7 @@ 'form.reports.include_not_invoiced' => 'not invoiced', 'form.reports.include_assigned' => 'assigned', 'form.reports.include_not_assigned' => 'not assigned', +'form.reports.include_pending' => 'pending', 'form.reports.include_approved' => 'approved', 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Select time period', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 87aff87cb..559e3286c 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -454,6 +454,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Seleccionar período de tiempo', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index cf2151af7..71a1288c5 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -421,6 +421,7 @@ // 'form.reports.include_not_invoiced' => 'arveldamata', // TODO: fix as per the above comment, if needed. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 1f4fd0ed4..b5bed52c6 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -437,6 +437,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'انتخاب بازه زمانی', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 442ce1570..c10ca5ea1 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -422,6 +422,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Valitse ajanjakso', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 37d0a0f45..b937b771b 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -414,6 +414,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Sélectionner la période de temps', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index ecaea1c15..c5e8d5e86 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -405,6 +405,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Επιλογή χρονικής περιόδου', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 4c24586df..b2a7dfd1c 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -443,6 +443,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'בחר תקופת זמן', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 50ba1b3e2..f6bceaeeb 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -443,6 +443,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Jelölj meg egy időszakot', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 3a4777422..fc8a08157 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -418,6 +418,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Seleziona il periodo di tempo', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 55b8ee09d..7f83a7677 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -449,6 +449,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '時間期間の選択', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index d50f8170e..aa40a0945 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -447,6 +447,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '시간 기간을 선택', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 8f4954052..ee170ceed 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -392,6 +392,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Kies periode', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 95bf5e2bf..e43dad9b4 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -447,6 +447,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Velg tidsperiode', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 2b63f06bd..9b243eefa 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -425,6 +425,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Wybierz okres', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 964c55d9b..71fcef6f9 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -420,6 +420,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Selecione o período de tempo', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index c51af296a..0723acffa 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -427,6 +427,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Selecione o período de tempo', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 2e1d2f273..b94bcd988 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -450,6 +450,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Alege perioada', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 77c90653f..19bedf9b4 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -384,6 +384,7 @@ 'form.reports.include_not_invoiced' => 'не внесённые в счёт', 'form.reports.include_assigned' => 'присвоена', 'form.reports.include_not_assigned' => 'не присвоена', +'form.reports.include_pending' => 'в ожидании', 'form.reports.include_approved' => 'одобрена', 'form.reports.include_not_approved' => 'не одобрена', 'form.reports.select_period' => 'Выберите интервал времени', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index bd6202002..d3525c0d6 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -433,6 +433,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Vyberte časový rozsah', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 66992c49b..fedc796ab 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -424,6 +424,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', // 'form.reports.select_period' => 'Select time period', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 73966ca86..229100788 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -423,6 +423,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Odaberi vremenski raspon', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 410a64f5c..480650e4a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -421,6 +421,7 @@ // TODO: translate the following. // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Välj intervall', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index e5387283e..87b44ca09 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -460,6 +460,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Zaman aralığını seç', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 4406831d8..9d03e7b0f 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -432,6 +432,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '选择时间段', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 47d2cfbc6..e488dbd68 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -440,6 +440,7 @@ // 'form.reports.include_not_invoiced' => 'not invoiced', // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', +// 'form.reports.include_pending' => 'pending', // 'form.reports.include_approved' => 'approved', // 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '選擇時間段', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7bd156421..b8f56833c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- -{if constant('2FA_DEBUG')} @@ -51,7 +50,6 @@ License: See license.txt *} {$i18n.label.what_is_it} -{/if} diff --git a/initialize.php b/initialize.php index d56c43b36..f3138065a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.2.5667"); +define("APP_VERSION", "1.21.2.5668"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/login.php b/login.php index a097c8883..69377fed2 100644 --- a/login.php +++ b/login.php @@ -43,8 +43,12 @@ // Check user login. $loginSucceeded = $auth->doLogin($cl_login, $cl_password); - if (!$loginSucceeded) + if ($loginSucceeded) { + // Remember user login in a cookie. + setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); + } else { $err->add($i18n->get('error.auth')); + } } // Do we have to use 2FA? @@ -114,9 +118,6 @@ if ($current_user_date) $_SESSION['date'] = $current_user_date; - // Remember user login in a cookie. - setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); - // Redirect, depending on user role. if ($user->can('administer_site')) { header('Location: admin_groups.php'); From e4f35b788164da94bbbdbb9f376d9e3ee970ed1a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 19 Mar 2022 14:16:55 +0000 Subject: [PATCH 1694/1848] Starting work on allowing multiple uncompleted entries. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/group_edit.tpl | 11 +++++++++++ group_edit.php | 6 ++++++ initialize.php | 2 +- 33 files changed, 53 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 5db492323..8b3182047 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -593,6 +593,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index c689bafbc..fd4ba142b 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -605,6 +605,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index e2a0da44e..4e41f9dd3 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -571,6 +571,7 @@ 'form.group_edit.type_duration' => 'Varighed', // TODO: translate the following. // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', 'form.group_edit.uncompleted_indicators' => 'Uafsluttede indikatore', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 10c6cba46..989afc571 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -546,6 +546,8 @@ 'form.group_edit.type_start_finish' => 'Start und Ende', 'form.group_edit.type_duration' => 'Dauer', 'form.group_edit.punch_mode' => 'Stechuhr-Modus', +// TODO: translate the following. +// 'form.group_edit.one_uncompleted' => 'One uncompleted', 'form.group_edit.allow_overlap' => 'Erlaube Überschneidung', 'form.group_edit.future_entries' => 'Einträge in der Zukunft', 'form.group_edit.uncompleted_indicators' => 'Zeige unfertige Einträge', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index fb31f0f85..576be5b97 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -526,6 +526,7 @@ 'form.group_edit.type_start_finish' => 'start and finish', 'form.group_edit.type_duration' => 'duration', 'form.group_edit.punch_mode' => 'Punch mode', +'form.group_edit.one_uncompleted' => 'One uncompleted', 'form.group_edit.allow_overlap' => 'Allow overlap', 'form.group_edit.future_entries' => 'Future entries', 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index bbb923fd3..3f815af04 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -607,6 +607,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index e698f9391..76417e948 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -580,6 +580,8 @@ 'form.group_edit.type_start_finish' => 'algus ja lõpp', 'form.group_edit.type_duration' => 'vahemik', 'form.group_edit.punch_mode' => 'Kellast-kellani režiim', +// TODO: translate the following. +// 'form.group_edit.one_uncompleted' => 'One uncompleted', 'form.group_edit.allow_overlap' => 'Luba ajaline ülekate', 'form.group_edit.future_entries' => 'Tuleviku kirjed', 'form.group_edit.uncompleted_indicators' => 'Lõpetamata kirjete indikaator', // TODO: Fix this. Indicators (plural), not indicator. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 7a2e8fbca..d4a52de89 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -594,6 +594,7 @@ 'form.group_edit.type_duration' => 'مدت زمان', // TODO: translate the following. // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 4b6a1832d..d4850d85f 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -578,6 +578,7 @@ 'form.group_edit.type_duration' => 'kesto', // TODO: translate the following. // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index b6d170271..7d2bb08cc 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -568,6 +568,7 @@ 'form.group_edit.type_duration' => 'Durée', // TODO: translate the following. // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index a7eec7329..222c98b05 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -558,6 +558,8 @@ 'form.group_edit.type_start_finish' => 'αρχή και τέλος', 'form.group_edit.type_duration' => 'διάρκεια', 'form.group_edit.punch_mode' => 'Λειτουργία διάτρησης', +// TODO: translate the following. +// 'form.group_edit.one_uncompleted' => 'One uncompleted', 'form.group_edit.allow_overlap' => 'Επικάλυψη επιτρεπτή', 'form.group_edit.future_entries' => 'Μελλοντικές καταχωρήσεις', 'form.group_edit.uncompleted_indicators' => 'Μη ολοκληρωμένες ενδείξεις', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index e4ebe5198..450fa5859 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -598,6 +598,7 @@ 'form.group_edit.type_duration' => 'משך זמן', // TODO: translate the following. // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 7c761eec5..3b4069a31 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -597,6 +597,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index a873bb477..d1925e638 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -573,6 +573,7 @@ 'form.group_edit.type_duration' => 'durata', // TODO: translate the following. // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', 'form.group_edit.uncompleted_indicators' => 'Indicatori incompleti', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 9d5807078..602427b16 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -600,6 +600,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 59222f086..2200b7080 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -598,6 +598,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 6503da028..497d941ef 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -516,6 +516,8 @@ 'form.group_edit.type_start_finish' => 'begin en einde', 'form.group_edit.type_duration' => 'duur', 'form.group_edit.punch_mode' => 'Start/stop modus', +// TODO: translate the following. +// 'form.group_edit.one_uncompleted' => 'One uncompleted', 'form.group_edit.allow_overlap' => 'Sta overlapping van tijden toe', 'form.group_edit.future_entries' => 'Toevoegingen toestaan in de toekomst', 'form.group_edit.uncompleted_indicators' => 'Onvolledige indicatoren', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 255495601..f45cbf120 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -600,6 +600,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 3a91e417d..e6bf9b24d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -580,6 +580,7 @@ 'form.group_edit.type_duration' => 'czas trwania', // TODO: translate the following. // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index af1c6e943..36a20c20b 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -514,6 +514,8 @@ 'form.group_edit.type_start_finish' => 'início e fim', 'form.group_edit.type_duration' => 'duração', 'form.group_edit.punch_mode' => 'Modo punch', +// TODO: translate the following. +// 'form.group_edit.one_uncompleted' => 'One uncompleted', 'form.group_edit.allow_overlap' => 'Permitir sobreposição', 'form.group_edit.future_entries' => 'Entradas futuros', 'form.group_edit.uncompleted_indicators' => 'Indicadores incompletos', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 8b915d4db..5def67598 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -578,6 +578,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 5f267efa1..05e6fe5a7 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -601,6 +601,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index c64c8e9c4..2fbe0dfbe 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -513,6 +513,7 @@ 'form.group_edit.type_start_finish' => 'начало и конец', 'form.group_edit.type_duration' => 'длительность', 'form.group_edit.punch_mode' => 'Пробивать время', +'form.group_edit.one_uncompleted' => 'Одна незавершённая', 'form.group_edit.allow_overlap' => 'Возможное перекрывание', 'form.group_edit.future_entries' => 'Будущие записи', 'form.group_edit.uncompleted_indicators' => 'Индикаторы незавершения', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 98d429610..440944c78 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -584,6 +584,7 @@ 'form.group_edit.type_duration' => 'trvanie', // TODO: translate the following. // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 0f757c7d2..7ad63d0ec 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -574,6 +574,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 60c504ca0..1fc9691fb 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -580,6 +580,7 @@ 'form.group_edit.type_duration' => 'trajanje', // TODO: translate the following. // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 06e7f46af..f3a943154 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -577,6 +577,7 @@ 'form.group_edit.type_duration' => 'Varaktighet', // TODO: translate the following. // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', 'form.group_edit.uncompleted_indicators' => 'Indikatorer för oavslutad registrering', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 9d8ef4111..b8763bf2c 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -614,6 +614,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 1a91e596f..4c797a3c5 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -589,6 +589,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 0a2f8510c..1cf542d9e 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -592,6 +592,7 @@ // 'form.group_edit.type_start_finish' => 'start and finish', // 'form.group_edit.type_duration' => 'duration', // 'form.group_edit.punch_mode' => 'Punch mode', +// 'form.group_edit.one_uncompleted' => 'One uncompleted', // 'form.group_edit.allow_overlap' => 'Allow overlap', // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index 05a134dd9..673af5e23 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -110,6 +110,17 @@ function chLocation(newLocation) { document.location = newLocation; } {$i18n.label.what_is_it} +{if constant('ONE_UNCOMPLETED_DEBUG')} + + + + + + +{/if} diff --git a/group_edit.php b/group_edit.php index ab3065d52..dbfca56bb 100644 --- a/group_edit.php +++ b/group_edit.php @@ -66,6 +66,7 @@ $cl_project_required = $request->getParameter('project_required'); $cl_record_type = $request->getParameter('record_type'); $cl_punch_mode = (bool)$request->getParameter('punch_mode'); + $cl_one_uncompleted = (bool)$request->getParameter('one_uncompleted'); $cl_allow_overlap = (bool)$request->getParameter('allow_overlap'); $cl_future_entries = (bool)$request->getParameter('future_entries'); $cl_uncompleted_indicators = (bool)$request->getParameter('uncompleted_indicators'); @@ -82,6 +83,7 @@ $cl_project_required = $group['project_required']; $cl_record_type = $group['record_type']; $cl_punch_mode = $config->getDefinedValue('punch_mode'); + $cl_one_uncompleted = $config->getDefinedValue('one_uncompleted'); $cl_allow_overlap = $config->getDefinedValue('allow_overlap'); $cl_future_entries = $config->getDefinedValue('future_entries'); $cl_uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators'); @@ -166,6 +168,9 @@ // Punch mode checkbox. $form->addInput(array('type'=>'checkbox','name'=>'punch_mode','value'=>$cl_punch_mode)); +// One uncompleted. +$form->addInput(array('type'=>'checkbox','name'=>'one_uncompleted','value'=>$cl_one_uncompleted)); + // Allow overlap checkbox. $form->addInput(array('type'=>'checkbox','name'=>'allow_overlap','value'=>$cl_allow_overlap)); @@ -200,6 +205,7 @@ if ($err->no()) { // Update config. $config->setDefinedValue('punch_mode', $cl_punch_mode); + $config->setDefinedValue('one_uncompleted', $cl_one_uncompleted); $config->setDefinedValue('allow_overlap', $cl_allow_overlap); $config->setDefinedValue('future_entries', $cl_future_entries); $config->setDefinedValue('uncompleted_indicators', $cl_uncompleted_indicators); diff --git a/initialize.php b/initialize.php index f3138065a..0295c2bc6 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.2.5668"); +define("APP_VERSION", "1.21.2.5669"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 630f9ded901a89ccdf665405bf708961540eb6d3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 20 Mar 2022 15:25:17 +0000 Subject: [PATCH 1695/1848] Implemented multiple uncompleted entries with config option. --- WEB-INF/lib/ttTimeHelper.class.php | 44 ++++++++++++++++++++++++++---- WEB-INF/templates/group_edit.tpl | 2 -- WEB-INF/templates/puncher.tpl | 6 ++-- WEB-INF/templates/time.tpl | 6 ---- WEB-INF/templates/time_script.tpl | 16 +++++++++++ initialize.php | 2 +- puncher.php | 20 ++++++++------ time.php | 4 ++- time_edit.php | 4 ++- 9 files changed, 77 insertions(+), 27 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index b45c6d17f..fa110fa40 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -449,7 +449,6 @@ static function insert($fields) } else { $duration = ttTimeHelper::toDuration($start, $finish); if ($duration === false) $duration = 0; - if (!$duration && ttTimeHelper::getUncompleted($user_id)) return false; $sql = "insert into tt_log (user_id, group_id, org_id, date, start, duration, client_id, project_id, task_id, invoice_id, comment, billable, paid, created, created_ip, created_by) ". "values ($user_id, $group_id, $org_id, ".$mdb2->quote($date).", '$start', '$duration', ".$mdb2->quote($client).", ".$mdb2->quote($project).", ".$mdb2->quote($task).", ".$mdb2->quote($invoice).", ".$mdb2->quote($note).", $billable, $paid $created_v)"; @@ -512,9 +511,9 @@ static function update($fields) $duration = ttTimeHelper::toDuration($start, $finish); if ($duration === false) $duration = 0; - $uncompleted = ttTimeHelper::getUncompleted($user_id); - if (!$duration && $uncompleted && ($uncompleted['id'] != $id)) - return false; + //$uncompleted = ttTimeHelper::getUncompleted($user_id); + //if (!$duration && $uncompleted && ($uncompleted['id'] != $id)) +// return false; $sql = "UPDATE tt_log SET start = '$start', duration = '$duration', client_id = ".$mdb2->quote($client).", project_id = ".$mdb2->quote($project).", task_id = ".$mdb2->quote($task).", ". "comment = ".$mdb2->quote($note)."$billable_part $paid_part $modified_part, date = '$date' WHERE id = $id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; @@ -673,10 +672,43 @@ static function getTimeForMonth2($date) { // getUncompleted - retrieves an uncompleted record for user, if one exists. static function getUncompleted($user_id) { + + global $user; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $mdb2 = getConnection(); + + $sql = "select id, start, date from tt_log". + " where user_id = $user_id and start is not null and time_to_sec(duration) = 0 and status = 1". + " and group_id = $group_id and org_id = $org_id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + if (!$res->numRows()) { + return false; + } + if ($val = $res->fetchRow()) { + return $val; + } + } + return false; + } + + // getFirstUncompletedForDate - retrieves first found uncompleted record for user for a specific date, if one exists. + static function getFirstUncompletedForDate($user_id, $date) { + + $user_id = (int) $user_id; // Protection against sql injection. + + global $user; + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $mdb2 = getConnection(); $sql = "select id, start, date from tt_log". - " where user_id = $user_id and start is not null and time_to_sec(duration) = 0 and status = 1"; + " where user_id = $user_id and start is not null and time_to_sec(duration) = 0 and status = 1". + " and group_id = $group_id and org_id = $org_id and date = ".$mdb2->quote($date). + " order by start"; // Ordering by start time to get the eraliest uncompleted for date. $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if (!$res->numRows()) { @@ -740,6 +772,8 @@ static function overlaps($user_id, $date, $start, $finish, $record_id = null) { // getRecord - retrieves a time record identified by its id. static function getRecord($id) { global $user; + + $id = (int) $id; // Protection against sql injections. $user_id = $user->getUser(); $group_id = $user->getGroup(); diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index 673af5e23..909b485e6 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -110,7 +110,6 @@ function chLocation(newLocation) { document.location = newLocation; } {$i18n.label.what_is_it} -{if constant('ONE_UNCOMPLETED_DEBUG')} @@ -120,7 +119,6 @@ function chLocation(newLocation) { document.location = newLocation; } {$i18n.label.what_is_it} -{/if} diff --git a/WEB-INF/templates/puncher.tpl b/WEB-INF/templates/puncher.tpl index 8060c2ff5..9190af396 100644 --- a/WEB-INF/templates/puncher.tpl +++ b/WEB-INF/templates/puncher.tpl @@ -48,11 +48,11 @@ function stopTimer() { } -{if $uncompleted} +{if $uncompleted_today} + {if $show_navigation}
{$i18n.label.day_view} @@ -113,6 +121,9 @@ License: See license.txt *}
 Anuko Time Tracker 1.18.37.4760 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4761 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 264e5645c..f652027b1 100644 --- a/reports.php +++ b/reports.php @@ -186,7 +186,11 @@ $form->addInput(array('type'=>'combobox', 'name'=>'timesheet', 'style'=>'width: 250px;', - 'data'=>array('1'=>$i18n->get('form.reports.include_assigned'),'2'=>$i18n->get('form.reports.include_not_assigned')), + 'data'=>array(TIMESHEET_NOT_ASSIGNED=>$i18n->get('form.reports.include_not_assigned'), + TIMESHEET_ASSIGNED=>$i18n->get('form.reports.include_assigned'), + TIMESHEET_PENDING=>$i18n->get('form.reports.include_pending'), + TIMESHEET_APPROVED=>$i18n->get('form.reports.include_approved'), + TIMESHEET_NOT_APPROVED=>$i18n->get('form.reports.include_not_approved')), 'empty'=>array(''=>$i18n->get('dropdown.all')) )); } From da69449d0d9100e8603a88e36f0882d6798215e9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 19:23:47 +0000 Subject: [PATCH 0703/1848] Fixed subtotals for timesheet options. --- WEB-INF/lib/ttReportHelper.class.php | 26 ++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index a14313b35..441cbec9b 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1546,6 +1546,18 @@ static function makeJoinPart($options) { if ($options['show_cost'] && $trackingMode != MODE_TIME) { $join .= ' left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)'; } + // Prepare inner joins. + $inner_joins = null; + if ($user->isPluginEnabled('ts') && $options['timesheet']) { + $timesheet_option = $options['timesheet']; + if ($timesheet_option == TIMESHEET_PENDING) + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + else if ($timesheet_option == TIMESHEET_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 1)"; + else if ($timesheet_option == TIMESHEET_NOT_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 0)"; + } + $join .= $inner_joins; return $join; } @@ -1581,6 +1593,8 @@ static function makeCostPart($options) { // makeJoinExpensesPart builds a left join part for getSubtotals query for expense items. static function makeJoinExpensesPart($options) { + global $user; + if (ttReportHelper::groupingBy('user', $options)) { $join .= ' left join tt_users u on (ei.user_id = u.id)'; } @@ -1590,6 +1604,18 @@ static function makeJoinExpensesPart($options) { if (ttReportHelper::groupingBy('project', $options)) { $join .= ' left join tt_projects p on (ei.project_id = p.id)'; } + // Prepare inner joins. + $inner_joins = null; + if ($user->isPluginEnabled('ts') && $options['timesheet']) { + $timesheet_option = $options['timesheet']; + if ($timesheet_option == TIMESHEET_PENDING) + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + else if ($timesheet_option == TIMESHEET_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 1)"; + else if ($timesheet_option == TIMESHEET_NOT_APPROVED) + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 0)"; + } + $join .= $inner_joins; return $join; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b8f56833c..9677eea8a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.37.4761 | Copyright © Anuko | +  Anuko Time Tracker 1.18.37.4762 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c71ac60a3c6913ad64b22f367b994983ff77ca22 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 21:47:45 +0000 Subject: [PATCH 0704/1848] Introduced view_client_unapproved access right. --- WEB-INF/lib/ttRoleHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 4 ++-- dbinstall.php | 10 ++++++---- mysql.sql | 4 ++-- reports.php | 16 ++++++++++------ 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 000f7cebe..92f6bec32 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -189,7 +189,7 @@ static function createPredefinedRoles($group_id, $lang) $mdb2 = getConnection(); - $rights_client = 'view_client_reports,view_client_timesheets,view_client_invoices,manage_own_settings'; + $rights_client = 'view_client_reports,view_client_timesheets,view_client_unapproved,view_client_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9677eea8a..d0cc37fdd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} -{if $show_timesheet} +{if $show_timesheet_dropdown} {/if} @@ -259,7 +259,7 @@ function handleCheckboxes() { {if $show_project} {/if} -{if $show_timesheet} +{if $show_timesheet_checkbox} {/if} {if $show_cf_1_checkbox} diff --git a/dbinstall.php b/dbinstall.php index e40d4be67..f700d99ee 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11840"]) { + if ($_POST["convert11797to11841"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1083,6 +1083,8 @@ function ttExecute($sql) { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_timesheets', 'view_client_timesheets') where rank = 16"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_invoices', 'view_client_invoices') where rank = 16"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.40', modified = now() where param_name = 'version_db' and param_value = '1.18.39'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.40') set rights = replace(rights, 'view_client_timesheets,view_client_invoices', 'view_client_timesheets,view_client_unapproved,view_client_invoices') where rank = 16"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.41', modified = now() where param_name = 'version_db' and param_value = '1.18.40'"); } if ($_POST["cleanup"]) { @@ -1131,7 +1133,7 @@ function ttExecute($sql) {

DB Install

 Anuko Time Tracker 1.18.37.4762 | Copyright © Anuko | +  Anuko Time Tracker 1.18.41.4763 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 821352782..07c398346 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -216,7 +216,7 @@ function handleCheckboxes() {
{$i18n.label.invoice}
{$forms.reportForm.invoice.control}
{$i18n.label.timesheet}
{$forms.reportForm.timesheet.control}
-
Create database structure (v1.18.40) + Create database structure (v1.18.41)
(applies only to new installations, do not execute when updating)
@@ -1176,8 +1178,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.40)Update database structure (v1.17.97 to v1.18.41)
diff --git a/mysql.sql b/mysql.sql index 0218cf750..2a507ee21 100644 --- a/mysql.sql +++ b/mysql.sql @@ -75,7 +75,7 @@ create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_unapproved,view_client_invoices,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group'); # @@ -518,4 +518,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.40', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.41', now()); # TODO: change when structure changes. diff --git a/reports.php b/reports.php index f652027b1..fdb2d2ed3 100644 --- a/reports.php +++ b/reports.php @@ -179,10 +179,10 @@ } // Add timesheet assignment selector. -$showTimesheet = $user->isPluginEnabled('ts') && +$showTimesheetDropdown = $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('view_timesheets') || - $user->can('view_all_timesheets') || $user->can('view_client_timesheets')); -if ($showTimesheet) { + $user->can('view_all_timesheets') || ($user->can('view_client_timesheets') && $user->can('view_client_unapproved'))); +if ($showTimesheetDropdown) { $form->addInput(array('type'=>'combobox', 'name'=>'timesheet', 'style'=>'width: 250px;', @@ -194,6 +194,9 @@ 'empty'=>array(''=>$i18n->get('dropdown.all')) )); } +$showTimesheetCheckbox = $user->isPluginEnabled('ts') && + ($user->can('view_own_timesheets') || $user->can('view_timesheets') || + $user->can('view_all_timesheets') || $user->can('view_client_timesheets')); // Add user table. $showUsers = $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient(); @@ -274,11 +277,11 @@ $showWorkUnits = $user->isPluginEnabled('wu'); if ($showWorkUnits) $form->addInput(array('type'=>'checkbox','name'=>'chunits')); -if ($showTimesheet) +if ($showTimesheetCheckbox) $form->addInput(array('type'=>'checkbox','name'=>'chtimesheet')); // Add a hidden control for timesheet_user_id (who to generate a timesheet for). -if ($showTimesheet) +if ($showTimesheetCheckbox) $form->addInput(array('type'=>'hidden','name'=>'timesheet_user_id')); // Add group by control. @@ -428,7 +431,8 @@ $smarty->assign('show_invoice_dropdown', $showInvoiceDropdown); $smarty->assign('show_invoice_checkbox', $showInvoiceCheckbox); $smarty->assign('show_paid_status', $showPaidStatus); -$smarty->assign('show_timesheet', $showTimesheet); +$smarty->assign('show_timesheet_dropdown', $showTimesheetDropdown); +$smarty->assign('show_timesheet_checkbox', $showTimesheetCheckbox); $smarty->assign('show_users', $showUsers); $smarty->assign('show_start', $showStart); $smarty->assign('show_finish', $showFinish); From a6f6687b468a81a0f96c108faefbfc69dd607acf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 22:02:58 +0000 Subject: [PATCH 0705/1848] Adjusted client access to unapproved records. --- WEB-INF/lib/ttReportHelper.class.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 441cbec9b..ac3582e68 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1054,6 +1054,8 @@ static function getReportOptions($bean) { $options['invoice'] = $bean->getAttribute('invoice'); $options['paid_status'] = $bean->getAttribute('paid_status'); $options['timesheet'] = $bean->getAttribute('timesheet'); + if ($user->isPluginEnabled('ts') && $user->isClient() && !$user->can('view_client_unapproved')) + $options['timesheet'] = TIMESHEET_APPROVED; // Restrict clients to approved timesheet records only. if (is_array($bean->getAttribute('users'))) $options['users'] = join(',', $bean->getAttribute('users')); $options['period'] = $bean->getAttribute('period'); $options['period_start'] = $bean->getAttribute('start_date'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d0cc37fdd..a0366229d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.41.4763 | Copyright © Anuko | +  Anuko Time Tracker 1.18.41.4764 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b14cf15f563feabc7015e3af99ea8cb7a1903dc1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 22:21:48 +0000 Subject: [PATCH 0706/1848] Fixed ttTimesheetHelper::getApprovers function. --- WEB-INF/lib/ttTimesheetHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 21e75a96d..058326574 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -336,7 +336,7 @@ static function getApprovers($user_id) { $sql = "select u.id, u.name, u.email". " from tt_users u". " left join tt_roles r on (r.id = u.role_id)". - " where u.status = 1 and u.email is not null". + " where u.status = 1 and u.email is not null and u.group_id = $group_id and u.org_id = $org_id". " and (r.rights like '%approve_all_timesheets%' or (r.rank > $rank and r.rights like '%approve_timesheets%'))"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a0366229d..63d61ef93 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +{if constant('PASSWORD_COMPLEXITY_DEBUG')} + + + + + + +{/if} diff --git a/group_advanced_edit.php b/group_advanced_edit.php index d08017576..a950b8d22 100644 --- a/group_advanced_edit.php +++ b/group_advanced_edit.php @@ -22,11 +22,13 @@ $cl_description = trim($request->getParameter('description')); $cl_bcc_email = trim($request->getParameter('bcc_email')); $cl_allow_ip = trim($request->getParameter('allow_ip')); + $cl_password_compexity = trim($request->getParameter('password_complexity')); } else { $cl_group = $group['name']; $cl_description = $group['description']; $cl_bcc_email = $group['bcc_email']; $cl_allow_ip = $group['allow_ip']; + $cl_password_compexity = $group['password_complexity']; } $form = new Form('groupAdvancedForm'); @@ -34,6 +36,7 @@ $form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'bcc_email','value'=>$cl_bcc_email)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'allow_ip','value'=>$cl_allow_ip)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'password_complexity','value'=>$cl_password_complexity)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); @@ -44,6 +47,7 @@ if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.bcc')); if (!ttValidIP($cl_allow_ip, true)) $err->add($i18n->get('error.field'), $i18n->get('form.group_edit.allow_ip')); + // TODO: add validation for password complexity field. // Finished validating user input. if ($err->no()) { @@ -51,7 +55,8 @@ 'name' => $cl_group, 'description' => $cl_description, 'bcc_email' => $cl_bcc_email, - 'allow_ip' => $cl_allow_ip))) { + 'allow_ip' => $cl_allow_ip, + 'password_complexity' => $cl_password_complexity))) { header('Location: success.php'); exit(); } else From 26c4bcf64643c64b6bd3c5e36f0b3e99ede56b38 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 13 Mar 2022 17:27:48 +0000 Subject: [PATCH 1675/1848] Some mnore progress on password complexity. --- WEB-INF/lib/common.lib.php | 10 ++++++++++ WEB-INF/lib/ttUser.class.php | 3 ++- group_advanced_edit.php | 6 +++--- initialize.php | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 6702919b7..365452f88 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -396,6 +396,16 @@ function ttValidHolidays($val) return true; } +// ttValidPasswordComplexity is used to check user input for password complexity field. +function ttValidPasswordComplexity($val) +{ + // Password complexity example may contain a-z, A-Z, 0-9, and a #. + if (!preg_match('/^[a-zA-Z0-9#]*$/', $val)) + return false; + + return true; +} + // ttAccessAllowed checks whether user is allowed access to a particular page. // It is used as an initial check on all publicly available pages // (except login.php, register.php, and others where we don't have to check). diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index f1eb3e094..ff9295d04 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -693,6 +693,7 @@ function updateGroup($fields) { if (isset($fields['record_type'])) $record_type_part = ', record_type = '.(int) $fields['record_type']; if (isset($fields['bcc_email'])) $bcc_email_part = ', bcc_email = '.$mdb2->quote($fields['bcc_email']); if (isset($fields['allow_ip'])) $allow_ip_part = ', allow_ip = '.$mdb2->quote($fields['allow_ip']); + if (isset($fields['password_complexity'])) $password_complexity_part = ', password_complexity = '.$mdb2->quote($fields['password_complexity']); if (isset($fields['plugins'])) $plugins_part = ', plugins = '.$mdb2->quote($fields['plugins']); if (isset($fields['config'])) $config_part = ', config = '.$mdb2->quote($fields['config']); if (isset($fields['custom_css'])) $custom_css_part = ', custom_css = '.$mdb2->quote($fields['custom_css']); @@ -703,7 +704,7 @@ function updateGroup($fields) { $parts = trim($name_part.$description_part.$currency_part.$lang_part.$decimal_mark_part.$date_format_part. $time_format_part.$week_start_part.$tracking_mode_part.$project_required_part.$record_type_part. - $bcc_email_part.$allow_ip_part.$plugins_part.$config_part.$custom_css_part.$lock_spec_part.$holidays_part.$workday_minutes_part.$modified_part, ','); + $bcc_email_part.$allow_ip_part.$password_complexity_part.$plugins_part.$config_part.$custom_css_part.$lock_spec_part.$holidays_part.$workday_minutes_part.$modified_part, ','); $sql = "update tt_groups set $parts where id = $group_id and org_id = $this->org_id"; $affected = $mdb2->exec($sql); diff --git a/group_advanced_edit.php b/group_advanced_edit.php index a950b8d22..7683d879c 100644 --- a/group_advanced_edit.php +++ b/group_advanced_edit.php @@ -22,13 +22,13 @@ $cl_description = trim($request->getParameter('description')); $cl_bcc_email = trim($request->getParameter('bcc_email')); $cl_allow_ip = trim($request->getParameter('allow_ip')); - $cl_password_compexity = trim($request->getParameter('password_complexity')); + $cl_password_complexity = trim($request->getParameter('password_complexity')); } else { $cl_group = $group['name']; $cl_description = $group['description']; $cl_bcc_email = $group['bcc_email']; $cl_allow_ip = $group['allow_ip']; - $cl_password_compexity = $group['password_complexity']; + $cl_password_complexity = $group['password_complexity']; } $form = new Form('groupAdvancedForm'); @@ -47,7 +47,7 @@ if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.bcc')); if (!ttValidIP($cl_allow_ip, true)) $err->add($i18n->get('error.field'), $i18n->get('form.group_edit.allow_ip')); - // TODO: add validation for password complexity field. + if (!ttValidPasswordComplexity($cl_password_complexity, true)) $err->add($i18n->get('error.field'), $i18n->get('form.group_edit.password_complexity')); // Finished validating user input. if ($err->no()) { diff --git a/initialize.php b/initialize.php index d9e800df7..8a7e9390c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.0.5651"); +define("APP_VERSION", "1.21.0.5652"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From a7c55a3af569745243e29dcc3e45125a27e70fd6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 13 Mar 2022 18:13:27 +0000 Subject: [PATCH 1676/1848] Introduced error.weak_password to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ initialize.php | 2 +- user_add.php | 3 +++ 32 files changed, 54 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index a9937cea6..f1a31d7db 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -74,6 +74,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Usuari o parula de pas incorrecta.', // TODO: translate the following. +// 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 9d5331736..c54d09d62 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -76,6 +76,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Nesprávné jméno nebo heslo.', // TODO: translate the following. +// 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 22aba0ded..84ec205c5 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -66,6 +66,8 @@ // TODO: translate the following. // 'error.record' => 'Select record.', 'error.auth' => 'Forkert brugernavn eller adgangskode.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Brugernavn eksistere allerede.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 9a845d1f0..6a79d3978 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -64,6 +64,8 @@ 'error.report' => 'Bericht auswählen.', 'error.record' => 'Eintrag auswählen.', 'error.auth' => 'Benutzername oder Passwort ungültig.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Benutzer mit diesem Konto ist bereits vorhanden.', 'error.object_exists' => 'Objekt mit diesem Namen ist bereits vorhanden.', 'error.invoice_exists' => 'Rechnung mit dieser Nummer existiert bereits.', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index ab7769558..3a4b699c0 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -60,6 +60,7 @@ 'error.report' => 'Select report.', 'error.record' => 'Select record.', 'error.auth' => 'Incorrect login or password.', +'error.weak_password' => 'Weak password.', 'error.user_exists' => 'User with this login already exists.', 'error.object_exists' => 'Object with this name already exists.', 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index b7942fbeb..d622d857d 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -72,6 +72,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Usuario o contraseña incorrecta.', // TODO: translate the following. +// 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index e14416bc1..6a6d5d02c 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -65,6 +65,8 @@ 'error.report' => 'Vali raport.', 'error.record' => 'Vali kirje.', 'error.auth' => 'Autentimine ebaõnnestus.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Selle nimega kasutaja on juba kasutusel.', 'error.object_exists' => 'Sellise nimega objekt on juba olemas.', 'error.invoice_exists' => 'Arve number on juba kasutusel.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 8ccc29f08..bde6ab03d 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -71,6 +71,8 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', 'error.auth' => 'نام کاربری یا رمز عبور اشتباه است.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'کاربری با این نام کاربری موجود است.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 26c150880..db49d601e 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -68,6 +68,8 @@ // TODO: translate the following. // 'error.record' => 'Select record.', 'error.auth' => 'Virheellinen käyttäjänimi tai salasana.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Tämä käyttäjänimi on jo olemassa.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 892b0291f..73d9ae28a 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -66,6 +66,8 @@ // TODO: translate the following. // 'error.record' => 'Select record.', 'error.auth' => 'Nom d\\\'utilisateur ou mot de passe incorrect.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Un utilisateur avec cet identifiant existe déjà.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index f1dbbc3c5..d8cf3d68f 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -63,6 +63,8 @@ 'error.report' => 'Επιλογή αναφοράς.', 'error.record' => 'Επιλογή εγγραφής.', 'error.auth' => 'Λανθασμένο όνομα εισόδου ή κωδικός.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Ο χρήστης με αυτήν τη σύνδεση υπάρχει ήδη.', 'error.object_exists' => 'Το αντικείμενο με αυτό το όνομα υπάρχει ήδη.', 'error.invoice_exists' => 'Το τιμολόγιο με αυτόν τον αριθμό υπάρχει ήδη.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 4f2a49236..0a6074693 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -81,6 +81,8 @@ // 'error.report' => 'Select report.' // 'error.record' => 'Select record.', 'error.auth' => 'שם משתמש או סיסמה שגויים', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'שם משתמש כבר קיים', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 924b4acc9..172e49fa4 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -74,6 +74,7 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', // 'error.auth' => 'Incorrect login or password.', +// 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 383b1ab13..8dc205860 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -65,6 +65,8 @@ 'error.report' => 'Seleziona rapporto.', 'error.record' => 'Seleziona record.', 'error.auth' => 'Login o password errati.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Esiste già un utente con questo username.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index b3fd57f48..cc9edc0d3 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -73,6 +73,8 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', 'error.auth' => '不正確なログインあるいはパスワードが不正確です。', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'このログインと関連されたユーザーは既に存在します。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index d182519a3..18b6ec6c2 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -73,6 +73,8 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', 'error.auth' => '부정확한 로그인 혹은 암호가 틀립니다.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => '본 로그인과 연계된 사용자가 이미 있습니다.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 8c1afa7fb..6e93f166c 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -59,6 +59,8 @@ 'error.report' => 'Kies rapport.', 'error.record' => 'Kies record.', 'error.auth' => 'Onjuiste inlognaam of wachtwoord.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Een gebruiker met deze inlognaam bestaat al.', 'error.object_exists' => 'Een object met deze naam bestaat al.', 'error.invoice_exists' => 'Dit nummer is al eens toegekend aan een factuur.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 8b5e13f0f..1e38bd0c1 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -74,6 +74,8 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', 'error.auth' => 'Feil brukernavn eller passord.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Bruker med et slikt brukernavn eksisterer allerede.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 97ac1e0da..2fc57348b 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -69,6 +69,8 @@ // TODO: translate the following. // 'error.record' => 'Select record.', 'error.auth' => 'Błędny login lub hasło.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Użytkownik o takiej nazwie już istnieje.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index b01e94d32..7f5601efe 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -59,6 +59,8 @@ 'error.report' => 'Selecione relatório.', 'error.record' => 'Selecione o registro.', 'error.auth' => 'Usuário ou senha incorretos.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Já existe usuário com este login.', 'error.object_exists' => 'Já existe um objeto com este nome.', 'error.invoice_exists' => 'Já existe fatura com este número.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 7c724cd29..2806b8437 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -72,6 +72,7 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', // 'error.auth' => 'Incorrect login or password.', +// 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 33c4547dc..8619ea27d 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -78,6 +78,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Nume de utilizator sau parola incorecta.', // TODO: translate the following. +// 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3707ce74a..41c95c845 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -59,6 +59,7 @@ 'error.report' => 'Выберите отчёт.', 'error.record' => 'Выберите запись.', 'error.auth' => 'Неправильно введен логин или пароль.', +'error.weak_password' => 'Слабый пароль.', 'error.user_exists' => 'Пользователь с таким логином уже существует.', 'error.object_exists' => 'Объект с таким именем уже есть.', 'error.invoice_exists' => 'Счёт с таким номером уже есть.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 345666d8f..e45b06512 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -70,6 +70,8 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', 'error.auth' => 'Nesprávne prihlasovacie meno alebo heslo.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Používateľ s týmto prihlasovacím menom už existuje.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index d5b56f4a0..4e519bcf0 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -69,6 +69,7 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', // 'error.auth' => 'Incorrect login or password.', +// 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 652eaa893..7aa5f1008 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -66,6 +66,8 @@ // TODO: translate the following. // 'error.record' => 'Select record.', 'error.auth' => 'Pogrešno korisničko ime ili lozinka.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Korisnik pod ovim imenom već postoji.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index b39366bc1..f641ef690 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -65,6 +65,8 @@ // TODO: translate the following. // 'error.record' => 'Select record.', 'error.auth' => 'Ogiltigt användarnamn eller lösenord.', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Det finns redan en användare med det här användarnamnet.', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 2aae8ed9c..9691b950f 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -81,6 +81,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Hatalı kullanıcı adı veya parola.', // TODO: translate the following. +// 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', // 'error.invoice_exists' => 'Invoice with this number already exists.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index f423fab84..afe7588ab 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -68,6 +68,8 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', 'error.auth' => '不正确的用户名或密码。', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => '该用户登录信息已经存在。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 92f5dbf52..294312892 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -71,6 +71,8 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', 'error.auth' => '不正確的用戶名或密碼。', +// TODO: translate the following. +// 'error.weak_password' => 'Weak password.', 'error.user_exists' => '該使用者登錄資訊已經存在。', // TODO: translate the following. // 'error.object_exists' => 'Object with this name already exists.', diff --git a/initialize.php b/initialize.php index 8a7e9390c..7d6e96ba2 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.0.5652"); +define("APP_VERSION", "1.21.0.5653"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_add.php b/user_add.php index 8d584afb7..f294cf71b 100644 --- a/user_add.php +++ b/user_add.php @@ -158,6 +158,9 @@ function render(&$table, $value, $row, $column, $selected = false) { if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($cl_password1 !== $cl_password2) $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); + // Check password complexity. + // if (!ttCheckPasswordComplexity($cl_password1)) + // $err->add($i18n->get('error.weak_password')); } if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); // Require selection of a client for a client role. From 596e07d7c3164ea98083b60bf9dec22df87bb5f6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 13 Mar 2022 21:05:17 +0000 Subject: [PATCH 1677/1848] Added a capability and enforcement of password complexity for users. --- WEB-INF/lib/common.lib.php | 42 ++++++++++++++++++++++++++++++++++-- WEB-INF/lib/ttUser.class.php | 5 +++++ initialize.php | 2 +- password_change.php | 3 +++ profile_edit.php | 3 +++ user_add.php | 4 ++-- user_edit.php | 3 +++ 7 files changed, 57 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 365452f88..122987f1a 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -397,15 +397,53 @@ function ttValidHolidays($val) } // ttValidPasswordComplexity is used to check user input for password complexity field. -function ttValidPasswordComplexity($val) +function ttValidPasswordComplexity($complexityExample) { // Password complexity example may contain a-z, A-Z, 0-9, and a #. - if (!preg_match('/^[a-zA-Z0-9#]*$/', $val)) + if (!preg_match('/^[a-zA-Z0-9#]*$/', $complexityExample)) return false; return true; } +// ttCheckPasswordComplexity checks password complexity. +function ttCheckPasswordComplexity($password) +{ + global $user; + $complexity = $user->getPasswordComplexity(); + if (empty($complexity)) + return true; + + // Password complexity must be enforced. + if (strlen($password) < strlen($complexity)) + return false; // Password is too short. + + $numDigitsRequired = preg_match_all( "/[0-9]/", $complexity); + $numDigitsSupplied = preg_match_all( "/[0-9]/", $password); + if ($numDigitsSupplied < $numDigitsRequired) + return false; // Number of digits in password is less than required number in complexity example. + + $numCapitalsRequired = preg_match_all( "/[A-Z]/", $complexity); + $numCapitalsSupplied = preg_match_all( "/[A-Z]/", $password); + if ($numCapitalsSupplied < $numCapitalsRequired) + return false; // Number of capitals A-Z in password is less than required number in complexity example. + + $numLowercaseRequired = preg_match_all( "/[a-z]/", $complexity); + $numLowercaseSupplied = preg_match_all( "/[a-z]/", $password); + if ($numLowercaseSupplied < $numLowercaseRequired) + return false; // Number of lowercase letter a-z in password is less than required number in complexity example. + + // Finally check the number of "all other" characters that are not alphanumeric. This includes utf-8 characters. + $numNotAlphanumericRequired = preg_match_all( "/[#]/", $complexity); + $passwordRemainder = preg_replace("/[a-zA-Z0-9]/", "", $password); + $numNotAlphanumericSupplied = mb_strlen($passwordRemainder); + if ($numNotAlphanumericSupplied < $numNotAlphanumericRequired) + return false; + + return true; +} + + // ttAccessAllowed checks whether user is allowed access to a particular page. // It is used as an initial check on all publicly available pages // (except login.php, register.php, and others where we don't have to check). diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index ff9295d04..7114bc7c6 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -169,6 +169,11 @@ function getEmail() { return ($this->behalfUser ? $this->behalfUser->email : $this->email); } + // getPasswordComplexity returns password complexity for active user. + function getPasswordComplexity() { + return ($this->behalfUser ? $this->behalfUser->password_complexity : $this->password_complexity); + } + // The getGroup returns group id on behalf of which the current user is operating. function getGroup() { return ($this->behalfGroup ? $this->behalfGroup->id : $this->group_id); diff --git a/initialize.php b/initialize.php index 7d6e96ba2..a4df18dda 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.0.5653"); +define("APP_VERSION", "1.21.1.5654"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/password_change.php b/password_change.php index 992bdd87b..d395b6396 100644 --- a/password_change.php +++ b/password_change.php @@ -49,6 +49,9 @@ if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($cl_password1 !== $cl_password2) $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); + // Check password complexity. + if (!ttCheckPasswordComplexity($cl_password1)) + $err->add($i18n->get('error.weak_password')); if ($err->no()) { // Use the "limit" plugin if we have one. Ignore include errors. diff --git a/profile_edit.php b/profile_edit.php index a9f11fc2d..3958a4018 100644 --- a/profile_edit.php +++ b/profile_edit.php @@ -67,6 +67,9 @@ if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($cl_password1 !== $cl_password2) $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); + // Check password complexity. + if (!ttCheckPasswordComplexity($cl_password1)) + $err->add($i18n->get('error.weak_password')); } if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); // Finished validating user input. diff --git a/user_add.php b/user_add.php index f294cf71b..e75e0901d 100644 --- a/user_add.php +++ b/user_add.php @@ -159,8 +159,8 @@ function render(&$table, $value, $row, $column, $selected = false) { if ($cl_password1 !== $cl_password2) $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); // Check password complexity. - // if (!ttCheckPasswordComplexity($cl_password1)) - // $err->add($i18n->get('error.weak_password')); + if (!ttCheckPasswordComplexity($cl_password1)) + $err->add($i18n->get('error.weak_password')); } if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); // Require selection of a client for a client role. diff --git a/user_edit.php b/user_edit.php index 57133eb39..6bdbef693 100644 --- a/user_edit.php +++ b/user_edit.php @@ -190,6 +190,9 @@ function render(&$table, $value, $row, $column, $selected = false) { if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); if ($cl_password1 !== $cl_password2) $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); + // Check password complexity. + if (!ttCheckPasswordComplexity($cl_password1)) + $err->add($i18n->get('error.weak_password')); } if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); // Require selection of a client for a client role. From 0261c3ffa9017327d54d0be9f315057707b43d91 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 13 Mar 2022 21:08:34 +0000 Subject: [PATCH 1678/1848] Removed a debug condition for password complextity feature. --- WEB-INF/templates/group_advanced_edit.tpl | 2 -- initialize.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/WEB-INF/templates/group_advanced_edit.tpl b/WEB-INF/templates/group_advanced_edit.tpl index 66fa41035..528daf465 100644 --- a/WEB-INF/templates/group_advanced_edit.tpl +++ b/WEB-INF/templates/group_advanced_edit.tpl @@ -32,7 +32,6 @@ License: See license.txt *} {$i18n.label.what_is_it} -{if constant('PASSWORD_COMPLEXITY_DEBUG')} @@ -42,7 +41,6 @@ License: See license.txt *} {$i18n.label.what_is_it} -{/if} diff --git a/initialize.php b/initialize.php index a4df18dda..73b693410 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5654"); +define("APP_VERSION", "1.21.1.5655"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 76667fa583dc775400db420fe77973f890b36954 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 14 Mar 2022 13:56:25 +0000 Subject: [PATCH 1679/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 6 ++---- initialize.php | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 6e93f166c..5d866e617 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -59,8 +59,7 @@ 'error.report' => 'Kies rapport.', 'error.record' => 'Kies record.', 'error.auth' => 'Onjuiste inlognaam of wachtwoord.', -// TODO: translate the following. -// 'error.weak_password' => 'Weak password.', +'error.weak_password' => 'Zwak wachtwoord.', 'error.user_exists' => 'Een gebruiker met deze inlognaam bestaat al.', 'error.object_exists' => 'Een object met deze naam bestaat al.', 'error.invoice_exists' => 'Dit nummer is al eens toegekend aan een factuur.', @@ -508,8 +507,7 @@ 'form.group_edit.uncompleted_indicators' => 'Onvolledige indicatoren', 'form.group_edit.confirm_save' => 'Bevestigen dat je wilt opslaan', 'form.group_edit.allow_ip' => 'Toegestane IP adressen', -// TODO: translate the following. -// 'form.group_edit.password_complexity' => 'Password complexity', +'form.group_edit.password_complexity' => 'Wachtwoord complexiteit', 'form.group_edit.advanced_settings' => 'Geavanceerde instellingen', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/initialize.php b/initialize.php index 73b693410..eb15642a8 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5655"); +define("APP_VERSION", "1.21.1.5656"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 1990edf7a7cc17f520c98f8ff929b54d509203e2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 14 Mar 2022 14:53:20 +0000 Subject: [PATCH 1680/1848] Improved password complexity specification by allowing an asterisk in there for better password length control. --- WEB-INF/lib/common.lib.php | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 122987f1a..db00923ab 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -399,8 +399,8 @@ function ttValidHolidays($val) // ttValidPasswordComplexity is used to check user input for password complexity field. function ttValidPasswordComplexity($complexityExample) { - // Password complexity example may contain a-z, A-Z, 0-9, and a #. - if (!preg_match('/^[a-zA-Z0-9#]*$/', $complexityExample)) + // Password complexity example may contain a-z, A-Z, 0-9, #, and *. + if (!preg_match('/^[a-zA-Z0-9#*]*$/', $complexityExample)) return false; return true; diff --git a/initialize.php b/initialize.php index eb15642a8..23e3c733f 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5656"); +define("APP_VERSION", "1.21.1.5657"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 4ce11322cefcf172b8103ae23b3c1c9684dd91ee Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Mar 2022 15:32:34 +0000 Subject: [PATCH 1681/1848] Starting work on 2fa. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + initialize.php | 2 +- 31 files changed, 32 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index f1a31d7db..e862f97f6 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -586,6 +586,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index c54d09d62..d73ef53d7 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -598,6 +598,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 84ec205c5..4c1f1b248 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -565,6 +565,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 6a79d3978..cbe69a211 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -540,6 +540,7 @@ 'form.group_edit.allow_ip' => 'Erlaube IP', // TODO: translate the following. // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 3a4b699c0..4c2b74b42 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -522,6 +522,7 @@ 'form.group_edit.confirm_save' => 'Confirm saving', 'form.group_edit.allow_ip' => 'Allow IP', 'form.group_edit.password_complexity' => 'Password complexity', +'form.group_edit.2fa' => 'Two factor authentication', 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index d622d857d..80683acc6 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -600,6 +600,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 6a6d5d02c..9c2a1c610 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -574,6 +574,7 @@ 'form.group_edit.allow_ip' => 'Luba IP', // TODO: translate the following. // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index bde6ab03d..1deb75471 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -587,6 +587,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index db49d601e..82c84df89 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -571,6 +571,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 73d9ae28a..b39b0aadc 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -561,6 +561,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index d8cf3d68f..d30201fc7 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -552,6 +552,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 0a6074693..19ce37687 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -591,6 +591,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 172e49fa4..83b82426d 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -590,6 +590,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 8dc205860..acf7cc5b7 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -567,6 +567,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index cc9edc0d3..3f68a935a 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -593,6 +593,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 18b6ec6c2..60b307f77 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -591,6 +591,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 5d866e617..f2b0da6fa 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -508,6 +508,8 @@ 'form.group_edit.confirm_save' => 'Bevestigen dat je wilt opslaan', 'form.group_edit.allow_ip' => 'Toegestane IP adressen', 'form.group_edit.password_complexity' => 'Wachtwoord complexiteit', +// TODO: translate the following. +// form.group_edit.2fa' => 'Two factor authentication', 'form.group_edit.advanced_settings' => 'Geavanceerde instellingen', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 1e38bd0c1..281f17689 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -594,6 +594,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 2fc57348b..b6610eef4 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -573,6 +573,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 7f5601efe..334db5ca7 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -508,6 +508,7 @@ 'form.group_edit.allow_ip' => 'Permitir IP', // TODO: translate the following. // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', 'form.group_edit.advanced_settings' => 'Configurações avançadas', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 2806b8437..d3aac4e3d 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -572,6 +572,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 8619ea27d..170642ef2 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -594,6 +594,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 41c95c845..e186fbef4 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -509,6 +509,7 @@ 'form.group_edit.confirm_save' => 'Предупреждать при сохранении', 'form.group_edit.allow_ip' => 'Разрешить доступ с IP', 'form.group_edit.password_complexity' => 'Сложность пароля', +'form.group_edit.2fa' => 'Двухфакторная аутентификация', 'form.group_edit.advanced_settings' => 'Продвинутые настройки', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index e45b06512..7fcc99405 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -577,6 +577,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 4e519bcf0..88aee6946 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -567,6 +567,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 7aa5f1008..2aead0d8c 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -573,6 +573,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index f641ef690..87b062f50 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -571,6 +571,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 9691b950f..cf2694c40 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -607,6 +607,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index afe7588ab..5686e2682 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -582,6 +582,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 294312892..62a9e9ced 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -585,6 +585,7 @@ // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', // 'form.group_edit.password_complexity' => 'Password complexity', +// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/initialize.php b/initialize.php index 23e3c733f..faf98ef38 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5657"); +define("APP_VERSION", "1.21.1.5658"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 992a7adb6f2001a5639605f8bb1e64dc68d0edd5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Mar 2022 16:06:13 +0000 Subject: [PATCH 1682/1848] Refactoring in translation files. --- WEB-INF/resources/ca.lang.php | 6 ++++++ WEB-INF/resources/cs.lang.php | 6 ++++++ WEB-INF/resources/da.lang.php | 6 ++++++ WEB-INF/resources/de.lang.php | 6 ++++++ WEB-INF/resources/en.lang.php | 5 +++++ WEB-INF/resources/es.lang.php | 6 ++++++ WEB-INF/resources/et.lang.php | 6 ++++++ WEB-INF/resources/fa.lang.php | 6 ++++++ WEB-INF/resources/fi.lang.php | 6 ++++++ WEB-INF/resources/fr.lang.php | 6 ++++++ WEB-INF/resources/gr.lang.php | 6 ++++++ WEB-INF/resources/he.lang.php | 6 ++++++ WEB-INF/resources/hu.lang.php | 6 ++++++ WEB-INF/resources/it.lang.php | 6 ++++++ WEB-INF/resources/ja.lang.php | 6 ++++++ WEB-INF/resources/ko.lang.php | 6 ++++++ WEB-INF/resources/nl.lang.php | 6 ++++++ WEB-INF/resources/no.lang.php | 6 ++++++ WEB-INF/resources/pl.lang.php | 6 ++++++ WEB-INF/resources/pt-br.lang.php | 6 ++++++ WEB-INF/resources/pt.lang.php | 6 ++++++ WEB-INF/resources/ro.lang.php | 6 ++++++ WEB-INF/resources/ru.lang.php | 5 +++++ WEB-INF/resources/sk.lang.php | 6 ++++++ WEB-INF/resources/sl.lang.php | 6 ++++++ WEB-INF/resources/sr.lang.php | 6 ++++++ WEB-INF/resources/sv.lang.php | 6 ++++++ WEB-INF/resources/tr.lang.php | 6 ++++++ WEB-INF/resources/zh-cn.lang.php | 6 ++++++ WEB-INF/resources/zh-tw.lang.php | 6 ++++++ initialize.php | 2 +- 31 files changed, 179 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index e862f97f6..dbbeb403a 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -589,6 +589,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d73ef53d7..8b5e5006c 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -601,6 +601,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 4c1f1b248..6860b8e37 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -568,6 +568,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index cbe69a211..10431c2a6 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -543,6 +543,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +'form.group_advanced_edit.allow_ip' => 'Erlaube IP', +// TODO: Translate the following. +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Sind Sie sicher, dass Sie die gesamte Gruppe löschen möchten?', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 4c2b74b42..7505043ce 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -525,6 +525,11 @@ 'form.group_edit.2fa' => 'Two factor authentication', 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +'form.group_advanced_edit.allow_ip' => 'Allow IP', +'form.group_advanced_edit.password_complexity' => 'Password complexity', +'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 80683acc6..0e94644a9 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -603,6 +603,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 9c2a1c610..4177bfffa 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -577,6 +577,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +'form.group_advanced_edit.allow_ip' => 'Luba IP', +// TODO: Translate the following. +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Oled kindel, et soovid kogu gruppi kustutada?', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 1deb75471..f37c789c1 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -590,6 +590,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 82c84df89..e124c61ac 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -574,6 +574,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index b39b0aadc..503327a92 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -564,6 +564,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index d30201fc7..310d6bd02 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -555,6 +555,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 19ce37687..95175c930 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -594,6 +594,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 83b82426d..c4745c0a0 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -593,6 +593,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index acf7cc5b7..5676164e3 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -570,6 +570,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 3f68a935a..f8f80c4f8 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -596,6 +596,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 60b307f77..f578659b2 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -594,6 +594,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index f2b0da6fa..a3e415b16 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -512,6 +512,12 @@ // form.group_edit.2fa' => 'Two factor authentication', 'form.group_edit.advanced_settings' => 'Geavanceerde instellingen', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +'form.group_advanced_edit.allow_ip' => 'Toegestane IP adressen', +'form.group_advanced_edit.password_complexity' => 'Wachtwoord complexiteit', +// TODO: Translate the following. +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Bent u er zeker van dat u de hele groep wilt verwijderen?', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 281f17689..82fca5f14 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -597,6 +597,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index b6610eef4..d4a5be37e 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -576,6 +576,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 334db5ca7..195cbc850 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -511,6 +511,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', 'form.group_edit.advanced_settings' => 'Configurações avançadas', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +'form.group_advanced_edit.allow_ip' => 'Permitir IP', +// TODO: Translate the following. +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php. 'form.group_delete.hint' => 'Tem certeza de que deseja excluir todo o grupo?', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d3aac4e3d..fa8c83846 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -575,6 +575,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 170642ef2..eab876d08 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -597,6 +597,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index e186fbef4..30737a76a 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -512,6 +512,11 @@ 'form.group_edit.2fa' => 'Двухфакторная аутентификация', 'form.group_edit.advanced_settings' => 'Продвинутые настройки', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +'form.group_advanced_edit.allow_ip' => 'Разрешить доступ с IP', +'form.group_advanced_edit.password_complexity' => 'Сложность пароля', +'form.group_advanced_edit.2fa' => 'Двухфакторная аутентификация', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Вы уверены, что хотите удалить всю группу?', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 7fcc99405..ae1a0376f 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -580,6 +580,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 88aee6946..d6499cb1b 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -570,6 +570,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 2aead0d8c..d05a97eeb 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -576,6 +576,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 87b062f50..80f6657bd 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -574,6 +574,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index cf2694c40..ca1dacaed 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -610,6 +610,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5686e2682..068ed52a8 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -585,6 +585,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 62a9e9ced..34e18441e 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -588,6 +588,12 @@ // 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', +// Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. +// TODO: Translate the following. +// 'form.group_advanced_edit.allow_ip' => 'Allow IP', +// 'form.group_advanced_edit.password_complexity' => 'Password complexity', +// 'form.group_advanced_edit.2fa' => 'Two factor authentication', + // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php // TODO: translate the following. // 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', diff --git a/initialize.php b/initialize.php index faf98ef38..3389203ce 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5658"); +define("APP_VERSION", "1.21.1.5659"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From bc1c36f9fa327aa478b71ecb7beb1a34f3ba405a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Mar 2022 16:29:36 +0000 Subject: [PATCH 1683/1848] Refactoring of translation files. --- WEB-INF/resources/ca.lang.php | 3 --- WEB-INF/resources/cs.lang.php | 3 --- WEB-INF/resources/da.lang.php | 3 --- WEB-INF/resources/de.lang.php | 3 --- WEB-INF/resources/en.lang.php | 2 -- WEB-INF/resources/es.lang.php | 3 --- WEB-INF/resources/et.lang.php | 3 --- WEB-INF/resources/fa.lang.php | 3 --- WEB-INF/resources/fi.lang.php | 3 --- WEB-INF/resources/fr.lang.php | 3 --- WEB-INF/resources/gr.lang.php | 3 --- WEB-INF/resources/he.lang.php | 3 --- WEB-INF/resources/hu.lang.php | 3 --- WEB-INF/resources/it.lang.php | 3 --- WEB-INF/resources/ja.lang.php | 3 --- WEB-INF/resources/ko.lang.php | 3 --- WEB-INF/resources/nl.lang.php | 4 ---- WEB-INF/resources/no.lang.php | 3 --- WEB-INF/resources/pl.lang.php | 3 --- WEB-INF/resources/pt-br.lang.php | 4 ---- WEB-INF/resources/pt.lang.php | 3 --- WEB-INF/resources/ro.lang.php | 3 --- WEB-INF/resources/ru.lang.php | 3 --- WEB-INF/resources/sk.lang.php | 3 --- WEB-INF/resources/sl.lang.php | 3 --- WEB-INF/resources/sr.lang.php | 3 --- WEB-INF/resources/sv.lang.php | 3 --- WEB-INF/resources/tr.lang.php | 3 --- WEB-INF/resources/zh-cn.lang.php | 3 --- WEB-INF/resources/zh-tw.lang.php | 3 --- WEB-INF/templates/group_advanced_edit.tpl | 8 ++++---- group_advanced_edit.php | 4 ++-- initialize.php | 2 +- 33 files changed, 7 insertions(+), 98 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index dbbeb403a..e1f9a191e 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -584,9 +584,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 8b5e5006c..562253c40 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -596,9 +596,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 6860b8e37..6070d5ab7 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -563,9 +563,6 @@ 'form.group_edit.uncompleted_indicators' => 'Uafsluttede indikatore', // TODO: translate the following. // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 10431c2a6..f627e77f4 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -537,10 +537,7 @@ 'form.group_edit.future_entries' => 'Einträge in der Zukunft', 'form.group_edit.uncompleted_indicators' => 'Zeige unfertige Einträge', 'form.group_edit.confirm_save' => 'Speichern bestätigen', -'form.group_edit.allow_ip' => 'Erlaube IP', // TODO: translate the following. -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 7505043ce..1cd30f07d 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -520,9 +520,7 @@ 'form.group_edit.future_entries' => 'Future entries', 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', 'form.group_edit.confirm_save' => 'Confirm saving', -'form.group_edit.allow_ip' => 'Allow IP', 'form.group_edit.password_complexity' => 'Password complexity', -'form.group_edit.2fa' => 'Two factor authentication', 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 0e94644a9..9cc4aabdc 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -598,9 +598,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 4177bfffa..9dd7d02df 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -571,10 +571,7 @@ 'form.group_edit.future_entries' => 'Tuleviku kirjed', 'form.group_edit.uncompleted_indicators' => 'Lõpetamata kirjete indikaator', // TODO: Fix this. Indicators (plural), not indicator. 'form.group_edit.confirm_save' => 'Kinnita salvestamine', -'form.group_edit.allow_ip' => 'Luba IP', // TODO: translate the following. -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f37c789c1..a7560fc4e 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -585,9 +585,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index e124c61ac..1f483ef1c 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -569,9 +569,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 503327a92..22132849e 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -559,9 +559,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 310d6bd02..f2606c41c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -550,9 +550,6 @@ 'form.group_edit.uncompleted_indicators' => 'Μη ολοκληρωμένες ενδείξεις', // TODO: translate the following. // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 95175c930..52892dbcf 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -589,9 +589,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index c4745c0a0..b880b22f5 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -588,9 +588,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 5676164e3..40bca63ed 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -565,9 +565,6 @@ 'form.group_edit.uncompleted_indicators' => 'Indicatori incompleti', // TODO: translate the following. // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index f8f80c4f8..518c42696 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -591,9 +591,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index f578659b2..dde934023 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -589,9 +589,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index a3e415b16..bd1ad69c4 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -506,10 +506,6 @@ 'form.group_edit.future_entries' => 'Toevoegingen toestaan in de toekomst', 'form.group_edit.uncompleted_indicators' => 'Onvolledige indicatoren', 'form.group_edit.confirm_save' => 'Bevestigen dat je wilt opslaan', -'form.group_edit.allow_ip' => 'Toegestane IP adressen', -'form.group_edit.password_complexity' => 'Wachtwoord complexiteit', -// TODO: translate the following. -// form.group_edit.2fa' => 'Two factor authentication', 'form.group_edit.advanced_settings' => 'Geavanceerde instellingen', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 82fca5f14..c38c74dd4 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -592,9 +592,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index d4a5be37e..865562299 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -571,9 +571,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 195cbc850..bbabafcbc 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -505,10 +505,6 @@ 'form.group_edit.future_entries' => 'Entradas futuros', 'form.group_edit.uncompleted_indicators' => 'Indicadores incompletos', 'form.group_edit.confirm_save' => 'Confirme o salvamento', -'form.group_edit.allow_ip' => 'Permitir IP', -// TODO: translate the following. -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', 'form.group_edit.advanced_settings' => 'Configurações avançadas', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index fa8c83846..41e06c0fc 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -570,9 +570,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index eab876d08..7f3168d41 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -592,9 +592,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 30737a76a..359666167 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -507,9 +507,6 @@ 'form.group_edit.future_entries' => 'Будущие записи', 'form.group_edit.uncompleted_indicators' => 'Индикаторы незавершения', 'form.group_edit.confirm_save' => 'Предупреждать при сохранении', -'form.group_edit.allow_ip' => 'Разрешить доступ с IP', -'form.group_edit.password_complexity' => 'Сложность пароля', -'form.group_edit.2fa' => 'Двухфакторная аутентификация', 'form.group_edit.advanced_settings' => 'Продвинутые настройки', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index ae1a0376f..c52d54601 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -575,9 +575,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index d6499cb1b..1302ccd6f 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -565,9 +565,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index d05a97eeb..ba65b4615 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -571,9 +571,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 80f6657bd..bd815b257 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -569,9 +569,6 @@ 'form.group_edit.uncompleted_indicators' => 'Indikatorer för oavslutad registrering', // TODO: translate the following. // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index ca1dacaed..a2f503308 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -605,9 +605,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 068ed52a8..7932da3bd 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -580,9 +580,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 34e18441e..78e3b25bf 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -583,9 +583,6 @@ // 'form.group_edit.future_entries' => 'Future entries', // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.password_complexity' => 'Password complexity', -// 'form.group_edit.2fa' => 'Two factor authentication', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. diff --git a/WEB-INF/templates/group_advanced_edit.tpl b/WEB-INF/templates/group_advanced_edit.tpl index 528daf465..4bcaedf49 100644 --- a/WEB-INF/templates/group_advanced_edit.tpl +++ b/WEB-INF/templates/group_advanced_edit.tpl @@ -24,18 +24,18 @@ License: See license.txt *} - + - + - + - + +{if constant('2FA_DEBUG')} + + + + + + +{/if} diff --git a/group_advanced_edit.php b/group_advanced_edit.php index a4cf540e3..26134c789 100644 --- a/group_advanced_edit.php +++ b/group_advanced_edit.php @@ -16,6 +16,7 @@ // End of access checks. $group = ttGroupHelper::getGroupAttrs($user->getGroup()); +$config = $user->getConfigHelper(); if ($request->isPost()) { $cl_group = trim($request->getParameter('group_name')); @@ -23,12 +24,14 @@ $cl_bcc_email = trim($request->getParameter('bcc_email')); $cl_allow_ip = trim($request->getParameter('allow_ip')); $cl_password_complexity = trim($request->getParameter('password_complexity')); + $cl_2fa = (bool) $request->getParameter('2fa'); } else { $cl_group = $group['name']; $cl_description = $group['description']; $cl_bcc_email = $group['bcc_email']; $cl_allow_ip = $group['allow_ip']; $cl_password_complexity = $group['password_complexity']; + $cl_2fa = $config->getDefinedValue('2fa'); } $form = new Form('groupAdvancedForm'); @@ -37,6 +40,7 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'bcc_email','value'=>$cl_bcc_email)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'allow_ip','value'=>$cl_allow_ip)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'password_complexity','value'=>$cl_password_complexity)); +$form->addInput(array('type'=>'checkbox','name'=>'2fa','value'=>$cl_2fa)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); @@ -51,12 +55,17 @@ // Finished validating user input. if ($err->no()) { + // Update config. + $config->setDefinedValue('2fa', $cl_2fa); + + // Update group. if ($user->updateGroup(array( 'name' => $cl_group, 'description' => $cl_description, 'bcc_email' => $cl_bcc_email, 'allow_ip' => $cl_allow_ip, - 'password_complexity' => $cl_password_complexity))) { + 'password_complexity' => $cl_password_complexity, + 'config' => $config->getConfig()))) { header('Location: success.php'); exit(); } else diff --git a/initialize.php b/initialize.php index 74d3da0ad..1eb308b01 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5660"); +define("APP_VERSION", "1.21.1.5661"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 178417e79adcf25143ab28b2a4505f625136f3ea Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 16 Mar 2022 14:54:46 +0000 Subject: [PATCH 1685/1848] Work in progress on 2fa. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 5 +++-- WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 1 + initialize.php | 2 +- login.php | 13 +++++++++++++ 32 files changed, 62 insertions(+), 3 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index e1f9a191e..6c577de0b 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -418,6 +418,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '¿Ha oblidat la seva paraula de pas?', // TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 562253c40..feee22377 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -425,6 +425,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zapomenuté heslo?', // TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 6070d5ab7..6a598edb7 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -402,6 +402,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Har du glemt din adgangskode?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker er et open source tidsregistrerings system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index f627e77f4..ad6727fba 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -389,6 +389,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Passwort vergessen?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker ist ein Open-Source Zeiterfassungssystem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 1cd30f07d..8df7601de 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -371,6 +371,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Forgot password?', +'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 9cc4aabdc..441b42586 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -422,6 +422,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '¿Olvido su contraseña?', // TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 9dd7d02df..715b68bc4 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -410,6 +410,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Unustasid salasõna?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker on avatud lähtekoodiga ajaarvestussüsteem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index a7560fc4e..f470be335 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -419,8 +419,9 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'بازیابی رمز عبور؟', -// TODO: translate form.login.about. -'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'درخواست بازیابی رمزعبور به ایمیل فرستاده شد.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 1f483ef1c..db157940c 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -407,6 +407,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Salasana unohtunut?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // TODO: check translation of form.login.about - is open source "vapaan koodin"? 'form.login.about' => 'Anuko Time Tracker on vapaan koodin tuntiseurantaohjelmisto.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 22132849e..d68e4cb44 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -399,6 +399,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Mot de passe oublié?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker est un système de gestion du temps, open source.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index f2606c41c..7c8e39562 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -398,6 +398,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Ξεχάσατε τον κωδικό πρόσβασης;', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker είναι ένα ανοικτού κώδικα σύστημα παρακολούθησης χρόνου.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 52892dbcf..fddf8d50b 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -424,6 +424,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'שכחת סיסמה?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // TODO: re-translate form.login.about as it has changed. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker הינה מערכת פשוטה, קלה לשימוש וחינמית לניהול זמן.', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index b880b22f5..d3cbd7f93 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -419,6 +419,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Elfelejtetted a jelszót?', // TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 40bca63ed..8d2cfaa00 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -408,6 +408,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Password dimenticata?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker è un sistema open source per registrare i tempi di lavoro.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 518c42696..3dc0b8773 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -420,6 +420,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'パスワードを忘れましたか?', // TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index dde934023..63999c23f 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -424,6 +424,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '암호를 잊으셨습니까?', // TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index bd1ad69c4..131d79935 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -363,6 +363,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Wachtwoord vergeten?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker is een open source tijdregistratiesysteem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index c38c74dd4..d2a934ee7 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -421,6 +421,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Glemt passordet?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // TODO: re-translate form.login.about as it has changed. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker er et enkelt, brukervennlig tidsregistreringssystem basert på åpen kildekode.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 865562299..4316435a3 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -410,6 +410,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Nie pamiętasz hasła?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker jest otwartoźródłowym systemem śledzenia czasu.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index bbabafcbc..c5a670a0d 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -362,6 +362,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Esqueceu a senha?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker é um sistema de código aberto de rastreamento do tempo.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 41e06c0fc..a40d8ed83 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -403,6 +403,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Esqueceu a senha?', // TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 7f3168d41..97c9a854f 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -424,6 +424,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Parola pierduta?', // TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 359666167..faa1c7aba 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -364,6 +364,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Забыли пароль?', +'form.login.2fa_code' => '2FA код', 'form.login.about' => 'Anuko Time Tracker - это открытая (open source) система трекинга рабочего времени.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index c52d54601..356e4e0a9 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -413,6 +413,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zabudnuté heslo?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker je systém na sledovanie času s otvoreným zdrojovým kódom.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 1302ccd6f..2bcba2362 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -396,6 +396,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. // TODO: translate the following. // 'form.login.forgot_password' => 'Forgot password?', +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index ba65b4615..dff5f2623 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -408,6 +408,8 @@ // Forma prijave. Pogledajte primer na https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zaboravili ste lozinku?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // TODO: re-translate form.login.about as it has changed. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker je jednostavan i lak za korišćenje za praćenje radnog vremena.', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index bd815b257..62a747e10 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -406,6 +406,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Glömt lösenordet?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // TODO: re-translate form.login.about as it has changed. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker är en lättanvänd applikation byggd med öppen källkod som enkelt låter dig spåra och hålla koll på arbetstider.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index a2f503308..e0a291f09 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -432,6 +432,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Parolanızı unuttunuz mu?', // TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7932da3bd..7dc37961c 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -413,6 +413,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '忘记密码?', +// TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // TODO: re-translate form.login.about as it has changed. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker 是一种简单、易用、开放源代码的实时跟踪系统。', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 78e3b25bf..2497f7ce7 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -418,6 +418,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '忘記密碼?', // TODO: translate the following. +// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/initialize.php b/initialize.php index 1eb308b01..2f537eb6b 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5661"); +define("APP_VERSION", "1.21.1.5662"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/login.php b/login.php index 93b1cd084..5ea77d185 100644 --- a/login.php +++ b/login.php @@ -48,6 +48,19 @@ setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); $user = new ttUser(null, $auth->getUserId()); + + // Determine if we have to additionally use two-factor authentication. + $config = $user->getConfigHelper(); + $use2FA = $config->getDefinedValue('2fa'); + if ($use2FA) { + + // TODO: send 2fa code to user. + $auth->doLogout(); + + header('Location: 2fa.php'); + exit(); + } + // Redirect, depending on user role. if ($user->can('administer_site')) { header('Location: admin_groups.php'); From f2fbe6e5a6251cf86be04f5aa8baa8c1bee038c7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 16 Mar 2022 15:25:33 +0000 Subject: [PATCH 1686/1848] Some refactoring in translation files related to 2fa. --- 2fa.php | 87 ++++++++++++++++++++++++++++++++ WEB-INF/resources/ca.lang.php | 5 +- WEB-INF/resources/cs.lang.php | 5 +- WEB-INF/resources/da.lang.php | 6 ++- WEB-INF/resources/de.lang.php | 6 ++- WEB-INF/resources/en.lang.php | 3 ++ WEB-INF/resources/es.lang.php | 5 +- WEB-INF/resources/et.lang.php | 6 ++- WEB-INF/resources/fa.lang.php | 5 +- WEB-INF/resources/fi.lang.php | 8 +-- WEB-INF/resources/fr.lang.php | 6 ++- WEB-INF/resources/gr.lang.php | 6 ++- WEB-INF/resources/he.lang.php | 6 ++- WEB-INF/resources/hu.lang.php | 5 +- WEB-INF/resources/it.lang.php | 6 ++- WEB-INF/resources/ja.lang.php | 5 +- WEB-INF/resources/ko.lang.php | 5 +- WEB-INF/resources/nl.lang.php | 6 ++- WEB-INF/resources/no.lang.php | 6 ++- WEB-INF/resources/pl.lang.php | 6 ++- WEB-INF/resources/pt-br.lang.php | 6 ++- WEB-INF/resources/pt.lang.php | 5 +- WEB-INF/resources/ro.lang.php | 5 +- WEB-INF/resources/ru.lang.php | 4 +- WEB-INF/resources/sk.lang.php | 6 ++- WEB-INF/resources/sl.lang.php | 5 +- WEB-INF/resources/sr.lang.php | 6 ++- WEB-INF/resources/sv.lang.php | 6 ++- WEB-INF/resources/tr.lang.php | 5 +- WEB-INF/resources/zh-cn.lang.php | 6 ++- WEB-INF/resources/zh-tw.lang.php | 5 +- WEB-INF/templates/2fa.tpl | 24 +++++++++ 32 files changed, 230 insertions(+), 46 deletions(-) create mode 100644 2fa.php create mode 100644 WEB-INF/templates/2fa.tpl diff --git a/2fa.php b/2fa.php new file mode 100644 index 000000000..7c1728d28 --- /dev/null +++ b/2fa.php @@ -0,0 +1,87 @@ +isPost()) { + // Validate that browser_today parameter is in correct format. + $browser_today = $request->getParameter('browser_today'); + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + header('Location: access_denied.php'); + exit(); + } +} +// End of access checks. + +$cl_2fa_code = $request->getParameter('2fa_code'); +$cl_password = $request->getParameter('password'); + +$form = new Form('2faForm'); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'2fa_code','value'=>$cl_2fa_code)); +$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_login click. +$form->addInput(array('type'=>'submit','name'=>'btn_login','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.login'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_2fa_code)) $err->add($i18n->get('error.field'), $i18n->get('fprm.2fa.2fa_code')); + + if ($err->no()) { + // Use the "limit" plugin if we have one. Ignore include errors. + // The "limit" plugin is not required for normal operation of Time Tracker. + @include('plugins/limit/access_check.php'); + + if ($auth->doLogin($cl_login, $cl_password)) { + // Set current user date (as determined by user browser) into session. + $current_user_date = $request->getParameter('browser_today', null); + if ($current_user_date) + $_SESSION['date'] = $current_user_date; + + // Remember user login in a cookie. + setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); + + $user = new ttUser(null, $auth->getUserId()); + + // Determine if we have to additionally use two-factor authentication. + $config = $user->getConfigHelper(); + $use2FA = $config->getDefinedValue('2fa'); + if ($use2FA) { + + // TODO: send 2fa code to user. + $auth->doLogout(); + + header('Location: 2fa.php'); + exit(); + } + + // Redirect, depending on user role. + if ($user->can('administer_site')) { + header('Location: admin_groups.php'); + } elseif ($user->isClient()) { + header('Location: reports.php'); + } else { + header('Location: time.php'); + } + exit(); + } else + $err->add($i18n->get('error.auth')); + } +} // isPost + +if(!isTrue('MULTIORG_MODE') && !ttOrgHelper::getOrgs()) + $err->add($i18n->get('error.no_groups')); + +// Determine whether to show login hint. It is currently used only for Windows LDAP authentication. +$show_hint = ('ad' == isset($GLOBALS['AUTH_MODULE_PARAMS']['type']) ? $GLOBALS['AUTH_MODULE_PARAMS']['type'] : null); + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('show_hint', $show_hint); +$smarty->assign('onload', 'onLoad="document.loginForm.'.(!$cl_login?'login':'password').'.focus()"'); +$smarty->assign('about_text', $i18n->get('form.login.about')); +$smarty->assign('title', $i18n->get('title.login')); +$smarty->assign('content_page_name', '2fa.tpl'); +$smarty->display('index.tpl'); diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 6c577de0b..3bd936dd1 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -418,9 +418,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '¿Ha oblidat la seva paraula de pas?', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'S\\\'ha enviat la petició de restablir paraula de pas.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Sol·licitud de restabliment de la paraula de pas de Anuko Time Tracker', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index feee22377..a4f116022 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -425,9 +425,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zapomenuté heslo?', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Zaslán požadavek k vymazání hesla.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker požadavek na vymazání hesla', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 6a598edb7..d1b991f41 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -402,10 +402,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Har du glemt din adgangskode?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker er et open source tidsregistrerings system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Nulstilling af adgangskode er sendt på email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker - Anmodning om nulstilling af adgangskode', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index ad6727fba..75c2c0a72 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -389,10 +389,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Passwort vergessen?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker ist ein Open-Source Zeiterfassungssystem.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Anfrage zur Zurücksetzung des Passwortes wurde per E-mail gesendet.', 'form.reset_password.email_subject' => 'Anuko Time Tracker Anfrage zur Zurücksetzung des Passwortes', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 8df7601de..7adaceadc 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -374,6 +374,9 @@ 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Password reset request sent by email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 441b42586..a78f1e6f2 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -422,9 +422,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '¿Olvido su contraseña?', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. // TODO: check / improve translation of form.reset_password.message. // English form is: 'form.reset_password.message' => 'Password reset request sent by email.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 715b68bc4..854a52e00 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -410,10 +410,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Unustasid salasõna?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker on avatud lähtekoodiga ajaarvestussüsteem.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Salasõna tühistamise teade on saadetud e-postile.', 'form.reset_password.email_subject' => 'Anuko Time Tracker, parooli tühistamise nõue', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f470be335..bda4a4758 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -420,9 +420,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'بازیابی رمز عبور؟', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'درخواست بازیابی رمزعبور به ایمیل فرستاده شد.', // TODO: check translation of form.reset_password.email_subject. This is the subject for email message for password reset. Below is the English original. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index db157940c..1d90ef233 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -407,11 +407,13 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Salasana unohtunut?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', - // TODO: check translation of form.login.about - is open source "vapaan koodin"? +// TODO: check translation of form.login.about - is open source "vapaan koodin"? 'form.login.about' => 'Anuko Time Tracker on vapaan koodin tuntiseurantaohjelmisto.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Salasanan nollauspyyntöviesti lähetetty.', 'form.reset_password.email_subject' => 'Anuko Time Tracker -salasanan nollauspyyntö', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index d68e4cb44..ccb429359 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -399,10 +399,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Mot de passe oublié?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker est un système de gestion du temps, open source.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Une demande de réinitialisation du mot de passe a été envoyé par courriel.', 'form.reset_password.email_subject' => 'Demande de réinitialisation de mot de passe Anuko Time Tracker', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 7c8e39562..4cf1f64f9 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -398,10 +398,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Ξεχάσατε τον κωδικό πρόσβασης;', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker είναι ένα ανοικτού κώδικα σύστημα παρακολούθησης χρόνου.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Το αίτημα επαναφοράς κωδικού πρόσβασης αποστέλλεται μέσω ηλεκτρονικού ταχυδρομείου.', 'form.reset_password.email_subject' => 'Αίτημα επαναφοράς κωδικού Anuko Time Tracker', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index fddf8d50b..4342ea846 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -424,12 +424,14 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'שכחת סיסמה?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // TODO: re-translate form.login.about as it has changed. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker הינה מערכת פשוטה, קלה לשימוש וחינמית לניהול זמן.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'הבקשה לאיפוס בסיסמה נשלחה בדואר אלקטרוני.', 'form.reset_password.email_subject' => 'בקשה לאיפוס סיסמה למערכת Anuko Time Tracker', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index d3cbd7f93..b105d2483 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -419,9 +419,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Elfelejtetted a jelszót?', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. // TODO: translate the following. // 'form.reset_password.message' => 'Password reset request sent by email.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 8d2cfaa00..16727cfe7 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -408,10 +408,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Password dimenticata?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker è un sistema open source per registrare i tempi di lavoro.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Richiesta di reset password inviata via mail.', 'form.reset_password.email_subject' => 'Richiesta reset password per Anuko Time Tracker', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 3dc0b8773..46c705532 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -420,9 +420,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'パスワードを忘れましたか?', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => '送信したパスワードの初期化の要求。', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Trackerのパスワードの初期化の要求', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 63999c23f..a82356937 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -424,9 +424,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '암호를 잊으셨습니까?', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => '송신한 암호 재설정 요청.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker 암호 재설정 요청', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 131d79935..9a7c1707d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -363,10 +363,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Wachtwoord vergeten?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker is een open source tijdregistratiesysteem.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Het verzoek om het wachtwoord te herstellen is verzonden per email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker wachtwoord herstel verzoek', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index d2a934ee7..b7500bbaa 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -421,12 +421,14 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Glemt passordet?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // TODO: re-translate form.login.about as it has changed. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker er et enkelt, brukervennlig tidsregistreringssystem basert på åpen kildekode.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. // TODO: translate the following. // 'form.reset_password.message' => 'Password reset request sent by email.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 4316435a3..0e482eebe 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -410,10 +410,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Nie pamiętasz hasła?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker jest otwartoźródłowym systemem śledzenia czasu.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Instrukcje zmiany hasła zostały wysłane na adres e-mail połączony z kontem.', 'form.reset_password.email_subject' => 'Anuko Time Tracker - żądanie zmiany hasła', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index c5a670a0d..f0b564de9 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -362,10 +362,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Esqueceu a senha?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker é um sistema de código aberto de rastreamento do tempo.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Pedido para resetar a senha enviado por e-mail.', 'form.reset_password.email_subject' => 'Pedido de alteração de senha no Anuko Time Tracker', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index a40d8ed83..dcb0d0357 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -403,9 +403,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Esqueceu a senha?', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. // TODO: translate the following. // 'form.reset_password.message' => 'Password reset request sent by email.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 97c9a854f..7a5b41a3d 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -424,9 +424,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Parola pierduta?', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Cererea de resetare a parolei a fost trimisa.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker - cerere de resetare a parolei', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index faa1c7aba..da8d8b0f9 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -364,9 +364,11 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Забыли пароль?', -'form.login.2fa_code' => '2FA код', 'form.login.about' => 'Anuko Time Tracker - это открытая (open source) система трекинга рабочего времени.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +'form.2fa.2fa_code' => '2FA код', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Запрос на сброс пароля отослан по e-mail.', 'form.reset_password.email_subject' => 'Сброс пароля к Anuko Time Tracker', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 356e4e0a9..3bdc0e4bd 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -413,10 +413,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zabudnuté heslo?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker je systém na sledovanie času s otvoreným zdrojovým kódom.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Žiadosť o obnovenie hesla bola odoslaná e-mailom.', 'form.reset_password.email_subject' => 'Žiadosť o obnovenie hesla do Anuko Time Tracker', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 2bcba2362..d7406f37a 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -396,9 +396,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. // TODO: translate the following. // 'form.login.forgot_password' => 'Forgot password?', -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Zahteva za razveljavitev gesla je bila poslana.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker zahteva za razveljavitev gesla', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index dff5f2623..b26d4f04a 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -408,12 +408,14 @@ // Forma prijave. Pogledajte primer na https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zaboravili ste lozinku?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // TODO: re-translate form.login.about as it has changed. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker je jednostavan i lak za korišćenje za praćenje radnog vremena.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Izmena forme za lozinku. Pogledajte primer na https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Zahtev za izmenu lozinke je poslat mejlom.', 'form.reset_password.email_subject' => 'Anuko Time Tracker zahtev za izmenu lozinke', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 62a747e10..1c139a0e4 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -406,12 +406,14 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Glömt lösenordet?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // TODO: re-translate form.login.about as it has changed. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker är en lättanvänd applikation byggd med öppen källkod som enkelt låter dig spåra och hålla koll på arbetstider.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Begäran om att återställa lösenordet skickades via e-post.', 'form.reset_password.email_subject' => 'Återställning av lösenord för Anuko Time Tracker begärd', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index e0a291f09..9f57fa3e0 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -432,9 +432,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Parolanızı unuttunuz mu?', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Parola sıfırlama talebi yollandı.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker parola sıfırlama talebi', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7dc37961c..400529f60 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -413,12 +413,14 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '忘记密码?', -// TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // TODO: re-translate form.login.about as it has changed. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker 是一种简单、易用、开放源代码的实时跟踪系统。', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => '密码重设请求已经发送。', // TODO: Add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko时间追踪器密码重设请求', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 2497f7ce7..3ece1f0fc 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -418,9 +418,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '忘記密碼?', // TODO: translate the following. -// 'form.login.2fa_code' => '2FA code', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +// TODO: translate the following. +// 'form.2fa.2fa_code' => '2FA code', + // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => '密碼重設請求已經發送。', // TODO: Add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko時間追蹤器密碼重設請求', diff --git a/WEB-INF/templates/2fa.tpl b/WEB-INF/templates/2fa.tpl new file mode 100644 index 000000000..e634b624b --- /dev/null +++ b/WEB-INF/templates/2fa.tpl @@ -0,0 +1,24 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + +{$forms.2faForm.open} +
 Anuko Time Tracker 1.18.41.4764 | Copyright © Anuko | +  Anuko Time Tracker 1.18.41.4765 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6754f969082857965dc10f96e9a83fac3e9a3559 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 23 Feb 2019 22:30:31 +0000 Subject: [PATCH 0707/1848] Fixed timesheet_view.php. --- WEB-INF/templates/footer.tpl | 2 +- timesheet_view.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 63d61ef93..35edfc1ea 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.41.4765 | Copyright © Anuko | +  Anuko Time Tracker 1.18.41.4766 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_view.php b/timesheet_view.php index 5079fe7b7..27956c9d7 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -60,7 +60,7 @@ // Determine which controls to show and obtain date for them. $showSubmit = $notClient && !$timesheet['submit_status']; if ($showSubmit) $approvers = ttTimesheetHelper::getApprovers($timesheet['user_id']); -$canApprove = $user->can('approve_timesheets') || $user_>can('approve_all_timesheets'); +$canApprove = $user->can('approve_timesheets') || $user->can('approve_all_timesheets'); $showApprove = $notClient && $timesheet['submit_status'] && $timesheet['approval_status'] == null; // Add a form with controls. From 8b5e58e72a7d6ec9728f6890261f1ece2cfa7cc8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 24 Feb 2019 14:51:10 +0000 Subject: [PATCH 0708/1848] Improved usability by hiding not relevant controls for client users. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/user_add.tpl | 17 +++++++++++------ WEB-INF/templates/mobile/user_edit.tpl | 14 ++++++++++---- WEB-INF/templates/user_add.tpl | 14 +++++++++----- WEB-INF/templates/user_edit.tpl | 13 +++++++++---- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 35edfc1ea..c99fe708f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - - - + {if $show_quota} {/if} + + + + + {if $show_projects} + +{/if} - -{/if} diff --git a/WEB-INF/templates/mobile/user_edit.tpl b/WEB-INF/templates/mobile/user_edit.tpl index 6bddbb99f..03c5db2ef 100644 --- a/WEB-INF/templates/mobile/user_edit.tpl +++ b/WEB-INF/templates/mobile/user_edit.tpl @@ -56,6 +56,7 @@ function setRate(element) { function handleClientControl() { var selectedRoleId = document.getElementById("role").value; var clientControl = document.getElementById("client"); + var nonClientBlock = document.getElementById("non_client_block"); var projectsControl = document.getElementById("projects_control"); var len = roles.length; @@ -64,6 +65,7 @@ function handleClientControl() { var isClient = roles[i][1]; if (isClient == 1) { clientControl.style.visibility = "visible"; + nonClientBlock.style.display = "none"; projectsControl.style.display = "none"; // Uncheck all project checkboxes. @@ -75,6 +77,7 @@ function handleClientControl() { } else { clientControl.value = ""; clientControl.style.visibility = "hidden"; + nonClientBlock.style.display = ""; projectsControl.style.display = ""; } break; @@ -83,6 +86,7 @@ function handleClientControl() { } + {$forms.userForm.open}
 Anuko Time Tracker 1.18.41.4766 | Copyright © Anuko | +  Anuko Time Tracker 1.18.41.4767 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/user_add.tpl b/WEB-INF/templates/mobile/user_add.tpl index 1bde81b18..9df99ff00 100644 --- a/WEB-INF/templates/mobile/user_add.tpl +++ b/WEB-INF/templates/mobile/user_add.tpl @@ -34,6 +34,7 @@ function setDefaultRate(element) { function handleClientControl() { var selectedRoleId = document.getElementById("role").value; var clientControl = document.getElementById("client"); + var nonClientBlock = document.getElementById("non_client_block"); var projectsControl = document.getElementById("projects_control"); var len = roles.length; @@ -42,6 +43,7 @@ function handleClientControl() { var isClient = roles[i][1]; if (isClient == 1) { clientControl.style.visibility = "visible"; + nonClientBlock.style.display = "none"; projectsControl.style.display = "none"; // Uncheck all project checkboxes. @@ -53,6 +55,7 @@ function handleClientControl() { } else { clientControl.value = ""; clientControl.style.visibility = "hidden"; + nonClientBlock.style.display = ""; projectsControl.style.display = ""; } break; @@ -90,27 +93,29 @@ function handleClientControl() { {$i18n.form.users.role}: {$forms.userForm.role.control} {$forms.userForm.client.control}
{$i18n.form.users.default_rate} (0{$user->decimal_mark}00):{$forms.userForm.rate.control}
{$i18n.label.quota} (%): {$forms.userForm.quota_percent.control}
{$i18n.form.users.default_rate} (0{$user->decimal_mark}00):{$forms.userForm.rate.control}
{$i18n.label.projects}: {$forms.userForm.projects.control}
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
@@ -118,16 +122,18 @@ function handleClientControl() { {/if} - - - - + {if $show_quota} {/if} + + + + + {if $show_projects} diff --git a/WEB-INF/templates/user_add.tpl b/WEB-INF/templates/user_add.tpl index c6dbaa7bb..155bf11cc 100644 --- a/WEB-INF/templates/user_add.tpl +++ b/WEB-INF/templates/user_add.tpl @@ -34,6 +34,7 @@ function setDefaultRate(element) { function handleClientControl() { var selectedRoleId = document.getElementById("role").value; var clientControl = document.getElementById("client"); + var nonClientBlock = document.getElementById("non_client_block"); var projectsControl = document.getElementById("projects_control"); var len = roles.length; @@ -42,6 +43,7 @@ function handleClientControl() { var isClient = roles[i][1]; if (isClient == 1) { clientControl.style.visibility = "visible"; + nonClientBlock.style.display = "none"; projectsControl.style.display = "none"; // Uncheck all project checkboxes. @@ -53,6 +55,7 @@ function handleClientControl() { } else { clientControl.value = ""; clientControl.style.visibility = "hidden"; + nonClientBlock.style.display = ""; projectsControl.style.display = ""; } break; @@ -90,16 +93,18 @@ function handleClientControl() { - - - - + {if $show_quota} {/if} + + + + + {if $show_projects} @@ -112,7 +117,6 @@ function handleClientControl() { - diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index 2bba1842d..e17651b21 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -56,6 +56,7 @@ function setRate(element) { function handleClientControl() { var selectedRoleId = document.getElementById("role").value; var clientControl = document.getElementById("client"); + var nonClientBlock = document.getElementById("non_client_block"); var projectsControl = document.getElementById("projects_control"); var len = roles.length; @@ -64,6 +65,7 @@ function handleClientControl() { var isClient = roles[i][1]; if (isClient == 1) { clientControl.style.visibility = "visible"; + nonClientBlock.style.display = "none"; projectsControl.style.display = "none"; // Uncheck all project checkboxes. @@ -75,6 +77,7 @@ function handleClientControl() { } else { clientControl.value = ""; clientControl.style.visibility = "hidden"; + nonClientBlock.style.display = ""; projectsControl.style.display = ""; } break; @@ -124,16 +127,18 @@ function handleClientControl() { {/if} - - - - + {if $show_quota} {/if} + + + + + {if $show_projects} From ce36d3475dd1ad6e38f95ac410e27c7c19d03ca1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 24 Feb 2019 15:52:47 +0000 Subject: [PATCH 0709/1848] Added approved field to tt_log and tt_expense_items tables. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 2 ++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c99fe708f..3594a9f4b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$forms.userForm.status.control}
{$i18n.form.users.default_rate} (0{$user->decimal_mark}00):{$forms.userForm.rate.control}
{$i18n.label.quota} (%): {$forms.userForm.quota_percent.control}
{$i18n.form.users.default_rate} (0{$user->decimal_mark}00):{$forms.userForm.rate.control}
{$i18n.form.users.role}: {$forms.userForm.role.control} {$forms.userForm.client.control}
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00):{$forms.userForm.rate.control}
{$i18n.label.quota} (%): {$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00):{$forms.userForm.rate.control}
 
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
{$user->role_name} {if $can_swap}{$i18n.form.user_edit.swap_roles}{/if}
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00):{$forms.userForm.rate.control}
{$i18n.label.quota} (%): {$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00):{$forms.userForm.rate.control}
 
- - - + +
 Anuko Time Tracker 1.18.41.4767 | Copyright © Anuko | +  Anuko Time Tracker 1.18.41.4768 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index f700d99ee..8babd31e0 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11841"]) { + if ($_POST["convert11797to11842"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1085,6 +1085,9 @@ function ttExecute($sql) { ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.40', modified = now() where param_name = 'version_db' and param_value = '1.18.39'"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.40') set rights = replace(rights, 'view_client_timesheets,view_client_invoices', 'view_client_timesheets,view_client_unapproved,view_client_invoices') where rank = 16"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.41', modified = now() where param_name = 'version_db' and param_value = '1.18.40'"); + ttExecute("ALTER TABLE `tt_log` ADD `approved` tinyint(4) default 0 AFTER `billable`"); + ttExecute("ALTER TABLE `tt_expense_items` ADD `approved` tinyint(4) default 0 AFTER `invoice_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.42', modified = now() where param_name = 'version_db' and param_value = '1.18.41'"); } if ($_POST["cleanup"]) { @@ -1133,7 +1136,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.41) + Create database structure (v1.18.42)
(applies only to new installations, do not execute when updating)
@@ -1178,8 +1181,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.41)Update database structure (v1.17.97 to v1.18.42)
diff --git a/mysql.sql b/mysql.sql index 2a507ee21..d79e9d7bf 100644 --- a/mysql.sql +++ b/mysql.sql @@ -201,6 +201,7 @@ CREATE TABLE `tt_log` ( `invoice_id` int(11) default NULL, # invoice id `comment` text, # user provided comment for time record `billable` tinyint(4) default 0, # whether the record is billable or not + `approved` tinyint(4) default 0, # whether the record is approved `paid` tinyint(4) default 0, # whether the record is paid `created` datetime default NULL, # creation timestamp `created_ip` varchar(45) default NULL, # creator ip @@ -431,6 +432,7 @@ CREATE TABLE `tt_expense_items` ( `name` text NOT NULL, # expense item name (what is an expense for) `cost` decimal(10,2) default '0.00', # item cost (including taxes, etc.) `invoice_id` int(11) default NULL, # invoice id + `approved` tinyint(4) default 0, # whether the item is approved `paid` tinyint(4) default 0, # whether the item is paid `created` datetime default NULL, # creation timestamp `created_ip` varchar(45) default NULL, # creator ip From 1e2a1839bd4b4530a43dfcdc3f0582623edd5486 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 24 Feb 2019 16:35:18 +0000 Subject: [PATCH 0710/1848] Introduced approve_reports and approve_all_reports rights. --- WEB-INF/lib/ttRoleHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 12 ++++++++---- mysql.sql | 4 ++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 92f6bec32..0be33d55a 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -191,7 +191,7 @@ static function createPredefinedRoles($group_id, $lang) $rights_client = 'view_client_reports,view_client_timesheets,view_client_unapproved,view_client_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; - $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; + $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; $rights_manager = $rights_comanager.',manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; @@ -254,7 +254,7 @@ static function createPredefinedRoles_1_17_44($group_id, $lang) $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; - $rights_manager = $rights_comanager.',manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; + $rights_manager = $rights_comanager.',manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups'; // Active roles. $name = $mdb2->quote($i18n->get('role.user.label')); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3594a9f4b..2ed9b3f0e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.41.4768 | Copyright © Anuko | +  Anuko Time Tracker 1.18.43.4769 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 8babd31e0..6124857b1 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11842"]) { + if ($_POST["convert11797to11843"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1088,6 +1088,10 @@ function ttExecute($sql) { ttExecute("ALTER TABLE `tt_log` ADD `approved` tinyint(4) default 0 AFTER `billable`"); ttExecute("ALTER TABLE `tt_expense_items` ADD `approved` tinyint(4) default 0 AFTER `invoice_id`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.42', modified = now() where param_name = 'version_db' and param_value = '1.18.41'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_unapproved,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,delete_group' where rank = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = replace(rights, 'view_reports,view_timesheets', 'view_reports,approve_reports,view_timesheets') where rank = 12 or rank = 68 or rank = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = replace(rights, 'export_data,approve_all_timesheets', 'export_data,approve_all_reports,approve_all_timesheets') where rank = 324"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.43', modified = now() where param_name = 'version_db' and param_value = '1.18.42'"); } if ($_POST["cleanup"]) { @@ -1136,7 +1140,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.42) + Create database structure (v1.18.43)
(applies only to new installations, do not execute when updating)
@@ -1181,8 +1185,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.42)Update database structure (v1.17.97 to v1.18.43)
diff --git a/mysql.sql b/mysql.sql index d79e9d7bf..8b1859190 100644 --- a/mysql.sql +++ b/mysql.sql @@ -75,7 +75,7 @@ create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_unapproved,view_client_invoices,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_unapproved,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,delete_group'); # @@ -520,4 +520,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.41', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.43', now()); # TODO: change when structure changes. From af80607509fae805aae37ba966f24aa50986fe9d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 24 Feb 2019 17:33:22 +0000 Subject: [PATCH 0711/1848] Work on progress on report approval plugin. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/plugins.tpl | 8 +++++++- plugins.php | 5 +++++ 33 files changed, 43 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 8b3d5d6f7..692fc3573 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -270,6 +270,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 17ea3e261..55845055c 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -280,6 +280,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 2a786b143..11295b152 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -257,6 +257,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Fejl', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 5e72116ba..99ec90867 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -245,6 +245,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Fehler', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 1fdd6111a..361b9d819 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -235,6 +235,7 @@ 'label.timesheet' => 'Timesheet', 'label.submitted' => 'Submitted', 'label.approved' => 'Approved', +'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Error', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 559e3286c..37ba0d2da 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -273,6 +273,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 71a1288c5..0d514ba16 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -260,6 +260,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index b5bed52c6..f30109a04 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -267,6 +267,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'خطا', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index c10ca5ea1..97065c45e 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -261,6 +261,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Virhe', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index b937b771b..150e018f1 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -255,6 +255,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Erreur', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index c5e8d5e86..28ebbe445 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -248,6 +248,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Σφάλμα', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index b2a7dfd1c..7dbb615c6 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -278,6 +278,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'שגיאה', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index f6bceaeeb..57cec891b 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -274,6 +274,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index fc8a08157..92b17f592 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -252,6 +252,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 7f83a7677..680cd280e 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -279,6 +279,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index aa40a0945..af3099ce4 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -279,6 +279,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index ee170ceed..ce08d7585 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -238,6 +238,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Fout', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index e43dad9b4..3b6925d06 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -277,6 +277,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 9b243eefa..27985c62d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -262,6 +262,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Błąd', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 71fcef6f9..7afd6f8b4 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -259,6 +259,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Erro', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 0723acffa..681731839 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -264,6 +264,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index b94bcd988..e279672de 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -277,6 +277,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 19bedf9b4..6edbfbedf 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -234,6 +234,7 @@ 'label.timesheet' => 'Табель учёта', 'label.submitted' => 'Подано', 'label.approved' => 'Одобрено', +'label.approval' => 'Одобрение отчётов', // Form titles. 'title.error' => 'Ошибка', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d3525c0d6..f593a8ab0 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -267,6 +267,7 @@ // 'label.quota' => 'Quota', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Chyba', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index fedc796ab..86695a4ad 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -260,6 +260,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 229100788..3c8df9237 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -260,6 +260,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. 'title.error' => 'Greška', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 480650e4a..516ab1300 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -256,6 +256,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Rubriker för formulär 'title.error' => 'Fel', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 87b44ca09..7b926fd73 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -283,6 +283,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // Form titles. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 9d03e7b0f..57fc9ebe3 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -267,6 +267,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index e488dbd68..130683d2c 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -274,6 +274,7 @@ // 'label.timesheet' => 'Timesheet', // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', +// 'label.approval' => 'Report approval', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2ed9b3f0e..2358030be 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +{if isTrue('APPROVAL_DEBUG')} + + + + +{/if} {if isTrue('TIMESHEET_DEBUG')} - + {/if} diff --git a/plugins.php b/plugins.php index 64615aa25..0981cb77a 100644 --- a/plugins.php +++ b/plugins.php @@ -51,6 +51,7 @@ $cl_quotas = $request->getParameter('quotas'); $cl_week_view = $request->getParameter('week_view'); $cl_work_units = $request->getParameter('work_units'); + $cl_approval = $request->getParameter('approval'); $cl_timesheets = $request->getParameter('timesheets'); } else { // Note: we get here in get, and also in post when group changes. @@ -69,6 +70,7 @@ $cl_quotas = in_array('mq', $plugins); $cl_week_view = in_array('wv', $plugins); $cl_work_units = in_array('wu', $plugins); + $cl_approval = in_array('ap', $plugins); $cl_timesheets = in_array('ts', $plugins); } @@ -88,6 +90,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'quotas','value'=>$cl_quotas,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'checkbox','name'=>'week_view','value'=>$cl_week_view,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'checkbox','name'=>'work_units','value'=>$cl_work_units,'onchange'=>'handlePluginCheckboxes()')); +$form->addInput(array('type'=>'checkbox','name'=>'approval','value'=>$cl_approval)); $form->addInput(array('type'=>'checkbox','name'=>'timesheets','value'=>$cl_timesheets)); // Submit button. $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); @@ -123,6 +126,8 @@ $plugins .= ',wv'; if ($cl_work_units) $plugins .= ',wu'; + if ($cl_approval) + $plugins .= ',ap'; if ($cl_timesheets) $plugins .= ',ts'; From 0eec39b28e4c408f92f9f99ede99e68640ef94d0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 24 Feb 2019 17:36:43 +0000 Subject: [PATCH 0712/1848] Cosmetic maintenance tune-up. --- WEB-INF/lib/ttOrgHelper.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index beb523378..461c751de 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -63,7 +63,7 @@ static function getName($org_id) { return false; } - // The getInactiveOrgs is a maintenance function that returns an array of inactive organization ids (max 5 for now). + // The getInactiveOrgs is a maintenance function that returns an array of inactive organization ids (max 10 for now). static function getInactiveOrgs() { $inactive_orgs = array(); $mdb2 = getConnection(); @@ -72,7 +72,7 @@ static function getInactiveOrgs() { $cutoff_timestamp = $mdb2->quote(date('Y-m-d', strtotime('-1 year'))); $sql = "select org_id from". " (select max(accessed) as last_access, org_id from tt_users where org_id > 0 group by org_id order by last_access, org_id) as t". - " where last_access is null or last_access < $cutoff_timestamp limit 5"; // Max 5 orgs at a time for now... + " where last_access is null or last_access < $cutoff_timestamp limit 10"; // Max 10 orgs at a time for now... $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { From 707afc287a1593f86b392f9146346060c7e95957 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 24 Feb 2019 18:07:06 +0000 Subject: [PATCH 0713/1848] Added controls for report approval options on reports.php. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 7 +++++++ reports.php | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2358030be..a20299b98 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.43.4769 | Copyright © Anuko | +  Anuko Time Tracker 1.18.43.4770 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index e252e32a9..ce0cd52ab 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -134,10 +134,16 @@ function handlePluginCheckboxes() { {$forms.pluginsForm.work_units.control} {$i18n.label.configure}
{$forms.pluginsForm.approval.control}
{$forms.pluginsForm.timesheets.control}
- {/if} +{if $show_approved} + + +{/if} {if $show_invoice_dropdown} @@ -289,6 +293,9 @@ function handleCheckboxes() { {/if} +{if $show_approved} + +{/if} {if $show_invoice_checkbox} {/if} diff --git a/reports.php b/reports.php index fdb2d2ed3..d8bf40995 100644 --- a/reports.php +++ b/reports.php @@ -198,6 +198,19 @@ ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets') || $user->can('view_client_timesheets')); +// Add approved / not approved selector. +$showApproved = $user->isPluginEnabled('ap') && + ($user->can('view_own_reports') || $user->can('view_reports') || + $user->can('view_all_reports') || ($user->can('view_client_reports') && $user->can('view_client_unapproved'))); +if ($showApproved) { + $form->addInput(array('type'=>'combobox', + 'name'=>'approved', + 'style'=>'width: 250px;', + 'data'=>array('1'=>$i18n->get('form.reports.include_approved'),'2'=>$i18n->get('form.reports.include_not_approved')), + 'empty'=>array(''=>$i18n->get('dropdown.all')) + )); +} + // Add user table. $showUsers = $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient(); $user_list = array(); @@ -279,6 +292,8 @@ $form->addInput(array('type'=>'checkbox','name'=>'chunits')); if ($showTimesheetCheckbox) $form->addInput(array('type'=>'checkbox','name'=>'chtimesheet')); +if ($showApproved) + $form->addInput(array('type'=>'checkbox','name'=>'chapproved')); // Add a hidden control for timesheet_user_id (who to generate a timesheet for). if ($showTimesheetCheckbox) @@ -428,6 +443,7 @@ $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); $smarty->assign('show_billable', $showBillable); +$smarty->assign('show_approved', $showApproved); $smarty->assign('show_invoice_dropdown', $showInvoiceDropdown); $smarty->assign('show_invoice_checkbox', $showInvoiceCheckbox); $smarty->assign('show_paid_status', $showPaidStatus); From a001599f5d6f1a803a279e602d3333cc036b69cc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 24 Feb 2019 19:05:46 +0000 Subject: [PATCH 0714/1848] Made approval control filtering work on reports. --- WEB-INF/lib/ttReportHelper.class.php | 12 ++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 5 +++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index ac3582e68..5d9de074e 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -72,6 +72,8 @@ static function getWhere($options) { if ($options['invoice']=='2') $dropdown_parts .= ' and l.invoice_id is null'; if ($options['timesheet']==TIMESHEET_NOT_ASSIGNED) $dropdown_parts .= ' and l.timesheet_id is null'; if ($options['timesheet']==TIMESHEET_ASSIGNED) $dropdown_parts .= ' and l.timesheet_id is not null'; + if ($options['approved']=='1') $dropdown_parts .= ' and l.approved = 1'; + if ($options['approved']=='2') $dropdown_parts .= ' and l.approved = 0'; if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; @@ -122,6 +124,8 @@ static function getExpenseWhere($options) { if ($options['invoice']=='2') $dropdown_parts .= ' and ei.invoice_id is null'; if ($options['timesheet']==TIMESHEET_NOT_ASSIGNED) $dropdown_parts .= ' and ei.timesheet_id is null'; if ($options['timesheet']==TIMESHEET_ASSIGNED) $dropdown_parts .= ' and ei.timesheet_id is not null'; + if ($options['approved']=='1') $dropdown_parts .= ' and ei.approved = 1'; + if ($options['approved']=='2') $dropdown_parts .= ' and ei.approved = 0'; if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; @@ -233,6 +237,9 @@ static function getItems($options) { array_push($fields, "cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use project rate for user. array_push($fields, "null as expense"); } + // Add approved. + if ($options['show_approved']) + array_push($fields, 'l.approved'); // Add paid status. if ($canViewReports && $options['show_paid']) array_push($fields, 'l.paid'); @@ -329,6 +336,9 @@ static function getItems($options) { array_push($fields, 'ei.name as note'); array_push($fields, 'ei.cost as cost'); array_push($fields, 'ei.cost as expense'); + // Add approved. + if ($options['show_approved']) + array_push($fields, 'ei.approved'); // Add paid status. if ($canViewReports && $options['show_paid']) array_push($fields, 'ei.paid'); @@ -1053,6 +1063,7 @@ static function getReportOptions($bean) { $options['billable'] = $bean->getAttribute('include_records'); $options['invoice'] = $bean->getAttribute('invoice'); $options['paid_status'] = $bean->getAttribute('paid_status'); + $options['approved'] = $bean->getAttribute('approved'); $options['timesheet'] = $bean->getAttribute('timesheet'); if ($user->isPluginEnabled('ts') && $user->isClient() && !$user->can('view_client_unapproved')) $options['timesheet'] = TIMESHEET_APPROVED; // Restrict clients to approved timesheet records only. @@ -1062,6 +1073,7 @@ static function getReportOptions($bean) { $options['period_end'] = $bean->getAttribute('end_date'); $options['show_client'] = $bean->getAttribute('chclient'); $options['show_invoice'] = $bean->getAttribute('chinvoice'); + $options['show_approved'] = $bean->getAttribute('chapproved'); $options['show_paid'] = $bean->getAttribute('chpaid'); $options['show_ip'] = $bean->getAttribute('chip'); $options['show_project'] = $bean->getAttribute('chproject'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a20299b98..a06110665 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.43.4770 | Copyright © Anuko | +  Anuko Time Tracker 1.18.43.4771 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 07c398346..1358d29de 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -212,6 +212,10 @@ function handleCheckboxes() {
{$i18n.label.task}
{$forms.reportForm.task.control}
{$i18n.label.approved}
{$forms.reportForm.approved.control}
{$i18n.label.invoice}
{$forms.reportForm.invoice.control}
- {/if} {if $bean->getAttribute('chnote')}{/if} {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} {if $bean->getAttribute('chinvoice')}{/if} @@ -74,6 +75,7 @@ {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote')}{/if} {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} {if $bean->getAttribute('chinvoice')}{/if} @@ -101,6 +103,7 @@ {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote')}{/if} {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} @@ -128,6 +131,7 @@ {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote')}{/if} {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} {if $bean->getAttribute('chinvoice')}{/if} @@ -150,6 +154,7 @@ {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote')}{/if} {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} {if $bean->getAttribute('chinvoice')}{/if} From 72c8ed85c06c6808aff2e967f35f5db45f9ba750 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 24 Feb 2019 22:02:23 +0000 Subject: [PATCH 0715/1848] Fixed export to files and PDF with approved column. --- WEB-INF/templates/footer.tpl | 2 +- tofile.php | 3 +++ topdf.php | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a06110665..6cb7a8068 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.43.4771 | Copyright © Anuko | +  Anuko Time Tracker 1.18.43.4772 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index f62929f9f..0de892ee6 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -50,6 +50,7 @@ {if $bean->getAttribute('chunits')}{$i18n.label.work_units_short}{$i18n.label.note}{$i18n.label.cost}{$i18n.label.approved}{$i18n.label.paid}{$i18n.label.ip}{$i18n.label.invoice}{$subtotals[$prev_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}{$item.units}{$item.note|escape}{if $user->can('manage_invoices') || $user->isClient()}{$item.cost}{else}{$item.expense}{/if}{if $item.approved == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{/if} {if $bean->getAttribute('chpaid')}{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{/if} {if $bean->getAttribute('chip')}{if $item.modified}{$item.modified_ip} {$item.modified}{else}{$item.created_ip} {$item.created}{/if}{/if} {if $bean->getAttribute('chinvoice')}{$item.invoice|escape}{$subtotals[$cur_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$cur_grouped_by]['cost']}{else}{$subtotals[$cur_grouped_by]['expenses']}{/if}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
- '; } if ($bean->getAttribute('chnote')) { $colspan++; $html .= ''; } if ($bean->getAttribute('chcost')) { $colspan++; $html .= "'; } + if ($bean->getAttribute('chapproved')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chpaid')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chip')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chinvoice')) { $colspan++; $html .= ''; } @@ -209,6 +210,7 @@ $html .= $subtotals[$prev_grouped_by]['expenses']; $html .= ''; } + if ($bean->getAttribute('chapproved')) $html .= ''; if ($bean->getAttribute('chpaid')) $html .= ''; if ($bean->getAttribute('chip')) $html .= ''; if ($bean->getAttribute('chinvoice')) $html .= ''; @@ -240,6 +242,11 @@ $html .= $item['expense']; $html .= ''; } + if ($bean->getAttribute('chapproved')) { + $html .= ''; + } if ($bean->getAttribute('chpaid')) { $html .= ''; } + if ($bean->getAttribute('chapproved')) $html .= ''; if ($bean->getAttribute('chpaid')) $html .= ''; if ($bean->getAttribute('chip')) $html .= ''; if ($bean->getAttribute('chinvoice')) $html .= ''; @@ -329,6 +337,7 @@ $html .= $totals['expenses']; $html .= ''; } + if ($bean->getAttribute('chapproved')) $html .= ''; if ($bean->getAttribute('chpaid')) $html .= ''; if ($bean->getAttribute('chip')) $html .= ''; if ($bean->getAttribute('chinvoice')) $html .= ''; From 2ad495c118de835e3c6902a328b153d30bc3b0fa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 24 Feb 2019 23:26:25 +0000 Subject: [PATCH 0716/1848] Fixed creating invoices by excluding uncompleted records. --- WEB-INF/lib/ttInvoiceHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index becea87bc..4c1bd2b06 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -351,7 +351,7 @@ static function createInvoice($fields) { " where l.status = 1 and l.client_id = $client_id and l.invoice_id is null". " and l.group_id = $group_id and l.org_id = $org_id". " and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end). - " and l.billable = 1"; // l.billable * u.rate * time_to_sec(l.duration)/3600 > 0"; // See explanation below. + " and l.duration > 0 and l.billable = 1"; // l.billable * u.rate * time_to_sec(l.duration)/3600 > 0"; // See explanation below. } else { // sql part for project id. if ($project_id) $project_part = " and l.project_id = $project_id"; @@ -363,7 +363,7 @@ static function createInvoice($fields) { " where l.status = 1 and l.client_id = $client_id $project_part and l.invoice_id is null". " and l.group_id = $group_id and l.org_id = $org_id". " and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end). - " and l.billable = 1"; // l.billable * upb.rate * time_to_sec(l.duration)/3600 > 0"; + " and l.duration > 0 and l.billable = 1"; // l.billable * upb.rate * time_to_sec(l.duration)/3600 > 0"; // Users with a lot of clients and projects (Jaro) may forget to set user rates properly. // Specifically, user rate may be set to 0 on a project, by mistake. This leads to error.no_invoiceable_items // and increased support cost. Commenting out allows us to include 0 cost items in invoices so that diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6cb7a8068..62960af62 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.43.4772 | Copyright © Anuko | +  Anuko Time Tracker 1.18.43.4773 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/tofile.php b/tofile.php index f4d5b29e8..9399c787c 100644 --- a/tofile.php +++ b/tofile.php @@ -140,6 +140,7 @@ print $item['expense']; print "]]>\n"; } + if ($bean->getAttribute('chapproved')) print "\t\n"; if ($bean->getAttribute('chpaid')) print "\t\n"; if ($bean->getAttribute('chip')) { $ip = $item['modified'] ? $item['modified_ip'].' '.$item['modified'] : $item['created_ip'].' '.$item['created']; @@ -207,6 +208,7 @@ if ($bean->getAttribute('chunits')) print ',"'.$i18n->get('label.work_units_short').'"'; if ($bean->getAttribute('chnote')) print ',"'.$i18n->get('label.note').'"'; if ($bean->getAttribute('chcost')) print ',"'.$i18n->get('label.cost').'"'; + if ($bean->getAttribute('chapproved')) print ',"'.$i18n->get('label.approved').'"'; if ($bean->getAttribute('chpaid')) print ',"'.$i18n->get('label.paid').'"'; if ($bean->getAttribute('chip')) print ',"'.$i18n->get('label.ip').'"'; if ($bean->getAttribute('chinvoice')) print ',"'.$i18n->get('label.invoice').'"'; @@ -237,6 +239,7 @@ else print ',"'.$item['expense'].'"'; } + if ($bean->getAttribute('chapproved')) print ',"'.$item['approved'].'"'; if ($bean->getAttribute('chpaid')) print ',"'.$item['paid'].'"'; if ($bean->getAttribute('chip')) { $ip = $item['modified'] ? $item['modified_ip'].' '.$item['modified'] : $item['created_ip'].' '.$item['created']; diff --git a/topdf.php b/topdf.php index a0be19ec4..8e0738d4c 100644 --- a/topdf.php +++ b/topdf.php @@ -156,6 +156,7 @@ if ($bean->getAttribute('chunits')) { $colspan++; $html .= "".$i18n->get('label.work_units_short').''.$i18n->get('label.note').'".$i18n->get('label.cost').'".$i18n->get('label.approved').'".$i18n->get('label.paid').'".$i18n->get('label.ip').''.$i18n->get('label.invoice').''; + $html .= $item['approved'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); + $html .= ''; $html .= $item['paid'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); @@ -300,6 +307,7 @@ $html .= $subtotals[$prev_grouped_by]['expenses']; $html .= '
- {/if} - {if ($user->exists() && $user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts'))) && + {if ($user->exists() && $user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts') || $user->can('view_all_charts'))) && (constant('MODE_PROJECTS') == $user->getTrackingMode() || constant('MODE_PROJECTS_AND_TASKS') == $user->getTrackingMode() || $user->isPluginEnabled('cl'))} diff --git a/WEB-INF/templates/site_map.tpl b/WEB-INF/templates/site_map.tpl index 54ff8818d..8688f7677 100644 --- a/WEB-INF/templates/site_map.tpl +++ b/WEB-INF/templates/site_map.tpl @@ -37,7 +37,7 @@ {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->can('view_client_invoices'))} {/if} - {if ($user->exists() && $user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts'))) && + {if ($user->exists() && $user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts') || $user->can('view_all_charts'))) && (constant('MODE_PROJECTS') == $user->getTrackingMode() || constant('MODE_PROJECTS_AND_TASKS') == $user->getTrackingMode() || $user->isPluginEnabled('cl'))} diff --git a/charts.php b/charts.php index 88878f6b0..cfd01c5fe 100644 --- a/charts.php +++ b/charts.php @@ -13,8 +13,10 @@ import('ttUserHelper'); import('ttTeamHelper'); +define('ALL_USERS_OPTION_ID', -1); // An identifier for "all users" seclection in User dropdown. + // Access checks. -if (!(ttAccessAllowed('view_own_charts') || ttAccessAllowed('view_charts'))) { +if (!(ttAccessAllowed('view_own_charts') || ttAccessAllowed('view_charts') || ttAccessAllowed('view_all_charts'))) { header('Location: access_denied.php'); exit(); } @@ -26,7 +28,7 @@ header('Location: access_denied.php'); // Nobody to display a chart for. exit(); } -if ($user->behalf_id && (!$user->can('view_charts') || !$user->checkBehalfId())) { +if ($user->behalf_id && (!($user->can('view_charts') || $user->can('view_all_charts')) || !$user->checkBehalfId())) { header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. exit(); } @@ -34,8 +36,13 @@ header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to view on behalf. exit(); } +$userDropdownSelectionId = (int) $request->getParameter('user'); // Resused below access checks. if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid((int)$request->getParameter('user'))) { + if ($userDropdownSelectionId == constant('ALL_USERS_OPTION_ID') && !ttAccessAllowed('view_all_charts')) { + header('Location: access_denied.php'); // All users option is only for users with view_all_charts access right. + exit(); + } + if ($userDropdownSelectionId != constant('ALL_USERS_OPTION_ID') && !$user->isUserValid($userDropdownSelectionId)) { header('Location: access_denied.php'); // Wrong user id on post. exit(); } @@ -47,13 +54,16 @@ } // End of access checks. -// Determine user for which we display this page. -$userChanged = (int)$request->getParameter('user_changed'); -if ($request->isPost() && $userChanged) { - $user_id = (int)$request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); +// Determine user for whom we display this page. +$userChanged = (int) $request->getParameter('user_changed'); +if ($request->isPost() && $userChanged ) { + if ($userDropdownSelectionId != constant('ALL_USERS_OPTION_ID')) { + $user->setOnBehalfUser($userDropdownSelectionId); + } +} +if ($request->isGet()) { + $userDropdownSelectionId = $user->getUser(); + // Note that this may change to ALL_USERS_OPTION_ID below from session. } $uc = new ttUserConfig(); @@ -77,6 +87,9 @@ if (!$cl_type) $cl_type = ttChartHelper::adjustType($cl_type); $_SESSION['chart_type'] = $cl_type; $uc->setValue(SYSC_CHART_TYPE, $cl_type); + + // Remember all users selection in session. + $_SESSION['chart_all_users'] = $userDropdownSelectionId == constant('ALL_USERS_OPTION_ID') ? true : false; } else { // Initialize chart interval. $cl_interval = @$_SESSION['chart_interval']; @@ -89,6 +102,11 @@ if (!$cl_type) $cl_type = $uc->getValue(SYSC_CHART_TYPE); $cl_type = ttChartHelper::adjustType($cl_type); $_SESSION['chart_type'] = $cl_type; + + // Set user selection to all users, if necessary. + $allUsersSetInSession = @$_SESSION['chart_all_users']; + if ($allUsersSetInSession) + $userDropdownSelectionId = constant('ALL_USERS_OPTION_ID'); } // Elements of chartForm. @@ -96,18 +114,22 @@ $largeScreenCalendarRowSpan = 1; // Number of rows calendar spans on large screens. // User dropdown. Changes the user "on behalf" of whom we are working. -if ($user->can('view_charts')) { +if ($user->can('view_charts') || $user->can('view_all_charts')) { $rank = $user->getMaxRankForGroup($user->getGroup()); if ($user->can('view_own_charts')) $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); else $options = array('status'=>ACTIVE,'max_rank'=>$rank); $user_list = $user->getUsers($options); + // Add the --- all --- option to dropdown. + if ($user->can('view_all_charts')) { + $user_list[] = array('id'=>'-1','group_id'=>$user->getGroup(), 'name'=>$i18n->get('dropdown.all'), 'rights'=>''); + } if (count($user_list) >= 1) { $chart_form->addInput(array('type'=>'combobox', 'onchange'=>'this.form.user_changed.value=1;this.form.submit();', 'name'=>'user', - 'value'=>$user_id, + 'value'=>$userDropdownSelectionId, 'data'=>$user_list, 'datakeys'=>array('id','name'), )); @@ -159,7 +181,7 @@ $chart_form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar // Get data for our chart. -$totals = ttChartHelper::getTotals($user_id, $cl_type, $cl_date, $cl_interval); +$totals = ttChartHelper::getTotals($userDropdownSelectionId, $cl_type, $cl_date, $cl_interval); $smarty->assign('totals', $totals); // Prepare chart for drawing. diff --git a/dbinstall.php b/dbinstall.php index a3168bbfa..182910ada 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1151,7 +1151,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to12000"]) { + if ($_POST["convert11900to12100"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1191,6 +1191,8 @@ function ttGenerateKeys() { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.19.29') set rights = replace(rights, 'swap_roles,update_work', 'swap_roles') where `rank` >= 12"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.19.29') set rights = replace(rights, 'view_all_reports,manage_work,bid_on_work', 'view_all_reports') where `rank` >= 68"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.20.0', modified = now() where param_name = 'version_db' and param_value = '1.19.29'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.20.0') set rights = replace(rights, 'manage_basic_settings,view_all_reports', 'manage_basic_settings,view_all_charts,view_all_reports') where `rank` >= 68"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.21.0', modified = now() where param_name = 'version_db' and param_value = '1.20.0'"); } if ($_POST["cleanup"]) { @@ -1241,7 +1243,7 @@ function ttGenerateKeys() {

DB Install

 Anuko Time Tracker 1.18.43.4773 | Copyright © Anuko | +  Anuko Time Tracker 1.18.43.4774 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 407329801a481ea008b8c5fb21ce41bb7559c678 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 25 Feb 2019 15:04:16 +0000 Subject: [PATCH 0717/1848] Added label.mark_approved to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 31 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 692fc3573..0b8e648ea 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -271,6 +271,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 55845055c..502484354 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -281,6 +281,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 11295b152..fe00d5489 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -258,6 +258,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Fejl', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 99ec90867..0de74a3e5 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -246,6 +246,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Fehler', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 361b9d819..91f3e09d7 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -236,6 +236,7 @@ 'label.submitted' => 'Submitted', 'label.approved' => 'Approved', 'label.approval' => 'Report approval', +'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Error', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 37ba0d2da..d5341b9cd 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -274,6 +274,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 0d514ba16..7696e9186 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -261,6 +261,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f30109a04..ac87cc8b0 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -268,6 +268,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'خطا', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 97065c45e..9e194dc8e 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -262,6 +262,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Virhe', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 150e018f1..d4ef90608 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -256,6 +256,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Erreur', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 28ebbe445..6b22ef584 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -249,6 +249,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Σφάλμα', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 7dbb615c6..545ef28cb 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -279,6 +279,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'שגיאה', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 57cec891b..05672d1dc 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -275,6 +275,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 92b17f592..60c7141f9 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -253,6 +253,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 680cd280e..6ba9449aa 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -280,6 +280,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index af3099ce4..5a69aa16a 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -280,6 +280,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index ce08d7585..917c33800 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -239,6 +239,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Fout', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 3b6925d06..77b3435ec 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -278,6 +278,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 27985c62d..4e08986cf 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -263,6 +263,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Błąd', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 7afd6f8b4..0ca9ea669 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -260,6 +260,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Erro', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 681731839..35ac6bdab 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -265,6 +265,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index e279672de..cb2f5d87b 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -278,6 +278,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 6edbfbedf..9254e12d9 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -235,6 +235,7 @@ 'label.submitted' => 'Подано', 'label.approved' => 'Одобрено', 'label.approval' => 'Одобрение отчётов', +'label.mark_approved' => 'Отметить одобрение', // Form titles. 'title.error' => 'Ошибка', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index f593a8ab0..dcb86e2cc 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -268,6 +268,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Chyba', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 86695a4ad..548606a4b 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -261,6 +261,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 3c8df9237..90b8da509 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -261,6 +261,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. 'title.error' => 'Greška', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 516ab1300..6499dd080 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -257,6 +257,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Rubriker för formulär 'title.error' => 'Fel', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 7b926fd73..56da8f166 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -284,6 +284,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // Form titles. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 57fc9ebe3..76ef7f740 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -268,6 +268,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 130683d2c..88af0624a 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -275,6 +275,7 @@ // 'label.submitted' => 'Submitted', // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', +// 'label.mark_approved' => 'Mark approved', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 62960af62..87bda8d17 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- "; } else { $html .= ""; @@ -188,7 +188,7 @@ function getHtml() { // Finished printing calendar table. // Print Today link. - $html .= " \n"; + $html .= " \n"; $html .= "
 Anuko Time Tracker 1.18.43.4774 | Copyright © Anuko | +  Anuko Time Tracker 1.18.43.4775 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a93a92b4959bf35c5c6b41adaea5a666b876bf2d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 25 Feb 2019 15:55:05 +0000 Subject: [PATCH 0718/1848] More work in progress on report approval. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 11 ++++++++++- report.php | 31 +++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 87bda8d17..0fb5ca50b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.43.4775 | Copyright © Anuko | +  Anuko Time Tracker 1.18.43.4776 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 0de892ee6..294582dc4 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -166,8 +166,17 @@
-{if $report_items && ($use_mark_paid || $use_assign_to_invoice)} +{if $report_items && ($use_mark_approved || $use_mark_paid || $use_assign_to_invoice)} + {if $use_mark_approved} + + + + {/if} {if $use_mark_paid} - - - - -
+ + +
{$i18n.label.mark_approved}: {$forms.reportViewForm.mark_approved_select_options.control} {$forms.reportViewForm.mark_approved_action_options.control} {$forms.reportViewForm.btn_mark_approved.control}
+
diff --git a/report.php b/report.php index 93720cb27..135c8f272 100644 --- a/report.php +++ b/report.php @@ -38,6 +38,12 @@ exit(); } +if ($user->isPluginEnabled('ap')) { + $cl_mark_approved_select_option = $request->getParameter('mark_approved_select_options', ($request->isPost() ? null : @$_SESSION['mark_approved_select_option'])); + $_SESSION['mark_approved_select_option'] = $cl_mark_approved_select_option; + $cl_mark_approved_action_option = $request->getParameter('mark_approved_action_options', ($request->isPost() ? null : @$_SESSION['mark_approved_action_option'])); + $_SESSION['mark_aproved_action_option'] = $cl_mark_approved_action_option; +} if ($user->isPluginEnabled('ps')) { $cl_mark_paid_select_option = $request->getParameter('mark_paid_select_options', ($request->isPost() ? null : @$_SESSION['mark_paid_select_option'])); $_SESSION['mark_paid_select_option'] = $cl_mark_paid_select_option; @@ -67,11 +73,32 @@ $client_id = $bean->getAttribute('client'); -// Do we need to show checkboxes? +// Do we need to show checkboxes? We show them if we allow setting approved or paid status, +// and also when we can assign / deassign records to invoces. +if ($bean->getAttribute('chapproved') && ($user->can('approve_reports') || $user->can('approve_all_eports'))) + $showForApproved = true; if ($bean->getAttribute('chpaid') || ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by1')) && !$user->isClient())) { if ($user->can('manage_invoices')) - $smarty->assign('use_checkboxes', true); + $showForInvoicesOrPaid = true; +} +if ($showForApproved || $showForInvoicesOrPaid) + $smarty->assign('use_checkboxes', true); + +// Controls for "Mark approved" block. +if ($showForApproved) { + $mark_approved_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); + $form->addInput(array('type'=>'combobox', + 'name'=>'mark_approved_select_options', + 'data'=>$mark_approved_select_options, + 'value'=>$cl_mark_approved_select_option)); + $mark_approved_action_options = array('1'=>$i18n->get('form.reports.include_approved'),'2'=>$i18n->get('form.reports.include_not_approved')); + $form->addInput(array('type'=>'combobox', + 'name'=>'mark_approved_action_options', + 'data'=>$mark_approved_action_options, + 'value'=>$cl_mark_approved_action_option)); + $form->addInput(array('type'=>'submit','name'=>'btn_mark_approved','value'=>$i18n->get('button.submit'))); + $smarty->assign('use_mark_approved', true); } // Controls for "Mark paid" block. From 8bee920461b35df9041cce507b043841d203e3e3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 25 Feb 2019 16:17:40 +0000 Subject: [PATCH 0719/1848] Some refactoring in translations. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 3 +++ WEB-INF/resources/en.lang.php | 3 +++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 3 +++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 3 +++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 3 +++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 3 +++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ 30 files changed, 66 insertions(+) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 0b8e648ea..c0a693134 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -398,6 +398,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 502484354..d48497cf2 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -407,6 +407,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index fe00d5489..2a639b2ad 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -374,6 +374,8 @@ 'dropdown.delete' => 'Slet', 'dropdown.do_not_delete' => 'Slet ikke', // TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 0de74a3e5..016ec8558 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -353,6 +353,9 @@ 'dropdown.status_inactive' => 'inaktiv', 'dropdown.delete' => 'löschen', 'dropdown.do_not_delete' => 'nicht löschen', +// TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'bezahlt', 'dropdown.not_paid' => 'nicht bezahlt', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 91f3e09d7..4ec12f82d 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -345,9 +345,12 @@ 'dropdown.status_inactive' => 'inactive', 'dropdown.delete' => 'delete', 'dropdown.do_not_delete' => 'do not delete', +'dropdown.approved' => 'approved', +'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'paid', 'dropdown.not_paid' => 'not paid', + // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases // a string can be defined on the main form and used on related forms. The reasoning for this is to make translation effort easier. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index d5341b9cd..3c6c44c85 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -397,6 +397,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 7696e9186..cccc548b8 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -374,6 +374,9 @@ 'dropdown.status_inactive' => 'mitte aktiivne', 'dropdown.delete' => 'kustuta', 'dropdown.do_not_delete' => 'ära kustuta', +// TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'makstud', 'dropdown.not_paid' => 'mitte makstud', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index ac87cc8b0..95a157391 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -385,6 +385,8 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 9e194dc8e..c06af3dec 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -374,6 +374,8 @@ 'dropdown.delete' => 'poista', 'dropdown.do_not_delete' => 'älä poista', // TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index d4ef90608..f95325d6c 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -366,6 +366,8 @@ 'dropdown.delete' => 'supprimer', 'dropdown.do_not_delete' => 'ne pas supprimer', // TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 6b22ef584..8079b6f8f 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -361,6 +361,9 @@ 'dropdown.status_inactive' => 'ανένεργος', 'dropdown.delete' => 'διαγραφή', 'dropdown.do_not_delete' => 'μη το διαγράψετε', +// TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'εξοφλημένο', 'dropdown.not_paid' => 'δεν έχει εξοφληθεί', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 545ef28cb..c2f66657a 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -395,6 +395,8 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 05672d1dc..245275ab9 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -398,6 +398,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 60c7141f9..da1f2ff99 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -371,6 +371,9 @@ 'dropdown.status_inactive' => 'inattivo', 'dropdown.delete' => 'elimina', 'dropdown.do_not_delete' => 'non eliminare', +// TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'pagato', 'dropdown.not_paid' => 'non pagato', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 6ba9449aa..faa497971 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -400,6 +400,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 5a69aa16a..89c01a34f 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -404,6 +404,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 917c33800..191e8aeea 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -348,6 +348,9 @@ 'dropdown.status_inactive' => 'inactief', 'dropdown.delete' => 'verwijderen', 'dropdown.do_not_delete' => 'niet verwijderen', +// TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'betaald', 'dropdown.not_paid' => 'niet betaald', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 77b3435ec..1f4cd35c8 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -401,6 +401,8 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 4e08986cf..53cb7e4bf 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -377,6 +377,8 @@ 'dropdown.delete' => 'usuń', 'dropdown.do_not_delete' => 'nie usuwaj', // TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 0ca9ea669..8189bdb48 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -372,6 +372,8 @@ 'dropdown.delete' => 'apagar', 'dropdown.do_not_delete' => 'não apagar', // TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 35ac6bdab..9ec2d495b 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -383,6 +383,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index cb2f5d87b..902ca04ba 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -405,6 +405,8 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 9254e12d9..588b737a7 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -342,6 +342,8 @@ 'dropdown.status_inactive' => 'неактивный', 'dropdown.delete' => 'удалить', 'dropdown.do_not_delete' => 'не удалять', +'dropdown.approved' => 'одобрено', +'dropdown.not_approved' => 'не одобрено', 'dropdown.paid' => 'оплачено', 'dropdown.not_paid' => 'не оплачено', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index dcb86e2cc..d08d06bc5 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -385,6 +385,8 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 548606a4b..c3ee36cbe 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -377,6 +377,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 90b8da509..6c2f926fb 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -375,6 +375,8 @@ 'dropdown.delete' => 'obriši', 'dropdown.do_not_delete' => 'nemoj obrisati', // TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 6499dd080..380958784 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -373,6 +373,8 @@ 'dropdown.delete' => 'Ta bort', 'dropdown.do_not_delete' => 'Ta inte bort', // TODO: translate the following. +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 56da8f166..1c2ce69f3 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -412,6 +412,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 76ef7f740..91ae2e993 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -390,6 +390,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 88af0624a..2888d5365 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -397,6 +397,8 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.approved' => 'approved', +// 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', From eb1332ec4a8cc403d3531bd472e9060dfe5e5d94 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 25 Feb 2019 16:27:57 +0000 Subject: [PATCH 0720/1848] More refactoring in translation files. --- WEB-INF/resources/ca.lang.php | 2 -- WEB-INF/resources/cs.lang.php | 2 -- WEB-INF/resources/da.lang.php | 2 -- WEB-INF/resources/de.lang.php | 2 -- WEB-INF/resources/en.lang.php | 2 -- WEB-INF/resources/es.lang.php | 2 -- WEB-INF/resources/et.lang.php | 3 --- WEB-INF/resources/fa.lang.php | 2 -- WEB-INF/resources/fi.lang.php | 2 -- WEB-INF/resources/fr.lang.php | 2 -- WEB-INF/resources/gr.lang.php | 2 -- WEB-INF/resources/he.lang.php | 2 -- WEB-INF/resources/hu.lang.php | 2 -- WEB-INF/resources/it.lang.php | 2 -- WEB-INF/resources/ja.lang.php | 2 -- WEB-INF/resources/ko.lang.php | 2 -- WEB-INF/resources/nl.lang.php | 2 -- WEB-INF/resources/no.lang.php | 2 -- WEB-INF/resources/pl.lang.php | 2 -- WEB-INF/resources/pt-br.lang.php | 2 -- WEB-INF/resources/pt.lang.php | 2 -- WEB-INF/resources/ro.lang.php | 2 -- WEB-INF/resources/ru.lang.php | 2 -- WEB-INF/resources/sk.lang.php | 2 -- WEB-INF/resources/sl.lang.php | 2 -- WEB-INF/resources/sr.lang.php | 2 -- WEB-INF/resources/sv.lang.php | 2 -- WEB-INF/resources/tr.lang.php | 2 -- WEB-INF/resources/zh-cn.lang.php | 2 -- WEB-INF/resources/zh-tw.lang.php | 2 -- WEB-INF/templates/footer.tpl | 2 +- report.php | 2 +- reports.php | 6 +++--- 33 files changed, 5 insertions(+), 66 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index c0a693134..293471700 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -446,8 +446,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Seleccionar període de temps', 'form.reports.set_period' => 'o establir dates', 'form.reports.show_fields' => 'Mostrar camps', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d48497cf2..c85cb6867 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -456,8 +456,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Výberte období', 'form.reports.set_period' => 'nebo určete dny', 'form.reports.show_fields' => 'Zobrazit pole', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 2a639b2ad..3dfb41c87 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -422,8 +422,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Vælg en periode', 'form.reports.set_period' => 'eller sæt datoer', 'form.reports.show_fields' => 'Vis felter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 016ec8558..c787f6d87 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -402,8 +402,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Zeitraum auswählen', 'form.reports.set_period' => 'oder Datum eingeben', 'form.reports.show_fields' => 'Felder anzeigen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 4ec12f82d..5c91c3ee4 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -398,8 +398,6 @@ 'form.reports.include_assigned' => 'assigned', 'form.reports.include_not_assigned' => 'not assigned', 'form.reports.include_pending' => 'pending', -'form.reports.include_approved' => 'approved', -'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Select time period', 'form.reports.set_period' => 'or set dates', 'form.reports.show_fields' => 'Show fields', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 3c6c44c85..c86741762 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -459,8 +459,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Seleccionar período de tiempo', 'form.reports.set_period' => 'o establecer fechas', 'form.reports.show_fields' => 'Mostrar campos', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index cccc548b8..7f2fe8eb0 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -427,9 +427,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', - 'form.reports.select_period' => 'Vali ajaperiood', 'form.reports.set_period' => 'või märgi kuupäevad', 'form.reports.show_fields' => 'Näita välju', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 95a157391..fdbcdba5f 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -442,8 +442,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'انتخاب بازه زمانی', 'form.reports.set_period' => 'یا تعیین تاریخ', 'form.reports.show_fields' => 'نمایش فیلدها', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index c06af3dec..bc66a2264 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -427,8 +427,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Valitse ajanjakso', 'form.reports.set_period' => 'tai aseta päivät', 'form.reports.show_fields' => 'Näytä kentät', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index f95325d6c..840f85590 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -419,8 +419,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Sélectionner la période de temps', 'form.reports.set_period' => 'ou dates indiquées', 'form.reports.show_fields' => 'Afficher les champs', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 8079b6f8f..2ebdaa8f3 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -411,8 +411,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Επιλογή χρονικής περιόδου', 'form.reports.set_period' => 'ή εύρος ημερομηνιών', 'form.reports.show_fields' => 'Εμφάνιση πεδίων', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index c2f66657a..cac16e9c5 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -448,8 +448,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'בחר תקופת זמן', 'form.reports.set_period' => 'או הגדר תאריכים', 'form.reports.show_fields' => 'הראה שדות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 245275ab9..f4d5dd139 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -448,8 +448,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Jelölj meg egy időszakot', 'form.reports.set_period' => 'vagy állíts be konkrét dátumot', // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index da1f2ff99..3d898e2f2 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -424,8 +424,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Seleziona il periodo di tempo', 'form.reports.set_period' => 'oppure setta le date', 'form.reports.show_fields' => 'Mostra i campi', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index faa497971..7f1a84119 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -454,8 +454,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '時間期間の選択', 'form.reports.set_period' => 'あるいは日付を設定', 'form.reports.show_fields' => 'フィールドの表示', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 89c01a34f..c5b7e0a21 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -452,8 +452,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '시간 기간을 선택', 'form.reports.set_period' => '혹은 날짜를 설정', 'form.reports.show_fields' => '필드들을 보기', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 191e8aeea..7307ec4a9 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -398,8 +398,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Kies periode', 'form.reports.set_period' => 'of stel datums in', 'form.reports.show_fields' => 'Toon velden', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 1f4cd35c8..a05071167 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -452,8 +452,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Velg tidsperiode', 'form.reports.set_period' => 'eller sett dato', 'form.reports.show_fields' => 'Vis feltene', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 53cb7e4bf..28e8a0ace 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -430,8 +430,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Wybierz okres', 'form.reports.set_period' => 'lub ustaw daty', 'form.reports.show_fields' => 'Pokaż pola', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 8189bdb48..74e5822f0 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -425,8 +425,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9ec2d495b..e1e6b29d8 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -432,8 +432,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 902ca04ba..cf701cf63 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -455,8 +455,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Alege perioada', 'form.reports.set_period' => 'sau introdu intervalul de date', 'form.reports.show_fields' => 'Arata campuri', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 588b737a7..2fec5db79 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -389,8 +389,6 @@ 'form.reports.include_assigned' => 'присвоена', 'form.reports.include_not_assigned' => 'не присвоена', 'form.reports.include_pending' => 'в ожидании', -'form.reports.include_approved' => 'одобрена', -'form.reports.include_not_approved' => 'не одобрена', 'form.reports.select_period' => 'Выберите интервал времени', 'form.reports.set_period' => 'или укажите даты', 'form.reports.show_fields' => 'Показывать поля', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d08d06bc5..08999f1de 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -438,8 +438,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Vyberte časový rozsah', 'form.reports.set_period' => 'alebo nastavte dátumy', 'form.reports.show_fields' => 'Zobraziť polia', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index c3ee36cbe..95d3f8587 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -429,8 +429,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', // 'form.reports.select_period' => 'Select time period', // 'form.reports.set_period' => 'or set dates', // 'form.reports.show_fields' => 'Show fields', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 6c2f926fb..170e5409f 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -428,8 +428,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Odaberi vremenski raspon', 'form.reports.set_period' => 'ili podesi datum', 'form.reports.show_fields' => 'Prikaži polja u izveštaju', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 380958784..be3f4f280 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -426,8 +426,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Välj intervall', 'form.reports.set_period' => 'eller ställ in datum', 'form.reports.show_fields' => 'Visa fält', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 1c2ce69f3..e30ddf06a 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -465,8 +465,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => 'Zaman aralığını seç', 'form.reports.set_period' => 'ya da tarihleri belirle', 'form.reports.show_fields' => 'Alanları göster', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 91ae2e993..05fa7a88e 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -437,8 +437,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '选择时间段', 'form.reports.set_period' => '或设定日期', 'form.reports.show_fields' => '显示栏目', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 2888d5365..760e9acfa 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -445,8 +445,6 @@ // 'form.reports.include_assigned' => 'assigned', // 'form.reports.include_not_assigned' => 'not assigned', // 'form.reports.include_pending' => 'pending', -// 'form.reports.include_approved' => 'approved', -// 'form.reports.include_not_approved' => 'not approved', 'form.reports.select_period' => '選擇時間段', 'form.reports.set_period' => '或設定日期', 'form.reports.show_fields' => '顯示欄目', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0fb5ca50b..4f4adc75a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} - {if $user->isPluginEnabled('wk') && ($user->can('update_work') || $user->can('bid_on_work') || $user->can('manage_work')) && $user->exists()} - - {/if} {if $user->can('export_data')} {/if} diff --git a/WEB-INF/templates/work/header.tpl b/WEB-INF/templates/work/header.tpl index 75a0d586f..6b767a16a 100644 --- a/WEB-INF/templates/work/header.tpl +++ b/WEB-INF/templates/work/header.tpl @@ -141,9 +141,6 @@ {if $user->isPluginEnabled('cl') && ($user->can('view_own_clients') || $user->can('manage_clients'))} {$i18n.menu.clients} {/if} - {if $user->isPluginEnabled('wk') && ($user->can('update_work') || $user->can('bid_on_work') || $user->can('manage_work')) && $user->exists()} - {$i18n.title.work} - {/if} {if $user->can('export_data')} {$i18n.menu.export} {/if} diff --git a/initialize.php b/initialize.php index c4fccc0f4..16f3a5b1e 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5611"); +define("APP_VERSION", "1.19.34.5612"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 4a289fddb562e738b03c4f8f5e2be4d1b53b3f81 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 25 Jan 2022 14:54:56 +0000 Subject: [PATCH 1632/1848] Removed code for Remote Work plugin. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 1028 ------------ WEB-INF/lib/ttWorkHelper.class.php | 1617 ------------------- WEB-INF/templates/header.tpl | 3 - WEB-INF/templates/site_map.tpl | 3 - WEB-INF/templates/work/admin_offer_edit.tpl | 70 - WEB-INF/templates/work/admin_work.tpl | 104 -- WEB-INF/templates/work/admin_work_edit.tpl | 67 - WEB-INF/templates/work/footer_old.tpl | 29 - WEB-INF/templates/work/header.tpl | 204 --- WEB-INF/templates/work/index.tpl | 5 - WEB-INF/templates/work/offer_add.tpl | 74 - WEB-INF/templates/work/offer_delete.tpl | 20 - WEB-INF/templates/work/offer_edit.tpl | 67 - WEB-INF/templates/work/offer_message.tpl | 32 - WEB-INF/templates/work/offer_view.tpl | 47 - WEB-INF/templates/work/offer_view_own.tpl | 42 - WEB-INF/templates/work/work.tpl | 140 -- WEB-INF/templates/work/work_add.tpl | 62 - WEB-INF/templates/work/work_delete.tpl | 20 - WEB-INF/templates/work/work_edit.tpl | 73 - WEB-INF/templates/work/work_message.tpl | 32 - WEB-INF/templates/work/work_offer_view.tpl | 57 - WEB-INF/templates/work/work_offers.tpl | 41 - WEB-INF/templates/work/work_view.tpl | 47 - WEB-INF/templates/work/work_view_own.tpl | 38 - work/admin_offer_delete.php | 71 - work/admin_offer_edit.php | 171 -- work/admin_work.php | 53 - work/admin_work_delete.php | 71 - work/admin_work_edit.php | 168 -- work/offer_add.php | 120 -- work/offer_delete.php | 75 - work/offer_edit.php | 135 -- work/offer_message.php | 90 -- work/offer_view.php | 81 - work/offer_view_own.php | 77 - work/work.php | 65 - work/work_add.php | 122 -- work/work_delete.php | 75 - work/work_edit.php | 151 -- work/work_message.php | 90 -- work/work_offer_view.php | 123 -- work/work_offers.php | 56 - work/work_view.php | 74 - work/work_view_own.php | 79 - 45 files changed, 5869 deletions(-) delete mode 100644 WEB-INF/lib/ttAdminWorkHelper.class.php delete mode 100644 WEB-INF/lib/ttWorkHelper.class.php delete mode 100644 WEB-INF/templates/work/admin_offer_edit.tpl delete mode 100644 WEB-INF/templates/work/admin_work.tpl delete mode 100644 WEB-INF/templates/work/admin_work_edit.tpl delete mode 100644 WEB-INF/templates/work/footer_old.tpl delete mode 100644 WEB-INF/templates/work/header.tpl delete mode 100644 WEB-INF/templates/work/index.tpl delete mode 100644 WEB-INF/templates/work/offer_add.tpl delete mode 100644 WEB-INF/templates/work/offer_delete.tpl delete mode 100644 WEB-INF/templates/work/offer_edit.tpl delete mode 100644 WEB-INF/templates/work/offer_message.tpl delete mode 100644 WEB-INF/templates/work/offer_view.tpl delete mode 100644 WEB-INF/templates/work/offer_view_own.tpl delete mode 100644 WEB-INF/templates/work/work.tpl delete mode 100644 WEB-INF/templates/work/work_add.tpl delete mode 100644 WEB-INF/templates/work/work_delete.tpl delete mode 100644 WEB-INF/templates/work/work_edit.tpl delete mode 100644 WEB-INF/templates/work/work_message.tpl delete mode 100644 WEB-INF/templates/work/work_offer_view.tpl delete mode 100644 WEB-INF/templates/work/work_offers.tpl delete mode 100644 WEB-INF/templates/work/work_view.tpl delete mode 100644 WEB-INF/templates/work/work_view_own.tpl delete mode 100644 work/admin_offer_delete.php delete mode 100644 work/admin_offer_edit.php delete mode 100644 work/admin_work.php delete mode 100644 work/admin_work_delete.php delete mode 100644 work/admin_work_edit.php delete mode 100644 work/offer_add.php delete mode 100644 work/offer_delete.php delete mode 100644 work/offer_edit.php delete mode 100644 work/offer_message.php delete mode 100644 work/offer_view.php delete mode 100644 work/offer_view_own.php delete mode 100644 work/work.php delete mode 100644 work/work_add.php delete mode 100644 work/work_delete.php delete mode 100644 work/work_edit.php delete mode 100644 work/work_message.php delete mode 100644 work/work_offer_view.php delete mode 100644 work/work_offers.php delete mode 100644 work/work_view.php delete mode 100644 work/work_view_own.php diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php deleted file mode 100644 index 22098b277..000000000 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ /dev/null @@ -1,1028 +0,0 @@ -errors = &$errors; - - $this->work_server_uri = defined('WORK_SERVER_URI') ? WORK_SERVER_URI : "https://www.anuko.com/work/"; - $this->register_uri = $this->work_server_uri.'register'; - $this->get_work_item_uri = $this->work_server_uri.'admin_getworkitem'; - $this->update_work_item_uri = $this->work_server_uri.'admin_updateworkitem'; - $this->delete_work_item_uri = $this->work_server_uri.'admin_deleteworkitem'; - $this->approve_work_item_uri = $this->work_server_uri.'admin_approveworkitem'; - $this->approve_work_item_on_offer_uri = $this->work_server_uri.'admin_approveworkitemonoffer'; - $this->disapprove_work_item_uri = $this->work_server_uri.'admin_disapproveworkitem'; - $this->disapprove_work_item_on_offer_uri = $this->work_server_uri.'admin_disapproveworkitemonoffer'; - $this->get_offer_uri = $this->work_server_uri.'admin_getoffer'; - $this->update_offer_uri = $this->work_server_uri.'admin_updateoffer'; - $this->delete_offer_uri = $this->work_server_uri.'admin_deleteoffer'; - $this->approve_offer_uri = $this->work_server_uri.'admin_approveoffer'; - $this->disapprove_offer_uri = $this->work_server_uri.'admin_disapproveoffer'; - $this->get_pending_work_items_uri = $this->work_server_uri.'admin_getpendingworkitems'; - $this->get_pending_offers_uri = $this->work_server_uri.'admin_getpendingoffers'; - $this->get_items_uri = $this->work_server_uri.'admin_getitems'; - $this->checkSiteRegistration(); - } - - // checkSiteRegistration - obtains site id and key from local database. - // If not found, it tries to register with remote work server. - function checkSiteRegistration() { - global $i18n; - global $user; - $mdb2 = getConnection(); - - // Obtain site id. - $sql = "select param_value as id from tt_site_config where param_name = 'worksite_id'"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - if (!$val) { - // No site id found, need to register. - $fields = array('lang' => urlencode($user->lang), - 'name' => urlencode('time tracker'), - 'origin' => urlencode('time tracker source')); - - // Urlify the data for the POST. - foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->register_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $reg_status = $result_array['reg_status']; // Registration status. - if ($reg_status['site_id'] && $reg_status['site_key']) { - $this->site_id = $reg_status['site_id']; - $this->site_key = $reg_status['site_key']; - - // Registration successful. Store id and key locally for future use. - $sql = "insert into tt_site_config values('worksite_id', $this->site_id, now(), null)"; - $mdb2->exec($sql); - $sql = "insert into tt_site_config values('worksite_key', ".$mdb2->quote($this->site_key).", now(), null)"; - $mdb2->exec($sql); - } else { - $this->errors->add($i18n->get('error.remote_work')); - } - } else { - // Site id found. - $this->site_id = $val['id']; - - // Obtain site key. - $sql = "select param_value as site_key from tt_site_config where param_name = 'worksite_key'"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $this->site_key = $val['site_key']; - } - } - - // getPendingOffers - obtains a list of offers pending approval. - function getPendingOffers() { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_pending_offers_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $pending_offers = $result_array['pending_offers']; - return $pending_offers; - } - - // getPendingWorkItems - obtains a list of work items pending approval. - function getPendingWorkItems() { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_pending_work_items_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $pending_work = $result_array['pending_work']; - return $pending_work; - } - - // getWorkItem - gets work item details from remote work server. - function getWorkItem($work_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'work_id' => urlencode($work_id)); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_work_item_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $work_item = $result_array['work_item']; - return $work_item; - } - - // deleteWorkItem - deletes work item from remote work server. - function deleteWorkItem($work_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'work_id' => urlencode($work_id), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->delete_work_item_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // deleteOffer - deletes an offer from remote work server. - function deleteOffer($offer_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'offer_id' => urlencode($offer_id), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->delete_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // getOffer - gets offer details from remote work server. - function getOffer($offer_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'offer_id' => urlencode($offer_id)); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $offer = $result_array['offer']; - return $offer; - } - - // updateWorkItem - updates a work item in remote work server. - function updateWorkItem($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'work_id' => urlencode($fields['work_id']), - 'subject' => urlencode(base64_encode($fields['subject'])), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']), - 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail())) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->update_work_item_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // approveWorkItem - approves work item in remote work server. - function approveWorkItem($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'work_id' => urlencode($fields['work_id']), - 'subject' => urlencode(base64_encode($fields['subject'])), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']), - 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->approve_work_item_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // disapproveWorkItem - disapproves work item in remote work server. - function disapproveWorkItem($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'work_id' => urlencode($fields['work_id']), - 'subject' => urlencode(base64_encode($fields['subject'])), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']), - 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->disapprove_work_item_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // disapproveWorkItemOnOffer - disapproves work item posted on offer in remote work server. - function disapproveWorkItemOnOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'work_id' => urlencode($fields['work_id']), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->disapprove_work_item_on_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // approveWorkItemOnOffer - approves work item posted on offer in remote work server. - function approveWorkItemOnOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'work_id' => urlencode($fields['work_id']), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->approve_work_item_on_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // updateOffer - updates an offer in remote work server. - function updateOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'offer_id' => urlencode($fields['offer_id']), - 'subject' => urlencode(base64_encode($fields['subject'])), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']), - 'payment_info' => urlencode(base64_encode($fields['payment_info'])), - 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail())) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->update_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // approveOffer - approves offer in remote work server. - function approveOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'offer_id' => urlencode($fields['offer_id']), - 'subject' => urlencode(base64_encode($fields['subject'])), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']), - 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->approve_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - - // disapproveOffer - disapproves offer in remote work server. - function disapproveOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id), - 'offer_id' => urlencode($fields['offer_id']), - 'subject' => urlencode(base64_encode($fields['subject'])), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']), - 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->disapprove_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // getItems - obtains a list of all items relevant to admin in one API call to Remote Work Server. - function getItems() { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'user_id' => urlencode($user->id) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_items_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - unset($result_array['call_status']); // Remove call_status element. - return $result_array; - } -} diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php deleted file mode 100644 index 6ddf87513..000000000 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ /dev/null @@ -1,1617 +0,0 @@ -errors = &$errors; - - $this->work_server_uri = defined('WORK_SERVER_URI') ? WORK_SERVER_URI : "https://www.anuko.com/work/"; - - // Note: at some point a need will arise for API versioning. - // When this happens, we will append an API version number to the end of URI, - // for example: register_0_1 instead of register. - // This should theoretically allow a remote work server to be able to work with - // a complete variety of deployed clients, including those without versions. - $this->register_uri = $this->work_server_uri.'register'; // register_0_0 - $this->put_own_work_item_uri = $this->work_server_uri.'putownworkitem'; - $this->get_own_work_item_uri = $this->work_server_uri.'getownworkitem'; - $this->get_own_work_item_offer_uri = $this->work_server_uri.'getownworkitemoffer'; - $this->get_own_work_item_offers_uri = $this->work_server_uri.'getownworkitemoffers'; - $this->get_own_work_items_uri = $this->work_server_uri.'getownworkitems'; - $this->get_available_work_items_uri = $this->work_server_uri.'getavailableworkitems'; - $this->get_available_work_item_uri = $this->work_server_uri.'getavailableworkitem'; - $this->delete_own_work_item_uri = $this->work_server_uri.'deleteownworkitem'; - $this->accept_own_work_item_offer_uri = $this->work_server_uri.'acceptownworkitemoffer'; - $this->decline_own_work_item_offer_uri = $this->work_server_uri.'declineownworkitemoffer'; - $this->update_own_work_item_uri = $this->work_server_uri.'updateownworkitem'; - $this->update_own_work_item_on_offer_uri = $this->work_server_uri.'updateownworkitemonoffer'; - $this->put_own_offer_uri = $this->work_server_uri.'putownoffer'; - $this->get_own_offer_uri = $this->work_server_uri.'getownoffer'; - $this->get_own_offers_uri = $this->work_server_uri.'getownoffers'; - - $this->get_available_offers_uri = $this->work_server_uri.'getavailableoffers'; - $this->get_available_offer_uri = $this->work_server_uri.'getavailableoffer'; - $this->get_group_items_uri = $this->work_server_uri.'getgroupitems'; - $this->delete_own_offer_uri = $this->work_server_uri.'deleteownoffer'; - $this->update_own_offer_uri = $this->work_server_uri.'updateownoffer'; - $this->send_message_to_work_owner_uri = $this->work_server_uri.'sendmessagetoworkowner'; - $this->send_message_to_offer_owner_uri = $this->work_server_uri.'sendmessagetoofferowner'; - $this->checkSiteRegistration(); - } - - // checkSiteRegistration - obtains site id and key from local database. - // If not found, it tries to register with remote work server. - function checkSiteRegistration() { - global $i18n; - global $user; - $mdb2 = getConnection(); - - // Obtain site id. - $sql = "select param_value as id from tt_site_config where param_name = 'worksite_id'"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - if (!$val) { - // No site id found, need to register. - $group_id = $user->getGroup(); - $org_id = $user->org_id; - $fields = array('lang' => urlencode($user->lang), - 'name' => urlencode('time tracker'), - 'origin' => urlencode('time tracker source'), - 'org_id' => urlencode($org_id), - 'group_id' => urlencode($group_id), - 'group_name' => urlencode(base64_encode($user->getGroupName())), - 'user_id' => urlencode($user->getUser()), - 'user_name' => urlencode(base64_encode($user->getName())), - 'user_email' => urlencode(base64_encode($user->getEmail())), - 'user_ip' => urlencode($_SERVER['REMOTE_ADDR'])); - - // Urlify the data for the POST. - foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->register_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $reg_status = $result_array['reg_status']; // Registration status. - if ($reg_status['site_id'] && $reg_status['site_key']) { - $this->site_id = $reg_status['site_id']; - $this->site_key = $reg_status['site_key']; - - // Registration successful. Store id and key locally for future use. - $sql = "insert into tt_site_config values('worksite_id', $this->site_id, now(), null)"; - $mdb2->exec($sql); - $sql = "insert into tt_site_config values('worksite_key', ".$mdb2->quote($this->site_key).", now(), null)"; - $mdb2->exec($sql); - } else { - $this->errors->add($i18n->get('error.remote_work')); - } - } else { - // Site id found. - $this->site_id = $val['id']; - - // Obtain site key. - $sql = "select param_value as site_key from tt_site_config where param_name = 'worksite_key'"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $this->site_key = $val['site_key']; - } - } - - // putOwnWorkItem - publishes a work item in remote work server. - // - // Note about some fields using additional base64 encoding. - // There is a problem with data posted by curl calls on the server side for - // some languages. Data arrives corrupted. - // - // For example: consider a case for a single Russian letter ф in the subject field. - // UTF-8 encoding for ф: 0xD1 0x84 (2 bytes). - // urlencoded ф: %D1%84 - a string of 6 characters. - // If we use a curl call like here with only urlencoded ф, what arrives on the server in POST is "C3 91 C2 84" - // no idea what it is. - // - // A workaround for now is to use use an additional base64 encoding for all text fields, - // which are decoded back to utf-8 strings on the server side. - function putOwnWorkItem($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_name' => urlencode(base64_encode($user->getGroupName())), - 'group_key' => urlencode($user->getGroupKey()), - 'offer_id' => urlencode($fields['offer_id']), - 'type' => urlencode($fields['type']), - 'subject' => urlencode(base64_encode($fields['subject'])), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']), - 'created_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'created_by' => urlencode($user->getUser()), - 'created_by_name' => urlencode(base64_encode($user->getName())), - 'created_by_email' => urlencode(base64_encode($user->getEmail())) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->put_own_work_item_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // updateOwnWorkItem - updates a work item in remote work server. - function updateOwnWorkItem($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_name' => urlencode(base64_encode($user->getGroupName())), - 'group_key' => urlencode($user->getGroupKey()), - 'work_id' => urlencode($fields['work_id']), - 'type' => urlencode($fields['type']), - 'subject' => urlencode(base64_encode($fields['subject'])), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail())) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->update_own_work_item_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // updateOwnWorkItemOnOffer - updates own work item posted on offer in remote work server. - function updateOwnWorkItemOnOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_name' => urlencode(base64_encode($user->getGroupName())), - 'group_key' => urlencode($user->getGroupKey()), - 'work_id' => urlencode($fields['work_id']), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail())) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->update_own_work_item_on_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // getOwnWorkItems - obtains a list of work items this group is currently outsourcing. - function getOwnWorkItems() { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_own_work_items_iri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $active_work = $result_array['active_work']; - return $active_work; - } - - // getAvailableWorkItems - obtains a list of available work items this group can bid on. - function getAvailableWorkItems() { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_available_work_items_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $available_work = $result_array['available_work']; - return $available_work; - } - - // getOwnWorkItem - gets work item details from remote work server. - function getOwnWorkItem($work_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'work_id' => urlencode($work_id)); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_own_work_item_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $work_item = $result_array['work_item']; - return $work_item; - } - - // getOwnWorkItemOffers - gets offers on own work item from remote work server. - function getOwnWorkItemOffers($work_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'work_id' => urlencode($work_id)); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_own_work_item_offers_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $work_item_offers = $result_array['work_item_offers']; - return $work_item_offers; - } - - // deleteOwnWorkItem - deletes work item from remote work server. - function deleteOwnWorkItem($work_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'work_id' => urlencode($work_id), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->delete_own_work_item_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // putOwnOffer - publishes an offer in remote work server. - function putOwnOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_name' => urlencode(base64_encode($user->getGroupName())), - 'group_key' => urlencode($user->getGroupKey()), - 'work_id' => urlencode($fields['work_id']), - 'subject' => urlencode(base64_encode($fields['subject'])), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']), - 'payment_info' => urlencode(base64_encode($fields['payment_info'])), - 'created_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'created_by' => urlencode($user->getUser()), - 'created_by_name' => urlencode(base64_encode($user->getName())), - 'created_by_email' => urlencode(base64_encode($user->getEmail())) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->put_own_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // getOwnOffers - obtains a list of offers this group made available to other groups. - function getOwnOffers() { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_own_offers_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $active_offers = $result_array['active_offers']; - return $active_offers; - } - - // getAvailableOffers - obtains a list of available offers from other organizations. - function getAvailableOffers() { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_available_offers_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $available_offers = $result_array['available_offers']; - return $available_offers; - } - - // getOwnOffer - gets offer details from remote work server. - function getOwnOffer($offer_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'offer_id' => urlencode($offer_id)); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_own_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $offer = $result_array['offer']; - return $offer; - } - - // updateOwnOffer - updates an offer in remote work server. - function updateOwnOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_name' => urlencode(base64_encode($user->getGroupName())), - 'group_key' => urlencode($user->getGroupKey()), - 'offer_id' => urlencode($fields['offer_id']), - 'subject' => urlencode(base64_encode($fields['subject'])), - 'descr_short' => urlencode(base64_encode($fields['descr_short'])), - 'descr_long' => urlencode(base64_encode($fields['descr_long'])), - 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']), - 'payment_info' => urlencode(base64_encode($fields['payment_info'])), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail())) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->update_own_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // deleteOwnOffer - deletes an offer from remote work server. - function deleteOwnOffer($offer_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'offer_id' => urlencode($offer_id), - 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'modified_by' => urlencode($user->getUser()), - 'modified_by_name' => urlencode(base64_encode($user->getName())), - 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->delete_own_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // getOwnWorkItemOffer - gets offer details from remote work server - // for an offer posted on own work item. - function getOwnWorkItemOffer($offer_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'offer_id' => urlencode($offer_id)); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_own_work_item_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $offer = $result_array['offer']; - return $offer; - } - - // declineOwnWorkItemOffer - declines an offer posted on own work item in remote work server. - function declineOwnWorkItemOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'offer_id' => urlencode($fields['offer_id']), - 'client_comment' => urlencode(base64_encode($fields['client_comment']))); - //'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), - //'modified_by' => urlencode($user->getUser()), - //'modified_by_name' => urlencode(base64_encode($user->getName())), - //'modified_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->decline_own_work_item_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // acceptOwnWorkItemOffer - accepts an offer posted on own work item in remote work server. - function acceptOwnWorkItemOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'offer_id' => urlencode($fields['offer_id']), - 'client_comment' => urlencode(base64_encode($fields['client_comment'])), - 'accepted_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'accepted_by' => urlencode($user->getUser()), - 'accepted_by_name' => urlencode(base64_encode($user->getName())), - 'accepted_by_email' => urlencode(base64_encode($user->getEmail()))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->accept_own_work_item_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // getCurrencies - obtains a list of supported currencies. - static function getCurrencies() { - $mdb2 = getConnection(); - - $sql = "select id, name from tt_work_currencies order by id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) return false; - - while ($val = $res->fetchRow()) { - $result[] = array('id'=>$val['id'], 'name'=>$val['name']); - } - return $result; - } - - // getCurrencyID - obtains an ID for currency. - static function getCurrencyID($currency) { - $mdb2 = getConnection(); - - $currency_id = null; - $sql = "select id from tt_work_currencies where name = ".$mdb2->quote($currency); - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) return null; - - if($val = $res->fetchRow()) { - $currency_id = $val['id']; - } - return $currency_id; - } - - // getCurrencyName - obtains currency name using its id. - static function getCurrencyName($currency_id) { - $mdb2 = getConnection(); - - $currency_name = null; - $sql = "select name from tt_work_currencies where id = $currency_id"; - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) return null; - - if($val = $res->fetchRow()) { - $currency_name = $val['name']; - } - return $currency_name; - } - - // getGroupItems - obtains a list of all items relevant to group in one API call to Remote Work Server. - function getGroupItems() { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_group_items_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - unset($result_array['call_status']); // Remove call_status element, - return $result_array; - } - - // getAvailableWorkItem - gets available work item details from remote work server. - function getAvailableWorkItem($work_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'group_id' => urlencode($group_id), - 'group_name' => urlencode(base64_encode($user->getGroupName())), - 'user_id' => urlencode($user->getUser()), - 'user_name' => urlencode(base64_encode($user->getName())), - 'user_email' => urlencode(base64_encode($user->getEmail())), - 'user_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'work_id' => urlencode($work_id)); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_available_work_item_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $work_item = $result_array['work_item']; - return $work_item; - } - - // getAvailableOffer - gets available offer details from remote work server. - function getAvailableOffer($offer_id) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'group_id' => urlencode($group_id), - 'group_name' => urlencode(base64_encode($user->getGroupName())), - 'user_id' => urlencode($user->getUser()), - 'user_name' => urlencode(base64_encode($user->getName())), - 'user_email' => urlencode(base64_encode($user->getEmail())), - 'user_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'offer_id' => urlencode($offer_id)); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_available_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - $offer = $result_array['offer']; - return $offer; - } - - // sendMessageToWorkOwner - sends a message to work owner via remote work server. - function sendMessageToWorkOwner($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_name' => urlencode(base64_encode($user->getGroupName())), - 'group_key' => urlencode($user->getGroupKey()), - 'work_id' => urlencode($fields['work_id']), - 'sender_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'sender_user_id' => urlencode($user->getUser()), - 'sender_name' => urlencode(base64_encode($user->getName())), - 'sender_email' => urlencode(base64_encode($user->getEmail())), - 'message_body' => urlencode(base64_encode($fields['message_body']))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->send_message_to_work_owner_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } - - // sendMessageToOfferOwner - sends a message to offer owner via remote work server. - function sendMessageToOfferOwner($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('lang' => urlencode($user->lang), - 'site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_name' => urlencode(base64_encode($user->getGroupName())), - 'group_key' => urlencode($user->getGroupKey()), - 'offer_id' => urlencode($fields['offer_id']), - 'sender_ip' => urlencode($_SERVER['REMOTE_ADDR']), - 'sender_user_id' => urlencode($user->getUser()), - 'sender_name' => urlencode(base64_encode($user->getName())), - 'sender_email' => urlencode(base64_encode($user->getEmail())), - 'message_body' => urlencode(base64_encode($fields['message_body']))); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->send_message_to_offer_owner_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - - // Check for errors. - $call_status = $result_array['call_status']; - if (!$call_status) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error']); - return false; - } - - return true; - } -} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 372b18d46..a189e50e5 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -63,9 +63,6 @@ - {if isTrue('WORK_SERVER_ADMINISTRATION')} - - {/if}
 Anuko Time Tracker 1.18.43.4776 | Copyright © Anuko | +  Anuko Time Tracker 1.18.43.4777 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index 135c8f272..6b26fe1ca 100644 --- a/report.php +++ b/report.php @@ -92,7 +92,7 @@ 'name'=>'mark_approved_select_options', 'data'=>$mark_approved_select_options, 'value'=>$cl_mark_approved_select_option)); - $mark_approved_action_options = array('1'=>$i18n->get('form.reports.include_approved'),'2'=>$i18n->get('form.reports.include_not_approved')); + $mark_approved_action_options = array('1'=>$i18n->get('dropdown.approved'),'2'=>$i18n->get('dropdown.not_approved')); $form->addInput(array('type'=>'combobox', 'name'=>'mark_approved_action_options', 'data'=>$mark_approved_action_options, diff --git a/reports.php b/reports.php index d8bf40995..107f8cee6 100644 --- a/reports.php +++ b/reports.php @@ -189,8 +189,8 @@ 'data'=>array(TIMESHEET_NOT_ASSIGNED=>$i18n->get('form.reports.include_not_assigned'), TIMESHEET_ASSIGNED=>$i18n->get('form.reports.include_assigned'), TIMESHEET_PENDING=>$i18n->get('form.reports.include_pending'), - TIMESHEET_APPROVED=>$i18n->get('form.reports.include_approved'), - TIMESHEET_NOT_APPROVED=>$i18n->get('form.reports.include_not_approved')), + TIMESHEET_APPROVED=>$i18n->get('dropdown.approved'), + TIMESHEET_NOT_APPROVED=>$i18n->get('dropdown.not_approved')), 'empty'=>array(''=>$i18n->get('dropdown.all')) )); } @@ -206,7 +206,7 @@ $form->addInput(array('type'=>'combobox', 'name'=>'approved', 'style'=>'width: 250px;', - 'data'=>array('1'=>$i18n->get('form.reports.include_approved'),'2'=>$i18n->get('form.reports.include_not_approved')), + 'data'=>array('1'=>$i18n->get('dropdown.approved'),'2'=>$i18n->get('dropdown.not_approved')), 'empty'=>array(''=>$i18n->get('dropdown.all')) )); } From cb0478b58a3e34cfffcf41e4e89de5a75685460d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 25 Feb 2019 16:54:38 +0000 Subject: [PATCH 0721/1848] Added approval handling to reports. --- WEB-INF/lib/ttReportHelper.class.php | 23 +++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- report.php | 19 ++++++++++++++++++- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 5d9de074e..57d004728 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -659,6 +659,29 @@ static function assignToInvoice($invoice_id, $time_log_ids, $expense_item_ids) { } } + // The markApproved marks a set of records as either approved or unapproved. + static function markApproved($time_log_ids, $expense_item_ids, $approved = true) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $approved_val = (int) $approved; + if ($time_log_ids) { + $sql = "update tt_log set approved = $approved_val". + " where id in(".join(', ', $time_log_ids).") and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); + } + if ($expense_item_ids) { + $sql = "update tt_expense_items set approved = $approved_val". + " where id in(".join(', ', $expense_item_ids).") and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); + } + } + // The markPaid marks a set of records as either paid or unpaid. static function markPaid($time_log_ids, $expense_item_ids, $paid = true) { global $user; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4f4adc75a..57554741f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - - - - -
 Anuko Time Tracker 1.18.43.4777 | Copyright © Anuko | +  Anuko Time Tracker 1.18.43.4778 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index 6b26fe1ca..aacb889ac 100644 --- a/report.php +++ b/report.php @@ -142,7 +142,8 @@ if ($request->isPost()) { // Validate parameters and at the same time build arrays of record ids. - if (($request->getParameter('btn_mark_paid') && 2 == $request->getParameter('mark_paid_select_options')) + if (($request->getParameter('btn_mark_approved') && 2 == $request->getParameter('mark_approved_select_options')) + || ($request->getParameter('btn_mark_paid') && 2 == $request->getParameter('mark_paid_select_options')) || ($request->getParameter('btn_assign') && 2 == $request->getParameter('assign_invoice_select_options'))) { // We act on selected records. Are there any? foreach($_POST as $key => $val) { @@ -164,6 +165,22 @@ } if ($err->no()) { + if ($request->getParameter('btn_mark_approved')) { + // User clicked the "Mark approved" button to mark some or all items either approved or not approved. + + // Determine user action. + $mark_approved = $request->getParameter('mark_approved_action_options') == 1 ? true : false; + + // Mark as requested. + if ($time_log_ids || $expense_item_ids) { + ttReportHelper::markApproved($time_log_ids, $expense_item_ids, $mark_approved); + } + + // Re-display this form. + header('Location: report.php'); + exit(); + } + if ($request->getParameter('btn_mark_paid')) { // User clicked the "Mark paid" button to mark some or all items either paid or not paid. From c14bc01ae221ece2c5b78c9c39b4902cb25154d6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 25 Feb 2019 17:40:15 +0000 Subject: [PATCH 0722/1848] Releasing Approval plugin for testing. --- WEB-INF/lib/ttReportHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/plugins.tpl | 2 -- reports.php | 26 +++++++++++++------------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 57d004728..80ead68ed 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1087,9 +1087,9 @@ static function getReportOptions($bean) { $options['invoice'] = $bean->getAttribute('invoice'); $options['paid_status'] = $bean->getAttribute('paid_status'); $options['approved'] = $bean->getAttribute('approved'); + if ($user->isPluginEnabled('ap') && $user->isClient() && !$user->can('view_client_unapproved')) + $options['approved'] = 1; // Restrict clients to approved records only. $options['timesheet'] = $bean->getAttribute('timesheet'); - if ($user->isPluginEnabled('ts') && $user->isClient() && !$user->can('view_client_unapproved')) - $options['timesheet'] = TIMESHEET_APPROVED; // Restrict clients to approved timesheet records only. if (is_array($bean->getAttribute('users'))) $options['users'] = join(',', $bean->getAttribute('users')); $options['period'] = $bean->getAttribute('period'); $options['period_start'] = $bean->getAttribute('start_date'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 57554741f..32d68a094 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- -{if isTrue('APPROVAL_DEBUG')} -{/if} {if isTrue('TIMESHEET_DEBUG')} diff --git a/reports.php b/reports.php index 107f8cee6..febfad794 100644 --- a/reports.php +++ b/reports.php @@ -178,6 +178,19 @@ )); } +// Add approved / not approved selector. +$showApproved = $user->isPluginEnabled('ap') && + ($user->can('view_own_reports') || $user->can('view_reports') || + $user->can('view_all_reports') || ($user->can('view_client_reports') && $user->can('view_client_unapproved'))); +if ($showApproved) { + $form->addInput(array('type'=>'combobox', + 'name'=>'approved', + 'style'=>'width: 250px;', + 'data'=>array('1'=>$i18n->get('dropdown.approved'),'2'=>$i18n->get('dropdown.not_approved')), + 'empty'=>array(''=>$i18n->get('dropdown.all')) + )); +} + // Add timesheet assignment selector. $showTimesheetDropdown = $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('view_timesheets') || @@ -198,19 +211,6 @@ ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets') || $user->can('view_client_timesheets')); -// Add approved / not approved selector. -$showApproved = $user->isPluginEnabled('ap') && - ($user->can('view_own_reports') || $user->can('view_reports') || - $user->can('view_all_reports') || ($user->can('view_client_reports') && $user->can('view_client_unapproved'))); -if ($showApproved) { - $form->addInput(array('type'=>'combobox', - 'name'=>'approved', - 'style'=>'width: 250px;', - 'data'=>array('1'=>$i18n->get('dropdown.approved'),'2'=>$i18n->get('dropdown.not_approved')), - 'empty'=>array(''=>$i18n->get('dropdown.all')) - )); -} - // Add user table. $showUsers = $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient(); $user_list = array(); From 9fa13d0babab9e51a19824ec7ef64830cf530fb2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 25 Feb 2019 19:54:48 +0000 Subject: [PATCH 0723/1848] Fixed export by adding approved status and timesheets to output. --- WEB-INF/lib/ttGroupExportHelper.class.php | 29 +++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 1ab501eab..aa9ec8cfb 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -42,6 +42,7 @@ class ttGroupExportHelper { var $taskMap = array(); var $projectMap = array(); var $clientMap = array(); + var $timesheetMap = array(); var $invoiceMap = array(); var $logMap = array(); var $customFieldMap = array(); @@ -174,6 +175,11 @@ function writeData() { foreach ($clients as $key=>$client_item) $this->clientMap[$client_item['id']] = $key + 1; + // Prepare timesheet map. + $timesheets = $this->getRecordsFromTable('tt_timesheets'); + foreach ($timesheets as $key=>$timesheet_item) + $this->timesheetMap[$timesheet_item['id']] = $key + 1; + // Prepare invoice map. $invoices = ttTeamHelper::getAllInvoices(); foreach ($invoices as $key=>$invoice_item) @@ -318,6 +324,27 @@ function writeData() { unset($bind_part); } + // Write timesheets. + if (count($timesheets) > 0) { + fwrite($this->file, $this->indentation." \n"); + foreach ($timesheets as $timesheet_item) { + $timesheet_part = $this->indentation.' '."timesheetMap[$timesheet_item['id']]."\""; + $timesheet_part .= " user_id=\"".$this->userMap[$timesheet_item['user_id']]."\""; + $timesheet_part .= " client_id=\"".$this->clientMap[$timesheet_item['client_id']]."\""; + $timesheet_part .= " name=\"".htmlspecialchars($timesheet_item['name'])."\""; + $timesheet_part .= " submit_status=\"".$timesheet_item['submit_status']."\""; + $timesheet_part .= " submitter_comment=\"".htmlspecialchars($timesheet_item['submitter_name'])."\""; + $timesheet_part .= " approval_status=\"".$timesheet_item['approval_status']."\""; + $timesheet_part .= " manager_comment=\"".htmlspecialchars($timesheet_item['manager_comment'])."\""; + $timesheet_part .= " status=\"".$timesheet_item['status']."\""; + $timesheet_part .= ">\n"; + fwrite($this->file, $timesheet_part); + } + fwrite($this->file, $this->indentation." \n"); + unset($timesheets); + unset($timesheet_part); + } + // Write invoices. if (count($invoices) > 0) { fwrite($this->file, $this->indentation." \n"); @@ -355,9 +382,11 @@ function writeData() { $log_part .= " client_id=\"".$this->clientMap[$record['client_id']]."\""; $log_part .= " project_id=\"".$this->projectMap[$record['project_id']]."\""; $log_part .= " task_id=\"".$this->taskMap[$record['task_id']]."\""; + $log_part .= " timesheet_id=\"".$this->timesheetMap[$record['timesheet_id']]."\""; $log_part .= " invoice_id=\"".$this->invoiceMap[$record['invoice_id']]."\""; $log_part .= " comment=\"".htmlspecialchars($record['comment'])."\""; $log_part .= " billable=\"".$record['billable']."\""; + $log_part .= " approved=\"".$record['approved']."\""; $log_part .= " paid=\"".$record['paid']."\""; $log_part .= " status=\"".$record['status']."\""; $log_part .= ">\n"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 32d68a094..f61c6cfbf 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.43.4778 | Copyright © Anuko | +  Anuko Time Tracker 1.18.44.4779 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index ce0cd52ab..5c5941c3e 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -134,12 +134,10 @@ function handlePluginCheckboxes() { {$forms.pluginsForm.work_units.control} {$i18n.label.configure}
{$forms.pluginsForm.approval.control}
{$forms.pluginsForm.timesheets.control}
- - - + +
 Anuko Time Tracker 1.18.44.4779 | Copyright © Anuko | +  Anuko Time Tracker 1.18.44.4780 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From ecb94422f83654dd371f751a30112a80833748dd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 25 Feb 2019 22:00:22 +0000 Subject: [PATCH 0724/1848] Fixes to import/export for timesheets and approval status. --- WEB-INF/lib/ttGroupExportHelper.class.php | 2 + WEB-INF/lib/ttOrgImportHelper.class.php | 76 +++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- report.php | 5 +- 4 files changed, 76 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index aa9ec8cfb..11104a5ff 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -456,9 +456,11 @@ function writeData() { $expense_item_part .= " user_id=\"".$this->userMap[$expense_item['user_id']]."\""; $expense_item_part .= " client_id=\"".$this->clientMap[$expense_item['client_id']]."\""; $expense_item_part .= " project_id=\"".$this->projectMap[$expense_item['project_id']]."\""; + $expense_item_part .= " timesheet_id=\"".$this->timesheetMap[$expense_item['timesheet_id']]."\""; $expense_item_part .= " name=\"".htmlspecialchars($expense_item['name'])."\""; $expense_item_part .= " cost=\"".$expense_item['cost']."\""; $expense_item_part .= " invoice_id=\"".$this->invoiceMap[$expense_item['invoice_id']]."\""; + $expense_item_part .= " approved=\"".$expense_item['approved']."\""; $expense_item_part .= " paid=\"".$expense_item['paid']."\""; $expense_item_part .= " status=\"".$expense_item['status']."\""; $expense_item_part .= ">\n"; diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 251cb3ea6..d7161d90a 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -36,7 +36,7 @@ class ttOrgImportHelper { var $canImport = true; // False if we cannot import data due to a conflict such as login collision. var $firstPass = true; // True during first pass through the file. var $org_id = null; // Organization id (same as top group_id). - var $current_group_id = null; // Current group id during parsing. + var $current_group_id = null; // Current group id during parsing. var $parents = array(); // A stack of parent group ids for current group all the way to the root including self. var $top_role_id = 0; // Top role id. @@ -46,6 +46,7 @@ class ttOrgImportHelper { var $currentGroupProjectMap = array(); var $currentGroupClientMap = array(); var $currentGroupUserMap = array(); + var $currentGroupTimesheetMap = array(); var $currentGroupInvoiceMap = array(); var $currentGroupLogMap = array(); var $currentGroupCustomFieldMap = array(); @@ -138,6 +139,7 @@ function startElement($parser, $name, $attrs) { unset($this->currentGroupProjectMap); $this->currentGroupProjectMap = array(); unset($this->currentGroupClientMap); $this->currentGroupClientMap = array(); unset($this->currentGroupUserMap); $this->currentGroupUserMap = array(); + unset($this->currentGroupTimesheetMap); $this->currentGroupTimesheetMap = array(); unset($this->currentGroupInvoiceMap); $this->currentGroupInvoiceMap = array(); unset($this->currentGroupLogMap); $this->currentGroupLogMap = array(); unset($this->currentGroupCustomFieldMap); $this->currentGroupCustomFieldMap = array(); @@ -274,6 +276,28 @@ function startElement($parser, $name, $attrs) { return; } + if ($name == 'TIMESHEET') { + // We get here when processing tags for the current group. + $timesheet_id = $this->insertTimesheet(array( + 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], + 'group_id' => $this->current_group_id, + 'org_id' => $this->org_id, + 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'name' => $attrs['NAME'], + 'submit_status' => $attrs['SUBMIT_STATUS'], + 'submitter_comment' => $attrs['SUBMITTER_COMMENT'], + 'approval_status' => $attrs['APPROVAL_STATUS'], + 'manager_comment' => $attrs['MANAGER_COMMENT'], + 'status' => $attrs['STATUS'])); + if ($timesheet_id) { + // Add a mapping. + $this->currentGroupTimesheetMap[$attrs['ID']] = $timesheet_id; + } else { + $this->errors->add($i18n->get('error.db')); + } + return; + } + if ($name == 'INVOICE') { // We get here when processing tags for the current group. $invoice_id = $this->insertInvoice(array( @@ -305,9 +329,11 @@ function startElement($parser, $name, $attrs) { 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], 'task_id' => $this->currentGroupTaskMap[$attrs['TASK_ID']], + 'timesheet_id' => $this->currentGroupTimesheetMap[$attrs['TIMESHEET_ID']], 'invoice_id' => $this->currentGroupInvoiceMap[$attrs['INVOICE_ID']], 'comment' => (isset($attrs['COMMENT']) ? $attrs['COMMENT'] : ''), 'billable' => $attrs['BILLABLE'], + 'approved' => $attrs['APPROVED'], 'paid' => $attrs['PAID'], 'status' => $attrs['STATUS'])); if ($log_item_id) { @@ -371,9 +397,11 @@ function startElement($parser, $name, $attrs) { 'org_id' => $this->org_id, 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], + 'timesheet_id' => $this->currentGroupTimesheetMap[$attrs['TIMESHEET_ID']], 'name' => $attrs['NAME'], 'cost' => $attrs['COST'], 'invoice_id' => $this->currentGroupInvoiceMap[$attrs['INVOICE_ID']], + 'approved' => $attrs['APPROVED'], 'paid' => $attrs['PAID'], 'status' => $attrs['STATUS'])); if (!$expense_item_id) $this->errors->add($i18n->get('error.db')); @@ -719,17 +747,21 @@ private function insertExpense($fields) { $user_id = (int) $fields['user_id']; $client_id = $fields['client_id']; $project_id = $fields['project_id']; + $timesheet_id = $fields['timesheet_id']; $name = $fields['name']; $cost = str_replace(',', '.', $fields['cost']); $invoice_id = $fields['invoice_id']; $status = $fields['status']; + $approved = (int) $fields['approved']; $paid = (int) $fields['paid']; $created = ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$user->id; $sql = "insert into tt_expense_items". - " (date, user_id, group_id, org_id, client_id, project_id, name, cost, invoice_id, paid, created, created_ip, created_by, status)". + " (date, user_id, group_id, org_id, client_id, project_id, timesheet_id, name,". + " cost, invoice_id, approved, paid, created, created_ip, created_by, status)". " values (".$mdb2->quote($date).", $user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($project_id). - ", ".$mdb2->quote($name).", ".$mdb2->quote($cost).", ".$mdb2->quote($invoice_id).", $paid $created, ".$mdb2->quote($status).")"; + ", ".$mdb2->quote($timesheet_id).", ".$mdb2->quote($name).", ".$mdb2->quote($cost).", ".$mdb2->quote($invoice_id). + ", $approved, $paid $created, ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -865,6 +897,35 @@ private function insertRole($fields) return $last_id; } + // insertTimesheet - inserts a timesheet in database. + private function insertTimesheet($fields) + { + $mdb2 = getConnection(); + + $user_id = (int) $fields['user_id']; + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $client_id = $fields['client_id']; + $name = $fields['name']; + $submit_status = $fields['submit_status']; + $submitter_comment = $fields['submitter_comment']; + $approval_status = $fields['approval_status']; + $manager_comment = $fields['manager_comment']; + $status = $fields['status']; + + // Insert a new timesheet record. + $sql = "insert into tt_timesheets (user_id, group_id, org_id, client_id, name,". + " submit_status, submitter_comment, approval_status, manager_comment, status)". + " values($user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($name).", ". + $mdb2->quote($fields['submit_status']).", ".$mdb2->quote($fields['submiter_comment']).", ". + $mdb2->quote($fields['approval_status']).", ".$mdb2->quote($fields['manager_comment']).", ".$mdb2->quote($fields['status']).")"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + $last_id = $mdb2->lastInsertID('tt_timesheets', 'id'); + return $last_id; + } + // insertInvoice - inserts an invoice in database. private function insertInvoice($fields) { @@ -1056,15 +1117,17 @@ private function insertLogEntry($fields) { $client_id = $fields['client_id']; $project_id = $fields['project_id']; $task_id = $fields['task_id']; + $timesheet_id = $fields['timesheet_id']; $invoice_id = $fields['invoice_id']; $comment = $fields['comment']; $billable = (int) $fields['billable']; + $approved = (int) $fields['approved']; $paid = (int) $fields['paid']; $status = $fields['status']; $sql = "insert into tt_log". - " (user_id, group_id, org_id, date, start, duration, client_id, project_id, task_id, invoice_id, comment". - ", billable, paid, created, created_ip, created_by, status)". + " (user_id, group_id, org_id, date, start, duration, client_id, project_id, task_id, timesheet_id, invoice_id, comment". + ", billable, approved, paid, created, created_ip, created_by, status)". " values ($user_id, $group_id, $org_id". ", ".$mdb2->quote($date). ", ".$mdb2->quote($start). @@ -1072,9 +1135,10 @@ private function insertLogEntry($fields) { ", ".$mdb2->quote($client_id). ", ".$mdb2->quote($project_id). ", ".$mdb2->quote($task_id). + ", ".$mdb2->quote($timesheet_id). ", ".$mdb2->quote($invoice_id). ", ".$mdb2->quote($comment). - ", $billable, $paid". + ", $billable, $approved, $paid". ", now(), ".$mdb2->quote($_SERVER['REMOTE_ADDR']).", ".$user->id. ", ". $mdb2->quote($status).")"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f61c6cfbf..36ff12c7c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- '; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { $colspan++; $html .= ''; } // User custom field labels. - if ($custom_fields && $custom_fields->userFields) { + if (isset($custom_fields) && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; $checkbox_control_name = 'show_'.$field_name; @@ -139,7 +140,7 @@ if ($bean->getAttribute('chproject')) { $colspan++; $html .= ''; } if ($bean->getAttribute('chtask')) { $colspan++; $html .= ''; } // Time custom field labels. - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; $checkbox_control_name = 'show_'.$field_name; @@ -174,7 +175,7 @@ $html .= ''; } // User custom fields. - if ($custom_fields && $custom_fields->userFields) { + if (isset($custom_fields) && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; $checkbox_control_name = 'show_'.$field_name; @@ -197,7 +198,7 @@ $html .= ''; } // Time custom fields. - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; $checkbox_control_name = 'show_'.$field_name; @@ -242,7 +243,7 @@ $html .= ''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $html .= ''; // User custom fields. - if ($custom_fields && $custom_fields->userFields) { + if (isset($custom_fields) && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; $checkbox_control_name = 'show_'.$field_name; @@ -253,7 +254,7 @@ if ($bean->getAttribute('chproject')) $html .= ''; if ($bean->getAttribute('chtask')) $html .= ''; // Time custom fields. - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; $checkbox_control_name = 'show_'.$field_name; @@ -314,7 +315,7 @@ $html .= ''; } // User custom fields. - if ($custom_fields && $custom_fields->userFields) { + if (isset($custom_fields) && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; $checkbox_control_name = 'show_'.$field_name; @@ -337,7 +338,7 @@ $html .= ''; } // Time custom fields. - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; $checkbox_control_name = 'show_'.$field_name; @@ -371,7 +372,7 @@ $html .= ''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $html .= ''; // User custom fields. - if ($custom_fields && $custom_fields->userFields) { + if (isset($custom_fields) && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; $checkbox_control_name = 'show_'.$field_name; @@ -382,7 +383,7 @@ if ($bean->getAttribute('chproject')) $html .= ''; if ($bean->getAttribute('chtask')) $html .= ''; // Time custom fields. - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; $checkbox_control_name = 'show_'.$field_name; From c90d809986888e191292af4ce5660a64f12c040a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 19 May 2021 18:58:44 +0000 Subject: [PATCH 1588/1848] Eliminated 2 more php8 warnings. --- WEB-INF/lib/ttFavReportHelper.class.php | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index d1cce7240..be23f6a39 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -304,7 +304,7 @@ static function loadReport(&$bean) { if ($val['report_spec']) { $report_spec = $val['report_spec']; // Time custom field settings. - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; $checkbox_field_name = 'show_'.$field_name; @@ -315,7 +315,7 @@ static function loadReport(&$bean) { } } // User custom field settings. - if ($custom_fields && $custom_fields->userFields) { + if (isset($custom_fields) && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; $checkbox_field_name = 'show_'.$field_name; diff --git a/initialize.php b/initialize.php index 2493a2154..3d348f59a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5572"); +define("APP_VERSION", "1.19.28.5573"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 273e129c8e1a28ce5d8d0a425caf3865332d3bda Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Jun 2021 15:22:58 +0000 Subject: [PATCH 1589/1848] Starting to integrate newly translated pt-br strings from pr #111. --- WEB-INF/resources/ca.lang.php | 1 - WEB-INF/resources/cs.lang.php | 1 - WEB-INF/resources/da.lang.php | 1 - WEB-INF/resources/de.lang.php | 2 -- WEB-INF/resources/en.lang.php | 1 - WEB-INF/resources/es.lang.php | 1 - WEB-INF/resources/et.lang.php | 1 - WEB-INF/resources/fa.lang.php | 1 - WEB-INF/resources/fi.lang.php | 1 - WEB-INF/resources/fr.lang.php | 1 - WEB-INF/resources/gr.lang.php | 2 -- WEB-INF/resources/he.lang.php | 1 - WEB-INF/resources/hu.lang.php | 2 -- WEB-INF/resources/it.lang.php | 2 -- WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 1 - WEB-INF/resources/no.lang.php | 1 - WEB-INF/resources/pl.lang.php | 1 - WEB-INF/resources/pt-br.lang.php | 21 +++++++-------------- WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 1 - WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 1 - WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 1 - WEB-INF/resources/sv.lang.php | 2 -- WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 1 - WEB-INF/resources/zh-tw.lang.php | 1 - initialize.php | 2 +- 31 files changed, 8 insertions(+), 49 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index b1fbd33ce..333d78abe 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -40,7 +40,6 @@ 'menu.users' => 'Usuaris', 'menu.groups' => 'Grups', // TODO: translate the following. -// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Clients', 'menu.options' => 'Opcions', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 97f37507f..a7a3fbdb5 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -41,7 +41,6 @@ 'menu.users' => 'Uživatelů', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Export', 'menu.clients' => 'Zákazníci', // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index dd185700f..f2e0ff43e 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -38,7 +38,6 @@ 'menu.users' => 'Brugere', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Eksport', 'menu.clients' => 'Kunder', 'menu.options' => 'Indstillinger', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index ed2d2587a..7a8318646 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -37,8 +37,6 @@ 'menu.tasks' => 'Aufgaben', 'menu.users' => 'Personen', 'menu.groups' => 'Gruppen', -// TODO: translate the following. -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Exportieren', 'menu.clients' => 'Kunden', 'menu.options' => 'Optionen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 80ef82777..4da63222f 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -21,7 +21,6 @@ 'menu.register' => 'Register', 'menu.profile' => 'Profile', 'menu.group' => 'Group', -'menu.subgroups' => 'Subgroups', 'menu.plugins' => 'Plugins', 'menu.time' => 'Time', 'menu.puncher' => 'Punch', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index c50f388b9..571c167c8 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -39,7 +39,6 @@ 'menu.users' => 'Personas', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Clientes', 'menu.options' => 'Opciones', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 573d684c6..15888784d 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -38,7 +38,6 @@ 'menu.tasks' => 'Tööülesanded', 'menu.users' => 'Kasutajad', 'menu.groups' => 'Grupid', -'menu.subgroups' => 'Alamgrupid', 'menu.export' => 'Eksport', // TODO: is this a correct term as an opposite of "Import"? 'menu.clients' => 'Kliendid', 'menu.options' => 'Suvandid', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 2e2718eb7..f9ae9a082 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -39,7 +39,6 @@ 'menu.users' => 'کاربران', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'پشتیبانی', 'menu.clients' => 'مشتری ها', 'menu.options' => 'تنظیمات', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 534a94b8c..bcfe62417 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -38,7 +38,6 @@ 'menu.users' => 'Käyttäjät', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Vie', 'menu.clients' => 'Asiakkaat', 'menu.options' => 'Optiot', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 0b55172df..d0170ebda 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -38,7 +38,6 @@ 'menu.users' => 'Utilisateurs', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Exporter', 'menu.clients' => 'Clients', 'menu.options' => 'Options', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index f8bdb0dc5..b8e6789c0 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -36,8 +36,6 @@ 'menu.tasks' => 'Εργασίες', 'menu.users' => 'Χρήστες', 'menu.groups' => 'Ομάδες', -// TODO: translate the following. -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Εξαγωγή', 'menu.clients' => 'Πελάτες', 'menu.options' => 'Επιλογές', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 7505f0965..011b5f573 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -39,7 +39,6 @@ 'menu.users' => 'משתמשים', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'ייצוא', 'menu.clients' => 'לקוחות', 'menu.options' => 'אפשרויות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 052dbe72e..f8fb388d6 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -41,8 +41,6 @@ // 'menu.users' => 'Users', 'menu.groups' => 'Csoportok', // TODO: translate the following. -// 'menu.subgroups' => 'Subgroups', -// TODO: translate the following. // 'menu.export' => 'Export', 'menu.clients' => 'Ügyfelek', 'menu.options' => 'Opciók', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 55faab87c..4e2bdfb2f 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -38,8 +38,6 @@ 'menu.tasks' => 'Compiti', 'menu.users' => 'Utenti', 'menu.groups' => 'Gruppi', -// TODO: translate the following. -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Esportazione', 'menu.clients' => 'Clienti', 'menu.options' => 'Opzioni', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 57f5592df..15db98a04 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -40,7 +40,6 @@ 'menu.users' => 'ユーザー', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'クライアント', 'menu.options' => 'オプション', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 832464fbc..8f22ae323 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -40,7 +40,6 @@ 'menu.users' => '사용자', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => '클라이언트', 'menu.options' => '옵션', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 66c32ea5a..378216466 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -34,7 +34,6 @@ 'menu.tasks' => 'Taken', 'menu.users' => 'Medewerkers', 'menu.groups' => 'Groepen', -'menu.subgroups' => 'Subgroepen', 'menu.export' => 'Exporteren', 'menu.clients' => 'Klanten', 'menu.options' => 'Opties', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 3929ac4bc..b13b942f5 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -41,7 +41,6 @@ 'menu.users' => 'Brukere', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Eksport', 'menu.clients' => 'Klienter', 'menu.options' => 'Opsjoner', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 98018f677..144ea434d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -38,7 +38,6 @@ 'menu.users' => 'Użytkownicy', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Eksport', 'menu.clients' => 'Klienci', 'menu.options' => 'Opcje', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 3fdfae2d1..a67633ab7 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -5,7 +5,7 @@ // Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. -$i18n_language = 'Portuguese (Português brasileiro)'; +$i18n_language = 'Portuguese (Português Brasileiro)'; $i18n_months = array('Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'); $i18n_weekdays = array('Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado'); $i18n_weekdays_short = array('Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab'); @@ -18,27 +18,20 @@ 'menu.logout' => 'Logout', 'menu.forum' => 'Fórum', 'menu.help' => 'Ajuda', -// TODO: translate the following. -// 'menu.register' => 'Register', +'menu.register' => 'Registro', 'menu.profile' => 'Perfil', -// TODO: translate the following. -// 'menu.group' => 'Group', +'menu.group' => 'Grupo', 'menu.plugins' => 'Plugins', 'menu.time' => 'Tempo', -// TODO: translate the following. -// 'menu.puncher' => 'Punch', -// 'menu.week' => 'Week', -'menu.expenses' => 'Gastos', +'menu.puncher' => 'Punch', +'menu.week' => 'Semana', +'menu.expenses' => 'Despesas', 'menu.reports' => 'Relatórios', -// TODO: translate the following. -// 'menu.timesheets' => 'Timesheets', +'menu.timesheets' => 'Planilha de horas', 'menu.charts' => 'Gráficos', 'menu.projects' => 'Projetos', 'menu.tasks' => 'Tarefas', 'menu.users' => 'Usuários', -// TODO: translate the following. -// 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Exportar', 'menu.clients' => 'Clientes', 'menu.options' => 'Opções', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9cdaffd82..585db686f 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -42,7 +42,6 @@ 'menu.users' => 'Usuários', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', // 'menu.clients' => 'Clients', 'menu.options' => 'Opções', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 7e42575c3..eb99020fa 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -42,7 +42,6 @@ 'menu.users' => 'Utilizatori', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Clienti', // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index c74e45bc5..e5e767ff4 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -33,7 +33,6 @@ 'menu.tasks' => 'Задачи', 'menu.users' => 'Пользователи', 'menu.groups' => 'Группы', -'menu.subgroups' => 'Подгруппы', 'menu.export' => 'Экспорт', 'menu.clients' => 'Клиенты', 'menu.options' => 'Опции', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 574a283f5..dcdcb8c81 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -38,7 +38,6 @@ 'menu.users' => 'Používatelia', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Export', 'menu.clients' => 'Klienti', 'menu.options' => 'Nastavenia', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index a2ce91ee7..095b12f30 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -40,7 +40,6 @@ // 'menu.tasks' => 'Tasks', // 'menu.users' => 'Users', // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Stranke', 'menu.options' => 'Možnosti', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index b876161b5..73a1dce54 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -38,7 +38,6 @@ 'menu.users' => 'Korisnici', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Izvoz', 'menu.clients' => 'Klijenti', 'menu.options' => 'Opcije', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 3f4cc33bc..764671820 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -36,8 +36,6 @@ 'menu.tasks' => 'Arbetsuppgifter', 'menu.users' => 'Användare', 'menu.groups' => 'Grupper', -// TODO: translate the following. -// 'menu.subgroups' => 'Subgroups', 'menu.export' => 'Exportera', 'menu.clients' => 'Kunder', 'menu.options' => 'Alternativ', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index bf768a1b6..5e7ee26d1 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -42,7 +42,6 @@ 'menu.users' => 'Kullanıcılar', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', // 'menu.export' => 'Export', 'menu.clients' => 'Müşteriler', // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 00095186b..d10d1c7c3 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -38,7 +38,6 @@ 'menu.users' => '用户', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => '导出数据', 'menu.clients' => '客户', 'menu.options' => '选项', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index d4fa2a9f8..f1a6a6e30 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -38,7 +38,6 @@ 'menu.users' => '用戶', // TODO: translate the following. // 'menu.groups' => 'Groups', -// 'menu.subgroups' => 'Subgroups', 'menu.export' => '輸出資料', 'menu.clients' => '客戶', 'menu.options' => '選項', diff --git a/initialize.php b/initialize.php index 3d348f59a..c47a19f44 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5573"); +define("APP_VERSION", "1.19.28.5574"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 5ff85207b6b74ed20d665de27263d8256bbab5e1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Jun 2021 16:00:41 +0000 Subject: [PATCH 1590/1848] Work in progress integrating changes from pr #111. --- WEB-INF/resources/pt-br.lang.php | 51 ++++++++++++++------------------ initialize.php | 2 +- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index a67633ab7..b7203dea6 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -32,6 +32,7 @@ 'menu.projects' => 'Projetos', 'menu.tasks' => 'Tarefas', 'menu.users' => 'Usuários', +'menu.groups' => 'Grupos', 'menu.export' => 'Exportar', 'menu.clients' => 'Clientes', 'menu.options' => 'Opções', @@ -46,59 +47,51 @@ 'error.access_denied' => 'Acesso negado.', 'error.sys' => 'Erro no sistema.', 'error.db' => 'Erro no banco de dados.', -// TODO: translate the following. -// 'error.registered_recently' => 'Registered recently.', -// 'error.feature_disabled' => 'Feature is disabled.', +'error.registered_recently' => 'Registrado recentemente.', +'error.feature_disabled' => 'Recurso desabilitado.', 'error.field' => 'Dados incorretos "{0}".', 'error.empty' => 'Campo "{0}" está vazio.', 'error.not_equal' => 'Campo "{0}" é diferente do campo "{1}".', -// TODO: translate the following. -// 'error.interval' => 'Field "{0}" must be greater than "{1}".', +'error.interval' => 'Campo "{0}" precisa ser maior que "{1}".', 'error.project' => 'Selecione projeto.', 'error.task' => 'Selecione tarefa.', 'error.client' => 'Selecione cliente.', 'error.report' => 'Selecione relatório.', -// TODO: translate the following. -// 'error.record' => 'Select record.', +'error.record' => 'Selecione o registro.', 'error.auth' => 'Usuário ou senha incorretos.', 'error.user_exists' => 'Já existe usuário com este login.', -// TODO: translate the following. -// 'error.object_exists' => 'Object with this name already exists.', +'error.object_exists' => 'Já existe um objeto com este nome.', 'error.invoice_exists' => 'Já existe fatura com este número.', -// TODO: translate the following. -// 'error.role_exists' => 'Role with this rank already exists.', +// TODO: improve translation of the word "role" in error.role_exists. função here, papel elsewhere? +'error.role_exists' => 'Já existe uma função com este rank.', 'error.no_invoiceable_items' => 'Não há items faturáveis.', -// TODO: translate the following. -// 'error.no_records' => 'There are no records.', +'error.no_records' => 'Não há registros.', 'error.no_login' => 'Não há usuário com este login.', -'error.no_groups' => 'Sua base de dados está vazia. Entre como admin e crie uma equipe nova.', // TODO: replace "team" with "group". +'error.no_groups' => 'Sua base de dados está vazia. Entre como admin e crie um grupo novo.', 'error.upload' => 'Erro no envio do arquivo.', 'error.range_locked' => 'Período está bloqueado.', 'error.mail_send' => 'Erro enviando o e-mail.', -// TODO: improve the translation above by adding MAIL_SMTP_DEBUG part. -// 'error.mail_send' => 'Error sending mail. Use MAIL_SMTP_DEBUG for diagnostics.', +// TODO: is "Use" in error.mail_send translated correctly? +'error.mail_send' => 'Erro ao enviar e-mail. Use MAIL_SMTP_DEBUG para diagnósticos.', 'error.no_email' => 'Não há e-mail associado a este login.', 'error.uncompleted_exists' => 'Entrada incompleta existente. Feche ou remova-a.', 'error.goto_uncompleted' => 'Ir até a entrada incompleta.', 'error.overlap' => 'O intervalo se sobrepõe com entradas já existentes.', 'error.future_date' => 'Data é no futuro.', -// TODO: translate the following. -// 'error.xml' => 'Error in XML file at line %d: %s.', -// 'error.cannot_import' => 'Cannot import: %s.', -// 'error.format' => 'Invalid file format.', -// 'error.user_count' => 'Limit on user count.', -// 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. +'error.xml' => 'Erro no arquivo XML, linha line %d: %s.', +'error.cannot_import' => 'Não foi possível importar: %s.', +'error.format' => 'Formato de arquivo inválido.', +'error.user_count' => 'Limite na contagem de usuários.', +'error.expired' => 'Data de expiração atingida.', +'error.file_storage' => 'Erro relacionado ao servidor de armazenamento de arquivos.', +'error.remote_work' => 'Erro relacionado ao servidor responsável pelo plugin work.', // Warning messages. -// TODO: translate the following. -// 'warn.sure' => 'Are you sure?', -// 'warn.confirm_save' => 'Date has changed. Confirm saving, not copying this item.', +'warn.sure' => 'Tem certeza?', +'warn.confirm_save' => 'A data mudou. Confirme salvando, não copiando este item.', // Success messages. -// TODO: translate the following. -// 'msg.success' => 'Operation completed successfully.', +'msg.success' => 'Operação concluída com sucesso.', // Labels for buttons. 'button.login' => 'Login', diff --git a/initialize.php b/initialize.php index c47a19f44..88b47d256 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5574"); +define("APP_VERSION", "1.19.28.5575"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 565d1b835511f1af29f945d3c944645a0bda57d3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Jun 2021 17:57:11 +0000 Subject: [PATCH 1591/1848] A bit more progress integrating pr #111. --- WEB-INF/resources/ca.lang.php | 2 - WEB-INF/resources/cs.lang.php | 2 - WEB-INF/resources/da.lang.php | 2 - WEB-INF/resources/de.lang.php | 2 - WEB-INF/resources/en.lang.php | 2 - WEB-INF/resources/es.lang.php | 2 - WEB-INF/resources/et.lang.php | 2 - WEB-INF/resources/fa.lang.php | 2 - WEB-INF/resources/fi.lang.php | 2 - WEB-INF/resources/fr.lang.php | 2 - WEB-INF/resources/gr.lang.php | 2 - WEB-INF/resources/he.lang.php | 2 - WEB-INF/resources/hu.lang.php | 2 - WEB-INF/resources/it.lang.php | 2 - WEB-INF/resources/ja.lang.php | 2 - WEB-INF/resources/ko.lang.php | 2 - WEB-INF/resources/nl.lang.php | 2 - WEB-INF/resources/no.lang.php | 2 - WEB-INF/resources/pl.lang.php | 2 - WEB-INF/resources/pt-br.lang.php | 97 ++++++++++++++------------------ WEB-INF/resources/pt.lang.php | 2 - WEB-INF/resources/ro.lang.php | 2 - WEB-INF/resources/ru.lang.php | 2 - WEB-INF/resources/sk.lang.php | 2 - WEB-INF/resources/sl.lang.php | 2 - WEB-INF/resources/sr.lang.php | 2 - WEB-INF/resources/sv.lang.php | 2 - WEB-INF/resources/tr.lang.php | 2 - WEB-INF/resources/zh-cn.lang.php | 2 - WEB-INF/resources/zh-tw.lang.php | 2 - initialize.php | 2 +- 31 files changed, 42 insertions(+), 115 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 333d78abe..1f735771e 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -260,8 +260,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index a7a3fbdb5..b180b884e 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -270,8 +270,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index f2e0ff43e..9c6aea90d 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -252,8 +252,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Aktive Brugere', 'label.inactive_users' => 'Inaktive Brugere', // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 7a8318646..d2dff2a08 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -244,8 +244,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Aktive Nutzer', 'label.inactive_users' => 'Inaktive Nutzer', // TODO: translate the following or confirm that "Details" is also correct for German (exactly as the English string). diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 4da63222f..d7fb49ac4 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -234,8 +234,6 @@ 'label.attachments' => 'Attachments', 'label.files' => 'Files', 'label.file' => 'File', -'label.image' => 'Image', -'label.download' => 'Download', 'label.active_users' => 'Active Users', 'label.inactive_users' => 'Inactive Users', 'label.details' => 'Details', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 571c167c8..c352f5d9a 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -263,8 +263,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 15888784d..c4ab61d3a 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -260,8 +260,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Aktiivsed kasutajad', 'label.inactive_users' => 'Mitteaktiivsed kasutajad', // TODO: translate the following. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f9ae9a082..dfff12bd2 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -263,8 +263,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'کاربران فعال', 'label.inactive_users' => 'کاربران غیرفعال', // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index bcfe62417..f624a91d1 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -256,8 +256,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Aktiiviset käyttäjät', 'label.inactive_users' => 'Ei-aktiiviset käyttäjät', // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index d0170ebda..f3e0c862a 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -250,8 +250,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Utilisateurs actifs', 'label.inactive_users' => 'Utilisateurs inactifs', // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index b8e6789c0..b5ba3bf3e 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -245,8 +245,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Ενεργοί χρήστες', 'label.inactive_users' => 'Ανενεργοί χρήστες', // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 011b5f573..f85fbb544 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -271,8 +271,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'משתמשים פעילים', 'label.inactive_users' => 'משתמשים לא פעילים', // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index f8fb388d6..791105b34 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -265,8 +265,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 4e2bdfb2f..2654c6398 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -249,8 +249,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Utenti attivi', 'label.inactive_users' => 'Utenti inattivi', // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 15db98a04..b9d84a9ac 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -270,8 +270,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 8f22ae323..f1cff3fc4 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -270,8 +270,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 378216466..dfd469993 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -228,8 +228,6 @@ 'label.attachments' => 'Bijlagen', 'label.files' => 'Bestanden', 'label.file' => 'Bestand', -'label.image' => 'Afbeelding', -'label.download' => 'Download', 'label.active_users' => 'Actieve medewerkers', 'label.inactive_users' => 'Inactieve medewerkers', 'label.details' => 'Details', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index b13b942f5..3511faec7 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -267,8 +267,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 144ea434d..dd4deeadd 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -257,8 +257,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Aktywni użytkownicy', 'label.inactive_users' => 'Nieaktywni użytkownicy', // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index b7203dea6..40f7a8362 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -110,16 +110,13 @@ 'button.export' => 'Exportar equipe', // TODO: replace "team" with "group". 'button.import' => 'Importar equipe', // TODO: replace "team" with "group". 'button.close' => 'Fechar', -// TODO: translate the following. -// 'button.start' => 'Start', +'button.start' => 'Iniciar', 'button.stop' => 'Parar', -// TODO: translate the following. -// 'button.approve' => 'Approve', -// 'button.disapprove' => 'Disapprove', +'button.approve' => 'Aprovar', +'button.disapprove' => 'Desaprovar', // Labels for controls on forms. Labels in this section are used on multiple forms. -// TODO: translate the following. -// 'label.menu' => 'Menu', +'label.menu' => 'Menu', 'label.group_name' => 'Nome da equipe', // TODO: replace "team" with "group". 'label.address' => 'Endereço', 'label.currency' => 'Moeda', @@ -132,18 +129,16 @@ 'label.confirm_password' => 'Confirme a senha', 'label.email' => 'E-mail', 'label.cc' => 'Cc', -// TODO: translate the following. -// 'label.bcc' => 'Bcc', +'label.bcc' => 'Bcc', 'label.subject' => 'Assunto', 'label.date' => 'Data', 'label.start_date' => 'Data inicial', 'label.end_date' => 'Data final', 'label.user' => 'Usuário', 'label.users' => 'Usuários', -// TODO: translate the following. -// 'label.group' => 'Group', -// 'label.subgroups' => 'Subgroups', -// 'label.roles' => 'Roles', +'label.group' => 'Grupo', +'label.subgroups' => 'Subgrupos', +'label.roles' => 'Papéis', 'label.client' => 'Cliente', 'label.clients' => 'Clientes', 'label.option' => 'Opção', @@ -157,16 +152,13 @@ 'label.finish' => 'Fim', 'label.duration' => 'Duração', 'label.note' => 'Anotação', -// TODO: translate the following. -// 'label.notes' => 'Notes', +'label.notes' => 'Anotações', 'label.item' => 'Item', 'label.cost' => 'Custo', -// TODO: translate the following. -// 'label.ip' => 'IP', +'label.ip' => 'IP', 'label.day_total' => 'Total diário', 'label.week_total' => 'Total semanal', -// TODO: translate the following. -// 'label.month_total' => 'Month total', +'label.month_total' => 'Total mensal', 'label.today' => 'Hoje', 'label.view' => 'Ver', 'label.edit' => 'Editar', @@ -174,10 +166,9 @@ 'label.configure' => 'Configurar', 'label.select_all' => 'Selecionar todos', 'label.select_none' => 'Desmarcar todos', -// TODO: translate the following. -// 'label.day_view' => 'Day view', -// 'label.week_view' => 'Week view', -// 'label.puncher' => 'Puncher', +'label.day_view' => 'Visão diária', +'label.week_view' => 'Visão semanal', +'label.puncher' => 'Puncher', 'label.id' => 'ID', 'label.language' => 'Idioma', 'label.decimal_mark' => 'Ponto decimal', @@ -200,17 +191,14 @@ 'label.role_comanager' => '(coordenador)', 'label.role_admin' => '(administrador)', 'label.page' => 'Página', -// TODO: translate the following. -// 'label.condition' => 'Condition', -// 'label.yes' => 'yes', -// 'label.no' => 'no', -// 'label.sort' => 'Sort', +'label.condition' => 'Condição', +'label.yes' => 'sim', +'label.no' => 'não', +'label.sort' => 'Ordenar', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Campos personalizados', -// Translate the following. -// 'label.monthly_quotas' => 'Monthly quotas', -// TODO: translate the following. -// 'label.entity' => 'Entity', +'label.monthly_quotas' => 'Cotas mensais', +'label.entity' => 'Entidade', 'label.type' => 'Tipo', 'label.type_dropdown' => 'lista suspensa', 'label.type_text' => 'texto', @@ -218,31 +206,28 @@ 'label.fav_report' => 'Relatório favorito', 'label.schedule' => 'Agenda', 'label.what_is_it' => 'O que é?', -// 'label.expense' => 'Expense', -// 'label.quantity' => 'Quantity', -// 'label.paid_status' => 'Paid status', -// 'label.paid' => 'Paid', -// 'label.mark_paid' => 'Mark paid', -// 'label.week_note' => 'Week note', -// 'label.week_list' => 'Week list', -// 'label.work_units' => 'Work units', -// 'label.work_units_short' => 'Units', +'label.expense' => 'Despesa', +'label.quantity' => 'Quantidade', +'label.paid_status' => 'Status pago', +'label.paid' => 'Pago', +'label.mark_paid' => 'Marcar como pago', +'label.week_note' => 'Anotação da semana', +'label.week_list' => 'Lista da semana', +'label.work_units' => 'Unidades de trabalho', +'label.work_units_short' => 'Unidades', 'label.totals_only' => 'Somente totais', -// TODO: translate the following. -// 'label.quota' => 'Quota', -// 'label.timesheet' => 'Timesheet', -// 'label.submitted' => 'Submitted', -// 'label.approved' => 'Approved', -// 'label.approval' => 'Report approval', -// 'label.mark_approved' => 'Mark approved', -// 'label.template' => 'Template', -// 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_note' => 'Prepopulate Note field', -// 'label.attachments' => 'Attachments', -// 'label.files' => 'Files', -// 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', +'label.quota' => 'Cota', +'label.timesheet' => 'Planilha de horas', +'label.submitted' => 'Enviado', +'label.approved' => 'Aprovado', +'label.approval' => 'Aprovação de relatório', +'label.mark_approved' => 'Marcar como aprovado', +'label.template' => 'Modelo', +'label.bind_templates_with_projects' => 'Vincular modelos com projetos', +'label.prepopulate_note' => 'Pré-preencher campo de anotação', +'label.attachments' => 'Anexos', +'label.files' => 'Arquivos', +'label.file' => 'Arquivo', 'label.active_users' => 'Usuários ativos', 'label.inactive_users' => 'Usuários inativos', // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 585db686f..374cf4da6 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -255,8 +255,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index eb99020fa..cdca51cc1 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -267,8 +267,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index e5e767ff4..abfff9a20 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -225,8 +225,6 @@ 'label.attachments' => 'Приложения', 'label.files' => 'Файлы', 'label.file' => 'Файл', -'label.image' => 'Изображение', -'label.download' => 'Скачать', 'label.active_users' => 'Активные пользователи', 'label.inactive_users' => 'Неактивные пользователи', 'label.details' => 'Детали', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index dcdcb8c81..8c9717270 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -260,8 +260,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Aktívny používatelia', 'label.inactive_users' => 'Neaktívny používatelia', // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 095b12f30..e45e43a52 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -250,8 +250,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 73a1dce54..cd9ff6182 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -255,8 +255,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Aktivni korisnik', 'label.inactive_users' => 'Neaktivni korisnik', // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 764671820..5a9b86787 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -251,8 +251,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', 'label.active_users' => 'Aktiva användare', 'label.inactive_users' => 'Inaktiva användare', // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 5e7ee26d1..a1b4b0d84 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -274,8 +274,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index d10d1c7c3..fc07dc618 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -260,8 +260,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index f1a6a6e30..1b20c2d11 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -265,8 +265,6 @@ // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', -// 'label.image' => 'Image', -// 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', diff --git a/initialize.php b/initialize.php index 88b47d256..6104df6ef 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5575"); +define("APP_VERSION", "1.19.28.5576"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 0b6c6bf40b94be1b25f4675eea05354297103409 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Jun 2021 19:16:27 +0000 Subject: [PATCH 1592/1848] More progress on integrating strings from pr #111. --- WEB-INF/resources/ca.lang.php | 1 - WEB-INF/resources/cs.lang.php | 1 - WEB-INF/resources/da.lang.php | 1 - WEB-INF/resources/de.lang.php | 2 -- WEB-INF/resources/en.lang.php | 1 - WEB-INF/resources/es.lang.php | 1 - WEB-INF/resources/et.lang.php | 1 - WEB-INF/resources/fa.lang.php | 1 - WEB-INF/resources/fi.lang.php | 1 - WEB-INF/resources/fr.lang.php | 1 - WEB-INF/resources/gr.lang.php | 1 - WEB-INF/resources/he.lang.php | 1 - WEB-INF/resources/hu.lang.php | 1 - WEB-INF/resources/it.lang.php | 1 - WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 1 - WEB-INF/resources/no.lang.php | 1 - WEB-INF/resources/pl.lang.php | 1 - WEB-INF/resources/pt-br.lang.php | 31 ++++++++++++------------------- WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 1 - WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 1 - WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 1 - WEB-INF/resources/sv.lang.php | 1 - WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 1 - WEB-INF/resources/zh-tw.lang.php | 1 - initialize.php | 2 +- 31 files changed, 13 insertions(+), 50 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 1f735771e..c91a3ae3a 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -291,7 +291,6 @@ 'title.login' => 'Sessió iniciada', 'title.groups' => 'Grups', // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Eliminar grup', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index b180b884e..2829fc0ff 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -301,7 +301,6 @@ 'title.login' => 'Přihlásit', 'title.groups' => 'Týmy', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Smazat tým', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 9c6aea90d..bec944e15 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -280,7 +280,6 @@ 'title.login' => 'Login', 'title.groups' => 'Teams', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Redigér Team', // TODO: change "team" to "group". 'title.delete_group' => 'Slet Team', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index d2dff2a08..2c270748e 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -274,8 +274,6 @@ 'title.success' => 'Erfol', 'title.login' => 'Anmelden', 'title.groups' => 'Gruppen', -// TODO: translate the following. -// 'title.subgroups' => 'Subgroups', 'title.add_group' => 'Gruppe anlegen', 'title.edit_group' => 'Gruppe bearbeiten', 'title.delete_group' => 'Gruppe löschen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index d7fb49ac4..2339a9961 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -258,7 +258,6 @@ 'title.success' => 'Success', 'title.login' => 'Login', 'title.groups' => 'Groups', -'title.subgroups' => 'Subgroups', 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Deleting Group', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index c352f5d9a..c538fbc94 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -290,7 +290,6 @@ 'title.login' => 'Sesión iniciada', 'title.groups' => 'Grupos', // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', // 'title.delete_group' => 'Deleting Group', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index c4ab61d3a..08f392f65 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -290,7 +290,6 @@ 'title.success' => 'Õnnestumine', 'title.login' => 'Sisene', 'title.groups' => 'Grupid', -'title.subgroups' => 'Alamgrupid', 'title.add_group' => 'Lisa grupp', 'title.edit_group' => 'Muuda gruppi', 'title.delete_group' => 'Kustuta grupp', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index dfff12bd2..75220b462 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -291,7 +291,6 @@ 'title.login' => 'ورود', 'title.groups' => 'تیم ها', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'حذف تیم', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index f624a91d1..a497a690e 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -284,7 +284,6 @@ 'title.login' => 'Kirjautuminen', 'title.groups' => 'Tiimit', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Tiimin muokkaus', // TODO: change "team" to "group". 'title.delete_group' => 'Tiimin poisto', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index f3e0c862a..d1b0bc906 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -278,7 +278,6 @@ 'title.login' => 'Connexion', 'title.groups' => 'Équipes', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Modification d\\\'une équipe', // TODO: change "team" to "group". 'title.delete_group' => 'Suppression d\\\'une équipe', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index b5ba3bf3e..647475c47 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -273,7 +273,6 @@ 'title.login' => 'Σύνδεση', 'title.groups' => 'Ομάδες', // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Επεξεργασία ομάδας', 'title.delete_group' => 'Διαγραφή ομάδας', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index f85fbb544..8ad1fe77a 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -299,7 +299,6 @@ 'title.login' => 'כניסה', 'title.groups' => 'צוותים', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'מחיקת צוות', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 791105b34..403e178b8 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -292,7 +292,6 @@ 'title.login' => 'Bejelentkezés', 'title.groups' => 'Csoportok', // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Csoport törlése', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 2654c6398..c48251969 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -281,7 +281,6 @@ 'title.login' => 'Login', 'title.groups' => 'Gruppi', // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Modifica gruppo', 'title.delete_group' => 'Elimina gruppo', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index b9d84a9ac..df981bc5a 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -297,7 +297,6 @@ 'title.login' => 'ログイン', 'title.groups' => 'チーム', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'チームの削除', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index f1cff3fc4..120734f78 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -297,7 +297,6 @@ 'title.login' => '로그인', 'title.groups' => '팀', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => '팀 삭제', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index dfd469993..2190504f8 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -248,7 +248,6 @@ 'title.success' => 'Succes', 'title.login' => 'Aanmelden', 'title.groups' => 'Groepen', -'title.subgroups' => 'Subgroepen', 'title.add_group' => 'Groep toevoegen', 'title.edit_group' => 'Groep bewerken', 'title.delete_group' => 'Groep aan het verwijderen', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 3511faec7..a0ebfcde0 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -294,7 +294,6 @@ 'title.login' => 'Innlogging', // TODO: translate the following. // 'title.groups' => 'Groups', -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Slett team', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index dd4deeadd..42ff39036 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -285,7 +285,6 @@ 'title.login' => 'Logowanie', 'title.groups' => 'Zespoły', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Edytowanie zespołu', // TODO: change "team" to "group". 'title.delete_group' => 'Usuwanie zespołu', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 40f7a8362..d936a13f2 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -217,7 +217,7 @@ 'label.work_units_short' => 'Unidades', 'label.totals_only' => 'Somente totais', 'label.quota' => 'Cota', -'label.timesheet' => 'Planilha de horas', +'label.timesheet' => 'Planilha de horas', 'label.submitted' => 'Enviado', 'label.approved' => 'Aprovado', 'label.approval' => 'Aprovação de relatório', @@ -230,33 +230,26 @@ 'label.file' => 'Arquivo', 'label.active_users' => 'Usuários ativos', 'label.inactive_users' => 'Usuários inativos', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. +'label.details' => 'Detalhes', +'label.budget' => 'Orçamento', +'label.work' => 'Trabalho', +'label.offer' => 'Oferta', +'label.contractor' => 'Contratante', +'label.how_to_pay' => 'Como pagar', +'label.moderator_comment' => 'Comentário do moderador', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. -// TODO: translate the following. -// 'entity.time' => 'time', -// 'entity.user' => 'user', -// 'entity.project' => 'project', +'entity.time' => 'tempo', +'entity.user' => 'usuário', +'entity.project' => 'projeto', // Form titles. 'title.error' => 'Erro', -// TODO: Translate the following. -// 'title.success' => 'Success', +'title.success' => 'Sucesso', 'title.login' => 'Login', 'title.groups' => 'Equipes', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Editando equipe', // TODO: change "team" to "group". 'title.delete_group' => 'Apagando equipe', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 374cf4da6..2bd9783fa 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -282,7 +282,6 @@ 'title.login' => 'Login', // TODO: translate the following. // 'title.groups' => 'Groups', -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', // 'title.delete_group' => 'Deleting Group', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index cdca51cc1..561543d4c 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -297,7 +297,6 @@ 'title.login' => 'Autentificare', 'title.groups' => 'Echipe', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Șterge echipa', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index abfff9a20..c5c01a17f 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -246,7 +246,6 @@ 'title.success' => 'Успех', 'title.login' => 'Вход в систему', 'title.groups' => 'Группы', -'title.subgroups' => 'Подгруппы', 'title.add_group' => 'Добавление группы', 'title.edit_group' => 'Редактирование группы', 'title.delete_group' => 'Удаление группы', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 8c9717270..68ba10552 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -288,7 +288,6 @@ 'title.login' => 'Prihlásenie', 'title.groups' => 'Tímy', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Vymazávanie tímu', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index e45e43a52..0942fbbd6 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -277,7 +277,6 @@ 'title.login' => 'Prijava', 'title.groups' => 'Timi', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', // 'title.delete_group' => 'Deleting Group', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index cd9ff6182..a7118c7ca 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -283,7 +283,6 @@ 'title.login' => 'Prijava', 'title.groups' => 'Timovi', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Izmeni tim', // TODO: change "team" to "group". 'title.delete_group' => 'Obriši tim', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 5a9b86787..66f1b159d 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -279,7 +279,6 @@ 'title.login' => 'Logga in', 'title.groups' => 'Grupper', // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Redigera grupp', 'title.delete_group' => 'Ta bort grupp', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index a1b4b0d84..7ae9c8e07 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -306,7 +306,6 @@ 'title.login' => 'Giriş', 'title.groups' => 'Ekipler', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => 'Ekibi sil', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index fc07dc618..f370b737e 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -287,7 +287,6 @@ 'title.login' => '登录', 'title.groups' => '团队', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => '删除团队', // TODO: change "team" to "group". diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 1b20c2d11..c7985b99a 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -292,7 +292,6 @@ 'title.login' => '登錄', 'title.groups' => '團隊', // TODO: change "teams" to "groups". // TODO: translate the following. -// 'title.subgroups' => 'Subgroups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', 'title.delete_group' => '刪除團隊', // TODO: change "team" to "group". diff --git a/initialize.php b/initialize.php index 6104df6ef..edfd70a71 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5576"); +define("APP_VERSION", "1.19.28.5577"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 1406aa8ff086976efeea555da98d547f268845c7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Jun 2021 20:17:02 +0000 Subject: [PATCH 1593/1848] More work on progress improving pt-br translation from pr #111. --- WEB-INF/resources/pt-br.lang.php | 127 ++++++++++++++----------------- initialize.php | 2 +- 2 files changed, 57 insertions(+), 72 deletions(-) diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index d936a13f2..d736843a4 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -217,7 +217,7 @@ 'label.work_units_short' => 'Unidades', 'label.totals_only' => 'Somente totais', 'label.quota' => 'Cota', -'label.timesheet' => 'Planilha de horas', +'label.timesheet' => 'Planilha de horas', 'label.submitted' => 'Enviado', 'label.approved' => 'Aprovado', 'label.approval' => 'Aprovação de relatório', @@ -248,37 +248,32 @@ 'title.error' => 'Erro', 'title.success' => 'Sucesso', 'title.login' => 'Login', -'title.groups' => 'Equipes', // TODO: change "teams" to "groups". -// TODO: translate the following. -// 'title.add_group' => 'Adding Group', -'title.edit_group' => 'Editando equipe', // TODO: change "team" to "group". -'title.delete_group' => 'Apagando equipe', // TODO: change "team" to "group". +'title.groups' => 'Grupos', +'title.add_group' => 'Adicionando grupo', +'title.edit_group' => 'Editando grupo', +'title.delete_group' => 'Apagando grupo', 'title.reset_password' => 'Resetando a senha', 'title.change_password' => 'Alterando a senha', 'title.time' => 'Tempo', 'title.edit_time_record' => 'Editando entrada de hora', 'title.delete_time_record' => 'Apagando entrada de hora', -// TODO: Translate the following. -// 'title.time_files' => 'Time Record Files', -// 'title.puncher' => 'Puncher', +'title.time_files' => 'Arquivos de registro de tempo', +'title.puncher' => 'Puncher', 'title.expenses' => 'Gastos', 'title.edit_expense' => 'Editando item de gasto', 'title.delete_expense' => 'Apagando item de gasto', -// TODO: translate the following. -// 'title.expense_files' => 'Expense Item Files', +'title.expense_files' => 'Arquivos de itens de despesas', 'title.reports' => 'Relatórios', 'title.report' => 'Report', 'title.send_report' => 'Enviando relatório', -// TODO: Translate the following. -// 'title.timesheets' => 'Timesheets', -// 'title.timesheet' => 'Timesheet', -// 'title.timesheet_files' => 'Timesheet Files', +'title.timesheets' => 'Planilhas de horas', +'title.timesheet' => 'Planilha de horas', +'title.timesheet_files' => 'Arquivos de planilha de horas', 'title.invoice' => 'Fatura', 'title.send_invoice' => 'Enviando fatura', 'title.charts' => 'Gráficos', 'title.projects' => 'Projetos', -// TODO: translate the following. -// 'title.project_files' => 'Project Files', +'title.project_files' => 'Arquivos do projeto', 'title.add_project' => 'Adicionando projeto', 'title.edit_project' => 'Editando projeto', 'title.delete_project' => 'Apagando projeto', @@ -290,8 +285,8 @@ 'title.add_user' => 'Adicionando usuário', 'title.edit_user' => 'Editando usuário', 'title.delete_user' => 'Apagando usuário', +'title.roles' => 'Papéis', // TODO: translate the following. -// 'title.roles' => 'Roles', // 'title.add_role' => 'Adding Role', // 'title.edit_role' => 'Editing Role', // 'title.delete_role' => 'Deleting Role', @@ -307,16 +302,14 @@ 'title.add_notification' => 'Adicionando notificação', 'title.edit_notification' => 'Editando notificação', 'title.delete_notification' => 'Apagando notificação', -// TODO: translate the following. -// 'title.add_timesheet' => 'Adding Timesheet', -// 'title.edit_timesheet' => 'Editing Timesheet', -// 'title.delete_timesheet' => 'Deleting Timesheet', -// 'title.monthly_quotas' => 'Monthly Quotas', +'title.add_timesheet' => 'Adicionando planilha de horas', +'title.edit_timesheet' => 'Editando planilha de horas', +'title.delete_timesheet' => 'Apagando planilha de horas', +'title.monthly_quotas' => 'Cotas mensais', 'title.export' => 'Exportando dados de equipe', // TODO: replace "team" with "group". 'title.import' => 'Importando dados de equipe', // TODO: replace "team" with "group". 'title.options' => 'Opções', -// TODO: translate the following. -// 'title.display_options' => 'Display Options', +'title.display_options' => 'Opções de exibição', 'title.profile' => 'Perfil', 'title.plugins' => 'Plugins', 'title.cf_custom_fields' => 'Campos personalizados', @@ -328,41 +321,39 @@ 'title.cf_edit_dropdown_option' => 'Editando opção', 'title.cf_delete_dropdown_option' => 'Apagando opção', 'title.locking' => 'Bloquear', -// TODO: translate the following. -// 'title.week_view' => 'Week View', -// 'title.swap_roles' => 'Swapping Roles', -// 'title.work_units' => 'Work Units', -// 'title.templates' => 'Templates', -// 'title.add_template' => 'Adding Template', -// 'title.edit_template' => 'Editing Template', -// 'title.delete_template' => 'Deleting Template', -// 'title.edit_file' => 'Editing File', -// 'title.delete_file' => 'Deleting File', -// 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. +'title.week_view' => 'Visão semanal', +'title.swap_roles' => 'Alteração de papéis', +'title.work_units' => 'Unidades de trabalho', +'title.templates' => 'Modelos', +'title.add_template' => 'Adicionando modelo', +'title.edit_template' => 'Editando modelo', +'title.delete_template' => 'Apagando modelo', +'title.edit_file' => 'Editando arquivo', +'title.delete_file' => 'Apagando arquivo', +'title.download_file' => 'Baixando arquivo', +'title.work' => 'Trabalho', +'title.add_work' => 'Adicionando trabalho', +'title.edit_work' => 'Editando trabalho', +'title.delete_work' => 'Apagando trabalho', +'title.active_work' => 'Trabalho ativo', +'title.available_work' => 'Trabalho disponível', +'title.inactive_work' => 'Trabalho inativo', +'title.pending_work' => 'Trabalho pendente', +'title.offer' => 'Oferta', +'title.add_offer' => 'Adicionando oferta', +'title.edit_offer' => 'Editando oferta', +'title.delete_offer' => 'Apagando oferta', +'title.active_offers' => 'Ofertas ativas', +'title.available_offers' => 'Ofertas disponíveis', +'title.inactive_offers' => 'Ofertas inativas', +'title.pending_offers' => 'Ofertas pendentes', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. 'dropdown.all' => '--- todos ---', 'dropdown.no' => '--- não ---', -// TODO: translate the following. -// 'dropdown.current_day' => 'today', -// 'dropdown.previous_day' => 'yesterday', +'dropdown.current_day' => 'hoje', +'dropdown.previous_day' => 'ontem', 'dropdown.selected_day' => 'dia', 'dropdown.current_week' => 'esta semana', 'dropdown.previous_week' => 'última semana', @@ -371,8 +362,7 @@ 'dropdown.previous_month' => 'último mês', 'dropdown.selected_month' => 'mês', 'dropdown.current_year' => 'este ano', -// TODO: translate the following. -// 'dropdown.previous_year' => 'previous year', +'dropdown.previous_year' => 'último ano', // TODO: check if this is correct. I used último for consistency with other dropdown options. 'dropdown.selected_year' => 'ano', 'dropdown.all_time' => 'todas as datas', 'dropdown.projects' => 'projetos', @@ -380,20 +370,18 @@ 'dropdown.clients' => 'clientes', 'dropdown.select' => '--- selecione ---', 'dropdown.select_invoice' => '--- selecione fatura ---', -// TODO: translate the following. -// 'dropdown.select_timesheet' => '--- select timesheet ---', +'dropdown.select_timesheet' => '--- selecione planilha de horas ---', 'dropdown.status_active' => 'ativo', 'dropdown.status_inactive' => 'inativo', 'dropdown.delete' => 'apagar', 'dropdown.do_not_delete' => 'não apagar', -// TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', -// 'dropdown.approved' => 'approved', -// 'dropdown.not_approved' => 'not approved', -// 'dropdown.paid' => 'paid', -// 'dropdown.not_paid' => 'not paid', -// 'dropdown.ascending' => 'ascending', -// 'dropdown.descending' => 'descending', +'dropdown.pending_approval' => 'aprovação pendente', +'dropdown.approved' => 'aprovado', +'dropdown.not_approved' => 'não aprovado', +'dropdown.paid' => 'pago', +'dropdown.not_paid' => 'não pago', +'dropdown.ascending' => 'ascendente', +'dropdown.descending' => 'descendente', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases @@ -407,10 +395,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Pedido para resetar a senha enviado por e-mail.', 'form.reset_password.email_subject' => 'Pedido de alteração de senha no Anuko Time Tracker', -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", -// "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Prezado usuário,\n\nAlguém, IP %s, solicitou o reset da sua senha do Anuko Time Tracker. Entre nete link para resetar a sua senha.\n\n%s\n\nAnuko Time Tracker é um sistema de código abertois, de rastreamento do tempo. Visite https://www.anuko.com para mais informações.\n\n", +'form.reset_password.email_body' => "Caro usuário,\n\nAlguém do IP %s solicitou a redefinição da senha do Anuko Time Tracker. Visite este link se quiser redefinir sua senha.\n\n%s\n\nAnuko Time Tracker é um sistema de rastreamento de apontamentos de código aberto. Visite https://www.anuko.com para obter mais informações.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Entre com a nova senha e clique em Salvar.', diff --git a/initialize.php b/initialize.php index edfd70a71..80ad77c08 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5577"); +define("APP_VERSION", "1.19.28.5578"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From c1633c81d3003d84aeea7e185d13f33b6142ab9f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Jun 2021 22:21:33 +0000 Subject: [PATCH 1594/1848] More work in progress on pt-br translation. --- WEB-INF/resources/ca.lang.php | 4 +-- WEB-INF/resources/cs.lang.php | 4 +-- WEB-INF/resources/da.lang.php | 4 +-- WEB-INF/resources/de.lang.php | 4 +-- WEB-INF/resources/en.lang.php | 4 +-- WEB-INF/resources/es.lang.php | 4 +-- WEB-INF/resources/et.lang.php | 4 +-- WEB-INF/resources/fa.lang.php | 4 +-- WEB-INF/resources/fi.lang.php | 4 +-- WEB-INF/resources/fr.lang.php | 4 +-- WEB-INF/resources/gr.lang.php | 4 +-- WEB-INF/resources/he.lang.php | 4 +-- WEB-INF/resources/hu.lang.php | 4 +-- WEB-INF/resources/it.lang.php | 4 +-- WEB-INF/resources/ja.lang.php | 4 +-- WEB-INF/resources/ko.lang.php | 4 +-- WEB-INF/resources/nl.lang.php | 4 +-- WEB-INF/resources/no.lang.php | 4 +-- WEB-INF/resources/pl.lang.php | 4 +-- WEB-INF/resources/pt-br.lang.php | 46 +++++++++++++++----------------- WEB-INF/resources/pt.lang.php | 4 +-- WEB-INF/resources/ro.lang.php | 4 +-- WEB-INF/resources/ru.lang.php | 4 +-- WEB-INF/resources/sk.lang.php | 4 +-- WEB-INF/resources/sl.lang.php | 4 +-- WEB-INF/resources/sr.lang.php | 4 +-- WEB-INF/resources/sv.lang.php | 4 +-- WEB-INF/resources/tr.lang.php | 4 +-- WEB-INF/resources/zh-cn.lang.php | 4 +-- WEB-INF/resources/zh-tw.lang.php | 4 +-- initialize.php | 2 +- 31 files changed, 81 insertions(+), 83 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index c91a3ae3a..205600d04 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -520,8 +520,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Número de factura', 'form.invoice.person' => 'Persona', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 2829fc0ff..7a685029b 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -529,8 +529,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Faktura číslo', 'form.invoice.person' => 'Osoba', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index bec944e15..3cb53a5a3 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -503,8 +503,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Fakturanummer', 'form.invoice.person' => 'Person', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 2c270748e..c0d69b6d6 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -489,8 +489,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Rechnungsnummer', 'form.invoice.person' => 'Person', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 2339a9961..1acc79084 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -472,8 +472,8 @@ 'form.templates.active_templates' => 'Active Templates', 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Invoice number', 'form.invoice.person' => 'Person', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index c538fbc94..ebe095e96 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -533,8 +533,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Número de factura', 'form.invoice.person' => 'Persona', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 08f392f65..961b8e2b5 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -515,8 +515,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Arve number', 'form.invoice.person' => 'Isik', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 75220b462..798406ccf 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -524,8 +524,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'شماره فاکتور', 'form.invoice.person' => 'شخص', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index a497a690e..813b442fe 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -509,8 +509,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Laskun numero', 'form.invoice.person' => 'Henkilö', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index d1b0bc906..e2642ad27 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -500,8 +500,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Numéro de facture', 'form.invoice.person' => 'Personne', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 647475c47..5a6a8df81 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -495,8 +495,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Αριθμός τιμολογίου', 'form.invoice.person' => 'Άτομο', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 8ad1fe77a..958a556e6 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -528,8 +528,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'מספר חשבונית', 'form.invoice.person' => 'משתמש', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 403e178b8..22b28039e 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -523,8 +523,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Számla azonosító száma', 'form.invoice.person' => 'Személy', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index c48251969..ab3852bf5 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -508,8 +508,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Numero fattura', 'form.invoice.person' => 'Persona', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index df981bc5a..85192f026 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -529,8 +529,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => '送り状の番号', 'form.invoice.person' => '個人', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 120734f78..202578fcc 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -527,8 +527,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => '송장 번호', 'form.invoice.person' => '개인', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 2190504f8..10c905143 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -455,8 +455,8 @@ 'form.templates.active_templates' => 'Actieve sjablonen', 'form.templates.inactive_templates' => 'Inactieve sjablonen', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Factuur nummer', 'form.invoice.person' => 'Medewerker', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index a0ebfcde0..b3cf78863 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -527,8 +527,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Fakturanummer', 'form.invoice.person' => 'Person', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 42ff39036..b0602334f 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -511,8 +511,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Numer faktury', 'form.invoice.person' => 'Osoba', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index d736843a4..52193b87d 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -404,18 +404,16 @@ 'form.time.duration_format' => '(hh:mm ou 0.0h)', 'form.time.billable' => 'Faturável', 'form.time.uncompleted' => 'Incompleta', -// TODO: translate the following. -// 'form.time.remaining_quota' => 'Remaining quota', -// 'form.time.over_quota' => 'Over quota', -// 'form.time.remaining_balance' => 'Remaining balance', -// 'form.time.over_balance' => 'Over balance', +'form.time.remaining_quota' => 'Cota restante', // TODO: check if this translation is correct. I changed it from "Cota excedente", which appears to be wrong. +'form.time.over_quota' => 'Acima da cota', +'form.time.remaining_balance' => 'Saldo restante', +'form.time.over_balance' => 'Saldo excedente', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). 'form.time_edit.uncompleted' => 'Eesta entrada foi salva somente com hora de início. Não é um erro.', // Week view form. See example at https://timetracker.anuko.com/week.php. -// TODO: translate the following. -// 'form.week.new_entry' => 'New entry', +'form.week.new_entry' => 'Nova entrada', // Reports form. See example at https://timetracker.anuko.com/reports.php 'form.reports.save_as_favorite' => 'Guardar como favorito', @@ -424,16 +422,19 @@ 'form.reports.include_not_billable' => 'não faturável', 'form.reports.include_invoiced' => 'faturado', 'form.reports.include_not_invoiced' => 'não faturado', -// TODO: translate the following. -// 'form.reports.include_assigned' => 'assigned', -// 'form.reports.include_not_assigned' => 'not assigned', -// 'form.reports.include_pending' => 'pending', +'form.reports.include_assigned' => 'atribuído', +'form.reports.include_not_assigned' => 'não atribuído', +'form.reports.include_pending' => 'pendente', 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', -// TODO: translate the following. +// TODO: Try to improve the translation of form.reports.time_fields. This is a label for a section of custom fields that +// are associated with a time record. I suggest trying custom fields plugin, creating a few "time" custom fields, and seeing how +// reports.php page looks like. For example, one may create a "Ticket #" or a "Property" custom fields to be associated with time entries, +// the form.reports.time_fields groups these fields together on reports.php. // 'form.reports.time_fields' => 'Time fields', -// 'form.reports.user_fields' => 'User fields', +// 'form.reports.time_fields' => 'Campos de apontamento', +'form.reports.user_fields' => 'Campos de usuário', 'form.reports.group_by' => 'Agrupar por', 'form.reports.group_by_no' => '--- sem agrupar ---', 'form.reports.group_by_date' => 'data', @@ -445,22 +446,19 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportar', -// TODO: translate the following. -// 'form.report.assign_to_invoice' => 'Assign to invoice', -// 'form.report.assign_to_timesheet' => 'Assign to timesheet', +'form.report.assign_to_invoice' => 'Atribuir a fatura', +'form.report.assign_to_timesheet' => 'Atribuir a planilha de horas', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php -// TODO: translate the following. -// 'form.timesheets.active_timesheets' => 'Active Timesheets', -// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +'form.timesheets.active_timesheets' => 'Planilhas de horas ativas', +'form.timesheets.inactive_timesheets' => 'Planilhas de horas inativas', // Templates form. See example at https://timetracker.anuko.com/templates.php -// TODO: translate the following. -// 'form.templates.active_templates' => 'Active Templates', -// 'form.templates.inactive_templates' => 'Inactive Templates', +'form.templates.active_templates' => 'Modelos ativos', +'form.templates.inactive_templates' => 'Modelos inativos', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Número da fatura', 'form.invoice.person' => 'Pessoa', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 2bd9783fa..9a26f283e 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -505,8 +505,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). // TODO: translate the following. // 'form.invoice.number' => 'Invoice number', // 'form.invoice.person' => 'Person', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 561543d4c..95e27a122 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -527,8 +527,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Numar factura', 'form.invoice.person' => 'Persoana', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index c5c01a17f..cb4abe577 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -452,8 +452,8 @@ 'form.templates.active_templates' => 'Активные шаблоны', 'form.templates.inactive_templates' => 'Неактивные шаблоны', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Номер счёта', 'form.invoice.person' => 'Работник', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 68ba10552..821c23b45 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -514,8 +514,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Číslo faktúry', 'form.invoice.person' => 'Osoba', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 0942fbbd6..bb37b8631 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -500,8 +500,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). // TODO: translate the following. // 'form.invoice.number' => 'Invoice number', // 'form.invoice.person' => 'Person', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index a7118c7ca..e1f9a28e2 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -511,8 +511,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Forma izveštaja. Pogledajte primer na https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Broj računa', 'form.invoice.person' => 'Osoba', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 66f1b159d..cea1ddd88 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -509,8 +509,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Fakturanummer', 'form.invoice.person' => 'Person', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 7ae9c8e07..b94ba8d90 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -539,8 +539,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => 'Fatura numarası', 'form.invoice.person' => 'Kişi', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index f370b737e..0a6e4ab25 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -516,8 +516,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => '发票号码', 'form.invoice.person' => '人', // TODO: is this correct? diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index c7985b99a..2efd7bbe1 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -519,8 +519,8 @@ // 'form.templates.active_templates' => 'Active Templates', // 'form.templates.inactive_templates' => 'Inactive Templates', -// Invoice form. See example at https://timetracker.anuko.com/invoice.php -// (you can get to this form after generating a report). +// Invoice form. See example at https://timetracker.anuko.com/invoice_view.php +// (you can get to this form after generating an invoice). 'form.invoice.number' => '發票號碼', 'form.invoice.person' => '人', // TODO: is this correct? diff --git a/initialize.php b/initialize.php index 80ad77c08..33974fb78 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5578"); +define("APP_VERSION", "1.19.28.5579"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 2ac0bd2cc5b5d9b512476d884540b06b6c5f374a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Jun 2021 23:09:50 +0000 Subject: [PATCH 1595/1848] Finished integrating good changes from pr #111. --- WEB-INF/resources/pt-br.lang.php | 157 +++++++++++++++---------------- initialize.php | 2 +- 2 files changed, 75 insertions(+), 84 deletions(-) diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 52193b87d..f9085c538 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -465,8 +465,7 @@ // Deleting Invoice form. See example at https://timetracker.anuko.com/invoice_delete.php 'form.invoice.invoice_to_delete' => 'Fatura a ser apagada', 'form.invoice.invoice_entries' => 'Entradas de fatura', -// TODO: translate the following. -// 'form.invoice.confirm_deleting_entries' => 'Please confirm deleting invoice entries from Time Tracker.', +'form.invoice.confirm_deleting_entries' => 'Confirme a exclusão das entradas de fatura do Time Tracker.', // Charts form. See example at https://timetracker.anuko.com/charts.php 'form.charts.interval' => 'Intervalo', @@ -481,8 +480,12 @@ 'form.tasks.inactive_tasks' => 'Tarefas inativas', // Users form. See example at https://timetracker.anuko.com/users.php -// TODO: translate the following. +// TODO: check the translation of form.users.uncompleted_entry. Is "apontamento" a correct term for a time entry? +// The meaning of incomplete time entry in Time Tracker is that the entry only has the "start" time defined, but no finish time yet, +// and may be ongoing. For example, user started working on something and is curently in progress doing it. +// Check the Puncher plugin, which operates with such entries. // 'form.users.uncompleted_entry' => 'User has an uncompleted time entry', +'form.users.uncompleted_entry' => 'O usuário tem um apontamento incompleto', 'form.users.role' => 'Papel', 'form.users.manager' => 'Gerente', 'form.users.comanager' => 'Coordenador', @@ -490,17 +493,15 @@ 'form.users.default_rate' => 'Honorário padrão por hora', // Editing User form. See example at https://timetracker.anuko.com/user_edit.php -// TODO: translate the following. -// 'form.user_edit.swap_roles' => 'Swap roles', +'form.user_edit.swap_roles' => 'Alternar papéis', // Roles form. See example at https://timetracker.anuko.com/roles.php -// TODO: translate the following. -// 'form.roles.active_roles' => 'Active Roles', -// 'form.roles.inactive_roles' => 'Inactive Roles', -// 'form.roles.rank' => 'Rank', -// 'form.roles.rights' => 'Rights', -// 'form.roles.assigned' => 'Assigned', -// 'form.roles.not_assigned' => 'Not assigned', +'form.roles.active_roles' => 'Papéis ativos', +'form.roles.inactive_roles' => 'Papéis inativos', +'form.roles.rank' => 'Rank', +'form.roles.rights' => 'Direitos', +'form.roles.assigned' => 'Atribuído', +'form.roles.not_assigned' => 'Não atribuído', // Clients form. See example at https://timetracker.anuko.com/clients.php 'form.clients.active_clients' => 'Clientes ativos', @@ -529,9 +530,8 @@ // Group Settings form. See example at https://timetracker.anuko.com/group_edit.php. 'form.group_edit.12_hours' => '12 horas', 'form.group_edit.24_hours' => '24 horas', -// TODO: translate the following. -// 'form.group_edit.display_options' => 'Display options', -// 'form.group_edit.holidays' => 'Holidays', +'form.group_edit.display_options' => 'Opções de exibição', +'form.group_edit.holidays' => 'Feriados', 'form.group_edit.tracking_mode' => 'Modo de acompanhamento', 'form.group_edit.mode_time' => 'tempo', 'form.group_edit.mode_projects' => 'projetos', @@ -540,18 +540,16 @@ 'form.group_edit.type_all' => 'todos', 'form.group_edit.type_start_finish' => 'início e fim', 'form.group_edit.type_duration' => 'duração', -// TODO: translate the following. -// 'form.group_edit.punch_mode' => 'Punch mode', -// 'form.group_edit.allow_overlap' => 'Allow overlap', -// 'form.group_edit.future_entries' => 'Future entries', -// 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', -// 'form.group_edit.confirm_save' => 'Confirm saving', -// 'form.group_edit.allow_ip' => 'Allow IP', -// 'form.group_edit.advanced_settings' => 'Advanced settings', +'form.group_edit.punch_mode' => 'Modo punch', +'form.group_edit.allow_overlap' => 'Permitir sobreposição', +'form.group_edit.future_entries' => 'Entradas futuros', +'form.group_edit.uncompleted_indicators' => 'Indicadores incompletos', +'form.group_edit.confirm_save' => 'Confirme o salvamento', +'form.group_edit.allow_ip' => 'Permitir IP', +'form.group_edit.advanced_settings' => 'Configurações avançadas', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php -// TODO: translate the following. -// 'form.group_delete.hint' => 'Are you sure you want to delete the entire group?', +'form.group_delete.hint' => 'Tem certeza de que deseja excluir todo o grupo?', // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Para', @@ -561,74 +559,67 @@ 'form.mail.invoice_sent' => 'Fatura enviada.', // Quotas configuration form. See example at https://timetracker.anuko.com/quotas.php after enabling Monthly quotas plugin. -// TODO: translate the following. -// 'form.quota.year' => 'Year', -// 'form.quota.month' => 'Month', -// 'form.quota.workday_hours' => 'Hours in a work day', -// 'form.quota.hint' => 'If values are empty, quotas are calculated automatically based on workday hours and holidays.', +'form.quota.year' => 'Ano', +'form.quota.month' => 'Mês', +'form.quota.workday_hours' => 'Horas em um dia útil', +'form.quota.hint' => 'Se os valores estiverem vazios, as cotas serão calculadas automaticamente com base nas horas de trabalho e feriados.', // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. -// TODO: translate the following. -// 'form.swap.hint' => 'Demote yourself to a lower role by swapping roles with someone else. This cannot be undone.', -// 'form.swap.swap_with' => 'Swap roles with', +'form.swap.hint' => 'Rebaixe-se a papel inferior trocando funções com outra pessoa. Isto não pode ser desfeito.', +'form.swap.swap_with' => 'Trocar papéis com', // Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. -// TODO: translate the following. -// 'form.work_units.minutes_in_unit' => 'Minutes in unit', -// 'form.work_units.1st_unit_threshold' => '1st unit threshold', +'form.work_units.minutes_in_unit' => 'Minutos em unidade', +'form.work_units.1st_unit_threshold' => 'Limiar da 1ª unidade', // Roles and rights. These strings are used in multiple places. Grouped here to provide consistent translations. -// TODO: translate the following. -// 'role.user.label' => 'User', -// 'role.user.low_case_label' => 'user', -// 'role.user.description' => 'A regular member without management rights.', -// 'role.client.label' => 'Client', -// 'role.client.low_case_label' => 'client', -// 'role.client.description' => 'A client can view its own data.', -// 'role.supervisor.label' => 'Supervisor', -// 'role.supervisor.low_case_label' => 'supervisor', -// 'role.supervisor.description' => 'A person with a small set of management rights.', -// 'role.comanager.label' => 'Co-manager', -// 'role.comanager.low_case_label' => 'co-manager', -// 'role.comanager.description' => 'A person with a big set of management functions.', -// 'role.manager.label' => 'Manager', -// 'role.manager.low_case_label' => 'manager', -// 'role.manager.description' => 'Group manager. Can do most of things for a group.', -// 'role.top_manager.label' => 'Top manager', -// 'role.top_manager.low_case_label' => 'top manager', -// 'role.top_manager.description' => 'Top group manager. Can do everything in a tree of groups.', -// 'role.admin.label' => 'Administrator', -// 'role.admin.low_case_label' => 'administrator', -// 'role.admin.description' => 'Site adminsitrator.', +'role.user.label' => 'Usuário', +'role.user.low_case_label' => 'usuário', +'role.user.description' => 'Um membro regular sem direitos de gestão.', +'role.client.label' => 'Cliente', +'role.client.low_case_label' => 'cliente', +'role.client.description' => 'Um cliente pode visualizar seus próprios dados.', +'role.supervisor.label' => 'Supervisor', +'role.supervisor.low_case_label' => 'supervisor', +'role.supervisor.description' => 'Uma pessoa com um pequeno conjunto de direitos de gerenciamento.', +'role.comanager.label' => 'Co-gerente', +'role.comanager.low_case_label' => 'co-gerente', +'role.comanager.description' => 'Uma pessoa com um grande conjunto de funções de gerenciamento.', +'role.manager.label' => 'Gerente', +'role.manager.low_case_label' => 'gerente', +'role.manager.description' => 'Gerente de grupo. Pode fazer a maioria das coisas para um grupo.', +'role.top_manager.label' => 'Gerente geral', +'role.top_manager.low_case_label' => 'gerente geral', +'role.top_manager.description' => 'Principal gerente de grupo. Pode fazer tudo em uma árvore de grupos.', +'role.admin.label' => 'Administrador', +'role.admin.low_case_label' => 'administrador', +'role.admin.description' => 'Adminsitrador do site/sistema.', // Timesheet View form. See example at https://timetracker.anuko.com/timesheet_view.php. -// TODO: translate the following. -// 'form.timesheet_view.submit_subject' => 'Timesheet approval request', -// 'form.timesheet_view.submit_body' => "A new timesheet requires approval.

User: %s.", -// 'form.timesheet_view.approve_subject' => 'Timesheet approved', -// 'form.timesheet_view.approve_body' => "Your timesheet %s was approved.

%s", -// 'form.timesheet_view.disapprove_subject' => 'Timesheet not approved', -// 'form.timesheet_view.disapprove_body' => "Your timesheet %s was not approved.

%s", +'form.timesheet_view.submit_subject' => 'Solicitação de aprovação de planilha de horas', +'form.timesheet_view.submit_body' => "Uma nova planilha de horas requer aprovação.

Usuário: %s.", +'form.timesheet_view.approve_subject' => 'Planilha de horas aprovada', +'form.timesheet_view.approve_body' => "Sua planilha de horas %s foi aprovada.

%s", +'form.timesheet_view.disapprove_subject' => 'Planilha de horas não aprovada', +'form.timesheet_view.disapprove_body' => "Sua planilha de horas %s não foi aprovada.

%s", // Display Options form. See example at https://timetracker.anuko.com/display_options.php. -// TODO: translate the following. -// 'form.display_options.note_on_separate_row' => 'Note on separate row', -// 'form.display_options.not_complete_days' => 'Not complete days', -// 'form.display_options.custom_css' => 'Custom CSS', +'form.display_options.note_on_separate_row' => 'Anotação em linha separada', +'form.display_options.not_complete_days' => 'Dias não completos', +'form.display_options.custom_css' => 'CSS customizado', // Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', +'work.error.work_not_available' => 'Item de trabalho não está disponível.', +'work.error.offer_not_available' => 'Oferta não disponível', +'work.type.one_time' => 'Uma interação', +'work.type.ongoing' => 'Em progresso', +'work.label.own_work' => 'Trabalho próprio', +'work.label.own_offers' => 'Ofertas próprias', +'work.label.offers' => 'Ofertas', +'work.button.send_message' => 'Enviar mensagem', +'work.button.make_offer' => 'Fazer oferta', +'work.button.accept' => 'Aceitar', +'work.button.decline' => 'Recusar', +'work.title.send_message' => 'Enviando mensagem', +'work.msg.message_sent' => 'Mensagem enviada.', ); diff --git a/initialize.php b/initialize.php index 33974fb78..a89b0c287 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5579"); +define("APP_VERSION", "1.19.28.5580"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 9e937b53f8265d44579fdab0de1b9074582125b0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Jun 2021 23:17:58 +0000 Subject: [PATCH 1596/1848] Improved TODO comments for pt-br translators. --- WEB-INF/resources/pt-br.lang.php | 16 ++++++++-------- initialize.php | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index f9085c538..38ca0dfec 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -106,9 +106,9 @@ 'button.reset_password' => 'Resetar senha', 'button.send' => 'Enviar', 'button.send_by_email' => 'Enviar por e-mail', -'button.create_group' => 'Criar equipe', // TODO: replace "team" with "group". -'button.export' => 'Exportar equipe', // TODO: replace "team" with "group". -'button.import' => 'Importar equipe', // TODO: replace "team" with "group". +'button.create_group' => 'Criar equipe', // TODO: replace "equipe" with "group". +'button.export' => 'Exportar equipe', // TODO: replace "equipe" with "group". +'button.import' => 'Importar equipe', // TODO: replace "equipe" with "group". 'button.close' => 'Fechar', 'button.start' => 'Iniciar', 'button.stop' => 'Parar', @@ -117,7 +117,7 @@ // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.menu' => 'Menu', -'label.group_name' => 'Nome da equipe', // TODO: replace "team" with "group". +'label.group_name' => 'Nome da equipe', // TODO: replace "equipe" with "group". 'label.address' => 'Endereço', 'label.currency' => 'Moeda', 'label.manager_name' => 'Nome do gerente', @@ -306,8 +306,8 @@ 'title.edit_timesheet' => 'Editando planilha de horas', 'title.delete_timesheet' => 'Apagando planilha de horas', 'title.monthly_quotas' => 'Cotas mensais', -'title.export' => 'Exportando dados de equipe', // TODO: replace "team" with "group". -'title.import' => 'Importando dados de equipe', // TODO: replace "team" with "group". +'title.export' => 'Exportando dados de equipe', // TODO: replace "equipe" with "group". +'title.import' => 'Importando dados de equipe', // TODO: replace "equipe" with "group". 'title.options' => 'Opções', 'title.display_options' => 'Opções de exibição', 'title.profile' => 'Perfil', @@ -512,7 +512,7 @@ 'form.client.client_entries' => 'Entradas de cliente', // Exporting Group Data form. See example at https://timetracker.anuko.com/export.php -// TODO: replace "team" with "group" in the string below. +// TODO: replace "equipe" with "group" in the string below. 'form.export.hint' => 'Você pode exportar todos os dados da equipe para um arquivo xml. Isto pode ser útil se você estiver migrando os dados para um servidor próprio.', 'form.export.compression' => 'Compressão', 'form.export.compression_none' => 'nenhuma', @@ -524,7 +524,7 @@ 'form.import.success' => 'Importação realizada com sucesso.', // Groups form. See example at https://timetracker.anuko.com/admin_groups.php (login as admin first). -// TODO: replace "team" with "group" in the string below (3 places). +// TODO: replace "equipe" with "group" in the string below (3 places). 'form.groups.hint' => 'Crie uma nova equipe fazendo uma nova conta de gerente.
Você também pode importar os dados de um arquivo xml de outro servidor Anuko Time Tracker (não havendo colisão de usuários).', // Group Settings form. See example at https://timetracker.anuko.com/group_edit.php. diff --git a/initialize.php b/initialize.php index a89b0c287..24ac12b57 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5580"); +define("APP_VERSION", "1.19.28.5581"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 387034aed0193e99e1ac6cc3e01977118064201c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Jun 2021 18:06:29 +0000 Subject: [PATCH 1597/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 12 ++++-------- initialize.php | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 10c905143..51d4e41ee 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -23,8 +23,7 @@ 'menu.group' => 'Groep', 'menu.plugins' => 'Plugins', 'menu.time' => 'Tijden', -// TODO: translate the following: -// 'menu.puncher' => 'Punch', +'menu.puncher' => 'Prikklok', 'menu.week' => 'Week', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Rapporten', @@ -108,8 +107,7 @@ 'button.export' => 'Groep exporteren', 'button.import' => 'Groep importeren', 'button.close' => 'Sluiten', -// TODO: translate the following. -// 'button.start' => 'Start', +'button.start' => 'Start', 'button.stop' => 'Stop', 'button.approve' => 'Goedkeuren', 'button.disapprove' => 'Afkeuren', @@ -167,8 +165,7 @@ 'label.select_none' => 'Selecteer niets', 'label.day_view' => 'Dag overzicht', 'label.week_view' => 'Week overzicht', -// TODO: translate the following. -// 'label.puncher' => 'Puncher', +'label.puncher' => 'Prikklok', 'label.id' => 'ID', 'label.language' => 'Taal', 'label.decimal_mark' => 'Decimaal teken', @@ -257,8 +254,7 @@ 'title.edit_time_record' => 'Wijzigen tijdrecord', 'title.delete_time_record' => 'Verwijder tijdrecord', 'title.time_files' => 'Tijden bestanden', -// TODO: Translate the following: -// 'title.puncher' => 'Puncher', +'title.puncher' => 'Prikklok', 'title.expenses' => 'Kosten', 'title.edit_expense' => 'Bewerk kosten artikel', 'title.delete_expense' => 'Verwijder kosten artikel', diff --git a/initialize.php b/initialize.php index 24ac12b57..b5407ad8a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5581"); +define("APP_VERSION", "1.19.28.5582"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From c446afd20b43b27d34a840010ccf114f1eeb7b53 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 24 Jun 2021 17:08:40 +0000 Subject: [PATCH 1598/1848] Cosmetic change to .gitignore. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 92e2728c3..d81178e11 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ Thumbs.db *.DS_Store *~ .idea/ +api/ From 0b57ed4799b8ab05e9add3028977fb79d7c6fb90 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 6 Jul 2021 15:19:18 +0000 Subject: [PATCH 1599/1848] Integrating useful changes from pr#111 with yet some remaining todo. --- WEB-INF/resources/pt-br.lang.php | 95 ++++++++++++++------------------ initialize.php | 2 +- 2 files changed, 42 insertions(+), 55 deletions(-) diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 38ca0dfec..3e2c6526f 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -62,16 +62,15 @@ 'error.user_exists' => 'Já existe usuário com este login.', 'error.object_exists' => 'Já existe um objeto com este nome.', 'error.invoice_exists' => 'Já existe fatura com este número.', -// TODO: improve translation of the word "role" in error.role_exists. função here, papel elsewhere? 'error.role_exists' => 'Já existe uma função com este rank.', 'error.no_invoiceable_items' => 'Não há items faturáveis.', 'error.no_records' => 'Não há registros.', 'error.no_login' => 'Não há usuário com este login.', 'error.no_groups' => 'Sua base de dados está vazia. Entre como admin e crie um grupo novo.', 'error.upload' => 'Erro no envio do arquivo.', -'error.range_locked' => 'Período está bloqueado.', -'error.mail_send' => 'Erro enviando o e-mail.', -// TODO: is "Use" in error.mail_send translated correctly? +'error.range_locked' => 'Período bloqueado.', +// TODO: is "Use" in error.mail_send translated correctly? Usar, or utilizar, perhaps? "Use" looks like an untranslated English word. +// The meaning of this error is that mail send feature did not work, and using MAIL_SMTP_DEBUG should help admin to troubleshoot it. 'error.mail_send' => 'Erro ao enviar e-mail. Use MAIL_SMTP_DEBUG para diagnósticos.', 'error.no_email' => 'Não há e-mail associado a este login.', 'error.uncompleted_exists' => 'Entrada incompleta existente. Feche ou remova-a.', @@ -106,9 +105,9 @@ 'button.reset_password' => 'Resetar senha', 'button.send' => 'Enviar', 'button.send_by_email' => 'Enviar por e-mail', -'button.create_group' => 'Criar equipe', // TODO: replace "equipe" with "group". -'button.export' => 'Exportar equipe', // TODO: replace "equipe" with "group". -'button.import' => 'Importar equipe', // TODO: replace "equipe" with "group". +'button.create_group' => 'Criar grupo', +'button.export' => 'Exportar grupo', +'button.import' => 'Importar grupo', 'button.close' => 'Fechar', 'button.start' => 'Iniciar', 'button.stop' => 'Parar', @@ -117,7 +116,7 @@ // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.menu' => 'Menu', -'label.group_name' => 'Nome da equipe', // TODO: replace "equipe" with "group". +'label.group_name' => 'Nome do grupo', 'label.address' => 'Endereço', 'label.currency' => 'Moeda', 'label.manager_name' => 'Nome do gerente', @@ -286,10 +285,9 @@ 'title.edit_user' => 'Editando usuário', 'title.delete_user' => 'Apagando usuário', 'title.roles' => 'Papéis', -// TODO: translate the following. -// 'title.add_role' => 'Adding Role', -// 'title.edit_role' => 'Editing Role', -// 'title.delete_role' => 'Deleting Role', +'title.add_role' => 'Adicionando função', +'title.edit_role' => 'Editando função', +'title.delete_role' => 'Apagando função', 'title.clients' => 'Clientes', 'title.add_client' => 'Adicionando cliente', 'title.edit_client' => 'Editando cliente', @@ -306,8 +304,8 @@ 'title.edit_timesheet' => 'Editando planilha de horas', 'title.delete_timesheet' => 'Apagando planilha de horas', 'title.monthly_quotas' => 'Cotas mensais', -'title.export' => 'Exportando dados de equipe', // TODO: replace "equipe" with "group". -'title.import' => 'Importando dados de equipe', // TODO: replace "equipe" with "group". +'title.export' => 'Exportando dados do grupo', +'title.import' => 'Importando dados do grupo', 'title.options' => 'Opções', 'title.display_options' => 'Opções de exibição', 'title.profile' => 'Perfil', @@ -362,7 +360,7 @@ 'dropdown.previous_month' => 'último mês', 'dropdown.selected_month' => 'mês', 'dropdown.current_year' => 'este ano', -'dropdown.previous_year' => 'último ano', // TODO: check if this is correct. I used último for consistency with other dropdown options. +'dropdown.previous_year' => 'último ano', 'dropdown.selected_year' => 'ano', 'dropdown.all_time' => 'todas as datas', 'dropdown.projects' => 'projetos', @@ -404,7 +402,7 @@ 'form.time.duration_format' => '(hh:mm ou 0.0h)', 'form.time.billable' => 'Faturável', 'form.time.uncompleted' => 'Incompleta', -'form.time.remaining_quota' => 'Cota restante', // TODO: check if this translation is correct. I changed it from "Cota excedente", which appears to be wrong. +'form.time.remaining_quota' => 'Cota restante', 'form.time.over_quota' => 'Acima da cota', 'form.time.remaining_balance' => 'Saldo restante', 'form.time.over_balance' => 'Saldo excedente', @@ -415,7 +413,7 @@ // Week view form. See example at https://timetracker.anuko.com/week.php. 'form.week.new_entry' => 'Nova entrada', -// Reports form. See example at https://timetracker.anuko.com/reports.php +// Reports form. See example at https://timetracker.anuko.com/reports.php. 'form.reports.save_as_favorite' => 'Guardar como favorito', 'form.reports.confirm_delete' => 'Tem certeza que deseja remover este relatório dos favoritos?', 'form.reports.include_billable' => 'faturável', @@ -428,12 +426,7 @@ 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', -// TODO: Try to improve the translation of form.reports.time_fields. This is a label for a section of custom fields that -// are associated with a time record. I suggest trying custom fields plugin, creating a few "time" custom fields, and seeing how -// reports.php page looks like. For example, one may create a "Ticket #" or a "Property" custom fields to be associated with time entries, -// the form.reports.time_fields groups these fields together on reports.php. -// 'form.reports.time_fields' => 'Time fields', -// 'form.reports.time_fields' => 'Campos de apontamento', +'form.reports.time_fields' => 'Campos de tempo', 'form.reports.user_fields' => 'Campos de usuário', 'form.reports.group_by' => 'Agrupar por', 'form.reports.group_by_no' => '--- sem agrupar ---', @@ -449,11 +442,11 @@ 'form.report.assign_to_invoice' => 'Atribuir a fatura', 'form.report.assign_to_timesheet' => 'Atribuir a planilha de horas', -// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php +// Timesheets form. See example at https://timetracker.anuko.com/timesheets.php. 'form.timesheets.active_timesheets' => 'Planilhas de horas ativas', 'form.timesheets.inactive_timesheets' => 'Planilhas de horas inativas', -// Templates form. See example at https://timetracker.anuko.com/templates.php +// Templates form. See example at https://timetracker.anuko.com/templates.php. 'form.templates.active_templates' => 'Modelos ativos', 'form.templates.inactive_templates' => 'Modelos inativos', @@ -462,70 +455,63 @@ 'form.invoice.number' => 'Número da fatura', 'form.invoice.person' => 'Pessoa', -// Deleting Invoice form. See example at https://timetracker.anuko.com/invoice_delete.php +// Deleting Invoice form. See example at https://timetracker.anuko.com/invoice_delete.php. 'form.invoice.invoice_to_delete' => 'Fatura a ser apagada', 'form.invoice.invoice_entries' => 'Entradas de fatura', 'form.invoice.confirm_deleting_entries' => 'Confirme a exclusão das entradas de fatura do Time Tracker.', -// Charts form. See example at https://timetracker.anuko.com/charts.php +// Charts form. See example at https://timetracker.anuko.com/charts.php. 'form.charts.interval' => 'Intervalo', 'form.charts.chart' => 'Gráfico', -// Projects form. See example at https://timetracker.anuko.com/projects.php +// Projects form. See example at https://timetracker.anuko.com/projects.php. 'form.projects.active_projects' => 'Projetos ativos', 'form.projects.inactive_projects' => 'Projetos inativos', -// Tasks form. See example at https://timetracker.anuko.com/tasks.php +// Tasks form. See example at https://timetracker.anuko.com/tasks.php. 'form.tasks.active_tasks' => 'Tarefas ativas', 'form.tasks.inactive_tasks' => 'Tarefas inativas', -// Users form. See example at https://timetracker.anuko.com/users.php -// TODO: check the translation of form.users.uncompleted_entry. Is "apontamento" a correct term for a time entry? -// The meaning of incomplete time entry in Time Tracker is that the entry only has the "start" time defined, but no finish time yet, -// and may be ongoing. For example, user started working on something and is curently in progress doing it. -// Check the Puncher plugin, which operates with such entries. -// 'form.users.uncompleted_entry' => 'User has an uncompleted time entry', -'form.users.uncompleted_entry' => 'O usuário tem um apontamento incompleto', -'form.users.role' => 'Papel', +// Users form. See example at https://timetracker.anuko.com/users.php. +'form.users.uncompleted_entry' => 'O usuário tem uma entrada incompleta', +'form.users.role' => 'Função', 'form.users.manager' => 'Gerente', 'form.users.comanager' => 'Coordenador', 'form.users.rate' => 'Honorário', 'form.users.default_rate' => 'Honorário padrão por hora', -// Editing User form. See example at https://timetracker.anuko.com/user_edit.php -'form.user_edit.swap_roles' => 'Alternar papéis', +// Editing User form. See example at https://timetracker.anuko.com/user_edit.php. +'form.user_edit.swap_roles' => 'Alternar funções', -// Roles form. See example at https://timetracker.anuko.com/roles.php -'form.roles.active_roles' => 'Papéis ativos', -'form.roles.inactive_roles' => 'Papéis inativos', +// Roles form. See example at https://timetracker.anuko.com/roles.php. +'form.roles.active_roles' => 'Funções ativas', +'form.roles.inactive_roles' => 'Funções inativas', 'form.roles.rank' => 'Rank', 'form.roles.rights' => 'Direitos', 'form.roles.assigned' => 'Atribuído', 'form.roles.not_assigned' => 'Não atribuído', -// Clients form. See example at https://timetracker.anuko.com/clients.php +// Clients form. See example at https://timetracker.anuko.com/clients.php. 'form.clients.active_clients' => 'Clientes ativos', 'form.clients.inactive_clients' => 'Clientes inativos', -// Deleting Client form. See example at https://timetracker.anuko.com/client_delete.php +// Deleting Client form. See example at https://timetracker.anuko.com/client_delete.php. 'form.client.client_to_delete' => 'Cliente a ser apagado', 'form.client.client_entries' => 'Entradas de cliente', -// Exporting Group Data form. See example at https://timetracker.anuko.com/export.php -// TODO: replace "equipe" with "group" in the string below. -'form.export.hint' => 'Você pode exportar todos os dados da equipe para um arquivo xml. Isto pode ser útil se você estiver migrando os dados para um servidor próprio.', +// Exporting Group Data form. See example at https://timetracker.anuko.com/export.php. +'form.export.hint' => 'Você pode exportar todos os dados do grupo para um arquivo xml. Isto pode ser útil se você estiver migrando os dados para um servidor próprio.', 'form.export.compression' => 'Compressão', 'form.export.compression_none' => 'nenhuma', 'form.export.compression_bzip' => 'bzip', // Importing Group Data form. See example at https://timetracker.anuko.com/import.php (login as admin first). -'form.import.hint' => 'Importar dados de equipe de um arquivo xml.', // TODO: replace "team" with "group". +'form.import.hint' => 'Importar dados do grupo de um arquivo xml.', 'form.import.file' => 'Selecionar arquivo', 'form.import.success' => 'Importação realizada com sucesso.', // Groups form. See example at https://timetracker.anuko.com/admin_groups.php (login as admin first). -// TODO: replace "equipe" with "group" in the string below (3 places). -'form.groups.hint' => 'Crie uma nova equipe fazendo uma nova conta de gerente.
Você também pode importar os dados de um arquivo xml de outro servidor Anuko Time Tracker (não havendo colisão de usuários).', +'form.groups.hint' => 'Crie um novo grupo fazendo uma nova conta de gerente.
Você também pode importar os dados de um arquivo xml de outro servidor Anuko Time Tracker (não havendo colisão de usuários).', // Group Settings form. See example at https://timetracker.anuko.com/group_edit.php. 'form.group_edit.12_hours' => '12 horas', @@ -548,7 +534,7 @@ 'form.group_edit.allow_ip' => 'Permitir IP', 'form.group_edit.advanced_settings' => 'Configurações avançadas', -// Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php +// Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php. 'form.group_delete.hint' => 'Tem certeza de que deseja excluir todo o grupo?', // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. @@ -565,8 +551,8 @@ 'form.quota.hint' => 'Se os valores estiverem vazios, as cotas serão calculadas automaticamente com base nas horas de trabalho e feriados.', // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. -'form.swap.hint' => 'Rebaixe-se a papel inferior trocando funções com outra pessoa. Isto não pode ser desfeito.', -'form.swap.swap_with' => 'Trocar papéis com', +'form.swap.hint' => 'Rebaixe-se a função inferior trocando funções com outra pessoa. Isto não pode ser desfeito.', +'form.swap.swap_with' => 'Trocar papéis com', // TODO: replace papéis with funções? // Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. 'form.work_units.minutes_in_unit' => 'Minutos em unidade', @@ -608,7 +594,7 @@ 'form.display_options.not_complete_days' => 'Dias não completos', 'form.display_options.custom_css' => 'CSS customizado', -// Work plugin strings. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php. 'work.error.work_not_available' => 'Item de trabalho não está disponível.', 'work.error.offer_not_available' => 'Oferta não disponível', 'work.type.one_time' => 'Uma interação', @@ -623,3 +609,4 @@ 'work.title.send_message' => 'Enviando mensagem', 'work.msg.message_sent' => 'Mensagem enviada.', ); + diff --git a/initialize.php b/initialize.php index b5407ad8a..f0b52b40b 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5582"); +define("APP_VERSION", "1.19.28.5583"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 227ab161cfe26f605406ef31959449aa0ada0f27 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 7 Jul 2021 13:28:54 +0000 Subject: [PATCH 1600/1848] Minor improvement in pt-br file as per pr #111. --- WEB-INF/resources/pt-br.lang.php | 2 +- initialize.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 3e2c6526f..bef8e5f40 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -552,7 +552,7 @@ // Swap roles form. See example at https://timetracker.anuko.com/swap_roles.php. 'form.swap.hint' => 'Rebaixe-se a função inferior trocando funções com outra pessoa. Isto não pode ser desfeito.', -'form.swap.swap_with' => 'Trocar papéis com', // TODO: replace papéis with funções? +'form.swap.swap_with' => 'Trocar função com', // Work Units configuration form. See example at https://timetracker.anuko.com/work_units.php after enabling Work units plugin. 'form.work_units.minutes_in_unit' => 'Minutos em unidade', diff --git a/initialize.php b/initialize.php index f0b52b40b..dc53874d9 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5583"); +define("APP_VERSION", "1.19.28.5584"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From f22d240ca21743681e52edecfa050450cd596213 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 7 Jul 2021 13:35:58 +0000 Subject: [PATCH 1601/1848] Added a comment in pt-br file. --- WEB-INF/resources/pt-br.lang.php | 2 +- initialize.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index bef8e5f40..128f57f49 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -137,7 +137,7 @@ 'label.users' => 'Usuários', 'label.group' => 'Grupo', 'label.subgroups' => 'Subgrupos', -'label.roles' => 'Papéis', +'label.roles' => 'Papéis', // TODO: for consistency, use funçãos, perhaps? 'label.client' => 'Cliente', 'label.clients' => 'Clientes', 'label.option' => 'Opção', diff --git a/initialize.php b/initialize.php index dc53874d9..c282d3f35 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5584"); +define("APP_VERSION", "1.19.28.5585"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 7e78a97138a71ff4b8070d3ec354475ddf0b8e29 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 8 Jul 2021 13:37:19 +0000 Subject: [PATCH 1602/1848] Finished integrating changes from pr #111. --- WEB-INF/resources/pt-br.lang.php | 12 +++++------- initialize.php | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 128f57f49..5d3e2b6ed 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -69,9 +69,7 @@ 'error.no_groups' => 'Sua base de dados está vazia. Entre como admin e crie um grupo novo.', 'error.upload' => 'Erro no envio do arquivo.', 'error.range_locked' => 'Período bloqueado.', -// TODO: is "Use" in error.mail_send translated correctly? Usar, or utilizar, perhaps? "Use" looks like an untranslated English word. -// The meaning of this error is that mail send feature did not work, and using MAIL_SMTP_DEBUG should help admin to troubleshoot it. -'error.mail_send' => 'Erro ao enviar e-mail. Use MAIL_SMTP_DEBUG para diagnósticos.', +'error.mail_send' => 'Erro ao enviar e-mail. Use MAIL_SMTP_DEBUG para diagnósticos.', // "Use" means the same in pt-br as in en. 'error.no_email' => 'Não há e-mail associado a este login.', 'error.uncompleted_exists' => 'Entrada incompleta existente. Feche ou remova-a.', 'error.goto_uncompleted' => 'Ir até a entrada incompleta.', @@ -137,7 +135,7 @@ 'label.users' => 'Usuários', 'label.group' => 'Grupo', 'label.subgroups' => 'Subgrupos', -'label.roles' => 'Papéis', // TODO: for consistency, use funçãos, perhaps? +'label.roles' => 'Funções', 'label.client' => 'Cliente', 'label.clients' => 'Clientes', 'label.option' => 'Opção', @@ -284,7 +282,7 @@ 'title.add_user' => 'Adicionando usuário', 'title.edit_user' => 'Editando usuário', 'title.delete_user' => 'Apagando usuário', -'title.roles' => 'Papéis', +'title.roles' => 'Funções', 'title.add_role' => 'Adicionando função', 'title.edit_role' => 'Editando função', 'title.delete_role' => 'Apagando função', @@ -320,7 +318,7 @@ 'title.cf_delete_dropdown_option' => 'Apagando opção', 'title.locking' => 'Bloquear', 'title.week_view' => 'Visão semanal', -'title.swap_roles' => 'Alteração de papéis', +'title.swap_roles' => 'Alteração de funções', 'title.work_units' => 'Unidades de trabalho', 'title.templates' => 'Modelos', 'title.add_template' => 'Adicionando modelo', @@ -408,7 +406,7 @@ 'form.time.over_balance' => 'Saldo excedente', // Editing Time Record form. See example at https://timetracker.anuko.com/time_edit.php (get there by editing an uncompleted time record). -'form.time_edit.uncompleted' => 'Eesta entrada foi salva somente com hora de início. Não é um erro.', +'form.time_edit.uncompleted' => 'Esta entrada foi salva somente com hora de início. Não é um erro.', // Week view form. See example at https://timetracker.anuko.com/week.php. 'form.week.new_entry' => 'Nova entrada', diff --git a/initialize.php b/initialize.php index c282d3f35..76b5058ef 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5585"); +define("APP_VERSION", "1.19.28.5586"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From bd5871c86bd95adff6d429c3481f03ec9a244414 Mon Sep 17 00:00:00 2001 From: Thiago Alves Cavalcante Date: Thu, 8 Jul 2021 10:45:13 -0300 Subject: [PATCH 1603/1848] Add conditional if ldap is enabled on passwords (#112) Adds same conditional on verifications of passwords in case of ldap (external password) is enabled. Else is not possible create groups due to erros on this verification with ldap configured. --- admin_group_add.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/admin_group_add.php b/admin_group_add.php index 52850b608..9aeff1831 100644 --- a/admin_group_add.php +++ b/admin_group_add.php @@ -69,12 +69,14 @@ $err->add($i18n->get('error.field'), $i18n->get('label.manager_login')); if (ttUserHelper::getUserByLogin($cl_manager_login)) $err->add($i18n->get('error.user_exists')); - if (!ttValidString($cl_password1)) - $err->add($i18n->get('error.field'), $i18n->get('label.password')); - if (!ttValidString($cl_password2)) - $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); + if (!$auth->isPasswordExternal()) { + if (!ttValidString($cl_password1)) + $err->add($i18n->get('error.field'), $i18n->get('label.password')); + if (!ttValidString($cl_password2)) + $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); + if ($cl_password1 !== $cl_password2) + $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); + } if (!ttValidEmail($cl_manager_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); if (!ttUserHelper::canAdd()) From 0a94b8f7afe1ee14b69b15789fd751d928255dd4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Jul 2021 15:23:21 +0000 Subject: [PATCH 1604/1848] Fixed ttUser::getUserDetails() function to allow supervisors work on behalf of users. --- WEB-INF/lib/ttUser.class.php | 7 ++----- initialize.php | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index cf1065f06..2086a3740 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -587,11 +587,8 @@ function getSubgroups($group_id = null) { return $groups; } - // getUserDetails function is used to manage users in group and returns user details. - // At the moment, the function is used for user edits and deletes. - function getUserDetails($user_id) { - if (!$this->can('manage_users')) return false; - + // getUserDetails function returns user details. + function getUserDetails($user_id) { $mdb2 = getConnection(); $group_id = $this->getGroup(); $org_id = $this->org_id; diff --git a/initialize.php b/initialize.php index 76b5058ef..6b968992a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5586"); +define("APP_VERSION", "1.19.28.5587"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 36d735b4748bc786196f4b8c5f9ce72867aa1fe2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Jul 2021 15:06:30 +0000 Subject: [PATCH 1605/1848] Work started on inactive projects display option for reports. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + initialize.php | 2 +- 31 files changed, 33 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 205600d04..5f37900bd 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -682,6 +682,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 7a685029b..0ff169553 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -695,6 +695,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 3cb53a5a3..142655586 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -659,6 +659,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index c0d69b6d6..86834287a 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -636,6 +636,7 @@ 'form.display_options.note_on_separate_row' => 'Beschreibung in separater Zeile', // TODO: translate the following. // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 1acc79084..93d77217e 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -614,6 +614,7 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.note_on_separate_row' => 'Note on separate row', 'form.display_options.not_complete_days' => 'Not complete days', +'form.display_options.inactive_projects' => 'Inactive projects', 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index ebe095e96..1fb69298e 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -697,6 +697,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 961b8e2b5..28693401c 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -667,6 +667,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 798406ccf..7d453ef33 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -683,6 +683,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 813b442fe..f45dec85a 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -667,6 +667,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index e2642ad27..168b01a5b 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -655,6 +655,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 5a6a8df81..3b1ca3883 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -647,6 +647,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 958a556e6..2ed161e3e 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -688,6 +688,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 22b28039e..78971e4f5 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -686,6 +686,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ab3852bf5..d1c172a5d 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -661,6 +661,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 85192f026..2e1b012d3 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -690,6 +690,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 202578fcc..a5960229d 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -688,6 +688,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 51d4e41ee..c261b7491 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -593,6 +593,8 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', // Translator (Henk) comment: "kolom is the right word in Dutch." 'form.display_options.not_complete_days' => 'Niet complete dagen', +// TODO: translate the following. +// 'form.display_options.inactive_projects' => 'Inactive projects', 'form.display_options.custom_css' => 'Aangepaste CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index b3cf78863..6a6161f5d 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -689,6 +689,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index b0602334f..376f324b7 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -668,6 +668,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 5d3e2b6ed..db8503038 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -590,6 +590,8 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.note_on_separate_row' => 'Anotação em linha separada', 'form.display_options.not_complete_days' => 'Dias não completos', +// TODO: translate the following. +// 'form.display_options.inactive_projects' => 'Inactive projects', 'form.display_options.custom_css' => 'CSS customizado', // Work plugin strings. See example at https://timetracker.anuko.com/work.php. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9a26f283e..4617faf4c 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -669,6 +669,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 95e27a122..d325468ce 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -690,6 +690,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index cb4abe577..5fbca6032 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -594,6 +594,7 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.note_on_separate_row' => 'Комментарий в отдельном ряду', 'form.display_options.not_complete_days' => 'Незавершенные дни', +'form.display_options.inactive_projects' => 'Неактивные проекты', 'form.display_options.custom_css' => 'Пользовательская CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 821c23b45..d8add50c8 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -672,6 +672,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index bb37b8631..ac49e7d81 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -663,6 +663,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index e1f9a28e2..6fcae026c 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -670,6 +670,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index cea1ddd88..49df06651 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -667,6 +667,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index b94ba8d90..08eec0619 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -703,6 +703,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 0a6e4ab25..4ec6da135 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -677,6 +677,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 2efd7bbe1..970d79263 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -680,6 +680,7 @@ // TODO: translate the following. // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/initialize.php b/initialize.php index 6b968992a..60598cb3c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5587"); +define("APP_VERSION", "1.19.28.5588"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ae7dfacad852cccff08c0a1f6fdcc8c7e7f50cf1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Jul 2021 16:42:27 +0000 Subject: [PATCH 1606/1848] Implemented report inactive projects display option. --- WEB-INF/lib/ttProjectHelper.class.php | 12 +++++++++--- WEB-INF/templates/display_options.tpl | 8 ++++++++ display_options.php | 4 ++++ initialize.php | 2 +- reports.php | 4 +++- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index d456c3110..ebbd055fb 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -77,17 +77,23 @@ static function getRates($user_id) { return $result; } - // getProjects - returns an array of active and inactive projects in group. - static function getProjects() { + // getProjects - returns an array of projects for group. + static function getProjects($includeInactiveProjects = true) { global $user; $mdb2 = getConnection(); $group_id = $user->getGroup(); $org_id = $user->org_id; + // Construct status part. + $statusPart = 'status = 1'; + if ($includeInactiveProjects) { + $statusPart = '(status = 0 or '.$statusPart.')'; + } + $result = array(); $sql = "select id, name, tasks from tt_projects". - " where group_id = $group_id and org_id = $org_id and (status = 0 or status = 1) order by upper(name)"; + " where group_id = $group_id and org_id = $org_id and $statusPart order by upper(name)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index 8c9db8ea7..6486c0b25 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -41,6 +41,14 @@ License: See license.txt *} {$i18n.label.what_is_it}

+ + + + + diff --git a/display_options.php b/display_options.php index 21b488c64..6e0ccc548 100644 --- a/display_options.php +++ b/display_options.php @@ -20,12 +20,14 @@ $cl_time_not_complete_days = (bool)$request->getParameter('time_not_complete_days'); $cl_record_custom_fields = (bool)$request->getParameter('record_custom_fields'); $cl_report_note_on_separate_row = (bool)$request->getParameter('report_note_on_separate_row'); + $cl_report_inactive_projects = (bool)($request->getParameter('report_inactive_projects')); $cl_custom_css = trim($request->getParameter('custom_css')); } else { $cl_time_note_on_separate_row = $config->getDefinedValue('time_note_on_separate_row'); $cl_time_not_complete_days = $config->getDefinedValue('time_not_complete_days'); $cl_record_custom_fields = $config->getDefinedValue('record_custom_fields'); $cl_report_note_on_separate_row = $config->getDefinedValue('report_note_on_separate_row'); + $cl_report_inactive_projects = $config->getDefinedValue('report_inactive_projects'); $cl_custom_css = $user->getCustomCss(); } @@ -46,6 +48,7 @@ // Reports. $form->addInput(array('type'=>'checkbox','name'=>'report_note_on_separate_row','value'=>$cl_report_note_on_separate_row)); +$form->addInput(array('type'=>'checkbox','name'=>'report_inactive_projects','value'=>$cl_report_inactive_projects)); // TODO: add PDF break controller here. $form->addInput(array('type'=>'textarea','name'=>'custom_css','value'=>$cl_custom_css)); @@ -62,6 +65,7 @@ $config->setDefinedValue('time_not_complete_days', $cl_time_not_complete_days); $config->setDefinedValue('record_custom_fields', $cl_record_custom_fields); $config->setDefinedValue('report_note_on_separate_row', $cl_report_note_on_separate_row); + $config->setDefinedValue('report_inactive_projects', $cl_report_inactive_projects); if ($user->updateGroup(array( 'config' => $config->getConfig(), 'custom_css' => $cl_custom_css))) { diff --git a/initialize.php b/initialize.php index 60598cb3c..f8f514ee0 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5588"); +define("APP_VERSION", "1.19.28.5589"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports.php b/reports.php index b71706220..c1df04387 100644 --- a/reports.php +++ b/reports.php @@ -73,7 +73,9 @@ $project_list = array(); if ($showProject) { if ($user->can('view_reports') || $user->can('view_all_reports')) { - $project_list = ttProjectHelper::getProjects(); // All active and inactive projects. + $config = new ttConfigHelper($user->getConfig()); + $includeInactiveProjects = $config->getDefinedValue('report_inactive_projects'); + $project_list = ttProjectHelper::getProjects($includeInactiveProjects); } elseif ($user->isClient()) { $project_list = ttProjectHelper::getProjectsForClient(); } else { From fb9f7b179726343b7c59aadf11c9ef1fa0b0762d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 6 Aug 2021 18:21:40 +0000 Subject: [PATCH 1607/1848] Added a resource string. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + initialize.php | 2 +- 31 files changed, 32 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 5f37900bd..f9d9952db 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -131,6 +131,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 0ff169553..453a51000 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -133,6 +133,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 142655586..a33224168 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -128,6 +128,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 86834287a..47eb84a16 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -125,6 +125,7 @@ // The problem is they do not appear precise, deviate from the meaning of approval / disaproval of report items.) // 'button.approve' => 'Approve', (suggested 'Freigeben / Genehmigen' does not appear precise) // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 93d77217e..c1c00af9d 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -120,6 +120,7 @@ 'button.stop' => 'Stop', 'button.approve' => 'Approve', 'button.disapprove' => 'Disapprove', +'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.menu' => 'Menu', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 1fb69298e..8a8902f7d 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -130,6 +130,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 28693401c..3299e8ada 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -139,6 +139,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 7d453ef33..019c4ca31 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -136,6 +136,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index f45dec85a..0940dc597 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -130,6 +130,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 168b01a5b..88a96690e 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -128,6 +128,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 3b1ca3883..489185a8c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -123,6 +123,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2ed161e3e..918b5f7dc 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -144,6 +144,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 78971e4f5..407c22cd4 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -133,6 +133,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index d1c172a5d..165afe880 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -127,6 +127,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 2e1b012d3..dbac8f190 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -137,6 +137,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index a5960229d..896f1939f 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -136,6 +136,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index c261b7491..921d50af8 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -111,6 +111,7 @@ 'button.stop' => 'Stop', 'button.approve' => 'Goedkeuren', 'button.disapprove' => 'Afkeuren', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.menu' => 'Menu', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 6a6161f5d..5cb39137d 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -136,6 +136,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 376f324b7..d77f11c3d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -132,6 +132,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index db8503038..15e3ef91f 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -111,6 +111,8 @@ 'button.stop' => 'Parar', 'button.approve' => 'Aprovar', 'button.disapprove' => 'Desaprovar', +// TODO: translate the following. +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.menu' => 'Menu', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 4617faf4c..6a1598cc7 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -129,6 +129,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index d325468ce..f93f12085 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -136,6 +136,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 5fbca6032..71bc709bf 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -111,6 +111,7 @@ 'button.stop' => 'Завершить', 'button.approve' => 'Одобрить', 'button.disapprove' => 'Не одобрить', +'button.sync' => 'Синхронизовать', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.menu' => 'Меню', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d8add50c8..da24d8caf 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -133,6 +133,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ac49e7d81..40abaabea 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -126,6 +126,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 6fcae026c..8e9fe4e8f 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -129,6 +129,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 49df06651..bd025f84b 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -127,6 +127,7 @@ // TODO: translate the following. // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 08eec0619..5ac60a72d 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -140,6 +140,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 4ec6da135..6c6451214 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -129,6 +129,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 970d79263..d16bf4cb7 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -133,6 +133,7 @@ // 'button.stop' => 'Stop', // 'button.approve' => 'Approve', // 'button.disapprove' => 'Disapprove', +// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. // Labels for controls on forms. Labels in this section are used on multiple forms. // TODO: translate the following. diff --git a/initialize.php b/initialize.php index f8f514ee0..d36445879 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5589"); +define("APP_VERSION", "1.19.28.5590"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From d1a34ad77b7f38f8831fa303a215c242aaab492b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 13 Aug 2021 13:26:18 +0000 Subject: [PATCH 1608/1848] Introduced entities_modified field in tt_groups table for future API support. --- dbinstall.php | 10 ++++++---- initialize.php | 2 +- mysql.sql | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/dbinstall.php b/dbinstall.php index 322b05663..2dfe30d66 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1137,7 +1137,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11923"]) { + if ($_POST["convert11900to11929"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1170,6 +1170,8 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.22', modified = now() where param_name = 'version_db' and param_value = '1.19.19'"); ttExecute("ALTER TABLE `tt_groups` drop `task_required`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.23', modified = now() where param_name = 'version_db' and param_value = '1.19.22'"); + ttExecute("ALTER TABLE `tt_groups` ADD `entities_modified` datetime default NULL AFTER `modified_by`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.29', modified = now() where param_name = 'version_db' and param_value = '1.19.23'"); } if ($_POST["cleanup"]) { @@ -1220,7 +1222,7 @@ function ttGenerateKeys() {

DB Install

 Anuko Time Tracker 1.18.44.4780 | Copyright © Anuko | +  Anuko Time Tracker 1.18.44.4781 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index aacb889ac..ed7928c7f 100644 --- a/report.php +++ b/report.php @@ -82,7 +82,8 @@ if ($user->can('manage_invoices')) $showForInvoicesOrPaid = true; } -if ($showForApproved || $showForInvoicesOrPaid) +$use_checkboxes = $showForApproved || $showForInvoicesOrPaid; +if ($use_checkboxes) $smarty->assign('use_checkboxes', true); // Controls for "Mark approved" block. @@ -218,7 +219,7 @@ $report_items = ttReportHelper::getItems($options); // Store record ids in session in case user wants to act on records such as marking them all paid. -if ($request->isGet() && $user->isPluginEnabled('ps')) +if ($request->isGet() && $use_checkboxes) ttReportHelper::putInSession($report_items); if (ttReportHelper::grouping($options)) { From bcd76a04871724775c3b648bffa56e6d4ea4551c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 26 Feb 2019 16:01:34 +0000 Subject: [PATCH 0725/1848] Removed view_client_unapproved right from default client role. --- WEB-INF/lib/ttRoleHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 13 ++++++++----- mysql.sql | 2 +- reports.php | 2 +- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 0be33d55a..c45d4d3f9 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -189,7 +189,7 @@ static function createPredefinedRoles($group_id, $lang) $mdb2 = getConnection(); - $rights_client = 'view_client_reports,view_client_timesheets,view_client_unapproved,view_client_invoices,manage_own_settings'; + $rights_client = 'view_client_reports,view_client_timesheets,view_client_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 36ff12c7c..0ecaee021 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.44.4781 | Copyright © Anuko | +  Anuko Time Tracker 1.18.44.4782 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 6124857b1..0503760f6 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11843"]) { + if ($_POST["convert11797to11844"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1092,7 +1092,10 @@ function ttExecute($sql) { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = replace(rights, 'view_reports,view_timesheets', 'view_reports,approve_reports,view_timesheets') where rank = 12 or rank = 68 or rank = 324"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = replace(rights, 'export_data,approve_all_timesheets', 'export_data,approve_all_reports,approve_all_timesheets') where rank = 324"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.43', modified = now() where param_name = 'version_db' and param_value = '1.18.42'"); - } + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.43') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,view_client_unapproved,delete_group' where rank = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.43') set rights = replace(rights, 'view_client_timesheets,view_client_unapproved,view_client_invoices', 'view_client_timesheets,view_client_invoices') where rank = 16"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.44', modified = now() where param_name = 'version_db' and param_value = '1.18.43'"); +} if ($_POST["cleanup"]) { @@ -1140,7 +1143,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.43) + Create database structure (v1.18.44)
(applies only to new installations, do not execute when updating)
@@ -1185,8 +1188,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.43)Update database structure (v1.17.97 to v1.18.44)
diff --git a/mysql.sql b/mysql.sql index 8b1859190..9958fbd24 100644 --- a/mysql.sql +++ b/mysql.sql @@ -75,7 +75,7 @@ create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_unapproved,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,view_client_unapproved,delete_group'); # diff --git a/reports.php b/reports.php index febfad794..d6a9a7074 100644 --- a/reports.php +++ b/reports.php @@ -194,7 +194,7 @@ // Add timesheet assignment selector. $showTimesheetDropdown = $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('view_timesheets') || - $user->can('view_all_timesheets') || ($user->can('view_client_timesheets') && $user->can('view_client_unapproved'))); + $user->can('view_all_timesheets') || ($user->can('view_client_timesheets'))); if ($showTimesheetDropdown) { $form->addInput(array('type'=>'combobox', 'name'=>'timesheet', From 09cb0a1a3c772c618ff58b339cd40cbdb59f7492 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 26 Feb 2019 17:09:27 +0000 Subject: [PATCH 0726/1848] Extended tt_fav_reports table for approved and timesheet options. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 13 +++++++++---- mysql.sql | 6 +++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0ecaee021..90c81e1a5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.44.4782 | Copyright © Anuko | +  Anuko Time Tracker 1.18.45.4783 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 0503760f6..d7f90cb82 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11844"]) { + if ($_POST["convert11797to11845"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1095,6 +1095,11 @@ function ttExecute($sql) { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.43') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,view_client_unapproved,delete_group' where rank = 512"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.43') set rights = replace(rights, 'view_client_timesheets,view_client_unapproved,view_client_invoices', 'view_client_timesheets,view_client_invoices') where rank = 16"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.44', modified = now() where param_name = 'version_db' and param_value = '1.18.43'"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `approved` tinyint(4) default NULL AFTER `billable`"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `timesheet` tinyint(4) default NULL AFTER `invoice`"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `show_timesheet` tinyint(4) NOT NULL default 0 AFTER `show_project`"); + ttExecute("ALTER TABLE `tt_fav_reports` ADD `show_approved` tinyint(4) NOT NULL default 0 AFTER `show_note`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.45', modified = now() where param_name = 'version_db' and param_value = '1.18.44'"); } if ($_POST["cleanup"]) { @@ -1143,7 +1148,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.44) + Create database structure (v1.18.45)
(applies only to new installations, do not execute when updating)
@@ -1188,8 +1193,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.44)Update database structure (v1.17.97 to v1.18.45)
diff --git a/mysql.sql b/mysql.sql index 9958fbd24..1747b590a 100644 --- a/mysql.sql +++ b/mysql.sql @@ -267,7 +267,9 @@ CREATE TABLE `tt_fav_reports` ( `project_id` int(11) default NULL, # project id (if selected) `task_id` int(11) default NULL, # task id (if selected) `billable` tinyint(4) default NULL, # whether to include billable, not billable, or all records + `approved` tinyint(4) default NULL, # whether to include approved, unapproved, or all records `invoice` tinyint(4) default NULL, # whether to include invoiced, not invoiced, or all records + `timesheet` tinyint(4) default NULL, # include records with a specific timesheet status, or all records `paid_status` tinyint(4) default NULL, # whether to include paid, not paid, or all records `users` text default NULL, # Comma-separated list of user ids. Nothing here means "all" users. `period` tinyint(4) default NULL, # selected period type for report @@ -278,12 +280,14 @@ CREATE TABLE `tt_fav_reports` ( `show_paid` tinyint(4) NOT NULL default 0, # whether to show paid column `show_ip` tinyint(4) NOT NULL default 0, # whether to show ip column `show_project` tinyint(4) NOT NULL default 0, # whether to show project column + `show_timesheet` tinyint(4) NOT NULL default 0, # whether to show timesheet column `show_start` tinyint(4) NOT NULL default 0, # whether to show start field `show_duration` tinyint(4) NOT NULL default 0, # whether to show duration field `show_cost` tinyint(4) NOT NULL default 0, # whether to show cost field `show_task` tinyint(4) NOT NULL default 0, # whether to show task column `show_end` tinyint(4) NOT NULL default 0, # whether to show end field `show_note` tinyint(4) NOT NULL default 0, # whether to show note column + `show_approved` tinyint(4) NOT NULL default 0, # whether to show approved column `show_custom_field_1` tinyint(4) NOT NULL default 0, # whether to show custom field 1 `show_work_units` tinyint(4) NOT NULL default 0, # whether to show work units `show_totals_only` tinyint(4) NOT NULL default 0, # whether to show totals only @@ -520,4 +524,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.43', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.45', now()); # TODO: change when structure changes. From da31afab09f45aa188f4a6a8c939715a80216992 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 26 Feb 2019 19:25:31 +0000 Subject: [PATCH 0727/1848] Made fav reports to remember approved and timesheet options. --- WEB-INF/lib/ttFavReportHelper.class.php | 74 +++++++++++++++++-------- WEB-INF/templates/footer.tpl | 2 +- reports.php | 20 ++++--- 3 files changed, 64 insertions(+), 32 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 30bfc235f..97f7e47ae 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -120,22 +120,23 @@ static function insertReport($fields) { $sql = "insert into tt_fav_reports". " (name, user_id, group_id, org_id, client_id, cf_1_option_id, project_id, task_id,". - " billable, invoice, paid_status, users, period, period_start, period_end,". - " show_client, show_invoice, show_paid, show_ip,". - " show_project, show_start, show_duration, show_cost,". - " show_task, show_end, show_note, show_custom_field_1, show_work_units,". + " billable, approved, invoice, timesheet, paid_status, users, period, period_start,". + " period_end, show_client, show_invoice, show_paid, show_ip,". + " show_project, show_timesheet, show_start, show_duration, show_cost,". + " show_task, show_end, show_note, show_approved, show_custom_field_1, show_work_units,". " group_by1, group_by2, group_by3, show_totals_only)". " values(". $mdb2->quote($fields['name']).", $user_id, $group_id, $org_id, ". $mdb2->quote($fields['client']).", ".$mdb2->quote($fields['option']).", ". $mdb2->quote($fields['project']).", ".$mdb2->quote($fields['task']).", ". - $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['invoice']).", ". + $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['approved']).", ". + $mdb2->quote($fields['invoice']).", ".$mdb2->quote($fields['timesheet']).", ". $mdb2->quote($fields['paid_status']).", ". $mdb2->quote($fields['users']).", ".$mdb2->quote($fields['period']).", ". $mdb2->quote($fields['from']).", ".$mdb2->quote($fields['to']).", ". $fields['chclient'].", ".$fields['chinvoice'].", ".$fields['chpaid'].", ".$fields['chip'].", ". - $fields['chproject'].", ".$fields['chstart'].", ".$fields['chduration'].", ".$fields['chcost'].", ". - $fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ".$fields['chcf_1'].", ".$fields['chunits'].", ". + $fields['chproject'].", ".$fields['chtimesheet'].", ".$fields['chstart'].", ".$fields['chduration'].", ".$fields['chcost'].", ". + $fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ".$fields['chapproved'].", ".$fields['chcf_1'].", ".$fields['chunits'].", ". $mdb2->quote($fields['group_by1']).", ".$mdb2->quote($fields['group_by2']).", ". $mdb2->quote($fields['group_by3']).", ".$fields['chtotalsonly'].")"; $affected = $mdb2->exec($sql); @@ -162,7 +163,9 @@ static function updateReport($fields) { "project_id = ".$mdb2->quote($fields['project']).", ". "task_id = ".$mdb2->quote($fields['task']).", ". "billable = ".$mdb2->quote($fields['billable']).", ". + "approved = ".$mdb2->quote($fields['approved']).", ". "invoice = ".$mdb2->quote($fields['invoice']).", ". + "timesheet = ".$mdb2->quote($fields['timesheet']).", ". "paid_status = ".$mdb2->quote($fields['paid_status']).", ". "users = ".$mdb2->quote($fields['users']).", ". "period = ".$mdb2->quote($fields['period']).", ". @@ -173,12 +176,14 @@ static function updateReport($fields) { "show_paid = ".$fields['chpaid'].", ". "show_ip = ".$fields['chip'].", ". "show_project = ".$fields['chproject'].", ". + "show_timesheet = ".$fields['chtimesheet'].", ". "show_start = ".$fields['chstart'].", ". "show_duration = ".$fields['chduration'].", ". "show_cost = ".$fields['chcost'].", ". "show_task = ".$fields['chtask'].", ". "show_end = ".$fields['chfinish'].", ". "show_note = ".$fields['chnote'].", ". + "show_approved = ".$fields['chapproved'].", ". "show_custom_field_1 = ".$fields['chcf_1'].", ". "show_work_units = ".$fields['chunits'].", ". "group_by1 = ".$mdb2->quote($fields['group_by1']).", ". @@ -200,18 +205,24 @@ static function saveReport($bean) { // Set default value of 0 for not set checkboxes (in bean). // Later in this function we use it to construct $fields array to update database. if (!$bean->getAttribute('chclient')) $bean->setAttribute('chclient', 0); - if (!$bean->getAttribute('chinvoice')) $bean->setAttribute('chinvoice', 0); - if (!$bean->getAttribute('chpaid')) $bean->setAttribute('chpaid', 0); - if (!$bean->getAttribute('chip')) $bean->setAttribute('chip', 0); - if (!$bean->getAttribute('chproject')) $bean->setAttribute('chproject', 0); if (!$bean->getAttribute('chstart')) $bean->setAttribute('chstart', 0); + if (!$bean->getAttribute('chfinish')) $bean->setAttribute('chfinish', 0); if (!$bean->getAttribute('chduration')) $bean->setAttribute('chduration', 0); - if (!$bean->getAttribute('chcost')) $bean->setAttribute('chcost', 0); + + if (!$bean->getAttribute('chproject')) $bean->setAttribute('chproject', 0); if (!$bean->getAttribute('chtask')) $bean->setAttribute('chtask', 0); - if (!$bean->getAttribute('chfinish')) $bean->setAttribute('chfinish', 0); if (!$bean->getAttribute('chnote')) $bean->setAttribute('chnote', 0); + if (!$bean->getAttribute('chcost')) $bean->setAttribute('chcost', 0); + + if (!$bean->getAttribute('chtimesheet')) $bean->setAttribute('chtimesheet', 0); + if (!$bean->getAttribute('chip')) $bean->setAttribute('chip', 0); + if (!$bean->getAttribute('chapproved')) $bean->setAttribute('chapproved', 0); + if (!$bean->getAttribute('chpaid')) $bean->setAttribute('chpaid', 0); + if (!$bean->getAttribute('chcf_1')) $bean->setAttribute('chcf_1', 0); if (!$bean->getAttribute('chunits')) $bean->setAttribute('chunits', 0); + if (!$bean->getAttribute('chinvoice')) $bean->setAttribute('chinvoice', 0); + if (!$bean->getAttribute('chtotalsonly')) $bean->setAttribute('chtotalsonly', 0); $users_in_bean = $bean->getAttribute('users'); @@ -234,25 +245,29 @@ static function saveReport($bean) { 'project'=>$bean->getAttribute('project'), 'task'=>$bean->getAttribute('task'), 'billable'=>$bean->getAttribute('include_records'), - 'invoice'=>$bean->getAttribute('invoice'), + 'approved'=>$bean->getAttribute('approved'), 'paid_status'=>$bean->getAttribute('paid_status'), + 'invoice'=>$bean->getAttribute('invoice'), + 'timesheet'=>$bean->getAttribute('timesheet'), 'users'=>$users, 'period'=>$bean->getAttribute('period'), 'from'=>$from, 'to'=>$to, 'chclient'=>$bean->getAttribute('chclient'), - 'chinvoice'=>$bean->getAttribute('chinvoice'), - 'chpaid'=>$bean->getAttribute('chpaid'), - 'chip'=>$bean->getAttribute('chip'), - 'chproject'=>$bean->getAttribute('chproject'), 'chstart'=>$bean->getAttribute('chstart'), + 'chfinish'=>$bean->getAttribute('chfinish'), 'chduration'=>$bean->getAttribute('chduration'), - 'chcost'=>$bean->getAttribute('chcost'), + 'chproject'=>$bean->getAttribute('chproject'), 'chtask'=>$bean->getAttribute('chtask'), - 'chfinish'=>$bean->getAttribute('chfinish'), 'chnote'=>$bean->getAttribute('chnote'), + 'chcost'=>$bean->getAttribute('chcost'), + 'chtimesheet'=>$bean->getAttribute('chtimesheet'), + 'chip'=>$bean->getAttribute('chip'), + 'chapproved'=>$bean->getAttribute('chapproved'), + 'chpaid'=>$bean->getAttribute('chpaid'), 'chcf_1'=>$bean->getAttribute('chcf_1'), 'chunits'=>$bean->getAttribute('chunits'), + 'chinvoice'=>$bean->getAttribute('chinvoice'), 'group_by1'=>$bean->getAttribute('group_by1'), 'group_by2'=>$bean->getAttribute('group_by2'), 'group_by3'=>$bean->getAttribute('group_by3'), @@ -303,8 +318,10 @@ static function loadReport(&$bean) { $bean->setAttribute('project', $val['project_id']); $bean->setAttribute('task', $val['task_id']); $bean->setAttribute('include_records', $val['billable']); + $bean->setAttribute('approved', $val['approved']); $bean->setAttribute('invoice', $val['invoice']); $bean->setAttribute('paid_status', $val['paid_status']); + $bean->setAttribute('timesheet', $val['timesheet']); $bean->setAttribute('users', explode(',', $val['users'])); $bean->setAttribute('period', $val['period']); if ($val['period_start']) { @@ -320,12 +337,14 @@ static function loadReport(&$bean) { $bean->setAttribute('chpaid', $val['show_paid']); $bean->setAttribute('chip', $val['show_ip']); $bean->setAttribute('chproject', $val['show_project']); + $bean->setAttribute('chtimesheet', $val['show_timesheet']); $bean->setAttribute('chstart', $val['show_start']); $bean->setAttribute('chduration', $val['show_duration']); $bean->setAttribute('chcost', $val['show_cost']); $bean->setAttribute('chtask', $val['show_task']); $bean->setAttribute('chfinish', $val['show_end']); $bean->setAttribute('chnote', $val['show_note']); + $bean->setAttribute('chapproved', $val['show_approved']); $bean->setAttribute('chcf_1', $val['show_custom_field_1']); $bean->setAttribute('chunits', $val['show_work_units']); $bean->setAttribute('group_by1', $val['group_by1']); @@ -341,20 +360,27 @@ static function loadReport(&$bean) { 'project'=>'', 'task'=>'', 'include_records'=>'', + 'approved'=>'', + 'paid_status'=>'', 'invoice'=>'', + 'timesheet'=>'', 'users'=>$user_id, 'period'=>'', 'chclient'=>'1', - 'chinvoice'=>'', - 'chproject'=>'1', 'chstart'=>'1', + 'chfinish'=>'1', 'chduration'=>'1', - 'chcost'=>'', + 'chproject'=>'1', 'chtask'=>'1', - 'chfinish'=>'1', 'chnote'=>'1', + 'chcost'=>'', + 'chtimesheet'=>'', + 'chip'=>'', + 'chapproved'=>'', + 'chpaid'=>'', 'chcf_1'=>'', 'chunits'=>'', + 'chinvoice'=>'', 'group_by1'=>'', 'group_by2'=>'', 'group_by3'=>'', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 90c81e1a5..80072db49 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} - + {if $show_files} {/if} @@ -68,8 +68,8 @@ License: See license.txt *} {if $show_client} {/if} - + {if $show_files} {/if} diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl index 42fa0b34e..41568f601 100644 --- a/WEB-INF/templates/week.tpl +++ b/WEB-INF/templates/week.tpl @@ -195,4 +195,5 @@ function fillDropdowns() { {/if}
 Anuko Time Tracker 1.18.45.4783 | Copyright © Anuko | +  Anuko Time Tracker 1.18.45.4784 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index d6a9a7074..5700025c7 100644 --- a/reports.php +++ b/reports.php @@ -336,20 +336,26 @@ $period = new Period(INTERVAL_THIS_MONTH, new DateAndTime($user->getDateFormat())); $form->setValueByElement('start_date', $period->getStartDate()); $form->setValueByElement('end_date', $period->getEndDate()); + $form->setValueByElement('chclient', '1'); - $form->setValueByElement('chinvoice', '0'); - $form->setValueByElement('chpaid', '0'); - $form->setValueByElement('chip', '0'); - $form->setValueByElement('chproject', '1'); $form->setValueByElement('chstart', '1'); + $form->setValueByElement('chfinish', '1'); $form->setValueByElement('chduration', '1'); - $form->setValueByElement('chcost', '0'); + + $form->setValueByElement('chproject', '1'); $form->setValueByElement('chtask', '1'); - $form->setValueByElement('chfinish', '1'); $form->setValueByElement('chnote', '1'); + $form->setValueByElement('chcost', '0'); + + $form->setValueByElement('chtimesheet', '0'); + $form->setValueByElement('chip', '0'); + $form->setValueByElement('chapproved', '0'); + $form->setValueByElement('chpaid', '0'); + $form->setValueByElement('chcf_1', '0'); $form->setValueByElement('chunits', '0'); - $form->setValueByElement('chtimesheet', '0'); + $form->setValueByElement('chinvoice', '0'); + $form->setValueByElement('chtotalsonly', '0'); } From 7dff008c1343e02229a5607df059a7db4774f975 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 26 Feb 2019 21:16:58 +0000 Subject: [PATCH 0728/1848] A fix for fav reports sent to clients. --- WEB-INF/lib/ttFavReportHelper.class.php | 5 ++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 97f7e47ae..694bb5947 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -414,7 +414,7 @@ static function getReportOptions($id) { return $options; } - // adjustOptions takes and array or report options and adjusts them for current user + // adjustOptions takes an array or report options and adjusts them for current user // (and group) settings. This is needed in situations when a fav report is stored in db // long ago, but user or group attributes are now changed, so we have to adjust. static function adjustOptions($options) { @@ -457,6 +457,9 @@ static function adjustOptions($options) { // TODO: add checking the existing user list for potentially changed access rights for user. } + if ($user->isPluginEnabled('ap') && $user->isClient() && !$user->can('view_client_unapproved')) + $options['approved'] = 1; // Restrict clients to approved records only. + return $options; } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 80072db49..39d8eb771 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- '; if ($options['show_cost']) $body .= ''; + if ($options['show_approved']) + $body .= ''; if ($options['show_paid']) $body .= ''; if ($options['show_ip']) $body .= ''; if ($options['show_invoice']) $body .= ''; + if ($options['show_timesheet']) + $body .= ''; $body .= ''; // Initialize variables to print subtotals. @@ -880,9 +884,11 @@ static function prepareReportBody($options, $comment = null) $body .= ($canViewReports || $isClient) ? $subtotals[$prev_grouped_by]['cost'] : $subtotals[$prev_grouped_by]['expenses']; $body .= ''; } + if ($options['show_approved']) $body .= ''; if ($options['show_paid']) $body .= ''; if ($options['show_ip']) $body .= ''; if ($options['show_invoice']) $body .= ''; + if ($options['show_timesheet']) $body .= ''; $body .= ''; $body .= ''; } @@ -916,6 +922,11 @@ static function prepareReportBody($options, $comment = null) $body .= ''; if ($options['show_cost']) $body .= ''; + if ($options['show_approved']) { + $body .= ''; + } if ($options['show_paid']) { $body .= ''; + if ($options['show_timesheet']) + $body .= ''; $body .= ''; $prev_date = $record['date']; @@ -956,9 +969,11 @@ static function prepareReportBody($options, $comment = null) $body .= ($canViewReports || $isClient) ? $subtotals[$cur_grouped_by]['cost'] : $subtotals[$cur_grouped_by]['expenses']; $body .= ''; } + if ($options['show_approved']) $body .= ''; if ($options['show_paid']) $body .= ''; if ($options['show_ip']) $body .= ''; if ($options['show_invoice']) $body .= ''; + if ($options['show_timesheet']) $body .= ''; $body .= ''; } @@ -981,9 +996,11 @@ static function prepareReportBody($options, $comment = null) $body .= ($canViewReports || $isClient) ? $totals['cost'] : $totals['expenses']; $body .= ''; } + if ($options['show_approved']) $body .= ''; if ($options['show_paid']) $body .= ''; if ($options['show_ip']) $body .= ''; if ($options['show_invoice']) $body .= ''; + if ($options['show_timesheet']) $body .= ''; $body .= ''; $body .= '
 Anuko Time Tracker 1.18.45.4784 | Copyright © Anuko | +  Anuko Time Tracker 1.18.45.4785 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9857411f4fd9eb9275d0df54565db6aa7edcd029 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 26 Feb 2019 23:34:09 +0000 Subject: [PATCH 0729/1848] Fixed emailed reports for approved and timesheet columns. --- WEB-INF/lib/ttReportHelper.class.php | 17 +++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 80ead68ed..c45548610 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -834,12 +834,16 @@ static function prepareReportBody($options, $comment = null) $body .= ''.$i18n->get('label.note').''.$i18n->get('label.cost').''.$i18n->get('label.approved').''.$i18n->get('label.paid').''.$i18n->get('label.ip').''.$i18n->get('label.invoice').''.$i18n->get('label.timesheet').'
 
'.htmlspecialchars($record['note']).''.$record['cost'].''; + $body .= $record['approved'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); + $body .= ''; $body .= $record['paid'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); @@ -928,6 +939,8 @@ static function prepareReportBody($options, $comment = null) } if ($options['show_invoice']) $body .= ''.htmlspecialchars($record['invoice']).''.htmlspecialchars($record['timesheet']).'
'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 39d8eb771..1bb542f21 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +
 Anuko Time Tracker 1.18.45.4785 | Copyright © Anuko | +  Anuko Time Tracker 1.18.45.4786 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From f42e768a0b39f5c375814bf9e3f36fb53563ecfd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 27 Feb 2019 00:59:55 +0000 Subject: [PATCH 0730/1848] Fixed adjusting users for clients in fav report emails. --- WEB-INF/lib/ttFavReportHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 694bb5947..8b9f4052e 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -448,8 +448,8 @@ static function adjustOptions($options) { $user_ids[] = $single_user['id']; } foreach ($users_to_adjust as $user_to_adjust) { - if (in_array($user_to_adjust['id'], $user_ids)) { - $adjusted_user_ids[] = $user_to_adjust['id']; + if (in_array($user_to_adjust, $user_ids)) { + $adjusted_user_ids[] = $user_to_adjust; } } $options['users'] = implode(',', $adjusted_user_ids); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1bb542f21..647512385 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - +
 Anuko Time Tracker 1.18.45.4786 | Copyright © Anuko | +  Anuko Time Tracker 1.18.45.4787 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From d4760fcf826cf3e528bd7a8f5301896d16da0266 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 27 Feb 2019 14:50:20 +0000 Subject: [PATCH 0731/1848] Fixed fav report export by adding missing fields. --- WEB-INF/lib/ttGroupExportHelper.class.php | 8 +++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 11104a5ff..06a3697d0 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -522,6 +522,10 @@ function writeData() { $fav_report_part .= " project_id=\"".$this->projectMap[$fav_report['project_id']]."\""; $fav_report_part .= " task_id=\"".$this->taskMap[$fav_report['task_id']]."\""; $fav_report_part .= " billable=\"".$fav_report['billable']."\""; + $fav_report_part .= " approved=\"".$fav_report['approved']."\""; + $fav_report_part .= " invoice=\"".$fav_report['invoice']."\""; + $fav_report_part .= " timesheet=\"".$fav_report['timesheet']."\""; + $fav_report_part .= " paid_status=\"".$fav_report['paid_status']."\""; $fav_report_part .= " users=\"".$user_list."\""; $fav_report_part .= " period=\"".$fav_report['period']."\""; $fav_report_part .= " period_start=\"".$fav_report['period_start']."\""; @@ -531,18 +535,20 @@ function writeData() { $fav_report_part .= " show_paid=\"".$fav_report['show_paid']."\""; $fav_report_part .= " show_ip=\"".$fav_report['show_ip']."\""; $fav_report_part .= " show_project=\"".$fav_report['show_project']."\""; + $fav_report_part .= " show_timesheet=\"".$fav_report['show_timesheet']."\""; $fav_report_part .= " show_start=\"".$fav_report['show_start']."\""; $fav_report_part .= " show_duration=\"".$fav_report['show_duration']."\""; $fav_report_part .= " show_cost=\"".$fav_report['show_cost']."\""; $fav_report_part .= " show_task=\"".$fav_report['show_task']."\""; $fav_report_part .= " show_end=\"".$fav_report['show_end']."\""; $fav_report_part .= " show_note=\"".$fav_report['show_note']."\""; + $fav_report_part .= " show_approved=\"".$fav_report['show_approved']."\""; + $fav_report_part .= " show_totals_only=\"".$fav_report['show_totals_only']."\""; $fav_report_part .= " show_custom_field_1=\"".$fav_report['show_custom_field_1']."\""; $fav_report_part .= " show_work_units=\"".$fav_report['show_work_units']."\""; $fav_report_part .= " group_by1=\"".$fav_report['group_by1']."\""; $fav_report_part .= " group_by2=\"".$fav_report['group_by2']."\""; $fav_report_part .= " group_by3=\"".$fav_report['group_by3']."\""; - $fav_report_part .= " show_totals_only=\"".$fav_report['show_totals_only']."\""; $fav_report_part .= ">\n"; fwrite($this->file, $fav_report_part); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 647512385..e8eb58ebc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {foreach $time_records as $record} - + {if $show_client} diff --git a/initialize.php b/initialize.php index dc0c35452..469d92a7b 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5533"); +define("APP_VERSION", "1.19.28.5534"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/week_old.php b/week_old.php deleted file mode 100644 index 01597704d..000000000 --- a/week_old.php +++ /dev/null @@ -1,555 +0,0 @@ -isPluginEnabled('wv')) { - header('Location: feature_disabled.php'); - exit(); -} -if ($user->behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. - exit(); -} -if ($request->isPost()) { - $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { - header('Location: access_denied.php'); // User changed, but no right or wrong user id. - exit(); - } -} -// End of access checks. - -// Determine user for whom we display this page. -if ($request->isPost() && $userChanged) { - $user_id = (int)$request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -$group_id = $user->getGroup(); - -$showClient = $user->isPluginEnabled('cl'); -$showBillable = $user->isPluginEnabled('iv'); -$trackingMode = $user->getTrackingMode(); -$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; -$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; -if ($showTask) $taskRequired = $user->getConfigOption('task_required'); -$showWeekNote = $user->isOptionEnabled('week_note'); -$showWeekNotes = $user->isOptionEnabled('week_notes'); -$recordType = $user->getRecordType(); -$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; -$showFiles = $user->isPluginEnabled('at'); - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; - -// Determine selected week start and end dates. -$weekStartDay = $user->getWeekStart(); -$t_arr = localtime($selected_date->getTimestamp()); -$t_arr[5] = $t_arr[5] + 1900; -if ($t_arr[6] < $weekStartDay) - $startWeekBias = $weekStartDay - 7; -else - $startWeekBias = $weekStartDay; -$startDate = new DateAndTime(); -$startDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+$startWeekBias,$t_arr[5])); -$endDate = new DateAndTime(); -$endDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+6+$startWeekBias,$t_arr[5])); -// The above is needed to set date range (timestring) in page title. - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -// Use Monthly Quotas plugin, if applicable. -if ($user->isPluginEnabled('mq')){ - require_once('plugins/MonthlyQuota.class.php'); - $quota = new MonthlyQuota(); - $month_quota_minutes = $quota->getUserQuota($selected_date->mYear, $selected_date->mMonth); - $month_total = ttTimeHelper::getTimeForMonth($selected_date); - $minutes_left = $month_quota_minutes - ttTimeHelper::toMinutes($month_total); - - $smarty->assign('month_total', $month_total); - $smarty->assign('over_quota', $minutes_left < 0); - $smarty->assign('quota_remaining', ttTimeHelper::toAbsDuration($minutes_left)); -} - -// Initialize variables. -$cl_billable = 1; -if ($showBillable) { - if ($request->isPost()) { - $cl_billable = $request->getParameter('billable'); - $_SESSION['billable'] = (int) $cl_billable; - } else - if (isset($_SESSION['billable'])) - $cl_billable = $_SESSION['billable']; -} -$cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); -$_SESSION['client'] = $cl_client; -$cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); -$_SESSION['project'] = $cl_project; -$cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); -$_SESSION['task'] = $cl_task; -$cl_note = $request->getParameter('note', ($request->isPost() ? null : @$_SESSION['note'])); -$_SESSION['note'] = $cl_note; - -$timeCustomFields = array(); -// If we have time custom fields - collect input. -if ($request->isPost()) { - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($request->getParameter($control_name))); - } - } -} - -// Get the data we need to display week view. -// Get column headers, which are day numbers in month. -$dayHeaders = ttWeekViewHelper::getDayHeadersForWeek($startDate->toString(DB_DATEFORMAT)); -$lockedDays = ttWeekViewHelper::getLockedDaysForWeek($startDate->toString(DB_DATEFORMAT)); -// Get already existing records. -$records = ttWeekViewHelper::getRecordsForInterval($startDate->toString(DB_DATEFORMAT), $endDate->toString(DB_DATEFORMAT), $showFiles); -// Build data array for the table. Format is described in ttWeekViewHelper::getDataForWeekView function. -if ($records) - $dataArray = ttWeekViewHelper::getDataForWeekView($records, $dayHeaders); -else - $dataArray = ttWeekViewHelper::prePopulateFromPastWeeks($startDate->toString(DB_DATEFORMAT), $dayHeaders); - -// Build day totals (total durations for each day in week). -$dayTotals = ttWeekViewHelper::getDayTotals($dataArray, $dayHeaders); - -// Define rendering class for a label field to the left of durations. -class LabelCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - global $user; - $showNotes = $user->isOptionEnabled('week_notes'); - - $this->setOptions(array('width'=>200,'valign'=>'middle')); - - // Special handling for a new week entry (row 0, or 0 and 1 if we show notes). - if (0 == $row) { - $this->setOptions(array('style'=>'text-align: center; font-weight: bold; vertical-align: top;')); - } else if ($showNotes && (1 == $row)) { - $this->setOptions(array('style'=>'text-align: right; vertical-align: top;')); - } else if ($showNotes && (0 != $row % 2)) { - $this->setOptions(array('style'=>'text-align: right;')); - } - // Special handling for not billable entries. - $ignoreRow = $showNotes ? 1 : 0; - if ($row > $ignoreRow) { - $row_id = $table->getValueAtName($row,'row_id'); - $billable = ttWeekViewHelper::parseFromWeekViewRow($row_id, 'bl'); - if (!$billable) { - if (($showNotes && (0 == $row % 2)) || !$showNotes) { - $this->setOptions(array('style'=>'color: red;')); // TODO: style it properly in CSS. - } - } - } - $this->setValue(htmlspecialchars($value)); // This escapes HTML for output. - return $this->toString(); - } -} - -// Define rendering class for a single cell for a time or a comment entry in week view table. -class WeekViewCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - global $user; - $showNotes = $user->isOptionEnabled('week_notes'); - - $field_name = $table->getValueAt($row,$column)['control_id']; // Our text field names (and ids) are like x_y (row_column). - $field = new TextField($field_name); - // Disable control if the date is locked. - global $lockedDays; - if ($lockedDays[$column-1]) - $field->setEnabled(false); - $field->setFormName($table->getFormName()); - $field->setStyle('width: 60px;'); // TODO: need to style everything properly, eventually. - // Provide visual separation for new entry row. - $rowToSeparate = $showNotes ? 1 : 0; - if ($rowToSeparate == $row) { - $field->setStyle('width: 60px; margin-bottom: 40px'); - } - if ($showNotes) { - if (0 == $row % 2) { - $field->setValue($table->getValueAt($row,$column)['duration']); // Duration for even rows. - } else { - $field->setValue($table->getValueAt($row,$column)['note']); // Comment for odd rows. - $field->setTitle($table->getValueAt($row,$column)['note']); // Tooltip to help view the entire comment. - } - } else { - $field->setValue($table->getValueAt($row,$column)['duration']); - // $field->setTitle($table->getValueAt($row,$column)['note']); // Tooltip to see comment. TODO - value not available. - } - // Disable control when time entry mode is TYPE_START_FINISH and there is no value in control - // because we can't supply start and finish times in week view - there are no fields for them. - if (!$field->getValue() && TYPE_START_FINISH == $user->getRecordType()) { - $field->setEnabled(false); - } - $this->setValue($field->getHtml()); - return $this->toString(); - } -} - -// Elements of weekTimeForm. -$form = new Form('weekTimeForm'); - -if ($user->can('track_time')) { - $rank = $user->getMaxRankForGroup($group_id); - if ($user->can('track_own_time')) - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); - if (count($user_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'document.weekTimeForm.user_changed.value=1;document.weekTimeForm.submit();', - 'name'=>'user', - 'style'=>'width: 250px;', - 'value'=>$user_id, - 'data'=>$user_list, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $smarty->assign('user_dropdown', 1); - } -} - -// Create week_durations table. -$table = new Table('week_durations'); -// $table->setCssClass('week_view_table'); // Currently not used. Fix this. -$table->setTableOptions(array('width'=>'100%','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('class'=>'tableHeaderCentered')); -$table->setData($dataArray); -// Add columns to table. -$table->addColumn(new TableColumn('label', '', new LabelCellRenderer(), $dayTotals['label'])); -for ($i = 0; $i < 7; $i++) { - $table->addColumn(new TableColumn($dayHeaders[$i], $dayHeaders[$i], new WeekViewCellRenderer(), $dayTotals[$dayHeaders[$i]])); -} -$table->setInteractive(false); -$form->addInputElement($table); - -// Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $trackingMode && $showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -// Billable checkbox. -if ($user->isPluginEnabled('iv')) - $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); - -// If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($timeField['id']), - 'value'=>$timeCustomFields[$timeField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -// If we show project dropdown, add controls for project and client. -if ($showProject) { - // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - if (is_array($projects_assigned_to_client) && is_array($projects_assigned_to_user)) - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} - -// Task dropdown. -if ($showTask) { - $task_list = ttGroupHelper::getActiveTasks(); - $form->addInput(array('type'=>'combobox', - 'name'=>'task', - 'style'=>'width: 250px;', - 'value'=>$cl_task, - 'data'=>$task_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); -} - -// Week note control. -if ($showWeekNote) { - if (!defined('NOTE_INPUT_HEIGHT')) - define('NOTE_INPUT_HEIGHT', 40); - $form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_note)); -} - -// Calendar. -$form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); - -// A hidden control for today's date from user's browser. -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'get_date()')); // User current date, which gets filled in on btn_submit click. - -// Submit button. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); - -// Submit. -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - // Validate user input for row 0. - // Determine if a new entry was posted. - $newEntryPosted = false; - foreach($dayHeaders as $dayHeader) { - $control_id = '0_'.$dayHeader; - if ($request->getParameter($control_id)) { - $newEntryPosted = true; - break; - } - } - if ($newEntryPosted) { - if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - // Validate input in time custom fields. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($timeCustomFields as $timeField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); - } - } - if ($showProject) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } - if ($showTask && $taskRequired) { - if (!$cl_task) $err->add($i18n->get('error.task')); - } - } - // Finished validating user input for row 0. - - // Process the table of values. - if ($err->no()) { - - // Obtain values. Iterate through posted parameters one by one, - // see if value changed, apply one change at a time until we see an error. - $result = true; - $rowNumber = 0; - // Iterate through existing rows. - foreach ($dataArray as $row) { - // Iterate through days. - foreach ($dayHeaders as $key => $dayHeader) { - // Do not process locked days. - if ($lockedDays[$key]) continue; - // Make control id for the cell. - $control_id = $rowNumber.'_'.$dayHeader; - - // Handle durations and comments in separate blocks of code. - if (!$showWeekNotes || (0 == $rowNumber % 2)) { - // Handle durations row here. - - // Obtain existing and posted durations. - $postedDuration = $request->getParameter($control_id); - $existingDuration = $dataArray[$rowNumber][$dayHeader]['duration']; - // If posted value is not null, check and normalize it. - if ($postedDuration) { - if (false === ttTimeHelper::postedDurationToMinutes($postedDuration)) { - $err->add($i18n->get('error.field'), $i18n->get('label.duration')); - $result = false; break; // Break out. Stop any further processing. - } else { - $minutes = ttTimeHelper::postedDurationToMinutes($postedDuration); - $postedDuration = ttTimeHelper::minutesToDuration($minutes); - } - } - // Do not process if value has not changed. - if ($postedDuration == $existingDuration) - continue; - // Posted value is different. - if ($existingDuration == null) { - // Skip inserting 0 duration values. - if (0 == ttTimeHelper::toMinutes($postedDuration)) - continue; - // Insert a new record. - $fields = array(); - $fields['row_id'] = $dataArray[$rowNumber]['row_id']; - if (!$fields['row_id']) { - // Special handling for row 0, a new entry. Need to construct new row_id. - $record = array(); - $record['client_id'] = $cl_client; - $record['billable'] = $cl_billable ? '1' : '0'; - $record['project_id'] = $cl_project; - $record['task_id'] = $cl_task; - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) - $record[$field_name] = $timeCustomFields[$timeField['id']]['value']; - else if ($timeField['type'] == CustomFields::TYPE_DROPDOWN) - $record[$field_name.'_option_id'] = $timeCustomFields[$timeField['id']]['value']; - } - } - $fields['row_id'] = ttWeekViewHelper::makeRowIdentifier($record).'_0'; - // Note: no need to check for a possible conflict with an already existing row - // because we are doing an insert that does not affect already existing data. - - if ($showWeekNote) { - $fields['note'] = $request->getParameter('note'); - } - } - $fields['day_header'] = $dayHeader; - $fields['start_date'] = $startDate->toString(DB_DATEFORMAT); // To be able to determine date for the entry using $dayHeader. - $fields['duration'] = $postedDuration; - $fields['browser_today'] = $request->getParameter('browser_today', null); - if ($showWeekNotes) { - // Take note value from the control below duration. - $noteRowNumber = $rowNumber + 1; - $note_control_id = $noteRowNumber.'_'.$dayHeader; - $fields['note'] = $request->getParameter($note_control_id); - } - $result = ttWeekViewHelper::insertDurationFromWeekView($fields, $custom_fields, $err); - } elseif ($postedDuration == null || 0 == ttTimeHelper::toMinutes($postedDuration)) { - // Delete an already existing record here. - $result = ttTimeHelper::delete($dataArray[$rowNumber][$dayHeader]['tt_log_id']); - } else { - $fields = array(); - $fields['tt_log_id'] = $dataArray[$rowNumber][$dayHeader]['tt_log_id']; - $fields['duration'] = $postedDuration; - $result = ttWeekViewHelper::modifyDurationFromWeekView($fields, $err); - } - if (!$result) break; // Break out of the loop in case of first error. - - } else if ($showWeekNotes) { - // Handle commments row here. - - // Obtain existing and posted comments. - $postedComment = $request->getParameter($control_id); - $existingComment = $dataArray[$rowNumber][$dayHeader]['note']; - // If posted value is not null, check it. - if ($postedComment && !ttValidString($postedComment, true)) { - $err->add($i18n->get('error.field'), $i18n->get('label.note')); - $result = false; break; // Break out. Stop any further processing. - } - // Do not process if value has not changed. - if ($postedComment == $existingComment) - continue; - - // Posted value is different. - // TODO: handle new entries separately in the durations block above. - - // Here, only update the comment on an already existing record. - $fields = array(); - $fields['tt_log_id'] = $dataArray[$rowNumber][$dayHeader]['tt_log_id']; - if ($fields['tt_log_id']) { - $fields['comment'] = $postedComment; - $result = ttWeekViewHelper::modifyCommentFromWeekView($fields); - } - if (!$result) break; // Break out of the loop on first error. - } - } - if (!$result) break; // Break out of the loop on first error. - $rowNumber++; - } - if ($result) { - header('Location: week.php'); // Normal exit. - exit(); - } - } - } -} // isPost - -$week_total = ttTimeHelper::getTimeForWeek($selected_date); - -$smarty->assign('selected_date', $selected_date); -$smarty->assign('week_total', $week_total); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="fillDropdowns()"'); -$smarty->assign('timestring', $startDate->toString($user->date_format).' - '.$endDate->toString($user->date_format)); -$smarty->assign('time_records', $records); -$smarty->assign('show_navigation', !$user->isOptionEnabled('week_menu')); -$smarty->assign('show_client', $showClient); -$smarty->assign('show_billable', $showBillable); -$smarty->assign('show_project', $showProject); -$smarty->assign('show_task', $showTask); -$smarty->assign('task_required', $taskRequired); -$smarty->assign('show_week_note', $showWeekNote); -$smarty->assign('show_week_list', $user->isOptionEnabled('week_list')); -$smarty->assign('show_start', $showStart); -$smarty->assign('show_files', $showFiles); -$smarty->assign('title', $i18n->get('menu.week')); -$smarty->assign('content_page_name', 'week.tpl'); -$smarty->display('index.tpl'); From 89db773dd2810bd5a52049e4c2908a6db4dd7636 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 May 2021 19:50:23 +0000 Subject: [PATCH 1549/1848] Addressed issue #110 for php8. --- WEB-INF/lib/form/DateField.class.php | 4 +++- initialize.php | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/form/DateField.class.php b/WEB-INF/lib/form/DateField.class.php index 01c14f2e6..f5d6f8f73 100644 --- a/WEB-INF/lib/form/DateField.class.php +++ b/WEB-INF/lib/form/DateField.class.php @@ -406,7 +406,9 @@ function adjustiFrame(pickerDiv, iFrameDiv) { $html .= " value=\"".htmlspecialchars($this->getValue())."\""; $html .= ">"; - $dir_name = trim(@constant('DIR_NAME'), '/'); + $dir_name = $app_root = ''; + if (defined('DIR_NAME')) + $dir_name = trim(constant('DIR_NAME'), '/'); if (!empty($dir_name)) $app_root = '/'.$dir_name; diff --git a/initialize.php b/initialize.php index 469d92a7b..7d469b378 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5534"); +define("APP_VERSION", "1.19.28.5535"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 6b8482702e23b70f3c54f476888b7efbc7bfee1e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 May 2021 20:21:07 +0000 Subject: [PATCH 1550/1848] Addressed a few more php8 warnings. --- WEB-INF/lib/ttTimeHelper.class.php | 4 +-- WEB-INF/lib/ttWeekViewHelper.class.php | 34 +++++--------------------- WEB-INF/templates/week2.tpl | 4 +-- initialize.php | 2 +- week.php | 11 ++++++--- 5 files changed, 18 insertions(+), 37 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 58f2f4222..031ccfb61 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -414,8 +414,8 @@ static function insert($fields) $org_id = $user->org_id; $date = $fields['date']; - $start = $fields['start']; - $finish = $fields['finish']; + $start = isset($fields['start']) ? $fields['start'] : null; + $finish = isset($fields['finish']) ? $fields['finish'] : null ; $duration = isset($fields['duration']) ? $fields['duration'] : null; if ($duration) { $minutes = ttTimeHelper::postedDurationToMinutes($duration); diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index aee8c8d61..55e40dc18 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -1,30 +1,6 @@ get('label.day_total').':'; - + foreach($dayHeaders as $dayHeader) { + $dayTotals[$dayHeader] = 0; + } foreach ($dataArray as $row) { foreach($dayHeaders as $dayHeader) { if (array_key_exists($dayHeader, $row)) { - $minutes = ttTimeHelper::toMinutes($row[$dayHeader]['duration']); + $minutes = ttTimeHelper::toMinutes(@$row[$dayHeader]['duration']); $dayTotals[$dayHeader] += $minutes; } } diff --git a/WEB-INF/templates/week2.tpl b/WEB-INF/templates/week2.tpl index 7dbf5d1f9..99da5ef47 100644 --- a/WEB-INF/templates/week2.tpl +++ b/WEB-INF/templates/week2.tpl @@ -148,14 +148,14 @@ function fillDropdowns() { {/if} {/if} mBgColor."\" onmouseover=\"setRowBackground(this, '".$this->mBgColorOver."')\" onmouseout=\"setRowBackground(this, null)\">\n"; - for ($col = 0; $col < $this->getColumnCount(); $col++) { - if (0 == $col && strtolower(get_class($this->mColumns[$col]->getRenderer())) == 'checkboxcellrenderer') { - // Checkbox for the row. Determine if selected. - $selected = false; - if (is_array($this->value)) { - foreach ($this->value as $p) { - if ($p == $this->mData[$row][$this->mKeyField]) { - $selected = true; - break; + if (is_array($this->mData)) { + for ($row = 0; $row < count($this->mData); $row++) { + $html .= "\nmBgColor."\" onmouseover=\"setRowBackground(this, '".$this->mBgColorOver."')\" onmouseout=\"setRowBackground(this, null)\">\n"; + for ($col = 0; $col < $this->getColumnCount(); $col++) { + if (0 == $col && strtolower(get_class($this->mColumns[$col]->getRenderer())) == 'checkboxcellrenderer') { + // Checkbox for the row. Determine if selected. + $selected = false; + if (is_array($this->value)) { + foreach ($this->value as $p) { + if ($p == $this->mData[$row][$this->mKeyField]) { + $selected = true; + break; + } } } + // Render control checkbox. + $html .= $this->mColumns[$col]->renderCell($this->mData[$row][$this->mKeyField], $row, $col, $selected); + } else { + // Render regular cell. + $html .= $this->mColumns[$col]->renderCell($this->getValueAt($row, $col), $row, $col); } - // Render control checkbox. - $html .= $this->mColumns[$col]->renderCell($this->mData[$row][$this->mKeyField], $row, $col, $selected); - } else { - // Render regular cell. - $html .= $this->mColumns[$col]->renderCell($this->getValueAt($row, $col), $row, $col); } + $html .= "\n"; } - $html .= "\n"; } // Print footers. diff --git a/initialize.php b/initialize.php index 69580f622..e219033d3 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5536"); +define("APP_VERSION", "1.19.28.5537"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_edit.php b/user_edit.php index dc19ad6aa..bae837c43 100644 --- a/user_edit.php +++ b/user_edit.php @@ -37,6 +37,7 @@ } $show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); +$projects = array(); if ($show_projects) { $projects = ttGroupHelper::getActiveProjects(); if (count($projects) == 0) $show_projects = false; From cc0928bf1d0b319a42359b44743d04eaaa0fdd05 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 13:20:39 +0000 Subject: [PATCH 1552/1848] Addressed a couple more of php8 issues. --- WEB-INF/lib/form/DateField.class.php | 28 ++-------------------------- initialize.php | 2 +- password_reset.php | 5 ++++- 3 files changed, 7 insertions(+), 28 deletions(-) diff --git a/WEB-INF/lib/form/DateField.class.php b/WEB-INF/lib/form/DateField.class.php index f5d6f8f73..922e8bf5e 100644 --- a/WEB-INF/lib/form/DateField.class.php +++ b/WEB-INF/lib/form/DateField.class.php @@ -1,30 +1,6 @@ setCharSet(CHARSET); $mailer->setSender(SENDER); $mailer->setReceiver("$receiver"); + $secure_connection = false; if ((!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] !== 'off')) || ($_SERVER['SERVER_PORT'] == 443)) $secure_connection = true; if($secure_connection) @@ -85,7 +86,9 @@ $cl_subject = $user_i18n->get('form.reset_password.email_subject'); - $dir_name = trim(@constant('DIR_NAME'), '/'); + $dir_name = $app_root = ''; + if (defined('DIR_NAME')) + $dir_name = trim(constant('DIR_NAME'), '/'); if (!empty($dir_name)) $app_root = '/'.$dir_name; From 8e469a82a605b16607d1deca358ba698db4bc165 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 13:46:44 +0000 Subject: [PATCH 1553/1848] Removed no longer used template files. --- WEB-INF/templates/header.tpl | 211 ------------------------ WEB-INF/templates/index.tpl | 5 - WEB-INF/templates/{ => work}/footer.tpl | 1 + WEB-INF/templates/work/index.tpl | 2 +- initialize.php | 2 +- 5 files changed, 3 insertions(+), 218 deletions(-) delete mode 100644 WEB-INF/templates/header.tpl delete mode 100644 WEB-INF/templates/index.tpl rename WEB-INF/templates/{ => work}/footer.tpl (99%) diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl deleted file mode 100644 index 29ec892d3..000000000 --- a/WEB-INF/templates/header.tpl +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - - -{if (isset($i18n.language.rtl) && $i18n.language.rtl)} - -{/if} -{if $user->getCustomCss()} - -{/if} - Time Tracker{if $title} - {$title}{/if} - - - - - - - -{assign var="tab_width" value="700"} - -
 Anuko Time Tracker 1.18.45.4787 | Copyright © Anuko | +  Anuko Time Tracker 1.18.45.4788 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 0b379eb7277555af8e7363bbe66b9e39c7b1d0e8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 27 Feb 2019 15:34:55 +0000 Subject: [PATCH 0732/1848] Fixed fav report import by including missing fields. --- WEB-INF/lib/ttOrgImportHelper.class.php | 20 ++++++++++++++------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index d7161d90a..43056bdfc 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -448,6 +448,10 @@ function startElement($parser, $name, $attrs) { 'project' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], 'task' => $this->currentGroupTaskMap[$attrs['TASK_ID']], 'billable' => $attrs['BILLABLE'], + 'approved' => $attrs['APPROVED'], + 'invoice' => $attrs['INVOICE'], + 'timesheet' => $attrs['TIMESHEET'], + 'paid_status' => $attrs['PAID_STATUS'], 'users' => $user_list, 'period' => $attrs['PERIOD'], 'from' => $attrs['PERIOD_START'], @@ -457,12 +461,14 @@ function startElement($parser, $name, $attrs) { 'chpaid' => (int) $attrs['SHOW_PAID'], 'chip' => (int) $attrs['SHOW_IP'], 'chproject' => (int) $attrs['SHOW_PROJECT'], + 'chtimesheet' => (int) $attrs['SHOW_TIMESHEET'], 'chstart' => (int) $attrs['SHOW_START'], 'chduration' => (int) $attrs['SHOW_DURATION'], 'chcost' => (int) $attrs['SHOW_COST'], 'chtask' => (int) $attrs['SHOW_TASK'], 'chfinish' => (int) $attrs['SHOW_END'], 'chnote' => (int) $attrs['SHOW_NOTE'], + 'chapproved' => (int) $attrs['SHOW_APPROVED'], 'chcf_1' => (int) $attrs['SHOW_CUSTOM_FIELD_1'], 'chunits' => (int) $attrs['SHOW_WORK_UNITS'], 'group_by1' => $attrs['GROUP_BY1'], @@ -995,22 +1001,24 @@ private function insertFavReport($fields) { $sql = "insert into tt_fav_reports". " (name, user_id, group_id, org_id, client_id, cf_1_option_id, project_id, task_id,". - " billable, invoice, paid_status, users, period, period_start, period_end,". + " billable, approved, invoice, timesheet, paid_status, users, period, period_start, period_end,". " show_client, show_invoice, show_paid, show_ip,". - " show_project, show_start, show_duration, show_cost,". - " show_task, show_end, show_note, show_custom_field_1, show_work_units,". + " show_project, show_timesheet, show_start, show_duration, show_cost,". + " show_task, show_end, show_note, show_approved, show_custom_field_1, show_work_units,". " group_by1, group_by2, group_by3, show_totals_only)". " values(". $mdb2->quote($fields['name']).", ".$fields['user_id'].", $group_id, $org_id, ". $mdb2->quote($fields['client']).", ".$mdb2->quote($fields['option']).", ". $mdb2->quote($fields['project']).", ".$mdb2->quote($fields['task']).", ". - $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['invoice']).", ". + $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['approved']).", ". + $mdb2->quote($fields['invoice']).", ".$mdb2->quote($fields['timesheet']).", ". $mdb2->quote($fields['paid_status']).", ". $mdb2->quote($fields['users']).", ".$mdb2->quote($fields['period']).", ". $mdb2->quote($fields['from']).", ".$mdb2->quote($fields['to']).", ". $fields['chclient'].", ".$fields['chinvoice'].", ".$fields['chpaid'].", ".$fields['chip'].", ". - $fields['chproject'].", ".$fields['chstart'].", ".$fields['chduration'].", ".$fields['chcost'].", ". - $fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ".$fields['chcf_1'].", ".$fields['chunits'].", ". + $fields['chproject'].", ".$fields['chtimesheet'].", ".$fields['chstart'].", ".$fields['chduration'].", ". + $fields['chcost'].", ".$fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ". + $fields['chapproved'].", ".$fields['chcf_1'].", ".$fields['chunits'].", ". $mdb2->quote($fields['group_by1']).", ".$mdb2->quote($fields['group_by2']).", ". $mdb2->quote($fields['group_by3']).", ".$fields['chtotalsonly'].")"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e8eb58ebc..a9861f6ab 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.45.4788 | Copyright © Anuko | +  Anuko Time Tracker 1.18.45.4789 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 14a6ab5e563acb66d090c6c291b5d51b1a31fae7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 27 Feb 2019 19:42:10 +0000 Subject: [PATCH 0733/1848] Started redesign of timesheets feature. --- WEB-INF/lib/ttRoleHelper.class.php | 2 +- WEB-INF/lib/ttTimesheetHelper.class.php | 15 ++++----------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- WEB-INF/templates/timesheet_add.tpl | 8 ++++++++ dbinstall.php | 10 ++++++---- mysql.sql | 4 ++-- reports.php | 6 ++---- timesheet_add.php | 4 ++++ timesheet_view.php | 2 +- timesheets.php | 4 ++-- 11 files changed, 32 insertions(+), 27 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index c45d4d3f9..c03368f9b 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -189,7 +189,7 @@ static function createPredefinedRoles($group_id, $lang) $mdb2 = getConnection(); - $rights_client = 'view_client_reports,view_client_timesheets,view_client_invoices,manage_own_settings'; + $rights_client = 'view_client_reports,view_client_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 058326574..636504e30 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -285,17 +285,10 @@ static function isUserValid($user_id) { global $user; - // Step 1. - // A client must have view_client_timesheets and - // aser must be assigned to one of client projects. - if ($user->isClient()) { - if (!$user->can('view_client_timesheets')) - return false; - $valid_users = ttGroupHelper::getUsersForClient($user->client_id); - $v = 2; - } - - return true; + // TODO: we are currently re-designing timesheets. + // Clients are not supposed to view them at all. + // And the post will change on_behalf user, to keep things consistent. + return false; } // getReportOptions prepares $options array to be used with ttReportHelper diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a9861f6ab..25f41decf 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + + + + + diff --git a/dbinstall.php b/dbinstall.php index d7f90cb82..09d552920 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11845"]) { + if ($_POST["convert11797to11846"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1100,6 +1100,8 @@ function ttExecute($sql) { ttExecute("ALTER TABLE `tt_fav_reports` ADD `show_timesheet` tinyint(4) NOT NULL default 0 AFTER `show_project`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `show_approved` tinyint(4) NOT NULL default 0 AFTER `show_note`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.45', modified = now() where param_name = 'version_db' and param_value = '1.18.44'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.45') set rights = replace(rights, 'view_client_timesheets,', '')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.46', modified = now() where param_name = 'version_db' and param_value = '1.18.45'"); } if ($_POST["cleanup"]) { @@ -1148,7 +1150,7 @@ function ttExecute($sql) {

DB Install

 Anuko Time Tracker 1.18.45.4789 | Copyright © Anuko | +  Anuko Time Tracker 1.18.46.4790 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 385f8a85b..a89d60f81 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -115,7 +115,7 @@ {if $user->exists() && ($user->can('view_own_reports') || $user->can('view_reports') || $user->can('view_all_reports') || $user->can('view_client_reports'))} {if !$user->isClient()}·{/if} {$i18n.menu.reports} {/if} - {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets') || $user->can('view_client_timesheets'))} + {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets'))} · {$i18n.menu.timesheets} {/if} {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->can('view_client_invoices'))} diff --git a/WEB-INF/templates/timesheet_add.tpl b/WEB-INF/templates/timesheet_add.tpl index b475af0ea..e24a36b36 100644 --- a/WEB-INF/templates/timesheet_add.tpl +++ b/WEB-INF/templates/timesheet_add.tpl @@ -7,6 +7,14 @@ {$i18n.label.thing_name} (*): {$forms.timesheetForm.timesheet_name.control}
{$i18n.label.start_date} (*):{$forms.timesheetForm.start.control}
{$i18n.label.end_date} (*):{$forms.timesheetForm.finish.control}
{$i18n.label.comment}: {$forms.timesheetForm.submitter_comment.control}
-
Create database structure (v1.18.45) + Create database structure (v1.18.46)
(applies only to new installations, do not execute when updating)
@@ -1193,8 +1195,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.45)Update database structure (v1.17.97 to v1.18.46)
diff --git a/mysql.sql b/mysql.sql index 1747b590a..d6cb375ff 100644 --- a/mysql.sql +++ b/mysql.sql @@ -75,7 +75,7 @@ create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,view_client_unapproved,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,view_client_unapproved,delete_group'); # @@ -524,4 +524,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.45', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.46', now()); # TODO: change when structure changes. diff --git a/reports.php b/reports.php index 5700025c7..fc77e0910 100644 --- a/reports.php +++ b/reports.php @@ -193,8 +193,7 @@ // Add timesheet assignment selector. $showTimesheetDropdown = $user->isPluginEnabled('ts') && - ($user->can('view_own_timesheets') || $user->can('view_timesheets') || - $user->can('view_all_timesheets') || ($user->can('view_client_timesheets'))); + ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets')); if ($showTimesheetDropdown) { $form->addInput(array('type'=>'combobox', 'name'=>'timesheet', @@ -208,8 +207,7 @@ )); } $showTimesheetCheckbox = $user->isPluginEnabled('ts') && - ($user->can('view_own_timesheets') || $user->can('view_timesheets') || - $user->can('view_all_timesheets') || $user->can('view_client_timesheets')); + ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets')); // Add user table. $showUsers = $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient(); diff --git a/timesheet_add.php b/timesheet_add.php index 9e6b9acd0..1ab4b704c 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -52,6 +52,10 @@ $form = new Form('timesheetForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'timesheet_name','style'=>'width: 250px;','value'=>$cl_name)); + +$form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start','value'=>$cl_start)); +$form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'finish','value'=>$cl_finish)); + $form->addInput(array('type'=>'textarea','name'=>'submitter_comment','style'=>'width: 250px; height: 40px;','value'=>$cl_comment)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); diff --git a/timesheet_view.php b/timesheet_view.php index 27956c9d7..e86b2df77 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -30,7 +30,7 @@ import('ttTimesheetHelper'); // Access checks. -if (!(ttAccessAllowed('view_own_timesheets') || ttAccessAllowed('view_timesheets') || ttAccessAllowed('view_all_timesheets') || ttAccessAllowed('view_client_timesheets'))) { +if (!(ttAccessAllowed('view_own_timesheets') || ttAccessAllowed('view_timesheets') || ttAccessAllowed('view_all_timesheets'))) { header('Location: access_denied.php'); exit(); } diff --git a/timesheets.php b/timesheets.php index 672e85974..546a7b638 100644 --- a/timesheets.php +++ b/timesheets.php @@ -32,7 +32,7 @@ import('ttTimesheetHelper'); // Access checks. -if (!(ttAccessAllowed('view_own_timesheets') || ttAccessAllowed('view_timesheets') || ttAccessAllowed('view_all_timesheets') || ttAccessAllowed('view_client_timesheets'))) { +if (!(ttAccessAllowed('view_own_timesheets') || ttAccessAllowed('view_timesheets') || ttAccessAllowed('view_all_timesheets'))) { header('Location: access_denied.php'); exit(); } @@ -71,7 +71,7 @@ // Elements of timesheetsForm. $form = new Form('timesheetsForm'); -if ($user->can('view_timesheets') || $user->can('view_all_timesheets') || $user->can('view_client_timesheets')) { +if ($user->can('view_timesheets') || $user->can('view_all_timesheets')) { // Prepare user list for dropdown. if ($notClient) { $rank = $user->can('view_all_timesheets') ? MAX_RANK : $user->getMaxRankForGroup($group_id); From 88bd95ec82e6b715f84b6bd09c04aebbdb4b5e4d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 27 Feb 2019 21:02:28 +0000 Subject: [PATCH 0734/1848] A bit of cleanup with ongoing timesheet redesign. --- WEB-INF/resources/ca.lang.php | 1 - WEB-INF/resources/cs.lang.php | 1 - WEB-INF/resources/da.lang.php | 1 - WEB-INF/resources/de.lang.php | 1 - WEB-INF/resources/en.lang.php | 1 - WEB-INF/resources/es.lang.php | 1 - WEB-INF/resources/et.lang.php | 1 - WEB-INF/resources/fa.lang.php | 1 - WEB-INF/resources/fi.lang.php | 1 - WEB-INF/resources/fr.lang.php | 1 - WEB-INF/resources/gr.lang.php | 1 - WEB-INF/resources/he.lang.php | 1 - WEB-INF/resources/hu.lang.php | 1 - WEB-INF/resources/it.lang.php | 1 - WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 1 - WEB-INF/resources/no.lang.php | 1 - WEB-INF/resources/pl.lang.php | 1 - WEB-INF/resources/pt-br.lang.php | 1 - WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 1 - WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 1 - WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 1 - WEB-INF/resources/sv.lang.php | 1 - WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 1 - WEB-INF/resources/zh-tw.lang.php | 1 - WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheets.tpl | 3 -- timesheets.php | 49 ++++++++++++-------------------- 33 files changed, 19 insertions(+), 65 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 293471700..d4d24c728 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -467,7 +467,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index c85cb6867..2ca15cc9a 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -477,7 +477,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 3dfb41c87..de4813f65 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -441,7 +441,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index c787f6d87..a14e34527 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -420,7 +420,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 5c91c3ee4..b6f0054b5 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -415,7 +415,6 @@ 'form.report.assign_to_invoice' => 'Assign to invoice', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php -'form.timesheets.hint' => 'Use reports to add new timesheets.', 'form.timesheets.active_timesheets' => 'Active Timesheets', 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index c86741762..99c4431da 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -480,7 +480,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 7f2fe8eb0..4f40c7e77 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -445,7 +445,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index fdbcdba5f..566b50811 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -461,7 +461,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index bc66a2264..226e8496d 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -446,7 +446,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 840f85590..a90cc042b 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -438,7 +438,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 2ebdaa8f3..7257a33f9 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -429,7 +429,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index cac16e9c5..47c06c859 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -468,7 +468,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index f4d5dd139..bd699aca0 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -470,7 +470,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 3d898e2f2..351c1cd66 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -442,7 +442,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 7f1a84119..53f1c5066 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -475,7 +475,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index c5b7e0a21..d8da0d813 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -473,7 +473,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 7307ec4a9..848e0f349 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -416,7 +416,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index a05071167..1474cac31 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -472,7 +472,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 28e8a0ace..94a094e8f 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -449,7 +449,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 74e5822f0..a10fe4c63 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -444,7 +444,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index e1e6b29d8..9da1e3588 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -451,7 +451,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index cf701cf63..70fc0ac19 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -475,7 +475,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 2fec5db79..6c1daa246 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -406,7 +406,6 @@ 'form.report.assign_to_invoice' => 'Включить в счёт', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php -'form.timesheets.hint' => 'Используйте отчёты для добавления новых табелей.', 'form.timesheets.active_timesheets' => 'Активные табели', 'form.timesheets.inactive_timesheets' => 'Неактивные табели', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 08999f1de..a1253d9b3 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -458,7 +458,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 95d3f8587..68e2df6a8 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -449,7 +449,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 170e5409f..8976bda59 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -447,7 +447,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index be3f4f280..715481d3a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -445,7 +445,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index e30ddf06a..eb92614a9 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -486,7 +486,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 05fa7a88e..d31db3259 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -458,7 +458,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 760e9acfa..ca0dad53a 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -466,7 +466,6 @@ // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. -// form.timesheets.hint' => 'Use reports to add new timesheets.', // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 25f41decf..5b3b25e20 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/timesheet_add.php b/timesheet_add.php index 1ab4b704c..e8eb56591 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -43,31 +43,56 @@ if ($request->isPost()) { $cl_name = trim($request->getParameter('timesheet_name')); - $cl_comment = trim($request->getParameter('submitter_comment')); - - // Report settings are stored in session bean before we get here. - $bean = new ActionForm('reportBean', new Form('reportForm'), $request); - $bean->loadBean(); + $cl_client = $request->getParameter('client'); + $cl_project = $request->getParameter('project'); + $cl_start = $request->getParameter('start'); + $cl_finish = $request->getParameter('finish'); + $cl_comment = trim($request->getParameter('comment')); } +$user_id = $user->getUser(); + $form = new Form('timesheetForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'timesheet_name','style'=>'width: 250px;','value'=>$cl_name)); +// Dropdown for clients if the clients plugin is enabled. +$showClient = $user->isPluginEnabled('cl'); +if ($showClient) { + $clients = ttGroupHelper::getActiveClients(); + $form->addInput(array('type'=>'combobox','name'=>'client','style'=>'width: 250px;','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->get('dropdown.select')))); +} +// Dropdown for projects. +$showProject = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); +if ($showProject) { + $projects = $user->getAssignedProjects(); + $form->addInput(array('type'=>'combobox','name'=>'project','style'=>'width: 250px;','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_project,'empty'=>array(''=>$i18n->get('dropdown.all')))); +} $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start','value'=>$cl_start)); $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'finish','value'=>$cl_finish)); - -$form->addInput(array('type'=>'textarea','name'=>'submitter_comment','style'=>'width: 250px; height: 40px;','value'=>$cl_comment)); +$form->addInput(array('type'=>'textarea','name'=>'comment','style'=>'width: 250px; height: 40px;','value'=>$cl_comment)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidDate($cl_start)) $err->add($i18n->get('error.field'), $i18n->get('label.start_date')); + if (!ttValidDate($cl_finish)) $err->add($i18n->get('error.field'), $i18n->get('label.end_date')); if (!ttValidString($cl_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); + if ($err->no() && ttTimesheetHelper::getTimesheetByName($cl_name, $user_id)) $err->add($i18n->get('error.object_exists')); + $fields = array('user_id' => $user_id, + 'name' => $cl_name, + 'client_id' => $cl_client, + 'project_id' => $cl_project, + 'start_date' => $cl_start, + 'end_date' => $cl_finish, + 'comment' => $cl_comment); + if ($err->no() && !ttTimesheetHelper::timesheetItemsExist($fields)) $err->add($i18n->get('error.no_records')); + // Finished validating user input. + /* if ($err->no()) { - $user_id = $bean->getDetachedAttribute('timesheet_user_id'); - if (!ttTimesheetHelper::getTimesheetByName($cl_name, $user_id)) { - if (ttTimesheetHelper::insert(array('user_id' => $user_id, + // TODO: use $fields. + if (ttTimesheetHelper::insert(array('user_id' => $user_id, 'client_id' => $bean->getAttribute('client'), 'name' => $cl_name, 'comment' => $cl_comment))) { @@ -75,13 +100,13 @@ exit(); } else $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } + } */ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.timesheetForm.timesheet_name.focus()"'); +$smarty->assign('show_client', $showClient); +$smarty->assign('show_project', $showProject); $smarty->assign('title', $i18n->get('title.add_timesheet')); $smarty->assign('content_page_name', 'timesheet_add.tpl'); $smarty->display('index.tpl'); From 343dfea2506d317ae99b965667e1b62ea4d83480 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 28 Feb 2019 16:33:04 +0000 Subject: [PATCH 0736/1848] Coded ttTimesheetHelper::timesheetItemsExist(). --- WEB-INF/lib/ttTimesheetHelper.class.php | 56 +++++-------------------- WEB-INF/templates/footer.tpl | 2 +- timesheet_add.php | 18 ++++---- 3 files changed, 18 insertions(+), 58 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index e14bbd7bf..2ba87abce 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -415,10 +415,12 @@ static function timesheetItemsExist($fields) { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; - $client_id = (int) $fields['client_id']; + if (isset($fields['client_id'])) $client_id = (int) $fields['client_id']; + if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; $start_date = new DateAndTime($user->date_format, $fields['start_date']); $start = $start_date->toString(DB_DATEFORMAT); @@ -426,34 +428,14 @@ static function timesheetItemsExist($fields) { $end_date = new DateAndTime($user->date_format, $fields['end_date']); $end = $end_date->toString(DB_DATEFORMAT); - if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; + // sql parts. + if ($client_id) $client_part = " and client_id = $client_id"; + if ($project_id) $project_part = " and project_id = $project_id"; - // Our query is different depending on tracking mode. - if (MODE_TIME == $user->getTrackingMode()) { - // In "time only" tracking mode there is a single user rate. - $sql = "select count(*) as num from tt_log l, tt_users u". - " where l.status = 1 and l.client_id = $client_id and l.invoice_id is null". - " and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end). - " and l.user_id = u.id and l.group_id = $group_id and l.org_id = $org_id". - " and l.billable = 1"; // l.billable * u.rate * time_to_sec(l.duration)/3600 > 0 // See explanation below. - } else { - // sql part for project id. - if ($project_id) $project_part = " and l.project_id = $project_id"; - - // When we have projects, rates are defined for each project in tt_user_project_binds table. - $sql = "select count(*) as num from tt_log l, tt_user_project_binds upb". - " where l.status = 1 and l.client_id = $client_id $project_part and l.invoice_id is null". - " and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end). - " and l.group_id = $group_id and l.org_id = $org_id". - " and upb.user_id = l.user_id and upb.project_id = l.project_id". - " and l.billable = 1"; // l.billable * upb.rate * time_to_sec(l.duration)/3600 > 0 - // Users with a lot of clients and projects (Jaro) may forget to set user rates properly. - // Specifically, user rate may be set to 0 on a project, by mistake. This leads to error.no_invoiceable_items - // and increased support cost. Commenting out allows us to include 0 cost items in invoices so that - // the problem becomes obvious. - - // TODO: If the above turns out useful, rework the query to simplify it by removing left join. - } + $sql = "select count(*) as num from tt_log". + " where status = 1 $client_part $project_part and timesheet_id is null". + " and date >= ".$mdb2->quote($start)." and date <= ".$mdb2->quote($end). + " and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -462,24 +444,6 @@ static function timesheetItemsExist($fields) { } } - if ($user->isPluginEnabled('ex')) { - // sql part for project id. - if ($project_id) $project_part = " and ei.project_id = $project_id"; - - $sql = "select count(*) as num from tt_expense_items ei". - " where ei.client_id = $client_id $project_part and ei.invoice_id is null". - " and ei.date >= ".$mdb2->quote($start)." and ei.date <= ".$mdb2->quote($end). - " and ei.group_id = $group_id and ei.org_id = $org_id". - " and ei.cost <> 0 and ei.status = 1"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - $val = $res->fetchRow(); - if ($val['num']) { - return true; - } - } - } - return false; } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a3dbfb192..ec180725a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.46.4790 | Copyright © Anuko | +  Anuko Time Tracker 1.18.46.4791 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index f9b89d792..af65d14b5 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -4,9 +4,6 @@ {$forms.timesheetsForm.open} -{if $not_client} - -{/if} {if $user_dropdown} {/if} diff --git a/timesheets.php b/timesheets.php index 546a7b638..cc43f0dd3 100644 --- a/timesheets.php +++ b/timesheets.php @@ -41,48 +41,38 @@ exit(); } if ($user->isClient()) { - $users_for_client = ttGroupHelper::getUsersForClient($user->client_id); - if (count($users_for_client) == 0) { - header('Location: access_denied.php'); // There are no users for client. - exit(); - } + header('Location: access_denied.php'); // No timesheets for clients. + exit(); } if ($request->isPost()) { - $userChanged = $request->getParameter('user_changed'); - if ($userChanged && !(ttTimesheetHelper::isUserValid($request->getParameter('user')))) { - header('Location: access_denied.php'); // Wrong user id. + $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('view_timesheets') && $user->isUserValid($request->getParameter('user')))) { + header('Location: access_denied.php'); // Group changed, but no rght or wrong user id. TODO: research relevance of this... exit(); } } // End of access checks. -// Determine user for whom we display this page. -$notClient = !$user->isClient(); +// Determine user for which we display this page. if ($request->isPost() && $userChanged) { $user_id = $request->getParameter('user'); + $user->setOnBehalfUser($user_id); } else { - if ($notClient) - $user_id = $user->getUser(); - else - $user_id = $users_for_client[0]['id']; // First found user for a client. + $user_id = $user->getUser(); } + $group_id = $user->getGroup(); // Elements of timesheetsForm. $form = new Form('timesheetsForm'); if ($user->can('view_timesheets') || $user->can('view_all_timesheets')) { - // Prepare user list for dropdown. - if ($notClient) { - $rank = $user->can('view_all_timesheets') ? MAX_RANK : $user->getMaxRankForGroup($group_id); - if ($user->can('view_own_timesheets')) - $options = array('max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('max_rank'=>$rank); - $user_list = $user->getUsers($options); - } else - $user_list = $users_for_client; // Obtained above. - + $rank = $user->getMaxRankForGroup($group_id); + if ($user->can('view_own_timesheets')) + $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); + else + $options = array('status'=>ACTIVE,'max_rank'=>$rank); + $user_list = $user->getUsers($options); if (count($user_list) >= 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'document.timesheetsForm.user_changed.value=1;document.timesheetsForm.submit();', @@ -97,17 +87,14 @@ } $active_timesheets = ttTimesheetHelper::getActiveTimesheets($user_id); -if ($notClient) - $inactive_timesheets = ttTimesheetHelper::getInactiveTimesheets($user_id); +$inactive_timesheets = ttTimesheetHelper::getInactiveTimesheets($user_id); -$showClient = $user->isPluginEnabled('cl') && $notClient; -$canEdit = $notClient && ($user->can('manage_own_timesheets') || - $user->can('manage_timesheets') || $user->can('manage_all_timesheets')); +$showClient = $user->isPluginEnabled('cl'); +$canEdit = $user->can('manage_own_timesheets') || $user->can('manage_timesheets') || $user->can('manage_all_timesheets'); $smarty->assign('active_timesheets', $active_timesheets); $smarty->assign('inactive_timesheets', $inactive_timesheets); $smarty->assign('show_client', $showClient); -$smarty->assign('not_client', $notClient); $smarty->assign('can_edit', $canEdit); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.timesheets')); From c6aa77a9e6299cf3103f97274e573cc9938c1215 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 28 Feb 2019 16:04:17 +0000 Subject: [PATCH 0735/1848] A bit more progress on timesheet coding. --- WEB-INF/lib/ttTimesheetHelper.class.php | 74 +++++++++++++++++++++++++ WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 + WEB-INF/resources/de.lang.php | 2 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 + WEB-INF/resources/fa.lang.php | 2 + WEB-INF/resources/fi.lang.php | 2 + WEB-INF/resources/fr.lang.php | 2 + WEB-INF/resources/gr.lang.php | 2 + WEB-INF/resources/he.lang.php | 2 + WEB-INF/resources/hu.lang.php | 2 + WEB-INF/resources/it.lang.php | 2 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 2 + WEB-INF/resources/pt-br.lang.php | 2 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 + WEB-INF/resources/sv.lang.php | 2 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_add.tpl | 14 ++++- WEB-INF/templates/timesheets.tpl | 24 +++----- timesheet_add.php | 51 ++++++++++++----- 35 files changed, 179 insertions(+), 32 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 636504e30..e14bbd7bf 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -408,4 +408,78 @@ static function disapproveTimesheet($fields) { // TODO: send email to submitter here... return true; } + + // The timesheetItemsExist determines whether tt_log records exist in the specified period + // for inclusion in a new timesheet. + static function timesheetItemsExist($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $client_id = (int) $fields['client_id']; + + $start_date = new DateAndTime($user->date_format, $fields['start_date']); + $start = $start_date->toString(DB_DATEFORMAT); + + $end_date = new DateAndTime($user->date_format, $fields['end_date']); + $end = $end_date->toString(DB_DATEFORMAT); + + if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; + + // Our query is different depending on tracking mode. + if (MODE_TIME == $user->getTrackingMode()) { + // In "time only" tracking mode there is a single user rate. + $sql = "select count(*) as num from tt_log l, tt_users u". + " where l.status = 1 and l.client_id = $client_id and l.invoice_id is null". + " and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end). + " and l.user_id = u.id and l.group_id = $group_id and l.org_id = $org_id". + " and l.billable = 1"; // l.billable * u.rate * time_to_sec(l.duration)/3600 > 0 // See explanation below. + } else { + // sql part for project id. + if ($project_id) $project_part = " and l.project_id = $project_id"; + + // When we have projects, rates are defined for each project in tt_user_project_binds table. + $sql = "select count(*) as num from tt_log l, tt_user_project_binds upb". + " where l.status = 1 and l.client_id = $client_id $project_part and l.invoice_id is null". + " and l.date >= ".$mdb2->quote($start)." and l.date <= ".$mdb2->quote($end). + " and l.group_id = $group_id and l.org_id = $org_id". + " and upb.user_id = l.user_id and upb.project_id = l.project_id". + " and l.billable = 1"; // l.billable * upb.rate * time_to_sec(l.duration)/3600 > 0 + // Users with a lot of clients and projects (Jaro) may forget to set user rates properly. + // Specifically, user rate may be set to 0 on a project, by mistake. This leads to error.no_invoiceable_items + // and increased support cost. Commenting out allows us to include 0 cost items in invoices so that + // the problem becomes obvious. + + // TODO: If the above turns out useful, rework the query to simplify it by removing left join. + } + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if ($val['num']) { + return true; + } + } + + if ($user->isPluginEnabled('ex')) { + // sql part for project id. + if ($project_id) $project_part = " and ei.project_id = $project_id"; + + $sql = "select count(*) as num from tt_expense_items ei". + " where ei.client_id = $client_id $project_part and ei.invoice_id is null". + " and ei.date >= ".$mdb2->quote($start)." and ei.date <= ".$mdb2->quote($end). + " and ei.group_id = $group_id and ei.org_id = $org_id". + " and ei.cost <> 0 and ei.status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if ($val['num']) { + return true; + } + } + } + + return false; + } } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index d4d24c728..34ba35f6e 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -103,6 +103,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', // 'error.no_login' => 'No user with this login.', 'error.no_groups' => 'La seva base de dades està buida. Iniciï sessió com a administrador i creï un nou grup.', 'error.upload' => 'Error pujant l\\\'arxiu.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 2ca15cc9a..e43d2cc0d 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -105,6 +105,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', // 'error.no_login' => 'No user with this login.', 'error.no_groups' => 'Vaše databáze je prázdná. Přihlašte se jako admin a vytvořte nový tým.', // TODO: replace "team" with "group". 'error.upload' => 'Chyba přenosu souboru.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index de4813f65..1247264e7 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -96,6 +96,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'Der er ingen fakturerbar emner.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Der finde ingen bruger med dette brugernavn.', 'error.no_groups' => 'Din database er tom, log ind som administrator og lav et nyt team.', // TODO: replace "team" with "group". 'error.upload' => 'Fil upload problem.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index a14e34527..72f4b5cb1 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -90,6 +90,8 @@ 'error.invoice_exists' => 'Rechnung mit dieser Nummer existiert bereits.', 'error.role_exists' => 'Rolle mit diesem Rang existiert bereits.', 'error.no_invoiceable_items' => 'Keine Einträge zur Rechnungsstellung gefunden.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Benutzer mit diesen Anmeldedaten nicht vorhanden.', 'error.no_groups' => 'Die Datenbank ist leer. Als Administrator anmelden und ein neues Gruppe erzeugen.', 'error.upload' => 'Fehler beim hochladen einer Datei.', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index b6f0054b5..6701a4c34 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -89,6 +89,7 @@ 'error.invoice_exists' => 'Invoice with this number already exists.', 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'There are no invoiceable items.', +'error.no_records' => 'There are no records.', 'error.no_login' => 'No user with this login.', 'error.no_groups' => 'Your database is empty. Login as admin and create a new group.', 'error.upload' => 'File upload error.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 99c4431da..7a2bf9a90 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -101,6 +101,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', // 'error.no_login' => 'No user with this login.', 'error.no_groups' => 'Su base de datos esta vacía. Inicie sesión como administrador y cree un nuevo grupo.', 'error.upload' => 'Error subiendo el archivo.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 4f40c7e77..6f37883ee 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -103,6 +103,8 @@ // Google auto-translates below as "No billable invoices found." which seems wrong. // 'error.no_invoiceable_items' => 'Arveldatavaid arveid ei leitud.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Sellise tunnusega kasutajat ei ole.', // TODO: Improve translation of error.no_groups. Replace meeskond with grupp? diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 566b50811..5a6c6aa8c 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -101,6 +101,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'آیتمی جهت فاکتور کردن وجود ندارد.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'کاربری با این نام کاربری موجود نیست.', 'error.no_groups' => 'پایگاه داده شما خالی است با کاربر admin وارد شوید و تیم ایجاد کنید.', // TODO: replace "team" with "group". 'error.upload' => 'خطا در آپلود فایل.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 226e8496d..9f577f3dc 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -98,6 +98,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'Ei laskutettavia syötteitä.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Tuntematon käyttäjänimi.', 'error.no_groups' => 'Tietokanta on tyhjä. Kirjaudu ylläpitäjänä ja luo uusi tiimi.', // TODO: replace "team" with "group". 'error.upload' => 'Virhe tiedoston lataus.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a90cc042b..be5c9d22b 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -96,6 +96,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'Il n\\\'y a pas d\\\'éléments à facturer.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Aucun utilisateur avec cet identifiant.', 'error.no_groups' => 'Votre base de données est vide. Connectez-vous comme administrateur et créez une nouvelle équipe.', // TODO: replace "team" with "group". 'error.upload' => 'Erreur de chargement du fichier.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 7257a33f9..288982735 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -91,6 +91,8 @@ 'error.invoice_exists' => 'Το τιμολόγιο με αυτόν τον αριθμό υπάρχει ήδη.', 'error.role_exists' => 'Ο ρόλος σε αυτή τη σειρά υπάρχει ήδη.', 'error.no_invoiceable_items' => 'Δεν υπάρχουν στοιχεία προς τιμολόγηση.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Δεν υπάρχει χρήστης με αυτά τα στοιχεία.', 'error.no_groups' => 'Η βάση δεδομένων σας είναι κενή. Συνδεθείτε ως διαχειριστής και δημιουργήστε μια νέα ομάδα.', 'error.upload' => 'Σφάλμα φόρτωσης αρχείου.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 47c06c859..d9ab0d1c6 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -112,6 +112,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'אין פריטים לחיוב', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'משתמש זה אינו קיים', 'error.no_groups' => 'בסיס הנתונים שלך ריק. התחבר כמנהל וצור צוות חדש', // TODO: replace "team" with "group". 'error.upload' => 'שגיאה בהעלת קובץ', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index bd699aca0..38ec28cb7 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -103,6 +103,8 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', // 'error.no_login' => 'No user with this login.', // 'error.no_groups' => 'Your database is empty. Login as admin and create a new group.', 'error.upload' => 'File feltöltési hiba.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 351c1cd66..e4d328e61 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -95,6 +95,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'Non ci sono voci fatturabili.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Non esiste un utente con questo username.', 'error.no_groups' => 'Il database è vuoto. Loggati come amministratore e crea un nuovo gruppo.', 'error.upload' => 'Errore di caricamento file.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 53f1c5066..3f0db6e0e 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -104,6 +104,7 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'このログインと関連されたユーザーはいません。', 'error.no_groups' => 'あなたのデータベースは空いています。管理者にログインして新規チームを作成してください。', // TODO: replace "team" with "group". 'error.upload' => 'ファイルのアップロードのエラー。', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index d8da0d813..d59c16347 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -103,6 +103,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', 'error.no_login' => '본 로그인과 연계된 사용자가 없습니다.', 'error.no_groups' => '당신의 데이터베이스는 비어있습니다. 관리자로 로그인하여 새로운 팀을 생성하십시오.', // TODO: replace "team" with "group". 'error.upload' => '파일 업로드 오류.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 848e0f349..8aa557e67 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -89,6 +89,8 @@ 'error.invoice_exists' => 'Dit nummer is al eens toegekend aan een factuur.', 'error.role_exists' => 'Een rol met deze rangorde bestaat al.', 'error.no_invoiceable_items' => 'Er zijn geen factuureerbare onderdelen.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Een medewerker met deze inlognaam bestaat niet.', 'error.no_groups' => 'Uw database is leeg. Meld je aan als admin en maak een nieuw groep.', 'error.upload' => 'Fout bij het uploaden van het bestand.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 1474cac31..cdcc05de1 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -104,6 +104,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Det er ingen bruker med dette brukernavnet.', 'error.no_groups' => 'Databasen din er tom. Logg inn som admin og opprett et nytt team.', // TODO: replace "team" with "group". 'error.upload' => 'Feil med lasting av fil.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 94a094e8f..11166236b 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -99,6 +99,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'Brak przedmiotów do faktury.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Użytkownik o takiej nazwie nie istnieje.', 'error.no_groups' => 'Twoja baza danych jest pusta. Zaloguj się jako administrator i stwórz nowy zespół.', // TODO: replace "team" with "group". 'error.upload' => 'Błąd podczas wysyłania pliku.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index a10fe4c63..bfeb7e720 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -97,6 +97,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'Não há items faturáveis.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Não há usuário com este login.', 'error.no_groups' => 'Sua base de dados está vazia. Entre como admin e crie uma equipe nova.', // TODO: replace "team" with "group". 'error.upload' => 'Erro no envio do arquivo.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9da1e3588..b9b746c9d 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -101,6 +101,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', // 'error.no_login' => 'No user with this login.', // 'error.no_groups' => 'Your database is empty. Login as admin and create a new group.', // 'error.upload' => 'File upload error.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 70fc0ac19..050bddef1 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -107,6 +107,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', // 'error.no_login' => 'No user with this login.', 'error.no_groups' => 'Baza de date este goala. Intra ca admin si adauga o noua echipa.', // TODO: replace "team" with "group". 'error.upload' => 'Eroare la upload-ul fisierului.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 6c1daa246..2d04e8f93 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -88,6 +88,7 @@ 'error.invoice_exists' => 'Счёт с таким номером уже есть.', 'error.role_exists' => 'Роль с таким рангом уже есть.', 'error.no_invoiceable_items' => 'Нет записей для включения в счёт.', +'error.no_records' => 'Нет записей.', 'error.no_login' => 'Нет пользователя с таким логином.', 'error.no_groups' => 'Ваша база данных пуста. Войдите в систему как администратор и создайте новую группу.', 'error.upload' => 'Ошибка загрузки файла.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index a1253d9b3..0ed070293 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -101,6 +101,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'Neexistujú položky, ktoré by bolo možné fakturovať.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Neexistuje používateľ s týmto prihlasovacím menom.', 'error.no_groups' => 'Vaša databáza je prázdna. Prihláste sa ako admin a vytvorte nový tím.', // TODO: replace "team" with "group". 'error.upload' => 'Prenos súboru bol neúspešný.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 68e2df6a8..e93884505 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -98,6 +98,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', // 'error.no_login' => 'No user with this login.', // 'error.no_groups' => 'Your database is empty. Login as admin and create a new group.', // 'error.upload' => 'File upload error.', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 8976bda59..5d2b9f88a 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -96,6 +96,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'Nema stavke za naplatu.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Nema korisnika pod ovom prijavom', 'error.no_groups' => 'Vaša baza podataka je prazna. Prijavite se kao administrator i napravite novi tim.', // TODO: replace "team" with "group". 'error.upload' => 'Greška pri otpremanju podatka.', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 715481d3a..ba2f6665f 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -95,6 +95,8 @@ // TODO: translate the following. // 'error.role_exists' => 'Role with this rank already exists.', 'error.no_invoiceable_items' => 'Det finns inga debiterbara tidsregistreringar.', +// TODO: translate the following. +// 'error.no_records' => 'There are no records.', 'error.no_login' => 'Det finns ingen användare med det här användarnamnet.', 'error.no_groups' => 'Databasen är tom. Logga in som administratör och skapa en ny grupp.', 'error.upload' => 'Ett fel uppstod när filen laddades upp.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index eb92614a9..22e872374 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -110,6 +110,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', // 'error.no_login' => 'No user with this login.', 'error.no_groups' => 'Veritabanınız boş. Yeni bir ekip yaratmak için yönetici olarak giriş yapın.', // TODO: replace "team" with "group". 'error.upload' => 'Dosya yükleme hatası.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index d31db3259..a1583eb4a 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -97,6 +97,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', 'error.no_login' => '没有该登录信息的用户。', 'error.no_groups' => '您的数据库没有任何记录。请以管理员身份登录并创建一个新团队。', // TODO: replace "team" with "group". 'error.upload' => '上传文件出错。', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index ca0dad53a..42f152029 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -101,6 +101,7 @@ // 'error.invoice_exists' => 'Invoice with this number already exists.', // 'error.role_exists' => 'Role with this rank already exists.', // 'error.no_invoiceable_items' => 'There are no invoiceable items.', +// 'error.no_records' => 'There are no records.', 'error.no_login' => '沒有該登錄資訊的使用者。', 'error.no_groups' => '您的資料庫沒有任何記錄。請以管理員身份登錄並創建一個新團隊。', // TODO: replace "team" with "group". 'error.upload' => '上傳文件出錯。', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5b3b25e20..a3dbfb192 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.timesheets.hint}
{$i18n.label.user}: {$forms.timesheetsForm.user.control}
- +{if $show_client} + + + + +{/if} +{if $show_project} + + + + +{/if} @@ -17,7 +29,7 @@ - + diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index af65d14b5..df4782b64 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -18,10 +18,8 @@ {if $show_client} {/if} -{if $not_client} -{/if} {if $can_edit} @@ -33,13 +31,11 @@ {if $show_client} {/if} - {if $not_client} - {if $timesheet.approval_status == null} + {if $timesheet.approval_status == null} - {else} + {else} - {/if} {/if} {if $can_edit} @@ -48,11 +44,10 @@ {/foreach}
 Anuko Time Tracker 1.18.46.4791 | Copyright © Anuko | +  Anuko Time Tracker 1.18.46.4792 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_add.tpl b/WEB-INF/templates/timesheet_add.tpl index e24a36b36..f4becf7f5 100644 --- a/WEB-INF/templates/timesheet_add.tpl +++ b/WEB-INF/templates/timesheet_add.tpl @@ -7,6 +7,18 @@ {$i18n.label.thing_name} (*): {$forms.timesheetForm.timesheet_name.control}
{$i18n.label.client}:{$forms.timesheetForm.client.control}
{$i18n.label.project}:{$forms.timesheetForm.project.control}
{$i18n.label.start_date} (*): {$forms.timesheetForm.start.control}
{$i18n.label.comment}:{$forms.timesheetForm.submitter_comment.control}{$forms.timesheetForm.comment.control}
{$i18n.label.client}{$i18n.label.submitted} {$i18n.label.approved}{$i18n.label.view}{$i18n.label.edit}{$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}
-{if $not_client} + - +


-{/if} {if $inactive_timesheets} @@ -63,10 +58,8 @@ {if $show_client} {/if} - {if $not_client} - {/if} {if $can_edit} @@ -78,13 +71,11 @@ {if $show_client} {/if} - {if $not_client} - {if $timesheet.approval_status == null} + {if $timesheet.approval_status == null} - {else} + {else} - {/if} {/if} {if $can_edit} @@ -93,11 +84,10 @@ {/foreach}
{$i18n.label.client}{$i18n.label.submitted} {$i18n.label.approved}{$i18n.label.view}{$i18n.label.edit}{$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}
- {if $not_client} +

- {/if} {/if}
- - {if $can_edit} - {/if} {foreach $inactive_timesheets as $timesheet} @@ -78,9 +72,7 @@ {/if} - {if $can_edit} - {/if} {/foreach}
 Anuko Time Tracker 1.18.46.4792 | Copyright © Anuko | +  Anuko Time Tracker 1.18.46.4793 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_add.php b/timesheet_add.php index e8eb56591..4dd1afaea 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -89,18 +89,14 @@ if ($err->no() && !ttTimesheetHelper::timesheetItemsExist($fields)) $err->add($i18n->get('error.no_records')); // Finished validating user input. - /* if ($err->no()) { - // TODO: use $fields. - if (ttTimesheetHelper::insert(array('user_id' => $user_id, - 'client_id' => $bean->getAttribute('client'), - 'name' => $cl_name, - 'comment' => $cl_comment))) { - header('Location: timesheets.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } */ + /* + if (ttTimesheetHelper::insert($fields)) { + header('Location: timesheets.php'); + exit(); + } else + $err->add($i18n->get('error.db'));*/ + } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); From 8260fa56e1cd984cd433d890c0a3316714b8b059 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 28 Feb 2019 17:07:09 +0000 Subject: [PATCH 0737/1848] Wrote createTimesheet function. --- WEB-INF/lib/ttTimesheetHelper.class.php | 81 +++++++------------------ WEB-INF/templates/footer.tpl | 2 +- timesheet_add.php | 5 +- 3 files changed, 24 insertions(+), 64 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 2ba87abce..e65a6216e 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -54,59 +54,17 @@ static function getTimesheetByName($name, $user_id) { return false; } - // insert function inserts a new timesheet into database. - static function insert($fields) + // createTimesheet function creates a new timesheet. + static function createTimesheet($fields) { - // First, we obtain report items. - - // Obtain session bean with report attributes. - $bean = new ActionForm('reportBean', new Form('reportForm')); - $options = ttReportHelper::getReportOptions($bean); - $report_items = ttReportHelper::getItems($options); - - // Prepare ids for time and expense items, at the same time checking - // if we can proceed with creating a timesheet. - $canCreateTimesheet = true; - $first_user_id = null; - - foreach ($report_items as $report_item) { - // Check user id. - if (!$first_user_id) - $first_user_id = $report_item['user_id']; - else { - if ($report_item['user_id'] != $first_user_id) { - // We have items for multiple users. - $canCreateTimesheet = false; - break; - } - } - // Check timesheet id. - if ($report_item['timesheet_id']) { - // We have an item already assigned to a timesheet. - $canCreateTimesheet = false; - break; - } - if ($report_item['type'] == 1) - $time_ids[] = $report_item['id']; - elseif ($report_item['type'] == 2) - $expense_ids[] = $report_item['id']; - } - if (!$canCreateTimesheet) return false; - - // Make comma-seperated lists of ids for sql. - if ($time_ids) - $comma_separated_time_ids = implode(',', $time_ids); - if ($expense_ids) - $comma_separated_expense_ids = implode(',', $expense_ids); - // Create a new timesheet entry. global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; - $user_id = $fields['user_id']; $client_id = $fields['client_id']; $name = $fields['name']; $submitter_comment = $fields['comment']; @@ -120,22 +78,25 @@ static function insert($fields) $last_id = $mdb2->lastInsertID('tt_timesheets', 'id'); // Associate time items with timesheet. - if ($comma_separated_time_ids) { - $sql = "update tt_log set timesheet_id = $last_id". - " where id in ($comma_separated_time_ids) and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - } + if (isset($fields['client'])) $client_id = (int) $fields['client_id']; + if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; + // sql parts. + if ($client_id) $client_part = " and client_id = $client_id"; + if ($project_id) $project_part = " and project_id = $project_id"; - // Associate expense items with timesheet. - if ($comma_separated_expense_ids) { - $sql = "update tt_expense_items set timesheet_id = $last_id". - " where id in ($comma_separated_expense_ids) and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - } + $start_date = new DateAndTime($user->date_format, $fields['start_date']); + $start = $start_date->toString(DB_DATEFORMAT); + + $end_date = new DateAndTime($user->date_format, $fields['end_date']); + $end = $end_date->toString(DB_DATEFORMAT); + + $sql = "update tt_log set timesheet_id = $last_id". + " where status = 1 $client_part $project_part and timesheet_id is null". + " and date >= ".$mdb2->quote($start)." and date <= ".$mdb2->quote($end). + " and user_id = $user_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; return $last_id; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ec180725a..5499b12eb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index df4782b64..907f41557 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -21,9 +21,7 @@ -{if $can_edit} -{/if} {foreach $active_timesheets as $timesheet} @@ -38,9 +36,7 @@ {/if} - {if $can_edit} - {/if} {/foreach}
 Anuko Time Tracker 1.18.46.4793 | Copyright © Anuko | +  Anuko Time Tracker 1.18.46.4794 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_add.php b/timesheet_add.php index 4dd1afaea..c450695ef 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -90,12 +90,11 @@ // Finished validating user input. if ($err->no()) { - /* - if (ttTimesheetHelper::insert($fields)) { + if (ttTimesheetHelper::createTimesheet($fields)) { header('Location: timesheets.php'); exit(); } else - $err->add($i18n->get('error.db'));*/ + $err->add($i18n->get('error.db')); } } // isPost From bfbd5b318b37a66ece219e719734a60249781b6d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 28 Feb 2019 22:00:25 +0000 Subject: [PATCH 0738/1848] More work in progress on timesheets, simplifying access rights. --- WEB-INF/lib/ttTimesheetHelper.class.php | 10 +++------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_view.tpl | 12 +++++------- WEB-INF/templates/timesheets.tpl | 8 -------- timesheet_add.php | 2 +- timesheet_delete.php | 2 +- timesheet_edit.php | 2 +- timesheet_view.php | 11 +++++------ timesheets.php | 24 +++++++++++++----------- 9 files changed, 30 insertions(+), 43 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index e65a6216e..25685483b 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -170,16 +170,12 @@ static function getTimesheet($timesheet_id) { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; - if ($user->isClient()) $client_part = "and ts.client_id = $user->client_id"; - - $sql = "select ts.id, ts.user_id, u.name as user_name, ts.client_id, c.name as client_name,". - " ts.name, ts.submitter_comment, ts.submit_status, ts.approval_status, ts.manager_comment from tt_timesheets ts". - " left join tt_users u on (u.id = ts.user_id)". - " left join tt_clients c on (c.id = ts.client_id)". - " where ts.id = $timesheet_id and ts.group_id = $group_id and ts.org_id = $org_id $client_part and ts.status is not null"; + $sql = "select * from tt_timesheets". + " where id = $timesheet_id and user_id = $user_id and group_id = $group_id and org_id = $org_id and status is not null"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5499b12eb..e23882ac8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} -{if $not_client} - {if $timesheet['submitter_comment']} +{if $timesheet['submitter_comment']} - {/if} - {if $timesheet['submit_status']} +{/if} +{if $timesheet['submit_status']} {/if} - {/if} - {if $timesheet['manager_comment']} +{/if} +{if $timesheet['manager_comment']} - {/if} {/if}
 Anuko Time Tracker 1.18.46.4794 | Copyright © Anuko | +  Anuko Time Tracker 1.18.46.4795 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl index 97591fe0b..e69882530 100644 --- a/WEB-INF/templates/timesheet_view.tpl +++ b/WEB-INF/templates/timesheet_view.tpl @@ -11,17 +11,15 @@ {if $timesheet['client_id']}
{$i18n.label.client}: {$timesheet['client_name']|escape}
{$i18n.label.submitted}: {if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.comment}: {$timesheet['submitter_comment']|escape}
{$i18n.label.approved}: {if $timesheet.approval_status != null}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.note}: {$timesheet['manager_comment']|escape}
{$i18n.label.submitted} {$i18n.label.approved} {$i18n.label.view}{$i18n.label.edit}
{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}{$i18n.label.edit}
@@ -61,9 +57,7 @@
{$i18n.label.submitted} {$i18n.label.approved} {$i18n.label.view}{$i18n.label.edit}
{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view}{$i18n.label.edit}
diff --git a/timesheet_add.php b/timesheet_add.php index c450695ef..294886be7 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -31,7 +31,7 @@ import('ttTimesheetHelper'); // Access checks. -if (!(ttAccessAllowed('manage_own_timesheets') || ttAccessAllowed('manage_timesheets') || ttAccessAllowed('manage_all_timesheets'))) { +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } diff --git a/timesheet_delete.php b/timesheet_delete.php index e4bf453c5..5e98a6cc9 100644 --- a/timesheet_delete.php +++ b/timesheet_delete.php @@ -31,7 +31,7 @@ import('ttTimesheetHelper'); // Access checks. -if (!(ttAccessAllowed('manage_own_timesheets') || ttAccessAllowed('manage_timesheets'))) { +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } diff --git a/timesheet_edit.php b/timesheet_edit.php index 1708bdf7c..d275ce5f8 100644 --- a/timesheet_edit.php +++ b/timesheet_edit.php @@ -31,7 +31,7 @@ import('ttTimesheetHelper'); // Access checks. -if (!(ttAccessAllowed('manage_own_timesheets') || ttAccessAllowed('manage_timesheets'))) { +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } diff --git a/timesheet_view.php b/timesheet_view.php index e86b2df77..df28e3061 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -30,7 +30,7 @@ import('ttTimesheetHelper'); // Access checks. -if (!(ttAccessAllowed('view_own_timesheets') || ttAccessAllowed('view_timesheets') || ttAccessAllowed('view_all_timesheets'))) { +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } @@ -38,8 +38,8 @@ header('Location: feature_disabled.php'); exit(); } -$timesheet_id = (int)$request->getParameter('id'); -$timesheet = ttTimesheetHelper::getTimesheet($timesheet_id); +$cl_timesheet_id = (int)$request->getParameter('id'); +$timesheet = ttTimesheetHelper::getTimesheet($cl_timesheet_id); if (!$timesheet) { header('Location: access_denied.php'); exit(); @@ -55,13 +55,12 @@ $options = ttTimesheetHelper::getReportOptions($timesheet); $subtotals = ttReportHelper::getSubtotals($options); $totals = ttReportHelper::getTotals($options); -$notClient = !$user->isClient(); // Determine which controls to show and obtain date for them. -$showSubmit = $notClient && !$timesheet['submit_status']; +$showSubmit = !$timesheet['submit_status']; if ($showSubmit) $approvers = ttTimesheetHelper::getApprovers($timesheet['user_id']); $canApprove = $user->can('approve_timesheets') || $user->can('approve_all_timesheets'); -$showApprove = $notClient && $timesheet['submit_status'] && $timesheet['approval_status'] == null; +$showApprove = $timesheet['submit_status'] && $timesheet['approval_status'] == null; // Add a form with controls. $form = new Form('timesheetForm'); diff --git a/timesheets.php b/timesheets.php index cc43f0dd3..650575e69 100644 --- a/timesheets.php +++ b/timesheets.php @@ -32,22 +32,26 @@ import('ttTimesheetHelper'); // Access checks. -if (!(ttAccessAllowed('view_own_timesheets') || ttAccessAllowed('view_timesheets') || ttAccessAllowed('view_all_timesheets'))) { +if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { header('Location: access_denied.php'); exit(); } -if (!$user->isPluginEnabled('ts')) { - header('Location: feature_disabled.php'); +if ($user->behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { + header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. + exit(); +} +if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. exit(); } -if ($user->isClient()) { - header('Location: access_denied.php'); // No timesheets for clients. +if (!$user->isPluginEnabled('ts')) { + header('Location: feature_disabled.php'); exit(); } if ($request->isPost()) { $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('view_timesheets') && $user->isUserValid($request->getParameter('user')))) { - header('Location: access_denied.php'); // Group changed, but no rght or wrong user id. TODO: research relevance of this... + if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + header('Location: access_denied.php'); // Group changed, but no rght or wrong user id. exit(); } } @@ -66,9 +70,9 @@ // Elements of timesheetsForm. $form = new Form('timesheetsForm'); -if ($user->can('view_timesheets') || $user->can('view_all_timesheets')) { +if ($user->can('track_time')) { $rank = $user->getMaxRankForGroup($group_id); - if ($user->can('view_own_timesheets')) + if ($user->can('track_own_time')) $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); else $options = array('status'=>ACTIVE,'max_rank'=>$rank); @@ -90,12 +94,10 @@ $inactive_timesheets = ttTimesheetHelper::getInactiveTimesheets($user_id); $showClient = $user->isPluginEnabled('cl'); -$canEdit = $user->can('manage_own_timesheets') || $user->can('manage_timesheets') || $user->can('manage_all_timesheets'); $smarty->assign('active_timesheets', $active_timesheets); $smarty->assign('inactive_timesheets', $inactive_timesheets); $smarty->assign('show_client', $showClient); -$smarty->assign('can_edit', $canEdit); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.timesheets')); $smarty->assign('content_page_name', 'timesheets.tpl'); From 66d86939b62dc5ae3d5f16088b61822e611cf58f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 28 Feb 2019 22:23:59 +0000 Subject: [PATCH 0739/1848] Disallowed editing records assigned to timesheets. --- WEB-INF/lib/ttTimeHelper.class.php | 29 ++++++++++++++--------------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/time.tpl | 2 +- WEB-INF/templates/time.tpl | 2 +- mobile/time_delete.php | 4 ++-- mobile/time_edit.php | 4 ++-- time_delete.php | 4 ++-- time_edit.php | 4 ++-- 8 files changed, 25 insertions(+), 26 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index a66652b70..bdec1a5f7 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -667,14 +667,14 @@ static function getRecord($id, $user_id) { $mdb2 = getConnection(); - $sql = "select l.id as id, TIME_FORMAT(l.start, $sql_time_format) as start, - TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), $sql_time_format) as finish, - TIME_FORMAT(l.duration, '%k:%i') as duration, - p.name as project_name, t.name as task_name, l.comment, l.client_id, l.project_id, l.task_id, l.invoice_id, l.billable, l.paid, l.date - from tt_log l - left join tt_projects p on (p.id = l.project_id) - left join tt_tasks t on (t.id = l.task_id) - where l.id = $id and l.user_id = $user_id and l.status = 1"; + $sql = "select l.id as id, TIME_FORMAT(l.start, $sql_time_format) as start,". + " TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), $sql_time_format) as finish,". + " TIME_FORMAT(l.duration, '%k:%i') as duration,". + " p.name as project_name, t.name as task_name, l.comment, l.client_id, l.project_id, l.task_id,". + " l.timesheet_id, l.invoice_id, l.billable, l.paid, l.date from tt_log l". + " left join tt_projects p on (p.id = l.project_id)". + " left join tt_tasks t on (t.id = l.task_id)". + " where l.id = $id and l.user_id = $user_id and l.status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if (!$res->numRows()) { @@ -730,13 +730,12 @@ static function getRecords($user_id, $date) { $left_joins .= " left join tt_clients c on (l.client_id = c.id)"; $result = array(); - $sql = "select l.id as id, TIME_FORMAT(l.start, $sql_time_format) as start, - TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), $sql_time_format) as finish, - TIME_FORMAT(l.duration, '%k:%i') as duration, p.name as project, t.name as task, l.comment, l.billable, l.invoice_id $client_field - from tt_log l - $left_joins - where l.date = '$date' and l.user_id = $user_id and l.group_id = $group_id and l.org_id = $org_id and l.status = 1 - order by l.start, l.id"; + $sql = "select l.id as id, TIME_FORMAT(l.start, $sql_time_format) as start,". + " TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), $sql_time_format) as finish,". + " TIME_FORMAT(l.duration, '%k:%i') as duration, p.name as project, t.name as task, l.comment,". + " l.billable, l.timesheet_id, l.invoice_id $client_field from tt_log l $left_joins". + " where l.date = '$date' and l.user_id = $user_id and l.group_id = $group_id and l.org_id = $org_id and l.status = 1". + " order by l.start, l.id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e23882ac8..b5578c431 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} - + {/foreach}
 Anuko Time Tracker 1.18.46.4795 | Copyright © Anuko | +  Anuko Time Tracker 1.18.46.4796 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/time.tpl b/WEB-INF/templates/mobile/time.tpl index 35242e2f3..cde0b5ef1 100644 --- a/WEB-INF/templates/mobile/time.tpl +++ b/WEB-INF/templates/mobile/time.tpl @@ -25,7 +25,7 @@ {$record.project|escape}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{$record.duration}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{if $record.invoice_id} {else}{$i18n.label.edit}{/if}{if $record.timesheet_id|| $record.invoice_id} {else}{$i18n.label.edit}{/if}
diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index bf28c5091..f82897d2a 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -130,7 +130,7 @@
{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if} {if $record.comment}{$record.comment|escape}{else} {/if} - {if $record.invoice_id} + {if $record.timesheet_id || $record.invoice_id}   {else} {$i18n.label.edit} diff --git a/mobile/time_delete.php b/mobile/time_delete.php index 104732601..8ebb98a88 100644 --- a/mobile/time_delete.php +++ b/mobile/time_delete.php @@ -40,8 +40,8 @@ $cl_id = (int)$request->getParameter('id'); $user_id = $user->getUser(); $time_rec = ttTimeHelper::getRecord($cl_id, $user_id); -if (!$time_rec || $time_rec['invoice_id']) { - // Prohibit deleting not ours or invoiced records. +if (!$time_rec || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { + // Prohibit deleting not ours, or assigned to timesheet, or invoiced records. header('Location: access_denied.php'); exit(); } diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 803ca4e4f..0b5b090e3 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -42,8 +42,8 @@ $cl_id = (int)$request->getParameter('id'); $user_id = $user->getUser(); $time_rec = ttTimeHelper::getRecord($cl_id, $user_id); -if (!$time_rec || $time_rec['invoice_id']) { - // Prohibit editing not ours or invoiced records. +if (!$time_rec || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { + // Prohibit editing not ours, or assigned to timesheet, or invoiced records. header('Location: access_denied.php'); exit(); } diff --git a/time_delete.php b/time_delete.php index 5d6e57298..1b6f5c298 100644 --- a/time_delete.php +++ b/time_delete.php @@ -40,8 +40,8 @@ $cl_id = (int)$request->getParameter('id'); $user_id = $user->getUser(); $time_rec = ttTimeHelper::getRecord($cl_id, $user_id); -if (!$time_rec || $time_rec['invoice_id']) { - // Prohibit deleting not ours or invoiced records. +if (!$time_rec || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { + // Prohibit deleting not ours, or assigned to timesheet, or invoiced records. header('Location: access_denied.php'); exit(); } diff --git a/time_edit.php b/time_edit.php index 3bd52e6f5..48db27ea7 100644 --- a/time_edit.php +++ b/time_edit.php @@ -42,8 +42,8 @@ $cl_id = (int)$request->getParameter('id'); $user_id = $user->getUser(); $time_rec = ttTimeHelper::getRecord($cl_id, $user_id); -if (!$time_rec || $time_rec['invoice_id']) { - // Prohibit editing not ours or invoiced records. +if (!$time_rec || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { + // Prohibit editing not ours, or assigned to timesheet, or invoiced records. header('Location: access_denied.php'); exit(); } From 086b93bd5a71b4c68ae3fa3e37d97182ee2a5b73 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 28 Feb 2019 22:47:13 +0000 Subject: [PATCH 0740/1848] A bit of refactoring. --- WEB-INF/lib/ttTimeHelper.class.php | 9 +++++++-- WEB-INF/templates/footer.tpl | 2 +- mobile/time_delete.php | 3 +-- mobile/time_edit.php | 5 +++-- mobile/timer.php | 2 +- time.php | 4 ++-- time_delete.php | 3 +-- time_edit.php | 5 +++-- 8 files changed, 19 insertions(+), 14 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index bdec1a5f7..d2a356476 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -659,8 +659,13 @@ static function overlaps($user_id, $date, $start, $finish, $record_id = null) { } // getRecord - retrieves a time record identified by its id. - static function getRecord($id, $user_id) { + static function getRecord($id) { global $user; + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $sql_time_format = "'%k:%i'"; // 24 hour format. if ('%I:%M %p' == $user->time_format) $sql_time_format = "'%h:%i %p'"; // 12 hour format for MySQL TIME_FORMAT function. @@ -674,7 +679,7 @@ static function getRecord($id, $user_id) { " l.timesheet_id, l.invoice_id, l.billable, l.paid, l.date from tt_log l". " left join tt_projects p on (p.id = l.project_id)". " left join tt_tasks t on (t.id = l.task_id)". - " where l.id = $id and l.user_id = $user_id and l.status = 1"; + " where l.id = $id and l.user_id = $user_id and l.group_id = $group_id and l.org_id = $org_id and l.status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if (!$res->numRows()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b5578c431..eb0fd5927 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} {if $show_week_note} - + - - + + {/if}
 Anuko Time Tracker 1.18.46.4796 | Copyright © Anuko | +  Anuko Time Tracker 1.18.46.4797 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/time_delete.php b/mobile/time_delete.php index 8ebb98a88..1b122fb9e 100644 --- a/mobile/time_delete.php +++ b/mobile/time_delete.php @@ -38,8 +38,7 @@ exit(); } $cl_id = (int)$request->getParameter('id'); -$user_id = $user->getUser(); -$time_rec = ttTimeHelper::getRecord($cl_id, $user_id); +$time_rec = ttTimeHelper::getRecord($cl_id); if (!$time_rec || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { // Prohibit deleting not ours, or assigned to timesheet, or invoiced records. header('Location: access_denied.php'); diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 0b5b090e3..1f8f7de91 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -40,8 +40,7 @@ exit(); } $cl_id = (int)$request->getParameter('id'); -$user_id = $user->getUser(); -$time_rec = ttTimeHelper::getRecord($cl_id, $user_id); +$time_rec = ttTimeHelper::getRecord($cl_id); if (!$time_rec || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { // Prohibit editing not ours, or assigned to timesheet, or invoiced records. header('Location: access_denied.php'); @@ -49,6 +48,8 @@ } // End of access checks. +$user_id = $user->getUser(); + // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('../plugins/CustomFields.class.php'); diff --git a/mobile/timer.php b/mobile/timer.php index c754740a6..d3a0d0fb6 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -254,7 +254,7 @@ } if ($request->getParameter('btn_stop')) { // Stop button clicked. We need to finish an uncompleted record in progress. - $record = ttTimeHelper::getRecord($uncompleted['id'], $user->getUser()); + $record = ttTimeHelper::getRecord($uncompleted['id']); // Can we complete this record? if (ttTimeHelper::isValidInterval($record['start'], $cl_finish) // finish time is greater than start time diff --git a/time.php b/time.php index e4547a949..f7b1c12e7 100644 --- a/time.php +++ b/time.php @@ -56,7 +56,7 @@ } // End of access checks. -// Determine user for which we display this page. +// Determine user for whom we display this page. if ($request->isPost() && $userChanged) { $user_id = $request->getParameter('user'); $user->setOnBehalfUser($user_id); @@ -347,7 +347,7 @@ } elseif ($request->getParameter('btn_stop')) { // Stop button pressed to finish an uncompleted record. $record_id = $request->getParameter('record_id'); - $record = ttTimeHelper::getRecord($record_id, $user_id); + $record = ttTimeHelper::getRecord($record_id); $browser_date = $request->getParameter('browser_date'); $browser_time = $request->getParameter('browser_time'); diff --git a/time_delete.php b/time_delete.php index 1b6f5c298..e83630edf 100644 --- a/time_delete.php +++ b/time_delete.php @@ -38,8 +38,7 @@ exit(); } $cl_id = (int)$request->getParameter('id'); -$user_id = $user->getUser(); -$time_rec = ttTimeHelper::getRecord($cl_id, $user_id); +$time_rec = ttTimeHelper::getRecord($cl_id); if (!$time_rec || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { // Prohibit deleting not ours, or assigned to timesheet, or invoiced records. header('Location: access_denied.php'); diff --git a/time_edit.php b/time_edit.php index 48db27ea7..23cc63d5a 100644 --- a/time_edit.php +++ b/time_edit.php @@ -40,8 +40,7 @@ exit(); } $cl_id = (int)$request->getParameter('id'); -$user_id = $user->getUser(); -$time_rec = ttTimeHelper::getRecord($cl_id, $user_id); +$time_rec = ttTimeHelper::getRecord($cl_id); if (!$time_rec || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { // Prohibit editing not ours, or assigned to timesheet, or invoiced records. header('Location: access_denied.php'); @@ -49,6 +48,8 @@ } // End of access checks. +$user_id = $user->getUser(); + // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); From fa647157935f37f999ae81377b19f5ea72e7bbbb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 1 Mar 2019 15:49:45 +0000 Subject: [PATCH 0741/1848] Changed structure of tt_timesheets table as part of redesign work. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 15 +++++++++++---- mysql.sql | 10 ++++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index eb0fd5927..ed56fe1fa 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.46.4797 | Copyright © Anuko | +  Anuko Time Tracker 1.18.47.4798 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 09d552920..c6a724158 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11846"]) { + if ($_POST["convert11797to11847"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1102,6 +1102,13 @@ function ttExecute($sql) { ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.45', modified = now() where param_name = 'version_db' and param_value = '1.18.44'"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.45') set rights = replace(rights, 'view_client_timesheets,', '')"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.46', modified = now() where param_name = 'version_db' and param_value = '1.18.45'"); + ttExecute("ALTER TABLE `tt_timesheets` ADD `comment` text AFTER `name`"); + ttExecute("ALTER TABLE `tt_timesheets` ADD `start_date` date NOT NULL AFTER `comment`"); + ttExecute("ALTER TABLE `tt_timesheets` ADD `end_date` date NOT NULL AFTER `start_date`"); + ttExecute("ALTER TABLE `tt_timesheets` DROP `submitter_comment`"); + ttExecute("ALTER TABLE `tt_timesheets` CHANGE `approval_status` `approve_status` tinyint(4) default NULL"); + ttExecute("ALTER TABLE `tt_timesheets` CHANGE `manager_comment` `approve_comment` text"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.47', modified = now() where param_name = 'version_db' and param_value = '1.18.46'"); } if ($_POST["cleanup"]) { @@ -1150,7 +1157,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.46) + Create database structure (v1.18.47)
(applies only to new installations, do not execute when updating)
@@ -1195,8 +1202,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.46)Update database structure (v1.17.97 to v1.18.47)
diff --git a/mysql.sql b/mysql.sql index d6cb375ff..126902d1a 100644 --- a/mysql.sql +++ b/mysql.sql @@ -496,10 +496,12 @@ CREATE TABLE `tt_timesheets` ( `org_id` int(11) default NULL, # organization id `client_id` int(11) default NULL, # client id `name` varchar(80) COLLATE utf8mb4_bin NOT NULL, # timesheet name + `comment` text, # timesheet comment + `start_date` date NOT NULL, # timesheet start date + `end_date` date NOT NULL, # timesheet end date `submit_status` tinyint(4) default NULL, # submit status - `submitter_comment` text, # submitter comment - `approval_status` tinyint(4) default NULL, # approval status - `manager_comment` text, # manager comment + `approve_status` tinyint(4) default NULL, # approve status + `approve_comment` text, # approve comment `created` datetime default NULL, # creation timestamp `created_ip` varchar(45) default NULL, # creator ip `created_by` int(11) default NULL, # creator user_id @@ -524,4 +526,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.46', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.47', now()); # TODO: change when structure changes. From b7e0a81d78007c097e7860c752f445263683b42b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 1 Mar 2019 17:30:17 +0000 Subject: [PATCH 0742/1848] Some more work in progress on timesheets. --- WEB-INF/lib/ttTimesheetHelper.class.php | 21 +++++++++++---------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 25685483b..9ab86f0f6 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -67,10 +67,17 @@ static function createTimesheet($fields) $client_id = $fields['client_id']; $name = $fields['name']; - $submitter_comment = $fields['comment']; + $comment = $fields['comment']; - $sql = "insert into tt_timesheets (user_id, group_id, org_id, client_id, name, submitter_comment)". - " values ($user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($name).", ".$mdb2->quote($submitter_comment).")"; + $start_date = new DateAndTime($user->date_format, $fields['start_date']); + $start = $start_date->toString(DB_DATEFORMAT); + + $end_date = new DateAndTime($user->date_format, $fields['end_date']); + $end = $end_date->toString(DB_DATEFORMAT); + + $sql = "insert into tt_timesheets (user_id, group_id, org_id, client_id, name, comment, start_date, end_date)". + " values ($user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($name). + ", ".$mdb2->quote($comment).", ".$mdb2->quote($start).", ".$mdb2->quote($end).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -84,12 +91,6 @@ static function createTimesheet($fields) if ($client_id) $client_part = " and client_id = $client_id"; if ($project_id) $project_part = " and project_id = $project_id"; - $start_date = new DateAndTime($user->date_format, $fields['start_date']); - $start = $start_date->toString(DB_DATEFORMAT); - - $end_date = new DateAndTime($user->date_format, $fields['end_date']); - $end = $end_date->toString(DB_DATEFORMAT); - $sql = "update tt_log set timesheet_id = $last_id". " where status = 1 $client_part $project_part and timesheet_id is null". " and date >= ".$mdb2->quote($start)." and date <= ".$mdb2->quote($end). @@ -116,7 +117,7 @@ static function getActiveTimesheets($user_id) if ($user->isClient()) $client_part = "and ts.client_id = $user->client_id"; - $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name, ts.submit_status, ts.approval_status from tt_timesheets ts". + $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name, ts.submit_status, ts.approve_status from tt_timesheets ts". " left join tt_clients c on (c.id = ts.client_id)". " where ts.status = 1 and ts.group_id = $group_id and ts.org_id = $org_id and ts.user_id = $user_id". " $client_part order by ts.name"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ed56fe1fa..2afec4f9e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.47.4798 | Copyright © Anuko | +  Anuko Time Tracker 1.18.47.4799 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 5897ea0d3efe16a50706bcf1bde8d33044b5cf5f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 1 Mar 2019 17:49:49 +0000 Subject: [PATCH 0743/1848] Cleaning up no longer needed access rights. --- WEB-INF/lib/ttRoleHelper.class.php | 4 ++-- WEB-INF/lib/ttTimesheetHelper.class.php | 4 ---- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 4 ++-- reports.php | 6 ++---- 7 files changed, 15 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index c03368f9b..966c409bb 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -190,8 +190,8 @@ static function createPredefinedRoles($group_id, $lang) $mdb2 = getConnection(); $rights_client = 'view_client_reports,view_client_invoices,manage_own_settings'; - $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; - $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; + $rights_user = 'track_own_time,track_own_expenses,view_own_reports,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; + $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,approve_reports,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; $rights_manager = $rights_comanager.',manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 9ab86f0f6..6b13ae537 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -236,10 +236,6 @@ static function update($fields) { // in current context. static function isUserValid($user_id) { // We have to cover several situations. - // - // 1) User is a client. - // 2) User with view_all_timesheets rights. - // 3) User with view_timesheets rights. global $user; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2afec4f9e..7db679914 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.47.4799 | Copyright © Anuko | +  Anuko Time Tracker 1.18.47.4800 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index a89d60f81..d00000a70 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -115,7 +115,7 @@ {if $user->exists() && ($user->can('view_own_reports') || $user->can('view_reports') || $user->can('view_all_reports') || $user->can('view_client_reports'))} {if !$user->isClient()}·{/if} {$i18n.menu.reports} {/if} - {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets'))} + {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('track_own_time') || $user->can('track_time'))} · {$i18n.menu.timesheets} {/if} {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->can('view_client_invoices'))} diff --git a/dbinstall.php b/dbinstall.php index c6a724158..5a239b25f 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11847"]) { + if ($_POST["convert11797to11848"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1109,6 +1109,9 @@ function ttExecute($sql) { ttExecute("ALTER TABLE `tt_timesheets` CHANGE `approval_status` `approve_status` tinyint(4) default NULL"); ttExecute("ALTER TABLE `tt_timesheets` CHANGE `manager_comment` `approve_comment` text"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.47', modified = now() where param_name = 'version_db' and param_value = '1.18.46'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.47') set rights = replace(rights, 'view_own_timesheets,', '')"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.47') set rights = replace(rights, 'view_timesheets,', '')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.48', modified = now() where param_name = 'version_db' and param_value = '1.18.47'"); } if ($_POST["cleanup"]) { @@ -1157,7 +1160,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.47) + Create database structure (v1.18.48)
(applies only to new installations, do not execute when updating)
@@ -1202,8 +1205,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.47)Update database structure (v1.17.97 to v1.18.48)
diff --git a/mysql.sql b/mysql.sql index 126902d1a..8f3242483 100644 --- a/mysql.sql +++ b/mysql.sql @@ -75,7 +75,7 @@ create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,view_client_unapproved,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,view_client_unapproved,delete_group'); # @@ -526,4 +526,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.47', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.48', now()); # TODO: change when structure changes. diff --git a/reports.php b/reports.php index fc77e0910..fb74e16cc 100644 --- a/reports.php +++ b/reports.php @@ -192,8 +192,7 @@ } // Add timesheet assignment selector. -$showTimesheetDropdown = $user->isPluginEnabled('ts') && - ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets')); +$showTimesheetDropdown = $user->isPluginEnabled('ts'); if ($showTimesheetDropdown) { $form->addInput(array('type'=>'combobox', 'name'=>'timesheet', @@ -206,8 +205,7 @@ 'empty'=>array(''=>$i18n->get('dropdown.all')) )); } -$showTimesheetCheckbox = $user->isPluginEnabled('ts') && - ($user->can('view_own_timesheets') || $user->can('view_timesheets') || $user->can('view_all_timesheets')); +$showTimesheetCheckbox = $user->isPluginEnabled('ts'); // Add user table. $showUsers = $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient(); From 30bec134aac46efe3cdd5371de46598a68138c46 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 1 Mar 2019 18:07:36 +0000 Subject: [PATCH 0744/1848] A bit of cleanup for timesheet redesign. --- WEB-INF/resources/ca.lang.php | 2 -- WEB-INF/resources/cs.lang.php | 2 -- WEB-INF/resources/da.lang.php | 2 -- WEB-INF/resources/de.lang.php | 2 -- WEB-INF/resources/en.lang.php | 1 - WEB-INF/resources/es.lang.php | 2 -- WEB-INF/resources/et.lang.php | 2 -- WEB-INF/resources/fa.lang.php | 2 -- WEB-INF/resources/fi.lang.php | 2 -- WEB-INF/resources/fr.lang.php | 2 -- WEB-INF/resources/gr.lang.php | 2 -- WEB-INF/resources/he.lang.php | 2 -- WEB-INF/resources/hu.lang.php | 2 -- WEB-INF/resources/it.lang.php | 2 -- WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 2 -- WEB-INF/resources/no.lang.php | 2 -- WEB-INF/resources/pl.lang.php | 2 -- WEB-INF/resources/pt-br.lang.php | 2 -- WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 2 -- WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 2 -- WEB-INF/resources/sl.lang.php | 2 -- WEB-INF/resources/sr.lang.php | 2 -- WEB-INF/resources/sv.lang.php | 2 -- WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 1 - WEB-INF/resources/zh-tw.lang.php | 1 - WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 3 --- report.php | 34 -------------------------------- 33 files changed, 1 insertion(+), 90 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 34ba35f6e..f2ec9cf3a 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -145,8 +145,6 @@ 'button.send' => 'Enviar', 'button.send_by_email' => 'Enviar per correu', 'button.create_group' => 'Crear grup', -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportar grup', 'button.import' => 'Importar grup', // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index e43d2cc0d..edc7d3ecb 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -147,8 +147,6 @@ 'button.send' => 'Poslat', 'button.send_by_email' => 'Poslat e-mailem', 'button.create_group' => 'Vytvořit tým', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportovat tým', // TODO: replace "team" with "group". 'button.import' => 'Importovat tým', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 1247264e7..7bb213802 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -140,8 +140,6 @@ 'button.send' => 'Send', 'button.send_by_email' => 'Send som e-mail', 'button.create_group' => 'Lav et team', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Eksporter team', // TODO: replace "team" with "group". 'button.import' => 'Importer team', // TODO: replace "team" with "group". 'button.close' => 'Luk', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 72f4b5cb1..02ab0484e 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -134,8 +134,6 @@ 'button.send' => 'Senden', 'button.send_by_email' => 'Als E-Mail senden', 'button.create_group' => 'Gruppe erstellen', -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Gruppe exportieren', 'button.import' => 'Gruppe importieren', 'button.close' => 'Schließen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 6701a4c34..6740c556a 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -127,7 +127,6 @@ 'button.send' => 'Send', 'button.send_by_email' => 'Send by e-mail', 'button.create_group' => 'Create group', -'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Export group', 'button.import' => 'Import group', 'button.close' => 'Close', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 7a2bf9a90..5bb6eefe4 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -144,8 +144,6 @@ 'button.send' => 'Enviar', 'button.send_by_email' => 'Enviar por correo', 'button.create_group' => 'Crear grupo', -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportar grupo', 'button.import' => 'Importar grupo', // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 6f37883ee..e0b512e6c 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -148,8 +148,6 @@ 'button.send' => 'Saada', 'button.send_by_email' => 'Saada e-postiga', 'button.create_group' => 'Loo grupp', -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Ekspordi grupp', 'button.import' => 'Impordi grupp', 'button.close' => 'Sulge', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 5a6c6aa8c..97610c3a6 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -147,8 +147,6 @@ 'button.send' => 'ارسال', 'button.send_by_email' => 'ارسال به ایمیل', 'button.create_group' => 'ایجاد تیم', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'ایجاد پشتیبان از تیم', // TODO: replace "team" with "group". 'button.import' => 'وارد کردن تیم', // TODO: replace "team" with "group". 'button.close' => 'بستن', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 9f577f3dc..91bcd40dd 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -142,8 +142,6 @@ 'button.send' => 'Lähetä', 'button.send_by_email' => 'Lähetä sähköpostilla', 'button.create_group' => 'Luo tiimi', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Vie tiimi', // TODO: replace "team" with "group". 'button.import' => 'Tuo tiimi', // TODO: replace "team" with "group". 'button.close' => 'Sulje', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index be5c9d22b..0cb6764a4 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -140,8 +140,6 @@ 'button.send' => 'Envoyer', 'button.send_by_email' => 'Envoyer par courriel', 'button.create_group' => 'Créer une équipe', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exporter l\\\'équipe', // TODO: replace "team" with "group". 'button.import' => 'Importer une équipe', // TODO: replace "team" with "group". 'button.close' => 'Fermer', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 288982735..e34554651 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -135,8 +135,6 @@ 'button.send' => 'Αποστολή', 'button.send_by_email' => 'Αποστολή μέσω email', 'button.create_group' => 'Δημιουργία ομάδας', -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Εξαγωγη ομάδας', 'button.import' => 'Εισαγωγή ομάδας', 'button.close' => 'Κλείσιμο', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index d9ab0d1c6..2d65957bf 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -157,8 +157,6 @@ 'button.send' => 'שלח', 'button.send_by_email' => 'שלח בדואר אלקטרוני', 'button.create_group' => 'צור צוות', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'ייצא צוות', // TODO: replace "team" with "group". 'button.import' => 'ייבא צוות', // TODO: replace "team" with "group". 'button.close' => 'סגור', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 38ec28cb7..c9e59f476 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -147,8 +147,6 @@ 'button.send' => 'Küld', 'button.send_by_email' => 'Küldés e-mail-ben', 'button.create_group' => 'Csoport létrehozása', -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Csoport exportálása', 'button.import' => 'Csoport importálása', // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index e4d328e61..7402e033e 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -139,8 +139,6 @@ 'button.send' => 'Invia', 'button.send_by_email' => 'Invia tramite e-mail', 'button.create_group' => 'Crea gruppo', -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Esporta gruppo', 'button.import' => 'Importa gruppo', 'button.close' => 'Chiudi', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 3f0db6e0e..5cb5305e6 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -151,7 +151,6 @@ 'button.send_by_email' => 'Eメールの送信', // TODO: translate the following. // 'button.create_group' => 'Create group', -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'チームのエクスポート', // TODO: replace "team" with "group". 'button.import' => 'チームのインポート', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index d59c16347..df1311708 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -150,7 +150,6 @@ 'button.send_by_email' => '이메일로 송신', // TODO: translate the following. // 'button.create_group' => 'Create group', -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => '팀 익스포트', // TODO: replace "team" with "group". 'button.import' => '팀 임포트', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 8aa557e67..e6425badd 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -128,8 +128,6 @@ 'button.send' => 'Verzenden', 'button.send_by_email' => 'Verzend per e-mail', 'button.create_group' => 'Maak groep', -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Groep exporteren', 'button.import' => 'Groep importeren', 'button.close' => 'Sluiten', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index cdcc05de1..09fdec8e2 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -150,8 +150,6 @@ 'button.send' => 'Send', 'button.send_by_email' => 'Send som e-post', 'button.create_group' => 'Opprett team', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Eksport team', // TODO: replace "team" with "group". 'button.import' => 'Importer team', // TODO: replace "team" with "group". 'button.close' => 'Lukk', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 11166236b..678f38e9a 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -144,8 +144,6 @@ 'button.send' => 'Wyślij', 'button.send_by_email' => 'Wyślij e-mail', 'button.create_group' => 'Stwórz zespół', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Eksportuj zespół', // TODO: replace "team" with "group". 'button.import' => 'Importuj zespół', // TODO: replace "team" with "group". 'button.close' => 'Zamknij', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index bfeb7e720..967bfabd2 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -141,8 +141,6 @@ 'button.send' => 'Enviar', 'button.send_by_email' => 'Enviar por e-mail', 'button.create_group' => 'Criar equipe', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportar equipe', // TODO: replace "team" with "group". 'button.import' => 'Importar equipe', // TODO: replace "team" with "group". 'button.close' => 'Fechar', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index b9b746c9d..9ce23328b 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -144,7 +144,6 @@ 'button.send_by_email' => 'Enviar por e-mail', // TODO: translate the following. // 'button.create_group' => 'Create group', -// 'button.create_timesheet' => 'Create timesheet', // 'button.export' => 'Export group', // 'button.import' => 'Import group', // 'button.close' => 'Close', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 050bddef1..7472f0b5f 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -150,8 +150,6 @@ 'button.send' => 'Trimite', 'button.send_by_email' => 'Trimite pe e-mail', 'button.create_group' => 'Adauga echipa', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exporta echipa', // TODO: replace "team" with "group". 'button.import' => 'Importa echipa', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 2d04e8f93..ac9d0d146 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -126,7 +126,6 @@ 'button.send' => 'Отправить', 'button.send_by_email' => 'Отправить по e-mail', 'button.create_group' => 'Создать группу', -'button.create_timesheet' => 'Создать табель', 'button.export' => 'Экспортировать группу', 'button.import' => 'Импортировать группу', 'button.close' => 'Закрыть', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 0ed070293..f1e0c894b 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -147,8 +147,6 @@ 'button.send' => 'Odoslať', 'button.send_by_email' => 'Odoslať na e-mail', 'button.create_group' => 'Vytvoriť tím', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportovať tím', // TODO: replace "team" with "group". 'button.import' => 'Importovať tím', // TODO: replace "team" with "group". 'button.close' => 'Zatvoriť', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index e93884505..17e8ca7f7 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -140,8 +140,6 @@ 'button.send' => 'Pošlji', 'button.send_by_email' => 'Pošlji preko elektronske pošte', 'button.create_group' => 'Ustvari tim', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Izvozi tim', // TODO: replace "team" with "group". 'button.import' => 'Uvozi tim', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 5d2b9f88a..ee49bd17f 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -141,8 +141,6 @@ 'button.send' => 'Pošalji', 'button.send_by_email' => 'Pošalji mejlom', 'button.create_group' => 'Napravi tim', // TODO: replace "team" with "group". -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Izvezi tim', // TODO: replace "team" with "group". 'button.import' => 'Uvezi tim', // TODO: replace "team" with "group". 'button.close' => 'Zatvori', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index ba2f6665f..6acbcc0d8 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -139,8 +139,6 @@ 'button.send' => 'Skicka', 'button.send_by_email' => 'Skicka som e-post', 'button.create_group' => 'Skapa grupp', -// TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => 'Exportera grupp', 'button.import' => 'Importera grupp', 'button.close' => 'Stäng', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 22e872374..614ce9426 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -154,7 +154,6 @@ 'button.send_by_email' => 'E-posta ile gönder', 'button.create_group' => 'Ekip yarat', // TODO: replace "team" with "group". // TODO: translate the following. -// 'button.create_timesheet' => 'Create timesheet', // 'button.export' => 'Export group', 'button.import' => 'Ekibi içeri aktar', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index a1583eb4a..9239d7edf 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -142,7 +142,6 @@ 'button.send_by_email' => '通过邮件发送', // TODO: translate the following. // 'button.create_group' => 'Create group', -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => '导出团队信息', // TODO: replace "team" with "group". 'button.import' => '导入团队信息', // TODO: replace "team" with "group". 'button.close' => '关闭', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 42f152029..fdbf657c8 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -147,7 +147,6 @@ 'button.send_by_email' => '通過郵件發送', // TODO: translate the following. // 'button.create_group' => 'Create group', -// 'button.create_timesheet' => 'Create timesheet', 'button.export' => '輸出團隊資訊', // TODO: replace "team" with "group". 'button.import' => '輸入團隊資訊', // TODO: replace "team" with "group". // TODO: translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7db679914..90fe1c064 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/report.php b/report.php index ed7928c7f..84b18b66c 100644 --- a/report.php +++ b/report.php @@ -228,39 +228,6 @@ } $totals = ttReportHelper::getTotals($options); -// TODO: Determine if we can create a timesheet out of this report. -// There must be only one user, and nothing assigned to existing timesheets. -$canCreateTimesheet = false; -if ($user->isPluginEnabled('ts') && count($report_items) > 0 && - ($user->can('manage_own_timesheets') || $user->can('manage_timesheets'))) { - - $canCreateTimesheet = true; // Start with true and reset if we can't. - $first_user_id = null; - foreach ($report_items as $report_item) { - // Check user id. - if (!$first_user_id) - $first_user_id = $report_item['user_id']; - else { - if ($report_item['user_id'] != $first_user_id) { - // We have items for multiple users. - $canCreateTimesheet = false; - break; - } - } - // Check timesheet id. - if ($report_item['timesheet_id']) { - // We have an item already assigned to a timesheet. - $canCreateTimesheet = false; - break; - } - } - // Save user_id in session. - $bean->saveDetachedAttribute('timesheet_user_id', $first_user_id); - - // TODO: Improve this for "view_all_reports" situation. - // We may need to add "manage_all_timesheets" right. -} - // Assign variables that are used to print subtotals. if ($report_items) { $smarty->assign('print_subtotals', true); @@ -277,7 +244,6 @@ $smarty->assign('report_items', $report_items); $smarty->assign('subtotals', $subtotals); $smarty->assign('totals', $totals); -$smarty->assign('can_create_timesheet', $canCreateTimesheet); $smarty->assign('bean', $bean); $smarty->assign('title', $i18n->get('title.report').": ".$totals['start_date']." - ".$totals['end_date']); $smarty->assign('content_page_name', 'report.tpl'); From a4697cccdffc187c38d6560c5824fe344e59f5be Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 1 Mar 2019 18:29:55 +0000 Subject: [PATCH 0745/1848] Further streamlining of access rights. --- WEB-INF/lib/ttRoleHelper.class.php | 6 +++--- WEB-INF/lib/ttTimesheetHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 14 ++++++++++---- mysql.sql | 4 ++-- timesheet_view.php | 2 +- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 966c409bb..d12fcd442 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -190,8 +190,8 @@ static function createPredefinedRoles($group_id, $lang) $mdb2 = getConnection(); $rights_client = 'view_client_reports,view_client_invoices,manage_own_settings'; - $rights_user = 'track_own_time,track_own_expenses,view_own_reports,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; - $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,approve_reports,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; + $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; + $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; $rights_manager = $rights_comanager.',manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups'; @@ -254,7 +254,7 @@ static function createPredefinedRoles_1_17_44($group_id, $lang) $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets'; $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; - $rights_manager = $rights_comanager.',manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups'; + $rights_manager = $rights_comanager.',manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_own_timesheets,manage_subgroups'; // Active roles. $name = $mdb2->quote($i18n->get('role.user.label')); diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 6b13ae537..636b1fcf2 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -284,7 +284,7 @@ static function getApprovers($user_id) { " from tt_users u". " left join tt_roles r on (r.id = u.role_id)". " where u.status = 1 and u.email is not null and u.group_id = $group_id and u.org_id = $org_id". - " and (r.rights like '%approve_all_timesheets%' or (r.rank > $rank and r.rights like '%approve_timesheets%'))"; + " and (r.rank > $rank and r.rights like '%approve_timesheets%')"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 90fe1c064..f81320ad6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.47.4800 | Copyright © Anuko | +  Anuko Time Tracker 1.18.47.4801 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 294582dc4..44a6e3376 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -205,9 +205,6 @@ -{if $can_create_timesheet} - -{/if}
- - - + +
 Anuko Time Tracker 1.18.47.4801 | Copyright © Anuko | +  Anuko Time Tracker 1.18.47.4802 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 5a239b25f..90b5669a4 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11848"]) { + if ($_POST["convert11797to11849"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1112,6 +1112,12 @@ function ttExecute($sql) { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.47') set rights = replace(rights, 'view_own_timesheets,', '')"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.47') set rights = replace(rights, 'view_timesheets,', '')"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.48', modified = now() where param_name = 'version_db' and param_value = '1.18.47'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.48') set rights = replace(rights, 'manage_own_timesheets,', '')"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.48') set rights = replace(rights, 'manage_timesheets,', '')"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.48') set rights = replace(rights, 'view_all_timesheets,', '')"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.48') set rights = replace(rights, 'manage_all_timesheets,', '')"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.48') set rights = replace(rights, 'approve_all_timesheets,', 'approve_own_timesheets,')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.49', modified = now() where param_name = 'version_db' and param_value = '1.18.48'"); } if ($_POST["cleanup"]) { @@ -1160,7 +1166,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.48) + Create database structure (v1.18.49)
(applies only to new installations, do not execute when updating)
@@ -1205,8 +1211,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.48)Update database structure (v1.17.97 to v1.18.49)
diff --git a/mysql.sql b/mysql.sql index 8f3242483..3378fc0b6 100644 --- a/mysql.sql +++ b/mysql.sql @@ -75,7 +75,7 @@ create unique index role_idx on tt_roles(group_id, rank, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,view_client_unapproved,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_own_timesheets,manage_subgroups,view_client_unapproved,delete_group'); # @@ -526,4 +526,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.48', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.49', now()); # TODO: change when structure changes. diff --git a/timesheet_view.php b/timesheet_view.php index df28e3061..9b5b4cdfe 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -59,7 +59,7 @@ // Determine which controls to show and obtain date for them. $showSubmit = !$timesheet['submit_status']; if ($showSubmit) $approvers = ttTimesheetHelper::getApprovers($timesheet['user_id']); -$canApprove = $user->can('approve_timesheets') || $user->can('approve_all_timesheets'); +$canApprove = $user->can('approve_timesheets') || $user->can('approve_own_timesheets'); $showApprove = $timesheet['submit_status'] && $timesheet['approval_status'] == null; // Add a form with controls. From 88c67a664a63623a83ed241054525aa112f9c70c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 1 Mar 2019 18:55:38 +0000 Subject: [PATCH 0746/1848] Added conditional display of show approvers. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_view.tpl | 2 +- timesheet_view.php | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f81320ad6..246dfca29 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/timesheet_view.php b/timesheet_view.php index 9b5b4cdfe..813edffb8 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -58,7 +58,10 @@ // Determine which controls to show and obtain date for them. $showSubmit = !$timesheet['submit_status']; -if ($showSubmit) $approvers = ttTimesheetHelper::getApprovers($timesheet['user_id']); +if ($showSubmit) { + $approvers = ttTimesheetHelper::getApprovers($timesheet['user_id']); + $showApprovers = count($approvers) >= 1; +} $canApprove = $user->can('approve_timesheets') || $user->can('approve_own_timesheets'); $showApprove = $timesheet['submit_status'] && $timesheet['approval_status'] == null; @@ -67,7 +70,7 @@ $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$timesheet['id'])); if ($showSubmit) { - if (count($approvers) >= 1) { + if ($showApprovers) { $form->addInput(array('type'=>'combobox', 'name'=>'approver', 'style'=>'width: 200px;', @@ -124,6 +127,7 @@ $smarty->assign('timesheet', $timesheet); $smarty->assign('subtotals', $subtotals); $smarty->assign('totals', $totals); +$smarty->assign('show_approvers', $showApprovers); $smarty->assign('show_submit', $showSubmit); $smarty->assign('show_approve', $showApprove); $smarty->assign('forms', array($form->getName()=>$form->toArray())); From a8084d2e767dd2ea7e57f2348a27d4fc2da42a6f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 1 Mar 2019 23:49:49 +0000 Subject: [PATCH 0747/1848] Added project_id to tt_timesheets table. --- WEB-INF/lib/ttTimesheetHelper.class.php | 21 +++++++++++++-------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_view.tpl | 21 ++++++++++++++------- dbinstall.php | 10 ++++++---- mysql.sql | 3 ++- timesheet_view.php | 2 +- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 636b1fcf2..78e790165 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -66,6 +66,7 @@ static function createTimesheet($fields) $org_id = $user->org_id; $client_id = $fields['client_id']; + $project_id = $fields['project_id']; $name = $fields['name']; $comment = $fields['comment']; @@ -75,8 +76,8 @@ static function createTimesheet($fields) $end_date = new DateAndTime($user->date_format, $fields['end_date']); $end = $end_date->toString(DB_DATEFORMAT); - $sql = "insert into tt_timesheets (user_id, group_id, org_id, client_id, name, comment, start_date, end_date)". - " values ($user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($name). + $sql = "insert into tt_timesheets (user_id, group_id, org_id, client_id, project_id, name, comment, start_date, end_date)". + " values ($user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($project_id).", ".$mdb2->quote($name). ", ".$mdb2->quote($comment).", ".$mdb2->quote($start).", ".$mdb2->quote($end).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) @@ -175,8 +176,12 @@ static function getTimesheet($timesheet_id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $sql = "select * from tt_timesheets". - " where id = $timesheet_id and user_id = $user_id and group_id = $group_id and org_id = $org_id and status is not null"; + $sql = "select ts.*, u.name as user_name, c.name as client_name,". + " p.name as project_name from tt_timesheets ts". + " left join tt_users u on (ts.user_id = u.id)". + " left join tt_clients c on (ts.client_id = c.id)". + " left join tt_projects p on (ts.project_id = p.id)". + " where ts.id = $timesheet_id and ts.user_id = $user_id and ts.group_id = $group_id and ts.org_id = $org_id and ts.status is not null"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { if ($val = $res->fetchRow()) @@ -329,9 +334,9 @@ static function approveTimesheet($fields) { // Even if mail part below does not work, this will get us a functioning workflow // (without email notifications). $timesheet_id = $fields['timesheet_id']; - $manager_comment = $fields['comment']; + $comment = $fields['comment']; - $sql = "update tt_timesheets set approval_status = 1, manager_comment = ".$mdb2->quote($manager_comment). + $sql = "update tt_timesheets set approve_status = 1, approve_comment = ".$mdb2->quote($comment). " where id = $timesheet_id and submit_status = 1 and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -352,9 +357,9 @@ static function disapproveTimesheet($fields) { // Even if mail part below does not work, this will get us a functioning workflow // (without email notifications). $timesheet_id = $fields['timesheet_id']; - $manager_comment = $fields['comment']; + $comment = $fields['comment']; - $sql = "update tt_timesheets set approval_status = 0, manager_comment = ".$mdb2->quote($manager_comment). + $sql = "update tt_timesheets set approve_status = 0, approve_comment = ".$mdb2->quote($comment). " where id = $timesheet_id and submit_status = 1 and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 246dfca29..bd0a554dc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.47.4802 | Copyright © Anuko | +  Anuko Time Tracker 1.18.47.4803 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl index e69882530..bce187e74 100644 --- a/WEB-INF/templates/timesheet_view.tpl +++ b/WEB-INF/templates/timesheet_view.tpl @@ -53,7 +53,7 @@
- +
{$i18n.form.mail.to}: {$forms.timesheetForm.approver.control} {$forms.timesheetForm.btn_submit.control}
{if $show_approvers}{$i18n.form.mail.to}: {$forms.timesheetForm.approver.control}{/if} {$forms.timesheetForm.btn_submit.control}
- @@ -53,7 +60,7 @@ diff --git a/dbinstall.php b/dbinstall.php index 90b5669a4..e33635aaf 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11849"]) { + if ($_POST["convert11797to11850"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1118,6 +1118,8 @@ function ttExecute($sql) { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.48') set rights = replace(rights, 'manage_all_timesheets,', '')"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.48') set rights = replace(rights, 'approve_all_timesheets,', 'approve_own_timesheets,')"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.49', modified = now() where param_name = 'version_db' and param_value = '1.18.48'"); + ttExecute("ALTER TABLE `tt_timesheets` ADD `project_id` int(11) default NULL AFTER `client_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.50', modified = now() where param_name = 'version_db' and param_value = '1.18.49'"); } if ($_POST["cleanup"]) { @@ -1166,7 +1168,7 @@ function ttExecute($sql) {

DB Install

 Anuko Time Tracker 1.18.47.4803 | Copyright © Anuko | +  Anuko Time Tracker 1.18.50.4804 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl index bce187e74..76481eed9 100644 --- a/WEB-INF/templates/timesheet_view.tpl +++ b/WEB-INF/templates/timesheet_view.tpl @@ -7,19 +7,26 @@ +{if $user->behalfUser} +{/if} {if $timesheet['client_id']} {/if} +{if $timesheet['project_id']} + +{/if} +{if $timesheet['comment']} + +{/if} +{if $timesheet['approve_status'] == null} -{if $timesheet['submitter_comment']} - {/if} -{if $timesheet['submit_status']} - {/if} +{if $timesheet['approve_status'] != null} + {/if} -{if $timesheet['manager_comment']} - +{if $timesheet['approve_comment']} + {/if}
{$timesheet['name']|escape}
{$i18n.label.user}: {$timesheet['user_name']|escape}
{$i18n.label.client}: {$timesheet['client_name']|escape}
{$i18n.label.project}: {$timesheet['project_name']|escape}
{$i18n.label.comment}: {$timesheet['comment']|escape}
{$i18n.label.submitted}: {if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.comment}: {$timesheet['submitter_comment']|escape}
{$i18n.label.approved}: {if $timesheet.approval_status != null}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.approved}: {if $timesheet.approve_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.note}: {$timesheet['manager_comment']|escape}
{$i18n.label.note}: {$timesheet['approve_comment']|escape}
- +
{if $show_approvers}{$i18n.form.mail.to}: {$forms.timesheetForm.approver.control}{/if} {$forms.timesheetForm.btn_submit.control}
{if $show_approvers}{$i18n.form.mail.to}: {$forms.timesheetForm.approver.control}{/if} {$forms.timesheetForm.btn_submit.control}
-
Create database structure (v1.18.49) + Create database structure (v1.18.50)
(applies only to new installations, do not execute when updating)
@@ -1211,8 +1213,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.49)Update database structure (v1.17.97 to v1.18.50)
diff --git a/mysql.sql b/mysql.sql index 3378fc0b6..525a4769a 100644 --- a/mysql.sql +++ b/mysql.sql @@ -495,6 +495,7 @@ CREATE TABLE `tt_timesheets` ( `group_id` int(11) default NULL, # group id `org_id` int(11) default NULL, # organization id `client_id` int(11) default NULL, # client id + `project_id` int(11) default NULL, # project id `name` varchar(80) COLLATE utf8mb4_bin NOT NULL, # timesheet name `comment` text, # timesheet comment `start_date` date NOT NULL, # timesheet start date @@ -526,4 +527,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.49', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.50', now()); # TODO: change when structure changes. diff --git a/timesheet_view.php b/timesheet_view.php index 813edffb8..bde974e67 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -131,6 +131,6 @@ $smarty->assign('show_submit', $showSubmit); $smarty->assign('show_approve', $showApprove); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.timesheet')); +$smarty->assign('title', $i18n->get('title.timesheet').": ".$timesheet['start_date']." - ".$timesheet['end_date']); $smarty->assign('content_page_name', 'timesheet_view.tpl'); $smarty->display('index.tpl'); From f8112c585d6ba4dac203e9082b2229fd027f985c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 2 Mar 2019 14:46:01 +0000 Subject: [PATCH 0748/1848] A few fixes related to tt_timesheets fields renaming. --- WEB-INF/lib/ttGroupExportHelper.class.php | 7 ++++--- WEB-INF/lib/ttOrgImportHelper.class.php | 10 +++++++--- WEB-INF/templates/footer.tpl | 2 +- timesheet_view.php | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 06a3697d0..ac35cd87d 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -331,11 +331,12 @@ function writeData() { $timesheet_part = $this->indentation.' '."timesheetMap[$timesheet_item['id']]."\""; $timesheet_part .= " user_id=\"".$this->userMap[$timesheet_item['user_id']]."\""; $timesheet_part .= " client_id=\"".$this->clientMap[$timesheet_item['client_id']]."\""; + $timesheet_part .= " project_id=\"".$this->projectMap[$timesheet_item['project_id']]."\""; $timesheet_part .= " name=\"".htmlspecialchars($timesheet_item['name'])."\""; $timesheet_part .= " submit_status=\"".$timesheet_item['submit_status']."\""; - $timesheet_part .= " submitter_comment=\"".htmlspecialchars($timesheet_item['submitter_name'])."\""; - $timesheet_part .= " approval_status=\"".$timesheet_item['approval_status']."\""; - $timesheet_part .= " manager_comment=\"".htmlspecialchars($timesheet_item['manager_comment'])."\""; + $timesheet_part .= " comment=\"".htmlspecialchars($timesheet_item['comment'])."\""; + $timesheet_part .= " approve_status=\"".$timesheet_item['approve_status']."\""; + $timesheet_part .= " approve_comment=\"".htmlspecialchars($timesheet_item['approve_comment'])."\""; $timesheet_part .= " status=\"".$timesheet_item['status']."\""; $timesheet_part .= ">\n"; fwrite($this->file, $timesheet_part); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 43056bdfc..edd59b6b8 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -283,11 +283,15 @@ function startElement($parser, $name, $attrs) { 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], 'name' => $attrs['NAME'], + 'comment' => $attrs['COMMENT'], + // TODO: add handling of these. + //`start_date` date NOT NULL, # timesheet start date + //`end_date` date NOT NULL, # timesheet end date 'submit_status' => $attrs['SUBMIT_STATUS'], - 'submitter_comment' => $attrs['SUBMITTER_COMMENT'], - 'approval_status' => $attrs['APPROVAL_STATUS'], - 'manager_comment' => $attrs['MANAGER_COMMENT'], + 'approve_status' => $attrs['APPROVE_STATUS'], + 'approve_comment' => $attrs['APPROVE_COMMENT'], 'status' => $attrs['STATUS'])); if ($timesheet_id) { // Add a mapping. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bd0a554dc..02b5b048b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} +{if $show_invoice_dropdown} + + + + + + +{/if} {if $show_paid_status} @@ -294,6 +302,22 @@ License: See license.txt *} {/if} +{if $show_approved} + + + + + + +{/if} +{if $show_timesheet_dropdown} + + + + + + +{/if}
 Anuko Time Tracker 1.18.50.4804 | Copyright © Anuko | +  Anuko Time Tracker 1.18.50.4805 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_view.php b/timesheet_view.php index bde974e67..57eff61c7 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -63,7 +63,7 @@ $showApprovers = count($approvers) >= 1; } $canApprove = $user->can('approve_timesheets') || $user->can('approve_own_timesheets'); -$showApprove = $timesheet['submit_status'] && $timesheet['approval_status'] == null; +$showApprove = $timesheet['submit_status'] && $timesheet['approve_status'] == null; // Add a form with controls. $form = new Form('timesheetForm'); From 179facbe37379829ddffc9ee2e29ca6c3d969ce8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 2 Mar 2019 15:16:55 +0000 Subject: [PATCH 0749/1848] Some fixes to export/import of timesheets. --- WEB-INF/lib/ttGroupExportHelper.class.php | 4 +++- WEB-INF/lib/ttOrgImportHelper.class.php | 25 +++++++++++++---------- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index ac35cd87d..59bdc8c8d 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -333,8 +333,10 @@ function writeData() { $timesheet_part .= " client_id=\"".$this->clientMap[$timesheet_item['client_id']]."\""; $timesheet_part .= " project_id=\"".$this->projectMap[$timesheet_item['project_id']]."\""; $timesheet_part .= " name=\"".htmlspecialchars($timesheet_item['name'])."\""; - $timesheet_part .= " submit_status=\"".$timesheet_item['submit_status']."\""; $timesheet_part .= " comment=\"".htmlspecialchars($timesheet_item['comment'])."\""; + $timesheet_part .= " start_date=\"".$timesheet_item['start_date']."\""; + $timesheet_part .= " end_date=\"".$timesheet_item['end_date']."\""; + $timesheet_part .= " submit_status=\"".$timesheet_item['submit_status']."\""; $timesheet_part .= " approve_status=\"".$timesheet_item['approve_status']."\""; $timesheet_part .= " approve_comment=\"".htmlspecialchars($timesheet_item['approve_comment'])."\""; $timesheet_part .= " status=\"".$timesheet_item['status']."\""; diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index edd59b6b8..0efb6b031 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -286,9 +286,8 @@ function startElement($parser, $name, $attrs) { 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], 'name' => $attrs['NAME'], 'comment' => $attrs['COMMENT'], - // TODO: add handling of these. - //`start_date` date NOT NULL, # timesheet start date - //`end_date` date NOT NULL, # timesheet end date + 'start_date' => $attrs['START_DATE'], + 'end_date' => $attrs['END_DATE'], 'submit_status' => $attrs['SUBMIT_STATUS'], 'approve_status' => $attrs['APPROVE_STATUS'], 'approve_comment' => $attrs['APPROVE_COMMENT'], @@ -916,19 +915,23 @@ private function insertTimesheet($fields) $group_id = (int) $fields['group_id']; $org_id = (int) $fields['org_id']; $client_id = $fields['client_id']; + $project_id = $fields['project_id']; $name = $fields['name']; + $comment = $fields['comment']; + $start_date = $fields['start_date']; + $end_date = $fields['end_date']; $submit_status = $fields['submit_status']; - $submitter_comment = $fields['submitter_comment']; - $approval_status = $fields['approval_status']; - $manager_comment = $fields['manager_comment']; + $approve_status = $fields['approve_status']; + $approve_comment = $fields['approve_comment']; $status = $fields['status']; // Insert a new timesheet record. - $sql = "insert into tt_timesheets (user_id, group_id, org_id, client_id, name,". - " submit_status, submitter_comment, approval_status, manager_comment, status)". - " values($user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($name).", ". - $mdb2->quote($fields['submit_status']).", ".$mdb2->quote($fields['submiter_comment']).", ". - $mdb2->quote($fields['approval_status']).", ".$mdb2->quote($fields['manager_comment']).", ".$mdb2->quote($fields['status']).")"; + $sql = "insert into tt_timesheets (user_id, group_id, org_id, client_id, project_id, name,". + " comment, start_date, end_date, submit_status, approve_status, approve_comment, status)". + " values($user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($project_id).", ".$mdb2->quote($name).", ". + $mdb2->quote($comment).", ".$mdb2->quote($start_date).", ".$mdb2->quote($end_date).", ". + $mdb2->quote($submit_status).", ".$mdb2->quote($approve_status).", ". + $mdb2->quote($approve_comment).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 02b5b048b..ac521a4b4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.50.4805 | Copyright © Anuko | +  Anuko Time Tracker 1.18.50.4806 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 49814b0298d01a1e9efd2add26ea31cb79530f5a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 2 Mar 2019 15:50:33 +0000 Subject: [PATCH 0750/1848] Refactoring timesheet related code. --- WEB-INF/lib/ttTimesheetHelper.class.php | 16 +++++++--------- WEB-INF/templates/footer.tpl | 2 +- timesheet_add.php | 2 +- timesheet_edit.php | 6 +++--- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 78e790165..e2af4e72e 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -27,24 +27,22 @@ // +----------------------------------------------------------------------+ import('ttUserHelper'); -import('ttGroupHelper'); -import('form.ActionForm'); -import('ttReportHelper'); // Class ttTimesheetHelper is used to help with project related tasks. class ttTimesheetHelper { // The getTimesheetByName looks up a project by name. - static function getTimesheetByName($name, $user_id) { + static function getTimesheetByName($name) { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; $sql = "select id from tt_timesheets". " where group_id = $group_id and org_id = $org_id and user_id = $user_id and name = ".$mdb2->quote($name). - " and (status = 1 or status = 0)"; + " and status is not null"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); @@ -150,7 +148,7 @@ static function getInactiveTimesheets($user_id) if ($user->isClient()) $client_part = "and ts.client_id = $user->client_id"; - $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name, ts.submit_status, ts.approval_status from tt_timesheets ts". + $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name, ts.submit_status, ts.approve_status from tt_timesheets ts". " left join tt_clients c on (c.id = ts.client_id)". " where ts.status = 0 and ts.group_id = $group_id and ts.org_id = $org_id and ts.user_id = $user_id". " $client_part order by ts.name"; @@ -227,10 +225,10 @@ static function update($fields) { $timesheet_id = $fields['id']; // Timesheet we are updating. $name = $fields['name']; // Timesheet name. - $submitter_comment = $fields['submitter_comment']; - $status = $fields['status']; // Project status. + $comment = $fields['comment']; + $status = $fields['status']; // Timesheet status. - $sql = "update tt_timesheets set name = ".$mdb2->quote($name).", submitter_comment = ".$mdb2->quote($submitter_comment). + $sql = "update tt_timesheets set name = ".$mdb2->quote($name).", comment = ".$mdb2->quote($comment). ", status = ".$mdb2->quote($status). " where id = $timesheet_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ac521a4b4..c801c7659 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.50.4806 | Copyright © Anuko | +  Anuko Time Tracker 1.18.50.4807 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_add.php b/timesheet_add.php index 294886be7..09a2d3848 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -78,7 +78,7 @@ if (!ttValidDate($cl_start)) $err->add($i18n->get('error.field'), $i18n->get('label.start_date')); if (!ttValidDate($cl_finish)) $err->add($i18n->get('error.field'), $i18n->get('label.end_date')); if (!ttValidString($cl_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); - if ($err->no() && ttTimesheetHelper::getTimesheetByName($cl_name, $user_id)) $err->add($i18n->get('error.object_exists')); + if ($err->no() && ttTimesheetHelper::getTimesheetByName($cl_name)) $err->add($i18n->get('error.object_exists')); $fields = array('user_id' => $user_id, 'name' => $cl_name, 'client_id' => $cl_client, diff --git a/timesheet_edit.php b/timesheet_edit.php index d275ce5f8..7919125a9 100644 --- a/timesheet_edit.php +++ b/timesheet_edit.php @@ -53,7 +53,7 @@ $cl_status = $request->getParameter('status'); } else { $cl_name = $timesheet['name']; - $cl_comment = $timesheet['submitter_comment']; + $cl_comment = $timesheet['comment']; $cl_status = $timesheet['status']; } @@ -73,13 +73,13 @@ if ($request->getParameter('btn_save')) { if ($err->no()) { - $existing_timesheet = ttTimesheetHelper::getTimesheetByName($cl_name, $timesheet['user_id']); + $existing_timesheet = ttTimesheetHelper::getTimesheetByName($cl_name); if (!$existing_timesheet || ($cl_timesheet_id == $existing_timesheet['id'])) { // Update timesheet information. if (ttTimesheetHelper::update(array( 'id' => $cl_timesheet_id, 'name' => $cl_name, - 'submitter_comment' => $cl_comment, + 'comment' => $cl_comment, 'status' => $cl_status))) { header('Location: timesheets.php'); exit(); From d40f3b7898583d430d651cc5210994cf55dd5b13 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 2 Mar 2019 16:05:40 +0000 Subject: [PATCH 0751/1848] More refactoring on timesheet code. --- WEB-INF/lib/ttTimesheetHelper.class.php | 34 ++++++++----------------- WEB-INF/templates/footer.tpl | 2 +- timesheet_view.php | 1 + timesheets.php | 4 +-- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index e2af4e72e..743477b2c 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -83,7 +83,7 @@ static function createTimesheet($fields) $last_id = $mdb2->lastInsertID('tt_timesheets', 'id'); - // Associate time items with timesheet. + // Associate tt_log items with timesheet. if (isset($fields['client'])) $client_id = (int) $fields['client_id']; if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; // sql parts. @@ -102,31 +102,25 @@ static function createTimesheet($fields) } // The getActiveTimesheets obtains active timesheets for a user. - static function getActiveTimesheets($user_id) + static function getActiveTimesheets() { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; - // $addPaidStatus = $user->isPluginEnabled('ps'); $result = array(); - - if ($user->isClient()) - $client_part = "and ts.client_id = $user->client_id"; - - $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name, ts.submit_status, ts.approve_status from tt_timesheets ts". + $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name,". + " ts.submit_status, ts.approve_status from tt_timesheets ts". " left join tt_clients c on (c.id = ts.client_id)". " where ts.status = 1 and ts.group_id = $group_id and ts.org_id = $org_id and ts.user_id = $user_id". - " $client_part order by ts.name"; + " order by ts.name"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { - $dt = new DateAndTime(DB_DATEFORMAT); while ($val = $res->fetchRow()) { - //if ($addPaidStatus) - // $val['paid'] = ttTimesheetHelper::isPaid($val['id']); $result[] = $val; } } @@ -134,31 +128,25 @@ static function getActiveTimesheets($user_id) } // The getInactiveTimesheets obtains inactive timesheets for a user. - static function getInactiveTimesheets($user_id) + static function getInactiveTimesheets() { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; - // $addPaidStatus = $user->isPluginEnabled('ps'); $result = array(); - - if ($user->isClient()) - $client_part = "and ts.client_id = $user->client_id"; - - $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name, ts.submit_status, ts.approve_status from tt_timesheets ts". + $sql = "select ts.id, ts.name, ts.client_id, c.name as client_name,". + " ts.submit_status, ts.approve_status from tt_timesheets ts". " left join tt_clients c on (c.id = ts.client_id)". " where ts.status = 0 and ts.group_id = $group_id and ts.org_id = $org_id and ts.user_id = $user_id". - " $client_part order by ts.name"; + " order by ts.name"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { - $dt = new DateAndTime(DB_DATEFORMAT); while ($val = $res->fetchRow()) { - //if ($addPaidStatus) - // $val['paid'] = ttTimesheetHelper::isPaid($val['id']); $result[] = $val; } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c801c7659..e98faf235 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +
 Anuko Time Tracker 1.18.50.4807 | Copyright © Anuko | +  Anuko Time Tracker 1.18.50.4808 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_view.php b/timesheet_view.php index 57eff61c7..e6368a396 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -28,6 +28,7 @@ require_once('initialize.php'); import('ttTimesheetHelper'); +import('ttReportHelper'); // Access checks. if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { diff --git a/timesheets.php b/timesheets.php index 650575e69..b3b47772f 100644 --- a/timesheets.php +++ b/timesheets.php @@ -90,8 +90,8 @@ } } -$active_timesheets = ttTimesheetHelper::getActiveTimesheets($user_id); -$inactive_timesheets = ttTimesheetHelper::getInactiveTimesheets($user_id); +$active_timesheets = ttTimesheetHelper::getActiveTimesheets(); +$inactive_timesheets = ttTimesheetHelper::getInactiveTimesheets(); $showClient = $user->isPluginEnabled('cl'); From b55f038f3aa3d23376a9a68d22109f7be5ba1f09 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 2 Mar 2019 16:41:44 +0000 Subject: [PATCH 0752/1848] More timesheet related refactoring. --- WEB-INF/lib/ttTimesheetHelper.class.php | 34 +++++-------------------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_view.tpl | 3 --- 3 files changed, 7 insertions(+), 32 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 743477b2c..d03f8010a 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -181,24 +181,19 @@ static function delete($timesheet_id) { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; - // Handle time records. + // Handle tt_log records. $sql = "update tt_log set timesheet_id = null". - " where timesheet_id = $timesheet_id and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; - - // Handle expense items. - $sql = "update tt_expense_items set timesheet_id = null". - " where timesheet_id = $timesheet_id and group_id = $group_id and org_id = $org_id"; + " where timesheet_id = $timesheet_id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; // Delete timesheet. $sql = "update tt_timesheets set status = null". - " where id = $timesheet_id and group_id = $group_id and org_id = $org_id"; + " where id = $timesheet_id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } @@ -208,6 +203,7 @@ static function update($fields) { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; @@ -218,24 +214,11 @@ static function update($fields) { $sql = "update tt_timesheets set name = ".$mdb2->quote($name).", comment = ".$mdb2->quote($comment). ", status = ".$mdb2->quote($status). - " where id = $timesheet_id and group_id = $group_id and org_id = $org_id"; + " where id = $timesheet_id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } - // isUserValid function is used during access checks and determines whether user id, passed in post, is valid - // in current context. - static function isUserValid($user_id) { - // We have to cover several situations. - - global $user; - - // TODO: we are currently re-designing timesheets. - // Clients are not supposed to view them at all. - // And the post will change on_behalf user, to keep things consistent. - return false; - } - // getReportOptions prepares $options array to be used with ttReportHelper // to obtain items for timesheet view. static function getReportOptions($timesheet) { @@ -245,11 +228,6 @@ static function getReportOptions($timesheet) { $group_by_project = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $options['timesheet_id'] = $timesheet['id']; - $options['client_id'] = $timesheet['client_id']; - $options['users'] = $timesheet['user_id']; - $options['show_durarion'] = 1; - $options['show_cost'] = 1; // To include expenses. - $options['show_totals_only'] = 1; $options['group_by1'] = 'date'; if ($group_by_client || $group_by_project) { $options['group_by2'] = $group_by_client ? 'client' : 'project'; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e98faf235..c9463c886 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - {foreach $subtotals as $subtotal} - {/foreach} -
 Anuko Time Tracker 1.18.50.4808 | Copyright © Anuko | +  Anuko Time Tracker 1.18.50.4809 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl index 76481eed9..3bd8ddd20 100644 --- a/WEB-INF/templates/timesheet_view.tpl +++ b/WEB-INF/templates/timesheet_view.tpl @@ -37,20 +37,17 @@
{$group_by_header|escape} {$i18n.label.duration}{$i18n.label.cost}
{if $subtotal['name']}{$subtotal['name']|escape}{else} {/if} {$subtotal['time']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotal['cost']}{else}{$subtotal['expenses']}{/if}
 
{$i18n.label.total} {$totals['time']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
From b25ffbdc86bf97657cbca486aaa1aa068fb16288 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 2 Mar 2019 17:11:08 +0000 Subject: [PATCH 0753/1848] Some more work on timesheets. --- WEB-INF/lib/ttTimesheetHelper.class.php | 27 +++++++++++++++---------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_view.tpl | 1 + timesheet_view.php | 2 +- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index d03f8010a..1fff19554 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -240,10 +240,11 @@ static function getReportOptions($timesheet) { // getApprovers obtains a list of users who can approve a timesheet for a given user // and also have an email to receive a notification about it. - static function getApprovers($user_id) { + static function getApprovers() { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; @@ -263,20 +264,22 @@ static function getApprovers($user_id) { return $approvers; } - // submitTimesheet marks a timesheet as submitted and sends an email to an approver. + // submitTimesheet marks a timesheet as submitted and also sends an email + // to a selected approver. static function submitTimesheet($fields) { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; - // First, mark a timesheet as submitted. + // First, mark timesheet as submitted. // Even if mail part below does not work, this will get us a functioning workflow - // (without email notifications). + // without email notification. $timesheet_id = $fields['timesheet_id']; $sql = "update tt_timesheets set submit_status = 1". - " where id = $timesheet_id and group_id = $group_id and org_id = $org_id"; + " where id = $timesheet_id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -291,17 +294,18 @@ static function approveTimesheet($fields) { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; - // First, mark a timesheet as approved. + // First, mark timesheet as approved. // Even if mail part below does not work, this will get us a functioning workflow - // (without email notifications). + // without email notification. $timesheet_id = $fields['timesheet_id']; $comment = $fields['comment']; $sql = "update tt_timesheets set approve_status = 1, approve_comment = ".$mdb2->quote($comment). - " where id = $timesheet_id and submit_status = 1 and group_id = $group_id and org_id = $org_id"; + " where id = $timesheet_id and submit_status = 1 and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -314,17 +318,18 @@ static function disapproveTimesheet($fields) { global $user; $mdb2 = getConnection(); + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; - // First, mark a timesheet as disapproved. + // First, mark timesheet as disapproved. // Even if mail part below does not work, this will get us a functioning workflow - // (without email notifications). + // without email notification. $timesheet_id = $fields['timesheet_id']; $comment = $fields['comment']; $sql = "update tt_timesheets set approve_status = 0, approve_comment = ".$mdb2->quote($comment). - " where id = $timesheet_id and submit_status = 1 and group_id = $group_id and org_id = $org_id"; + " where id = $timesheet_id and submit_status = 1 and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c9463c886..e32cca999 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +
 Anuko Time Tracker 1.18.50.4809 | Copyright © Anuko | +  Anuko Time Tracker 1.18.50.4810 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl index 3bd8ddd20..77cc78bd5 100644 --- a/WEB-INF/templates/timesheet_view.tpl +++ b/WEB-INF/templates/timesheet_view.tpl @@ -49,6 +49,7 @@ {$i18n.label.total} {$totals['time']}
 
{$forms.timesheetForm.open} diff --git a/timesheet_view.php b/timesheet_view.php index e6368a396..d0198c780 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -60,7 +60,7 @@ // Determine which controls to show and obtain date for them. $showSubmit = !$timesheet['submit_status']; if ($showSubmit) { - $approvers = ttTimesheetHelper::getApprovers($timesheet['user_id']); + $approvers = ttTimesheetHelper::getApprovers(); $showApprovers = count($approvers) >= 1; } $canApprove = $user->can('approve_timesheets') || $user->can('approve_own_timesheets'); From 9f37cea35130359a3fe915c63a59cbfcdc75663f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 2 Mar 2019 17:22:56 +0000 Subject: [PATCH 0754/1848] Fixed reports for renamed timesheet field. --- WEB-INF/lib/ttReportHelper.class.php | 36 ++++++++++++++-------------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheets.tpl | 8 +++---- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index c45548610..7d2e40c56 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -285,11 +285,11 @@ static function getItems($options) { if ($user->isPluginEnabled('ts')) { $timesheet_option = $options['timesheet']; if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 1)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 1)"; else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 0)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 0)"; else if ($options['show_timesheet']) $inner_joins .= " left join tt_timesheets ts on (l.timesheet_id = ts.id)"; // Left join for timesheet nme. } @@ -371,11 +371,11 @@ static function getItems($options) { if ($user->isPluginEnabled('ts')) { $timesheet_option = $options['timesheet']; if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 1)"; + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 1)"; else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 0)"; + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 0)"; else if ($options['show_timesheet']) $inner_joins .= " left join tt_timesheets ts on (ei.timesheet_id = ts.id)"; // Left join for timesheet name. } @@ -566,11 +566,11 @@ static function getTotals($options) if ($user->isPluginEnabled('ts') && $options['timesheet']) { $timesheet_option = $options['timesheet']; if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 1)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 1)"; else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 0)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 0)"; } // Prepare a query for time items. $sql = "select $time_part $units_part $cost_part from tt_log l $left_joins $inner_joins $where"; @@ -582,11 +582,11 @@ static function getTotals($options) if ($user->isPluginEnabled('ts') && $options['timesheet']) { $timesheet_option = $options['timesheet']; if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 1)"; + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 1)"; else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 0)"; + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 0)"; } $where = ttReportHelper::getExpenseWhere($options); $sql_for_expenses = "select null as time"; @@ -1605,11 +1605,11 @@ static function makeJoinPart($options) { if ($user->isPluginEnabled('ts') && $options['timesheet']) { $timesheet_option = $options['timesheet']; if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 1)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 1)"; else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 0)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 0)"; } $join .= $inner_joins; return $join; @@ -1663,11 +1663,11 @@ static function makeJoinExpensesPart($options) { if ($user->isPluginEnabled('ts') && $options['timesheet']) { $timesheet_option = $options['timesheet']; if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 1)"; + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 1)"; else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 0)"; + $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 0)"; } $join .= $inner_joins; return $join; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e32cca999..f5c550ced 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} - {if $timesheet.approval_status == null} + {if $timesheet.approve_status == null} {else} - + {/if} @@ -66,10 +66,10 @@ {/if} - {if $timesheet.approval_status == null} + {if $timesheet.approve_status == null} {else} - + {/if} From 7aced3f6210fcd9bad8db0f6ff7d12d1f9daf62e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 2 Mar 2019 18:44:23 +0000 Subject: [PATCH 0755/1848] Dropped timesheet_id from tt_expense_items and simplified sql. --- WEB-INF/lib/ttGroupExportHelper.class.php | 1 - WEB-INF/lib/ttOrgImportHelper.class.php | 5 +-- WEB-INF/lib/ttReportHelper.class.php | 54 +++-------------------- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++-- mysql.sql | 4 +- 6 files changed, 17 insertions(+), 60 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 59bdc8c8d..7810c79e8 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -459,7 +459,6 @@ function writeData() { $expense_item_part .= " user_id=\"".$this->userMap[$expense_item['user_id']]."\""; $expense_item_part .= " client_id=\"".$this->clientMap[$expense_item['client_id']]."\""; $expense_item_part .= " project_id=\"".$this->projectMap[$expense_item['project_id']]."\""; - $expense_item_part .= " timesheet_id=\"".$this->timesheetMap[$expense_item['timesheet_id']]."\""; $expense_item_part .= " name=\"".htmlspecialchars($expense_item['name'])."\""; $expense_item_part .= " cost=\"".$expense_item['cost']."\""; $expense_item_part .= " invoice_id=\"".$this->invoiceMap[$expense_item['invoice_id']]."\""; diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 0efb6b031..c29c01cca 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -756,7 +756,6 @@ private function insertExpense($fields) { $user_id = (int) $fields['user_id']; $client_id = $fields['client_id']; $project_id = $fields['project_id']; - $timesheet_id = $fields['timesheet_id']; $name = $fields['name']; $cost = str_replace(',', '.', $fields['cost']); $invoice_id = $fields['invoice_id']; @@ -766,10 +765,10 @@ private function insertExpense($fields) { $created = ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$user->id; $sql = "insert into tt_expense_items". - " (date, user_id, group_id, org_id, client_id, project_id, timesheet_id, name,". + " (date, user_id, group_id, org_id, client_id, project_id, name,". " cost, invoice_id, approved, paid, created, created_ip, created_by, status)". " values (".$mdb2->quote($date).", $user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($project_id). - ", ".$mdb2->quote($timesheet_id).", ".$mdb2->quote($name).", ".$mdb2->quote($cost).", ".$mdb2->quote($invoice_id). + ", ".$mdb2->quote($name).", ".$mdb2->quote($cost).", ".$mdb2->quote($invoice_id). ", $approved, $paid $created, ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 7d2e40c56..abb5ab9e6 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -107,12 +107,6 @@ static function getExpenseWhere($options) { $group_id = $user->getGroup(); $org_id = $user->org_id; - // A shortcut for timesheets. - if ($options['timesheet_id']) { - $where = " where ei.timesheet_id = ".$options['timesheet_id']." and ei.group_id = $group_id and ei.org_id = $org_id"; - return $where; - } - // Prepare dropdown parts. $dropdown_parts = ''; if ($options['client_id']) @@ -122,8 +116,9 @@ static function getExpenseWhere($options) { if ($options['project_id']) $dropdown_parts .= ' and ei.project_id = '.$options['project_id']; if ($options['invoice']=='1') $dropdown_parts .= ' and ei.invoice_id is not null'; if ($options['invoice']=='2') $dropdown_parts .= ' and ei.invoice_id is null'; - if ($options['timesheet']==TIMESHEET_NOT_ASSIGNED) $dropdown_parts .= ' and ei.timesheet_id is null'; - if ($options['timesheet']==TIMESHEET_ASSIGNED) $dropdown_parts .= ' and ei.timesheet_id is not null'; + if (isset($options['timesheet']) && ($options['timesheet']!=TIMESHEET_ALL && $options['timesheet']!=TIMESHEET_NOT_ASSIGNED)) { + $dropdown_parts .= ' and 0 = 1'; // Expense items do not have a timesheet_id. + } if ($options['approved']=='1') $dropdown_parts .= ' and ei.approved = 1'; if ($options['approved']=='2') $dropdown_parts .= ' and ei.approved = 0'; if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; @@ -353,7 +348,7 @@ static function getItems($options) { if (($canViewReports || $isClient) && $options['show_invoice']) array_push($fields, 'i.name as invoice'); if ($options['show_timesheet']) - array_push($fields, 'ts.name as timesheet_name'); + array_push($fields, 'null as timesheet_name'); // Prepare sql query part for left joins. $left_joins = null; @@ -366,24 +361,10 @@ static function getItems($options) { if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; - // Prepare sql query part for inner joins. - $inner_joins = null; - if ($user->isPluginEnabled('ts')) { - $timesheet_option = $options['timesheet']; - if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; - else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 1)"; - else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 0)"; - else if ($options['show_timesheet']) - $inner_joins .= " left join tt_timesheets ts on (ei.timesheet_id = ts.id)"; // Left join for timesheet name. - } - $where = ttReportHelper::getExpenseWhere($options); // Construct sql query for expense items. - $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $inner_joins $where"; + $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $where"; // Construct a union. $sql = "($sql) union all ($sql_for_expense_items)"; @@ -577,21 +558,10 @@ static function getTotals($options) // If we have expenses, query becomes a bit more complex. if ($options['show_cost'] && $user->isPluginEnabled('ex')) { - // Prepare sql query part for inner joins. - $inner_joins = null; - if ($user->isPluginEnabled('ts') && $options['timesheet']) { - $timesheet_option = $options['timesheet']; - if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; - else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 1)"; - else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 0)"; - } $where = ttReportHelper::getExpenseWhere($options); $sql_for_expenses = "select null as time"; if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; - $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $inner_joins $where"; + $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; // Create a combined query. $combined = "select sum(time) as time"; @@ -1658,18 +1628,6 @@ static function makeJoinExpensesPart($options) { if (ttReportHelper::groupingBy('project', $options)) { $join .= ' left join tt_projects p on (ei.project_id = p.id)'; } - // Prepare inner joins. - $inner_joins = null; - if ($user->isPluginEnabled('ts') && $options['timesheet']) { - $timesheet_option = $options['timesheet']; - if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; - else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 1)"; - else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approve_status = 0)"; - } - $join .= $inner_joins; return $join; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f5c550ced..c7af2f278 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.50.4810 | Copyright © Anuko | +  Anuko Time Tracker 1.18.50.4811 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index 907f41557..91c626df0 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -30,10 +30,10 @@ {$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approve_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view} {$i18n.label.edit}{$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approval_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approve_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.view} {$i18n.label.edit}
- - - + +
 Anuko Time Tracker 1.18.50.4811 | Copyright © Anuko | +  Anuko Time Tracker 1.18.51.4812 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index e33635aaf..65a6776da 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11850"]) { + if ($_POST["convert11797to11851"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1120,6 +1120,9 @@ function ttExecute($sql) { ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.49', modified = now() where param_name = 'version_db' and param_value = '1.18.48'"); ttExecute("ALTER TABLE `tt_timesheets` ADD `project_id` int(11) default NULL AFTER `client_id`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.50', modified = now() where param_name = 'version_db' and param_value = '1.18.49'"); + ttExecute("drop index timesheet_idx on tt_expense_items"); + ttExecute("ALTER TABLE `tt_expense_items` DROP `timesheet_id`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.51', modified = now() where param_name = 'version_db' and param_value = '1.18.50'"); } if ($_POST["cleanup"]) { @@ -1168,7 +1171,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.50) + Create database structure (v1.18.51)
(applies only to new installations, do not execute when updating)
@@ -1213,8 +1216,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.50)Update database structure (v1.17.97 to v1.18.51)
diff --git a/mysql.sql b/mysql.sql index 525a4769a..bec26520c 100644 --- a/mysql.sql +++ b/mysql.sql @@ -432,7 +432,6 @@ CREATE TABLE `tt_expense_items` ( `org_id` int(11) default NULL, # organization id `client_id` int(11) default NULL, # client id `project_id` int(11) default NULL, # project id - `timesheet_id` int(11) default NULL, # timesheet id `name` text NOT NULL, # expense item name (what is an expense for) `cost` decimal(10,2) default '0.00', # item cost (including taxes, etc.) `invoice_id` int(11) default NULL, # invoice id @@ -454,7 +453,6 @@ create index user_idx on tt_expense_items(user_id); create index group_idx on tt_expense_items(group_id); create index client_idx on tt_expense_items(client_id); create index project_idx on tt_expense_items(project_id); -create index timesheet_idx on tt_expense_items(timesheet_id); create index invoice_idx on tt_expense_items(invoice_id); @@ -527,4 +525,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.50', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.51', now()); # TODO: change when structure changes. From 6385f0cb8f380c6dea36f8c2905aaa578d54d17f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 2 Mar 2019 18:58:24 +0000 Subject: [PATCH 0756/1848] Realeasing timesheets feature for user testing. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/plugins.tpl | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c7af2f278..66e0203bd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- -{if isTrue('TIMESHEET_DEBUG')} -{/if} From a6eb3d4378c5eb969eb3bd29abf0f2b4eb53feb9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 3 Mar 2019 15:11:20 +0000 Subject: [PATCH 0757/1848] Prohibited adding overlapping timesheets. --- WEB-INF/lib/ttTimesheetHelper.class.php | 40 +++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- timesheet_add.php | 1 + 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 1fff19554..f214963b2 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -374,4 +374,44 @@ static function timesheetItemsExist($fields) { return false; } + + // The overlaps function determines if a new timesheet overlaps with + // an already existing timesheet. + static function overlaps($fields) { + global $user; + $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + if (isset($fields['client_id'])) $client_id = (int) $fields['client_id']; + if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; + + $start_date = new DateAndTime($user->date_format, $fields['start_date']); + $start = $start_date->toString(DB_DATEFORMAT); + $quoted_start = $mdb2->quote($start); + + $end_date = new DateAndTime($user->date_format, $fields['end_date']); + $end = $end_date->toString(DB_DATEFORMAT); + $quoted_end = $mdb2->quote($end); + + // sql parts. + if ($client_id) $client_part = " and client_id = $client_id"; + if ($project_id) $project_part = " and project_id = $project_id"; + + $sql = "select id from tt_timesheets". + " where status is not null $client_part $project_part". + " and (($quoted_start >= start_date and $quoted_start <= end_date)". + " or ($quoted_end >= start_date and $quoted_end <= end_date))". + " and user_id = $user_id and group_id = $group_id and org_id = $org_id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if ($val['id']) { + return true; + } + } + return false; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 66e0203bd..1a9296dc9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.18.51.4812 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4813 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index 5c5941c3e..a6436bf27 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -138,12 +138,10 @@ function handlePluginCheckboxes() { {$forms.pluginsForm.approval.control}
{$forms.pluginsForm.timesheets.control}
 
-
 Anuko Time Tracker 1.18.52.4813 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4814 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_add.php b/timesheet_add.php index 09a2d3848..7c7633c6c 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -87,6 +87,7 @@ 'end_date' => $cl_finish, 'comment' => $cl_comment); if ($err->no() && !ttTimesheetHelper::timesheetItemsExist($fields)) $err->add($i18n->get('error.no_records')); + if ($err->no() && ttTimesheetHelper::overlaps($fields)) $err->add($i18n->get('error.overlap')); // Finished validating user input. if ($err->no()) { From ef5c9ae2d3e3a31f054470020b9539794e64b9d2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 3 Mar 2019 15:40:39 +0000 Subject: [PATCH 0758/1848] Added a string to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 36 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index f2ec9cf3a..b26a67041 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -463,6 +463,7 @@ 'form.report.export' => 'Exportar', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index edc7d3ecb..125dc9c50 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -473,6 +473,7 @@ 'form.report.export' => 'Exportovat', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 7bb213802..1cf78282a 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -438,6 +438,7 @@ 'form.report.export' => 'Eksport', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 02ab0484e..828d1e564 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -417,6 +417,8 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportiere', 'form.report.assign_to_invoice' => 'Zu Rechnung hinzufügen', +// TODO: translate the following. +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 6740c556a..60daeedee 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -413,6 +413,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Export', 'form.report.assign_to_invoice' => 'Assign to invoice', +'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php 'form.timesheets.active_timesheets' => 'Active Timesheets', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 5bb6eefe4..f87a44db9 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -476,6 +476,7 @@ 'form.report.export' => 'Exportar', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index e0b512e6c..9ddd0acaf 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -442,6 +442,8 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Eksport', 'form.report.assign_to_invoice' => 'Lisa arvele', +// TODO: translate the following. +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 97610c3a6..0c9ad727a 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -458,6 +458,7 @@ 'form.report.export' => 'پشتیبانی', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 91bcd40dd..84f0ab4c7 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -443,6 +443,7 @@ 'form.report.export' => 'Vie', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 0cb6764a4..1ba1d5d79 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -435,6 +435,7 @@ 'form.report.export' => 'Exporter', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index e34554651..c3072e2ae 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -426,6 +426,8 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Εξαγωγή', 'form.report.assign_to_invoice' => 'Ανάθεση στο τιμολόγιο', +// TODO: translate the following. +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2d65957bf..e037389f4 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -465,6 +465,7 @@ 'form.report.export' => 'ייצא נתונים בתבנית', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index c9e59f476..4112e3d93 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -467,6 +467,7 @@ 'form.report.export' => 'Exportálása', // TODO: is this correct? // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 7402e033e..7b61b0496 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -439,6 +439,8 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Esporta', 'form.report.assign_to_invoice' => 'Assegna alla fattura', +// TODO: translate the following. +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 5cb5305e6..09f89ea8f 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -472,6 +472,7 @@ 'form.report.export' => '輸出する', // TODO: is this correct? // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index df1311708..4e31b75f5 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -470,6 +470,7 @@ 'form.report.export' => '익스포트', // TODO: is this correct? // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index e6425badd..461dbdaf2 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -413,6 +413,8 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exporteer', 'form.report.assign_to_invoice' => 'Voeg toe aan factuur', +// TODO: translate the following. +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 09fdec8e2..8e5219cf6 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -468,6 +468,7 @@ 'form.report.export' => 'Eksporter', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 678f38e9a..e46c282d3 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -446,6 +446,7 @@ 'form.report.export' => 'Eksport', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 967bfabd2..d5a382e8c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -441,6 +441,7 @@ 'form.report.export' => 'Exportar', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9ce23328b..f337dbc0f 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -448,6 +448,7 @@ // TODO: translate the following. // 'form.report.export' => 'Export', // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 7472f0b5f..a782c0789 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -471,6 +471,7 @@ 'form.report.export' => 'Exporta', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index ac9d0d146..1664d3e4a 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -404,6 +404,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Экспортировать', 'form.report.assign_to_invoice' => 'Включить в счёт', +'form.report.assign_to_timesheet' => 'Включить в табель', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php 'form.timesheets.active_timesheets' => 'Активные табели', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index f1e0c894b..f0204668e 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -455,6 +455,7 @@ 'form.report.export' => 'Exportovať', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 17e8ca7f7..fd76109d3 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -445,6 +445,7 @@ // TODO: translate the following. // 'form.report.export' => 'Export', // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index ee49bd17f..704e2799b 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -444,6 +444,7 @@ 'form.report.export' => 'Izvoz', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 6acbcc0d8..1eaaf5f7d 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -442,6 +442,7 @@ 'form.report.export' => 'Exportera som', // TODO: translate the following. // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 614ce9426..bc6538079 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -483,6 +483,7 @@ // TODO: translate the following. // 'form.report.export' => 'Export', // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 9239d7edf..37ebf9cf6 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -455,6 +455,7 @@ // TODO: translate the following. // 'form.report.export' => 'Export', // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index fdbf657c8..c065668d0 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -463,6 +463,7 @@ // TODO: translate the following. // 'form.report.export' => 'Export', // 'form.report.assign_to_invoice' => 'Assign to invoice', +// 'form.report.assign_to_timesheet' => 'Assign to timesheet', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php // TODO: translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1a9296dc9..10008cf79 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/foreach} - {if $tax} + {if isset($tax)} diff --git a/WEB-INF/templates/invoices.tpl b/WEB-INF/templates/invoices.tpl deleted file mode 100644 index e27eb3991..000000000 --- a/WEB-INF/templates/invoices.tpl +++ /dev/null @@ -1,60 +0,0 @@ - - -{if $show_sorting_options} - {$forms.invoicesForm.open} -
-
 Anuko Time Tracker 1.18.52.4814 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4815 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9c8422b2c186feac1b572f09ab27d4c754d5e492 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 3 Mar 2019 16:00:50 +0000 Subject: [PATCH 0759/1848] Added a string to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 45 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index b26a67041..29c293a13 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -392,6 +392,7 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'actiu', // TODO: translate the following. // 'dropdown.status_inactive' => 'inactive', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 125dc9c50..a1ea87123 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -402,6 +402,7 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', // 'dropdown.status_active' => 'active', // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 1cf78282a..e1179c620 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -369,6 +369,8 @@ 'dropdown.clients' => 'Klienter', 'dropdown.select' => '--- Vælg ---', 'dropdown.select_invoice' => '--- Vælg faktura ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'Aktive', 'dropdown.status_inactive' => 'Inaktive', 'dropdown.delete' => 'Slet', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 828d1e564..0cc35fcf2 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -349,6 +349,8 @@ 'dropdown.clients' => 'Kunden', 'dropdown.select' => '--- auswählen ---', 'dropdown.select_invoice' => '--- Rechnung auswählen ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'aktiv', 'dropdown.status_inactive' => 'inaktiv', 'dropdown.delete' => 'löschen', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 60daeedee..0784ed5f2 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -341,6 +341,7 @@ 'dropdown.clients' => 'clients', 'dropdown.select' => '--- select ---', 'dropdown.select_invoice' => '--- select invoice ---', +'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'active', 'dropdown.status_inactive' => 'inactive', 'dropdown.delete' => 'delete', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index f87a44db9..58028ba52 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -392,6 +392,7 @@ 'dropdown.select' => '--- seleccionar ---', // TODO: translate the following. // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', // 'dropdown.status_active' => 'active', // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 9ddd0acaf..78971e76d 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -370,6 +370,8 @@ 'dropdown.clients' => 'kliendid', 'dropdown.select' => '--- vali ---', 'dropdown.select_invoice' => '--- vali arve ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'aktiivne', 'dropdown.status_inactive' => 'mitte aktiivne', 'dropdown.delete' => 'kustuta', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 0c9ad727a..789a64b94 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -380,6 +380,8 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', 'dropdown.select_invoice' => '--- انتخاب فاکتور ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'فعال', 'dropdown.status_inactive' => 'غیرفعال', // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 84f0ab4c7..5fb4f2baf 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -369,6 +369,8 @@ 'dropdown.clients' => 'asiakkaat', 'dropdown.select' => '--- valitse ---', 'dropdown.select_invoice' => '--- valitse lasku ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'aktiivinen', 'dropdown.status_inactive' => 'inaktiivinen', 'dropdown.delete' => 'poista', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 1ba1d5d79..9911721ad 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -361,6 +361,8 @@ 'dropdown.clients' => 'Clients', 'dropdown.select' => '--- sélectionnez ---', 'dropdown.select_invoice' => '--- selectionnez facture ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'actif', 'dropdown.status_inactive' => 'inactif', 'dropdown.delete' => 'supprimer', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index c3072e2ae..eacfa1791 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -357,6 +357,8 @@ 'dropdown.clients' => 'πελάτες', 'dropdown.select' => '--- επιλογή ---', 'dropdown.select_invoice' => '--- επιλογή τιμολόγιου ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'ενεργός', 'dropdown.status_inactive' => 'ανένεργος', 'dropdown.delete' => 'διαγραφή', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index e037389f4..d6bd794b8 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -390,6 +390,8 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', 'dropdown.select_invoice' => '--- בחר חשבונית ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'פעיל', 'dropdown.status_inactive' => 'לא פעיל', // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 4112e3d93..2f0e2d5d0 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -393,6 +393,7 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'aktív', // TODO: translate the following. // 'dropdown.status_inactive' => 'inactive', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 7b61b0496..a92ddd832 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -367,6 +367,8 @@ 'dropdown.clients' => 'clienti', 'dropdown.select' => '--- seleziona ---', 'dropdown.select_invoice' => '--- seleziona la fattura ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'attivo', 'dropdown.status_inactive' => 'inattivo', 'dropdown.delete' => 'elimina', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 09f89ea8f..80373c038 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -396,6 +396,7 @@ // 'dropdown.clients' => 'clients', // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', // 'dropdown.status_active' => 'active', // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 4e31b75f5..98c017e8e 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -400,6 +400,7 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', // 'dropdown.status_active' => 'active', // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 461dbdaf2..b6094b16c 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -344,6 +344,8 @@ 'dropdown.clients' => 'klanten', 'dropdown.select' => '--- kies ---', 'dropdown.select_invoice' => '--- kies factuur ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'actief', 'dropdown.status_inactive' => 'inactief', 'dropdown.delete' => 'verwijderen', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 8e5219cf6..bf2ff64d7 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -395,6 +395,7 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'aktiv', 'dropdown.status_inactive' => 'inaktiv', // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index e46c282d3..c471a0c0c 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -372,6 +372,8 @@ 'dropdown.clients' => 'klienci', 'dropdown.select' => '--- wybierz ---', 'dropdown.select_invoice' => '--- wybierz fakturę ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'aktywny', 'dropdown.status_inactive' => 'nieaktywny', 'dropdown.delete' => 'usuń', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index d5a382e8c..741e87fde 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -367,6 +367,8 @@ 'dropdown.clients' => 'clientes', 'dropdown.select' => '--- selecione ---', 'dropdown.select_invoice' => '--- selecione fatura ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'ativo', 'dropdown.status_inactive' => 'inativo', 'dropdown.delete' => 'apagar', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index f337dbc0f..bda088ea0 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -379,6 +379,7 @@ // 'dropdown.clients' => 'clients', // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', // 'dropdown.status_active' => 'active', // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index a782c0789..12c2a6818 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -399,6 +399,7 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'activ', 'dropdown.status_inactive' => 'inactiv', // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 1664d3e4a..d43ae31c7 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -338,6 +338,7 @@ 'dropdown.clients' => 'клиенты', 'dropdown.select' => '--- выберите ---', 'dropdown.select_invoice' => '--- выберите счёт ---', +'dropdown.select_timesheet' => '--- выберите табель ---', 'dropdown.status_active' => 'активный', 'dropdown.status_inactive' => 'неактивный', 'dropdown.delete' => 'удалить', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index f0204668e..d3c847910 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -380,6 +380,7 @@ 'dropdown.select' => '--- vyberte ---', // TODO: translate the following. // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'aktívny', 'dropdown.status_inactive' => 'neaktívny', // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index fd76109d3..88b5e8b71 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -372,6 +372,7 @@ // 'dropdown.clients' => 'clients', // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', // 'dropdown.status_active' => 'active', // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 704e2799b..e49e1d080 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -370,6 +370,8 @@ 'dropdown.clients' => 'klijenti', 'dropdown.select' => '--- odaberi ---', 'dropdown.select_invoice' => '--- odaberi račun ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'aktivan', 'dropdown.status_inactive' => 'neaktivan', 'dropdown.delete' => 'obriši', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 1eaaf5f7d..bcf5ee258 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -368,6 +368,8 @@ 'dropdown.clients' => 'Kunder', 'dropdown.select' => '--- Välj ---', 'dropdown.select_invoice' => '--- Välj faktura ---', +// TODO: translate the following. +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'Aktiv', 'dropdown.status_inactive' => 'Inaktiv', 'dropdown.delete' => 'Ta bort', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index bc6538079..62f59f629 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -407,6 +407,7 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', 'dropdown.status_active' => 'aktif', // TODO: translate the following. // 'dropdown.status_inactive' => 'inactive', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 37ebf9cf6..d3a3d9810 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -386,6 +386,7 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', // 'dropdown.status_active' => 'active', // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index c065668d0..6c8f6c0e8 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -393,6 +393,7 @@ // TODO: translate the following. // 'dropdown.select' => '--- select ---', // 'dropdown.select_invoice' => '--- select invoice ---', +// 'dropdown.select_timesheet' => '--- select timesheet ---', // 'dropdown.status_active' => 'active', // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 10008cf79..6732e72eb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + - + - + diff --git a/default.css b/default.css index 23098db42..65f3be3b9 100644 --- a/default.css +++ b/default.css @@ -273,6 +273,11 @@ span.what-is-it-text { display: inline-block; } +/* span for what format example */ +span.format-example { + color: #777777; +} + /* buttons */ input[type="submit"], input[type="button"] { -webkit-appearance: none; @@ -295,6 +300,11 @@ input[type="text"].project-rate-field { width: 236px; } +/* dropdown control with an associated format example */ +.dropdown-field-with-format-example { + width: 136px; +} + /* textareas for fields */ #description, #address, #item_name, #custom_css { width: 220px; diff --git a/group_edit.php b/group_edit.php index e1a7a5234..cea5a6a41 100644 --- a/group_edit.php +++ b/group_edit.php @@ -118,7 +118,7 @@ $form->addInput(array('type'=>'combobox','name'=>'lang','data'=>$longname_lang,'datakeys'=>array('id','name'),'value'=>$cl_lang)); $DECIMAL_MARK_OPTIONS = array(array('id'=>'.','name'=>'.'),array('id'=>',','name'=>',')); -$form->addInput(array('type'=>'combobox','name'=>'decimal_mark','style'=>'width: 150px','data'=>$DECIMAL_MARK_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_decimal_mark, +$form->addInput(array('type'=>'combobox','name'=>'decimal_mark','class'=>'dropdown-field-with-format-example','data'=>$DECIMAL_MARK_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_decimal_mark, 'onchange'=>'adjustDecimalPreview()')); $DATE_FORMAT_OPTIONS = array( @@ -127,12 +127,12 @@ array('id'=>'%d-%m-%Y','name'=>'d-m-Y'), array('id'=>'%d.%m.%Y','name'=>'d.m.Y'), array('id'=>'%d.%m.%Y %a','name'=>'d.m.Y a')); -$form->addInput(array('type'=>'combobox','name'=>'date_format','style'=>'width: 150px;','data'=>$DATE_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_date_format, +$form->addInput(array('type'=>'combobox','name'=>'date_format','class'=>'dropdown-field-with-format-example','data'=>$DATE_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_date_format, 'onchange'=>'MakeFormatPreview("date_format_preview", this);')); $TIME_FORMAT_OPTIONS = array( array('id'=>'%H:%M','name'=>$i18n->get('form.group_edit.24_hours')), array('id'=>'%I:%M %p','name'=>$i18n->get('form.group_edit.12_hours'))); -$form->addInput(array('type'=>'combobox','name'=>'time_format','style'=>'width: 150px;','data'=>$TIME_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_time_format, +$form->addInput(array('type'=>'combobox','name'=>'time_format','class'=>'dropdown-field-with-format-example','data'=>$TIME_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_time_format, 'onchange'=>'MakeFormatPreview("time_format_preview", this);')); // Prepare week start choices. diff --git a/initialize.php b/initialize.php index e161a3122..ec49622fe 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5474"); +define("APP_VERSION", "1.19.28.5475"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 524081ff8eab73ed2498a89800a73be31ce4f7a4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Apr 2021 20:10:42 +0000 Subject: [PATCH 1488/1848] Made groups.php mobile friendly and fixed a bug to set on behalf group properly when user clicks an edit icon. --- WEB-INF/templates/groups.tpl | 42 -------------------------------- WEB-INF/templates/groups2.tpl | 45 +++++++++++++++++++++++++++++++++++ group_edit.php | 5 +++- groups.php | 5 ++-- initialize.php | 2 +- 5 files changed, 52 insertions(+), 47 deletions(-) delete mode 100644 WEB-INF/templates/groups.tpl create mode 100644 WEB-INF/templates/groups2.tpl diff --git a/WEB-INF/templates/groups.tpl b/WEB-INF/templates/groups.tpl deleted file mode 100644 index 636a252b0..000000000 --- a/WEB-INF/templates/groups.tpl +++ /dev/null @@ -1,42 +0,0 @@ - -{$forms.subgroupsForm.open} -{if $group_dropdown} -
 Anuko Time Tracker 1.18.52.4815 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4816 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a7b601e885915db17770998a3ef366f64ccad8c7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 3 Mar 2019 17:40:36 +0000 Subject: [PATCH 0760/1848] A bit of refactoring in report.php for timesheet assignment. --- WEB-INF/lib/ttTimesheetHelper.class.php | 12 ++++++++- WEB-INF/templates/footer.tpl | 2 +- report.php | 33 +++++++++++++++---------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index f214963b2..22f129275 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -414,4 +414,14 @@ static function overlaps($fields) { } return false; } -} + + // The canAssign function determines if we can show controls on a report page + // for timesheet assignment. + // + // Conditions: + // - Report date range, client_id, and project_id match an existing timesheet + // with approved_status null. + static function canAssign($options) { + return false; + } +} \ No newline at end of file diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6732e72eb..f7a521961 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} - {if $show_record_custom_fields && $custom_fields && $custom_fields->timeFields} + {if $show_record_custom_fields && isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {/foreach} @@ -148,7 +148,7 @@ License: See license.txt *} {/if} {* record custom fileds *} - {if $show_record_custom_fields && $custom_fields && $custom_fields->timeFields} + {if $show_record_custom_fields && isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {assign var="control_name" value='time_field_'|cat:$timeField['id']} diff --git a/expense_edit.php b/expense_edit.php index c930956ab..f4d3c2216 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -112,11 +112,10 @@ $form->addInput(array('type'=>'combobox', 'onchange'=>'recalculateCost();', 'name'=>'predefined_expense', - 'value'=>$cl_predefined_expense, 'data'=>$predefined_expenses, 'datakeys'=>array('id', 'name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','value'=>$cl_quantity)); + $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity')); } $form->addInput(array('type'=>'textarea','maxlength'=>'800','name'=>'item_name','value'=>$cl_item_name)); $form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','value'=>$cl_cost)); diff --git a/export.php b/export.php index 2bcba2dce..b5e1206dd 100644 --- a/export.php +++ b/export.php @@ -55,5 +55,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.export')); -$smarty->assign('content_page_name', 'export.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'export2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index dd9e8a636..235e90f0e 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5467"); +define("APP_VERSION", "1.19.28.5468"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/success.php b/success.php index 6fbf8ad2a..eea4687a2 100644 --- a/success.php +++ b/success.php @@ -8,5 +8,5 @@ if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. $smarty->assign('title', $i18n->get('title.success')); -$smarty->assign('content_page_name', 'success.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'success2.tpl'); +$smarty->display('index2.tpl'); diff --git a/time.php b/time.php index a0e009b68..f6cd1daf1 100644 --- a/time.php +++ b/time.php @@ -80,7 +80,7 @@ // Determine column span for note field. $colspan = 0; if ($showClient) $colspan++; - if ($showRecordCustomFields && $custom_fields && $custom_fields->timeFields) { + if ($showRecordCustomFields && isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $colspan++; } From d6e6398d13d65f13569cb4628dba6b1c82f58127 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Apr 2021 20:33:38 +0000 Subject: [PATCH 1481/1848] Made group_add.php and group_advanced_edit.php mobile friendly. --- WEB-INF/lib/ttGroup.class.php | 30 +++------------- WEB-INF/templates/group_add.tpl | 28 --------------- WEB-INF/templates/group_add2.tpl | 22 ++++++++++++ WEB-INF/templates/group_advanced_edit.tpl | 37 -------------------- WEB-INF/templates/group_advanced_edit2.tpl | 40 ++++++++++++++++++++++ group_add.php | 7 ++-- group_advanced_edit.php | 8 ++--- initialize.php | 2 +- 8 files changed, 75 insertions(+), 99 deletions(-) delete mode 100644 WEB-INF/templates/group_add.tpl create mode 100644 WEB-INF/templates/group_add2.tpl delete mode 100644 WEB-INF/templates/group_advanced_edit.tpl create mode 100644 WEB-INF/templates/group_advanced_edit2.tpl diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index bd0f944e3..bc747e097 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -1,30 +1,6 @@ config = $val['config']; $this->configHelper = new ttConfigHelper($val['config']); + $this->custom_css = $val['custom_css']; // Set user config options. $this->punch_mode = $this->configHelper->getDefinedValue('punch_mode'); $this->allow_overlap = $this->configHelper->getDefinedValue('allow_overlap'); diff --git a/WEB-INF/templates/group_add.tpl b/WEB-INF/templates/group_add.tpl deleted file mode 100644 index 852f1b78b..000000000 --- a/WEB-INF/templates/group_add.tpl +++ /dev/null @@ -1,28 +0,0 @@ -{$forms.groupForm.open} -
 Anuko Time Tracker 1.18.52.4816 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4817 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/report.php b/report.php index 84b18b66c..b31394e27 100644 --- a/report.php +++ b/report.php @@ -73,21 +73,29 @@ $client_id = $bean->getAttribute('client'); -// Do we need to show checkboxes? We show them if we allow setting approved or paid status, -// and also when we can assign / deassign records to invoces. +// Do we need to show checkboxes? We show them in the following 4 situations: +// - We can approve items. +// - We can mark items as paid. +// - We can sssign items to invoices. +// - We can assign items to a timesheet. +// Determine these conditions separately. if ($bean->getAttribute('chapproved') && ($user->can('approve_reports') || $user->can('approve_all_eports'))) - $showForApproved = true; -if ($bean->getAttribute('chpaid') || - ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by1')) && !$user->isClient())) { - if ($user->can('manage_invoices')) - $showForInvoicesOrPaid = true; -} -$use_checkboxes = $showForApproved || $showForInvoicesOrPaid; + $useMarkApproved = true; +if ($bean->getAttribute('chpaid') && $user->can('manage_invoices')) + $useMarkPaid = true; +if ($bean->getAttribute('chinvoice') && $client_id && 'no_grouping' == $bean->getAttribute('group_by1') && !$user->isClient() && $user->can('manage_invoices')) + $useAssignToInvoice = true; +//if ($bean->getAttribute('chtimesheet') && ($user->can('track_own_time') || $user->can('track_time'))) +// $useAssignToTimesheet = true; // TODO: add a check for timesheet capability. +//if (ttTimesheetHelper::canAssign($options)) +// $useAssignToTimesheet = true; + +$use_checkboxes = $useMarkApproved || $useMarkPaid || $useAssignToInvoice || $useAssignToTimesheet; if ($use_checkboxes) $smarty->assign('use_checkboxes', true); // Controls for "Mark approved" block. -if ($showForApproved) { +if ($useMarkApproved) { $mark_approved_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); $form->addInput(array('type'=>'combobox', 'name'=>'mark_approved_select_options', @@ -103,7 +111,7 @@ } // Controls for "Mark paid" block. -if ($user->can('manage_invoices') && $bean->getAttribute('chpaid')) { +if ($useMarkPaid) { $mark_paid_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); $form->addInput(array('type'=>'combobox', 'name'=>'mark_paid_select_options', @@ -119,8 +127,7 @@ } // Controls for "Assign to invoice" block. -if ($user->can('manage_invoices') && - ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by1')) && !$user->isClient())) { +if ($useAssignToInvoice) { // Client is selected and we are displaying the invoice column. $recent_invoices = ttGroupHelper::getRecentInvoices($client_id); if ($recent_invoices) { From d5923832a32b1f43cbc6c5d74bbd064888761c80 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 3 Mar 2019 21:56:31 +0000 Subject: [PATCH 0761/1848] Added a mechanism to assign report items to timesheets. --- WEB-INF/lib/ttReportHelper.class.php | 20 ++++++++ WEB-INF/lib/ttTimesheetHelper.class.php | 62 +++++++++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 13 +++++- report.php | 57 +++++++++++++++++++---- 5 files changed, 134 insertions(+), 20 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index abb5ab9e6..ceaee4b01 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -629,6 +629,26 @@ static function assignToInvoice($invoice_id, $time_log_ids, $expense_item_ids) { } } + // The assignToTimesheet assigns a set of tt_log records to a specific timesheet. + static function assignToTimesheet($timesheet_id, $time_log_ids) { + global $user; + $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + if ($time_log_ids) { + $sql = "update tt_log l". + // TODO: inner join does not work properly for de-assignment. Improve. + // " inner join tt_timesheets ts on (ts.id = $timesheet_id and ts.approve_status is null)". + " set l.timesheet_id = ".$mdb2->quote($timesheet_id). + " where l.id in(".join(', ', $time_log_ids).") and l.user_id = $user_id and l.group_id = $group_id and l.org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); + } + } + // The markApproved marks a set of records as either approved or unapproved. static function markApproved($time_log_ids, $expense_item_ids, $approved = true) { global $user; diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 22f129275..895715108 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -415,13 +415,59 @@ static function overlaps($fields) { return false; } - // The canAssign function determines if we can show controls on a report page - // for timesheet assignment. + // The getMatchingTimesheets function retrieves a timesheet that "matches" + // a report for an option to assign report items to it. // - // Conditions: - // - Report date range, client_id, and project_id match an existing timesheet - // with approved_status null. - static function canAssign($options) { - return false; + // Condition: report range is fully enclosed in an existing timesheet with + // matching client_id and project_id and null approved_status. + static function getMatchingTimesheets($options) { + global $user; + $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // Check users. + if (isset($options['users'])) { + $comma_separated = $options['users']; + $users = explode(',', $comma_separated); + if (count($users) > 1 || $users[0] != $user->getUser()) + return false; + } + + // No timesheets for expenses. + if ($options['show_cost'] && $user->isPluginEnabled('ex')) return false; + + // Parts for client and project. + if ($options['client_id']) $client_part = ' and client_id = '.(int)$options['client_id']; + if ($options['project_id']) $project_part = ' and project_id = '.(int)$options['project_id']; + + // Determine start and end dates. + $dateFormat = $user->getDateFormat(); + if ($options['period']) + $period = new Period($options['period'], new DateAndTime($dateFormat)); + else { + $period = new Period(); + $period->setPeriod( + new DateAndTime($dateFormat, $options['period_start']), + new DateAndTime($dateFormat, $options['period_end'])); + } + $start = $period->getStartDate(DB_DATEFORMAT); + $end = $period->getEndDate(DB_DATEFORMAT); + + $result = false; + $sql = "select id, name from tt_timesheets". + " where ".$mdb2->quote($start)." >= start_date and ".$mdb2->quote($end)." <= end_date". + "$client_part $project_part". + " and user_id = $user_id and group_id = $group_id and org_id = $org_id". + " and approve_status is null and status is not null"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; } -} \ No newline at end of file +} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f7a521961..da170551e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.52.4817 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4818 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 44a6e3376..9e215c4df 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -166,7 +166,7 @@
-{if $report_items && ($use_mark_approved || $use_mark_paid || $use_assign_to_invoice)} +{if $report_items && ($use_mark_approved || $use_mark_paid || $use_assign_to_invoice || $use_assign_to_timesheet)} {if $use_mark_approved} @@ -190,7 +190,16 @@ + + {/if} + {if $use_assign_to_timesheet} + + diff --git a/report.php b/report.php index b31394e27..4a29c320b 100644 --- a/report.php +++ b/report.php @@ -31,6 +31,7 @@ import('form.ActionForm'); import('ttReportHelper'); import('ttGroupHelper'); +import('ttTimesheetHelper'); // Access check. if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports') || ttAccessAllowed('view_client_reports'))) { @@ -56,6 +57,12 @@ $cl_recent_invoice_option = $request->getParameter('recent_invoice', ($request->isPost() ? null : @$_SESSION['recent_invoice_option'])); $_SESSION['recent_invoice_option'] = $cl_recent_invoice_option; } +if ($user->isPluginEnabled('ts')) { + $cl_assign_timesheet_select_option = $request->getParameter('assign_timesheet_select_options', ($request->isPost() ? null : @$_SESSION['assign_timesheet_select_option'])); + $_SESSION['assign_timesheet_select_option'] = $cl_assign_timesheet_select_option; + $cl_timesheet_option = $request->getParameter('timesheet', ($request->isPost() ? null : @$_SESSION['timesheet_option'])); + $_SESSION['timesheet_option'] = $cl_timesheet_option; +} // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { @@ -72,6 +79,7 @@ if ($request->isPost()) $bean->loadBean(); $client_id = $bean->getAttribute('client'); +$options = ttReportHelper::getReportOptions($bean); // Do we need to show checkboxes? We show them in the following 4 situations: // - We can approve items. @@ -85,10 +93,10 @@ $useMarkPaid = true; if ($bean->getAttribute('chinvoice') && $client_id && 'no_grouping' == $bean->getAttribute('group_by1') && !$user->isClient() && $user->can('manage_invoices')) $useAssignToInvoice = true; -//if ($bean->getAttribute('chtimesheet') && ($user->can('track_own_time') || $user->can('track_time'))) -// $useAssignToTimesheet = true; // TODO: add a check for timesheet capability. -//if (ttTimesheetHelper::canAssign($options)) -// $useAssignToTimesheet = true; +if ($bean->getAttribute('chtimesheet')) { + $timesheets = ttTimesheetHelper::getMatchingTimesheets($options); + if ($timesheets) $useAssignToTimesheet = true; +} $use_checkboxes = $useMarkApproved || $useMarkPaid || $useAssignToInvoice || $useAssignToTimesheet; if ($use_checkboxes) @@ -142,17 +150,35 @@ 'datakeys'=>array('id','name'), 'value'=>$cl_recent_invoice_option, 'empty'=>array(''=>$i18n->get('dropdown.select_invoice')))); - $form->addInput(array('type'=>'submit','name'=>'btn_assign','value'=>$i18n->get('button.submit'))); + $form->addInput(array('type'=>'submit','name'=>'btn_assign_invoice','value'=>$i18n->get('button.submit'))); $smarty->assign('use_assign_to_invoice', true); } } +// Controls for "Assign to timesheet" block. +if ($useAssignToTimesheet) { + $assign_timesheet_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); + $form->addInput(array('type'=>'combobox', + 'name'=>'assign_timesheet_select_options', + 'data'=>$assign_timesheet_select_options, + 'value'=>$cl_assign_timesheet_select_option)); + $form->addInput(array('type'=>'combobox', + 'name'=>'timesheet', + 'data'=>$timesheets, + 'datakeys'=>array('id','name'), + 'value'=>$cl_timesheet_option, + 'empty'=>array(''=>$i18n->get('dropdown.select_timesheet')))); + $form->addInput(array('type'=>'submit','name'=>'btn_assign_timesheet','value'=>$i18n->get('button.submit'))); + $smarty->assign('use_assign_to_timesheet', true); +} + if ($request->isPost()) { // Validate parameters and at the same time build arrays of record ids. if (($request->getParameter('btn_mark_approved') && 2 == $request->getParameter('mark_approved_select_options')) || ($request->getParameter('btn_mark_paid') && 2 == $request->getParameter('mark_paid_select_options')) - || ($request->getParameter('btn_assign') && 2 == $request->getParameter('assign_invoice_select_options'))) { + || ($request->getParameter('btn_assign_invoice') && 2 == $request->getParameter('assign_invoice_select_options')) + || ($request->getParameter('btn_assign_timesheet') && 2 == $request->getParameter('assign_timesheet_select_options'))) { // We act on selected records. Are there any? foreach($_POST as $key => $val) { if ('log_id_' == substr($key, 0, 7)) @@ -205,7 +231,7 @@ exit(); } - if ($request->getParameter('btn_assign')) { + if ($request->getParameter('btn_assign_invoice')) { // User clicked the Submit button to assign all or some items to a recent invoice. // Determine invoice id. @@ -219,11 +245,24 @@ header('Location: report.php'); exit(); } + + if ($request->getParameter('btn_assign_timesheet')) { + // User clicked the Submit button to assign all or some items to a timesheet. + + // Determine invoice id. + $timesheet_id = $request->getParameter('timesheet'); + + // Assign as requested. + if ($time_log_ids) { + ttReportHelper::assignToTimesheet($timesheet_id, $time_log_ids); + } + // Re-display this form. + header('Location: report.php'); + exit(); + } } } // isPost -$options = ttReportHelper::getReportOptions($bean); - $report_items = ttReportHelper::getItems($options); // Store record ids in session in case user wants to act on records such as marking them all paid. if ($request->isGet() && $use_checkboxes) From 75345c7086761ea68d7e75fbffeaef64a3642fdd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 3 Mar 2019 23:57:49 +0000 Subject: [PATCH 0762/1848] Improved safety of timesheet assignment by adding an inner join. --- WEB-INF/lib/ttReportHelper.class.php | 7 ++++--- WEB-INF/lib/ttTimesheetHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index ceaee4b01..a64bb8700 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -639,9 +639,10 @@ static function assignToTimesheet($timesheet_id, $time_log_ids) { $org_id = $user->org_id; if ($time_log_ids) { - $sql = "update tt_log l". - // TODO: inner join does not work properly for de-assignment. Improve. - // " inner join tt_timesheets ts on (ts.id = $timesheet_id and ts.approve_status is null)". + if ($timesheet_id) + $inner_join = " inner join tt_timesheets ts on (ts.id = $timesheet_id and ts.approve_status is null)"; + + $sql = "update tt_log l $inner_join". " set l.timesheet_id = ".$mdb2->quote($timesheet_id). " where l.id in(".join(', ', $time_log_ids).") and l.user_id = $user_id and l.group_id = $group_id and l.org_id = $org_id"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 895715108..a348cb57b 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -442,6 +442,7 @@ static function getMatchingTimesheets($options) { // Parts for client and project. if ($options['client_id']) $client_part = ' and client_id = '.(int)$options['client_id']; if ($options['project_id']) $project_part = ' and project_id = '.(int)$options['project_id']; + // TODO: test and fix the above for NULL client and project ids... // Determine start and end dates. $dateFormat = $user->getDateFormat(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index da170551e..3f1664439 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + +
{$i18n.form.report.assign_to_invoice}: {$forms.reportViewForm.assign_invoice_select_options.control} {$forms.reportViewForm.recent_invoice.control} {$forms.reportViewForm.btn_assign.control}
{$i18n.form.report.assign_to_invoice}: {$forms.reportViewForm.assign_invoice_select_options.control} {$forms.reportViewForm.recent_invoice.control} {$forms.reportViewForm.btn_assign_invoice.control}
+
+ +
{$i18n.form.report.assign_to_timesheet}: {$forms.reportViewForm.assign_timesheet_select_options.control} {$forms.reportViewForm.timesheet.control} {$forms.reportViewForm.btn_assign_timesheet.control}
- - - -
 Anuko Time Tracker 1.18.52.4818 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4819 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 840056890d9b574fcc62fdf386db346f133baa91 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 4 Mar 2019 15:30:40 +0000 Subject: [PATCH 0763/1848] Improved sfety of inner join for timesheet assignment. --- WEB-INF/lib/ttReportHelper.class.php | 3 ++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index a64bb8700..0fa00d130 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -640,7 +640,8 @@ static function assignToTimesheet($timesheet_id, $time_log_ids) { if ($time_log_ids) { if ($timesheet_id) - $inner_join = " inner join tt_timesheets ts on (ts.id = $timesheet_id and ts.approve_status is null)"; + $inner_join = " inner join tt_timesheets ts on (ts.id = $timesheet_id". + " and ts.user_id = $user_id and ts.approve_status is null)"; $sql = "update tt_log l $inner_join". " set l.timesheet_id = ".$mdb2->quote($timesheet_id). diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3f1664439..9ce9723f4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} -{if $custom_fields && $custom_fields->timeFields} +{if isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {assign var="control_name" value='time_field_'|cat:$timeField['id']} diff --git a/initialize.php b/initialize.php index d83cfe133..f922de080 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5437"); +define("APP_VERSION", "1.19.28.5438"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 90d54c0cf..95ae5cc79 100644 --- a/time.php +++ b/time.php @@ -50,6 +50,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +$taskRequired = false; if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; @@ -136,7 +137,7 @@ // Handle time custom fields. $timeCustomFields = array(); -if ($custom_fields && $custom_fields->timeFields) { +if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $control_name = 'time_field_'.$timeField['id']; $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); @@ -195,7 +196,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); // If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { +if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) { @@ -255,6 +256,7 @@ } // Task dropdown. +$task_list = array(); if ($showTask) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', From 6ba6101125b592da256f9561824a9aade059cce4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Apr 2021 18:12:42 +0000 Subject: [PATCH 1450/1848] Addressed a few more php8 issues. --- WEB-INF/lib/ttFileHelper.class.php | 8 +++----- initialize.php | 2 +- project_add.php | 1 + project_files.php | 1 + time_files.php | 1 + 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttFileHelper.class.php b/WEB-INF/lib/ttFileHelper.class.php index 48105e417..d97ec00ee 100644 --- a/WEB-INF/lib/ttFileHelper.class.php +++ b/WEB-INF/lib/ttFileHelper.class.php @@ -362,7 +362,7 @@ private function entityHasFiles($entity_id, $entity_type) { " and entity_type = ".$mdb2->quote($entity_type)." and entity_id = $entity_id limit 1"; $res = $mdb2->query($sql); $val = $res->fetchRow(); - return $val['id'] > 0; + return (isset($val['id']) && $val['id'] > 0); } // getEntityFiles obtains a list of files for an entity. @@ -446,6 +446,7 @@ function getFile($fields) { 'file_name' => urlencode($fields['file_name'])); // url-ify the data for the POST. + $fields_string = ''; foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } $fields_string = rtrim($fields_string, '&'); @@ -461,9 +462,6 @@ function getFile($fields) { // Execute a post request. $result = curl_exec($ch); - $error = curl_error(); - $result_array2 = json_decode($result, true); - // Close connection. curl_close($ch); @@ -474,7 +472,7 @@ function getFile($fields) { $result_array = json_decode($result, true); $status = (int) $result_array['status']; - $error = $result_array['error']; + $error = isset($result_array['error']) ? $result_array['error'] : false; if ($error) { // Add an error from file storage facility if we have it. diff --git a/initialize.php b/initialize.php index f922de080..c8acab4ec 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5438"); +define("APP_VERSION", "1.19.28.5439"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/project_add.php b/project_add.php index 1b326b627..16af7a8d1 100644 --- a/project_add.php +++ b/project_add.php @@ -29,6 +29,7 @@ $all_tasks[$task_item['id']] = $task_item['name']; $show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; +$cl_name = $cl_description = ''; if ($request->isPost()) { $cl_name = trim($request->getParameter('project_name')); $cl_description = trim($request->getParameter('description')); diff --git a/project_files.php b/project_files.php index 5dd816d6c..60fc4d9e3 100644 --- a/project_files.php +++ b/project_files.php @@ -24,6 +24,7 @@ } // End of access checks. +$cl_description = ''; if ($request->isPost()) { $cl_description = trim($request->getParameter('description')); } diff --git a/time_files.php b/time_files.php index 18489aa98..210bd534c 100644 --- a/time_files.php +++ b/time_files.php @@ -24,6 +24,7 @@ } // End of access checks. +$cl_description = ''; if ($request->isPost()) { $cl_description = trim($request->getParameter('description')); } From b0dc8fc28c87679721c9817d2606e7938956eac0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Apr 2021 18:51:53 +0000 Subject: [PATCH 1451/1848] Fixed a few more php8 warnings. --- WEB-INF/lib/ttFileHelper.class.php | 11 ++++++----- WEB-INF/templates/time_edit2.tpl | 4 ++-- initialize.php | 2 +- time.php | 4 ++-- time_edit.php | 14 ++++++++------ 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/WEB-INF/lib/ttFileHelper.class.php b/WEB-INF/lib/ttFileHelper.class.php index d97ec00ee..859435a2b 100644 --- a/WEB-INF/lib/ttFileHelper.class.php +++ b/WEB-INF/lib/ttFileHelper.class.php @@ -137,11 +137,12 @@ function putFile($fields) { 'entity_type' => urlencode($fields['entity_type']), 'entity_id' => urlencode($fields['entity_id']), 'file_name' => urlencode($fields['file_name']), - 'description' => urlencode($fields['description']), + 'description' => urlencode(isset($fields['description']) ? $fields['description'] : ''), 'content' => urlencode(base64_encode(file_get_contents($_FILES['newfile']['tmp_name']))) ); // url-ify the data for the POST. + $fields_string = ''; foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } $fields_string = rtrim($fields_string, '&'); @@ -171,7 +172,7 @@ function putFile($fields) { $result_array = json_decode($result, true); $file_id = (int) $result_array['file_id']; $file_key = $result_array['file_key']; - $error = $result_array['error']; + $error = isset($result_array['error']) ? $result_array['error'] : false; if ($error || !$file_id || !$file_key) { if ($error) { @@ -186,7 +187,7 @@ function putFile($fields) { $entity_type = $mdb2->quote($fields['entity_type']); $entity_id = (int) $fields['entity_id']; $file_name = $mdb2->quote($fields['file_name']); - $description = $mdb2->quote($fields['description']); + $description = $mdb2->quote(isset($fields['description']) ? $fields['description'] : ''); $created = 'now()'; $created_ip = $mdb2->quote($_SERVER['REMOTE_ADDR']); $created_by = $user->id; @@ -295,6 +296,7 @@ function deleteEntityFiles($entity_id, $entity_type) { 'entity_id' => urlencode($entity_id)); // url-ify the data for the POST. + $fields_string = ''; foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } $fields_string = rtrim($fields_string, '&'); @@ -320,7 +322,7 @@ function deleteEntityFiles($entity_id, $entity_type) { $result_array = json_decode($result, true); $status = (int) $result_array['status']; - $error = $result_array['error']; + $error = isset($result_array['error']) ? $result_array['error'] : false; if ($error) { // Add an error from file storage facility if we have it. @@ -336,7 +338,6 @@ function deleteEntityFiles($entity_id, $entity_type) { // records from the database. // Delete all entity records from the database. - $file_id = $fields['id']; $sql = "delete from tt_files". " where entity_id = $entity_id". " and entity_type = ".$mdb2->quote($entity_type). diff --git a/WEB-INF/templates/time_edit2.tpl b/WEB-INF/templates/time_edit2.tpl index 2f8f9e985..8425965b9 100644 --- a/WEB-INF/templates/time_edit2.tpl +++ b/WEB-INF/templates/time_edit2.tpl @@ -4,7 +4,7 @@ License: See license.txt *} {include file="time_script.tpl"} {* Conditional include of confirmSave handler. *} -{if $confirm_save} +{if isset($confirm_save) && $confirm_save} - -
 Anuko Time Tracker 1.18.52.4819 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4820 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From f2b99f6c76ea5684968ac22300c98eae0777f540 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 4 Mar 2019 17:13:44 +0000 Subject: [PATCH 0764/1848] Improvements to timesheet assignment algorithm. --- WEB-INF/lib/ttReportHelper.class.php | 13 +++++++++++-- WEB-INF/lib/ttTimesheetHelper.class.php | 5 ++--- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 0fa00d130..0cc2702cb 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -639,9 +639,18 @@ static function assignToTimesheet($timesheet_id, $time_log_ids) { $org_id = $user->org_id; if ($time_log_ids) { - if ($timesheet_id) + // Use inner join as a protection mechanism not to do anything with "acted upon" timesheets. + // Allow oprations only with pending timesheets. + if ($timesheet_id) { + // Assigning a timesheet to records. $inner_join = " inner join tt_timesheets ts on (ts.id = $timesheet_id". - " and ts.user_id = $user_id and ts.approve_status is null)"; + " and ts.user_id = $user_id and ts.approve_status is null". // Timesheet to assign to is pending. + // Part below: existing timesheet either not exists or is also pending. + " and (l.timesheet_id is null or (l.timesheet_id = ts.id and ts.approve_status is null)))"; + } else { + $inner_join = " inner join tt_timesheets ts on (ts.id = l.timesheet_id". + " and ts.user_id = $user_id and ts.approve_status is null)"; // Do not deassign from acted-upon timesheets. + } $sql = "update tt_log l $inner_join". " set l.timesheet_id = ".$mdb2->quote($timesheet_id). diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index a348cb57b..c2841c88d 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -440,9 +440,8 @@ static function getMatchingTimesheets($options) { if ($options['show_cost'] && $user->isPluginEnabled('ex')) return false; // Parts for client and project. - if ($options['client_id']) $client_part = ' and client_id = '.(int)$options['client_id']; - if ($options['project_id']) $project_part = ' and project_id = '.(int)$options['project_id']; - // TODO: test and fix the above for NULL client and project ids... + if ($options['client_id']) $client_part = ' and (client_id is null or client_id = '.(int)$options['client_id'].')'; + if ($options['project_id']) $project_part = ' and (project_id is null or project_id = '.(int)$options['project_id'].')'; // Determine start and end dates. $dateFormat = $user->getDateFormat(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9ce9723f4..fea07f597 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/timesheet_edit.php b/timesheet_edit.php index 7919125a9..b883b20e9 100644 --- a/timesheet_edit.php +++ b/timesheet_edit.php @@ -57,6 +57,11 @@ $cl_status = $timesheet['status']; } +// Can we delete this timesheet? +$canDelete = $timesheet['approve_status'] != 1 + || (($user->id == $timesheet['user_id'] && $user->can('approve_own_timesheets')) + || ($user->id != $timesheet['user_id'] && $user->can('approve_timesheets'))); + $form = new Form('timesheetForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_timesheet_id)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'timesheet_name','style'=>'width: 250px;','value'=>$cl_name)); @@ -64,7 +69,7 @@ $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +if ($canDelete) $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); if ($request->isPost()) { // Validate user input. @@ -90,7 +95,7 @@ } } - if ($request->getParameter('btn_delete')) { + if ($request->getParameter('btn_delete') && $canDelete) { header("Location: timesheet_delete.php?id=$cl_timesheet_id"); exit(); } @@ -98,8 +103,7 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.timesheetForm.timesheet_name.focus()"'); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', $show_tasks); +$smarty->assign('can_delete', $canDelete); $smarty->assign('title', $i18n->get('title.edit_timesheet')); $smarty->assign('content_page_name', 'timesheet_edit.tpl'); $smarty->display('index.tpl'); From 566ab32f690c6e281a85c79345af95dca9a97898 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 5 Mar 2019 15:43:17 +0000 Subject: [PATCH 0766/1848] Implemented sending email to timesheet approver. --- WEB-INF/lib/ttTimesheetHelper.class.php | 65 +++++++++++++++++++++++-- WEB-INF/lib/ttUser.class.php | 5 ++ WEB-INF/resources/en.lang.php | 10 ++++ WEB-INF/templates/footer.tpl | 2 +- timesheet_view.php | 13 +++-- 5 files changed, 87 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index c2841c88d..391e93275 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -264,6 +264,29 @@ static function getApprovers() { return $approvers; } + // getApprover obtains approver properties such as name and email. + static function getApprover($user_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $rank = ttUserHelper::getUserRank($user->getUser()); + $sql = "select u.name, u.email". + " from tt_users u". + " left join tt_roles r on (r.id = u.role_id)". + " where u.id = $user_id and u.status = 1 and u.email is not null and u.group_id = $group_id and u.org_id = $org_id". + " and (r.rank > $rank and r.rights like '%approve_timesheets%')"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + if ($val = $res->fetchRow()) { + return $val; + } + } + return false; + } + // submitTimesheet marks a timesheet as submitted and also sends an email // to a selected approver. static function submitTimesheet($fields) { @@ -281,10 +304,46 @@ static function submitTimesheet($fields) { $sql = "update tt_timesheets set submit_status = 1". " where id = $timesheet_id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; + return (!is_a($affected, 'PEAR_Error')); + } + + // sendSubmitEmail sends a notification to an approver about a timesheet submit. + static function sendSubmitEmail($fields) { + global $i18n; + global $user; + + // Send email to a selected approver. + if (!$fields['approver_id']) return true; // No approver, nothing to do. - // TODO: send email to approver here... - // $approver_id = $fields['approver_id']; + $approver = ttTimesheetHelper::getApprover($fields['approver_id']); + if (!$approver) return false; // Invalid approver id. + + $fields['to'] = $approver['email']; + $fields['subject'] = $i18n->get('form.timesheet_view.submit_subject'); + $fields['body'] = sprintf($i18n->get('form.timesheet_view.submit_body'), $user->getName()); + + return ttTimesheetHelper::sendEmail($fields); + } + + // sendEmail is a generic finction that sends a timesheet related email. + // TODO: perhaps make it even more generic for the entire application. + static function sendEmail($fields, $html = true) { + global $i18n; + global $user; + + // Send email. + import('mail.Mailer'); + $mailer = new Mailer(); + $mailer->setCharSet(CHARSET); + if ($html) + $mailer->setContentType('text/html'); + $mailer->setSender(SENDER); + $mailer->setReceiver($fields['to']); + if (!empty($user->bcc_email)) + $mailer->setReceiverBCC($user->bcc_email); + $mailer->setMailMode(MAIL_MODE); + if (!$mailer->send($fields['subject'], $fields['body'])) + return false; return true; } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 28eeebcfd..4a2320b40 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -167,6 +167,11 @@ function getUser() { return ($this->behalfUser ? $this->behalfUser->id : $this->id); } + // getName returns user name on behalf of whom the current user is operating. + function getName() { + return ($this->behalfUser ? $this->behalfUser->name : $this->name); + } + // getQuotaPercent returns quota percent for active user. function getQuotaPercent() { return ($this->behalfUser ? $this->behalfUser->quota_percent : $this->quota_percent); diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 0784ed5f2..9e2a364c5 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -551,4 +551,14 @@ 'role.admin.label' => 'Administrator', 'role.admin.low_case_label' => 'administrator', 'role.admin.description' => 'Site adminsitrator.', + +// Timesheet View form. See example at https://timetracker.anuko.com/timesheet_view.php. +// TODO: improve wording, then fill in other translation files. +'form.timesheet_view.submit_subject' => 'Timesheet approval request', +'form.timesheet_view.submit_body' => "A new timesheet requires approval.

User: %s.", +'form.timesheet_view.approve_subject' => 'Timesheet approved', +'form.timesheet_view.approve_body' => "Dear User,\n\nYour timesheet %s was approved.", +'form.timesheet_view.disapprove_subject' => 'Timesheet not approved', +'form.timesheet_view.disapprove_subject' => "Dear User,\n\nYour timesheet %s was not approved.\n\n%s", +'form.timesheet_view.success_message' => 'Notification sent by email.', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b1be81d21..fe8ac9ff1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@

 Anuko Time Tracker 1.18.52.4820 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4821 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From d013f6f24164f5476cd270ceee3d5b7edf74ce79 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 4 Mar 2019 18:41:53 +0000 Subject: [PATCH 0765/1848] Added a check for timesheet delete operation possibility. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/timesheet_edit.tpl | 2 +- timesheet_edit.php | 12 ++++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fea07f597..b1be81d21 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - +
 Anuko Time Tracker 1.18.52.4821 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4822 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/timesheet_edit.tpl b/WEB-INF/templates/timesheet_edit.tpl index 5848c5710..ec1123608 100644 --- a/WEB-INF/templates/timesheet_edit.tpl +++ b/WEB-INF/templates/timesheet_edit.tpl @@ -25,7 +25,7 @@
{$forms.timesheetForm.btn_save.control} {$forms.timesheetForm.btn_delete.control}{$forms.timesheetForm.btn_save.control} {if $can_delete}{$forms.timesheetForm.btn_delete.control}{/if}
- {/if} -{if $template_dropdown} +{if (isset($template_dropdown) && $template_dropdown)} diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 5834ba3cc..67c5062cc 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -46,23 +46,25 @@ var task_names = new Array(); // Prepare an array of template ids for projects. var template_ids = new Array(); -{if $bind_templates_with_projects} +{if (isset($bind_templates_with_projects) && $bind_templates_with_projects)} {foreach $project_list as $project} template_ids[{$project.id}] = "{$project.templates}"; {/foreach} {/if} // Prepare an array of template names. var template_names = new Array(); -{if $bind_templates_with_projects} +{if (isset($bind_templates_with_projects) && $bind_templates_with_projects) && isset($template_list)} {foreach $template_list as $template} template_names[{$template.id}] = "{$template.name|escape:'javascript'}"; {/foreach} {/if} // Prepare an array of template bodies. var template_bodies = new Array(); -{foreach $template_list as $template} - template_bodies[{$template.id}] = "{$template.content|escape:'javascript'}"; -{/foreach} +{if isset($template_list)} + {foreach $template_list as $template} + template_bodies[{$template.id}] = "{$template.content|escape:'javascript'}"; + {/foreach} +{/if} // The fillNote function populates the Note field with a selected template body. function fillNote(id) { @@ -189,7 +191,7 @@ function fillTaskDropdown(id) { // The fillTemplateDropdown function populates the template combo box with // templates associated with a selected project (project id is passed here as id). function fillTemplateDropdown(id) { -{if !$bind_templates_with_projects} +{if (!isset($bind_templates_with_projects) || !$bind_templates_with_projects)} return; // Do nothing if we are not binding templates with projects, {/if} @@ -234,7 +236,7 @@ function fillTemplateDropdown(id) { // The prepopulateNote function populates the note field with first found template body in Template dropdown. function prepopulateNote() { - {if !$prepopulate_note} + {if (!isset($prepopulate_note) || !$prepopulate_note)} return; {/if} var dropdown = document.getElementById("template"); diff --git a/initialize.php b/initialize.php index a739b939e..d34aa56d5 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5433"); +define("APP_VERSION", "1.19.28.5434"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 66cf4da4b..90d54c0cf 100644 --- a/time.php +++ b/time.php @@ -225,6 +225,7 @@ $largeScreenCalendarRowSpan += 2; // Client dropdown. + $client_list = array(); if ($showClient) { $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. From 1ce02deaaa3f2c66162a55fe0b62acb1dd94739a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Apr 2021 22:11:54 +0000 Subject: [PATCH 1445/1848] Addressed a few more php8 warnings. --- WEB-INF/lib/ttTimeHelper.class.php | 4 ++-- WEB-INF/templates/header2.tpl | 8 ++++---- WEB-INF/templates/time_edit2.tpl | 2 +- initialize.php | 2 +- time_edit.php | 2 ++ 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index af2a436a5..78e7a2cf5 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -424,10 +424,10 @@ static function insert($fields) $client = $fields['client']; $project = $fields['project']; $task = $fields['task']; - $invoice = $fields['invoice']; + $invoice = isset($fields['invoice']) ? $fields['invoice'] : null; $note = $fields['note']; $billable = $fields['billable']; - $paid = $fields['paid']; + $paid = isset($fields['paid']) ? $fields['paid'] : null; $start = ttTimeHelper::to24HourFormat($start); if ($finish) { diff --git a/WEB-INF/templates/header2.tpl b/WEB-INF/templates/header2.tpl index 74ccb1adc..65af554ee 100644 --- a/WEB-INF/templates/header2.tpl +++ b/WEB-INF/templates/header2.tpl @@ -21,7 +21,7 @@ - + -{if $template_dropdown} +{if (isset($template_dropdown) && $template_dropdown)} diff --git a/initialize.php b/initialize.php index d34aa56d5..be7ff2576 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5434"); +define("APP_VERSION", "1.19.28.5435"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time_edit.php b/time_edit.php index 774add2c6..31ee2d137 100644 --- a/time_edit.php +++ b/time_edit.php @@ -76,6 +76,7 @@ $cl_billable = 1; if ($showBillable) $cl_billable = $request->getParameter('billable'); + $cl_paid = 0; if ($showPaidStatus) $cl_paid = $request->getParameter('paid'); } else { @@ -166,6 +167,7 @@ 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Client dropdown. + $client_list = array(); if ($showClient) { $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. From 0c78b2191214590d9468be1392b547913ddcb10c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Apr 2021 00:00:57 +0000 Subject: [PATCH 1446/1848] Eliminated a few more php8 warnings. --- WEB-INF/lib/ttGroupHelper.class.php | 6 +++++- WEB-INF/lib/ttUser.class.php | 5 ++++- WEB-INF/templates/header.tpl | 6 +++--- plugins.php | 1 + 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 895fa1dc6..6da527085 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -336,6 +336,8 @@ static function getActiveProjects($includeFiles = false) $group_id = $user->getGroup(); $org_id = $user->org_id; + $filePart = ''; + $fileJoin = ''; if ($includeFiles) { $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; $fileJoin = " left join (select distinct entity_id from tt_files". @@ -364,6 +366,8 @@ static function getInactiveProjects($includeFiles = false) $group_id = $user->getGroup(); $org_id = $user->org_id; + $filePart = ''; + $fileJoin = ''; if ($includeFiles) { $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; $fileJoin = " left join (select distinct entity_id from tt_files". @@ -502,7 +506,7 @@ static function getActiveUsers($options = null) { return false; while ($val = $res->fetchRow()) { // Localize top manager role name, as it is not localized in db. - if ($val['rank'] == 512) + if (isset($val['rank']) && $val['rank'] == 512) $val['role_name'] = $i18n->get('role.top_manager.label'); $user_list[] = $val; } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index fcfc1b9d5..ca0b759e8 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -694,10 +694,13 @@ function adjustBehalfId() { function updateGroup($fields) { $mdb2 = getConnection(); - $group_id = $fields['group_id']; + $group_id = isset($fields['group_id']) ? $fields['group_id'] : null; if ($group_id && !$this->isGroupValid($group_id)) return false; if (!$group_id) $group_id = $this->getGroup(); + $name_part = $description_part = $currency_part = $lang_part = $decimal_mark_part = $date_format_part = $time_format_part = + $week_start_part = $tracking_mode_part = $project_required_part = $record_type_part = $bcc_email_part = $allow_ip_part = + $plugins_part = $config_part = $custom_css_part = $lock_spec_part = $holidays_part = $workday_minutes_part = ''; if (isset($fields['name'])) $name_part = ', name = '.$mdb2->quote($fields['name']); if (isset($fields['description'])) $description_part = ', description = '.$mdb2->quote($fields['description']); if (isset($fields['currency'])) $currency_part = ', currency = '.$mdb2->quote($fields['currency']); diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 10640cb29..29ec892d3 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -5,7 +5,7 @@ -{if $i18n.language.rtl} +{if (isset($i18n.language.rtl) && $i18n.language.rtl)} {/if} {if $user->getCustomCss()} @@ -20,7 +20,7 @@ - + {assign var="tab_width" value="700"} @@ -176,7 +176,7 @@ {if $title}
 Anuko Time Tracker 1.18.52.4822 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4823 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_view.php b/timesheet_view.php index d0198c780..0a3cc7201 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -51,6 +51,7 @@ if ($request->isPost()) { $cl_comment = trim($request->getParameter('comment')); + $approver_id = $request->getParameter('approver'); } $options = ttTimesheetHelper::getReportOptions($timesheet); @@ -76,7 +77,7 @@ 'name'=>'approver', 'style'=>'width: 200px;', 'data'=>$approvers, - 'datakeys'=>array('id','name'))); + 'datakeys'=>array('id','name','email'))); } $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); } @@ -92,12 +93,16 @@ if ($request->getParameter('btn_submit')) { $fields = array('timesheet_id' => $timesheet['id'], 'approver_id' => $approver_id); // TODO: obtain (and check) approver id above during access checks. - if (ttTimesheetHelper::submitTimesheet($fields)) { + if (!ttTimesheetHelper::submitTimesheet($fields)) + $err->add($i18n->get('error.db')); + if ($err->no() && !ttTimesheetHelper::sendSubmitEmail($fields)) { + $err->add($i18n->get('error.mail_send')); + } + if ($err->no()) { // Redirect to self. header('Location: timesheet_view.php?id='.$timesheet['id']); exit(); - } else - $err->add($i18n->get('error.db')); + } } if ($request->getParameter('btn_approve')) { From f3fe1f260bbb449253c86a6e08dae62957df468a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 5 Mar 2019 15:57:11 +0000 Subject: [PATCH 0767/1848] Renamed a function for clarity. --- WEB-INF/lib/ttTimesheetHelper.class.php | 8 ++------ WEB-INF/templates/footer.tpl | 2 +- timesheet_view.php | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 391e93275..9d4919dcc 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -287,9 +287,8 @@ static function getApprover($user_id) { return false; } - // submitTimesheet marks a timesheet as submitted and also sends an email - // to a selected approver. - static function submitTimesheet($fields) { + // markSubmitted marks a timesheet as submitted. + static function markSubmitted($fields) { global $user; $mdb2 = getConnection(); @@ -297,9 +296,6 @@ static function submitTimesheet($fields) { $group_id = $user->getGroup(); $org_id = $user->org_id; - // First, mark timesheet as submitted. - // Even if mail part below does not work, this will get us a functioning workflow - // without email notification. $timesheet_id = $fields['timesheet_id']; $sql = "update tt_timesheets set submit_status = 1". " where id = $timesheet_id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fe8ac9ff1..06ab61412 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.52.4823 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4824 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_view.php b/timesheet_view.php index 0a3cc7201..3dc80253d 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -93,7 +93,7 @@ if ($request->getParameter('btn_submit')) { $fields = array('timesheet_id' => $timesheet['id'], 'approver_id' => $approver_id); // TODO: obtain (and check) approver id above during access checks. - if (!ttTimesheetHelper::submitTimesheet($fields)) + if (!ttTimesheetHelper::markSubmitted($fields)) $err->add($i18n->get('error.db')); if ($err->no() && !ttTimesheetHelper::sendSubmitEmail($fields)) { $err->add($i18n->get('error.mail_send')); From bac0563d910ee1c055db5e2ad9ec4c6d08846f7f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 5 Mar 2019 16:29:17 +0000 Subject: [PATCH 0768/1848] Added timesheet approval email notification. --- WEB-INF/lib/ttTimesheetHelper.class.php | 29 +++++++++++++++++-------- WEB-INF/resources/en.lang.php | 5 ++--- WEB-INF/templates/footer.tpl | 2 +- timesheet_view.php | 14 ++++++++---- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 9d4919dcc..ca837fe7f 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -321,6 +321,23 @@ static function sendSubmitEmail($fields) { return ttTimesheetHelper::sendEmail($fields); } + // sendApprovedEmail sends a notification to user about a timesheet approval. + static function sendApprovedEmail($fields) { + global $i18n; + global $user; + + // Obtain user email. + $user_details = $user->getUserDetails($fields['user_id']); + $email = $user_details['email']; + if (!$email) return true; // No email to send to, nothing to do. + + $fields['to'] = $email; + $fields['subject'] = $i18n->get('form.timesheet_view.approve_subject'); + $fields['body'] = sprintf($i18n->get('form.timesheet_view.approve_body'), htmlspecialchars($fields['name'])); + + return ttTimesheetHelper::sendEmail($fields); + } + // sendEmail is a generic finction that sends a timesheet related email. // TODO: perhaps make it even more generic for the entire application. static function sendEmail($fields, $html = true) { @@ -344,8 +361,8 @@ static function sendEmail($fields, $html = true) { return true; } - // approveTimesheet marks a timesheet as approved and sends an email to submitter. - static function approveTimesheet($fields) { + // markApproved marks a timesheet as approved. + static function markApproved($fields) { global $user; $mdb2 = getConnection(); @@ -353,19 +370,13 @@ static function approveTimesheet($fields) { $group_id = $user->getGroup(); $org_id = $user->org_id; - // First, mark timesheet as approved. - // Even if mail part below does not work, this will get us a functioning workflow - // without email notification. $timesheet_id = $fields['timesheet_id']; $comment = $fields['comment']; $sql = "update tt_timesheets set approve_status = 1, approve_comment = ".$mdb2->quote($comment). " where id = $timesheet_id and submit_status = 1 and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; - - // TODO: send email to submitter here... - return true; + return (!is_a($affected, 'PEAR_Error')); } // disapproveTimesheet marks a timesheet as approved and sends an email to submitter. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 9e2a364c5..fdf72ae68 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -557,8 +557,7 @@ 'form.timesheet_view.submit_subject' => 'Timesheet approval request', 'form.timesheet_view.submit_body' => "A new timesheet requires approval.

User: %s.", 'form.timesheet_view.approve_subject' => 'Timesheet approved', -'form.timesheet_view.approve_body' => "Dear User,\n\nYour timesheet %s was approved.", +'form.timesheet_view.approve_body' => "Your timesheet %s was approved.", 'form.timesheet_view.disapprove_subject' => 'Timesheet not approved', -'form.timesheet_view.disapprove_subject' => "Dear User,\n\nYour timesheet %s was not approved.\n\n%s", -'form.timesheet_view.success_message' => 'Notification sent by email.', +'form.timesheet_view.disapprove_subject' => "Your timesheet %s was not approved.", ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 06ab61412..1a85ccfc2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} - {* {* column for edit icons *} + {* column for edit icons *} {/if} @@ -172,7 +172,12 @@ {if 1 == $item.type}{/if} {if 2 == $item.type}{/if} {/if} - {* {* column for edit icons *} + {if $item.approved || $item.timesheet_id || $item.invoice_id} + + {else} + {if 1 == $item.type}{/if} + {if 2 == $item.type}{/if} + {/if} {if $note_on_separate_row && $bean->getAttribute('chnote') && $item.note} @@ -222,7 +227,7 @@ {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} - {* {* column for edit icons *} + {* column for edit icons *} {/if} @@ -264,7 +269,7 @@ {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} - {* {* column for edit icons *} + {* column for edit icons *} {/if}
 Anuko Time Tracker 1.18.52.4824 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4825 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_view.php b/timesheet_view.php index 3dc80253d..f6e8aac71 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -92,7 +92,7 @@ if ($request->isPost()) { if ($request->getParameter('btn_submit')) { $fields = array('timesheet_id' => $timesheet['id'], - 'approver_id' => $approver_id); // TODO: obtain (and check) approver id above during access checks. + 'approver_id' => $approver_id); if (!ttTimesheetHelper::markSubmitted($fields)) $err->add($i18n->get('error.db')); if ($err->no() && !ttTimesheetHelper::sendSubmitEmail($fields)) { @@ -107,13 +107,19 @@ if ($request->getParameter('btn_approve')) { $fields = array('timesheet_id' => $timesheet['id'], + 'name' => $timesheet['name'], + 'user_id' => $timesheet['user_id'], 'comment' => $cl_comment); - if (ttTimesheetHelper::approveTimesheet($fields)) { + if (!ttTimesheetHelper::markApproved($fields)) + $err->add($i18n->get('error.db')); + if ($err->no() && !ttTimesheetHelper::sendApprovedEmail($fields)) { + $err->add($i18n->get('error.mail_send')); + } + if ($err->no()) { // Redirect to self. header('Location: timesheet_view.php?id='.$timesheet['id']); exit(); - } else - $err->add($i18n->get('error.db')); + } } if ($request->getParameter('btn_disapprove')) { From 53c471451a8cb9e0fefd6d5907220bafdd77b53e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 5 Mar 2019 17:03:41 +0000 Subject: [PATCH 0769/1848] Timesheet email workflow done. --- WEB-INF/lib/ttTimesheetHelper.class.php | 31 +++++++++++++++++-------- WEB-INF/resources/en.lang.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- timesheet_view.php | 12 +++++++--- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index ca837fe7f..240d91312 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -333,7 +333,24 @@ static function sendApprovedEmail($fields) { $fields['to'] = $email; $fields['subject'] = $i18n->get('form.timesheet_view.approve_subject'); - $fields['body'] = sprintf($i18n->get('form.timesheet_view.approve_body'), htmlspecialchars($fields['name'])); + $fields['body'] = sprintf($i18n->get('form.timesheet_view.approve_body'), htmlspecialchars($fields['name']), htmlspecialchars($fields['comment'])); + + return ttTimesheetHelper::sendEmail($fields); + } + + // sendDisapprovedEmail sends a notification to user about a timesheet disapproval. + static function sendDisapprovedEmail($fields) { + global $i18n; + global $user; + + // Obtain user email. + $user_details = $user->getUserDetails($fields['user_id']); + $email = $user_details['email']; + if (!$email) return true; // No email to send to, nothing to do. + + $fields['to'] = $email; + $fields['subject'] = $i18n->get('form.timesheet_view.disapprove_subject'); + $fields['body'] = sprintf($i18n->get('form.timesheet_view.disapprove_body'), htmlspecialchars($fields['name']), htmlspecialchars($fields['comment'])); return ttTimesheetHelper::sendEmail($fields); } @@ -379,8 +396,8 @@ static function markApproved($fields) { return (!is_a($affected, 'PEAR_Error')); } - // disapproveTimesheet marks a timesheet as approved and sends an email to submitter. - static function disapproveTimesheet($fields) { + // markDisapproved marks a timesheet as not approved. + static function markDisapproved($fields) { global $user; $mdb2 = getConnection(); @@ -388,19 +405,13 @@ static function disapproveTimesheet($fields) { $group_id = $user->getGroup(); $org_id = $user->org_id; - // First, mark timesheet as disapproved. - // Even if mail part below does not work, this will get us a functioning workflow - // without email notification. $timesheet_id = $fields['timesheet_id']; $comment = $fields['comment']; $sql = "update tt_timesheets set approve_status = 0, approve_comment = ".$mdb2->quote($comment). " where id = $timesheet_id and submit_status = 1 and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; - - // TODO: send email to submitter here... - return true; + return (!is_a($affected, 'PEAR_Error')); } // The timesheetItemsExist determines whether tt_log records exist in the specified period diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index fdf72ae68..18d87eecf 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -557,7 +557,7 @@ 'form.timesheet_view.submit_subject' => 'Timesheet approval request', 'form.timesheet_view.submit_body' => "A new timesheet requires approval.

User: %s.", 'form.timesheet_view.approve_subject' => 'Timesheet approved', -'form.timesheet_view.approve_body' => "Your timesheet %s was approved.", +'form.timesheet_view.approve_body' => "Your timesheet %s was approved.

%s", 'form.timesheet_view.disapprove_subject' => 'Timesheet not approved', -'form.timesheet_view.disapprove_subject' => "Your timesheet %s was not approved.", +'form.timesheet_view.disapprove_body' => "Your timesheet %s was not approved.

%s", ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1a85ccfc2..e4384ddb3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} + {* {* column for edit icons *} {/if} @@ -171,6 +172,7 @@ {if 1 == $item.type}{/if} {if 2 == $item.type}{/if} {/if} + {* {* column for edit icons *} {if $note_on_separate_row && $bean->getAttribute('chnote') && $item.note} @@ -220,6 +222,7 @@ {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} + {* {* column for edit icons *} {/if} @@ -261,6 +264,7 @@ {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} + {* {* column for edit icons *} {/if}
 Anuko Time Tracker 1.18.52.4825 | Copyright © Anuko | +  Anuko Time Tracker 1.18.53.4826 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_view.php b/timesheet_view.php index f6e8aac71..c8d7048a4 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -124,13 +124,19 @@ if ($request->getParameter('btn_disapprove')) { $fields = array('timesheet_id' => $timesheet['id'], + 'name' => $timesheet['name'], + 'user_id' => $timesheet['user_id'], 'comment' => $cl_comment); - if (ttTimesheetHelper::disapproveTimesheet($fields)) { + if (!ttTimesheetHelper::markDisapproved($fields)) + $err->add($i18n->get('error.db')); + if ($err->no() && !ttTimesheetHelper::sendDisapprovedEmail($fields)) { + $err->add($i18n->get('error.mail_send')); + } + if ($err->no()) { // Redirect to self. header('Location: timesheet_view.php?id='.$timesheet['id']); exit(); - } else - $err->add($i18n->get('error.db')); + } } } From d71e36acc9393f7657dd3ab1fbb148c4bbf466c7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 5 Mar 2019 18:42:59 +0000 Subject: [PATCH 0770/1848] Added project filter on reports depending on selected client. --- WEB-INF/lib/ttClientHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 77 +++++++++++++++++++++++++++- reports.php | 2 + 4 files changed, 79 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 02014f1f5..64eedb0a7 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -63,7 +63,7 @@ static function getClients() { $result = array(); - $sql = "select id, name from tt_clients where group_id = $group_id and org_id = $org_id and (status = 0 or status = 1) order by upper(name)"; + $sql = "select id, name, projects from tt_clients where group_id = $group_id and org_id = $org_id and (status = 0 or status = 1) order by upper(name)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e4384ddb3..a83f58e3b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + {/if} diff --git a/WEB-INF/templates/predefined_expenses.tpl b/WEB-INF/templates/predefined_expenses.tpl index 147230dc5..9c8625c77 100644 --- a/WEB-INF/templates/predefined_expenses.tpl +++ b/WEB-INF/templates/predefined_expenses.tpl @@ -2,7 +2,6 @@
 Anuko Time Tracker 1.18.53.4826 | Copyright © Anuko | +  Anuko Time Tracker 1.18.53.4827 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 1358d29de..3b66c71f9 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -1,4 +1,28 @@ @@ -145,7 +155,7 @@ function handlePluginCheckboxes() { {if isTrue('TEMPLATES_DEBUG')}
{$forms.pluginsForm.templates.control} {$i18n.label.what_is_it} {$i18n.label.configure} {$i18n.label.what_is_it}
-{if $user->can('manage_advanced_settings')} @@ -25,7 +24,6 @@
{$i18n.label.thing_name}

{$forms.predefinedExpensesForm.btn_add.control}
-{/if}
diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl new file mode 100644 index 000000000..a1ea3496e --- /dev/null +++ b/WEB-INF/templates/templates.tpl @@ -0,0 +1,28 @@ +{$forms.templatesForm.open} + + + + +
+ + + + + + + {if $templates} + {foreach $templates as $template} + + + + + + {/foreach} + {/if} +
{$i18n.label.thing_name}{$i18n.label.edit}{$i18n.label.delete}
{$template_expense['name']|escape}{$i18n.label.edit}{$i18n.label.delete}
+ + + +

{$forms.templatesForm.btn_add.control}
+
+{$forms.templatesForm.close} diff --git a/dbinstall.php b/dbinstall.php index c4eb1becf..358f6f025 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1152,6 +1152,7 @@ function ttExecute($sql) { ttExecute("OPTIMIZE TABLE tt_invoices"); ttExecute("OPTIMIZE TABLE tt_log"); ttExecute("OPTIMIZE TABLE tt_monthly_quotas"); + ttExecute("OPTIMIZE TABLE tt_templates"); ttExecute("OPTIMIZE TABLE tt_predefined_expenses"); ttExecute("OPTIMIZE TABLE tt_project_task_binds"); ttExecute("OPTIMIZE TABLE tt_projects"); diff --git a/plugins.php b/plugins.php index bf0e527f8..e20bb9617 100644 --- a/plugins.php +++ b/plugins.php @@ -95,7 +95,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'approval','value'=>$cl_approval)); $form->addInput(array('type'=>'checkbox','name'=>'timesheets','value'=>$cl_timesheets)); if (isTrue('TEMPLATES_DEBUG')) { - $form->addInput(array('type'=>'checkbox','name'=>'templates','value'=>$cl_templates)); + $form->addInput(array('type'=>'checkbox','name'=>'templates','value'=>$cl_templates,'onchange'=>'handlePluginCheckboxes()')); } // Submit button. $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); diff --git a/templates.php b/templates.php new file mode 100644 index 000000000..e2d0e7791 --- /dev/null +++ b/templates.php @@ -0,0 +1,61 @@ +isPluginEnabled('tp')) { + header('Location: feature_disabled.php'); + exit(); +} +// End of access checks. + +$form = new Form('templatesForm'); + +if ($request->isPost()) { + if ($request->getParameter('btn_add')) { + // The Add button clicked. Redirect to template_add.php page. + header('Location: template_add.php'); + exit(); + } +} else { + $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); + $predefinedExpenses = ttGroupHelper::getPredefinedExpenses(); +} + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('predefined_expenses', $predefinedExpenses); +$smarty->assign('title', $i18n->get('title.templates')); +$smarty->assign('content_page_name', 'templates.tpl'); +$smarty->display('index.tpl'); From 295a9e2e600768af193e7b199dd86bd1f2d1fecb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 14:50:14 +0000 Subject: [PATCH 0783/1848] Added description field to tt_templates. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c60717662..180c7671a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.18.54.4838 | Copyright © Anuko | +  Anuko Time Tracker 1.18.55.4839 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 358f6f025..7ecf75c4e 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -972,7 +972,7 @@ function ttExecute($sql) { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11854"]) { + if ($_POST["convert11797to11855"]) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1125,6 +1125,8 @@ function ttExecute($sql) { ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.51', modified = now() where param_name = 'version_db' and param_value = '1.18.50'"); ttExecute("CREATE TABLE `tt_templates` (`id` int(11) NOT NULL auto_increment,`group_id` int(11) default NULL,`org_id` int(11) default NULL,`name` varchar(80) COLLATE utf8mb4_bin NOT NULL,`content` text,`created` datetime default NULL,`created_ip` varchar(45) default NULL,`created_by` int(11) default NULL,`modified` datetime default NULL,`modified_ip` varchar(45) default NULL,`modified_by` int(11) default NULL,`status` tinyint(4) default 1,PRIMARY KEY (`id`))"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.54', modified = now() where param_name = 'version_db' and param_value = '1.18.51'"); + ttExecute("ALTER TABLE `tt_templates` ADD `description` varchar(255) default NULL AFTER `name`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.55', modified = now() where param_name = 'version_db' and param_value = '1.18.54'"); } if ($_POST["cleanup"]) { @@ -1174,7 +1176,7 @@ function ttExecute($sql) {

DB Install

-
Create database structure (v1.18.54) + Create database structure (v1.18.55)
(applies only to new installations, do not execute when updating)
@@ -1219,8 +1221,8 @@ function ttExecute($sql) {
Update database structure (v1.17.97 to v1.18.54)Update database structure (v1.17.97 to v1.18.55)
diff --git a/mysql.sql b/mysql.sql index 8c38425c2..eea348c03 100644 --- a/mysql.sql +++ b/mysql.sql @@ -521,6 +521,7 @@ CREATE TABLE `tt_templates` ( `group_id` int(11) default NULL, # group id `org_id` int(11) default NULL, # organization id `name` varchar(80) COLLATE utf8mb4_bin NOT NULL, # template name + `description` varchar(255) default NULL, # template description `content` text, # template content `created` datetime default NULL, # creation timestamp `created_ip` varchar(45) default NULL, # creator ip @@ -546,4 +547,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.54', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.18.55', now()); # TODO: change when structure changes. From fc92f9cd36dcaeb96da37c699a61331805d9e2fc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 15:13:42 +0000 Subject: [PATCH 0784/1848] Work in progress on templates plugin. --- WEB-INF/resources/ca.lang.php | 3 ++ WEB-INF/resources/cs.lang.php | 3 ++ WEB-INF/resources/da.lang.php | 3 ++ WEB-INF/resources/de.lang.php | 3 ++ WEB-INF/resources/en.lang.php | 3 ++ WEB-INF/resources/es.lang.php | 3 ++ WEB-INF/resources/et.lang.php | 3 ++ WEB-INF/resources/fa.lang.php | 3 ++ WEB-INF/resources/fi.lang.php | 3 ++ WEB-INF/resources/fr.lang.php | 3 ++ WEB-INF/resources/gr.lang.php | 3 ++ WEB-INF/resources/he.lang.php | 3 ++ WEB-INF/resources/hu.lang.php | 3 ++ WEB-INF/resources/it.lang.php | 3 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/template_add.tpl | 26 +++++++++++ WEB-INF/templates/templates.tpl | 4 +- template_add.php | 72 ++++++++++++++++++++++++++++++ 18 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/templates/template_add.tpl create mode 100644 template_add.php diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 04de03b62..07d4e8152 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -367,6 +367,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index a9389a30e..27494aec7 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -378,6 +378,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 981982ce9..f4fd9c537 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -345,6 +345,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index dbace500a..dcd666a4a 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -328,6 +328,9 @@ 'title.work_units' => 'Arbeitseinheiten', // TODO: translate the following. // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 660e84486..7fb968f9e 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -319,6 +319,9 @@ 'title.swap_roles' => 'Swapping Roles', 'title.work_units' => 'Work Units', 'title.templates' => 'Templates', +'title.add_template' => 'Adding Template', +'title.edit_template' => 'Editing Template', +'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 6b331febe..b31ec28eb 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -366,6 +366,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 722844640..c4c4cebd6 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -349,6 +349,9 @@ 'title.work_units' => 'Töö ühikud', // TODO: translate the following. // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 27fcf6842..6632b7ebf 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -353,6 +353,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index f8892dd4f..68d167fa3 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -345,6 +345,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 791e7bc23..807006f00 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -339,6 +339,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 802014493..d5dde2900 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -335,6 +335,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 568b78b22..bd4f06b63 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -365,6 +365,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 98e9d5f10..c35fb70ad 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -366,6 +366,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 1a15690fd..bb28e972f 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -345,6 +345,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 180c7671a..72f5079bf 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + {/if} diff --git a/WEB-INF/templates/client_edit2.tpl b/WEB-INF/templates/client_edit2.tpl index 67b79ecdf..39c965ae0 100644 --- a/WEB-INF/templates/client_edit2.tpl +++ b/WEB-INF/templates/client_edit2.tpl @@ -34,7 +34,7 @@ License: See license.txt *} - + {/if} diff --git a/WEB-INF/templates/project_add2.tpl b/WEB-INF/templates/project_add2.tpl index cd900cf36..8cc43fcaa 100644 --- a/WEB-INF/templates/project_add2.tpl +++ b/WEB-INF/templates/project_add2.tpl @@ -28,7 +28,7 @@ License: See license.txt *} - + {/if} @@ -37,7 +37,7 @@ License: See license.txt *} - + {/if} diff --git a/WEB-INF/templates/project_edit2.tpl b/WEB-INF/templates/project_edit2.tpl index f7b23a9ac..3ecc85a84 100644 --- a/WEB-INF/templates/project_edit2.tpl +++ b/WEB-INF/templates/project_edit2.tpl @@ -26,7 +26,7 @@ License: See license.txt *} - + {/if} @@ -35,7 +35,7 @@ License: See license.txt *} - + {/if} diff --git a/WEB-INF/templates/task_add2.tpl b/WEB-INF/templates/task_add2.tpl index 1b1c4e42e..d933160af 100644 --- a/WEB-INF/templates/task_add2.tpl +++ b/WEB-INF/templates/task_add2.tpl @@ -20,7 +20,7 @@ License: See license.txt *} - + {/if} diff --git a/WEB-INF/templates/task_edit2.tpl b/WEB-INF/templates/task_edit2.tpl index 9292ad151..c6e433b73 100644 --- a/WEB-INF/templates/task_edit2.tpl +++ b/WEB-INF/templates/task_edit2.tpl @@ -26,7 +26,7 @@ License: See license.txt *} - + {/if} diff --git a/default.css b/default.css index 95f56094b..377197f28 100644 --- a/default.css +++ b/default.css @@ -233,6 +233,12 @@ div.record-list { text-align: left; } +/* a table cell containing a set ov vertically stacked checkboxes */ +.td-with-checkboxes { + text-align: left; + width: 300px; +} + /* div containing how to contribute message */ div.contribute-msg { text-align: center; diff --git a/initialize.php b/initialize.php index 47f069ba8..6ccd4533e 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5408"); +define("APP_VERSION", "1.19.23.5409"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 7e9111012d54e0feae92598b508f99cb035167d0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 20 Jan 2021 17:26:27 +0000 Subject: [PATCH 1417/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 12 +++--------- initialize.php | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 6d51082c7..70750349d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -390,16 +390,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Wachtwoord vergeten?', - // TODO: re-translate form.login.about as it has changed. - // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', -'form.login.about' => 'Anuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem.', +'form.login.about' => 'Anuko Time Tracker is een open source tijdregistratiesysteem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Het verzoek om het wachtwoord te herstellen is verzonden per email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker wachtwoord herstel verzoek', -// TODO: retranslate form.reset_password.email_body as the string has changed. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", -'form.reset_password.email_body' => "Geachte medewerker,\n\nIemand, met IP adres %s, heeft verzocht uw wachtwoord in Anuko Time Tracker te herstellen. Klik op deze link als u uw wachtwoord wil wijzigen.\n\n%s\n\nAnuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem. Bezoek https://www.anuko.com voor meer informatie.\n\n", +'form.reset_password.email_body' => "Beste gebruiker,\n\nIemand, met IP adres %s, heeft verzocht uw wachtwoord in Anuko Time Tracker te herstellen. Klik op deze link als u uw wachtwoord wil wijzigen.\n\n%s\n\nAnuko Time Tracker is een open source tijdregistratiesysteem. Bezoek https://www.anuko.com voor meer informatie.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Voer het nieuwe wachtwoord in en klik op Bewaren.', @@ -546,9 +542,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Aan', 'form.mail.report_subject' => 'Time Tracker rapport', -// TODO: retranslate form.mail.footer as the English string has changed. -// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', -'form.mail.footer' => 'Anuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem. Bezoek www.anuko.com voor meer informatie.', +'form.mail.footer' => 'Anuko Time Tracker is een open source tijdregistratiesysteem. Bezoek www.anuko.com voor meer informatie.', 'form.mail.report_sent' => 'Rapport is verzonden.', 'form.mail.invoice_sent' => 'Factuur is verzonden.', diff --git a/initialize.php b/initialize.php index 6ccd4533e..f955479f7 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5409"); +define("APP_VERSION", "1.19.23.5410"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 13ad968d9729dbff50acdeb652bba5e298633c0e Mon Sep 17 00:00:00 2001 From: Josh Bowers Date: Wed, 27 Jan 2021 07:06:47 -0800 Subject: [PATCH 1418/1848] extra '+' character and end of line causing error (#105) PHP Fatal error: Uncaught TypeError: Unsupported operand types: Smarty * int in ./time_edit.php:453 --- time_edit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/time_edit.php b/time_edit.php index 89988409b..4065bf08f 100644 --- a/time_edit.php +++ b/time_edit.php @@ -449,7 +449,7 @@ $smarty->assign('entry_date', $cl_date); } $smarty->assign('show_client', $showClient); -$smarty->assign('show_billable', $showBillable);+ +$smarty->assign('show_billable', $showBillable); $smarty->assign('show_paid_status', $showPaidStatus); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); From 87b5c171f0ddb7ba24e5cf86a5238f1564e12459 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 20 Feb 2021 21:03:38 +0000 Subject: [PATCH 1419/1848] A couple of minor fixes to remove some php8 warnings. --- WEB-INF/lib/DateAndTime.class.php | 3 ++- WEB-INF/lib/ttUser.class.php | 1 + initialize.php | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/DateAndTime.class.php b/WEB-INF/lib/DateAndTime.class.php index 20f274265..1184bd853 100644 --- a/WEB-INF/lib/DateAndTime.class.php +++ b/WEB-INF/lib/DateAndTime.class.php @@ -325,6 +325,7 @@ function preprocessFormatString($format) { // replace locale-dependent strings $format = str_replace('%a', mb_substr($i18n->getWeekDayName($this->mDay), 0, 3, 'utf-8'), $format); $format = str_replace('%A', $i18n->getWeekDayName($this->mDay), $format); + /* This block is commented out because we currently do not use these formatters. $abbrev_month = mb_substr($i18n->monthNames[$this->mMonth], 0, 3, 'utf-8'); $format = str_replace('%b', $abbrev_month, $format); $format = str_replace('%h', $abbrev_month, $format); @@ -332,7 +333,7 @@ function preprocessFormatString($format) { $format = str_replace('%Z', date('O'), $format); // format as 'O' for consistency with JS strftime if (strpos($format, '%c') !== false) { $format = str_replace('%c', $this->preprocessFormatString('%a %d %b %Y %T %Z'), $format); - } + }*/ return $format; } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 72b829d31..c006350fd 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -488,6 +488,7 @@ function getUsers($options) { $includeSelf = isset($options['include_self']); $select_part = 'select u.id, u.group_id, u.name'; + $include_quota = false; if (isset($options['include_login'])) { $select_part .= ', u.login'; // Piggy-back on include_login to see if we must also include quota_percent. diff --git a/initialize.php b/initialize.php index f955479f7..55b1a1034 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5410"); +define("APP_VERSION", "1.19.23.5411"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From f3f9921ce9d15b84658b40bf1cefe4870490e0ab Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 20 Feb 2021 21:56:04 +0000 Subject: [PATCH 1420/1848] A couple more fixes for php8. --- WEB-INF/lib/form/Calendar.class.php | 2 +- WEB-INF/lib/ttUser.class.php | 4 +++- initialize.php | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index d335e1503..337737f1c 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -80,7 +80,7 @@ function getHtml() { $firstOfPreviousMonth = strftime(DB_DATEFORMAT, $firstOfPreviousMonth2AM); // Print calendar header. - $html .= "\n\n\n"; + $html = "\n\n\n"; $html .= '
 Anuko Time Tracker 1.18.55.4839 | Copyright © Anuko | +  Anuko Time Tracker 1.18.55.4840 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/template_add.tpl b/WEB-INF/templates/template_add.tpl new file mode 100644 index 000000000..fd2983a70 --- /dev/null +++ b/WEB-INF/templates/template_add.tpl @@ -0,0 +1,26 @@ +{$forms.predefinedExpenseForm.open} + + + + +
+ + + + + + + + + + + + + + + + + +
{$i18n.label.thing_name} (*):{$forms.predefinedExpenseForm.name.control}
{$i18n.label.cost} (*):{$forms.predefinedExpenseForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.required_fields}
 
{$forms.predefinedExpenseForm.btn_add.control}
+
+{$forms.predefinedExpenseForm.close} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index a1ea3496e..177f32cf3 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -5,13 +5,15 @@ + {if $templates} {foreach $templates as $template} - + + diff --git a/template_add.php b/template_add.php new file mode 100644 index 000000000..606ea9f71 --- /dev/null +++ b/template_add.php @@ -0,0 +1,72 @@ +isPluginEnabled('tp')) { + header('Location: feature_disabled.php'); + exit(); +} +// End of access checks. + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('name')); + $cl_cost = trim($request->getParameter('cost')); +} + +$form = new Form('predefinedExpenseForm'); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); + if ($err->no()) { + if (ttPredefinedExpenseHelper::insert(array( + 'name' => $cl_name, + 'cost' => $cl_cost))) { + header('Location: predefined_expenses.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.add_template')); +$smarty->assign('content_page_name', 'predefined_expense_add.tpl'); +$smarty->display('index.tpl'); From 5bbe544e3d2db9b79e5ea413e7994dcf0859f5f4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 15:28:24 +0000 Subject: [PATCH 0785/1848] Added strings to translation files for templates plugin. --- WEB-INF/resources/ja.lang.php | 3 +++ WEB-INF/resources/ko.lang.php | 3 +++ WEB-INF/resources/nl.lang.php | 3 +++ WEB-INF/resources/no.lang.php | 3 +++ WEB-INF/resources/pl.lang.php | 3 +++ WEB-INF/resources/pt-br.lang.php | 3 +++ WEB-INF/resources/pt.lang.php | 3 +++ WEB-INF/resources/ro.lang.php | 3 +++ WEB-INF/resources/ru.lang.php | 3 +++ WEB-INF/resources/sk.lang.php | 3 +++ WEB-INF/resources/sl.lang.php | 3 +++ WEB-INF/resources/sr.lang.php | 3 +++ WEB-INF/resources/sv.lang.php | 3 +++ WEB-INF/resources/tr.lang.php | 3 +++ WEB-INF/resources/zh-cn.lang.php | 3 +++ WEB-INF/resources/zh-tw.lang.php | 3 +++ WEB-INF/templates/footer.tpl | 2 +- 17 files changed, 49 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index b53cc6c0a..7ea3b8be2 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -373,6 +373,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index f8b788587..efae79032 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -374,6 +374,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index b8fb07434..6c2135015 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -323,6 +323,9 @@ 'title.work_units' => 'Werk eenheid', // TODO: translate the following. // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 2d60abf14..6a2c41b97 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -370,6 +370,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 040eed5ff..7668e51e4 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -348,6 +348,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index c921471ac..0294451fc 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -343,6 +343,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index a0efbf042..d13822d9e 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -354,6 +354,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index f634d9435..db8ba288c 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -373,6 +373,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 084d92274..61d033e24 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -316,6 +316,9 @@ 'title.swap_roles' => 'Обмен ролей', 'title.work_units' => 'Единицы работы', 'title.templates' => 'Шаблоны', +'title.add_template' => 'Добавление шаблона', +'title.edit_template' => 'Редактирование шаблона', +'title.delete_template' => 'Удаление шаблона', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 68aef000c..9254908c7 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -354,6 +354,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 16fa0cbbb..8f29d0e6c 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -348,6 +348,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 07bb86e8b..867491b1b 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -346,6 +346,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 0f173e0b6..b4c40c9db 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -346,6 +346,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 33d451af0..a7d1e1540 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -382,6 +382,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5f7dbb8e4..58ba2c44c 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -361,6 +361,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index efd1596b5..79b719d0a 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -368,6 +368,9 @@ // 'title.swap_roles' => 'Swapping Roles', // 'title.work_units' => 'Work Units', // 'title.templates' => 'Templates', +// 'title.add_template' => 'Adding Template', +// 'title.edit_template' => 'Editing Template', +// 'title.delete_template' => 'Deleting Template', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 72f5079bf..0d65482e6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.thing_name}{$i18n.label.description} {$i18n.label.edit} {$i18n.label.delete}
{$template_expense['name']|escape}{$template['name']|escape}{$template['description']|escape} {$i18n.label.edit} {$i18n.label.delete}
-
 Anuko Time Tracker 1.18.55.4840 | Copyright © Anuko | +  Anuko Time Tracker 1.18.55.4841 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 4a3754f39ede85db41f93f31bd82c516ce23e01a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 15:50:21 +0000 Subject: [PATCH 0786/1848] Work in progress on template_add.php. --- WEB-INF/resources/en.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/template_add.tpl | 16 ++++++++++------ template_add.php | 22 ++++++++++++++-------- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 7fb968f9e..eddafc936 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -237,6 +237,7 @@ 'label.approved' => 'Approved', 'label.approval' => 'Report approval', 'label.mark_approved' => 'Mark approved', +'label.template' => 'Template', // Form titles. 'title.error' => 'Error', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0d65482e6..cb6766ddd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {if $show_projects} + diff --git a/WEB-INF/templates/user_edit2.tpl b/WEB-INF/templates/user_edit2.tpl index 107891777..5adad2e9f 100644 --- a/WEB-INF/templates/user_edit2.tpl +++ b/WEB-INF/templates/user_edit2.tpl @@ -185,6 +185,7 @@ function handleClientRole() { {if $show_projects} + diff --git a/default.css b/default.css index c4f8ac542..8159cab08 100644 --- a/default.css +++ b/default.css @@ -234,6 +234,10 @@ input[type="text"] { width: 220px; } +input[type="text"].project-rate-field { + width: 100px; +} + input[type="password"] { width: 220px; } diff --git a/initialize.php b/initialize.php index 79d1105fe..68f36434c 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5393"); +define("APP_VERSION", "1.19.23.5394"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_add.php b/user_add.php index e87fed752..046ecdb87 100644 --- a/user_add.php +++ b/user_add.php @@ -123,6 +123,7 @@ class RateCellRenderer extends DefaultCellRenderer { function render(&$table, $value, $row, $column, $selected = false) { global $assigned_projects; $field = new FloatField('rate_'.$table->getValueAtName($row, 'id')); + $field->setCssClass('project-rate-field'); $field->setFormName($table->getFormName()); $field->setSize(5); $field->setFormat('.2'); diff --git a/user_edit.php b/user_edit.php index 17c8292e3..be0f13e26 100644 --- a/user_edit.php +++ b/user_edit.php @@ -156,6 +156,7 @@ function render(&$table, $value, $row, $column, $selected = false) { global $assigned_projects; $field = new FloatField('rate_'.$table->getValueAtName($row,'id')); + $field->setCssClass('project-rate-field'); $field->setFormName($table->getFormName()); $field->setSize(5); $field->setFormat('.2'); From 26058d1c778fba9ecdbef81453eaf64ed13f3607 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 29 Nov 2020 23:36:30 +0000 Subject: [PATCH 1402/1848] Improved presentation of project rates table. --- WEB-INF/lib/form/Table.class.php | 9 ++++----- default.css | 6 +++++- initialize.php | 2 +- user_edit.php | 5 +++-- week.php | 3 ++- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/form/Table.class.php b/WEB-INF/lib/form/Table.class.php index 7bcd78be8..1995b7dea 100644 --- a/WEB-INF/lib/form/Table.class.php +++ b/WEB-INF/lib/form/Table.class.php @@ -47,10 +47,9 @@ class Table extends FormElement { var $mHeaderOptions = array(); var $mProccessed = false; - function __construct($name, $cssClass = null) { + function __construct($name) { $this->class = 'Table'; $this->name = $name; - $this->cssClass = $cssClass; } function setKeyField($value) { @@ -123,15 +122,15 @@ function getHtml() { if ($this->mInteractive) $html .= $this->_addJavaScript(); $html .= "cssClass) { - $html .= " class=\"".$this->cssClass."\""; + if ($this->css_class) { + $html .= " class=\"".$this->css_class."\""; } if (count($this->mTableOptions) > 0) { foreach ($this->mTableOptions as $k=>$v) { $html .= " $k=\"$v\""; } } else { - $html .= " border=\"1\""; + // $html .= " border=\"1\""; } if ($this->mWidth!="") $html .= " width=\"".$this->mWidth."\""; $html .= ">\n"; diff --git a/default.css b/default.css index 8159cab08..2a6b06382 100644 --- a/default.css +++ b/default.css @@ -108,6 +108,10 @@ div.page-hint { margin-top: 1rem; } +.project-rate-table { + width: 300px; +} + .centered-table { margin-top: .5rem; margin-left: auto; @@ -235,7 +239,7 @@ input[type="text"] { } input[type="text"].project-rate-field { - width: 100px; + width: 50px; } input[type="password"] { diff --git a/initialize.php b/initialize.php index 68f36434c..ca81befef 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5394"); +define("APP_VERSION", "1.19.23.5395"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_edit.php b/user_edit.php index be0f13e26..b0868c4e5 100644 --- a/user_edit.php +++ b/user_edit.php @@ -146,7 +146,7 @@ // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200)); + //$this->setOptions(array('width'=>200)); $this->setValue(''); return $this->toString(); } @@ -169,8 +169,9 @@ function render(&$table, $value, $row, $column, $selected = false) { } // Create projects table. $table = new Table('projects'); +$table->setCssClass('project-rate-table'); $table->setIAScript('setRate'); -$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); +//$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); $table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); $table->setData($projects); $table->setKeyField('id'); diff --git a/week.php b/week.php index d86e0c99c..fee395d66 100644 --- a/week.php +++ b/week.php @@ -275,7 +275,8 @@ function render(&$table, $value, $row, $column, $selected = false) { } // Create week_durations table. -$table = new Table('week_durations', 'week_view_table'); +$table = new Table('week_durations'); +// $table->setCssClass('week_view_table'); // Currently not used. Fix this. $table->setTableOptions(array('width'=>'100%','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); $table->setRowOptions(array('class'=>'tableHeaderCentered')); $table->setData($dataArray); From 374853526cac28b5b38fc96638601eb550058564 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 1 Dec 2020 18:23:14 +0000 Subject: [PATCH 1403/1848] Resuming work on styles. --- WEB-INF/lib/form/Table.class.php | 3 +-- initialize.php | 2 +- user_edit.php | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/form/Table.class.php b/WEB-INF/lib/form/Table.class.php index 1995b7dea..c83d90bd8 100644 --- a/WEB-INF/lib/form/Table.class.php +++ b/WEB-INF/lib/form/Table.class.php @@ -129,9 +129,8 @@ function getHtml() { foreach ($this->mTableOptions as $k=>$v) { $html .= " $k=\"$v\""; } - } else { - // $html .= " border=\"1\""; } + if ($this->mWidth!="") $html .= " width=\"".$this->mWidth."\""; $html .= ">\n"; diff --git a/initialize.php b/initialize.php index ca81befef..daa1b0522 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5395"); +define("APP_VERSION", "1.19.23.5396"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_edit.php b/user_edit.php index b0868c4e5..c270243ad 100644 --- a/user_edit.php +++ b/user_edit.php @@ -171,8 +171,6 @@ function render(&$table, $value, $row, $column, $selected = false) { $table = new Table('projects'); $table->setCssClass('project-rate-table'); $table->setIAScript('setRate'); -//$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); $table->setData($projects); $table->setKeyField('id'); $table->setValue($cl_projects); From 5d1667d8de0bf0583234d750d2123f5c40962246 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 1 Dec 2020 18:33:13 +0000 Subject: [PATCH 1404/1848] Improved styles on user_add.php. --- default.css | 5 +++++ initialize.php | 2 +- user_add.php | 4 +--- user_edit.php | 2 -- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/default.css b/default.css index 2a6b06382..2aa8335f8 100644 --- a/default.css +++ b/default.css @@ -110,6 +110,11 @@ div.page-hint { .project-rate-table { width: 300px; + border-collapse: collapse; +} + +.project-rate-table td { + padding: .2rem; } .centered-table { diff --git a/initialize.php b/initialize.php index daa1b0522..aced0690c 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5396"); +define("APP_VERSION", "1.19.23.5397"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_add.php b/user_add.php index 046ecdb87..7b7b72ed8 100644 --- a/user_add.php +++ b/user_add.php @@ -114,7 +114,6 @@ // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200)); $this->setValue(''); return $this->toString(); } @@ -136,9 +135,8 @@ function render(&$table, $value, $row, $column, $selected = false) { } // Create projects table. $table = new Table('projects'); +$table->setCssClass('project-rate-table'); $table->setIAScript('setDefaultRate'); -$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); $table->setData($projects); $table->setKeyField('id'); $table->setValue($cl_projects); diff --git a/user_edit.php b/user_edit.php index c270243ad..b1f1e65e2 100644 --- a/user_edit.php +++ b/user_edit.php @@ -146,7 +146,6 @@ // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { function render(&$table, $value, $row, $column, $selected = false) { - //$this->setOptions(array('width'=>200)); $this->setValue(''); return $this->toString(); } @@ -154,7 +153,6 @@ function render(&$table, $value, $row, $column, $selected = false) { class RateCellRenderer extends DefaultCellRenderer { function render(&$table, $value, $row, $column, $selected = false) { global $assigned_projects; - $field = new FloatField('rate_'.$table->getValueAtName($row,'id')); $field->setCssClass('project-rate-field'); $field->setFormName($table->getFormName()); From 529edc11b2f3476cae0a976ff40bdd5b62e4cbd2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 1 Dec 2020 22:03:35 +0000 Subject: [PATCH 1405/1848] Some cleanup and commenting in css. --- WEB-INF/templates/charts2.tpl | 4 +- default.css | 92 ++++++++++++++++++++++------------- initialize.php | 2 +- 3 files changed, 61 insertions(+), 37 deletions(-) diff --git a/WEB-INF/templates/charts2.tpl b/WEB-INF/templates/charts2.tpl index 7f4c3844a..6e9f1756d 100644 --- a/WEB-INF/templates/charts2.tpl +++ b/WEB-INF/templates/charts2.tpl @@ -53,7 +53,7 @@ function adjustTodayLinks() {
 Anuko Time Tracker 1.18.55.4841 | Copyright © Anuko | +  Anuko Time Tracker 1.18.55.4842 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/template_add.tpl b/WEB-INF/templates/template_add.tpl index fd2983a70..2a52cec32 100644 --- a/WEB-INF/templates/template_add.tpl +++ b/WEB-INF/templates/template_add.tpl @@ -1,15 +1,19 @@ -{$forms.predefinedExpenseForm.open} +{$forms.templateForm.open}
- + - - + + + + + + @@ -17,10 +21,10 @@ - +
{$i18n.label.thing_name} (*):{$forms.predefinedExpenseForm.name.control}{$forms.templateForm.name.control}
{$i18n.label.cost} (*):{$forms.predefinedExpenseForm.cost.control} {$user->getCurrency()|escape}{$i18n.label.description}:{$forms.templateForm.description.control}
{$i18n.label.template} (*):{$forms.templateForm.content.control}
 
{$forms.predefinedExpenseForm.btn_add.control}{$forms.templateForm.btn_add.control}
-{$forms.predefinedExpenseForm.close} +{$forms.templateForm.close} diff --git a/template_add.php b/template_add.php index 606ea9f71..4fed72d55 100644 --- a/template_add.php +++ b/template_add.php @@ -43,23 +43,29 @@ if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); - $cl_cost = trim($request->getParameter('cost')); + $cl_description = trim($request->getParameter('description')); + $cl_content = trim($request->getParameter('content')); } -$form = new Form('predefinedExpenseForm'); +$form = new Form('templateForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'content','style'=>'width: 250px; height: 80px;','value'=>$cl_content)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_content)) $err->add($i18n->get('error.field'), $i18n->get('label.template')); + // Finished validating user input. + if ($err->no()) { - if (ttPredefinedExpenseHelper::insert(array( + if (ttTemplateHelper::insert(array( 'name' => $cl_name, - 'cost' => $cl_cost))) { - header('Location: predefined_expenses.php'); + 'description' => $cl_description, + 'coontent' => $cl_content))) { + header('Location: templates.php'); exit(); } else $err->add($i18n->get('error.db')); @@ -68,5 +74,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.add_template')); -$smarty->assign('content_page_name', 'predefined_expense_add.tpl'); +$smarty->assign('content_page_name', 'template_add.tpl'); $smarty->display('index.tpl'); From 163beaf9eb740a868fc08e0d8361ac72c932185c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 16:05:24 +0000 Subject: [PATCH 0787/1848] Added label.template to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 30 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 07d4e8152..56c6afec6 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -271,6 +271,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 27494aec7..9d28b7865 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -281,6 +281,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index f4fd9c537..1cc5e12a7 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -259,6 +259,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'Fejl', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index dcd666a4a..bf076ba11 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -247,6 +247,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'Fehler', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index b31ec28eb..75236792d 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -274,6 +274,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index c4c4cebd6..f80c9033f 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -262,6 +262,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 6632b7ebf..9c63333a8 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -269,6 +269,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'خطا', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 68d167fa3..0ea4e7575 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -263,6 +263,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'Virhe', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 807006f00..d189cea80 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -257,6 +257,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'Erreur', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index d5dde2900..202da58cc 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -250,6 +250,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'Σφάλμα', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index bd4f06b63..ad3fab930 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -280,6 +280,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'שגיאה', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index c35fb70ad..5d90ea16d 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -276,6 +276,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index bb28e972f..ca031b8c0 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -254,6 +254,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 7ea3b8be2..1d2d12cc6 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -281,6 +281,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index efae79032..42213851e 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -281,6 +281,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 6c2135015..d0be88edc 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -240,6 +240,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'Fout', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 6a2c41b97..a9354bfc8 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -278,6 +278,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 7668e51e4..4500070b1 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -264,6 +264,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'Błąd', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 0294451fc..b10533506 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -261,6 +261,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'Erro', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d13822d9e..0466b3290 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -266,6 +266,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index db8ba288c..4d6504bba 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -278,6 +278,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 61d033e24..e21252eb0 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -236,6 +236,7 @@ 'label.approved' => 'Одобрено', 'label.approval' => 'Одобрение отчётов', 'label.mark_approved' => 'Отметить одобрение', +'label.template' => 'Шаблон', // Form titles. 'title.error' => 'Ошибка', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 9254908c7..e1ccbc4d7 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -269,6 +269,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'Chyba', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 8f29d0e6c..769c22ed1 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -261,6 +261,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 867491b1b..66479467d 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -262,6 +262,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. 'title.error' => 'Greška', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index b4c40c9db..42ef84524 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -258,6 +258,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Rubriker för formulär 'title.error' => 'Fel', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index a7d1e1540..1d6ed7020 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -285,6 +285,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // Form titles. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 58ba2c44c..e5ede5ddc 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -269,6 +269,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 79b719d0a..58ad8fd0a 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -276,6 +276,7 @@ // 'label.approved' => 'Approved', // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', +// 'label.template' => 'Template', // Form titles. // TODO: Translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index cb6766ddd..11597100c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + +
 Anuko Time Tracker 1.18.55.4842 | Copyright © Anuko | +  Anuko Time Tracker 1.18.55.4843 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 18ad12139f489cfc5a0721e68b2b3e6aa0175b89 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 16:30:13 +0000 Subject: [PATCH 0788/1848] Implemented template add. --- WEB-INF/lib/ttTemplateHelper.class.php | 113 +++++++++++++++++++++++++ template_add.php | 4 +- 2 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/lib/ttTemplateHelper.class.php diff --git a/WEB-INF/lib/ttTemplateHelper.class.php b/WEB-INF/lib/ttTemplateHelper.class.php new file mode 100644 index 000000000..e2e565a39 --- /dev/null +++ b/WEB-INF/lib/ttTemplateHelper.class.php @@ -0,0 +1,113 @@ +getGroup(); + $org_id = $user->org_id; + + $sql = "select id, name, description, content from tt_templates". + " where id = $id and group_id = $group_id and org_id = $org_id". + " and status is not null"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if ($val) { + return $val; + } + } + return false; + } + + // delete - marks a template as deleted in tt_templates table in database. + static function delete($id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "update from tt_templates set status = null". + " where id = $id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + return true; + } + + // insert function inserts a new template into database. + static function insert($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $name = $fields['name']; + $description = $fields['description']; + $content = $fields['content']; + + $sql = "insert into tt_templates (group_id, org_id, name, description, content)". + " values ($group_id, $org_id, ".$mdb2->quote($name). + ", ".$mdb2->quote($description).", ".$mdb2->quote($content).")"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + return true; + } + + // update function - updates a template in database. + static function update($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $template_id = (int) $fields['id']; + $name = $fields['name']; + $description = $fields['description']; + $content = $fields['content']; + + $sql = "update tt_templates set name = ".$mdb2->quote($name). + ", description = ".$mdb2->quote($description). + ", content = ".$mdb2->quote($content). + " where id = $template_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } +} diff --git a/template_add.php b/template_add.php index 4fed72d55..6fb0238e4 100644 --- a/template_add.php +++ b/template_add.php @@ -28,7 +28,7 @@ require_once('initialize.php'); import('form.Form'); -// import('ttTemplateHelper'); +import('ttTemplateHelper'); // Access checks. if (!ttAccessAllowed('manage_advanced_settings')) { @@ -64,7 +64,7 @@ if (ttTemplateHelper::insert(array( 'name' => $cl_name, 'description' => $cl_description, - 'coontent' => $cl_content))) { + 'content' => $cl_content))) { header('Location: templates.php'); exit(); } else From acd436b6c7d3bc585bb3841d4d69dbe15cd8d140 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 16:54:19 +0000 Subject: [PATCH 0789/1848] Work in progress on templates.php. --- WEB-INF/lib/ttGroupHelper.class.php | 42 +++++++++++++++++++++++++++++ WEB-INF/resources/en.lang.php | 4 +++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/templates.tpl | 7 +++-- templates.php | 6 +++-- 5 files changed, 56 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 762fffb69..251fb9e71 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -518,6 +518,48 @@ static function getInactiveTasks() return $result; } + // getActiveTemplates - returns an array of active templates for a group. + static function getActiveTemplates() + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, name, description from tt_templates". + " where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } + + // getInactiveTemplates - returns an array of active templates for a group. + static function getInactiveTemplates() + { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, name, description from tt_templates". + " where group_id = $group_id and org_id = $org_id and status = 0 order by upper(name)"; + $res = $mdb2->query($sql); + $result = array(); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } + // validateCheckboxGroupInput - validates user input in a group of checkboxes // in context of a specific database table. // diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index eddafc936..db04f8181 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -425,6 +425,10 @@ 'form.timesheets.active_timesheets' => 'Active Timesheets', 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', + // Templates form. See example at https://timetracker.anuko.com/templates.php +'form.templates.active_templates' => 'Active Templates', +'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Invoice number', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 11597100c..e693b467f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.55.4843 | Copyright © Anuko | +  Anuko Time Tracker 1.18.55.4844 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index 177f32cf3..0e8f220a9 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -3,14 +3,17 @@
+{if $inactive_templates} + +{/if} - {if $templates} - {foreach $templates as $template} + {if $active_templates} + {foreach $active_templates as $template} diff --git a/templates.php b/templates.php index e2d0e7791..6bf6ae393 100644 --- a/templates.php +++ b/templates.php @@ -51,11 +51,13 @@ } } else { $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - $predefinedExpenses = ttGroupHelper::getPredefinedExpenses(); + $activeTemplates = ttGroupHelper::getActiveTemplates(); + $inactiveTemplates = ttGroupHelper::getInactiveTemplates(); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('predefined_expenses', $predefinedExpenses); +$smarty->assign('active_templates', $activeTemplates); +$smarty->assign('inactive_templates', $inactiveTemplates); $smarty->assign('title', $i18n->get('title.templates')); $smarty->assign('content_page_name', 'templates.tpl'); $smarty->display('index.tpl'); From 124f501c2f54e9480401ed46bd1986e10cc3afc3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 17:26:59 +0000 Subject: [PATCH 0790/1848] Added 2 more template strings in translation files. --- WEB-INF/resources/ca.lang.php | 5 +++++ WEB-INF/resources/cs.lang.php | 5 +++++ WEB-INF/resources/da.lang.php | 5 +++++ WEB-INF/resources/de.lang.php | 5 +++++ WEB-INF/resources/es.lang.php | 5 +++++ WEB-INF/resources/et.lang.php | 5 +++++ WEB-INF/resources/fa.lang.php | 5 +++++ WEB-INF/resources/fi.lang.php | 5 +++++ WEB-INF/resources/fr.lang.php | 5 +++++ WEB-INF/resources/gr.lang.php | 5 +++++ WEB-INF/resources/he.lang.php | 5 +++++ WEB-INF/resources/hu.lang.php | 5 +++++ WEB-INF/resources/it.lang.php | 5 +++++ WEB-INF/resources/ja.lang.php | 5 +++++ WEB-INF/resources/ko.lang.php | 5 +++++ WEB-INF/resources/nl.lang.php | 5 +++++ WEB-INF/resources/no.lang.php | 5 +++++ WEB-INF/resources/pl.lang.php | 5 +++++ WEB-INF/resources/pt-br.lang.php | 5 +++++ WEB-INF/resources/pt.lang.php | 5 +++++ WEB-INF/resources/ro.lang.php | 5 +++++ WEB-INF/resources/ru.lang.php | 4 ++++ WEB-INF/resources/sk.lang.php | 5 +++++ WEB-INF/resources/sl.lang.php | 5 +++++ WEB-INF/resources/sr.lang.php | 5 +++++ WEB-INF/resources/sv.lang.php | 5 +++++ WEB-INF/resources/tr.lang.php | 5 +++++ WEB-INF/resources/zh-cn.lang.php | 5 +++++ WEB-INF/resources/zh-tw.lang.php | 5 +++++ WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 145 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 56c6afec6..df7dda5e9 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -476,6 +476,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Número de factura', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 9d28b7865..1d71ad365 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -486,6 +486,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Faktura číslo', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 1cc5e12a7..87e34ae71 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -452,6 +452,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Fakturanummer', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index bf076ba11..1366c546f 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -433,6 +433,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Rechnungsnummer', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 75236792d..d880f13b0 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -489,6 +489,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Número de factura', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index f80c9033f..c3b956939 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -458,6 +458,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Arve number', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 9c63333a8..7bd1d9cfe 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -472,6 +472,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'شماره فاکتور', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 0ea4e7575..9117f62ac 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -457,6 +457,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Laskun numero', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index d189cea80..595b448d2 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -449,6 +449,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Numéro de facture', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 202da58cc..9ef0b9778 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -441,6 +441,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Αριθμός τιμολογίου', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index ad3fab930..bbe807887 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -479,6 +479,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'מספר חשבונית', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 5d90ea16d..2286ddfff 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -480,6 +480,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Számla azonosító száma', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ca031b8c0..691dc8b7b 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -454,6 +454,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Numero fattura', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 1d2d12cc6..ed89e4f0f 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -485,6 +485,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => '送り状の番号', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 42213851e..505c152d2 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -483,6 +483,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => '송장 번호', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index d0be88edc..fdd291ecb 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -429,6 +429,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Factuur nummer', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index a9354bfc8..4bef367f9 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -481,6 +481,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Fakturanummer', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 4500070b1..8e80c7536 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -460,6 +460,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Numer faktury', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index b10533506..b556bed71 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -455,6 +455,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Número da fatura', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 0466b3290..85478953b 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -461,6 +461,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 4d6504bba..24230219a 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -484,6 +484,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Numar factura', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index e21252eb0..929e2b2e2 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -416,6 +416,10 @@ 'form.timesheets.active_timesheets' => 'Активные табели', 'form.timesheets.inactive_timesheets' => 'Неактивные табели', +// Templates form. See example at https://timetracker.anuko.com/templates.php +'form.templates.active_templates' => 'Активные шаблоны', +'form.templates.inactive_templates' => 'Неактивные шаблоны', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Номер счёта', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index e1ccbc4d7..dde834a24 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -468,6 +468,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Číslo faktúry', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 769c22ed1..1e742abcb 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -458,6 +458,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 66479467d..9cc76d70a 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -458,6 +458,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Forma izveštaja. Pogledajte primer na https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Broj računa', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 42ef84524..0c5fbb4b1 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -456,6 +456,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Fakturanummer', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 1d6ed7020..c7a3191c9 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -496,6 +496,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => 'Fatura numarası', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index e5ede5ddc..1fdd32d06 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -468,6 +468,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => '发票号码', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 58ad8fd0a..5ca967e4e 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -476,6 +476,11 @@ // 'form.timesheets.active_timesheets' => 'Active Timesheets', // 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +// Templates form. See example at https://timetracker.anuko.com/templates.php +// TODO: translate the following. +// 'form.templates.active_templates' => 'Active Templates', +// 'form.templates.inactive_templates' => 'Inactive Templates', + // Invoice form. See example at https://timetracker.anuko.com/invoice.php // (you can get to this form after generating a report). 'form.invoice.number' => '發票號碼', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e693b467f..6a9ecb567 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.templates.active_templates}
{$i18n.label.thing_name} {$i18n.label.description} {$i18n.label.edit} {$i18n.label.delete}
{$template['name']|escape} {$template['description']|escape}
- {/if} - - - - + + + + - {if $active_templates} {foreach $active_templates as $template} @@ -21,12 +20,32 @@ {/foreach} - {/if}
 Anuko Time Tracker 1.18.55.4844 | Copyright © Anuko | +  Anuko Time Tracker 1.18.55.4845 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a6cc5ba9a2fb7a945f9754e9d07a8c0ac52698c3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 17:54:42 +0000 Subject: [PATCH 0791/1848] Work in progress on template edit. --- WEB-INF/templates/template_edit.tpl | 34 +++++++++++ template_edit.php | 95 +++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 WEB-INF/templates/template_edit.tpl create mode 100644 template_edit.php diff --git a/WEB-INF/templates/template_edit.tpl b/WEB-INF/templates/template_edit.tpl new file mode 100644 index 000000000..6f3e406f8 --- /dev/null +++ b/WEB-INF/templates/template_edit.tpl @@ -0,0 +1,34 @@ +{$forms.templateForm.open} + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.thing_name} (*):{$forms.templateForm.name.control}
{$i18n.label.description}:{$forms.templateForm.description.control}
{$i18n.label.template} (*):{$forms.templateForm.content.control}
{$i18n.label.status}:{$forms.templateForm.status.control}
{$i18n.label.required_fields}
 
{$forms.templateForm.btn_submit.control}
+
+{$forms.templateForm.close} diff --git a/template_edit.php b/template_edit.php new file mode 100644 index 000000000..90e5f5655 --- /dev/null +++ b/template_edit.php @@ -0,0 +1,95 @@ +isPluginEnabled('tp')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_template_id = (int) $request->getParameter('id'); +$template = ttTemplateHelper::get($cl_template_id); +if (!$template) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('name')); + $cl_description = trim($request->getParameter('description')); + $cl_content = trim($request->getParameter('content')); + $cl_status = $request->getParameter('status'); +} else { + $cl_name = $template['name']; + $cl_description = $template['description']; + $cl_content = $template['content']; + $cl_status = $template['status']; +} + +$form = new Form('templateForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_template_id)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'content','style'=>'width: 250px; height: 80px;','value'=>$cl_content)); +$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, + 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_content)) $err->add($i18n->get('error.field'), $i18n->get('label.template')); + // Finished validating user input. + + if ($err->no()) { + if (ttTemplateHelper::update(array( + 'id' => $cl_template_id, + 'name' => $cl_name, + 'description' => $cl_description, + 'content' => $cl_content, + 'status' => $cl_status))) { + header('Location: templates.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.edit_template')); +$smarty->assign('content_page_name', 'template_edit.tpl'); +$smarty->display('index.tpl'); From 6e2b1ec1880cebedef5a1ca380820ad0d40d06a2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 19:46:07 +0000 Subject: [PATCH 0792/1848] Some fixes to templates.php. --- WEB-INF/lib/ttTemplateHelper.class.php | 4 +++- WEB-INF/templates/templates.tpl | 33 ++++++++++++++++++++------ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttTemplateHelper.class.php b/WEB-INF/lib/ttTemplateHelper.class.php index e2e565a39..d6eefcde8 100644 --- a/WEB-INF/lib/ttTemplateHelper.class.php +++ b/WEB-INF/lib/ttTemplateHelper.class.php @@ -38,7 +38,7 @@ static function get($id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $sql = "select id, name, description, content from tt_templates". + $sql = "select id, name, description, content, status from tt_templates". " where id = $id and group_id = $group_id and org_id = $org_id". " and status is not null"; $res = $mdb2->query($sql); @@ -102,10 +102,12 @@ static function update($fields) { $name = $fields['name']; $description = $fields['description']; $content = $fields['content']; + $status = (int) $fields['status']; $sql = "update tt_templates set name = ".$mdb2->quote($name). ", description = ".$mdb2->quote($description). ", content = ".$mdb2->quote($content). + ", status = ".$status. " where id = $template_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index 0e8f220a9..c1a8d5b4b 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -7,12 +7,11 @@
{$i18n.form.templates.active_templates}
{$i18n.label.thing_name}{$i18n.label.description}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.thing_name}{$i18n.label.description}{$i18n.label.edit}{$i18n.label.delete}
{$template['name']|escape}{$i18n.label.delete}
-

{$forms.templatesForm.btn_add.control}
+{if $inactive_templates} + + + + + + + + + {foreach $inactive_templates as $template} + + + + + + + {/foreach} +
{$i18n.form.tasks.inactive_tasks}
{$i18n.label.thing_name}{$i18n.label.description}{$i18n.label.edit}{$i18n.label.delete}
{$template['name']|escape}{$template['description']|escape}{$i18n.label.edit}{$i18n.label.delete}
+ + +

{$forms.templatesForm.btn_add.control}
+{/if}
From 3b3e56c2f4e2a9624f0e25b1d5b0892a421a00bd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 19:56:41 +0000 Subject: [PATCH 0793/1848] Template editor done. --- WEB-INF/lib/ttTemplateHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/template_delete.tpl | 18 +++++++ template_delete.php | 75 ++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/templates/template_delete.tpl create mode 100644 template_delete.php diff --git a/WEB-INF/lib/ttTemplateHelper.class.php b/WEB-INF/lib/ttTemplateHelper.class.php index d6eefcde8..cc1818d29 100644 --- a/WEB-INF/lib/ttTemplateHelper.class.php +++ b/WEB-INF/lib/ttTemplateHelper.class.php @@ -59,7 +59,7 @@ static function delete($id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $sql = "update from tt_templates set status = null". + $sql = "update tt_templates set status = null". " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6a9ecb567..8b3fb0516 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - + + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + {/foreach} {/if} {if $show_project} @@ -108,96 +108,96 @@
 Anuko Time Tracker 1.18.55.4845 | Copyright © Anuko | +  Anuko Time Tracker 1.18.55.4846 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/template_delete.tpl b/WEB-INF/templates/template_delete.tpl new file mode 100644 index 000000000..2dc4114aa --- /dev/null +++ b/WEB-INF/templates/template_delete.tpl @@ -0,0 +1,18 @@ +{$forms.templateDeleteForm.open} + + + + +
+ + + + + + + + + +
{$template_to_delete|escape}
 
{$forms.templateDeleteForm.btn_delete.control}  {$forms.templateDeleteForm.btn_cancel.control}
+
+{$forms.templateDeleteForm.close} diff --git a/template_delete.php b/template_delete.php new file mode 100644 index 000000000..3eb34876e --- /dev/null +++ b/template_delete.php @@ -0,0 +1,75 @@ +isPluginEnabled('tp')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_template_id = (int) $request->getParameter('id'); +$template = ttTemplateHelper::get($cl_template_id); +if (!$template) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$template_to_delete = $template['name']; + +$form = new Form('templateDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_template_id)); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_delete')) { + if (ttTemplateHelper::delete($cl_template_id)) { + header('Location: templates.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } elseif ($request->getParameter('btn_cancel')) { + header('Location: templates.php'); + exit(); + } +} // isPost + +$smarty->assign('template_to_delete', $template_to_delete); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.templateDeleteForm.btn_cancel.focus()"'); +$smarty->assign('title', $i18n->get('title.delete_template')); +$smarty->assign('content_page_name', 'template_delete.tpl'); +$smarty->display('index.tpl'); From 3d2723cd9a817f59b26a40f5b34281e0586ba1ca Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Mar 2019 22:09:00 +0000 Subject: [PATCH 0794/1848] Added a template selector on time.php. --- WEB-INF/lib/ttGroupHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time.tpl | 23 +++++++++++++++++++++++ time.php | 16 ++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 251fb9e71..b77edf21a 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -527,7 +527,7 @@ static function getActiveTemplates() $group_id = $user->getGroup(); $org_id = $user->org_id; - $sql = "select id, name, description from tt_templates". + $sql = "select id, name, description, content from tt_templates". " where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)"; $res = $mdb2->query($sql); $result = array(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8b3fb0516..26443eea7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + +
 Anuko Time Tracker 1.18.55.4846 | Copyright © Anuko | +  Anuko Time Tracker 1.18.55.4847 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index a181b912e..fe9c294dc 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -1,5 +1,22 @@ {include file="time_script.tpl"} +{if $template_dropdown} + +{/if} + \n"; return $str; } From 80e8cc371b87d8a29863085ec3307d5a789e4659 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 13:34:07 +0000 Subject: [PATCH 1198/1848] Some refactoring and fixes on mobile time.php. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/time.tpl | 29 ++++---- mobile/time.php | 107 ++++++++++++++++++++---------- time.php | 12 ++-- 4 files changed, 97 insertions(+), 53 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7486f21e1..71d4fc489 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} -{if $user->isPluginEnabled('cl')} +{if $show_client} {/if} -{if $user->isPluginEnabled('iv')} +{if $show_billable} {/if} {if $custom_fields && $custom_fields->timeFields} @@ -68,22 +68,23 @@ {/foreach} {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} {/if} -{if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_task} {/if} -{if (($smarty.const.TYPE_START_FINISH == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))} +{if $show_start} - +{/if} +{if $show_finish} {/if} -{if (($smarty.const.TYPE_DURATION == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))} +{if $show_duration} {/if} diff --git a/mobile/time.php b/mobile/time.php index e51e00bdc..f1c4e4d84 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -68,6 +68,16 @@ $group_id = $user->getGroup(); $config = new ttConfigHelper($user->getConfig()); +$showClient = $user->isPluginEnabled('cl'); +$showBillable = $user->isPluginEnabled('iv'); +$trackingMode = $user->getTrackingMode(); +$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; +$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +$recordType = $user->getRecordType(); +$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; +$showFinish = $showStart; +$showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; + // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); $selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); @@ -94,7 +104,7 @@ $cl_duration = trim($request->getParameter('duration')); $cl_note = trim($request->getParameter('note')); $cl_billable = 1; -if ($user->isPluginEnabled('iv')) { +if ($showBillable) { if ($request->isPost()) { $cl_billable = $request->getParameter('billable'); $_SESSION['billable'] = (int) $cl_billable; @@ -150,7 +160,8 @@ } // Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $user->getTrackingMode() && $user->isPluginEnabled('cl')) { +// Note: for other tracking modes the control is added further below. +if (MODE_TIME == $trackingMode && $showClient) { $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', @@ -163,7 +174,28 @@ // Note: in other modes the client list is filtered to relevant clients only. See below. } -if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { +// Billable checkbox. +if ($showBillable) + $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); + +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'style'=>'width: 250px;', + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } + } +} + +// If we show project dropdown, add controls for project and client. +if ($showProject) { // Dropdown for projects assigned to user. $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); $project_list = $user->getAssignedProjects($options); @@ -176,8 +208,8 @@ 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Dropdown for clients if the clients plugin is enabled. - if ($user->isPluginEnabled('cl')) { + // Client dropdown. + if ($showClient) { $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) @@ -205,7 +237,8 @@ } } -if (MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { +// Task dropdown. +if ($showTask) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', @@ -215,7 +248,9 @@ 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); } -if ((TYPE_START_FINISH == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) { + +// Start and finish controls. +if ($showStart) { $form->addInput(array('type'=>'text','name'=>'start','value'=>$cl_start,'onchange'=>"formDisable('start');")); $form->addInput(array('type'=>'text','name'=>'finish','value'=>$cl_finish,'onchange'=>"formDisable('finish');")); if ($user->punch_mode && !$user->canOverridePunchMode()) { @@ -224,29 +259,10 @@ $form->getElement('finish')->setEnabled(false); } } -if ((TYPE_DURATION == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) - $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); -$form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height: 60px;','value'=>$cl_note)); -if ($user->isPluginEnabled('iv')) - $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); -// If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($timeField['id']), - 'value'=>$timeCustomFields[$timeField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} +// Duration control. +if ($showDuration) + $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); // If we have templates, add a dropdown to select one. if ($user->isPluginEnabled('tp')){ @@ -266,12 +282,20 @@ } } -// Submit. +// Note control. +$form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height: 60px;','value'=>$cl_note)); + +// A hidden control for today's date from user's browser. +$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. + +// Submit button. +$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); + if ($request->isPost()) { if ($request->getParameter('btn_submit')) { - + // Submit button clicked. // Validate user input. - if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) + if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); // Validate input in time custom fields. if ($custom_fields && $custom_fields->timeFields) { @@ -280,12 +304,14 @@ if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); } } - if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { + if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if (MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && $user->task_required) { + if ($showTask && $user->task_required) { if (!$cl_task) $err->add($i18n->get('error.task')); } + + // TODO: refactoring going on down from here... if (strlen($cl_duration) == 0) { if ($cl_start || $cl_finish) { if (!ttTimeHelper::isValidTime($cl_start)) @@ -368,6 +394,19 @@ $smarty->assign('next_date', $next_date); $smarty->assign('prev_date', $prev_date); $smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); + +$smarty->assign('show_client', $showClient); +$smarty->assign('show_billable', $showBillable); +$smarty->assign('show_project', $showProject); +$smarty->assign('show_task', $showTask); +$smarty->assign('show_start', $showStart); +$smarty->assign('show_finish', $showFinish); +$smarty->assign('show_duration', $showDuration); + + + + + $smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); diff --git a/time.php b/time.php index b1c0c4dba..1055470d0 100644 --- a/time.php +++ b/time.php @@ -138,7 +138,7 @@ $cl_duration = trim($request->getParameter('duration')); $cl_note = trim($request->getParameter('note')); $cl_billable = 1; -if ($user->isPluginEnabled('iv')) { +if ($showBillable) { if ($request->isPost()) { $cl_billable = $request->getParameter('billable'); $_SESSION['billable'] = (int) $cl_billable; @@ -293,9 +293,11 @@ $form->getElement('finish')->setEnabled(false); } } + // Duration control. if ($showDuration) $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); + // File upload control. if ($showFiles) $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); @@ -322,10 +324,13 @@ if (!defined('NOTE_INPUT_HEIGHT')) define('NOTE_INPUT_HEIGHT', 40); $form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 600px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_note)); + // Calendar. $form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar + // A hidden control for today's date from user's browser. $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. + // Submit button. $form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); @@ -342,10 +347,10 @@ if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); } } - if (MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode) { + if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if (MODE_PROJECTS_AND_TASKS == $trackingMode && $user->task_required) { + if ($showTask && $user->task_required) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (strlen($cl_duration) == 0) { @@ -480,7 +485,6 @@ $smarty->assign('show_start', $showStart); $smarty->assign('show_finish', $showFinish); $smarty->assign('show_duration', $showDuration); -$smarty->assign('show_templates', $showTemplates); $smarty->assign('show_note_column', $showNoteColumn); $smarty->assign('show_note_row', $showNoteRow); $smarty->assign('show_files', $showFiles); From 1a8bb88c2b59660be6d55da2816af800191a95b4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 14:32:23 +0000 Subject: [PATCH 1199/1848] Finished refactoring mobile time.php and template. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/time.tpl | 105 +++++++++++++++--------------- WEB-INF/templates/time.tpl | 96 +++++++++++++-------------- mobile/time.php | 14 +--- time.php | 4 +- 5 files changed, 105 insertions(+), 116 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 71d4fc489..3c0845777 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.18.5216 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5217 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/time.tpl b/WEB-INF/templates/mobile/time.tpl index 79398703b..b14e4d456 100644 --- a/WEB-INF/templates/mobile/time.tpl +++ b/WEB-INF/templates/mobile/time.tpl @@ -17,18 +17,18 @@
- {if $time_records} - - {foreach $time_records as $record} +{if $time_records} +
+ {foreach $time_records as $record} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $show_project} -{/if} + {/if} - {/foreach} + {/foreach}
{$record.project|escape}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{$record.duration}{if ($record.duration == '0:00' && $record.start <> '')}{/if} {if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.edit}{/if} {if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.delete}{/if}
@@ -36,7 +36,7 @@
{$day_total}
- {/if} +{/if}
@@ -53,11 +53,11 @@
{$i18n.label.user}:
{$forms.timeRecordForm.user.control}
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$i18n.label.project}:
{$forms.timeRecordForm.project.control}
{$i18n.label.task}:
{$forms.timeRecordForm.task.control}
{$i18n.label.start}:
{$forms.timeRecordForm.start.control} 
{$i18n.label.finish}:
{$forms.timeRecordForm.finish.control} 
{$i18n.label.duration}:
{$forms.timeRecordForm.duration.control}
-
 Anuko Time Tracker 1.19.18.5217 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5218 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/time.tpl b/WEB-INF/templates/mobile/time.tpl index b14e4d456..038d6790d 100644 --- a/WEB-INF/templates/mobile/time.tpl +++ b/WEB-INF/templates/mobile/time.tpl @@ -15,94 +15,91 @@
- - +
+
{if $time_records} - +
{foreach $time_records as $record} - + {if $show_project} - + {/if} - - - - + + + + {/foreach} -
{$record.project|escape}{$record.project|escape}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{$record.duration}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.edit}{/if}{if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.delete}{/if}
{if ($record.duration == '0:00' && $record.start <> '')}{/if}{$record.duration}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.edit}{/if}{if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.delete}{/if}
- - - - - -
{$i18n.label.day_total}:{$day_total}
+
+ + + + + +
{$i18n.label.day_total}:{$day_total}
{/if} -
{$forms.timeRecordForm.open} - - -
- - - - - -
- + + + +
+ + + + +
+ {if $user_dropdown} - - + + {/if} {if $show_client} - - + + {/if} {if $show_billable} - + {/if} {if $custom_fields && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + {/foreach} {/if} {if $show_project} - - + + {/if} {if $show_task} - - + + {/if} {if $show_start} - - + + {/if} {if $show_finish} - - + + {/if} {if $show_duration} - - + + {/if} {if $template_dropdown} - - + + {/if} - - - -
{$i18n.label.user}:
{$forms.timeRecordForm.user.control}
{$i18n.label.user}:
{$forms.timeRecordForm.user.control}
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project}:
{$forms.timeRecordForm.project.control}
{$i18n.label.project}:
{$forms.timeRecordForm.project.control}
{$i18n.label.task}:
{$forms.timeRecordForm.task.control}
{$i18n.label.task}:
{$forms.timeRecordForm.task.control}
{$i18n.label.start}:
{$forms.timeRecordForm.start.control} 
{$i18n.label.start}:
{$forms.timeRecordForm.start.control} 
{$i18n.label.finish}:
{$forms.timeRecordForm.finish.control} 
{$i18n.label.finish}:
{$forms.timeRecordForm.finish.control} 
{$i18n.label.duration}:
{$forms.timeRecordForm.duration.control}
{$i18n.label.duration}:
{$forms.timeRecordForm.duration.control}
{$i18n.label.template}:
{$forms.timeRecordForm.template.control}
{$i18n.label.template}:
{$forms.timeRecordForm.template.control}
{$i18n.label.note}:
{$forms.timeRecordForm.note.control}
+
{$i18n.label.note}:
{$forms.timeRecordForm.note.control}
+
{$forms.timeRecordForm.btn_submit.control}
{$forms.timeRecordForm.btn_submit.control}
-
{$forms.timeRecordForm.close} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index d153dc96d..0b78b1788 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -38,11 +38,11 @@ {/if} {if $custom_fields && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} -
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:{$forms.timeRecordForm.$control_name.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:{$forms.timeRecordForm.$control_name.control}
- - +
+
{if $time_records} - + {if $show_client} - + {/if} {if $show_project} - + {/if} {if $show_task} - + {/if} {if $show_start} - + {/if} {if $show_finish} - + {/if} - + {if $show_note_column} - + {/if} {if $show_files} - + {/if} - - - + + + {foreach $time_records as $record} - + {if $show_client} - + {/if} {if $show_project} - + {/if} {if $show_task} - + {/if} {if $show_start} - + {/if} {if $show_finish} - + {/if} - + {if $show_note_column} - + {/if} {if $show_files} {if $record.has_files} - + {else} - + {/if} {/if} - - + - + + {if $show_note_row && $record.comment} - - - - + + + + {/if} {/foreach} -
{$i18n.label.client}{$i18n.label.client}{$i18n.label.project}{$i18n.label.project}{$i18n.label.task}{$i18n.label.task}{$i18n.label.start}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.duration}{$i18n.label.note}{$i18n.label.note}
{$record.client|escape}{$record.client|escape}{$record.project|escape}{$record.project|escape}{$record.task|escape}{$record.task|escape}{if $record.start}{$record.start}{else} {/if}{if $record.start}{$record.start}{else} {/if}{if $record.finish}{$record.finish}{else} {/if}{if $record.finish}{$record.finish}{else} {/if}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}{if $record.comment}{$record.comment|escape}{else} {/if}{if $record.comment}{$record.comment|escape}{else} {/if}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files} + {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} - {$i18n.label.edit} + {$i18n.label.edit} {if ($record.duration == '0:00' && $record.start <> '')} - - - - + + + + {/if} {/if} - + {if $record.approved || $record.timesheet_id || $record.invoice_id} -   +   {else} - {$i18n.label.delete} + {$i18n.label.delete} {/if} -
{$i18n.label.note}:{$record.comment|escape}
{$i18n.label.note}:{$record.comment|escape}
+
{/if} -
diff --git a/mobile/time.php b/mobile/time.php index f1c4e4d84..233f1d16f 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -310,8 +310,6 @@ if ($showTask && $user->task_required) { if (!$cl_task) $err->add($i18n->get('error.task')); } - - // TODO: refactoring going on down from here... if (strlen($cl_duration) == 0) { if ($cl_start || $cl_finish) { if (!ttTimeHelper::isValidTime($cl_start)) @@ -323,11 +321,11 @@ $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); } } else { - if ((TYPE_START_FINISH == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) { + if ($showStart) { $err->add($i18n->get('error.empty'), $i18n->get('label.start')); $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); } - if ((TYPE_DURATION == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) + if ($showDuration) $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); } } else { @@ -393,8 +391,8 @@ $smarty->assign('next_date', $next_date); $smarty->assign('prev_date', $prev_date); +$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); - $smarty->assign('show_client', $showClient); $smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); @@ -402,12 +400,6 @@ $smarty->assign('show_start', $showStart); $smarty->assign('show_finish', $showFinish); $smarty->assign('show_duration', $showDuration); - - - - - -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); diff --git a/time.php b/time.php index 1055470d0..9f85d5981 100644 --- a/time.php +++ b/time.php @@ -364,11 +364,11 @@ $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); } } else { - if (TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType) { + if ($showStart) { $err->add($i18n->get('error.empty'), $i18n->get('label.start')); $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); } - if (TYPE_DURATION == $recordType || TYPE_ALL == $recordType) + if ($showDuration) $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); } } else { From bf36e82b0af62613d2826ef793e199eddaaa0ac6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 15:11:09 +0000 Subject: [PATCH 1200/1848] Some html fixes. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 1 + WEB-INF/templates/mobile/header.tpl | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3c0845777..0390d8a25 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/initialize.php b/initialize.php index 42b94a865..4e41c7ea3 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5382"); +define("APP_VERSION", "1.19.23.5383"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/client_add.php b/mobile/client_add.php deleted file mode 100644 index 2050204a6..000000000 --- a/mobile/client_add.php +++ /dev/null @@ -1,94 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_address = trim($request->getParameter('address')); - $cl_tax = $request->getParameter('tax'); - $cl_projects = $request->getParameter('projects'); -} else { - // Do not assign all projects to a new client by default. This should help to reduce clutter. - // foreach ($projects as $project_item) - // $cl_projects[] = $project_item['id']; -} - -$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; - -$form = new Form('clientForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','class'=>'mobile-textarea','value'=>$cl_address)); -$form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -if ($show_projects) - $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); - - if ($err->no()) { - if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array('name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'projects' => $cl_projects, - 'status' => ACTIVE))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"'); -$smarty->assign('show_projects',$show_projects); -$smarty->assign('title', $i18n->get('title.add_client')); -$smarty->assign('content_page_name', 'mobile/client_add.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/client_delete.php b/mobile/client_delete.php deleted file mode 100644 index 8e05ccde8..000000000 --- a/mobile/client_delete.php +++ /dev/null @@ -1,78 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -$id = (int)$request->getParameter('id'); -$client = ttClientHelper::getClient($id); -if (!$client) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$client_to_delete = $client['name']; - -$form = new Form('clientDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$id)); -$form->addInput(array('type'=>'combobox','name'=>'delete_client_entries', - 'data'=>array('0'=>$i18n->get('dropdown.do_not_delete'),'1'=>$i18n->get('dropdown.delete')))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if (ttClientHelper::delete($id, $request->getParameter('delete_client_entries'))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - - if ($request->getParameter('btn_cancel')) { - header('Location: clients.php'); - exit(); - } -} // isPost - -$smarty->assign('client_to_delete', $client_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.delete_client')); -$smarty->assign('content_page_name', 'mobile/client_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/client_edit.php b/mobile/client_edit.php deleted file mode 100644 index ab8686509..000000000 --- a/mobile/client_edit.php +++ /dev/null @@ -1,135 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -$client = ttClientHelper::getClient($cl_id, true); -if (!$client) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_address = trim($request->getParameter('address')); - $cl_tax = trim($request->getParameter('tax')); - $cl_status = $request->getParameter('status'); - $cl_projects = $request->getParameter('projects'); -} else { - $cl_name = $client['name']; - $cl_address = $client['address']; - $cl_tax = $client['tax']; - $cl_status = $client['status']; - $assigned_projects = ttClientHelper::getAssignedProjects($cl_id); - foreach($assigned_projects as $project_item) { - $cl_projects[] = $project_item['id']; - } -} - -$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; - -$form = new Form('clientForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'text','name'=>'name','maxlength'=>'100','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','class'=>'mobile-textarea','value'=>$cl_address)); -$form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -if ($show_projects) - $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'datakeys'=>array('id','name'),'layout'=>'H','value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $client = ttClientHelper::getClientByName($cl_name); - if (($client && ($cl_id == $client['id'])) || !$client) { - if (ttClientHelper::update(array('id' => $cl_id, - 'name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array('name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_delete')) { - header("Location: client_delete.php?id=$cl_id"); - exit(); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('title', $i18n->get('title.edit_client')); -$smarty->assign('content_page_name', 'mobile/client_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/clients.php b/mobile/clients.php deleted file mode 100644 index d1e6b38f3..000000000 --- a/mobile/clients.php +++ /dev/null @@ -1,54 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -if($user->can('manage_clients')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $inactive_clients = ttGroupHelper::getInactiveClients(true); -} else - $active_clients = $user->getAssignedClients(); - -$smarty->assign('active_clients', $active_clients); -$smarty->assign('inactive_clients', $inactive_clients); -$smarty->assign('title', $i18n->get('title.clients')); -$smarty->assign('content_page_name', 'mobile/clients.tpl'); -$smarty->display('mobile/index.tpl'); From fa0a08caa353fd5e2667780c7bb42eb763ad1b02 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Nov 2020 16:36:43 +0000 Subject: [PATCH 1391/1848] Cosmetic changes in translation files. --- README.md | 2 +- WEB-INF/resources/ca.lang.php | 34 +++++------------------------- WEB-INF/resources/cs.lang.php | 34 +++++------------------------- WEB-INF/resources/da.lang.php | 34 +++++------------------------- WEB-INF/resources/de.lang.php | 28 ++----------------------- WEB-INF/resources/en.lang.php | 34 +++++------------------------- WEB-INF/resources/es.lang.php | 36 ++++++-------------------------- WEB-INF/resources/et.lang.php | 28 ++----------------------- WEB-INF/resources/fa.lang.php | 34 +++++------------------------- WEB-INF/resources/fi.lang.php | 33 +++++------------------------ WEB-INF/resources/fr.lang.php | 32 ++++------------------------ WEB-INF/resources/gr.lang.php | 28 ++----------------------- WEB-INF/resources/he.lang.php | 28 ++----------------------- WEB-INF/resources/hu.lang.php | 28 ++----------------------- WEB-INF/resources/it.lang.php | 28 ++----------------------- WEB-INF/resources/ja.lang.php | 28 ++----------------------- WEB-INF/resources/ko.lang.php | 28 ++----------------------- WEB-INF/resources/nl.lang.php | 28 ++----------------------- WEB-INF/resources/no.lang.php | 28 ++----------------------- WEB-INF/resources/pl.lang.php | 28 ++----------------------- WEB-INF/resources/pt-br.lang.php | 28 ++----------------------- WEB-INF/resources/pt.lang.php | 28 ++----------------------- WEB-INF/resources/ro.lang.php | 28 ++----------------------- WEB-INF/resources/ru.lang.php | 28 ++----------------------- WEB-INF/resources/sk.lang.php | 28 ++----------------------- WEB-INF/resources/sl.lang.php | 28 ++----------------------- WEB-INF/resources/sr.lang.php | 28 ++----------------------- WEB-INF/resources/sv.lang.php | 28 ++----------------------- WEB-INF/resources/tr.lang.php | 28 ++----------------------- WEB-INF/resources/zh-cn.lang.php | 28 ++----------------------- WEB-INF/resources/zh-tw.lang.php | 34 +++++------------------------- initialize.php | 2 +- mobile/index.php | 5 ++--- 33 files changed, 91 insertions(+), 811 deletions(-) diff --git a/README.md b/README.md index f3b7987ef..cf2f8601f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Anuko Time Tracker ## About -Anuko [Time Tracker](https://www.anuko.com/time-tracker/index.htm) is a simple, easy to use, open source, web-based time tracking application written in PHP. It allows you to track the time that employees or colleagues spend working on projects and tasks. It needs a web server such as Apache, IIS, etc. to run on, and a database to keep the data in, such as MySQL. +Anuko [Time Tracker](https://www.anuko.com/time-tracker/index.htm) is an open source, web-based time tracking application written in PHP. It allows you to track the time that employees or colleagues spend working on projects and tasks. It needs a web server such as Apache, IIS, etc. to run on, and a database to keep the data in, such as MySQL. ## Free Hosting [Anuko](https://www.anuko.com) provides [free hosting](https://www.anuko.com/time-tracker/free-hosting/index.htm) of Time Tracker to individuals and small groups up to 5 users. To start using Time Tracker immediately, create a group at https://timetracker.anuko.com diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index de6e0df96..34421e73d 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -1,30 +1,6 @@ '¿Ha oblidat la seva paraula de pas?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'S\\\'ha enviat la petició de restablir paraula de pas.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Sol·licitud de restabliment de la paraula de pas de Anuko Time Tracker', // TODO: translate the following. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Per restablir la paraula de pas, si us plau escrigui-la i faci clic en guardar.', @@ -649,7 +625,7 @@ 'form.mail.to' => 'Per a', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Factura enviada.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 92411b33b..199a96faf 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -1,30 +1,6 @@ 'Zapomenuté heslo?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Zaslán požadavek k vymazání hesla.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker požadavek na vymazání hesla', // TODO: translate the following. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. @@ -662,7 +638,7 @@ 'form.mail.to' => 'Komu', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Faktura odeslána.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 3ab49c39e..88b5324fb 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -1,30 +1,6 @@ 'Nulstilling af adgangskode er sendt på email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker - Anmodning om nulstilling af adgangskode', // TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Hej\n\nNogen, IP %s, har bedt om at få nulstillet din adgangskode. Tryk på linket hvis du vil have nulstillet din adgangskode.\n\n%s\n\nAnuko Time Tracker er et nemt, let at bruge, open source tidsregistrerings system. Besøg https://www.anuko.com for mere information.\n\n", +'form.reset_password.email_body' => "Hej\n\nNogen, IP %s, har bedt om at få nulstillet din adgangskode. Tryk på linket hvis du vil have nulstillet din adgangskode.\n\n%s\n\nAnuko Time Tracker er et open source tidsregistrerings system. Besøg https://www.anuko.com for mere information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Skriv en ny adgangskode og tryk Gem.', @@ -626,7 +602,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Til', 'form.mail.report_subject' => 'Tidsregistrerings Rapport', -'form.mail.footer' => 'Anuko Time Tracker er et simpelt, let at bruge, open source
tidsregistrerings system. Besøg www.anuko.com for mere information.', +'form.mail.footer' => 'Anuko Time Tracker er et open source
tidsregistrerings system. Besøg www.anuko.com for mere information.', 'form.mail.report_sent' => 'Rapport sendt.', 'form.mail.invoice_sent' => 'Faktura sendt.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 7db6f93bb..be1ede828 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -1,30 +1,6 @@ 'Forgot password?', -'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Password reset request sent by email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', -'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Type new password and click on Save.', @@ -587,7 +563,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'To', 'form.mail.report_subject' => 'Time Tracker Report', -'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Invoice sent.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 0c1d2c6b9..e7df23ad6 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -1,30 +1,6 @@ '¿Olvido su contraseña?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. // TODO: check / improve translation of form.reset_password.message. @@ -486,9 +462,9 @@ 'form.reset_password.email_subject' => 'Solicitud de reestablecimiento de la contraseña de Anuko Time Tracker', // Note to translators: the ending of this string needs to be translated. // TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Querido usuario, Alguien, IP %s, solicitó reestablecer su contraseña de Anuko Time Tracker. Por favor visite este enlace si quiere reestablecer su contraseña.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.email_body' => "Querido usuario, Alguien, IP %s, solicitó reestablecer su contraseña de Anuko Time Tracker. Por favor visite este enlace si quiere reestablecer su contraseña.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: improve translation of form.change_password.tip. @@ -664,7 +640,7 @@ // TODO: translate form.mail.report_subject. // 'form.mail.report_subject' => 'Time Tracker Report', // Note to translators: the following strings need to be translated. -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Factura enviada.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index b6b442441..e2c63ef91 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -1,30 +1,6 @@ 'بازیابی رمز عبور؟', // TODO: translate form.login.about. -'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'درخواست بازیابی رمزعبور به ایمیل فرستاده شد.', @@ -481,7 +457,7 @@ // 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', 'form.reset_password.email_subject' => 'درخواست بازیابی رمزعبور فرستاده شد', // TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Older translation is below. // 'form.reset_password.email_body' => "کاربران گرامی\n\n یک نفر، شاید خودتان، درخواست بازیابی رمزعبور نرم افزار رهگیری زمان شما را داشته است.لطفا برای تغییر رمزعبور روی لینک زیر کلیک کنید: \n\n%s\n\n", @@ -649,7 +625,7 @@ 'form.mail.to' => 'به', 'form.mail.report_subject' => 'گزارش تایم شیت', // TODO: translate form.mail.footer. -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.report_sent' => 'گزارش ارسال شد.', 'form.mail.invoice_sent' => 'فاکتور ارسال شد.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 753dcf8ce..42af8047e 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -1,30 +1,6 @@ 'Salasanan nollauspyyntöviesti lähetetty.', 'form.reset_password.email_subject' => 'Anuko Time Tracker -salasanan nollauspyyntö', -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Hyvä käyttäjä,\n\nJoku, IP %s, on pyytänyt nollaamaan Anuko Time Tracker -ohjelman salasanasi. Jos haluat nollata salasanasi, käy sivulla \n\n%s\n\nAnuko Time Tracker on yksinkertainen ja helppokäyttöinen vapaan koodin tuntiseurantaohjelmisto. Lisätietoja sivulla https://www.anuko.com.\n\n", @@ -631,6 +607,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Vastaanottaja', 'form.mail.report_subject' => 'Time Tracker -raportti', +// TODO: English string for form.mail.footer changed. Re-translate. 'form.mail.footer' => 'Anuko Time Tracker on yksinkertainen ja helppokäyttöinen vapaan koodin tuntiseurantaohjelmisto. Lisätietoja sivulla www.anuko.com.', 'form.mail.report_sent' => 'Raportti lähetetty.', 'form.mail.invoice_sent' => 'Lasku lähetetty.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index ca00e9471..46116db12 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -1,30 +1,6 @@ 'Une demande de réinitialisation du mot de passe a été envoyé par courriel.', 'form.reset_password.email_subject' => 'Demande de réinitialisation de mot de passe Anuko Time Tracker', -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Cher utilisateur,\n\nQuelqu\'un, IP %s, avez demandé une réinitialisation de votre mot de passe. Veuillez de suivre ce lien pour le réinitialiser\n\n%s\n\nAnuko Time Tracker est un système de gestion du temps, open source, simple et facile à utiliser. Visitez https://www.anuko.com pour plus d\'informations.\n\n", diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index ba630f269..5e3ee8ee8 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -1,30 +1,6 @@ '忘記密碼?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => '密碼重設請求已經發送。', // TODO: Add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko時間追蹤器密碼重設請求', // TODO: translate the following. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. @@ -647,7 +623,7 @@ 'form.mail.to' => '到', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '發票已送出。', diff --git a/initialize.php b/initialize.php index 4e41c7ea3..ae59bd0db 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5383"); +define("APP_VERSION", "1.19.23.5384"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/index.php b/mobile/index.php index fa3f04c46..8fc64b35e 100644 --- a/mobile/index.php +++ b/mobile/index.php @@ -44,10 +44,9 @@ From 6f4cf24936570945a4809d8cfc33acb42c952813 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Nov 2020 17:17:34 +0000 Subject: [PATCH 1392/1848] Cosmetic improvements in translation files. --- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 3 ++- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 ++ initialize.php | 2 +- 25 files changed, 32 insertions(+), 19 deletions(-) diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 88b5324fb..040405503 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -431,7 +431,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Har du glemt din adgangskode?', -'form.login.about' => 'Anuko Time Tracker er et nemt, let at bruge, open source tidsregistrerings system.', +'form.login.about' => 'Anuko Time Tracker er et open source tidsregistrerings system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Nulstilling af adgangskode er sendt på email.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index be1ede828..2268692bb 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -422,7 +422,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Passwort vergessen?', -'form.login.about' => 'Anuko Time Tracker ist ein einfaches, leicht zu bedienendes, Open-Source Zeiterfassungssystem.', +'form.login.about' => 'Anuko Time Tracker ist ein Open-Source Zeiterfassungssystem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Anfrage zur Zurücksetzung des Passwortes wurde per E-mail gesendet.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index e2c63ef91..30f697cbd 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -439,7 +439,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Unustasid salasõna?', -'form.login.about' => 'Anuko Time Tracker on lihtne, lihtsalt kasutatav ja avatud lähtekoodiga ajaarvestussüsteem.', +'form.login.about' => 'Anuko Time Tracker on avatud lähtekoodiga ajaarvestussüsteem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Salasõna tühistamise teade on saadetud e-postile.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 42af8047e..034ea6ae0 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -436,7 +436,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Salasana unohtunut?', -'form.login.about' => 'Anuko Time Tracker on yksinkertainen ja helppokäyttöinen vapaan koodin tuntiseurantaohjelmisto.', + // TODO: check translation of form.login.about - is open source "vapaan koodin"? +'form.login.about' => 'Anuko Time Tracker on vapaan koodin tuntiseurantaohjelmisto.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Salasanan nollauspyyntöviesti lähetetty.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 46116db12..44ba9b2bb 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -428,7 +428,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Mot de passe oublié?', -'form.login.about' => 'Anuko Time Tracker est un système de gestion du temps, open source, simple et facile à utiliser.', +'form.login.about' => 'Anuko Time Tracker est un système de gestion du temps, open source.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Une demande de réinitialisation du mot de passe a été envoyé par courriel.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 5e3ee8ee8..29404a831 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -428,7 +428,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Ξεχάσατε τον κωδικό πρόσβασης;', -'form.login.about' => 'Anuko Time Tracker είναι ένα απλό, εύχρηστο, ανοικτού κώδικα σύστημα παρακολούθησης χρόνου.', +'form.login.about' => 'Anuko Time Tracker είναι ένα ανοικτού κώδικα σύστημα παρακολούθησης χρόνου.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Το αίτημα επαναφοράς κωδικού πρόσβασης αποστέλλεται μέσω ηλεκτρονικού ταχυδρομείου.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 1460943e2..2bc6129d9 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -453,6 +453,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'שכחת סיסמה?', + // TODO: re-translate form.login.about as it has changed. + // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker הינה מערכת פשוטה, קלה לשימוש וחינמית לניהול זמן.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 509034524..98a566d10 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -450,7 +450,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Elfelejtetted a jelszót?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 1626913ec..1b7f56e46 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -438,7 +438,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Password dimenticata?', -'form.login.about' => 'Anuko Time Tracker è un sistema semplice e open source per registrare i tempi di lavoro.', +'form.login.about' => 'Anuko Time Tracker è un sistema open source per registrare i tempi di lavoro.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Richiesta di reset password inviata via mail.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index b73f3ea83..aae1528cc 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -451,7 +451,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'パスワードを忘れましたか?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => '送信したパスワードの初期化の要求。', // TODO: add "by email" to match the English string. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index e7430b6ee..6794c57e7 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -455,7 +455,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '암호를 잊으셨습니까?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => '송신한 암호 재설정 요청.', // TODO: add "by email" to match the English string. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 959822057..8b2e557ea 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -390,6 +390,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Wachtwoord vergeten?', + // TODO: re-translate form.login.about as it has changed. + // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index ed392d932..77d43637f 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -450,6 +450,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Glemt passordet?', + // TODO: re-translate form.login.about as it has changed. + // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker er et enkelt, brukervennlig tidsregistreringssystem basert på åpen kildekode.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 5f67ff40f..b617314db 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -439,7 +439,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Nie pamiętasz hasła?', -'form.login.about' => 'Anuko Time Tracker jest prostym, łatwym w użyciu, otwartoźródłowym systemem śledzenia czasu.', +'form.login.about' => 'Anuko Time Tracker jest otwartoźródłowym systemem śledzenia czasu.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Instrukcje zmiany hasła zostały wysłane na adres e-mail połączony z kontem.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 3fb2f3aed..95e9d1060 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -434,7 +434,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Esqueceu a senha?', -'form.login.about' => 'Anuko Time Tracker é um sistema, simples, de fácil uso, de código aberto, de rastreamento do tempo.', +'form.login.about' => 'Anuko Time Tracker é um sistema de código aberto de rastreamento do tempo.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Pedido para resetar a senha enviado por e-mail.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index fab8af4cf..dd72ab4b6 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -434,7 +434,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Esqueceu a senha?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 32edb49e9..55731aa05 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -454,7 +454,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Parola pierduta?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Cererea de resetare a parolei a fost trimisa.', // TODO: add "by email" to match the English string. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3268f0878..dd6c1e1c8 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -391,7 +391,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Забыли пароль?', -'form.login.about' => 'Anuko Time Tracker - это открытая (open source), простая и лёгкая в использовании система трекинга рабочего времени.', +'form.login.about' => 'Anuko Time Tracker - это открытая (open source) система трекинга рабочего времени.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Запрос на сброс пароля отослан по e-mail.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 90f500e0c..95a025a7a 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -443,7 +443,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zabudnuté heslo?', -'form.login.about' => 'Anuko Time Tracker je jednoduchý a ľahko použiteľný systém na sledovanie času s otvoreným zdrojovým kódom.', +'form.login.about' => 'Anuko Time Tracker je systém na sledovanie času s otvoreným zdrojovým kódom.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Žiadosť o obnovenie hesla bola odoslaná e-mailom.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 2e1004810..eb8bd99dd 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -426,7 +426,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. // TODO: translate the following. // 'form.login.forgot_password' => 'Forgot password?', -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Zahteva za razveljavitev gesla je bila poslana.', // TODO: add "by email" to match the English string. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index f67e81334..a80f0e67a 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -437,6 +437,8 @@ // Forma prijave. Pogledajte primer na https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zaboravili ste lozinku?', + // TODO: re-translate form.login.about as it has changed. + // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker je jednostavan i lak za korišćenje za praćenje radnog vremena.', // Izmena forme za lozinku. Pogledajte primer na https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index fc1c7bd62..6bae583a7 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -436,6 +436,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Glömt lösenordet?', + // TODO: re-translate form.login.about as it has changed. + // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker är en lättanvänd applikation byggd med öppen källkod som enkelt låter dig spåra och hålla koll på arbetstider.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index f1c164c62..3ba51a116 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -462,7 +462,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Parolanızı unuttunuz mu?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Parola sıfırlama talebi yollandı.', // TODO: add "by email" to match the English string. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index c10942223..7eb54073a 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -442,6 +442,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '忘记密码?', +// TODO: re-translate form.login.about as it has changed. +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker 是一种简单、易用、开放源代码的实时跟踪系统。', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/initialize.php b/initialize.php index ae59bd0db..1f219134f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5384"); +define("APP_VERSION", "1.19.23.5385"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 2de5567b129e8190b9c1f9d80d9cedc5b6c5d37d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Nov 2020 18:10:00 +0000 Subject: [PATCH 1393/1848] Some more refactoring in translation files. --- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 4 ++-- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 6 +++--- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 4 ++-- WEB-INF/resources/pl.lang.php | 4 ++-- WEB-INF/resources/pt-br.lang.php | 4 ++-- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 6 +++--- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 4 ++-- WEB-INF/resources/sl.lang.php | 6 +++--- WEB-INF/resources/sr.lang.php | 4 ++-- WEB-INF/resources/sv.lang.php | 4 ++-- WEB-INF/resources/tr.lang.php | 6 +++--- WEB-INF/resources/zh-cn.lang.php | 2 +- initialize.php | 2 +- 25 files changed, 41 insertions(+), 39 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 2268692bb..13626d9e6 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -427,7 +427,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Anfrage zur Zurücksetzung des Passwortes wurde per E-mail gesendet.', 'form.reset_password.email_subject' => 'Anuko Time Tracker Anfrage zur Zurücksetzung des Passwortes', -'form.reset_password.email_body' => "Sehr geehrter Nutzer,\n\nEin Benutzer mit der IP %s hat vor Kurzem die Zurücksetzung Ihres Passworts für Anuko Time Tracker Passwort angefordert. Bitte rufen Sie diesen Link auf wenn Sie Ihr Passwort zurücksetzen möchten.\n\n%s\n\nAnuko Time Tracker ist ein einfaches, leicht zu bedienendes, Open-Source Zeiterfassungs-System. Besuchen Sie https://www.anuko.com für weitere Informationen.\n\n", +'form.reset_password.email_body' => "Sehr geehrter Nutzer,\n\nEin Benutzer mit der IP %s hat vor Kurzem die Zurücksetzung Ihres Passworts für Anuko Time Tracker Passwort angefordert. Bitte rufen Sie diesen Link auf wenn Sie Ihr Passwort zurücksetzen möchten.\n\n%s\n\nAnuko Time Tracker ist ein Open-Source Zeiterfassungs-System. Besuchen Sie https://www.anuko.com für weitere Informationen.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Um das Passwort zurückzusetzen, geben Sie ein Neues ein und klicken dann auf Speichern.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index e7df23ad6..05c24948c 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -461,7 +461,7 @@ 'form.reset_password.message' => 'Se ha enviado la petición de reestablecer contraseña.', 'form.reset_password.email_subject' => 'Solicitud de reestablecimiento de la contraseña de Anuko Time Tracker', // Note to translators: the ending of this string needs to be translated. -// TODO: English string has changed. "from IP added. Re-translate the beginning. +// TODO: English string has changed. "from IP added. Re-translate. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Querido usuario, Alguien, IP %s, solicitó reestablecer su contraseña de Anuko Time Tracker. Por favor visite este enlace si quiere reestablecer su contraseña.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 30f697cbd..d938cf079 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -444,7 +444,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Salasõna tühistamise teade on saadetud e-postile.', 'form.reset_password.email_subject' => 'Anuko Time Tracker, parooli tühistamise nõue', -'form.reset_password.email_body' => "Lugupeetud Kasutaja,\n\nIP-lt %s on nõutud Teie salasõna lähtestamist. Palun avage allolev link, kui soovite oma parooli lähtestada.\n\n%s\n\nAnuko Time Tracker on lihtne, lihtsalt kasutatav ja avatud lähtekoodiga ajaarvestussüsteem. Lisainfo saamiseks külastage https://www.anuko.com lehekülge.\n\n", +'form.reset_password.email_body' => "Lugupeetud Kasutaja,\n\nIP-lt %s on nõutud Teie salasõna lähtestamist. Palun avage allolev link, kui soovite oma parooli lähtestada.\n\n%s\n\nAnuko Time Tracker on avatud lähtekoodiga ajaarvestussüsteem. Lisainfo saamiseks külastage https://www.anuko.com lehekülge.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Kirjuta siia oma uus parool ja salvesta.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 0d578b64c..0fca34586 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -456,7 +456,7 @@ // TODO: check translation of form.reset_password.email_subject. This is the subject for email message for password reset. Below is the English original. // 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', 'form.reset_password.email_subject' => 'درخواست بازیابی رمزعبور فرستاده شد', -// TODO: English string has changed. "from IP added. Re-translate the beginning. +// TODO: English string has changed. Re-translate. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Older translation is below. // 'form.reset_password.email_body' => "کاربران گرامی\n\n یک نفر، شاید خودتان، درخواست بازیابی رمزعبور نرم افزار رهگیری زمان شما را داشته است.لطفا برای تغییر رمزعبور روی لینک زیر کلیک کنید: \n\n%s\n\n", diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 034ea6ae0..eaad8a293 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -445,7 +445,7 @@ // TODO: English string has changed. Re-translate. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Hyvä käyttäjä,\n\nJoku, IP %s, on pyytänyt nollaamaan Anuko Time Tracker -ohjelman salasanasi. Jos haluat nollata salasanasi, käy sivulla \n\n%s\n\nAnuko Time Tracker on yksinkertainen ja helppokäyttöinen vapaan koodin tuntiseurantaohjelmisto. Lisätietoja sivulla https://www.anuko.com.\n\n", +'form.reset_password.email_body' => "Hyvä käyttäjä,\n\nJoku, IP %s, on pyytänyt nollaamaan Anuko Time Tracker -ohjelman salasanasi. Jos haluat nollata salasanasi, käy sivulla \n\n%s\n\nAnuko Time Tracker on vapaan koodin tuntiseurantaohjelmisto. Lisätietoja sivulla https://www.anuko.com.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Syötä uusi salasana ja osoita Tallenna.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 44ba9b2bb..3d4845cc0 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -436,7 +436,7 @@ // TODO: English string has changed. Re-translate. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Cher utilisateur,\n\nQuelqu\'un, IP %s, avez demandé une réinitialisation de votre mot de passe. Veuillez de suivre ce lien pour le réinitialiser\n\n%s\n\nAnuko Time Tracker est un système de gestion du temps, open source, simple et facile à utiliser. Visitez https://www.anuko.com pour plus d\'informations.\n\n", +'form.reset_password.email_body' => "Cher utilisateur,\n\nQuelqu\'un, IP %s, avez demandé une réinitialisation de votre mot de passe. Veuillez de suivre ce lien pour le réinitialiser\n\n%s\n\nAnuko Time Tracker est un système de gestion du temps, open source. Visitez https://www.anuko.com pour plus d\'informations.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Saisissez votre nouveau mot de passe et cliquez sur Sauvegarder.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 29404a831..61b06f6bd 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -433,7 +433,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Το αίτημα επαναφοράς κωδικού πρόσβασης αποστέλλεται μέσω ηλεκτρονικού ταχυδρομείου.', 'form.reset_password.email_subject' => 'Αίτημα επαναφοράς κωδικού Anuko Time Tracker', -'form.reset_password.email_body' => "Αγαπητέ χρήστη,\n\nΚάποιος από την IP %s ζήτησε επαναφορά του κωδικού πρόσβασης στο Anuko Time Tracker. Πατήστε στον ακόλουθο σύνδεσμο για επαναφορά του κωδικού σας.\n\n%s\n\nΤο Anuko Time Tracker είναι ένα απλό, εύχρηστο, ανοικτού κώδικα σύστημα παρακολούθησης χρόνου. Επισκεφθείτε τη διεύθυνση https://www.anuko.com για περισσότερες πληροφορίες.\n\n", +'form.reset_password.email_body' => "Αγαπητέ χρήστη,\n\nΚάποιος από την IP %s ζήτησε επαναφορά του κωδικού πρόσβασης στο Anuko Time Tracker. Πατήστε στον ακόλουθο σύνδεσμο για επαναφορά του κωδικού σας.\n\n%s\n\nΤο Anuko Time Tracker είναι ένα ανοικτού κώδικα σύστημα παρακολούθησης χρόνου. Επισκεφθείτε τη διεύθυνση https://www.anuko.com για περισσότερες πληροφορίες.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Πληκτρολογήστε νέο κωδικό πρόσβασης και κάντε κλικ στην επιλογή Αποθήκευση.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2bc6129d9..b8459e8b7 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -460,8 +460,8 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'הבקשה לאיפוס בסיסמה נשלחה בדואר אלקטרוני.', 'form.reset_password.email_subject' => 'בקשה לאיפוס סיסמה למערכת Anuko Time Tracker', -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Older translation is below. // 'form.reset_password.email_body' => "משתמש יקר,\n\n התקבלה בקשה לאיפוס סיסמתך. נא ללחוץ על קישור זה אם ברצונך לאפס את הסיסמה.\n\n%s\n\n. Anuko Time Tracker הינה מערכת לניהול זמן פשוטה וחינמית. בקר באתרנו בכתובת https://www.anuko.com לפרטים נוספים.\n\n", diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 98a566d10..a4fe12023 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -456,7 +456,7 @@ // TODO: translate the following. // 'form.reset_password.message' => 'Password reset request sent by email.', // 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index aae1528cc..07db51091 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -457,10 +457,10 @@ 'form.reset_password.message' => '送信したパスワードの初期化の要求。', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Trackerのパスワードの初期化の要求', // TODO: translate the ending of this string. -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Older translation is below. -// 'form.reset_password.email_body' => "尊敬なるお客様、\n\n誰から(多分あなた)あなたのAnuko Time Trackerのパスワードの初期化が要求されました。あなたのパスワードを初期化しようとこのリンクを押してください。\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "尊敬なるお客様、\n\n誰から(多分あなた)あなたのAnuko Time Trackerのパスワードの初期化が要求されました。あなたのパスワードを初期化しようとこのリンクを押してください。\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 6794c57e7..975719ebd 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -461,7 +461,7 @@ 'form.reset_password.message' => '송신한 암호 재설정 요청.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker 암호 재설정 요청', // TODO: translate the following. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 8b2e557ea..ac8431264 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -397,6 +397,8 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Het verzoek om het wachtwoord te herstellen is verzonden per email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker wachtwoord herstel verzoek', +// TODO: retranslate form.reset_password.email_body as the string has changed. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", 'form.reset_password.email_body' => "Geachte medewerker,\n\nIemand, met IP adres %s, heeft verzocht uw wachtwoord in Anuko Time Tracker te herstellen. Klik op deze link als u uw wachtwoord wil wijzigen.\n\n%s\n\nAnuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem. Bezoek https://www.anuko.com voor meer informatie.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 77d43637f..eb406d0f9 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -458,8 +458,8 @@ // TODO: translate the following. // 'form.reset_password.message' => 'Password reset request sent by email.', // 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Kjære bruker,\n\nNoen, IP %s, bad om å få ditt Anuko Time Tracker password resatt. Vær vennlig å besøk denne lenken dersom du ønsker at passordet ditt skal resettes.\n\n%s\n\nAnuko Time Tracker er et enkelt og brukervennlig system for tidsregistrering basert på åpen kildekode. Les mer på https://www.anuko.com.\n\n", diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index b617314db..79952ff56 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -445,9 +445,9 @@ 'form.reset_password.message' => 'Instrukcje zmiany hasła zostały wysłane na adres e-mail połączony z kontem.', 'form.reset_password.email_subject' => 'Anuko Time Tracker - żądanie zmiany hasła', // TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Drogi Użytkowniku,\n\nktoś, IP %s, poprosił o zmianę hasła w aplikacji Anuko Time Tracker. Aby ustawić nowe hasło, proszę kliknąć na poniższy link lub go skopiować i otworzyć w oknie przeglądarki WWW.\n\n%s\n\nJeśli to nie Ty poprosiłeś o zmianę hasła, zignoruj tą wiadomość.\n\nAnuko Time Tracker jest prostym, łatwym w użyciu, otwartoźródłowym systemem do śledzenia czasu. Odwiedź https://www.anuko.com aby uzyskać więcej informacji.\n\n", +'form.reset_password.email_body' => "Drogi Użytkowniku,\n\nktoś, IP %s, poprosił o zmianę hasła w aplikacji Anuko Time Tracker. Aby ustawić nowe hasło, proszę kliknąć na poniższy link lub go skopiować i otworzyć w oknie przeglądarki WWW.\n\n%s\n\nJeśli to nie Ty poprosiłeś o zmianę hasła, zignoruj tą wiadomość.\n\nAnuko Time Tracker jest otwartoźródłowym systemem do śledzenia czasu. Odwiedź https://www.anuko.com aby uzyskać więcej informacji.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Wpisz nowe hasło i kliknij Zapisz.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 95e9d1060..9f446ce5f 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -440,9 +440,9 @@ 'form.reset_password.message' => 'Pedido para resetar a senha enviado por e-mail.', 'form.reset_password.email_subject' => 'Pedido de alteração de senha no Anuko Time Tracker', // TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Prezado usuário,\n\nAlguém, IP %s, solicitou o reset da sua senha do Anuko Time Tracker. Entre nete link para resetar a sua senha.\n\n%s\n\nAnuko Time Tracker é um sistema, simples, de fácil uso, de código abertois, de rastreamento do tempo. Visite https://www.anuko.com para mais informações.\n\n", +'form.reset_password.email_body' => "Prezado usuário,\n\nAlguém, IP %s, solicitou o reset da sua senha do Anuko Time Tracker. Entre nete link para resetar a sua senha.\n\n%s\n\nAnuko Time Tracker é um sistema de código abertois, de rastreamento do tempo. Visite https://www.anuko.com para mais informações.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Entre com a nova senha e clique em Salvar.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index dd72ab4b6..b0ae4794a 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -440,7 +440,7 @@ // TODO: translate the following. // 'form.reset_password.message' => 'Password reset request sent by email.', // 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 55731aa05..2ca785263 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -459,10 +459,10 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Cererea de resetare a parolei a fost trimisa.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker - cerere de resetare a parolei', -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Draga Utilizator,\n\nCineva, IP %s, a cerut resetarea parolei pentru contul Anuko Time Tracker. Te rog, viziteaza acesta legatura daca doresti sa iti resetezi parola.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.email_body' => "Draga Utilizator,\n\nCineva, IP %s, a cerut resetarea parolei pentru contul Anuko Time Tracker. Te rog, viziteaza acesta legatura daca doresti sa iti resetezi parola.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index dd6c1e1c8..53cb89b10 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -396,7 +396,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Запрос на сброс пароля отослан по e-mail.', 'form.reset_password.email_subject' => 'Сброс пароля к Anuko Time Tracker', -'form.reset_password.email_body' => "Уважаемый пользователь,\n\nКто-то c IP %s попросил сбросить ваш пароль к системе Anuko Time Tracker. Пройдите по данной ссылке для сброса пароля.\n\n%s\n\nAnuko Time Tracker - это открытая (open source), простая и лёгкая в использовании система трекинга рабочего времени. Подробности - на сайте https://www.anuko.com.", +'form.reset_password.email_body' => "Уважаемый пользователь,\n\nКто-то c IP %s попросил сбросить ваш пароль к системе Anuko Time Tracker. Пройдите по данной ссылке для сброса пароля.\n\n%s\n\nAnuko Time Tracker - это открытая (open source) система трекинга рабочего времени. Подробности - на сайте https://www.anuko.com.", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Впечатайте новый пароль и нажмите Cохранить.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 95a025a7a..56023db5a 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -449,9 +449,9 @@ 'form.reset_password.message' => 'Žiadosť o obnovenie hesla bola odoslaná e-mailom.', 'form.reset_password.email_subject' => 'Žiadosť o obnovenie hesla do Anuko Time Tracker', // TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Vážený používateľ,\n\nniekto, IP %s, si vyžiadal obnovenie vášho hesla do Anuko Time Tracker. Prosím kliknite na nasledujúcu linku, ak si prajete obnoviť heslo.\n\n%s\n\nAnuko Time Tracker je jednoduchý a ľahko použiteľný systém na sledovanie času s otvoreným zdrojovým kódom. Navštívte https://www.anuko.com pre viac informácií.\n\n", +'form.reset_password.email_body' => "Vážený používateľ,\n\nniekto, IP %s, si vyžiadal obnovenie vášho hesla do Anuko Time Tracker. Prosím kliknite na nasledujúcu linku, ak si prajete obnoviť heslo.\n\n%s\n\nAnuko Time Tracker je systém na sledovanie času s otvoreným zdrojovým kódom. Navštívte https://www.anuko.com pre viac informácií.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Zadajte nové heslo a kliknite na Uložiť.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index eb8bd99dd..ae6ec81c3 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -432,10 +432,10 @@ 'form.reset_password.message' => 'Zahteva za razveljavitev gesla je bila poslana.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker zahteva za razveljavitev gesla', // TODO: translate the ending of this string properly. -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. "from IP" added. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Spoštovani uporabnik,\n\nNekdo, IP %s, je zahteval razveljavitev vašega Anuko Time Tracker gesla. Prosimo obiščite to povezavo, če želite razveljaviti vaše geslo.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.email_body' => "Spoštovani uporabnik,\n\nNekdo, IP %s, je zahteval razveljavitev vašega Anuko Time Tracker gesla. Prosimo obiščite to povezavo, če želite razveljaviti vaše geslo.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index a80f0e67a..abfb0d7bd 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -444,8 +444,8 @@ // Izmena forme za lozinku. Pogledajte primer na https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Zahtev za izmenu lozinke je poslat mejlom.', 'form.reset_password.email_subject' => 'Anuko Time Tracker zahtev za izmenu lozinke', -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Poštovani korisniče,\n\nneko, IP %s, ste poslali zahtev za izmenu lozinke na Anuko Time Tracker nalogu. Molimo da pratite link ako želite da izmenite lozinku.\n\n%s\n\nAnuko Time Tracker je jednostavan i lak za korišćenje za praćenje radnog vremena. Posetite nas na https://www.anuko.com za više informacija.\n\n", diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 6bae583a7..17af93fd8 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -443,8 +443,8 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Begäran om att återställa lösenordet skickades via e-post.', 'form.reset_password.email_subject' => 'Återställning av lösenord för Anuko Time Tracker begärd', -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Kära användare,\n\Någon, IP %s, begärde att ditt lösenord för Anuko Time Tracker skulle återställas. Vänligen besök den här länken ifall du vill återställa ditt lösenord.\n\n%s\n\nAnuko Time Tracker är en lättanvänd applikation byggd med öppen källkod som enkelt låter dig spåra och hålla koll på arbetstider. Besök https://www.anuko.com för mer information.\n\n", diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 3ba51a116..3b98e0a50 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -468,10 +468,10 @@ 'form.reset_password.message' => 'Parola sıfırlama talebi yollandı.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker parola sıfırlama talebi', // TODO: translate the ending of the following. -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Sayın Kullanıcı,\n\nBirisi, IP %s, Anuko Time Tracker parolanızın sıfırlanmasını istedi. Parolanızı sıfırlamak isterseniz lütfen bu bağlantıyı takip edin.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.email_body' => "Sayın Kullanıcı,\n\nBirisi, IP %s, Anuko Time Tracker parolanızın sıfırlanmasını istedi. Parolanızı sıfırlamak isterseniz lütfen bu bağlantıyı takip edin.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7eb54073a..5500155fc 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -450,7 +450,7 @@ 'form.reset_password.message' => '密码重设请求已经发送。', // TODO: Add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko时间追踪器密码重设请求', // TODO: translate the following. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/initialize.php b/initialize.php index 1f219134f..6384b0dad 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5385"); +define("APP_VERSION", "1.19.23.5386"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ad140616820e9fae649e4adeef3663ddee6e48ea Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Nov 2020 19:19:45 +0000 Subject: [PATCH 1394/1848] Minor improvements in translation files. --- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 8 ++++---- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- initialize.php | 2 +- 25 files changed, 32 insertions(+), 24 deletions(-) diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 040405503..efdacc370 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -436,7 +436,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Nulstilling af adgangskode er sendt på email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker - Anmodning om nulstilling af adgangskode', -// TODO: English string has changed. "from IP added. Re-translate the beginning. +// TODO: English string has changed. Re-translate the beginning. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Hej\n\nNogen, IP %s, har bedt om at få nulstillet din adgangskode. Tryk på linket hvis du vil have nulstillet din adgangskode.\n\n%s\n\nAnuko Time Tracker er et open source tidsregistrerings system. Besøg https://www.anuko.com for mere information.\n\n", diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 13626d9e6..e41d92b09 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -580,7 +580,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'An', 'form.mail.report_subject' => 'Time Tracker Bericht', -'form.mail.footer' => 'Anuko Time Tracker ist ein einfaches, leicht zu bedienendes, Open-Source
Zeitverwaltungs-System. Besuchen Sie www.anuko.com für weitere Informationen.', +'form.mail.footer' => 'Anuko Time Tracker ist ein Open-Source
Zeitverwaltungs-System. Besuchen Sie www.anuko.com für weitere Informationen.', 'form.mail.report_sent' => 'Der Bericht wurde gesendet.', 'form.mail.invoice_sent' => 'Die Rechnung wurde gesendet.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 05c24948c..9df814845 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -461,7 +461,7 @@ 'form.reset_password.message' => 'Se ha enviado la petición de reestablecer contraseña.', 'form.reset_password.email_subject' => 'Solicitud de reestablecimiento de la contraseña de Anuko Time Tracker', // Note to translators: the ending of this string needs to be translated. -// TODO: English string has changed. "from IP added. Re-translate. +// TODO: English string has changed. Re-translate. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Querido usuario, Alguien, IP %s, solicitó reestablecer su contraseña de Anuko Time Tracker. Por favor visite este enlace si quiere reestablecer su contraseña.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index d938cf079..7638ade63 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -610,7 +610,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Kellele', 'form.mail.report_subject' => 'Time Tracker raport', -'form.mail.footer' => 'Anuko Time Tracker on lihtne, lihtsalt kasutatav ja avatud lähtekoodiga
ajaarvestussüsteem. Lisainfo saamiseks külastage www.anuko.com lehekülge.', +'form.mail.footer' => 'Anuko Time Tracker on avatud lähtekoodiga
ajaarvestussüsteem. Lisainfo saamiseks külastage www.anuko.com lehekülge.', 'form.mail.report_sent' => 'Raport on saadetud.', 'form.mail.invoice_sent' => 'Arve on saadetud.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 3d4845cc0..771ed18e3 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -598,7 +598,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'À', 'form.mail.report_subject' => 'Rapport Time Tracker', -'form.mail.footer' => 'Anuko Time Tracker est un système de gestion du temps, open source, simple et facile à utiliser. Visitez www.anuko.com pour plus d\\\'informations.', +'form.mail.footer' => 'Anuko Time Tracker est un système de gestion du temps, open source. Visitez www.anuko.com pour plus d\\\'informations.', 'form.mail.report_sent' => 'Le rapport a été envoyé.', 'form.mail.invoice_sent' => 'La facture a été envoyée.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 61b06f6bd..e9003045c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -590,7 +590,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Προς', 'form.mail.report_subject' => 'Time Tracker αναφορά', -'form.mail.footer' => 'Το Anuko Time Tracker είναι ένα απλό, εύχρηστο, ανοικτού κώδικα σύστημα παρακολούθησης χρόνου. Επισκεφθείτε τη διεύθυνση www.anuko.com για περισσότερες πληροφορίες.', +'form.mail.footer' => 'Το Anuko Time Tracker είναι ένα ανοικτού κώδικα σύστημα παρακολούθησης χρόνου. Επισκεφθείτε τη διεύθυνση www.anuko.com για περισσότερες πληροφορίες.', 'form.mail.report_sent' => 'Η αναφορά στάλθηκε.', 'form.mail.invoice_sent' => 'Το τιμολόγιο στάλθηκε.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index b8459e8b7..032e01bf0 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -628,6 +628,8 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'אל', 'form.mail.report_subject' => 'דוח Time Tracker', +// TODO: retranslate form.mail.footer as the English string has changed. +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.footer' => 'Anuko Time Tracker הינה מערכת פשוטה, קלה לשימוש וחינמית לניהול זמן. בקר באתר www.anuko.com לפרטים נוספים.', 'form.mail.report_sent' => 'הדוח נשלח.', 'form.mail.invoice_sent' => 'החשבונית נשלחה.', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index a4fe12023..1909682fb 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -630,7 +630,7 @@ 'form.mail.to' => 'Címzett', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'A számla elküldve.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 1b7f56e46..35035d3e9 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -443,10 +443,10 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Richiesta di reset password inviata via mail.', 'form.reset_password.email_subject' => 'Richiesta reset password per Anuko Time Tracker', -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate the beginning. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Caro utente,\n\n qualcuno, IP %s, ha richiesto di reimpostare la tua password per Anuko Time Tracker. Per favore visita questo link per reimpostare la tua password.\n\n%s\n\nAnuko Time Tracker è un sistema semplice e open source per registrare i tempi di lavoro. Visita https://www.anuko.com per maggiori informazioni.\n\n", +'form.reset_password.email_body' => "Caro utente,\n\n qualcuno, IP %s, ha richiesto di reimpostare la tua password per Anuko Time Tracker. Per favore visita questo link per reimpostare la tua password.\n\n%s\n\nAnuko Time Tracker è un sistema open source per registrare i tempi di lavoro. Visita https://www.anuko.com per maggiori informazioni.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Digita una nuova password e clicca su Salva.', @@ -605,7 +605,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'A', 'form.mail.report_subject' => 'Rapporto Time Tracker', -'form.mail.footer' => 'Anuko Time Tracker è un sistema semplice e open source
per registrare i tempi di lavoro. Visita www.anuko.com per maggiori informazioni.', +'form.mail.footer' => 'Anuko Time Tracker è un sistema open source
per registrare i tempi di lavoro. Visita www.anuko.com per maggiori informazioni.', 'form.mail.report_sent' => 'Rapporto inviato.', 'form.mail.invoice_sent' => 'Fattura inviata.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 07db51091..0ba848ba0 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -633,7 +633,7 @@ 'form.mail.to' => 'まで', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '送信した送り状。', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 975719ebd..975e42169 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -631,7 +631,7 @@ 'form.mail.to' => '까지', // TODO: is this correct? The meaning is that we send an email TO this person. // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '송신한 송장.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index ac8431264..6d51082c7 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -546,6 +546,8 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Aan', 'form.mail.report_subject' => 'Time Tracker rapport', +// TODO: retranslate form.mail.footer as the English string has changed. +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.footer' => 'Anuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem. Bezoek www.anuko.com voor meer informatie.', 'form.mail.report_sent' => 'Rapport is verzonden.', 'form.mail.invoice_sent' => 'Factuur is verzonden.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index eb406d0f9..cfaf305b5 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -632,7 +632,7 @@ 'form.mail.to' => 'Til', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', // 'form.mail.invoice_sent' => 'Invoice sent.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 79952ff56..24664d693 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -610,7 +610,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Do', 'form.mail.report_subject' => 'Raport Time Tracker', -'form.mail.footer' => 'Anuko Time Tracker jest prostym, łatwym w użyciu, otwartoźródłowym
systemem śledzenia czasu. Odwiedź www.anuko.com, aby uzyskać więcej informacji.', +'form.mail.footer' => 'Anuko Time Tracker jest otwartoźródłowym
systemem śledzenia czasu. Odwiedź www.anuko.com, aby uzyskać więcej informacji.', 'form.mail.report_sent' => 'Wysłano raport', 'form.mail.invoice_sent' => 'Wysłano fakturę', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 9f446ce5f..e41cf26c3 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -605,7 +605,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Para', 'form.mail.report_subject' => 'Relatório do Time Tracker', -'form.mail.footer' => 'Anuko Time Tracker é um sistema, simples, de fácil uso, de código aberto,
de rastreamento do tempo. Visite www.anuko.com para mais informações.', +'form.mail.footer' => 'Anuko Time Tracker é um sistema de código aberto,
de rastreamento do tempo. Visite www.anuko.com para mais informações.', 'form.mail.report_sent' => 'Relatório enviado.', 'form.mail.invoice_sent' => 'Fatura enviada.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index b0ae4794a..13912a44d 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -612,7 +612,7 @@ 'form.mail.to' => 'Para', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', // 'form.mail.invoice_sent' => 'Invoice sent.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 2ca785263..0c531ad11 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -633,7 +633,7 @@ 'form.mail.to' => 'Catre', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Factura trimisa.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 53cb89b10..835b90048 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -543,7 +543,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Кому', 'form.mail.report_subject' => 'Time Tracker отчёт', -'form.mail.footer' => 'Anuko Time Tracker - это открытая (open source), простая и лёгкая в использовании система трекинга рабочего времени. Подробности на сайте www.anuko.com.', +'form.mail.footer' => 'Anuko Time Tracker - это открытая (open source) система трекинга рабочего времени. Подробности на сайте www.anuko.com.', 'form.mail.report_sent' => 'Отчёт отправлен.', 'form.mail.invoice_sent' => 'Счёт отправлен.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 56023db5a..57c14a7db 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -615,7 +615,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Komu', 'form.mail.report_subject' => 'Time Tracker zostava', -'form.mail.footer' => 'Anuko Time Tracker je jednoduchý a ľahko použiteľný systém na sledovanie času s otvoreným zdrojovým kódom.
Navštívte www.anuko.com pre viac informácií.', +'form.mail.footer' => 'Anuko Time Tracker je systém na sledovanie času s otvoreným zdrojovým kódom.
Navštívte www.anuko.com pre viac informácií.', 'form.mail.report_sent' => 'Zostava odoslaná.', 'form.mail.invoice_sent' => 'Faktúra odoslaná.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ae6ec81c3..32e200f81 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -606,7 +606,7 @@ 'form.mail.to' => 'Za', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', // 'form.mail.invoice_sent' => 'Invoice sent.', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index abfb0d7bd..38cf8565b 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -610,6 +610,8 @@ // Forma mejla. Pogledajte primer na https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Za', 'form.mail.report_subject' => 'Evidencija vremena', +// TODO: retranslate form.mail.footer as the English string has changed. +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.footer' => 'Anuko Time Tracker je jednostavan i lak za korišćenje za praćenje
radnog vremena. Posetite www.anuko.com za više informacija.', 'form.mail.report_sent' => 'Izveštaj poslat.', 'form.mail.invoice_sent' => 'Račun poslat.', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 17af93fd8..fe05e89a7 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -609,6 +609,8 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Till', 'form.mail.report_subject' => 'Tidsrapport', +// TODO: retranslate form.mail.footer as the English string has changed. +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.footer' => 'Anuko Time Tracker är en lättanvänd applikation byggd med öppen källkod för att enkelt spåra och hålla koll på arbetstider. Besök www.anuko.com för mer information.', 'form.mail.report_sent' => 'Rapporten skickades.', 'form.mail.invoice_sent' => 'Fakturan skickades.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 3b98e0a50..777440e88 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -646,7 +646,7 @@ 'form.mail.to' => 'Kime', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Fatura yollandı.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5500155fc..01e639bdd 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -620,7 +620,7 @@ 'form.mail.to' => '到', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '发票已送出。', diff --git a/initialize.php b/initialize.php index 6384b0dad..52148e8b1 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5386"); +define("APP_VERSION", "1.19.23.5387"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 0ac7c8645b11b61d51a1da55685112c8ba7d97b5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 15:29:40 +0000 Subject: [PATCH 1395/1848] Added separators on some forms to improve UI. --- WEB-INF/templates/client_add2.tpl | 1 + WEB-INF/templates/client_edit2.tpl | 1 + WEB-INF/templates/project_add2.tpl | 2 ++ WEB-INF/templates/project_edit2.tpl | 2 ++ WEB-INF/templates/task_add2.tpl | 1 + WEB-INF/templates/task_edit2.tpl | 1 + initialize.php | 2 +- 7 files changed, 9 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/client_add2.tpl b/WEB-INF/templates/client_add2.tpl index 5fe001b23..2704a133c 100644 --- a/WEB-INF/templates/client_add2.tpl +++ b/WEB-INF/templates/client_add2.tpl @@ -24,6 +24,7 @@ License: See license.txt *}
{if $show_projects} + diff --git a/WEB-INF/templates/client_edit2.tpl b/WEB-INF/templates/client_edit2.tpl index 91f2b1c39..67b79ecdf 100644 --- a/WEB-INF/templates/client_edit2.tpl +++ b/WEB-INF/templates/client_edit2.tpl @@ -30,6 +30,7 @@ License: See license.txt *} {if $show_projects} + diff --git a/WEB-INF/templates/project_add2.tpl b/WEB-INF/templates/project_add2.tpl index 4f2c14286..cd900cf36 100644 --- a/WEB-INF/templates/project_add2.tpl +++ b/WEB-INF/templates/project_add2.tpl @@ -24,6 +24,7 @@ License: See license.txt *} {/if} {if $show_users} + @@ -32,6 +33,7 @@ License: See license.txt *} {/if} {if $show_tasks} + diff --git a/WEB-INF/templates/project_edit2.tpl b/WEB-INF/templates/project_edit2.tpl index 8ce9ae9c7..f7b23a9ac 100644 --- a/WEB-INF/templates/project_edit2.tpl +++ b/WEB-INF/templates/project_edit2.tpl @@ -22,6 +22,7 @@ License: See license.txt *} {if $show_users} + @@ -30,6 +31,7 @@ License: See license.txt *} {/if} {if $show_tasks} + diff --git a/WEB-INF/templates/task_add2.tpl b/WEB-INF/templates/task_add2.tpl index 534c9525e..1b1c4e42e 100644 --- a/WEB-INF/templates/task_add2.tpl +++ b/WEB-INF/templates/task_add2.tpl @@ -16,6 +16,7 @@ License: See license.txt *} {if $show_projects} + diff --git a/WEB-INF/templates/task_edit2.tpl b/WEB-INF/templates/task_edit2.tpl index e66a93e10..9292ad151 100644 --- a/WEB-INF/templates/task_edit2.tpl +++ b/WEB-INF/templates/task_edit2.tpl @@ -22,6 +22,7 @@ License: See license.txt *} {if $show_projects} + diff --git a/initialize.php b/initialize.php index 52148e8b1..2d5f9964d 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5387"); +define("APP_VERSION", "1.19.23.5388"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 1a9ec2adbc3adb32a857f2300ade94da1af8a37f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 16:19:46 +0000 Subject: [PATCH 1396/1848] Styles client address field. --- default.css | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/default.css b/default.css index 820382bdf..40d085f01 100644 --- a/default.css +++ b/default.css @@ -243,14 +243,14 @@ input[type="file"] { width: 237px; } -#description { +#description, #address { width: 220px; border-radius: 4px; border: 1px solid #c9c9c9; padding: .4rem; } -#description:focus { +#description:focus, #address:focus { background-color: yellow; border: 1px solid black; outline: none; diff --git a/initialize.php b/initialize.php index 2d5f9964d..472e4f37f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5388"); +define("APP_VERSION", "1.19.23.5389"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 706fa5628098a513ab667ed8f3261e89310ad3b1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 16:25:15 +0000 Subject: [PATCH 1397/1848] Styled item_name field for expenses. --- default.css | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/default.css b/default.css index 40d085f01..fea2e8da5 100644 --- a/default.css +++ b/default.css @@ -243,14 +243,14 @@ input[type="file"] { width: 237px; } -#description, #address { +#description, #address, #item_name { width: 220px; border-radius: 4px; border: 1px solid #c9c9c9; padding: .4rem; } -#description:focus, #address:focus { +#description:focus, #address:focus, #item_name:focus { background-color: yellow; border: 1px solid black; outline: none; diff --git a/initialize.php b/initialize.php index 472e4f37f..837759f2b 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5389"); +define("APP_VERSION", "1.19.23.5390"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From fef326c0478e77feff6a5b14dad4450b172e8017 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 16:58:05 +0000 Subject: [PATCH 1398/1848] Improved x-scrollable-table styles to alternate rows background. --- WEB-INF/templates/entity_files2.tpl | 3 ++- default.css | 6 ++++-- initialize.php | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/entity_files2.tpl b/WEB-INF/templates/entity_files2.tpl index d6b892b38..07a46443d 100644 --- a/WEB-INF/templates/entity_files2.tpl +++ b/WEB-INF/templates/entity_files2.tpl @@ -23,6 +23,7 @@ License: See license.txt *} {/if} {if $can_edit} +
{$forms.fileUploadForm.open}
 Anuko Time Tracker 1.19.18.5218 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5219 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 837ef05b3..55d047caa 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -1,3 +1,4 @@ + diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index ec0b05926..054c75363 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -1,3 +1,4 @@ + From 07c9f1d30e074481292412cda209f1516550ec1e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 15:28:35 +0000 Subject: [PATCH 1201/1848] Starting refactoring Calendar.class.php. --- WEB-INF/lib/form/Calendar.class.php | 8 +------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index 74f52895d..61b393cba 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -31,9 +31,7 @@ import('ttTimeHelper'); class Calendar extends FormElement { - var $holidays = array(); - var $showHolidays = true; - var $weekStartDay = 0; + var $weekStartDay = 0; // Defaults to Sunday. var $mHeader = "padding: 5px; font-size: 8pt; color: #333333; background-color: #d9d9d9;"; var $mDayCell = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #333333; background-color: #ffffff;"; @@ -72,10 +70,6 @@ function setCellStyle($style) { $this->mCellStyle = $style; } function setACellStyle($style) { $this->mACellStyle = $style; } function setLinkStyle($style) { $this->mLinkStyle = $style; } - function setShowHolidays($value) { - $this->showHolidays = $value; - } - /** * @return void * @param date diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0390d8a25..2278dd082 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} - + - +
Anuko Time Tracker 1.19.18.5219 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5220 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 20156f595b5b9716fa7e7ab4789ba838e52f1192 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 15:53:33 +0000 Subject: [PATCH 1202/1848] Work in progress moving styles out of Calendar class into css file. --- WEB-INF/lib/form/Calendar.class.php | 12 +++--------- WEB-INF/templates/footer.tpl | 2 +- default.css | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index 61b393cba..8ce99cc7e 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -33,9 +33,6 @@ class Calendar extends FormElement { var $weekStartDay = 0; // Defaults to Sunday. - var $mHeader = "padding: 5px; font-size: 8pt; color: #333333; background-color: #d9d9d9;"; - var $mDayCell = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #333333; background-color: #ffffff;"; - var $mDaySelected = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #666666; background-color: #a6ccf7;"; var $mDayWeekend = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #666666; background-color: #f7f7f7;"; var $mDayHoliday = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #666666; background-color: #f7f7f7;"; var $mDayHeader = "padding: 5px; border: 1px solid white; font-size: 8pt; color: #333333;"; @@ -106,7 +103,7 @@ function toString($date="") { $str = $this->_genStyles(); $str .= ' - {/if} - + - +
'. +
'. //'<< '. '<<< '. $this->mMonthNames[$thismonth-1].' '.$thisyear. @@ -159,7 +156,7 @@ function toString($date="") { $stl_cell = ' class="CalendarDayWeekend"'; $stl_link = ' class="CalendarLinkWeekend"'; } else { - $stl_cell = ' class="CalendarDay"'; + $stl_cell = ' class="calendarDay"'; } // holidays @@ -171,7 +168,7 @@ function toString($date="") { // selected day if ( $indate == strftime(DB_DATEFORMAT, $date)) - $stl_cell = ' class="CalendarDaySelected"'; + $stl_cell = ' class="calendarDaySelected"'; $str .= ''; @@ -238,9 +235,6 @@ function _getWeekDayBefore($year, $month) { function _genStyles() { $str = "\n"; - return $str; - } - // _getActiveDates returns an array of dates, for which entries exist for user. // Type of entries (time or expenses) is determined by $this->highlight value. function _getActiveDates($start, $end) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2f8b120bf..369e61911 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- @@ -129,14 +120,14 @@ function toString($date="") { $str .= "\n"; - list($wkstart,$monthstart,$monthend,$start_date) = $this->_getWeekDayBefore( $thisyear, $thismonth ); + list($wkstart,$monthstart,$monthend,$start_date) = $this->_getWeekDayBefore( $selectedYear, $selectedMonth ); $active_dates = $this->_getActiveDates($monthstart, $monthend); - for ( $i = $wkstart; $i<=$monthend; $i=mktime(0,0,0,$thismonth,$start_date+=7,$thisyear) ) { + for ( $i = $wkstart; $i<=$monthend; $i=mktime(0,0,0,$selectedMonth,$start_date+=7,$selectedYear) ) { $str .= "\n"; for ( $j = 0; $j < 7; $j++ ) { - $date = mktime(0,0,0,$thismonth,$start_date+$j,$thisyear); + $date = mktime(0,0,0,$selectedMonth,$start_date+$j,$selectedYear); if (($date >= $monthstart) && ($date <= $monthend)) { $stl_cell = ""; @@ -151,14 +142,14 @@ function toString($date="") { } // holidays - $date_to_check = ttTimeHelper::dateInDatabaseFormat($thisyear, $thismonth, $start_date+$j); + $date_to_check = ttTimeHelper::dateInDatabaseFormat($selectedYear, $selectedMonth, $start_date+$j); if (ttTimeHelper::isHoliday($date_to_check)) { $stl_cell = ' class="calendarDayHoliday"'; $stl_link = ' class="calendarLinkHoliday"'; } // selected day - if ( $indate == strftime(DB_DATEFORMAT, $date)) + if ( $selectedDate == strftime(DB_DATEFORMAT, $date)) $stl_cell = ' class="calendarDaySelected"'; @@ -196,7 +187,7 @@ function toString($date="") { $str .= "\n"; $str .= "
Anuko Time Tracker 1.19.18.5222 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5223 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/default.css b/default.css index 7f138ed38..3eac29ec2 100644 --- a/default.css +++ b/default.css @@ -133,6 +133,22 @@ input[type=checkbox], label { font-size: 8pt; color: #999999; } + +.calendarLinkWeekend { + color: #999999; +} + +.calendarLinkHoliday { + color: #999999; +} + +.calendarLinkRecordsExist { + color: #ff0000; +} + +.calendarLinkNonCompleteDay { + color: #800080; +} /* end of calendar styles */ .tableHeader { From 8dd1f536714f1bc6f09d2176dc84871d33ab94a3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 17:18:16 +0000 Subject: [PATCH 1205/1848] Some more refactoring in Calendar class. --- WEB-INF/lib/form/Calendar.class.php | 57 +++++++++++------------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index e7db6bcfd..dee9fbc0c 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -58,37 +58,28 @@ function localize() { $this->weekStartDay = $user->getWeekStart(); } - // TODO: refactoring ongoing down from here... - - /** - * @return void - * @param date - * @desc Enter description here... - */ - function toString($date="") { - global $i18n; - - $indate = $this->value; - if (!$indate) $indate = strftime(DB_DATEFORMAT); - - //current year and month - if ( strlen ( $indate ) > 0 ) { - $indateObj = new DateAndTime(DB_DATEFORMAT, $indate); - $thismonth = $indateObj->getMonth(); - $thisyear = $indateObj->getYear(); - } else { - $thismonth = date("m"); - $thisyear = date("Y"); - } + // Generates html code for Calendar control. + function getHtml() { + global $i18n; // Needed to print Today. + + $selectedDate = $this->value; + if (!$selectedDate) $selectedDate = strftime(DB_DATEFORMAT); + + // Determine month and year for selected date. + $selectedDateObject = new DateAndTime(DB_DATEFORMAT, $selectedDate); + $selectedMonth = $selectedDateObject->getMonth(); + $selectedYear = $selectedDateObject->getYear(); + + // TODO: refactoring ongoing down from here... // next date, month, year - $next = mktime ( 2, 0, 0, $thismonth + 1, 1, $thisyear ); + $next = mktime ( 2, 0, 0, $selectedMonth + 1, 1, $selectedYear ); $nextyear = date ( "Y", $next ); $nextmonth = date ( "m", $next ); $nextdate = strftime (DB_DATEFORMAT, $next ); // prev date, month, year - $prev = mktime ( 2, 0, 0, $thismonth - 1, 1, $thisyear ); + $prev = mktime ( 2, 0, 0, $selectedMonth - 1, 1, $selectedYear ); $prevyear = date ( "Y", $prev ); $prevmonth = date ( "m", $prev ); $prevdate = strftime(DB_DATEFORMAT, $prev ); @@ -97,7 +88,7 @@ function toString($date="") {
'. //'<< '. '<<< '. - $this->monthNames[$thismonth-1].' '.$thisyear. + $this->monthNames[$selectedMonth-1].' '.$selectedYear. ' >>>'. //' >>'. '
name."=".strftime(DB_DATEFORMAT)."\" tabindex=\"-1\">".$i18n->get('label.today')."
\n"; - $str .= "name\" value=\"$indate\">\n"; + $str .= "name\" value=\"$selectedDate\">\n"; // Add script to adjust today link to match browser today, as PHP may run in a different timezone. $str .= "\n"; - - return $str; - } + // Add a hidden control for selected date. + $html .= "name\" value=\"$selectedDate\">\n"; - function _getWeekDayBefore($year, $month) { - $weekday = date ( "w", mktime ( 2, 0, 0, $month, 1 - $this->weekStartDay, $year ) ); - return array( - mktime ( 0, 0, 0, $month, 1 - $weekday, $year ), - mktime ( 0, 0, 0, $month, 1, $year ), - mktime ( 0, 0, 0, $month + 1, 0, $year ), - (1 - $weekday) - ); - } + // Add script to adjust today link to match browser today, as PHP may run in a different timezone. + $html .= "\n"; + + $html .= "\n\n\n\n\n\n\n"; + return $html; + } - // _getActiveDates returns an array of dates, for which entries exist for user. - // Type of entries (time or expenses) is determined by $this->highlight value. - function _getActiveDates($start, $end) { + // getActiveDates returns an array of dates, for which entries exist for user. + // Type of entries (time or expenses) is determined by $this->highlight value. + function getActiveDates($start, $end) { - global $user; - $user_id = $user->getUser(); + global $user; + $user_id = $user->getUser(); - $table = ($this->highlight == 'expenses') ? 'tt_expense_items' : 'tt_log'; + $table = ($this->highlight == 'expenses') ? 'tt_expense_items' : 'tt_log'; - $mdb2 = getConnection(); - - $start_date = date("Y-m-d", $start); - $end_date = date("Y-m-d", $end); - $sql = "SELECT date FROM $table WHERE date >= '$start_date' AND date <= '$end_date' AND user_id = $user_id AND status = 1"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - while ($row = $res->fetchRow()) { - $out[] = date('Y-m-d', strtotime($row['date'])); - } - return @$out; + $mdb2 = getConnection(); + + $start_date = date("Y-m-d", $start); + $end_date = date("Y-m-d", $end); + $sql = "SELECT date FROM $table WHERE date >= '$start_date' AND date <= '$end_date' AND user_id = $user_id AND status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($row = $res->fetchRow()) { + $out[] = date('Y-m-d', strtotime($row['date'])); } - else - return false; + return @$out; } + else + return false; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7e4eb8f09..d6e3c31ac 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + + {/foreach}
Anuko Time Tracker 1.19.18.5225 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5226 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6c7355065a9e027cc82979e6ea54c62a598a03a9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 12 Jul 2020 16:49:19 +0000 Subject: [PATCH 1208/1848] Cosmetic. --- WEB-INF/lib/form/Calendar.class.php | 6 +++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index e3bf05924..e80f87380 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -134,7 +134,7 @@ function getHtml() { // Iterate through week days. for ($j = 0; $j < 7; $j++) { $cellDate0am = mktime(0, 0, 0, $selectedMonth, $startDayIdx + $j, $selectedYear); - if (($cellDate0am >= $firstDayOfSelectedMonth0am) && ($cellDate0am <= $lastDayOfSelectedMonth0am)) { + if ($cellDate0am >= $firstDayOfSelectedMonth0am && $cellDate0am <= $lastDayOfSelectedMonth0am) { $cell_style = ""; $link_style = ""; @@ -157,9 +157,9 @@ function getHtml() { $cell_style = ' class="calendarDaySelected"'; $html .= ''; - if($active_dates) { + if ($active_dates) { // Entries exist. - if( in_array(strftime(DB_DATEFORMAT, $cellDate0am), $active_dates) ){ + if (in_array(strftime(DB_DATEFORMAT, $cellDate0am), $active_dates)) { // TODO: add a config option to eliminate these call for users not wanting this feature. $day_total_minutes = ttTimeHelper::toMinutes(ttTimeHelper::getTimeForDay($date_to_check)); // Check if entries total to a complete work day. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d6e3c31ac..9e70ecb45 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9e70ecb45..3e158c480 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.18.5226 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5227 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 447afd69ce1a81cfaa2d17de1d050e418ffb68f2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 12 Jul 2020 18:52:07 +0000 Subject: [PATCH 1209/1848] Added a config option whether to show not complete days in calendar. --- WEB-INF/lib/form/Calendar.class.php | 19 +++-- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/display_options.tpl | 4 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/test.tpl | 17 +++++ display_options.php | 4 + test.php | 106 ++++++++++++++++++++++++++ 36 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 WEB-INF/templates/test.tpl create mode 100644 test.php diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index e80f87380..b624a8da2 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -126,6 +126,8 @@ function getHtml() { // Determine active dates where entries exist for user. $active_dates = $this->getActiveDates($firstDayOfSelectedMonth0am, $lastDayOfSelectedMonth0am); + $handleHolidays = $user->getHolidays() != null; + $handleNotCompleteDays = $user->isOptionEnabled('time_not_complete_days'); $workday_minutes = $user->getWorkdayMinutes(); // Print calendar cells one week row at a time. @@ -147,7 +149,7 @@ function getHtml() { // Handle holidays. $date_to_check = ttTimeHelper::dateInDatabaseFormat($selectedYear, $selectedMonth, $startDayIdx+$j); - if (ttTimeHelper::isHoliday($date_to_check)) { + if ($handleHolidays && ttTimeHelper::isHoliday($date_to_check)) { $cell_style = ' class="calendarDayHoliday"'; $link_style = ' class="calendarLinkHoliday"'; } @@ -157,16 +159,19 @@ function getHtml() { $cell_style = ' class="calendarDaySelected"'; $html .= ''; + // Handle days with existing entries. if ($active_dates) { // Entries exist. if (in_array(strftime(DB_DATEFORMAT, $cellDate0am), $active_dates)) { - // TODO: add a config option to eliminate these call for users not wanting this feature. - $day_total_minutes = ttTimeHelper::toMinutes(ttTimeHelper::getTimeForDay($date_to_check)); - // Check if entries total to a complete work day. - if ($day_total_minutes >= $workday_minutes) - $link_style = ' class="calendarLinkRecordsExist"'; + if ($handleNotCompleteDays && $this->highlight == 'time') { + $day_total_minutes = ttTimeHelper::toMinutes(ttTimeHelper::getTimeForDay($date_to_check)); + if ($day_total_minutes >= $workday_minutes) + $link_style = ' class="calendarLinkRecordsExist"'; + else + $link_style = ' class="calendarLinkNonCompleteDay"'; + } else - $link_style = ' class="calendarLinkNonCompleteDay"'; + $link_style = ' class="calendarLinkRecordsExist"'; } } $html .= "name."=".strftime(DB_DATEFORMAT, $cellDate0am)."\" tabindex=\"-1\">".date("d",$cellDate0am).""; diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 9893ad523..5260ecc1d 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -706,6 +706,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 59756d1b5..2ae8ed511 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -719,6 +719,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index a8a14b53d..f15a08b09 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -681,6 +681,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index a8f1d165a..fa0407b8f 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -657,6 +657,8 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Beschreibung in separater Zeile', +// TODO: translate the following. +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 2beefaa1c..c96415300 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -637,6 +637,7 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Note on separate row', +'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php 'work.error.work_not_available' => 'Work item is not available.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 1cf3ce768..fe77bf299 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -721,6 +721,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 5e2e78caa..9dc067415 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -688,6 +688,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index e078a0a34..a9a1d76f0 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -705,6 +705,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 575dc04f6..6e1787474 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -687,6 +687,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 5fe0f76d7..a4a9a74f7 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -677,6 +677,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 5d0dd6bde..8137dbd58 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -670,6 +670,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 199e26533..5010087a8 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -706,6 +706,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index a4a4dd005..683636a67 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -711,6 +711,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index b10575302..4d3540592 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -684,6 +684,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 8ebec5955..cfbeca196 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -714,6 +714,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 76c159472..2ed5c1bfc 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -712,6 +712,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 06f764d4c..6d815c746 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -640,6 +640,8 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', +// TODO: translate the following. +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index ad95bd7e3..8afcf5c17 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -711,6 +711,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index f988df4a4..4dbf608fe 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -690,6 +690,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 5c9d89a32..cca28d179 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -685,6 +685,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 3043e8bba..57db2d012 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -693,6 +693,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index add70a4ea..eab6eb7a5 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -714,6 +714,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index fb050a1a0..1050013e0 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -618,6 +618,7 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.menu' => 'Меню', 'form.display_options.note_on_separate_row' => 'Комментарий в отдельном ряду', +'form.display_options.not_complete_days' => 'Незавершенные дни', // Work plugin strings. See example at https://timetracker.anuko.com/work.php 'work.error.work_not_available' => 'Работа отсутствует.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index cf0b8432b..e0ae714fc 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -695,6 +695,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index f4aa21b58..0dd6f7206 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -687,6 +687,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index be5739b6e..b7b93ffbd 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -688,6 +688,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 43b0d92b6..24797672a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -686,6 +686,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index e241cace8..c2f30dfbb 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -727,6 +727,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index b1d81418b..9cbb47534 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -698,6 +698,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 05615586d..774b8024a 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -704,6 +704,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index d7bbdd57d..918a48f9e 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -5,6 +5,10 @@
{$forms.displayOptionsForm.time_note_on_separate_row.control} {$i18n.label.what_is_it}
{$forms.displayOptionsForm.time_not_complete_days.control} {$i18n.label.what_is_it}
- {/if} {if $u.group_id != $user->group_id || $u.rank < $user->rank || ($u.rank == $user->rank && $u.id == $user->id)} - - {if $u.id != $user->id}{else}{/if} + + {if $u.id != $user->id}{else}{/if} {else} @@ -76,8 +76,8 @@ {/if} {if $u.group_id != $user->group_id || $u.rank < $user->rank} - - + + {else} diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl index 5ac3be85e..9d3ef0bf2 100644 --- a/WEB-INF/templates/week.tpl +++ b/WEB-INF/templates/week.tpl @@ -149,23 +149,23 @@ function fillDropdowns() { {if $show_files} {if $record.has_files} - + {else} - + {/if} {/if} diff --git a/WEB-INF/templates/work/admin_work.tpl b/WEB-INF/templates/work/admin_work.tpl index 39050ab3e..929b4d619 100644 --- a/WEB-INF/templates/work/admin_work.tpl +++ b/WEB-INF/templates/work/admin_work.tpl @@ -22,8 +22,8 @@ - - + + {/foreach}
Anuko Time Tracker 1.19.18.5227 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5228 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/test.tpl b/WEB-INF/templates/test.tpl new file mode 100644 index 000000000..325d686bc --- /dev/null +++ b/WEB-INF/templates/test.tpl @@ -0,0 +1,17 @@ + + +{$forms.timeRecordForm.open} + + + + +
+ + +
{$forms.timeRecordForm.date.control}
+
+{$forms.timeRecordForm.close} diff --git a/display_options.php b/display_options.php index d65f15ab3..7dd724d44 100644 --- a/display_options.php +++ b/display_options.php @@ -41,9 +41,11 @@ if ($request->isPost()) { $cl_time_note_on_separate_row = $request->getParameter('time_note_on_separate_row'); + $cl_time_not_complete_days = $request->getParameter('time_not_complete_days'); $cl_report_note_on_separate_row = $request->getParameter('report_note_on_separate_row'); } else { $cl_time_note_on_separate_row = $config->getDefinedValue('time_note_on_separate_row'); + $cl_time_not_complete_days = $config->getDefinedValue('time_not_complete_days'); $cl_report_note_on_separate_row = $config->getDefinedValue('report_note_on_separate_row'); } @@ -58,6 +60,7 @@ // $form->addInput(array('type'=>'checkbox','name'=>'time_duration','value'=>$cl_time_duration)); // $form->addInput(array('type'=>'checkbox','name'=>'time_note','value'=>$cl_time_note)); $form->addInput(array('type'=>'checkbox','name'=>'time_note_on_separate_row','value'=>$cl_time_note_on_separate_row)); +$form->addInput(array('type'=>'checkbox','name'=>'time_not_complete_days','value'=>$cl_time_not_complete_days)); // TODO: consider adding other fields (timesheet, work_units, invoice, approved, cost, paid)? // Reports. @@ -70,6 +73,7 @@ if ($err->no()) { // Update config. $config->setDefinedValue('time_note_on_separate_row', $cl_time_note_on_separate_row); + $config->setDefinedValue('time_not_complete_days', $cl_time_not_complete_days); $config->setDefinedValue('report_note_on_separate_row', $cl_report_note_on_separate_row); if ($user->updateGroup(array('config' => $config->getConfig()))) { header('Location: success.php'); diff --git a/test.php b/test.php new file mode 100644 index 000000000..971ebaf36 --- /dev/null +++ b/test.php @@ -0,0 +1,106 @@ +behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { + header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. + exit(); +} +if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. + exit(); +} +if ($request->isPost()) { + $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + header('Location: access_denied.php'); // User changed, but no right or wrong user id. + exit(); + } +} +// End of access checks. + +// Determine user for whom we display this page. +if ($request->isPost() && $userChanged) { + $user_id = $request->getParameter('user'); + $user->setOnBehalfUser($user_id); +} else { + $user_id = $user->getUser(); +} + +$group_id = $user->getGroup(); +$config = new ttConfigHelper($user->getConfig()); + +// Initialize and store date in session. +$cl_date = $request->getParameter('date', @$_SESSION['date']); +$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); +if($selected_date->isError()) + $selected_date = new DateAndTime(DB_DATEFORMAT); +if(!$cl_date) + $cl_date = $selected_date->toString(DB_DATEFORMAT); +$_SESSION['date'] = $cl_date; + +// Elements of timeRecordForm. +$form = new Form('timeRecordForm'); + +// Calendar. +$form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar + +// A hidden control for today's date from user's browser. +$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. + +if ($request->isPost()) { + if ($request->getParameter('btn_submit')) { + + } +} // isPost + + +$smarty->assign('selected_date', $selected_date); +$smarty->assign('week_total', $week_total); +$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="fillDropdowns();prepopulateNote();"'); +$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); +$smarty->assign('title', $i18n->get('title.time')); +$smarty->assign('content_page_name', 'test.tpl'); +$smarty->display('index.tpl'); + From 86ac2ba703cf3477f4cd5d28dd4ee55e09ee8671 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 12 Jul 2020 18:53:45 +0000 Subject: [PATCH 1210/1848] Removed test page. --- WEB-INF/templates/test.tpl | 17 ------ test.php | 106 ------------------------------------- 2 files changed, 123 deletions(-) delete mode 100644 WEB-INF/templates/test.tpl delete mode 100644 test.php diff --git a/WEB-INF/templates/test.tpl b/WEB-INF/templates/test.tpl deleted file mode 100644 index 325d686bc..000000000 --- a/WEB-INF/templates/test.tpl +++ /dev/null @@ -1,17 +0,0 @@ - - -{$forms.timeRecordForm.open} - - - - -
- - -
{$forms.timeRecordForm.date.control}
-
-{$forms.timeRecordForm.close} diff --git a/test.php b/test.php deleted file mode 100644 index 971ebaf36..000000000 --- a/test.php +++ /dev/null @@ -1,106 +0,0 @@ -behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. - exit(); -} -if ($request->isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { - header('Location: access_denied.php'); // User changed, but no right or wrong user id. - exit(); - } -} -// End of access checks. - -// Determine user for whom we display this page. -if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -$group_id = $user->getGroup(); -$config = new ttConfigHelper($user->getConfig()); - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; - -// Elements of timeRecordForm. -$form = new Form('timeRecordForm'); - -// Calendar. -$form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar - -// A hidden control for today's date from user's browser. -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. - -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - - } -} // isPost - - -$smarty->assign('selected_date', $selected_date); -$smarty->assign('week_total', $week_total); -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="fillDropdowns();prepopulateNote();"'); -$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); -$smarty->assign('title', $i18n->get('title.time')); -$smarty->assign('content_page_name', 'test.tpl'); -$smarty->display('index.tpl'); - From 275fa15951ebfe27ba05572471de9e0ef914680c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 13 Jul 2020 13:28:47 +0000 Subject: [PATCH 1211/1848] Cosmetic. Removed some white space. --- WEB-INF/lib/form/Calendar.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index b624a8da2..1847b3fa8 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -80,7 +80,7 @@ function getHtml() { $firstOfPreviousMonth = strftime(DB_DATEFORMAT, $firstOfPreviousMonth2AM); // Print calendar header. - $html .= "\n\n\n\n\n\n\n"; + $html .= "\n\n\n"; $html .= ''."\n"; $html .= ' + {else} - + {/if} {/if} - - + + {/foreach}
'; $html .= '
'; @@ -201,7 +201,7 @@ function getHtml() { $html .= "adjustToday();\n"; $html .= "\n"; - $html .= "\n\n\n\n\n\n\n"; + $html .= "\n\n"; return $html; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3e158c480..549a20384 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +{if defined(CUSTOM_CSS_DEBUG)} + + + + + +{/if} + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f0706ae07..0ae53d506 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.18.5228 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5229 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 28992336205e7e453226a26273b4e5743eb81da0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 14 Jul 2020 18:22:40 +0000 Subject: [PATCH 1212/1848] Starting to work on custom css. Introduced a database field. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 549a20384..f0706ae07 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
Anuko Time Tracker 1.19.18.5229 | Copyright © Anuko | + Anuko Time Tracker 1.19.19.5230 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index f596a05e6..242d57b84 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1161,7 +1161,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11917"]) { + if ($_POST["convert11900to11919"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1188,6 +1188,8 @@ function ttGenerateKeys() { ttExecute("create index template_idx on tt_project_template_binds(template_id)"); ttExecute("create unique index project_template_idx on tt_project_template_binds(project_id, template_id)"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.17', modified = now() where param_name = 'version_db' and param_value = '1.19.14'"); + ttExecute("ALTER TABLE `tt_groups` ADD `custom_css` text default NULL AFTER `config`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.19', modified = now() where param_name = 'version_db' and param_value = '1.19.17'"); } if ($_POST["cleanup"]) { @@ -1238,7 +1240,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.19.17) + Create database structure (v1.19.19)
(applies only to new installations, do not execute when updating)
@@ -1287,8 +1289,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.17)Update database structure (v1.19 to v1.19.19)
diff --git a/mysql.sql b/mysql.sql index ae31890b5..e3ccd7d2c 100644 --- a/mysql.sql +++ b/mysql.sql @@ -39,6 +39,7 @@ CREATE TABLE `tt_groups` ( `workday_minutes` smallint(4) default 480, # number of work minutes in a regular working day `custom_logo` tinyint(4) default 0, # whether to use a custom logo or not `config` text default NULL, # miscellaneous group configuration settings + `custom_css` text default NULL, # custom css for group `created` datetime default NULL, # creation timestamp `created_ip` varchar(45) default NULL, # creator ip `created_by` int(11) default NULL, # creator user_id @@ -655,4 +656,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.17', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.19', now()); # TODO: change when structure changes. From c6d062ac68917e6e08f0e9f0706c071a09fb04d4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 14 Jul 2020 19:58:59 +0000 Subject: [PATCH 1213/1848] Some more work in progress on custom css feature. --- WEB-INF/lib/ttUser.class.php | 12 ++++++++++-- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/display_options.tpl | 8 ++++++++ WEB-INF/templates/footer.tpl | 2 +- display_options.php | 1 + 34 files changed, 50 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 4ef5d26e0..ed3dc437b 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -74,6 +74,7 @@ class ttUser { // Refactoring ongoing. Towards using helper instead of config string? var $config = null; // Comma-separated list of miscellaneous config options. var $configHelper = null; // An instance of ttConfigHelper class. + var $custom_css = null; // Custom css. var $custom_logo = 0; // Whether to use a custom logo for group. var $lock_spec = null; // Cron specification for record locking. @@ -97,7 +98,7 @@ function __construct($login, $id = null) { $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id,". " u.quota_percent, u.email, g.org_id, g.group_key, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format,". " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.task_required, g.record_type,". - " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.holidays, g.workday_minutes, g.custom_logo". + " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.custom_css, g.holidays, g.workday_minutes, g.custom_logo". " FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; if ($id) $sql .= "u.id = $id"; @@ -155,7 +156,9 @@ function __construct($login, $id = null) { $this->punch_mode = $this->configHelper->getDefinedValue('punch_mode'); $this->allow_overlap = $this->configHelper->getDefinedValue('allow_overlap'); $this->future_entries = $this->configHelper->getDefinedValue('future_entries'); - + + $this->custom_css = $val['custom_css']; + // Set "on behalf" id and name (user). if (isset($_SESSION['behalf_id'])) { $this->behalf_id = $_SESSION['behalf_id']; @@ -304,6 +307,11 @@ function getConfigInt($name, $defaultVal) { return $config->getIntValue($name, $defaultVal); } + // getCustomCss returns custom css for active group. + function getCustomCss() { + return ($this->behalfGroup ? $this->behalfGroup->custom_css : $this->custom_css); + } + // can - determines whether user has a right to do something. function can($do_something) { return in_array($do_something, $this->rights); diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 5260ecc1d..30efec063 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -707,6 +707,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 2ae8ed511..707b3dcbe 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -720,6 +720,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index f15a08b09..9b061118f 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -682,6 +682,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index fa0407b8f..a66723626 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -659,6 +659,7 @@ 'form.display_options.note_on_separate_row' => 'Beschreibung in separater Zeile', // TODO: translate the following. // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index c96415300..4b17bc464 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -638,6 +638,7 @@ 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Note on separate row', 'form.display_options.not_complete_days' => 'Not complete days', +'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php 'work.error.work_not_available' => 'Work item is not available.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index fe77bf299..0bd854328 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -722,6 +722,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 9dc067415..0b4603566 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -689,6 +689,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index a9a1d76f0..ef7591192 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -706,6 +706,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 6e1787474..2d91252ef 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -688,6 +688,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a4a9a74f7..a4452a4e2 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -678,6 +678,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 8137dbd58..d2d036ddf 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -671,6 +671,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 5010087a8..3f0cf5d66 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -707,6 +707,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 683636a67..82f1ff081 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -712,6 +712,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 4d3540592..15407a6b9 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -685,6 +685,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index cfbeca196..b116fb35b 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -715,6 +715,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 2ed5c1bfc..6b17d47d2 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -713,6 +713,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 6d815c746..5881139e3 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -642,6 +642,7 @@ 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', // TODO: translate the following. // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 8afcf5c17..3677fdda5 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -712,6 +712,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 4dbf608fe..dff252c93 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -691,6 +691,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index cca28d179..db5e0f17c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -686,6 +686,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 57db2d012..b88fb9f18 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -694,6 +694,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index eab6eb7a5..c569adb7e 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -715,6 +715,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 1050013e0..5302c225b 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -619,6 +619,7 @@ 'form.display_options.menu' => 'Меню', 'form.display_options.note_on_separate_row' => 'Комментарий в отдельном ряду', 'form.display_options.not_complete_days' => 'Незавершенные дни', +'form.display_options.custom_css' => 'Пользовательская CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php 'work.error.work_not_available' => 'Работа отсутствует.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index e0ae714fc..53c5ee3dc 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -696,6 +696,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 0dd6f7206..a3d350ca6 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -688,6 +688,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index b7b93ffbd..fe385a67c 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -689,6 +689,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 24797672a..221c39d4a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -687,6 +687,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index c2f30dfbb..0f0537325 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -728,6 +728,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 9cbb47534..29422cc5f 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -699,6 +699,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 774b8024a..d4720b341 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -705,6 +705,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index 918a48f9e..0f78e082e 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -19,6 +19,14 @@
{$forms.displayOptionsForm.report_note_on_separate_row.control} {$i18n.label.what_is_it}
 
{$i18n.form.display_options.custom_css}
{$forms.displayOptionsForm.custom_css.control}
 
{$forms.displayOptionsForm.btn_save.control}
- -{if defined(CUSTOM_CSS_DEBUG)} -{/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0ae53d506..50ff6f264 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.19.5230 | Copyright © Anuko | + Anuko Time Tracker 1.19.19.5231 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/display_options.php b/display_options.php index 7dd724d44..4430af38b 100644 --- a/display_options.php +++ b/display_options.php @@ -67,6 +67,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'report_note_on_separate_row','value'=>$cl_report_note_on_separate_row)); // TODO: add PDF break controller here. +$form->addInput(array('type'=>'textarea','name'=>'custom_css','style'=>'width: 250px; height: 40px;','value'=>$cl_custom_css)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()){ From f33ed44a6703ba05d933c2b37d44900bca8cfd49 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 15 Jul 2020 01:08:39 +0000 Subject: [PATCH 1214/1848] Initial implementation of custom css for groups. --- WEB-INF/lib/ttUser.class.php | 3 ++- WEB-INF/templates/display_options.tpl | 2 -- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 3 +++ WEB-INF/templates/mobile/header.tpl | 3 +++ custom_css.php | 34 +++++++++++++++++++++++++++ display_options.php | 6 ++++- 7 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 custom_css.php diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index ed3dc437b..a62fc5809 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -716,6 +716,7 @@ function updateGroup($fields) { if (isset($fields['allow_ip'])) $allow_ip_part = ', allow_ip = '.$mdb2->quote($fields['allow_ip']); if (isset($fields['plugins'])) $plugins_part = ', plugins = '.$mdb2->quote($fields['plugins']); if (isset($fields['config'])) $config_part = ', config = '.$mdb2->quote($fields['config']); + if (isset($fields['custom_css'])) $custom_css_part = ', custom_css = '.$mdb2->quote($fields['custom_css']); if (isset($fields['lock_spec'])) $lock_spec_part = ', lock_spec = '.$mdb2->quote($fields['lock_spec']); if (isset($fields['holidays'])) $holidays_part = ', holidays = '.$mdb2->quote($fields['holidays']); if (isset($fields['workday_minutes'])) $workday_minutes_part = ', workday_minutes = '.$mdb2->quote($fields['workday_minutes']); @@ -723,7 +724,7 @@ function updateGroup($fields) { $parts = trim($name_part.$description_part.$currency_part.$lang_part.$decimal_mark_part.$date_format_part. $time_format_part.$week_start_part.$tracking_mode_part.$task_required_part.$project_required_part.$record_type_part. - $bcc_email_part.$allow_ip_part.$plugins_part.$config_part.$lock_spec_part.$holidays_part.$workday_minutes_part.$modified_part, ','); + $bcc_email_part.$allow_ip_part.$plugins_part.$config_part.$custom_css_part.$lock_spec_part.$holidays_part.$workday_minutes_part.$modified_part, ','); $sql = "update tt_groups set $parts where id = $group_id and org_id = $this->org_id"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index 0f78e082e..f41bd6f58 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -19,13 +19,11 @@ {$forms.displayOptionsForm.report_note_on_separate_row.control} {$i18n.label.what_is_it}
 
{$i18n.form.display_options.custom_css}
{$forms.displayOptionsForm.custom_css.control}
 
- - + {/if} diff --git a/WEB-INF/templates/time_edit.tpl b/WEB-INF/templates/time_edit.tpl index f1eca33cf..45c9bc666 100644 --- a/WEB-INF/templates/time_edit.tpl +++ b/WEB-INF/templates/time_edit.tpl @@ -57,7 +57,7 @@ function confirmSave() { {/if} {if $show_task} - + {/if} diff --git a/group_edit.php b/group_edit.php index c4fdc2174..2196d280b 100644 --- a/group_edit.php +++ b/group_edit.php @@ -85,7 +85,6 @@ $cl_holidays = trim($request->getParameter('holidays')); $cl_tracking_mode = $request->getParameter('tracking_mode'); $cl_project_required = $request->getParameter('project_required'); - $cl_task_required = $request->getParameter('task_required'); $cl_record_type = $request->getParameter('record_type'); $cl_punch_mode = $request->getParameter('punch_mode'); $cl_allow_overlap = $request->getParameter('allow_overlap'); @@ -102,7 +101,6 @@ $cl_holidays = $group['holidays']; $cl_tracking_mode = $group['tracking_mode']; $cl_project_required = $group['project_required']; - $cl_task_required = $group['task_required']; $cl_record_type = $group['record_type']; $cl_punch_mode = $config->getDefinedValue('punch_mode'); $cl_allow_overlap = $config->getDefinedValue('allow_overlap'); @@ -177,9 +175,8 @@ $tracking_mode_options[MODE_TIME] = $i18n->get('form.group_edit.mode_time'); $tracking_mode_options[MODE_PROJECTS] = $i18n->get('form.group_edit.mode_projects'); $tracking_mode_options[MODE_PROJECTS_AND_TASKS] = $i18n->get('form.group_edit.mode_projects_and_tasks'); -$form->addInput(array('type'=>'combobox','name'=>'tracking_mode','style'=>'width: 150px;','data'=>$tracking_mode_options,'value'=>$cl_tracking_mode,'onchange'=>'handleTaskRequiredCheckbox()')); +$form->addInput(array('type'=>'combobox','name'=>'tracking_mode','style'=>'width: 150px;','data'=>$tracking_mode_options,'value'=>$cl_tracking_mode)); $form->addInput(array('type'=>'checkbox','name'=>'project_required','value'=>$cl_project_required)); -$form->addInput(array('type'=>'checkbox','name'=>'task_required','value'=>$cl_task_required)); // Prepare record type choices. $record_type_options = array(); @@ -241,7 +238,6 @@ 'holidays' => $cl_holidays, 'tracking_mode' => $cl_tracking_mode, 'project_required' => $cl_project_required, - 'task_required' => $cl_task_required, 'record_type' => $cl_record_type, 'uncompleted_indicators' => $cl_uncompleted_indicators, 'config' => $config->getConfig()))) { @@ -255,7 +251,7 @@ $smarty->assign('group_dropdown', count($groups) > 1); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="handleTaskRequiredCheckbox(); handlePluginCheckboxes();"'); +$smarty->assign('onload', 'onLoad="handlePluginCheckboxes();"'); $smarty->assign('title', $i18n->get('title.edit_group')); $smarty->assign('content_page_name', 'group_edit.tpl'); $smarty->display('index.tpl'); diff --git a/mobile/time.php b/mobile/time.php index 8f4ca0a32..58661632a 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -73,6 +73,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; @@ -306,7 +307,7 @@ if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (strlen($cl_duration) == 0) { @@ -396,6 +397,7 @@ $smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('show_start', $showStart); $smarty->assign('show_duration', $showDuration); $smarty->assign('client_list', $client_list); diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 1aa7dd1f4..fb3a918dc 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -58,6 +58,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; @@ -302,7 +303,7 @@ if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $task_required) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (!$cl_duration) { @@ -480,6 +481,7 @@ $smarty->assign('show_paid_status', $showPaidStatus); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('show_start', $showStart); $smarty->assign('show_duration', $showDuration); $smarty->assign('client_list', $client_list); diff --git a/tasks.php b/tasks.php index 7b5f99790..2e13ead5c 100644 --- a/tasks.php +++ b/tasks.php @@ -41,12 +41,35 @@ } // End of access checks. +$config = $user->getConfigHelper(); + +if ($request->isPost()) { + $cl_task_required = $request->getParameter('task_required'); +} else { + $cl_task_required = $config->getDefinedValue('task_required'); +} + if($user->can('manage_tasks')) { $active_tasks = ttGroupHelper::getActiveTasks(); $inactive_tasks = ttGroupHelper::getInactiveTasks(); } else $active_tasks = $user->getAssignedTasks(); +$form = new Form('tasksForm'); +$form->addInput(array('type'=>'checkbox','name'=>'task_required','value'=>$cl_task_required)); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_save')) { + // Save button clicked. Update config. + $config->setDefinedValue('task_required', $cl_task_required); + if (!$user->updateGroup(array('config' => $config->getConfig()))) { + $err->add($i18n->get('error.db')); + } + } +} + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('active_tasks', $active_tasks); $smarty->assign('inactive_tasks', $inactive_tasks); $smarty->assign('title', $i18n->get('title.tasks')); diff --git a/time.php b/time.php index bbd5d14a3..5e0dda153 100644 --- a/time.php +++ b/time.php @@ -74,6 +74,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; @@ -349,7 +350,7 @@ if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (strlen($cl_duration) == 0) { @@ -481,6 +482,7 @@ $smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('show_start', $showStart); $smarty->assign('show_duration', $showDuration); $smarty->assign('show_note_column', $showNoteColumn); diff --git a/time_edit.php b/time_edit.php index 44f04253c..b672c41cb 100644 --- a/time_edit.php +++ b/time_edit.php @@ -58,6 +58,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; @@ -302,7 +303,7 @@ if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (!$cl_duration) { @@ -480,6 +481,7 @@ $smarty->assign('show_paid_status', $showPaidStatus); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('show_start', $showStart); $smarty->assign('show_duration', $showDuration); $smarty->assign('client_list', $client_list); From c2306552c7c718337bb40f22642db073ac44d336 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 25 Jul 2020 20:24:01 +0000 Subject: [PATCH 1246/1848] Refactoring and some fixes for task_required config option. --- WEB-INF/lib/ttGroup.class.php | 4 +--- WEB-INF/lib/ttGroupExportHelper.class.php | 1 - WEB-INF/lib/ttGroupHelper.class.php | 3 +-- WEB-INF/lib/ttOrgImportHelper.class.php | 4 +--- WEB-INF/lib/ttUser.class.php | 7 ++----- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time_script.tpl | 2 +- WEB-INF/templates/week.tpl | 2 +- week.php | 4 +++- 9 files changed, 11 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index 46ce5be56..bd0f944e3 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -44,7 +44,6 @@ class ttGroup { var $week_start = 0; // Week start day. var $tracking_mode = 0; // Tracking mode. var $project_required = 0; // Whether project selection is required on time entires. - var $task_required = 0; // Whether task selection is required on time entires. var $record_type = 0; // Record type (duration vs start and finish, or both). var $punch_mode = 0; // Whether punch mode is enabled for user. var $allow_overlap = 0; // Whether to allow overlapping time entries. @@ -92,8 +91,7 @@ function __construct($id, $org_id) { $this->tracking_mode = $val['tracking_mode']; /* TODO: initialize other things here. $this->project_required = $val['project_required']; - $this->task_required = $val['task_required']; - */ + */ $this->record_type = $val['record_type']; /* $this->bcc_email = $val['bcc_email']; diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index d6415daea..a510da274 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -152,7 +152,6 @@ function writeData() { $group_part .= " week_start=\"".$group['week_start']."\""; $group_part .= " tracking_mode=\"".$group['tracking_mode']."\""; $group_part .= " project_required=\"".$group['project_required']."\""; - $group_part .= " task_required=\"".$group['task_required']."\""; $group_part .= " record_type=\"".$group['record_type']."\""; $group_part .= " bcc_email=\"".$group['bcc_email']."\""; $group_part .= " allow_ip=\"".$group['allow_ip']."\""; diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index af8d55345..895fa1dc6 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -97,7 +97,7 @@ static function insertSubgroup($fields) { $attrs = ttGroupHelper::getGroupAttrs($parent_id); $columns = '(parent_id, org_id, group_key, name, description, currency, decimal_mark, lang, date_format,'. - ' time_format, week_start, tracking_mode, project_required, task_required, record_type, bcc_email,'. + ' time_format, week_start, tracking_mode, project_required, record_type, bcc_email,'. ' allow_ip, password_complexity, plugins, lock_spec,'. ' workday_minutes, config, created, created_ip, created_by)'; @@ -113,7 +113,6 @@ static function insertSubgroup($fields) { $values .= ', '.(int)$attrs['week_start']; $values .= ', '.(int)$attrs['tracking_mode']; $values .= ', '.(int)$attrs['project_required']; - $values .= ', '.(int)$attrs['task_required']; $values .= ', '.(int)$attrs['record_type']; $values .= ', '.$mdb2->quote($attrs['bcc_email']); $values .= ', '.$mdb2->quote($attrs['allow_ip']); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index dbf838281..ac970426f 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -114,7 +114,6 @@ function startElement($parser, $name, $attrs) { 'week_start' => $attrs['WEEK_START'], 'tracking_mode' => $attrs['TRACKING_MODE'], 'project_required' => $attrs['PROJECT_REQUIRED'], - 'task_required' => $attrs['TASK_REQUIRED'], 'record_type' => $attrs['RECORD_TYPE'], 'bcc_email' => $attrs['BCC_EMAIL'], 'allow_ip' => $attrs['ALLOW_IP'], @@ -705,7 +704,7 @@ private function createGroup($fields) { $mdb2 = getConnection(); $columns = '(parent_id, org_id, group_key, name, description, currency, decimal_mark, lang, date_format, time_format,'. - ' week_start, tracking_mode, project_required, task_required, record_type, bcc_email,'. + ' week_start, tracking_mode, project_required, record_type, bcc_email,'. ' allow_ip, password_complexity, plugins, lock_spec,'. ' workday_minutes, config, custom_css, created, created_ip, created_by)'; @@ -723,7 +722,6 @@ private function createGroup($fields) { $values .= ', '.(int)$fields['week_start']; $values .= ', '.(int)$fields['tracking_mode']; $values .= ', '.(int)$fields['project_required']; - $values .= ', '.(int)$fields['task_required']; $values .= ', '.(int)$fields['record_type']; $values .= ', '.$mdb2->quote($fields['bcc_email']); $values .= ', '.$mdb2->quote($fields['allow_ip']); diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 8bf029921..58c51c632 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -60,7 +60,6 @@ class ttUser { var $week_start = 0; // Week start day. var $tracking_mode = 0; // Tracking mode. var $project_required = 0; // Whether project selection is required on time entires. - var $task_required = 0; // Whether task selection is required on time entires. var $record_type = 0; // Record type (duration vs start and finish, or both). var $punch_mode = 0; // Whether punch mode is enabled for user. var $allow_overlap = 0; // Whether to allow overlapping time entries. @@ -96,7 +95,7 @@ function __construct($login, $id = null) { $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id,". " u.quota_percent, u.email, g.org_id, g.group_key, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format,". - " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.task_required, g.record_type,". + " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.record_type,". " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.custom_css, g.holidays, g.workday_minutes, g.custom_logo". " FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; if ($id) @@ -134,7 +133,6 @@ function __construct($login, $id = null) { $this->week_start = $val['week_start']; $this->tracking_mode = $val['tracking_mode']; $this->project_required = $val['project_required']; - $this->task_required = $val['task_required']; $this->record_type = $val['record_type']; $this->bcc_email = $val['bcc_email']; $this->allow_ip = $val['allow_ip']; @@ -707,7 +705,6 @@ function updateGroup($fields) { if (isset($fields['tracking_mode'])) { $tracking_mode_part = ', tracking_mode = '.(int) $fields['tracking_mode']; $project_required_part = ' , project_required = '.(int) $fields['project_required']; - $task_required_part = ' , task_required = '.(int) $fields['task_required']; } if (isset($fields['record_type'])) $record_type_part = ', record_type = '.(int) $fields['record_type']; if (isset($fields['bcc_email'])) $bcc_email_part = ', bcc_email = '.$mdb2->quote($fields['bcc_email']); @@ -721,7 +718,7 @@ function updateGroup($fields) { $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($this->id); $parts = trim($name_part.$description_part.$currency_part.$lang_part.$decimal_mark_part.$date_format_part. - $time_format_part.$week_start_part.$tracking_mode_part.$task_required_part.$project_required_part.$record_type_part. + $time_format_part.$week_start_part.$tracking_mode_part.$project_required_part.$record_type_part. $bcc_email_part.$allow_ip_part.$plugins_part.$config_part.$custom_css_part.$lock_spec_part.$holidays_part.$workday_minutes_part.$modified_part, ','); $sql = "update tt_groups set $parts where id = $group_id and org_id = $this->org_id"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9a2f53491..9668dfc5c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.19.5231 | Copyright © Anuko | + Anuko Time Tracker 1.19.20.5232 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 55d047caa..4d140ed3e 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -7,6 +7,9 @@ {if $i18n.language.rtl} +{/if} +{if $user->getCustomCss()} + {/if} Time Tracker{if $title} - {$title}{/if} diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index 054c75363..6290dd025 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -8,6 +8,9 @@ {if $i18n.language.rtl} +{/if} +{if $user->getCustomCss()} + {/if} Time Tracker{if $title} - {$title}{/if} diff --git a/custom_css.php b/custom_css.php new file mode 100644 index 000000000..979e9a5bd --- /dev/null +++ b/custom_css.php @@ -0,0 +1,34 @@ +getCustomCss(); diff --git a/display_options.php b/display_options.php index 4430af38b..37a584657 100644 --- a/display_options.php +++ b/display_options.php @@ -43,10 +43,12 @@ $cl_time_note_on_separate_row = $request->getParameter('time_note_on_separate_row'); $cl_time_not_complete_days = $request->getParameter('time_not_complete_days'); $cl_report_note_on_separate_row = $request->getParameter('report_note_on_separate_row'); + $cl_custom_css = trim($request->getParameter('custom_css')); } else { $cl_time_note_on_separate_row = $config->getDefinedValue('time_note_on_separate_row'); $cl_time_not_complete_days = $config->getDefinedValue('time_not_complete_days'); $cl_report_note_on_separate_row = $config->getDefinedValue('report_note_on_separate_row'); + $cl_custom_css = $user->getCustomCss(); } $form = new Form('displayOptionsForm'); @@ -76,7 +78,9 @@ $config->setDefinedValue('time_note_on_separate_row', $cl_time_note_on_separate_row); $config->setDefinedValue('time_not_complete_days', $cl_time_not_complete_days); $config->setDefinedValue('report_note_on_separate_row', $cl_report_note_on_separate_row); - if ($user->updateGroup(array('config' => $config->getConfig()))) { + if ($user->updateGroup(array( + 'config' => $config->getConfig(), + 'custom_css' => $cl_custom_css))) { header('Location: success.php'); exit(); } else From 1b2c65d92bb6a1afff12080cd9713ffa90e331a2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 15 Jul 2020 15:12:13 +0000 Subject: [PATCH 1215/1848] Added a user input validator for custom css. --- WEB-INF/lib/common.lib.php | 19 +++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- display_options.php | 4 ++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 1f2829442..e01deeaa5 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -177,6 +177,25 @@ function ttValidString($val, $emptyValid = false) return true; } +// ttValidCss is used to check user input for custom css. +function ttValidCss($val) +{ + $val = trim($val); + if (strlen($val) == 0) + return true; + + // String must not contain any tags. + if (stristr($val, '<')) + return false; + + // Security note: the above may not be enough. + // Currently it is unclear how vulnerable we are assuming custom css is available only to a logged on user + // (one custom css per group). + // However, if abuse occurs or when the issue is better understood, we may have to rewrite this function, + // perhaps by specifying what exactly we allow to style. + return true; +} + // ttValidTemplateText is used to check template-based user input. // When templates are used, required input parts must be filled by user. // We identify these parts by 3 "stop sign" emojis (aka "octagonal sign" U+1F6D1). diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 50ff6f264..d10afc302 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
Anuko Time Tracker 1.19.20.5232 | Copyright © Anuko | + Anuko Time Tracker 1.19.20.5233 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/display_options.php b/display_options.php index 37a584657..a4d3deacb 100644 --- a/display_options.php +++ b/display_options.php @@ -73,6 +73,10 @@ $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()){ + // Validate user input. + if (!ttValidCss($cl_custom_css)) $err->add($i18n->get('error.field'), $i18n->get('form.display_options.custom_css')); + // Finished validating user input. + if ($err->no()) { // Update config. $config->setDefinedValue('time_note_on_separate_row', $cl_time_note_on_separate_row); From ddf4f8e805d3ae7c551ea86a55392af1db92b7d3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 15 Jul 2020 16:06:22 +0000 Subject: [PATCH 1216/1848] Fixed future entries behaviour for subgroups. --- WEB-INF/lib/ttGroup.class.php | 4 +--- WEB-INF/lib/ttUser.class.php | 2 -- WEB-INF/lib/ttWeekViewHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- expenses.php | 2 +- mobile/expense_edit.php | 2 +- mobile/expenses.php | 2 +- mobile/time.php | 2 +- mobile/time_edit.php | 2 +- mobile/timer.php | 2 +- time.php | 2 +- time_edit.php | 2 +- 12 files changed, 11 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index 5e1885af9..46ce5be56 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -34,7 +34,7 @@ class ttGroup { var $id = null; // Group id. var $group_key = null; // Group key. - var $parent_id = null; // Paerent group id. + var $parent_id = null; // Parent group id. var $org_id = null; // Organization id. var $name = null; // Group name. var $lang = null; // Language. @@ -48,7 +48,6 @@ class ttGroup { var $record_type = 0; // Record type (duration vs start and finish, or both). var $punch_mode = 0; // Whether punch mode is enabled for user. var $allow_overlap = 0; // Whether to allow overlapping time entries. - var $future_entries = 0; // Whether to allow creating future entries. var $bcc_email = null; // Bcc email. var $allow_ip = null; // Specification from where user is allowed access. var $password_complexity = null; // Password complexity example. @@ -117,7 +116,6 @@ function __construct($id, $org_id) { // Set user config options. $this->punch_mode = $this->configHelper->getDefinedValue('punch_mode'); $this->allow_overlap = $this->configHelper->getDefinedValue('allow_overlap'); - $this->future_entries = $this->configHelper->getDefinedValue('future_entries'); } // Determine active user count in a separate query. diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index a62fc5809..8bf029921 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -64,7 +64,6 @@ class ttUser { var $record_type = 0; // Record type (duration vs start and finish, or both). var $punch_mode = 0; // Whether punch mode is enabled for user. var $allow_overlap = 0; // Whether to allow overlapping time entries. - var $future_entries = 0; // Whether to allow creating future entries. var $bcc_email = null; // Bcc email. var $allow_ip = null; // Specification from where user is allowed access. var $password_complexity = null; // Password complexity example. @@ -155,7 +154,6 @@ function __construct($login, $id = null) { // Set user config options. $this->punch_mode = $this->configHelper->getDefinedValue('punch_mode'); $this->allow_overlap = $this->configHelper->getDefinedValue('allow_overlap'); - $this->future_entries = $this->configHelper->getDefinedValue('future_entries'); $this->custom_css = $val['custom_css']; diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index 05ec4e9d0..aee8c8d61 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -537,7 +537,7 @@ static function insertDurationFromWeekView($fields, $custom_fields, $err) { $objEntryDate = new DateAndTime(DB_DATEFORMAT, $entry_date); // Prohibit creating entries in future. - if (!$user->future_entries && $fields['browser_today']) { + if (!$user->isOptionEnabled('future_entries') && $fields['browser_today']) { $objBrowserToday = new DateAndTime(DB_DATEFORMAT, $fields['browser_today']); if ($objEntryDate->after($objBrowserToday)) { $err->add($i18n->get('error.future_date')); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d10afc302..687331f88 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + diff --git a/WEB-INF/templates/mobile/time.tpl b/WEB-INF/templates/mobile/time.tpl index 07e50fb39..a346ad6c6 100644 --- a/WEB-INF/templates/mobile/time.tpl +++ b/WEB-INF/templates/mobile/time.tpl @@ -73,7 +73,7 @@ {/if} {if $show_task} - + {/if} {if $show_start} diff --git a/WEB-INF/templates/mobile/time_edit.tpl b/WEB-INF/templates/mobile/time_edit.tpl index 5fd10ad15..3025a63f7 100644 --- a/WEB-INF/templates/mobile/time_edit.tpl +++ b/WEB-INF/templates/mobile/time_edit.tpl @@ -44,7 +44,7 @@ function confirmSave() { {/if} {if $show_task} - + {/if} {if $show_start} diff --git a/WEB-INF/templates/tasks.tpl b/WEB-INF/templates/tasks.tpl index 24fd04380..c5afab227 100644 --- a/WEB-INF/templates/tasks.tpl +++ b/WEB-INF/templates/tasks.tpl @@ -2,6 +2,7 @@ function chLocation(newLocation) { document.location = newLocation; } +{$forms.tasksForm.open}
Anuko Time Tracker 1.19.20.5233 | Copyright © Anuko | + Anuko Time Tracker 1.19.20.5234 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expenses.php b/expenses.php index 2b7a15bc4..7959bb311 100644 --- a/expenses.php +++ b/expenses.php @@ -202,7 +202,7 @@ if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); // Prohibit creating entries in future. - if (!$user->getConfigOption('future_entries')) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index 654d1698d..67813a6f1 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -167,7 +167,7 @@ $new_date = new DateAndTime($user->getDateFormat(), $cl_date); // Prohibit creating entries in future. - if (!$user->getConfigOption('future_entries')) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/mobile/expenses.php b/mobile/expenses.php index 3b229368e..05d469985 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -203,7 +203,7 @@ if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); // Prohibit creating entries in future. - if (!$user->getConfigOption('future_entries')) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/mobile/time.php b/mobile/time.php index 233f1d16f..1e5276cdf 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -340,7 +340,7 @@ // Finished validating user input. // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 6fefebd86..7e50731b6 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -305,7 +305,7 @@ $new_date = new DateAndTime($user->date_format, $cl_date); // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/mobile/timer.php b/mobile/timer.php index c7c1c2d40..0b513c235 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -218,7 +218,7 @@ // Finished validating user input. // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/time.php b/time.php index 9f85d5981..6664243a6 100644 --- a/time.php +++ b/time.php @@ -383,7 +383,7 @@ // Finished validating user input. // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/time_edit.php b/time_edit.php index 83989404f..918ecea52 100644 --- a/time_edit.php +++ b/time_edit.php @@ -310,7 +310,7 @@ $new_date = new DateAndTime($user->date_format, $cl_date); // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); From bacffb8ff036d508d8004f6b169adda11696627a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 15 Jul 2020 16:09:40 +0000 Subject: [PATCH 1217/1848] Forgot to check in one file. --- expense_edit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expense_edit.php b/expense_edit.php index 3cebac129..f736f2132 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -172,7 +172,7 @@ $new_date = new DateAndTime($user->getDateFormat(), $cl_date); // Prohibit creating entries in future. - if (!$user->getConfigOption('future_entries')) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); From b6a3fe7a3cf32bcfa0c20d57cf855cbbe670893f Mon Sep 17 00:00:00 2001 From: WizardStan Date: Thu, 16 Jul 2020 09:27:49 -0400 Subject: [PATCH 1218/1848] Replace cal_days_in_month with generic date call (#99) --- plugins/MonthlyQuota.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/MonthlyQuota.class.php b/plugins/MonthlyQuota.class.php index c8559ad46..0a8ee4e9b 100644 --- a/plugins/MonthlyQuota.class.php +++ b/plugins/MonthlyQuota.class.php @@ -133,7 +133,7 @@ private function getMany($year){ // getNumWorkdays returns a number of work days in a given month. private function getNumWorkdays($month, $year) { - $daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year); // Number of calendar days in month. + $daysInMonth = date('t', mktime(0, 0, 0, $month, 1, $year)); $workdaysInMonth = 0; // Iterate through the entire month. From 671b1a087c997ada7a9435a1ea8eb19e447e0f59 Mon Sep 17 00:00:00 2001 From: WizardStan Date: Thu, 16 Jul 2020 09:51:00 -0400 Subject: [PATCH 1219/1848] Create notifications that trigger based on hours (#98) --- WEB-INF/lib/common.lib.php | 3 ++- WEB-INF/lib/ttReportHelper.class.php | 30 +++++++++++++++++++--------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index e01deeaa5..725f343c0 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -343,7 +343,8 @@ function ttValidCondition($val, $emptyValid = true) if (stristr($val, ' {$forms.groupForm.open} @@ -74,7 +60,7 @@ function handleTaskRequiredCheckbox() {
{$i18n.form.group_edit.tracking_mode}:{$forms.groupForm.tracking_mode.control} {$forms.groupForm.task_required.control} {$forms.groupForm.tracking_mode.control}
{$i18n.form.group_edit.record_type}:
{$forms.timeRecordForm.project.control}
{$i18n.label.task}:
{$i18n.label.task}{if $task_required} (*){/if}:
{$forms.timeRecordForm.task.control}
{$forms.timeRecordForm.project.control}
{$i18n.label.task}:
{$i18n.label.task}{if $task_required} (*){/if}:
{$forms.timeRecordForm.task.control}
@@ -78,7 +79,20 @@ {/foreach} {/if}
- {/if} +{/if} +
+ + + + + + + + +
{$forms.tasksForm.task_required.control} {$i18n.label.what_is_it}
{$forms.tasksForm.btn_save.control}
+ +
+{$forms.tasksForm.close} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index 0cbf0caca..377b26c01 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -53,7 +53,7 @@ {/if} {if $show_task}
{$i18n.label.task}{if $user->task_required} (*){/if}:{$i18n.label.task}{if $task_required} (*){/if}: {$forms.timeRecordForm.task.control}
{$i18n.label.task}{if $user->task_required} (*){/if}:{$i18n.label.task}{if $task_required} (*){/if}: {$forms.timeRecordForm.task.control}
- - + {/if} diff --git a/week.php b/week.php index a1a579094..d86e0c99c 100644 --- a/week.php +++ b/week.php @@ -79,6 +79,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $user->getConfigOption('task_required'); $showWeekNote = $user->isOptionEnabled('week_note'); $showWeekNotes = $user->isOptionEnabled('week_notes'); $recordType = $user->getRecordType(); @@ -416,7 +417,7 @@ function render(&$table, $value, $row, $column, $selected = false) { if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } } @@ -567,6 +568,7 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('show_week_note', $showWeekNote); $smarty->assign('show_week_list', $user->isOptionEnabled('week_list')); $smarty->assign('show_start', $showStart); From bfef42dbca33313493b40dfdd265ee55f47ab29e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 25 Jul 2020 20:34:38 +0000 Subject: [PATCH 1247/1848] Fixed mobile timer.php for subgroups regarding task_required. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/timer.tpl | 2 +- mobile/timer.php | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9668dfc5c..0109338fa 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.22.5256 | Copyright © Anuko | + Anuko Time Tracker 1.19.22.5257 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 65a691abe..977db3d6c 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -178,7 +178,7 @@ function fillTaskDropdown(id) { } // Select a task if user is required to do so and there is only one task available. - if ({$user->task_required} && dropdown.options.length == 2) { // 2 because of mandatory top option. + if ({$user->getConfigOption('task_required')} && dropdown.options.length == 2) { // 2 because of mandatory top option. dropdown.options[1].selected = true; } } diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl index 2ee2e68a5..5ac3be85e 100644 --- a/WEB-INF/templates/week.tpl +++ b/WEB-INF/templates/week.tpl @@ -68,7 +68,7 @@ function fillDropdowns() { {/if} {if $show_task}
{$i18n.label.task}:{$i18n.label.task}{if $task_required} (*){/if}: {$forms.weekTimeForm.task.control}
- {/if} {if $show_task} - + {/if}
Anuko Time Tracker 1.19.22.5257 | Copyright © Anuko | + Anuko Time Tracker 1.19.22.5258 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/timer.tpl b/WEB-INF/templates/mobile/timer.tpl index 65f267d40..1fee04af3 100644 --- a/WEB-INF/templates/mobile/timer.tpl +++ b/WEB-INF/templates/mobile/timer.tpl @@ -84,7 +84,7 @@ startTimer();
{$forms.timeRecordForm.project.control}
{$i18n.label.task}:
{$i18n.label.task}{if $task_required} (*){/if}:
{$forms.timeRecordForm.task.control}
diff --git a/mobile/timer.php b/mobile/timer.php index ac43dc86d..e301716a4 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -46,6 +46,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $user->getConfigOption('task_required'); // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -229,7 +230,7 @@ if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } // Finished validating user input. @@ -318,6 +319,7 @@ $smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); $smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('client_list', $client_list); From 889ae54eaa95a4a69e0a4da875e2a250ca18a713 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 25 Jul 2020 20:43:05 +0000 Subject: [PATCH 1248/1848] Dropped task_required field from tt_groups table as it is now a part of config field. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 +-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0109338fa..80cb8a906 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
Anuko Time Tracker 1.19.22.5258 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5259 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index b6f831479..59d3923f8 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1161,7 +1161,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11922"]) { + if ($_POST["convert11900to11923"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1192,6 +1192,8 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.19', modified = now() where param_name = 'version_db' and param_value = '1.19.17'"); ttExecute("ALTER TABLE `tt_cron` ADD `comment` text AFTER `subject`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.22', modified = now() where param_name = 'version_db' and param_value = '1.19.19'"); + ttExecute("ALTER TABLE `tt_groups` drop `task_required`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.23', modified = now() where param_name = 'version_db' and param_value = '1.19.22'"); } if ($_POST["cleanup"]) { @@ -1242,7 +1244,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.19.22) + Create database structure (v1.19.23)
(applies only to new installations, do not execute when updating)
@@ -1291,8 +1293,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.22)Update database structure (v1.19 to v1.19.23)
diff --git a/mysql.sql b/mysql.sql index 1e37a59df..e9f4cc031 100644 --- a/mysql.sql +++ b/mysql.sql @@ -27,7 +27,6 @@ CREATE TABLE `tt_groups` ( `week_start` smallint(2) NOT NULL default 0, # Week start day, 0 == Sunday. `tracking_mode` smallint(2) NOT NULL default 1, # tracking mode ("time", "projects" or "projects and tasks") `project_required` smallint(2) NOT NULL default 0, # whether a project selection is required or optional - `task_required` smallint(2) NOT NULL default 0, # whether a task selection is required or optional `record_type` smallint(2) NOT NULL default 0, # time record type ("start and finish", "duration", or both) `bcc_email` varchar(100) default NULL, # bcc email to copy all reports to `allow_ip` varchar(255) default NULL, # specification from where users are allowed access @@ -657,4 +656,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.22', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.23', now()); # TODO: change when structure changes. From cdbd32b362368570f0627288bf5f83739a055d60 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 26 Jul 2020 11:56:46 +0000 Subject: [PATCH 1249/1848] Fixed behavior of Now buttons, broken in one of recent commits. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time_script.tpl | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 80cb8a906..f752264da 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + {else} - + {/if} {/if} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index a5e893e59..237eb98be 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -40,13 +40,13 @@ {/if} {if $show_files} {if $timesheet.has_files} - + {else} - + {/if} {/if} - - + + {/foreach}
Anuko Time Tracker 1.19.23.5259 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5260 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 977db3d6c..3d2013832 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -177,10 +177,12 @@ function fillTaskDropdown(id) { } } +{if $user->getConfigOption('task_required')} // Select a task if user is required to do so and there is only one task available. - if ({$user->getConfigOption('task_required')} && dropdown.options.length == 2) { // 2 because of mandatory top option. + if (dropdown.options.length == 2) { // 2 because of mandatory top option. dropdown.options[1].selected = true; } +{/if} } } From 9304cf358161f2dd63b0b570d57e3d84343ca81b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 26 Jul 2020 13:24:37 +0000 Subject: [PATCH 1250/1848] Cosmetic. Updated a link to user guide. --- WEB-INF/config.php.dist | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index a288ec0bf..24dd5a266 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -86,7 +86,7 @@ define('WEEKEND_START_DAY', 6); // Forum and help links from the main menu. // define('FORUM_LINK', 'https://www.anuko.com/forum/viewforum.php?f=4'); -define('HELP_LINK', 'https://www.anuko.com/time_tracker/user_guide/index.htm'); +define('HELP_LINK', 'https://www.anuko.com/time-tracker/user-guide/index.htm'); // Default sender for mail. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f752264da..b7e572713 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + + {/foreach}
Anuko Time Tracker 1.19.23.5260 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5261 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9c45529c062bf66c7def4dc4d8624a7cefda0061 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 28 Jul 2020 14:45:30 +0000 Subject: [PATCH 1251/1848] Moved the Required checkbox on top of tasks.php page to make it more visible. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/tasks.tpl | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b7e572713..50b48e893 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
Anuko Time Tracker 1.19.23.5261 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5262 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/tasks.tpl b/WEB-INF/templates/tasks.tpl index c5afab227..df502c7ae 100644 --- a/WEB-INF/templates/tasks.tpl +++ b/WEB-INF/templates/tasks.tpl @@ -7,6 +7,16 @@
{if $user->can('manage_tasks')} + + + + + + + + +
{$forms.tasksForm.task_required.control} {$i18n.label.what_is_it}
{$forms.tasksForm.btn_save.control}
+
{if $inactive_tasks} @@ -80,18 +90,6 @@ {/if}
{$i18n.form.tasks.active_tasks}
{/if} -
- - - - - - - - -
{$forms.tasksForm.task_required.control} {$i18n.label.what_is_it}
{$forms.tasksForm.btn_save.control}
- -
From b243785a17e90bb671058b092f390decbf20c149 Mon Sep 17 00:00:00 2001 From: kanfil Date: Thu, 30 Jul 2020 21:32:04 +0300 Subject: [PATCH 1252/1848] Save custom field values in session (#102) --- time.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/time.php b/time.php index 5e0dda153..a76b470d5 100644 --- a/time.php +++ b/time.php @@ -155,19 +155,21 @@ $timeCustomFields = array(); // If we have time custom fields - collect input. -if ($request->isPost()) { +#if ($request->isPost()) { if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $control_name = 'time_field_'.$timeField['id']; + $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); + $_SESSION[$control_name] = $cl_control_name; $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], 'control_name' => $control_name, 'label' => $timeField['label'], 'type' => $timeField['type'], 'required' => $timeField['required'], - 'value' => trim($request->getParameter($control_name))); + 'value' => trim($cl_control_name)); } } -} +#} // Elements of timeRecordForm. $form = new Form('timeRecordForm'); From ee4536e9f776191a95e1abd86ef873572a642961 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 30 Jul 2020 18:40:01 +0000 Subject: [PATCH 1253/1848] Added time custom fields storage in session to mobile time.php as in pr #102. --- WEB-INF/templates/footer.tpl | 2 +- mobile/time.php | 24 ++++++++++++------------ time.php | 28 +++++++++++++--------------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 50b48e893..1aa8e7ba2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {else} - + {/if}
Anuko Time Tracker 1.19.23.5262 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5263 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/time.php b/mobile/time.php index 58661632a..1cda7fb63 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -119,19 +119,19 @@ $cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; +// Handle time custom fields. $timeCustomFields = array(); -// If we have time custom fields - collect input. -if ($request->isPost()) { - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($request->getParameter($control_name))); - } +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); + $_SESSION[$control_name] = $cl_control_name; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($cl_control_name)); } } diff --git a/time.php b/time.php index a76b470d5..e375e8425 100644 --- a/time.php +++ b/time.php @@ -153,23 +153,21 @@ $cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; +// Handle time custom fields. $timeCustomFields = array(); -// If we have time custom fields - collect input. -#if ($request->isPost()) { - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); - $_SESSION[$control_name] = $cl_control_name; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($cl_control_name)); - } +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); + $_SESSION[$control_name] = $cl_control_name; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($cl_control_name)); } -#} +} // Elements of timeRecordForm. $form = new Form('timeRecordForm'); From 070846bb07629367d044a3affbea6f8135040c3f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 31 Jul 2020 15:00:29 +0000 Subject: [PATCH 1254/1848] Started to use relative values in css for better presentation. --- WEB-INF/templates/footer.tpl | 2 +- default.css | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1aa8e7ba2..9027eee8e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {else} - + {/if}
Anuko Time Tracker 1.19.23.5263 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5264 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/default.css b/default.css index 3eac29ec2..3b4921acf 100644 --- a/default.css +++ b/default.css @@ -63,17 +63,17 @@ input[type=checkbox], label { } .systemMenu { - font-size: 11pt; + font-size: 1rem; font-weight: bold; color: white; background-color: black; - margin: 2px 4px 2px 4px; + margin: .1rem .2rem .1rem .2rem; } .mainMenu { - font-size: 11pt; + font-size: 1rem; color: #444444; - margin: 2px 4px 2px 4px; + margin: .1rem .2rem .1rem .2rem; } .onBehalf { From 7f3061d5269131fea433dd6465565c93c9dcbb70 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 31 Jul 2020 15:47:40 +0000 Subject: [PATCH 1255/1848] Renamed tt_logo.png to just logo.png. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- WEB-INF/templates/mobile/header.tpl | 2 +- WEB-INF/templates/work/header.tpl | 2 +- images/{tt_logo.png => logo.png} | Bin 5 files changed, 4 insertions(+), 4 deletions(-) rename images/{tt_logo.png => logo.png} (100%) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9027eee8e..36d26a192 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {else} - + {/if}
Anuko Time Tracker 1.19.23.5264 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5265 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 4d140ed3e..4e89a8a20 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -45,7 +45,7 @@ {if $user->custom_logo} Time TrackerAnuko Time TrackerAnuko Time Tracker
diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index 6290dd025..e6d661d3a 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -46,7 +46,7 @@ {if $user->custom_logo}
Time TrackerAnuko Time TrackerAnuko Time Tracker
diff --git a/WEB-INF/templates/work/header.tpl b/WEB-INF/templates/work/header.tpl index 084870958..03f986885 100644 --- a/WEB-INF/templates/work/header.tpl +++ b/WEB-INF/templates/work/header.tpl @@ -41,7 +41,7 @@ {if $user->custom_logo}
Time TrackerAnuko Time TrackerAnuko Time Tracker
diff --git a/images/tt_logo.png b/images/logo.png similarity index 100% rename from images/tt_logo.png rename to images/logo.png From f534234e691f5b53ce6dccd3412c42d32f572c9a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 31 Jul 2020 16:33:39 +0000 Subject: [PATCH 1256/1848] Fixed language for for the login screen. --- WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 58c51c632..331633e11 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -53,7 +53,7 @@ class ttUser { var $group_name = null; // Group name. var $behalf_group_name = null;// Group name, on behalf of which we are working. var $email = null; // User email. - var $lang = 'en'; // Language. + var $lang = null; // Language. var $decimal_mark = '.'; // Decimal separator. var $date_format = null; // Date format. var $time_format = null; // Time format. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 36d26a192..e1a6031d3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {if $can_edit} - - + + {/if} {/foreach} diff --git a/WEB-INF/templates/expenses.tpl b/WEB-INF/templates/expenses.tpl index c064b13de..1e9476c3d 100644 --- a/WEB-INF/templates/expenses.tpl +++ b/WEB-INF/templates/expenses.tpl @@ -207,23 +207,23 @@ function recalculateCost() { {if $show_files} {if $item.has_files} - + {else} - + {/if} {/if} diff --git a/WEB-INF/templates/groups.tpl b/WEB-INF/templates/groups.tpl index 0289ef9ee..7b2a24017 100644 --- a/WEB-INF/templates/groups.tpl +++ b/WEB-INF/templates/groups.tpl @@ -22,8 +22,8 @@ - - + + {/foreach}
Anuko Time Tracker 1.19.23.5265 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5266 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 10c01f419f509827c240e46f80e495269c30a6da Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Aug 2020 13:19:49 +0000 Subject: [PATCH 1257/1848] Fixed broken PDF reposrts after renaming logo image. --- WEB-INF/templates/footer.tpl | 2 +- group_edit.php | 2 +- topdf.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e1a6031d3..dcf355e63 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + + {/foreach}
Anuko Time Tracker 1.19.23.5266 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5267 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_edit.php b/group_edit.php index 2196d280b..c8ad2e142 100644 --- a/group_edit.php +++ b/group_edit.php @@ -92,7 +92,7 @@ $cl_uncompleted_indicators = $request->getParameter('uncompleted_indicators'); $cl_confirm_save = $request->getParameter('confirm_save'); } else { - $cl_currency = ($group['currency'] == ''? CURRENCY_DEFAULT : $group['currency']); + $cl_currency = ($group['currency'] == '' ? CURRENCY_DEFAULT : $group['currency']); $cl_lang = $group['lang']; $cl_decimal_mark = $group['decimal_mark']; $cl_date_format = $group['date_format']; diff --git a/topdf.php b/topdf.php index 337a05a41..42c31e07f 100644 --- a/topdf.php +++ b/topdf.php @@ -460,7 +460,7 @@ // Extend TCPDF class so that we can use custom header and footer. class ttPDF extends TCPDF { - public $image_file = 'images/tt_logo.png'; // Image file for the logo in header. + public $image_file = 'images/logo.png'; // Image file for the logo in header. public $page_word = 'Page'; // Localized "Page" word in footer, ex: Page 1/2. // SetImageFile - sets image file name. From e650913e25f14120ac4510a740f4bbc3c19f0e98 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 Aug 2020 15:44:40 +0000 Subject: [PATCH 1258/1848] Added a link explaining tracking mode. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index dcf355e63..53f5fb82a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + From 3094adc7be3492465d3b7336bdee3df4e0850ea9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 Aug 2020 16:15:17 +0000 Subject: [PATCH 1259/1848] Changed APP_NAME named constant to DIR_NAME to better reflect its meaning. --- WEB-INF/config.php.dist | 14 +++++++------- WEB-INF/lib/form/DateField.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- password_reset.php | 4 ++-- readme.txt | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 24dd5a266..9583d59b3 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -50,13 +50,13 @@ define('DSN', 'mysqli://root:no@localhost/dbname?charset=utf8mb4'); define('MULTIORG_MODE', true); -// Application name. -// If you install time tracker into a sub-directory of your site reflect this in the APP_NAME parameter. -// For example, for http://localhost/timetracker/ define APP_NAME as 'timetracker'. +// Directory name. +// If you install time tracker into a sub-directory of your site reflect this in the DIR_NAME parameter. +// For example, for http://localhost/timetracker/ define DIR_NAME as 'timetracker'. // -// define('APP_NAME', 'timetracker'); +// define('DIR_NAME', 'timetracker'); // -define('APP_NAME', ''); +define('DIR_NAME', ''); // WEEKEND_START_DAY @@ -151,7 +151,7 @@ define('AUTH_MODULE', 'db'); // 'type' => 'openldap', // Type of server. openldap type should also work with Sun Directory Server when member_of is empty. // It may work with other (non Windows AD) LDAP servers. For Windows AD use the 'ad' type. // 'base_dn' => 'ou=People,dc=example,dc=com', // Path of user's base distinguished name in LDAP catalog. -// 'user_login_attribute' => 'uid', // LDAP attribute used for login +// 'user_login_attribute' => 'uid', // LDAP attribute used for login. // 'default_domain' => 'example.com', // Default domain. // 'member_of' => array()); // List of groups, membership in which is required for user to be authenticated. @@ -172,7 +172,7 @@ define('AUTH_MODULE', 'db'); // define('DEBUG', false); // Note: enabling DEBUG breaks redirects as debug output is printed before setting redirect header. Do not enable on production systems. -// Team managers can set monthly work hour quota for years between the following values. +// Group managers can set monthly work hour quota for years between the following values. // define('MONTHLY_QUOTA_YEAR_START', 2010); // If nothing is specified, it falls back to 2015. // define('MONTHLY_QUOTA_YEAR_END', 2025); // If nothing is specified, it falls back to 2030. diff --git a/WEB-INF/lib/form/DateField.class.php b/WEB-INF/lib/form/DateField.class.php index a197126fb..73c68220a 100644 --- a/WEB-INF/lib/form/DateField.class.php +++ b/WEB-INF/lib/form/DateField.class.php @@ -406,8 +406,8 @@ function adjustiFrame(pickerDiv, iFrameDiv) { $html .= " value=\"".htmlspecialchars($this->getValue())."\""; $html .= ">"; - if (APP_NAME) - $app_root = '/'.APP_NAME; + if (DIR_NAME) + $app_root = '/'.DIR_NAME; $html .= " name."');\">\n"; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 53f5fb82a..5a7521eeb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.23.5267 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5268 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index c55663ceb..e9b6deb56 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -60,7 +60,7 @@ function chLocation(newLocation) { document.location = newLocation; }
{$i18n.form.group_edit.tracking_mode}:{$forms.groupForm.tracking_mode.control}{$forms.groupForm.tracking_mode.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.record_type}:
- - - + + {/foreach} {/if} diff --git a/WEB-INF/templates/cf_custom_fields.tpl b/WEB-INF/templates/cf_custom_fields.tpl index e64f18157..e056c606b 100644 --- a/WEB-INF/templates/cf_custom_fields.tpl +++ b/WEB-INF/templates/cf_custom_fields.tpl @@ -30,8 +30,8 @@ {/if} - - + + {/foreach} {/if} diff --git a/WEB-INF/templates/cf_dropdown_options.tpl b/WEB-INF/templates/cf_dropdown_options.tpl index b920d733e..d694a1ebc 100644 --- a/WEB-INF/templates/cf_dropdown_options.tpl +++ b/WEB-INF/templates/cf_dropdown_options.tpl @@ -16,8 +16,8 @@ {foreach $options as $key=>$val} - - + + {/foreach} {/if} diff --git a/WEB-INF/templates/clients.tpl b/WEB-INF/templates/clients.tpl index ca93b92f5..cba3256c3 100644 --- a/WEB-INF/templates/clients.tpl +++ b/WEB-INF/templates/clients.tpl @@ -20,8 +20,8 @@ - - + + {/foreach}
Anuko Time Tracker 1.19.23.5268 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5269 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/password_reset.php b/password_reset.php index 4d4e24867..bbb54adb5 100644 --- a/password_reset.php +++ b/password_reset.php @@ -100,8 +100,8 @@ $http = 'http'; $cl_subject = $user_i18n->get('form.reset_password.email_subject'); - if (APP_NAME) - $pass_edit_url = $http.'://'.$_SERVER['HTTP_HOST'].'/'.APP_NAME.'/password_change.php?ref='.$temp_ref; + if (DIR_NAME) + $pass_edit_url = $http.'://'.$_SERVER['HTTP_HOST'].'/'.DIR_NAME.'/password_change.php?ref='.$temp_ref; else $pass_edit_url = $http.'://'.$_SERVER['HTTP_HOST'].'/password_change.php?ref='.$temp_ref; diff --git a/readme.txt b/readme.txt index c8929fae4..421a18cdb 100644 --- a/readme.txt +++ b/readme.txt @@ -29,7 +29,7 @@ The general installation procedure looks like this: 5) Create a config file by coping WEB-INF/config.php.dist to WEB-INF/config.php. 6) Change $dsn value in /WEB-INF/config.php file to reflect your database connection parameters (user name and password). 7) If you are upgrading from earlier Time Tracker version run dbinstall.php from your browser and do only the required "Update database structure" steps. -8) If you install time tracker into a sub-directory of your site reflect this in the APP_NAME parameter in /WEB-INF/config.php file. For example, for http://localhost/timetracker/ set APP_NAME = "timetracker". +8) If you install time tracker into a sub-directory of your site reflect this in the DIR_NAME parameter in /WEB-INF/config.php file. For example, for http://localhost/timetracker/ set DIR_NAME = "timetracker". 9) Login to your time tracker site as admin with password "secret" without quotes and create at least one group. 10) Change admin password (on the admin "options" page). You can also use the following SQL console command: update tt_users set password = md5('new_password_here') where login='admin' From 469a150062dc321309af92cfb50f249a8d931d94 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 Aug 2020 17:46:26 +0000 Subject: [PATCH 1260/1848] Shortened images directory name to img to keep things a bit shorter. --- WEB-INF/lib/form/DateField.class.php | 2 +- WEB-INF/templates/admin_groups.tpl | 4 ++-- WEB-INF/templates/cf_custom_fields.tpl | 4 ++-- WEB-INF/templates/cf_dropdown_options.tpl | 4 ++-- WEB-INF/templates/clients.tpl | 8 ++++---- WEB-INF/templates/entity_files.tpl | 4 ++-- WEB-INF/templates/expenses.tpl | 8 ++++---- WEB-INF/templates/groups.tpl | 4 ++-- WEB-INF/templates/header.tpl | 10 +++++----- WEB-INF/templates/invoices.tpl | 2 +- WEB-INF/templates/mobile/header.tpl | 10 +++++----- WEB-INF/templates/mobile/time.tpl | 4 ++-- WEB-INF/templates/notifications.tpl | 4 ++-- WEB-INF/templates/predefined_expenses.tpl | 4 ++-- WEB-INF/templates/projects.tpl | 18 +++++++++--------- WEB-INF/templates/report.tpl | 4 ++-- WEB-INF/templates/roles.tpl | 8 ++++---- WEB-INF/templates/tasks.tpl | 8 ++++---- WEB-INF/templates/templates.tpl | 8 ++++---- WEB-INF/templates/time.tpl | 8 ++++---- WEB-INF/templates/timesheets.tpl | 16 ++++++++-------- WEB-INF/templates/users.tpl | 8 ++++---- WEB-INF/templates/week.tpl | 8 ++++---- WEB-INF/templates/work/admin_work.tpl | 8 ++++---- WEB-INF/templates/work/header.tpl | 10 +++++----- WEB-INF/templates/work/work.tpl | 8 ++++---- {images => img}/1x1.gif | Bin {images => img}/calendar.gif | Bin {images => img}/icon_delete.png | Bin {images => img}/icon_edit.png | Bin {images => img}/icon_file.png | Bin {images => img}/icon_files.png | Bin {images => img}/logo.png | Bin {images => img}/subm_bg.gif | Bin {images => img}/top_bg.gif | Bin initialize.php | 4 ++-- password_change.php | 4 ++-- topdf.php | 6 +++--- 38 files changed, 99 insertions(+), 99 deletions(-) rename {images => img}/1x1.gif (100%) rename {images => img}/calendar.gif (100%) rename {images => img}/icon_delete.png (100%) rename {images => img}/icon_edit.png (100%) rename {images => img}/icon_file.png (100%) rename {images => img}/icon_files.png (100%) rename {images => img}/logo.png (100%) rename {images => img}/subm_bg.gif (100%) rename {images => img}/top_bg.gif (100%) diff --git a/WEB-INF/lib/form/DateField.class.php b/WEB-INF/lib/form/DateField.class.php index 73c68220a..18a3ec475 100644 --- a/WEB-INF/lib/form/DateField.class.php +++ b/WEB-INF/lib/form/DateField.class.php @@ -409,7 +409,7 @@ function adjustiFrame(pickerDiv, iFrameDiv) { if (DIR_NAME) $app_root = '/'.DIR_NAME; - $html .= " name."');\">\n"; + $html .= " name."');\">\n"; } return $html; diff --git a/WEB-INF/templates/admin_groups.tpl b/WEB-INF/templates/admin_groups.tpl index 218fe77cd..9f2ecb6f4 100644 --- a/WEB-INF/templates/admin_groups.tpl +++ b/WEB-INF/templates/admin_groups.tpl @@ -22,8 +22,8 @@ {$group.name|escape} {$group.date} {$group.lang}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
{$i18n.label.type_dropdown} {$i18n.label.configure}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
{$val|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
{$client.name|escape} {$client.address|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
@@ -43,8 +43,8 @@
{$client.name|escape} {$client.address|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
diff --git a/WEB-INF/templates/entity_files.tpl b/WEB-INF/templates/entity_files.tpl index fc552b24b..fe5dc5445 100644 --- a/WEB-INF/templates/entity_files.tpl +++ b/WEB-INF/templates/entity_files.tpl @@ -16,8 +16,8 @@
{$file.name|escape} {$file.description|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
{$item.cost}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files} {if $item.approved || $item.invoice_id}   {else} - {$i18n.label.edit} + {$i18n.label.edit} {/if} {if $item.approved || $item.invoice_id}   {else} - {$i18n.label.delete} + {$i18n.label.delete} {/if}
{$subgroup.name|escape} {$subgroup.description|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 4e89a8a20..eaf163824 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -34,18 +34,18 @@ {if $user->custom_logo}
{else} - + {/if} - - + + {/foreach}
- + {if $user->custom_logo} {else} - + {/if} @@ -74,7 +74,7 @@ - - - + + {/foreach} {/if} @@ -60,8 +60,8 @@ - - + + {/foreach} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index c1ffff729..fa3faac63 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -16,8 +16,8 @@
{$template['name']|escape} {$template['description']|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
@@ -37,8 +37,8 @@
{$template['name']|escape} {$template['description']|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index 377b26c01..d0121d0ee 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -155,16 +155,16 @@ {/if} {if $show_files} {if $record.has_files} -
{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files} {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} - {$i18n.label.edit} + {$i18n.label.edit} {if ($record.duration == '0:00' && $record.start <> '')} @@ -177,7 +177,7 @@ {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} - {$i18n.label.delete} + {$i18n.label.delete} {/if}
{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
@@ -86,13 +86,13 @@ {/if} {if $show_files} {if $timesheet.has_files} -
{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
diff --git a/WEB-INF/templates/users.tpl b/WEB-INF/templates/users.tpl index 401751fcb..d7d3e3aa7 100644 --- a/WEB-INF/templates/users.tpl +++ b/WEB-INF/templates/users.tpl @@ -35,8 +35,8 @@
{$u.quota_percent}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete} {$u.quota_percent}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete} {if $record.comment}{$record.comment|escape}{else} {/if}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files} {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} - {$i18n.label.edit} + {$i18n.label.edit} {/if} {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} - {$i18n.label.delete} + {$i18n.label.delete} {/if}
{$work_item.description|escape} {$work_item.group_name|escape} ({$work_item.site_id}.{$work_item.group_id}) {$work_item.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
@@ -48,8 +48,8 @@
{$offer.description|escape} {$offer.group_name|escape} ({$offer.site_id}.{$offer.group_id}) {$offer.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
diff --git a/WEB-INF/templates/work/header.tpl b/WEB-INF/templates/work/header.tpl index 03f986885..582e76144 100644 --- a/WEB-INF/templates/work/header.tpl +++ b/WEB-INF/templates/work/header.tpl @@ -30,18 +30,18 @@ {if $user->custom_logo}
{else} - + {/if} - + - + {if $show_projects} - + {/if} - +
- + {if $user->custom_logo} {else} - + {/if} @@ -70,7 +70,7 @@ - - + {if $show_projects} - + {/if} - + - + {$forms.taskForm.close} diff --git a/WEB-INF/templates/task_edit2.tpl b/WEB-INF/templates/task_edit2.tpl index 0ec709851..e0a15e693 100644 --- a/WEB-INF/templates/task_edit2.tpl +++ b/WEB-INF/templates/task_edit2.tpl @@ -11,23 +11,23 @@ {$forms.taskForm.description.control}
{$forms.taskForm.status.control}
{$i18n.label.projects}:
{$i18n.label.projects}: {$forms.taskForm.projects.control}
{$i18n.label.required_fields}
{$forms.taskForm.btn_save.control} {$forms.taskForm.btn_copy.control}
{$forms.taskForm.close} diff --git a/WEB-INF/templates/user_add2.tpl b/WEB-INF/templates/user_add2.tpl index 6adc5f7cd..dfb4bfa19 100644 --- a/WEB-INF/templates/user_add2.tpl +++ b/WEB-INF/templates/user_add2.tpl @@ -153,10 +153,10 @@ function handleClientRole() {
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
{$forms.userForm.close} diff --git a/WEB-INF/templates/user_edit2.tpl b/WEB-INF/templates/user_edit2.tpl index ecc0a838e..8a3507e7b 100644 --- a/WEB-INF/templates/user_edit2.tpl +++ b/WEB-INF/templates/user_edit2.tpl @@ -191,10 +191,10 @@ function handleClientRole() {
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
{$forms.userForm.close} diff --git a/initialize.php b/initialize.php index 1b0d371db..d50b940b3 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5375"); +define("APP_VERSION", "1.19.23.5376"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/register.php b/register.php index a036c26d4..3430d4366 100644 --- a/register.php +++ b/register.php @@ -1,30 +1,6 @@ Date: Wed, 25 Nov 2020 15:08:27 +0000 Subject: [PATCH 1384/1848] Improved styling of the description field. --- default.css | 13 +++++++++++++ initialize.php | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index 3873051e6..a1784c5bc 100644 --- a/default.css +++ b/default.css @@ -239,6 +239,19 @@ input.password-field { width: 237px; } +#description { + width: 220px; + border-radius: 4px; + border: 1px solid #c9c9c9; + padding: .4rem; +} + +#description:focus { + background-color: yellow; + border: 1px solid black; + outline: none; +} + .chart-image { width: 300px; height: 300px; diff --git a/initialize.php b/initialize.php index d50b940b3..3de6ba486 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5376"); +define("APP_VERSION", "1.19.23.5377"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ccd704eabdc20299faffe089feeb555b292ca7b4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Nov 2020 15:47:43 +0000 Subject: [PATCH 1385/1848] Improving style of file upload control. --- default.css | 7 +++++++ initialize.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index a1784c5bc..5e1334bc8 100644 --- a/default.css +++ b/default.css @@ -235,6 +235,13 @@ input.password-field { width: 220px; } +input[type=file] { + width: 220px; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + .dropdown-field { width: 237px; } diff --git a/initialize.php b/initialize.php index 3de6ba486..092bf840f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5377"); +define("APP_VERSION", "1.19.23.5378"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 1bbfcb4c137b50a8019151aeeef9b51c711409d4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Nov 2020 16:25:29 +0000 Subject: [PATCH 1386/1848] Some more progress on styles. --- WEB-INF/lib/form/PasswordField.class.php | 28 ++---------------------- default.css | 13 +++++------ initialize.php | 2 +- 3 files changed, 8 insertions(+), 35 deletions(-) diff --git a/WEB-INF/lib/form/PasswordField.class.php b/WEB-INF/lib/form/PasswordField.class.php index 579be5edb..ff6802c90 100644 --- a/WEB-INF/lib/form/PasswordField.class.php +++ b/WEB-INF/lib/form/PasswordField.class.php @@ -1,30 +1,6 @@ Date: Wed, 25 Nov 2020 16:41:48 +0000 Subject: [PATCH 1387/1848] Improved style of the note field. --- default.css | 9 +++++++++ initialize.php | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index e2b634693..da21649f7 100644 --- a/default.css +++ b/default.css @@ -295,6 +295,15 @@ input[type="file"] { margin: 0; height: 4rem; resize: none; + border-radius: 4px; + border: 1px solid #c9c9c9; + padding: .4rem; +} + +#note:focus { + background-color: yellow; + border: 1px solid black; + outline: none; } .day-totals { diff --git a/initialize.php b/initialize.php index 5b6cc1cb3..c98543252 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5379"); +define("APP_VERSION", "1.19.23.5380"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 7322bce85707960781c50df141e1c78cac7b675f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Nov 2020 17:26:45 +0000 Subject: [PATCH 1388/1848] Improved spacing between menu items on site-map.php. --- WEB-INF/templates/site_map.tpl | 76 +++++++++++++++++----------------- default.css | 9 ++++ initialize.php | 2 +- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/WEB-INF/templates/site_map.tpl b/WEB-INF/templates/site_map.tpl index 48b8d40c1..c951f2b99 100644 --- a/WEB-INF/templates/site_map.tpl +++ b/WEB-INF/templates/site_map.tpl @@ -1,90 +1,90 @@ {if $authenticated} {if $user->can('administer_site')} {* sub menu for admin *} -

- {$i18n.menu.groups}
- {$i18n.menu.options}
+

+ + {if isTrue('WORK_SERVER_ADMINISTRATION')} - {$i18n.label.work}
+ {/if} -

+
{* end of sub menu for admin *} {* main menu for admin *} -

- {$i18n.menu.logout}
- {$i18n.menu.forum}
- {$i18n.menu.help}
-

+ {* end of main menu for admin *} {else} {* sub menu for authorized user *} -

+

{if $user->exists() && ($user->can('track_own_time') || $user->can('track_time'))} - {$i18n.menu.time}
+ {if $user->isPluginEnabled('wv') && $user->isOptionEnabled('week_menu')} - {$i18n.menu.week}
+ {/if} {/if} {if $user->exists() && $user->isPluginEnabled('ex') && ($user->can('track_own_expenses') || $user->can('track_expenses'))} - {$i18n.menu.expenses}
+ {/if} {if $user->exists() && ($user->can('view_own_reports') || $user->can('view_reports') || $user->can('view_all_reports') || $user->can('view_client_reports'))} - {$i18n.menu.reports}
+ {/if} {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('track_own_time') || $user->can('track_time'))} - {$i18n.menu.timesheets}
+ {/if} {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->can('view_client_invoices'))} - {$i18n.title.invoices}
+ {/if} {if ($user->exists() && $user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts'))) && (constant('MODE_PROJECTS') == $user->getTrackingMode() || constant('MODE_PROJECTS_AND_TASKS') == $user->getTrackingMode() || $user->isPluginEnabled('cl'))} - {$i18n.menu.charts}
+ {/if} {if ($user->can('view_own_projects') || $user->can('manage_projects')) && (constant('MODE_PROJECTS') == $user->getTrackingMode() || constant('MODE_PROJECTS_AND_TASKS') == $user->getTrackingMode())} - {$i18n.menu.projects}
+ {/if} {if (constant('MODE_PROJECTS_AND_TASKS') == $user->getTrackingMode() && ($user->can('view_own_tasks') || $user->can('manage_tasks')))} - {$i18n.menu.tasks}
+ {/if} {if $user->can('view_users') || $user->can('manage_users')} - {$i18n.menu.users}
+ {/if} {if $user->isPluginEnabled('cl') && ($user->can('view_own_clients') || $user->can('manage_clients'))} - {$i18n.menu.clients}
+ {/if} {if $user->can('export_data')} - {$i18n.menu.export}
+ {/if} -

+
{* end of sub menu for authorized user *} {* main menu for authorized user *} -

- {$i18n.menu.logout}
+

+ {if $user->exists() && $user->can('manage_own_settings')} - {$i18n.menu.profile}
+ {/if} {if $user->can('manage_basic_settings')} - {$i18n.menu.group}
+ {/if} {if $user->can('manage_features')} - {$i18n.menu.plugins}
+ {/if} - {$i18n.menu.forum}
- {$i18n.menu.help}
-

+ + +
{* end of main menu for authorized user *} {/if} {else} {* main menu for non authorized user *} -

- {$i18n.menu.login}
+

+ {if isTrue('MULTIORG_MODE') && constant('AUTH_MODULE') == 'db'} - {$i18n.menu.register}
+ {/if} - {$i18n.menu.forum}
- {$i18n.menu.help}
-

+ + +
{* end of main menu for non authorized user *} {/if} diff --git a/default.css b/default.css index da21649f7..820382bdf 100644 --- a/default.css +++ b/default.css @@ -358,6 +358,15 @@ input[type="file"] { margin-right: auto; } +.sitemap-item-group { + margin-top: 2rem; + margin-bottom: 2rem; +} + +.sitemap-item { + margin: .4rem; +} + @media screen and (max-width: 600px) { .large-screen-label { diff --git a/initialize.php b/initialize.php index c98543252..f2b193e74 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5380"); +define("APP_VERSION", "1.19.23.5381"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 56c1de5a9c853ad16a350c36669901f3acfa26c9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Nov 2020 18:17:27 +0000 Subject: [PATCH 1389/1848] Cosmetic. Added copytight notices on refactored templates. --- WEB-INF/templates/client_add2.tpl | 3 +++ WEB-INF/templates/client_delete2.tpl | 3 +++ WEB-INF/templates/client_edit2.tpl | 3 +++ WEB-INF/templates/clients2.tpl | 3 +++ WEB-INF/templates/entity_files2.tpl | 3 +++ WEB-INF/templates/expense_delete2.tpl | 3 +++ WEB-INF/templates/expense_edit2.tpl | 3 +++ WEB-INF/templates/expenses2.tpl | 3 +++ WEB-INF/templates/login.db2.tpl | 3 +++ WEB-INF/templates/login.ldap2.tpl | 3 +++ WEB-INF/templates/login2.tpl | 3 +++ WEB-INF/templates/password_change2.tpl | 3 +++ WEB-INF/templates/password_reset2.tpl | 3 +++ WEB-INF/templates/project_add2.tpl | 3 +++ WEB-INF/templates/project_delete2.tpl | 3 +++ WEB-INF/templates/project_edit2.tpl | 3 +++ WEB-INF/templates/register2.tpl | 3 +++ WEB-INF/templates/swap_roles2.tpl | 3 +++ WEB-INF/templates/task_add2.tpl | 3 +++ WEB-INF/templates/task_delete2.tpl | 3 +++ WEB-INF/templates/task_edit2.tpl | 3 +++ WEB-INF/templates/tasks2.tpl | 3 +++ WEB-INF/templates/time2.tpl | 3 +++ WEB-INF/templates/time_delete2.tpl | 3 +++ WEB-INF/templates/time_edit2.tpl | 3 +++ WEB-INF/templates/user_add2.tpl | 3 +++ WEB-INF/templates/user_delete2.tpl | 3 +++ WEB-INF/templates/user_edit2.tpl | 3 +++ WEB-INF/templates/users2.tpl | 3 +++ initialize.php | 2 +- 30 files changed, 88 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/client_add2.tpl b/WEB-INF/templates/client_add2.tpl index e22081ef4..5fe001b23 100644 --- a/WEB-INF/templates/client_add2.tpl +++ b/WEB-INF/templates/client_add2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {$forms.clientForm.open} diff --git a/WEB-INF/templates/client_delete2.tpl b/WEB-INF/templates/client_delete2.tpl index bc583ea66..47506f79b 100644 --- a/WEB-INF/templates/client_delete2.tpl +++ b/WEB-INF/templates/client_delete2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {$forms.clientDeleteForm.open}
diff --git a/WEB-INF/templates/client_edit2.tpl b/WEB-INF/templates/client_edit2.tpl index 935c6a1e5..91f2b1c39 100644 --- a/WEB-INF/templates/client_edit2.tpl +++ b/WEB-INF/templates/client_edit2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {$forms.clientForm.open}
{$i18n.form.client.client_to_delete}:
diff --git a/WEB-INF/templates/clients2.tpl b/WEB-INF/templates/clients2.tpl index 1ec69df2f..9f7d4064b 100644 --- a/WEB-INF/templates/clients2.tpl +++ b/WEB-INF/templates/clients2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + diff --git a/WEB-INF/templates/entity_files2.tpl b/WEB-INF/templates/entity_files2.tpl index 9d48e24c1..d6b892b38 100644 --- a/WEB-INF/templates/entity_files2.tpl +++ b/WEB-INF/templates/entity_files2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {if $files}
diff --git a/WEB-INF/templates/expense_delete2.tpl b/WEB-INF/templates/expense_delete2.tpl index 9b9bab838..a9ea04d10 100644 --- a/WEB-INF/templates/expense_delete2.tpl +++ b/WEB-INF/templates/expense_delete2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {$forms.expenseItemForm.open}
diff --git a/WEB-INF/templates/expense_edit2.tpl b/WEB-INF/templates/expense_edit2.tpl index 3cea79482..ec921e007 100644 --- a/WEB-INF/templates/expense_edit2.tpl +++ b/WEB-INF/templates/expense_edit2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time2.tpl index 33aa428e7..487bff7cf 100644 --- a/WEB-INF/templates/time2.tpl +++ b/WEB-INF/templates/time2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {include file="time_script.tpl"} {if $show_navigation} diff --git a/WEB-INF/templates/time_delete2.tpl b/WEB-INF/templates/time_delete2.tpl index 20acb783c..59d9039d1 100644 --- a/WEB-INF/templates/time_delete2.tpl +++ b/WEB-INF/templates/time_delete2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {$forms.timeRecordForm.open}
diff --git a/WEB-INF/templates/time_edit2.tpl b/WEB-INF/templates/time_edit2.tpl index dc3d78cd0..8a25c43cf 100644 --- a/WEB-INF/templates/time_edit2.tpl +++ b/WEB-INF/templates/time_edit2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {include file="time_script.tpl"} {* Conditional include of confirmSave handler. *} diff --git a/WEB-INF/templates/user_add2.tpl b/WEB-INF/templates/user_add2.tpl index dfb4bfa19..ad421b9e8 100644 --- a/WEB-INF/templates/user_add2.tpl +++ b/WEB-INF/templates/user_add2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + diff --git a/initialize.php b/initialize.php index f2b193e74..42b94a865 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5381"); +define("APP_VERSION", "1.19.23.5382"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 25202d51cbcbe494fb4a5a30cf90687736d64342 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Nov 2020 18:25:02 +0000 Subject: [PATCH 1390/1848] Cleanup. Removed no longer used legacy mobile client pages and templates. --- WEB-INF/templates/mobile/client_add.tpl | 37 ------ WEB-INF/templates/mobile/client_delete.tpl | 25 ---- WEB-INF/templates/mobile/client_edit.tpl | 41 ------- WEB-INF/templates/mobile/clients.tpl | 66 ---------- WEB-INF/templates/mobile/header.tpl | 3 - initialize.php | 2 +- mobile/client_add.php | 94 -------------- mobile/client_delete.php | 78 ------------ mobile/client_edit.php | 135 --------------------- mobile/clients.php | 54 --------- 10 files changed, 1 insertion(+), 534 deletions(-) delete mode 100644 WEB-INF/templates/mobile/client_add.tpl delete mode 100644 WEB-INF/templates/mobile/client_delete.tpl delete mode 100644 WEB-INF/templates/mobile/client_edit.tpl delete mode 100644 WEB-INF/templates/mobile/clients.tpl delete mode 100644 mobile/client_add.php delete mode 100644 mobile/client_delete.php delete mode 100644 mobile/client_edit.php delete mode 100644 mobile/clients.php diff --git a/WEB-INF/templates/mobile/client_add.tpl b/WEB-INF/templates/mobile/client_add.tpl deleted file mode 100644 index db10ede45..000000000 --- a/WEB-INF/templates/mobile/client_add.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{$forms.clientForm.open} -
- - - -
- - - - - - - - - - - - - - - - - - -{if $show_projects} - - - - - -{/if} - - - -
{$i18n.label.client_name} (*):{$forms.clientForm.name.control}
{$i18n.label.client_address}:{$forms.clientForm.address.control}
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->getDecimalMark()}00)
{$i18n.label.required_fields}
 
{$i18n.label.projects}:{$forms.clientForm.projects.control}
 
{$forms.clientForm.btn_submit.control}
-
-{$forms.clientForm.close} diff --git a/WEB-INF/templates/mobile/client_delete.tpl b/WEB-INF/templates/mobile/client_delete.tpl deleted file mode 100644 index f40b94c12..000000000 --- a/WEB-INF/templates/mobile/client_delete.tpl +++ /dev/null @@ -1,25 +0,0 @@ -{$forms.clientDeleteForm.open} - - - - -
- - - - - - - - - - - - - - - - -
{$i18n.form.client.client_to_delete}:{$client_to_delete|escape}
{$i18n.form.client.client_entries}:{$forms.clientDeleteForm.delete_client_entries.control}
 
{$forms.clientDeleteForm.btn_delete.control}  {$forms.clientDeleteForm.btn_cancel.control}
-
-{$forms.clientDeleteForm.close} diff --git a/WEB-INF/templates/mobile/client_edit.tpl b/WEB-INF/templates/mobile/client_edit.tpl deleted file mode 100644 index 4f70ced7a..000000000 --- a/WEB-INF/templates/mobile/client_edit.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{$forms.clientForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - -{if $show_projects} - - - - -{/if} - - - - -
{$i18n.label.client_name} (*):{$forms.clientForm.name.control}
{$i18n.label.client_address}:{$forms.clientForm.address.control}
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->decimal_mark}00)
{$i18n.label.status}:{$forms.clientForm.status.control}
{$i18n.label.required_fields}
 
{$i18n.label.projects}:{$forms.clientForm.projects.control}
 
{$forms.clientForm.btn_save.control} {$forms.clientForm.btn_copy.control} {$forms.clientForm.btn_delete.control}
-
-{$forms.clientForm.close} diff --git a/WEB-INF/templates/mobile/clients.tpl b/WEB-INF/templates/mobile/clients.tpl deleted file mode 100644 index 34f53a919..000000000 --- a/WEB-INF/templates/mobile/clients.tpl +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - -
-{if $user->can('manage_clients')} - - {if $inactive_clients} - - {/if} - - - - - {foreach $active_clients as $client} - - - - - {/foreach} -
{$i18n.form.clients.active_clients}
{$i18n.label.person_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}
- - - -

- - {if $inactive_clients} - - - - - - - {foreach $inactive_clients as $client} - - - - - {/foreach} -
{$i18n.form.clients.inactive_clients}
{$i18n.label.person_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}
- - - -

- {/if} -{else} - - - - - - {if $active_clients} - {foreach $active_clients as $client} - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}
-{/if} -
diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index ccea5e7e1..d4cf2c53b 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -91,9 +91,6 @@ {/if} {if $user->can('view_users') || $user->can('manage_users')} {$i18n.menu.users} - {/if} - {if $user->isPluginEnabled('cl') && ($user->can('view_own_clients') || $user->can('manage_clients'))} - {$i18n.menu.clients} {/if}
{$i18n.label.required_fields}
{$i18n.label.projects}:
{$i18n.label.projects}:
{$i18n.label.required_fields}
{$i18n.label.projects}:
{$i18n.label.projects}:
{$i18n.label.users}:
{$i18n.label.users}:
{$i18n.label.tasks}:
{$i18n.label.tasks}:
{$i18n.label.users}:
{$i18n.label.users}:
{$i18n.label.tasks}:
{$i18n.label.tasks}:
{$i18n.label.projects}:
{$i18n.label.projects}:
{$i18n.label.projects}:
{$i18n.label.projects}:
@@ -37,8 +38,8 @@ License: See license.txt *} +
{$forms.fileUploadForm.description.control}
{$forms.fileUploadForm.btn_submit.control}
-
{$forms.fileUploadForm.btn_submit.control}
{$forms.fileUploadForm.close} {/if} diff --git a/default.css b/default.css index fea2e8da5..8079296aa 100644 --- a/default.css +++ b/default.css @@ -128,8 +128,7 @@ div.page-hint { margin-top: .5rem; margin-left: auto; margin-right: auto; - padding: .5rem; - background-color: #f0f0f0; + border-collapse: collapse; } .x-scrollable-table th { @@ -140,6 +139,9 @@ div.page-hint { padding: .25rem; } +.x-scrollable-table tr:nth-child(even) {background: #ffffff} +.x-scrollable-table tr:nth-child(odd) {background: #f5f5f5} + .text-cell { text-align: left; } diff --git a/initialize.php b/initialize.php index 837759f2b..2cd8198bb 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5390"); +define("APP_VERSION", "1.19.23.5391"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 83fc6da0ea7e7e2ef1e23653e9d442efa303c32e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 18:36:05 +0000 Subject: [PATCH 1399/1848] Some style fixes for calendar and x-scrollable-table. --- default.css | 5 +++++ initialize.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index 8079296aa..c4f8ac542 100644 --- a/default.css +++ b/default.css @@ -133,6 +133,7 @@ div.page-hint { .x-scrollable-table th { white-space: nowrap; + padding: .25rem; } .x-scrollable-table td { @@ -281,6 +282,10 @@ input[type="file"] { margin-right: auto; } +.small-screen-calendar a:focus, .large-screen-calendar a:focus { + outline: none; +} + .large-screen-calendar { display: block; width: 210px; diff --git a/initialize.php b/initialize.php index 2cd8198bb..627153414 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5391"); +define("APP_VERSION", "1.19.23.5392"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ad9d244216139d0c9e0aec21a00905eb3198a897 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 20:35:20 +0000 Subject: [PATCH 1400/1848] Fixed an issue with incorrect column span. --- initialize.php | 2 +- time.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/initialize.php b/initialize.php index 627153414..79d1105fe 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5392"); +define("APP_VERSION", "1.19.23.5393"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 27c21d431..6bd10ad53 100644 --- a/time.php +++ b/time.php @@ -86,8 +86,7 @@ } if ($showProject) $colspan++; if ($showTask) $colspan++; - if ($showStart) $colspan++; - if ($showFinish) $colspan++; + if ($showStart) $colspan += 2; // Another for show finish. $colspan++; // There is always a duration. if ($showFiles) $colspan++; $colspan++; // There is always an edit column. From 9d37ef6efab76fa1f94cb7b534f6c31cb2d227f0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 21:02:08 +0000 Subject: [PATCH 1401/1848] Improved UI for user pages. --- WEB-INF/templates/user_add2.tpl | 1 + WEB-INF/templates/user_edit2.tpl | 1 + default.css | 4 ++++ initialize.php | 2 +- user_add.php | 1 + user_edit.php | 1 + 6 files changed, 9 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/user_add2.tpl b/WEB-INF/templates/user_add2.tpl index ad421b9e8..7413fd2a2 100644 --- a/WEB-INF/templates/user_add2.tpl +++ b/WEB-INF/templates/user_add2.tpl @@ -147,6 +147,7 @@ function handleClientRole() {
-
+ {section name=i loop=$totals} {if $smarty.section.i.index <= 12} @@ -68,7 +68,7 @@ function adjustTodayLinks() {
-
+ {section name=i loop=$totals} {if $smarty.section.i.index <= 12} diff --git a/default.css b/default.css index 2aa8335f8..2262acf67 100644 --- a/default.css +++ b/default.css @@ -8,57 +8,53 @@ body { background-color: white; } +/* logo on top of pages */ div.logo { padding: .5rem; text-align: center; background-color: #a6ccf7; } +/* top menu bar for large screens */ div.top-menu-large-screen { background-color: black; display: block; } -.top-submenu-large-screen { +/* submenu for large screens */ +div.top-submenu-large-screen { background-color: #d9d9d9; display: block; } +/* top menu for small screens */ div.top-menu-small-screen { background-color: black; display: none; } -div.top-menu-small-screen a { +/* top menu items */ +div.top-menu-large-screen a, div.top-menu-small-screen a { font-size: 1rem; font-weight: bold; color: white; margin: .1rem .2rem .1rem .2rem; } -div.top-menu-large-screen a { - font-size: 1rem; - font-weight: bold; - color: white; - margin: .1rem .2rem .1rem .2rem; -} - -.top-menu-table { - margin-left: auto; - margin-right: auto; -} - -.top-submenu-table { +/* top menu tables */ +.top-menu-table, .top-submenu-table { margin-left: auto; margin-right: auto; } +/* top submenu items */ .top-submenu-large-screen a { font-size: 1rem; color: #444444; margin: .1rem .2rem .1rem .2rem; } +/* page title div */ div.page-title { font-size: 12pt; font-weight: bold; @@ -69,45 +65,60 @@ div.page-title { margin-bottom: .2rem; } +/* user details div */ div.user-details { text-align: center; padding: .2rem; } +/* page errors div */ .page-errors { margin-top: .5rem; text-align: center; color: red; } +/* page messages div */ .page-messages { margin-top: .5rem; text-align: center; color: blue; } +/* page content div */ .page-content { text-align: center; } +/* vertical separator for controls on forms for both large and small screens */ .form-control-separator { height: .5rem; } +/* vertical separator for controls on small screens */ +.small-screen-form-control-separator { + height: .25rem; + display: none; +} + +/* "about" text div on login page */ div#LoginAboutText { padding: 1rem; margin-left:auto; margin-right:auto; } +/* default domain text div for ldap login */ #ldapDefaultDomain { color: #777777; } +/* page hint div to display on top of some pages to clarify things */ div.page-hint { margin-top: 1rem; } +/* project rate table for user add and user edit pages */ .project-rate-table { width: 300px; border-collapse: collapse; @@ -117,21 +128,15 @@ div.page-hint { padding: .2rem; } +/* a table to display controls centered horizontally */ .centered-table { + display: inline-block; margin-top: .5rem; margin-left: auto; margin-right: auto; - display: inline-block; -} - -.chart-list { - border-spacing: .2rem; -} - -.record-list { - margin: 1rem; } +/* a table to hold things that may not fit into available screen width */ .x-scrollable-table { display: inline-block; margin-top: .5rem; @@ -152,40 +157,59 @@ div.page-hint { .x-scrollable-table tr:nth-child(even) {background: #ffffff} .x-scrollable-table tr:nth-child(odd) {background: #f5f5f5} +/* a text cell in tables */ .text-cell { text-align: left; } +/* time cell in tables */ .time-cell { text-align: right; } +/* text cell for note header when we display notes on separate rows */ .note-header-cell { text-align: right; } +/* control labels for large screens */ .large-screen-label { text-align: right; vertical-align: middle; display: table-cell; } -.large-screen-chart-list { +/* control labels for small screens */ +.small-screen-label { + text-align: left; + display: none; +} + +/* list of items displayed in a chart on large screens */ +.large-screen-chart-items-list { display: table-cell; } -.small-screen-chart-list { +/* list of items displayed in a chart on small screens */ +.small-screen-chart-items-list { display: none; } -.small-screen-label { - text-align: left; - display: none; +/* a div to display a chart in */ +div.chart { + padding-left: 1rem; + padding-right: 1rem; } -.small-screen-form-control-separator { - height: .25rem; - display: none; + + +/* TODO: work in progress below... */ +.chart-list { + border-spacing: .2rem; +} + +.record-list { + margin: 1rem; } .page-content input { @@ -393,11 +417,11 @@ input[type="file"] { display: none; } - .large-screen-chart-list { + .large-screen-chart-items-list { display: none; } - .small-screen-chart-list { + .small-screen-chart-items-list { display: table-cell; } diff --git a/initialize.php b/initialize.php index aced0690c..c33acb839 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5397"); +define("APP_VERSION", "1.19.23.5398"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 13bc4e28d73abdc10b4c02f264161719b6bc7866 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 2 Dec 2020 18:32:30 +0000 Subject: [PATCH 1406/1848] Some cleanup and commenting in styles. --- WEB-INF/templates/charts2.tpl | 4 ++-- default.css | 10 ++++++---- initialize.php | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/charts2.tpl b/WEB-INF/templates/charts2.tpl index 6e9f1756d..ff15ea8f2 100644 --- a/WEB-INF/templates/charts2.tpl +++ b/WEB-INF/templates/charts2.tpl @@ -54,7 +54,7 @@ function adjustTodayLinks() {
- +
{section name=i loop=$totals} {if $smarty.section.i.index <= 12} @@ -69,7 +69,7 @@ function adjustTodayLinks() {
{$totals[i].name|escape}
- +
{section name=i loop=$totals} {if $smarty.section.i.index <= 12} diff --git a/default.css b/default.css index 2262acf67..518f200db 100644 --- a/default.css +++ b/default.css @@ -145,15 +145,18 @@ div.page-hint { border-collapse: collapse; } +/* th in x-scrollable-table */ .x-scrollable-table th { white-space: nowrap; padding: .25rem; } +/* td in x-scrollable-table */ .x-scrollable-table td { padding: .25rem; } +/* alternating row background in x-scrollable-table */ .x-scrollable-table tr:nth-child(even) {background: #ffffff} .x-scrollable-table tr:nth-child(odd) {background: #f5f5f5} @@ -201,13 +204,12 @@ div.chart { padding-right: 1rem; } - - -/* TODO: work in progress below... */ -.chart-list { +/* a table to annotate items from chart picture */ +.chart-items-list-table { border-spacing: .2rem; } +/* TODO: work in progress below */ .record-list { margin: 1rem; } diff --git a/initialize.php b/initialize.php index c33acb839..0f49c474f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5398"); +define("APP_VERSION", "1.19.23.5399"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 000093299c75e46866bcccc6fd42a4092dd8a0ef Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 15:22:32 +0000 Subject: [PATCH 1407/1848] Put some more comments in default.css. --- default.css | 26 ++++++++++++++++++-------- initialize.php | 2 +- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/default.css b/default.css index 518f200db..619426ef1 100644 --- a/default.css +++ b/default.css @@ -209,38 +209,48 @@ div.chart { border-spacing: .2rem; } -/* TODO: work in progress below */ -.record-list { +/* a div to display a list of records in */ +div.record-list { margin: 1rem; } +/* input controls */ .page-content input { border-radius: 4px; border: 1px solid #c9c9c9; padding: .4rem; } -.td-with-input { - text-align: left; -} - +/* input controls with focus on them */ .page-content input:focus { background-color: yellow; border: 1px solid black; outline: none; } -.contribute-msg { +/* a table cell containing input control */ +.td-with-input { + text-align: left; +} + +/* div containing how to contribute message */ +div.contribute-msg { text-align: center; margin-top: 2rem; padding: .2rem; background-color: #eeeeee; } -.version-and-copyright { + +/* div containing app version and copyright info */ +div.version-and-copyright { text-align: center; padding: .5rem; } + + + +/* TODO: work in progress below */ .centered-table td img { vertical-align: middle; } diff --git a/initialize.php b/initialize.php index 0f49c474f..82cc5d7df 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5399"); +define("APP_VERSION", "1.19.23.5400"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 82fa8f93e9a8c5cffd16db0303b9ca18ec6cd25b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 16:59:01 +0000 Subject: [PATCH 1408/1848] Added more comments in default.css. --- default.css | 131 ++++++++++++++++++++++++++++++------------------- initialize.php | 2 +- 2 files changed, 82 insertions(+), 51 deletions(-) diff --git a/default.css b/default.css index 619426ef1..30160902b 100644 --- a/default.css +++ b/default.css @@ -247,82 +247,95 @@ div.version-and-copyright { padding: .5rem; } - - - -/* TODO: work in progress below */ +/* img in td in centered-table, ex: now icons */ .centered-table td img { vertical-align: middle; } -.what-is-it-img { +/* span for what is it icon image */ +span.what-is-it-img { display: none; } -.what-is-it-text { +/* span for what is it text */ +span.what-is-it-text { display: inline-block; } -input[type="submit"] { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} - -input[type="button"] { +/* buttons */ +input[type="submit"], input[type="button"] { -webkit-appearance: none; -moz-appearance: none; appearance: none; } -input[type="text"] { +/* input controls */ +input[type="text"], input[type="password"], input[type="file"] { width: 220px; } +/* project rate input control */ input[type="text"].project-rate-field { width: 50px; } -input[type="password"] { - width: 220px; +/* dropdown control */ +.dropdown-field { + width: 236px; } -input[type="file"] { +/* textareas for fields */ +#description, #address, #item_name { width: 220px; + border-radius: 4px; + border: 1px solid #c9c9c9; + padding: .4rem; } -.dropdown-field { - width: 237px; +/* textareas with focus */ +#description:focus, #address:focus, #item_name:focus { + background-color: yellow; + border: 1px solid black; + outline: none; } -#description, #address, #item_name { - width: 220px; +/* textarea for note field */ +#note { + width: 100%; + margin: 0; + height: 4rem; + resize: none; border-radius: 4px; border: 1px solid #c9c9c9; padding: .4rem; } -#description:focus, #address:focus, #item_name:focus { +/* note field with focus */ +#note:focus { background-color: yellow; border: 1px solid black; outline: none; } +/* chart image */ .chart-image { width: 300px; height: 300px; } +/* chart color cell for annotations */ .chart-color-cell { width: .4rem; height: 1rem; } +/* chart description cell for annotations */ .chart-description-cell { text-align: left; padding-left: .25rem; } +/* calendar for small screens */ .small-screen-calendar { display: none; width: 210px; @@ -331,10 +344,12 @@ input[type="file"] { margin-right: auto; } +/* calendars with focus */ .small-screen-calendar a:focus, .large-screen-calendar a:focus { outline: none; } +/* calendar for large screens */ .large-screen-calendar { display: block; width: 210px; @@ -342,143 +357,159 @@ input[type="file"] { margin-top: 1rem; } +/* label for checkboxes */ .checkbox-label { float: left; } -#note { - width: 100%; - margin: 0; - height: 4rem; - resize: none; - border-radius: 4px; - border: 1px solid #c9c9c9; - padding: .4rem; -} - -#note:focus { - background-color: yellow; - border: 1px solid black; - outline: none; -} - -.day-totals { +/* div for day totals */ +div.day-totals { margin-bottom: 1rem; + width: 100%; } +/* column 1 for day totals */ .day-totals-col1 { text-align: left; padding-left: .5rem; padding-right: .5rem; } +/* column 2 for day totals */ .day-totals-col2 { padding-left: .5rem; padding-right: .5rem; text-align: right; } +/* not billable items */ .not-billable { - color: #ff6666; + color: red; } -.remaining-quota { +/* remaining quota span */ +span.remaining-quota { color: red; } -.remaining-quota-balance { +/* remaining quota balance span */ +span.remaining-quota-balance { color: red; } -.over-quota { +/* over quota span */ +span.over-quota { color: green; } -.over-quota-balance { +/* over quota balance span */ +span.over-quota-balance { color: green; } -.optional-nav { +/* div for optional navigation, ex: week view */ +div.optional-nav { margin-top: .5rem; } +/* div for a set of buttons, ex: save, copy, delete */ .button-set { margin-top: .5rem; margin-bottom: 1rem; } -.section-header { +/* section header div */ +div.section-header { font-weight: bold; text-align: center; margin-left: auto; margin-right: auto; } -.sitemap-item-group { +/* div for a group of items in site map */ +div.sitemap-item-group { margin-top: 2rem; margin-bottom: 2rem; } -.sitemap-item { +/* div for a single item in site map */ +div.sitemap-item { margin: .4rem; } +/* media rules for small screens */ @media screen and (max-width: 600px) { + /* hide large screen labels */ .large-screen-label { display: none; } + /* hide large screen chart annotations */ .large-screen-chart-items-list { display: none; } + /* show small screen chart annotations */ .small-screen-chart-items-list { display: table-cell; } + /* show small screen labels */ .small-screen-label { display: block; } + /* show small screen calendar */ .small-screen-calendar { display: block; } + /* hide large screen calendar */ .large-screen-calendar { display: none; } + /* show small screen form control separators */ .small-screen-form-control-separator { display: block; } - .what-is-it-img { + /* show what is it icons */ + span.what-is-it-img { display: inline-block; } - .what-is-it-text { + /* hide what is it text */ + span.what-is-it-text { display: none; } + /* hide how to contribute message */ div.contribute-msg { display: none; } + /* hide version and copyright */ div.version-and-copyright { display: none; } } +/* media rules for menus on small screens */ @media screen and (max-width: 1170px) { + + /* show small screen menu */ div.top-menu-small-screen { display: block; } + /* hide large screen menu */ div.top-menu-large-screen { display: none; } + /* hide large screen submenu */ div.top-submenu-large-screen { display: none; } diff --git a/initialize.php b/initialize.php index 82cc5d7df..2978e7a1b 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5400"); +define("APP_VERSION", "1.19.23.5401"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 05988b6d9bf9be8fc5f64f55cc9c61e602058638 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 17:43:38 +0000 Subject: [PATCH 1409/1848] Removed no longer used files. --- charts1.php | 227 -------------------- clients1.php | 55 ----- default.css | 4 - expense_delete1.php | 88 -------- expense_edit1.php | 243 --------------------- expenses1.php | 251 ---------------------- initialize.php | 2 +- project_add1.php | 118 ----------- project_edit1.php | 136 ------------ projects1.php | 58 ----- task_add1.php | 89 -------- task_edit1.php | 122 ----------- tasks1.php | 77 ------- time1.php | 506 -------------------------------------------- user_add1.php | 244 --------------------- user_edit1.php | 308 --------------------------- users1.php | 69 ------ 17 files changed, 1 insertion(+), 2596 deletions(-) delete mode 100644 charts1.php delete mode 100644 clients1.php delete mode 100644 expense_delete1.php delete mode 100644 expense_edit1.php delete mode 100644 expenses1.php delete mode 100644 project_add1.php delete mode 100644 project_edit1.php delete mode 100644 projects1.php delete mode 100644 task_add1.php delete mode 100644 task_edit1.php delete mode 100644 tasks1.php delete mode 100644 time1.php delete mode 100644 user_add1.php delete mode 100644 user_edit1.php delete mode 100644 users1.php diff --git a/charts1.php b/charts1.php deleted file mode 100644 index 3b4ce15a1..000000000 --- a/charts1.php +++ /dev/null @@ -1,227 +0,0 @@ -isPluginEnabled('ch')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!$user->exists()) { - header('Location: access_denied.php'); // Nobody to display a chart for. - exit(); -} -if ($user->behalf_id && (!$user->can('view_charts') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('view_own_charts') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to view on behalf. - exit(); -} -if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid($request->getParameter('user'))) { - header('Location: access_denied.php'); // Wrong user id on post. - exit(); - } -} -// End of access checks. - -// Determine user for which we display this page. -$userChanged = $request->getParameter('user_changed'); -if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -$uc = new ttUserConfig(); -$tracking_mode = $user->getTrackingMode(); - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -if(!$cl_date) { - $now = new DateAndTime(DB_DATEFORMAT); - $cl_date = $now->toString(DB_DATEFORMAT); -} -$_SESSION['date'] = $cl_date; - -if ($request->isPost()) { - $cl_interval = $request->getParameter('interval'); - if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; - $_SESSION['chart_interval'] = $cl_interval; - $uc->setValue(SYSC_CHART_INTERVAL, $cl_interval); - - $cl_type = $request->getParameter('type'); - if (!$cl_type) $cl_type = ttChartHelper::adjustType($cl_type); - $_SESSION['chart_type'] = $cl_type; - $uc->setValue(SYSC_CHART_TYPE, $cl_type); -} else { - // Initialize chart interval. - $cl_interval = $_SESSION['chart_interval']; - if (!$cl_interval) $cl_interval = $uc->getValue(SYSC_CHART_INTERVAL); - if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; - $_SESSION['chart_interval'] = $cl_interval; - - // Initialize chart type. - $cl_type = $_SESSION['chart_type']; - if (!$cl_type) $cl_type = $uc->getValue(SYSC_CHART_TYPE); - $cl_type = ttChartHelper::adjustType($cl_type); - $_SESSION['chart_type'] = $cl_type; -} - -// Elements of chartForm. -$chart_form = new Form('chartForm'); - -// User dropdown. Changes the user "on behalf" of whom we are working. -if ($user->can('view_charts')) { - $rank = $user->getMaxRankForGroup($user->getGroup()); - if ($user->can('view_own_charts')) - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); - if (count($user_list) >= 1) { - $chart_form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.user_changed.value=1;this.form.submit();', - 'name'=>'user', - 'value'=>$user_id, - 'data'=>$user_list, - 'datakeys'=>array('id','name'), - )); - $chart_form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $smarty->assign('user_dropdown', 1); - } -} - -// Chart interval options. -$intervals = array(); -$intervals[INTERVAL_THIS_DAY] = $i18n->get('dropdown.selected_day'); -$intervals[INTERVAL_THIS_WEEK] = $i18n->get('dropdown.selected_week'); -$intervals[INTERVAL_THIS_MONTH] = $i18n->get('dropdown.selected_month'); -$intervals[INTERVAL_THIS_YEAR] = $i18n->get('dropdown.selected_year'); -$intervals[INTERVAL_ALL_TIME] = $i18n->get('dropdown.all_time'); - -// Chart interval dropdown. -$chart_form->addInput(array('type' => 'combobox', - 'onchange' => 'this.form.submit();', - 'name' => 'interval', - 'value' => $cl_interval, - 'data' => $intervals -)); - -// Chart type options. -$chart_selector = (MODE_PROJECTS_AND_TASKS == $tracking_mode || $user->isPluginEnabled('cl')); -if ($chart_selector) { - $types = array(); - if (MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode) - $types[CHART_PROJECTS] = $i18n->get('dropdown.projects'); - if (MODE_PROJECTS_AND_TASKS == $tracking_mode) - $types[CHART_TASKS] = $i18n->get('dropdown.tasks'); - if ($user->isPluginEnabled('cl')) - $types[CHART_CLIENTS] = $i18n->get('dropdown.clients'); - - // Add chart type dropdown. - $chart_form->addInput(array('type' => 'combobox', - 'onchange' => 'this.form.submit();', - 'name' => 'type', - 'value' => $cl_type, - 'data' => $types - )); -} - -// Calendar. -$chart_form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar - -// Get data for our chart. -$totals = ttChartHelper::getTotals($user_id, $cl_type, $cl_date, $cl_interval); -$smarty->assign('totals', $totals); - -// Prepare chart for drawing. -/* - * We use libchart.php library to draw chart images. It can draw chart labels, too (embed in the image). - * But quality of such auto-scaled text is not good. Therefore, we only use libchart to draw a pie-chart picture with - * auto-calculated percentage markers around it. We print labels (to the side of the picture) ourselves, - * using the same colors libchart is using. For labels printout, the $totals array (which is used for picture points) - * is also passed to charts.tpl Smarty template. - * - * To make all of the above possible with only one database call to obtain $totals we have to print the chart image - * to a file here (see code below). Once the image is available as a .png file, the charts.tpl can render it. - * - * PieChartEx class is a little extension to libchart-provided PieChart class. It allows us to print the chart - * without title, logo, and labels. - */ -$chart = new PieChartEx(300, 300); -$data_set = new XYDataSet(); -foreach($totals as $total) { - $data_set->addPoint(new Point( $total['name'], $total['time'])); -} -$chart->setDataSet($data_set); - -// Prepare a file name. -$img_dir = TEMPLATE_DIR.'_c/'; // Directory. -$file_name = uniqid('chart_').'.png'; // Short file name. Unique ID here is to avoid problems with browser caching. -$img_ref = 'WEB-INF/templates_c/'.$file_name; // Image reference for html. -$file_name = $img_dir.$file_name; // Full file name. - -// Clean up the file system from older images. -$img_files = glob($img_dir.'chart_*.png'); -if (is_array($img_files)) { - foreach($img_files as $file) { - // If file creation time is older than 1 minute, delete it. - if (filemtime($file) < (time() - 60)) { - unlink($file); - } - } -} - -// Write chart image to file system. -$chart->renderEx(array('fileName'=>$file_name,'hideLogo'=>true,'hideTitle'=>true,'hideLabel'=>true)); -// At this point libchart usage is complete and we have chart image on disk. - -$smarty->assign('img_file_name', $img_ref); -$smarty->assign('chart_selector', $chart_selector); -$smarty->assign('forms', array($chart_form->getName() => $chart_form->toArray())); -$smarty->assign('title', $i18n->get('title.charts')); -$smarty->assign('content_page_name', 'charts.tpl'); -$smarty->display('index.tpl'); diff --git a/clients1.php b/clients1.php deleted file mode 100644 index a299d3061..000000000 --- a/clients1.php +++ /dev/null @@ -1,55 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -if($user->can('manage_clients')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $inactive_clients = ttGroupHelper::getInactiveClients(true); -} else - $active_clients = $user->getAssignedClients(); - -$smarty->assign('active_clients', $active_clients); -$smarty->assign('inactive_clients', $inactive_clients); -$smarty->assign('title', $i18n->get('title.clients')); -$smarty->assign('content_page_name', 'clients.tpl'); -$smarty->display('index.tpl'); diff --git a/default.css b/default.css index 30160902b..595967e64 100644 --- a/default.css +++ b/default.css @@ -515,10 +515,6 @@ div.sitemap-item { } } - - - - /* TODO: below are legacy styles. Review as work on mobile-friendly pages continues. */ a { color: blue; text-decoration: none; } diff --git a/expense_delete1.php b/expense_delete1.php deleted file mode 100644 index 788fb59fa..000000000 --- a/expense_delete1.php +++ /dev/null @@ -1,88 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -// Get the expense item we are deleting. -$expense_item = ttExpenseHelper::getItem($cl_id); -if (!$expense_item || $expense_item['approved'] || $expense_item['invoice_id']) { - // Prohibit deleting not ours, approved, or invoiced items. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -if ($request->isPost()) { - if ($request->getParameter('delete_button')) { // Delete button pressed. - - // Determine if it is okay to delete the record. - $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); - if ($user->isDateLocked($item_date)) - $err->add($i18n->get('error.range_locked')); - - if ($err->no()) { - // Mark the record as deleted. - if (ttExpenseHelper::markDeleted($cl_id)) { - header('Location: expenses.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } - if ($request->getParameter('cancel_button')) { // Cancel button pressed. - header('Location: expenses.php'); - exit(); - } -} // isPost - -$form = new Form('expenseItemForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); - -$show_project = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); - -$smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('expense_item', $expense_item); -$smarty->assign('show_project', $show_project); -$smarty->assign('title', $i18n->get('title.delete_expense')); -$smarty->assign('content_page_name', 'expense_delete.tpl'); -$smarty->display('index.tpl'); diff --git a/expense_edit1.php b/expense_edit1.php deleted file mode 100644 index d8b452d56..000000000 --- a/expense_edit1.php +++ /dev/null @@ -1,243 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -// Get the expense item we are editing. -$expense_item = ttExpenseHelper::getItem($cl_id); -if (!$expense_item || $expense_item['approved'] || $expense_item['invoice_id']) { - // Prohibit editing not ours, approved, or invoiced items. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); -$confirm_save = $user->getConfigOption('confirm_save'); -$trackingMode = $user->getTrackingMode(); -$show_project = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; - -// Initialize variables. -$cl_date = $cl_client = $cl_project = $cl_item_name = $cl_cost = null; -if ($request->isPost()) { - $cl_date = trim($request->getParameter('date')); - $cl_client = $request->getParameter('client'); - $cl_project = $request->getParameter('project'); - $cl_item_name = trim($request->getParameter('item_name')); - $cl_cost = trim($request->getParameter('cost')); - if ($user->isPluginEnabled('ps')) - $cl_paid = $request->getParameter('paid'); -} else { - $cl_date = $item_date->toString($user->getDateFormat()); - $cl_client = $expense_item['client_id']; - $cl_project = $expense_item['project_id']; - $cl_item_name = $expense_item['name']; - $cl_cost = $expense_item['cost']; - $cl_paid = $expense_item['paid']; -} - -// Initialize elements of 'expenseItemForm'. -$form = new Form('expenseItemForm'); - -// Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $trackingMode && $user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -if ($show_project) { - // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} -// If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); -if ($predefined_expenses) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'recalculateCost();', - 'name'=>'predefined_expense', - 'style'=>'width: 250px;', - 'value'=>$cl_predefined_expense, - 'data'=>$predefined_expenses, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); -} -$form->addInput(array('type'=>'textarea','maxlength'=>'800','name'=>'item_name','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_item_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); -if ($user->can('manage_invoices') && $user->isPluginEnabled('ps')) - $form->addInput(array('type'=>'checkbox','name'=>'paid','value'=>$cl_paid)); -$form->addInput(array('type'=>'datefield','name'=>'date','maxlength'=>'20','value'=>$cl_date)); -// Hidden control for record id. -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -$on_click_action = 'browser_today.value=get_date();'; -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>$on_click_action,'value'=>$i18n->get('button.copy'))); -if ($confirm_save) $on_click_action .= 'return(confirmSave());'; -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>$on_click_action,'value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - // Validate user input. - if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - if ($show_project && !$cl_project) - $err->add($i18n->get('error.project')); - if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); - if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); - - // This is a new date for the expense item. - $new_date = new DateAndTime($user->getDateFormat(), $cl_date); - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($new_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating user input. - - // Save record. - if ($request->getParameter('btn_save')) { - // We need to: - // 1) Prohibit updating locked entries (that are in locked range). - // 2) Prohibit saving unlocked entries into locked range. - - // Now, step by step. - // 1) Prohibit saving locked entries in any form. - if ($user->isDateLocked($item_date)) - $err->add($i18n->get('error.range_locked')); - - // 2) Prohibit saving unlocked entries into locked range. - if ($err->no() && $user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // Now, an update. - if ($err->no()) { - if (ttExpenseHelper::update(array('id'=>$cl_id,'date'=>$new_date->toString(DB_DATEFORMAT), - 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'paid'=>$cl_paid))) { - header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } - } - } - - // Save as new record. - if ($request->getParameter('btn_copy')) { - // We need to prohibit saving into locked interval. - if ($user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // Now, a new insert. - if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'client_id'=>$cl_client, - 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { - header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } - - if ($request->getParameter('btn_delete')) { - header("Location: expense_delete.php?id=$cl_id"); - exit(); - } -} // isPost - -if ($confirm_save) { - $smarty->assign('confirm_save', true); - $smarty->assign('entry_date', $cl_date); -} -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_project', $show_project); -$smarty->assign('predefined_expenses', $predefined_expenses); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('title', $i18n->get('title.edit_expense')); -$smarty->assign('content_page_name', 'expense_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/expenses1.php b/expenses1.php deleted file mode 100644 index cd930a8b8..000000000 --- a/expenses1.php +++ /dev/null @@ -1,251 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!$user->exists()) { - header('Location: access_denied.php'); // Nobody to enter expenses for. - exit(); -} -if ($user->behalf_id && (!$user->can('track_expenses') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('track_own_expenses') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. - exit(); -} -if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid($request->getParameter('user'))) { - header('Location: access_denied.php'); // Wrong user id on post. - exit(); - } -} -// End of access checks. - -// Determine user for which we display this page. -$userChanged = $request->getParameter('user_changed'); -if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; - -$tracking_mode = $user->getTrackingMode(); -$show_project = MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode; -$showFiles = $user->isPluginEnabled('at'); - -// Initialize variables. -$cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); -$_SESSION['client'] = $cl_client; -$cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); -$_SESSION['project'] = $cl_project; -$cl_item_name = $request->getParameter('item_name'); -$cl_cost = $request->getParameter('cost'); - -// Elements of expensesForm. -$form = new Form('expensesForm'); - -if ($user->can('track_expenses')) { - $rank = $user->getMaxRankForGroup($user->getGroup()); - if ($user->can('track_own_expenses')) - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); - if (count($user_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.user_changed.value=1;this.form.submit();', - 'name'=>'user', - 'style'=>'width: 250px;', - 'value'=>$user_id, - 'data'=>$user_list, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $smarty->assign('user_dropdown', 1); - } -} - -// Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -if ($show_project) { - // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} -// If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); -if ($predefined_expenses) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'recalculateCost();', - 'name'=>'predefined_expense', - 'style'=>'width: 250px;', - 'value'=>$cl_predefined_expense, - 'data'=>$predefined_expenses, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); -} -$form->addInput(array('type'=>'textarea','maxlength'=>'800','name'=>'item_name','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_item_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); -if ($showFiles) - $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); -$form->addInput(array('type'=>'calendar','name'=>'date','highlight'=>'expenses','value'=>$cl_date)); // calendar -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); - -// Submit. -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - // Validate user input. - if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - if ($show_project && !$cl_project) - $err->add($i18n->get('error.project')); - if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating input data. - - // Prohibit creating entries in locked range. - if ($user->isDateLocked($selected_date)) - $err->add($i18n->get('error.range_locked')); - - // Insert record. - if ($err->no()) { - $id = ttExpenseHelper::insert(array('date'=>$cl_date,'client_id'=>$cl_client, - 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1)); - - // Put a new file in storage if we have it. - if ($id && $showFiles && $_FILES['newfile']['name']) { - $fileHelper = new ttFileHelper($err); - $fields = array('entity_type'=>'expense', - 'entity_id' => $id, - 'file_name' => $_FILES['newfile']['name']); - $fileHelper->putFile($fields); - } - - if ($id) { - header('Location: expenses.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } -} - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_project', $show_project); -$smarty->assign('show_files', $showFiles); -$smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); -$smarty->assign('expense_items', ttExpenseHelper::getItems($cl_date, $showFiles)); -$smarty->assign('predefined_expenses', $predefined_expenses); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); -$smarty->assign('title', $i18n->get('title.expenses')); -$smarty->assign('content_page_name', 'expenses.tpl'); -$smarty->display('index.tpl'); diff --git a/initialize.php b/initialize.php index 2978e7a1b..f176802f5 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5401"); +define("APP_VERSION", "1.19.23.5402"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/project_add1.php b/project_add1.php deleted file mode 100644 index 5768d5fb5..000000000 --- a/project_add1.php +++ /dev/null @@ -1,118 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$showFiles = $user->isPluginEnabled('at'); -$users = ttGroupHelper::getActiveUsers(); -foreach ($users as $user_item) - $all_users[$user_item['id']] = $user_item['name']; - -$tasks = ttGroupHelper::getActiveTasks(); -foreach ($tasks as $task_item) - $all_tasks[$task_item['id']] = $task_item['name']; -$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('project_name')); - $cl_description = trim($request->getParameter('description')); - $cl_users = $request->getParameter('users', array()); - $cl_tasks = $request->getParameter('tasks', array()); -} else { - foreach ($users as $user_item) - $cl_users[] = $user_item['id']; - foreach ($tasks as $task_item) - $cl_tasks[] = $task_item['id']; -} - -$form = new Form('projectForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -if ($showFiles) - $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); -$form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if ($show_tasks) - $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); - - if ($err->no()) { - if (!ttProjectHelper::getProjectByName($cl_name)) { - $id = ttProjectHelper::insert(array('name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE)); - - // Put a new file in storage if we have it. - if ($id && $showFiles && $_FILES['newfile']['name']) { - $fileHelper = new ttFileHelper($err); - $fields = array('entity_type'=>'project', - 'entity_id' => $id, - 'file_name' => $_FILES['newfile']['name']); - $fileHelper->putFile($fields); - } - if ($id) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('show_files', $showFiles); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', $show_tasks); -$smarty->assign('title', $i18n->get('title.add_project')); -$smarty->assign('content_page_name', 'project_add.tpl'); -$smarty->display('index.tpl'); diff --git a/project_edit1.php b/project_edit1.php deleted file mode 100644 index e1792e48c..000000000 --- a/project_edit1.php +++ /dev/null @@ -1,136 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_project_id = (int)$request->getParameter('id'); -$project = ttProjectHelper::get($cl_project_id); -if (!$project) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$users = ttGroupHelper::getActiveUsers(); -foreach ($users as $user_item) - $all_users[$user_item['id']] = $user_item['name']; - -$tasks = ttGroupHelper::getActiveTasks(); -foreach ($tasks as $task_item) - $all_tasks[$task_item['id']] = $task_item['name']; -$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('project_name')); - $cl_description = trim($request->getParameter('description')); - $cl_status = $request->getParameter('status'); - $cl_users = $request->getParameter('users', array()); - $cl_tasks = $request->getParameter('tasks', array()); -} else { - $cl_name = $project['name']; - $cl_description = $project['description']; - $cl_status = $project['status']; - $cl_users = ttProjectHelper::getAssignedUsers($cl_project_id); - $cl_tasks = explode(',', $project['tasks']); -} - -$form = new Form('projectForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if ($show_tasks) - $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $existing_project = ttProjectHelper::getProjectByName($cl_name); - if (!$existing_project || ($cl_project_id == $existing_project['id'])) { - // Update project information. - if (ttProjectHelper::update(array( - 'id' => $cl_project_id, - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'users' => $cl_users, - 'tasks' => $cl_tasks))) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array('name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE))) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', $show_tasks); -$smarty->assign('title', $i18n->get('title.edit_project')); -$smarty->assign('content_page_name', 'project_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/projects1.php b/projects1.php deleted file mode 100644 index 0075c038f..000000000 --- a/projects1.php +++ /dev/null @@ -1,58 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$showFiles = $user->isPluginEnabled('at'); - -if($user->can('manage_projects')) { - $active_projects = ttGroupHelper::getActiveProjects($showFiles); - $inactive_projects = ttGroupHelper::getInactiveProjects($showFiles); -} else { - $options['include_files'] = $showFiles; - $active_projects = $user->getAssignedProjects($options); -} - -$smarty->assign('active_projects', $active_projects); -$smarty->assign('inactive_projects', $inactive_projects); -$smarty->assign('show_files', $showFiles); -$smarty->assign('title', $i18n->get('title.projects')); -$smarty->assign('content_page_name', 'projects.tpl'); -$smarty->display('index.tpl'); diff --git a/task_add1.php b/task_add1.php deleted file mode 100644 index 078bd5ca1..000000000 --- a/task_add1.php +++ /dev/null @@ -1,89 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_description = trim($request->getParameter('description')); - $cl_projects = $request->getParameter('projects'); -} else { - foreach ($projects as $project_item) - $cl_projects[] = $project_item['id']; -} - -$form = new Form('taskForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - - if ($err->no()) { - if (!ttTaskHelper::getTaskByName($cl_name)) { - if (ttTaskHelper::insert(array( - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => ACTIVE, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', count($projects) > 0); -$smarty->assign('onload', 'onLoad="document.taskForm.name.focus()"'); -$smarty->assign('title', $i18n->get('title.add_task')); -$smarty->assign('content_page_name', 'task_add.tpl'); -$smarty->display('index.tpl'); diff --git a/task_edit1.php b/task_edit1.php deleted file mode 100644 index 10410c4b3..000000000 --- a/task_edit1.php +++ /dev/null @@ -1,122 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_task_id = (int)$request->getParameter('id'); -$task = ttTaskHelper::get($cl_task_id); -if (!$task) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_description = trim($request->getParameter('description')); - $cl_status = $request->getParameter('status'); - $cl_projects = $request->getParameter('projects'); -} else { - $cl_name = $task['name']; - $cl_description = $task['description']; - $cl_status = $task['status']; - $assigned_projects = ttTaskHelper::getAssignedProjects($cl_task_id); - foreach ($assigned_projects as $project_item) - $cl_projects[] = $project_item['id']; -} - -$form = new Form('taskForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_task_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $existing_task = ttTaskHelper::getTaskByName($cl_name); - if (!$existing_task || ($cl_task_id == $existing_task['id'])) { - // Update task information. - if (ttTaskHelper::update(array( - 'task_id' => $cl_task_id, - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttTaskHelper::getTaskByName($cl_name)) { - if (ttTaskHelper::insert(array( - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', count($projects) > 0); -$smarty->assign('title', $i18n->get('title.edit_task')); -$smarty->assign('content_page_name', 'task_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/tasks1.php b/tasks1.php deleted file mode 100644 index 2e13ead5c..000000000 --- a/tasks1.php +++ /dev/null @@ -1,77 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$config = $user->getConfigHelper(); - -if ($request->isPost()) { - $cl_task_required = $request->getParameter('task_required'); -} else { - $cl_task_required = $config->getDefinedValue('task_required'); -} - -if($user->can('manage_tasks')) { - $active_tasks = ttGroupHelper::getActiveTasks(); - $inactive_tasks = ttGroupHelper::getInactiveTasks(); -} else - $active_tasks = $user->getAssignedTasks(); - -$form = new Form('tasksForm'); -$form->addInput(array('type'=>'checkbox','name'=>'task_required','value'=>$cl_task_required)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_save')) { - // Save button clicked. Update config. - $config->setDefinedValue('task_required', $cl_task_required); - if (!$user->updateGroup(array('config' => $config->getConfig()))) { - $err->add($i18n->get('error.db')); - } - } -} - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('active_tasks', $active_tasks); -$smarty->assign('inactive_tasks', $inactive_tasks); -$smarty->assign('title', $i18n->get('title.tasks')); -$smarty->assign('content_page_name', 'tasks.tpl'); -$smarty->display('index.tpl'); diff --git a/time1.php b/time1.php deleted file mode 100644 index b249f05b7..000000000 --- a/time1.php +++ /dev/null @@ -1,506 +0,0 @@ -behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. - exit(); -} -if ($request->isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { - header('Location: access_denied.php'); // User changed, but no right or wrong user id. - exit(); - } -} -// End of access checks. - -// Determine user for whom we display this page. -if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -$group_id = $user->getGroup(); -$config = new ttConfigHelper($user->getConfig()); - -$showClient = $user->isPluginEnabled('cl'); -$showBillable = $user->isPluginEnabled('iv'); -$trackingMode = $user->getTrackingMode(); -$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; -$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; -if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); -$recordType = $user->getRecordType(); -$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; -$showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; -$showFiles = $user->isPluginEnabled('at'); -$showRecordCustomFields = $user->isOptionEnabled('record_custom_fields'); - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -$showNoteColumn = !$config->getDefinedValue('time_note_on_separate_row'); -$showNoteRow = $config->getDefinedValue('time_note_on_separate_row'); -if ($showNoteRow) { - // Determine column span for note field. - $colspan = 0; - if ($showClient) $colspan++; - if ($showRecordCustomFields && $custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $colspan++; - } - } - if ($showProject) $colspan++; - if ($showTask) $colspan++; - if ($showStart) $colspan++; - if ($showFinish) $colspan++; - $colspan++; // There is always a duration. - if ($showFiles) $colspan++; - $colspan++; // There is always an edit column. - // $colspan++; // There is always a delete column. - // $colspan--; // Remove one column for label. - $smarty->assign('colspan', $colspan); -} - -if ($user->isPluginEnabled('mq')){ - require_once('plugins/MonthlyQuota.class.php'); - $quota = new MonthlyQuota(); - $month_quota_minutes = $quota->getUserQuota($selected_date->mYear, $selected_date->mMonth); - $quota_minutes_from_1st = $quota->getUserQuotaFrom1st($selected_date); - $month_total = ttTimeHelper::getTimeForMonth($selected_date); - $month_total_minutes = ttTimeHelper::toMinutes($month_total); - $balance_left = $quota_minutes_from_1st - $month_total_minutes; - $minutes_left = $month_quota_minutes - $month_total_minutes; - - $smarty->assign('month_total', $month_total); - $smarty->assign('month_quota', ttTimeHelper::toAbsDuration($month_quota_minutes)); - $smarty->assign('over_balance', $balance_left < 0); - $smarty->assign('balance_remaining', ttTimeHelper::toAbsDuration($balance_left)); - $smarty->assign('over_quota', $minutes_left < 0); - $smarty->assign('quota_remaining', ttTimeHelper::toAbsDuration($minutes_left)); -} - -// Initialize variables. -$cl_start = trim($request->getParameter('start')); -$cl_finish = trim($request->getParameter('finish')); -$cl_duration = trim($request->getParameter('duration')); -$cl_note = trim($request->getParameter('note')); -$cl_billable = 1; -if ($showBillable) { - if ($request->isPost()) { - $cl_billable = $request->getParameter('billable'); - $_SESSION['billable'] = (int) $cl_billable; - } else - if (isset($_SESSION['billable'])) - $cl_billable = $_SESSION['billable']; -} -$cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); -$_SESSION['client'] = $cl_client; -$cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); -$_SESSION['project'] = $cl_project; -$cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); -$_SESSION['task'] = $cl_task; - -// Handle time custom fields. -$timeCustomFields = array(); -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); - $_SESSION[$control_name] = $cl_control_name; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($cl_control_name)); - } -} - -// Elements of timeRecordForm. -$form = new Form('timeRecordForm'); - -// Dropdown for user and a hidden control to indicate user change. -if ($user->can('track_time')) { - $rank = $user->getMaxRankForGroup($group_id); - if ($user->can('track_own_time')) - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); - if (count($user_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'document.timeRecordForm.user_changed.value=1;document.timeRecordForm.submit();', - 'name'=>'user', - 'style'=>'width: 250px;', - 'value'=>$user_id, - 'data'=>$user_list, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $smarty->assign('user_dropdown', 1); - } -} - -// Dropdown for clients in MODE_TIME. Use all active clients. -// Note: for other tracking modes the control is added further below. -if (MODE_TIME == $trackingMode && $showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -// Billable checkbox. -if ($showBillable) - $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); - -// If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($timeField['id']), - 'value'=>$timeCustomFields[$timeField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -// If we show project dropdown, add controls for project and client. -if ($showProject) { - // Dropdown for projects assigned to user. - $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); - $project_list = $user->getAssignedProjects($options); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);prepopulateNote();', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Client dropdown. - if ($showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - if (is_array($projects_assigned_to_client) && is_array($projects_assigned_to_user)) - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} - -// Task dropdown. -if ($showTask) { - $task_list = ttGroupHelper::getActiveTasks(); - $form->addInput(array('type'=>'combobox', - 'name'=>'task', - 'style'=>'width: 250px;', - 'value'=>$cl_task, - 'data'=>$task_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); -} - -// Start and finish controls. -if ($showStart) { - $form->addInput(array('type'=>'text','name'=>'start','value'=>$cl_start,'onchange'=>"formDisable('start');")); - $form->addInput(array('type'=>'text','name'=>'finish','value'=>$cl_finish,'onchange'=>"formDisable('finish');")); - if ($user->punch_mode && !$user->canOverridePunchMode()) { - // Make the start and finish fields read-only. - $form->getElement('start')->setEnabled(false); - $form->getElement('finish')->setEnabled(false); - } -} - -// Duration control. -if ($showDuration) - $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); - -// File upload control. -if ($showFiles) - $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); - -// If we have templates, add a dropdown to select one. -if ($user->isPluginEnabled('tp')){ - $template_list = ttGroupHelper::getActiveTemplates(); - if (count($template_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillNote(this.value);', - 'name'=>'template', - 'style'=>'width: 250px;', - 'data'=>$template_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $smarty->assign('template_dropdown', 1); - $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); - $smarty->assign('prepopulate_note', $config->getDefinedValue('prepopulate_note')); - $smarty->assign('template_list', $template_list); - } -} - -// Note control. -if (!defined('NOTE_INPUT_HEIGHT')) - define('NOTE_INPUT_HEIGHT', 40); -$form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 600px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_note)); - -// Calendar. -$form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar - -// A hidden control for today's date from user's browser. -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. - -// Submit button. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - // Submit button clicked. - // Validate user input. - if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - // Validate input in time custom fields. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($timeCustomFields as $timeField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); - } - } - if ($showProject) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } - if ($showTask && $taskRequired) { - if (!$cl_task) $err->add($i18n->get('error.task')); - } - if (strlen($cl_duration) == 0) { - if ($cl_start || $cl_finish) { - if (!ttTimeHelper::isValidTime($cl_start)) - $err->add($i18n->get('error.field'), $i18n->get('label.start')); - if ($cl_finish) { - if (!ttTimeHelper::isValidTime($cl_finish)) - $err->add($i18n->get('error.field'), $i18n->get('label.finish')); - if (!ttTimeHelper::isValidInterval($cl_start, $cl_finish)) - $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); - } - } else { - if ($showStart) { - $err->add($i18n->get('error.empty'), $i18n->get('label.start')); - $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); - } - if ($showDuration) - $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); - } - } else { - if (false === ttTimeHelper::postedDurationToMinutes($cl_duration)) - $err->add($i18n->get('error.field'), $i18n->get('label.duration')); - } - if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); - if ($user->isPluginEnabled('tp') && !ttValidTemplateText($cl_note)) { - $err->add($i18n->get('error.field'), $i18n->get('label.note')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating user input. - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - - // Prohibit creating entries in locked range. - if ($user->isDateLocked($selected_date)) - $err->add($i18n->get('error.range_locked')); - - // Prohibit creating another uncompleted record. - if ($err->no()) { - if (($not_completed_rec = ttTimeHelper::getUncompleted($user_id)) && (($cl_finish == '') && ($cl_duration == ''))) - $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); - } - - // Prohibit creating an overlapping record. - if ($err->no()) { - if (ttTimeHelper::overlaps($user_id, $cl_date, $cl_start, $cl_finish)) - $err->add($i18n->get('error.overlap')); - } - - // Insert record. - if ($err->no()) { - $id = ttTimeHelper::insert(array( - 'date' => $cl_date, - 'client' => $cl_client, - 'project' => $cl_project, - 'task' => $cl_task, - 'start' => $cl_start, - 'finish' => $cl_finish, - 'duration' => $cl_duration, - 'note' => $cl_note, - 'billable' => $cl_billable)); - - // Insert time custom fields if we have them. - $result = true; - if ($id && $custom_fields && $custom_fields->timeFields) { - $result = $custom_fields->insertTimeFields($id, $timeCustomFields); - } - - // Put a new file in storage if we have it. - if ($id && $showFiles && $_FILES['newfile']['name']) { - $fileHelper = new ttFileHelper($err); - $fields = array('entity_type'=>'time', - 'entity_id' => $id, - 'file_name' => $_FILES['newfile']['name']); - $fileHelper->putFile($fields); - } - - if ($id && $result && $err->no()) { - header('Location: time.php'); - exit(); - } - $err->add($i18n->get('error.db')); - } - } elseif ($request->getParameter('btn_stop')) { - // Stop button pressed to finish an uncompleted record. - $record_id = $request->getParameter('record_id'); - $record = ttTimeHelper::getRecord($record_id); - $browser_date = $request->getParameter('browser_date'); - $browser_time = $request->getParameter('browser_time'); - - // Can we complete this record? - if ($record['date'] == $browser_date // closing today's record - && ttTimeHelper::isValidInterval($record['start'], $browser_time) // finish time is greater than start time - && !ttTimeHelper::overlaps($user_id, $browser_date, $record['start'], $browser_time)) { // no overlap - $res = ttTimeHelper::update(array( - 'id'=>$record['id'], - 'date'=>$record['date'], - 'client'=>$record['client_id'], - 'project'=>$record['project_id'], - 'task'=>$record['task_id'], - 'start'=>$record['start'], - 'finish'=>$browser_time, - 'note'=>$record['comment'], - 'billable'=>$record['billable'])); - if (!$res) - $err->add($i18n->get('error.db')); - } else { - // Cannot complete, redirect for manual edit. - header('Location: time_edit.php?id='.$record_id); - exit(); - } - } -} // isPost - -$week_total = ttTimeHelper::getTimeForWeek($selected_date); -$timeRecords = ttTimeHelper::getRecords($cl_date, $showFiles); - -$smarty->assign('selected_date', $selected_date); -$smarty->assign('week_total', $week_total); -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); -$smarty->assign('time_records', $timeRecords); -$smarty->assign('show_record_custom_fields', $showRecordCustomFields); -$smarty->assign('show_navigation', $user->isPluginEnabled('wv') && !$user->isOptionEnabled('week_menu')); -$smarty->assign('show_client', $showClient); -$smarty->assign('show_billable', $showBillable); -$smarty->assign('show_project', $showProject); -$smarty->assign('show_task', $showTask); -$smarty->assign('task_required', $taskRequired); -$smarty->assign('show_start', $showStart); -$smarty->assign('show_duration', $showDuration); -$smarty->assign('show_note_column', $showNoteColumn); -$smarty->assign('show_note_row', $showNoteRow); -$smarty->assign('show_files', $showFiles); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="fillDropdowns();prepopulateNote();"'); -$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); -$smarty->assign('title', $i18n->get('title.time')); -$smarty->assign('content_page_name', 'time.tpl'); -$smarty->display('index.tpl'); diff --git a/user_add1.php b/user_add1.php deleted file mode 100644 index b7c2bc7a6..000000000 --- a/user_add1.php +++ /dev/null @@ -1,244 +0,0 @@ -isPluginEnabled('mq'); -if ($user->isPluginEnabled('cl')) - $clients = ttGroupHelper::getActiveClients(); - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -$assigned_projects = array(); -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_login = trim($request->getParameter('login')); - if (!$auth->isPasswordExternal()) { - $cl_password1 = $request->getParameter('pas1'); - $cl_password2 = $request->getParameter('pas2'); - } - $cl_email = trim($request->getParameter('email')); - $cl_role_id = $request->getParameter('role'); - $cl_client_id = $request->getParameter('client'); - $cl_quota_percent = $request->getParameter('quota_percent'); - // If we have user custom fields - collect input. - if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $control_name = 'user_field_'.$userField['id']; - $userCustomFields[$userField['id']] = array('field_id' => $userField['id'], - 'control_name' => $control_name, - 'label' => $userField['label'], - 'type' => $userField['type'], - 'required' => $userField['required'], - 'value' => trim($request->getParameter($control_name))); - } - } - $cl_rate = $request->getParameter('rate'); - $cl_projects = $request->getParameter('projects'); - if (is_array($cl_projects)) { - foreach ($cl_projects as $p) { - if (ttValidFloat($request->getParameter('rate_'.$p), true)) { - $project_with_rate = array(); - $project_with_rate['id'] = $p; - $project_with_rate['rate'] = $request->getParameter('rate_'.$p); - $assigned_projects[] = $project_with_rate; - } else - $err->add($i18n->get('error.field'), 'rate_'.$p); - } - } -} - -$form = new Form('userForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 300px;','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','style'=>'width: 300px;','value'=>$cl_login)); -if (!$auth->isPasswordExternal()) { - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas1','value'=>$cl_password1)); - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas2','value'=>$cl_password2)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email)); - -$active_roles = ttTeamHelper::getActiveRolesForUser(); -$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles,'datakeys'=>array('id', 'name'))); -if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); - -// If we have custom fields - add controls for them. -if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $field_name = 'user_field_'.$userField['id']; - if ($userField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$userCustomFields[$userField['id']]['value'])); - } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($userField['id']), - 'value'=>$userCustomFields[$userField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -if ($show_quota) - $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); - -$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); -if ($show_projects) { - $projects = ttGroupHelper::getActiveProjects(); - if (count($projects) == 0) $show_projects = false; -} - -// Define classes for the projects table. -class NameCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200)); - $this->setValue(''); - return $this->toString(); - } -} -class RateCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - global $assigned_projects; - $field = new FloatField('rate_'.$table->getValueAtName($row, 'id')); - $field->setFormName($table->getFormName()); - $field->setSize(5); - $field->setFormat('.2'); - foreach ($assigned_projects as $p) { - if ($p['id'] == $table->getValueAtName($row,'id')) $field->setValue($p['rate']); - } - $this->setValue($field->getHtml()); - return $this->toString(); - } -} -// Create projects table. -$table = new Table('projects'); -$table->setIAScript('setDefaultRate'); -$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); -$table->setData($projects); -$table->setKeyField('id'); -$table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); -$form->addInputElement($table); - -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); - if (!$auth->isPasswordExternal()) { - if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); - } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - // Require selection of a client for a client role. - if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); - // Validate input in user custom fields. - if ($custom_fields && $custom_fields->userFields) { - foreach ($userCustomFields as $userField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($userField['value'], !$userField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($userField['label'])); - } - } - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - if (!ttUserHelper::canAdd()) $err->add($i18n->get('error.user_count')); - - if ($err->no()) { - if (!ttUserHelper::getUserByLogin($cl_login)) { - $fields = array( - 'name' => $cl_name, - 'login' => $cl_login, - 'password' => $cl_password1, - 'rate' => $cl_rate, - 'quota_percent' => $cl_quota_percent, - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'role_id' => $cl_role_id, - 'client_id' => $cl_client_id, - 'projects' => $assigned_projects, - 'email' => $cl_email); - $user_id = ttUserHelper::insert($fields); - - // Insert user custom fields if we have them. - $result = true; - if ($user_id && $custom_fields && $custom_fields->userFields) { - $result = $custom_fields->insertEntityFields(CustomFields::ENTITY_USER, $user_id, $userCustomFields); - } - - if ($user_id && $result) { - if (!$user->exists()) { - // We added a user to an empty subgroup. Set new user as on behalf user. - // Needed for user-based things to work (such as notifications config). - $user->setOnBehalfUser($user_id); - } - header('Location: users.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.user_exists')); - } -} // isPost - -$smarty->assign('auth_external', $auth->isPasswordExternal()); -$smarty->assign('active_roles', $active_roles); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); -$smarty->assign('show_quota', $show_quota); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('title', $i18n->get('title.add_user')); -$smarty->assign('content_page_name', 'user_add.tpl'); -$smarty->display('index.tpl'); diff --git a/user_edit1.php b/user_edit1.php deleted file mode 100644 index d74ae2785..000000000 --- a/user_edit1.php +++ /dev/null @@ -1,308 +0,0 @@ -getParameter('id'); -$user_details = $user->getUserDetails($user_id); -if (!$user_details) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$show_quota = $user->isPluginEnabled('mq'); -if ($user->isPluginEnabled('cl')) - $clients = ttGroupHelper::getActiveClients(); - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); -if ($show_projects) { - $projects = ttGroupHelper::getActiveProjects(); - if (count($projects) == 0) $show_projects = false; -} -$assigned_projects = array(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_login = trim($request->getParameter('login')); - if (!$auth->isPasswordExternal()) { - $cl_password1 = $request->getParameter('pas1'); - $cl_password2 = $request->getParameter('pas2'); - } - $cl_email = trim($request->getParameter('email')); - $cl_role_id = $request->getParameter('role'); - $cl_client_id = $request->getParameter('client'); - $cl_status = $request->getParameter('status'); - $cl_quota_percent = $request->getParameter('quota_percent'); - // If we have user custom fields - collect input. - if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $control_name = 'user_field_'.$userField['id']; - $userCustomFields[$userField['id']] = array('field_id' => $userField['id'], - 'control_name' => $control_name, - 'label' => $userField['label'], - 'type' => $userField['type'], - 'required' => $userField['required'], - 'value' => trim($request->getParameter($control_name))); - } - } - $cl_rate = $request->getParameter('rate'); - $cl_projects = $request->getParameter('projects'); - if (is_array($cl_projects)) { - foreach ($cl_projects as $p) { - if (ttValidFloat($request->getParameter('rate_'.$p), true)) { - $project_with_rate = array(); - $project_with_rate['id'] = $p; - $project_with_rate['rate'] = $request->getParameter('rate_'.$p); - $assigned_projects[] = $project_with_rate; - } else - $err->add($i18n->get('error.field'), 'rate_'.$p); - } - } -} else { - $cl_name = $user_details['name']; - $cl_login = $user_details['login']; - $cl_email = $user_details['email']; - $cl_quota_percent = str_replace('.', $user->getDecimalMark(), $user_details['quota_percent']); - // If we have user custom fields - collect values from database. - if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $control_name = 'user_field_'.$userField['id']; - $userCustomFields[$userField['id']] = array('field_id' => $userField['id'], - 'control_name' => $control_name, - 'label' => $userField['label'], - 'type' => $userField['type'], - 'required' => $userField['required'], - 'value' => $custom_fields->getEntityFieldValue(CustomFields::ENTITY_USER, $user_id, $userField['id'], $userField['type'])); - } - } - $cl_rate = str_replace('.', $user->getDecimalMark(), $user_details['rate']); - $cl_role_id = $user_details['role_id']; - $cl_client_id = $user_details['client_id']; - $cl_status = $user_details['status']; - $cl_projects = array(); - $assigned_projects = ttProjectHelper::getAssignedProjects($user_id); - foreach($assigned_projects as $p) { - $cl_projects[] = $p['id']; - } -} - -$form = new Form('userForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 300px;','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','style'=>'width: 300px;','value'=>$cl_login)); -if (!$auth->isPasswordExternal()) { - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas1','value'=>$cl_password1)); - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas2','value'=>$cl_password2)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','style'=>'width: 300px;','value'=>$cl_email)); - -$active_roles = ttTeamHelper::getActiveRolesForUser(); -$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles, 'datakeys'=>array('id', 'name'))); -if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); - -// If we have custom fields - add controls for them. -if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $field_name = 'user_field_'.$userField['id']; - if ($userField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$userCustomFields[$userField['id']]['value'])); - } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($userField['id']), - 'value'=>$userCustomFields[$userField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -if ($show_quota) - $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); - -// Define classes for the projects table. -class NameCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200)); - $this->setValue(''); - return $this->toString(); - } -} -class RateCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - global $assigned_projects; - - $field = new FloatField('rate_'.$table->getValueAtName($row,'id')); - $field->setFormName($table->getFormName()); - $field->setSize(5); - $field->setFormat('.2'); - foreach ($assigned_projects as $p) { - if ($p['id'] == $table->getValueAtName($row,'id')) $field->setValue($p['rate']); - } - $this->setValue($field->getHtml()); - return $this->toString(); - } -} -// Create projects table. -$table = new Table('projects'); -$table->setIAScript('setRate'); -$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); -$table->setData($projects); -$table->setKeyField('id'); -$table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); -$form->addInputElement($table); - -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$user_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.save'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); - if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { - if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); - } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - // Require selection of a client for a client role. - if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); - // Validate input in user custom fields. - if ($custom_fields && $custom_fields->userFields) { - foreach ($userCustomFields as $userField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($userField['value'], !$userField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($userField['label'])); - } - } - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - - if ($err->no()) { - $existing_user = ttUserHelper::getUserByLogin($cl_login); - if (!$existing_user || ($user_id == $existing_user['id'])) { - - $fields = array( - 'name' => $cl_name, - 'login' => $cl_login, - 'password' => $cl_password1, - 'email' => $cl_email, - 'status' => $cl_status, - 'rate' => $cl_rate, - 'quota_percent' => $cl_quota_percent, - 'projects' => $assigned_projects); - if (in_array('manage_users', $user->rights) && $cl_role_id) { - $fields['role_id'] = $cl_role_id; - $fields['client_id'] = $cl_client_id; - } - - $result = ttUserHelper::update($user_id, $fields); - // Update user custom fields if we have them. - if ($result && $custom_fields && $custom_fields->userFields) { - $result = $custom_fields->updateEntityFields(CustomFields::ENTITY_USER, $user_id, $userCustomFields); - } - - if ($result) { - // If our own login changed, set new one in cookie to remember it. - if (($user_id == $user->id) && ($user->login != $cl_login)) { - setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); - } - - // In case the name of the "on behalf" user has changed - set it in session. - if (($user->behalf_id == $user_id) && ($user->behalf_name != $cl_name)) { - $_SESSION['behalf_name'] = $cl_name; - } - - // If we deactivated our own account, do housekeeping and logout. - if ($user->id == $user_id && !is_null($cl_status) && $cl_status == INACTIVE) { - // Remove LOGIN_COOKIE_NAME cookie that stores login name. - unset($_COOKIE[LOGIN_COOKIE_NAME]); - setcookie(LOGIN_COOKIE_NAME, NULL, -1); - - $auth->doLogout(); - header('Location: login.php'); - exit(); - } - - header('Location: users.php'); - exit(); - - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.user_exists')); - } -} // isPost - -$can_swap = false; -if ($user->id == $user_id && $user->can('swap_roles')) { - $users_for_swap = ttTeamHelper::getUsersForSwap(); - if (is_array($users_for_swap) && sizeof($users_for_swap) > 0) - $can_swap = true; -} - -$rates = ttProjectHelper::getRates($user_id); -$smarty->assign('rates', $rates); - -$smarty->assign('auth_external', $auth->isPasswordExternal()); -$smarty->assign('active_roles', $active_roles); -$smarty->assign('can_swap', $can_swap); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); -$smarty->assign('show_quota', $show_quota); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('user_id', $user_id); -$smarty->assign('title', $i18n->get('title.edit_user')); -$smarty->assign('content_page_name', 'user_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/users1.php b/users1.php deleted file mode 100644 index 2fbcb5d20..000000000 --- a/users1.php +++ /dev/null @@ -1,69 +0,0 @@ -getMaxRankForGroup($user->getGroup()); -if ($user->can('view_users')) - $options = array('status'=>ACTIVE,'include_clients'=>true,'include_login'=>true,'include_role'=>true); -else /* if ($user->can('manage_users')) */ - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_self'=>true,'include_login'=>true,'include_role'=>true); -$active_users = $user->getUsers($options); - -// Prepare a list of inactive users. -if($user->can('manage_users')) { - $options = array('status'=>INACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_login'=>true,'include_role'=>true); - $inactive_users = $user->getUsers($options); -} - -$uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); -if ($uncompleted_indicators) { - // Check each active user if they have an uncompleted time entry. - foreach ($active_users as $key => $active_user) { - $active_users[$key]['has_uncompleted_entry'] = (bool) ttTimeHelper::getUncompleted($active_user['id']); - } - $smarty->assign('uncompleted_indicators', true); -} - -$smarty->assign('active_users', $active_users); -$smarty->assign('inactive_users', $inactive_users); -$smarty->assign('show_quota', $user->isPluginEnabled('mq')); -$smarty->assign('title', $i18n->get('title.users')); -$smarty->assign('content_page_name', 'users.tpl'); -$smarty->display('index.tpl'); From ba13f2e7523c2913c1af268ff85e3392657872f0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 18:27:09 +0000 Subject: [PATCH 1410/1848] Made file_edit.php page mobile-friendly. --- WEB-INF/templates/file_edit2.tpl | 22 ++++++ client_edit1.php | 131 ------------------------------- file_edit.php | 36 ++------- initialize.php | 2 +- 4 files changed, 29 insertions(+), 162 deletions(-) create mode 100644 WEB-INF/templates/file_edit2.tpl delete mode 100644 client_edit1.php diff --git a/WEB-INF/templates/file_edit2.tpl b/WEB-INF/templates/file_edit2.tpl new file mode 100644 index 000000000..66f72cc3d --- /dev/null +++ b/WEB-INF/templates/file_edit2.tpl @@ -0,0 +1,22 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.fileForm.open} +
{$totals[i].name|escape}
+ + + + + + + + + + + + + + +
{$forms.fileForm.file_name.control}
{$forms.fileForm.description.control}
{$i18n.label.required_fields}
+
{$forms.fileForm.btn_save.control}
+{$forms.fileForm.close} diff --git a/client_edit1.php b/client_edit1.php deleted file mode 100644 index 7b572ea7c..000000000 --- a/client_edit1.php +++ /dev/null @@ -1,131 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -$client = ttClientHelper::getClient($cl_id, true); -if (!$client) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_address = trim($request->getParameter('address')); - $cl_tax = trim($request->getParameter('tax')); - $cl_status = $request->getParameter('status'); - $cl_projects = $request->getParameter('projects'); -} else { - $cl_name = $client['name']; - $cl_address = $client['address']; - $cl_tax = $client['tax']; - $cl_status = $client['status']; - $assigned_projects = ttClientHelper::getAssignedProjects($cl_id); - foreach($assigned_projects as $project_item) { - $cl_projects[] = $project_item['id']; - } -} - -$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; - -$form = new Form('clientForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'text','name'=>'name','maxlength'=>'100','style'=>'width: 350px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','style'=>'width: 350px; height: 80px;','value'=>$cl_address)); -$form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -if ($show_projects) - $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'datakeys'=>array('id','name'),'layout'=>'H','value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $client = ttClientHelper::getClientByName($cl_name); - if (($client && ($cl_id == $client['id'])) || !$client) { - if (ttClientHelper::update(array( - 'id' => $cl_id, - 'name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array('name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('title', $i18n->get('title.edit_client')); -$smarty->assign('content_page_name', 'client_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/file_edit.php b/file_edit.php index d2c8f2990..745293c2e 100644 --- a/file_edit.php +++ b/file_edit.php @@ -1,30 +1,6 @@ addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_file_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'file_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'file_name','value'=>$cl_name)); $form->getElement('file_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { @@ -120,5 +96,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fileForm.description.focus()"'); $smarty->assign('title', $i18n->get('title.edit_file')); -$smarty->assign('content_page_name', 'file_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'file_edit2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index f176802f5..0a7d91412 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5402"); +define("APP_VERSION", "1.19.23.5403"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From b72b5fbd56be8cede708844df1fc9d19ce5e84d2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 19:46:03 +0000 Subject: [PATCH 1411/1848] Made file_delete.php mobile-friendly. --- WEB-INF/templates/file_delete2.tpl | 7 +++++++ file_delete.php | 32 ++++-------------------------- initialize.php | 2 +- 3 files changed, 12 insertions(+), 29 deletions(-) create mode 100644 WEB-INF/templates/file_delete2.tpl diff --git a/WEB-INF/templates/file_delete2.tpl b/WEB-INF/templates/file_delete2.tpl new file mode 100644 index 000000000..80abe01ce --- /dev/null +++ b/WEB-INF/templates/file_delete2.tpl @@ -0,0 +1,7 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.fileDeleteForm.open} +
{$file_to_delete|escape}
+
{$forms.fileDeleteForm.btn_delete.control} {$forms.fileDeleteForm.btn_cancel.control}
+{$forms.fileDeleteForm.close} diff --git a/file_delete.php b/file_delete.php index ff56f118b..1b415c19b 100644 --- a/file_delete.php +++ b/file_delete.php @@ -1,30 +1,6 @@ assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fileDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_file')); -$smarty->assign('content_page_name', 'file_delete.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'file_delete2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index 0a7d91412..a863d270f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5403"); +define("APP_VERSION", "1.19.23.5404"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 509a401638a0eaba661196cc38e0b3159e71db7c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 20:36:33 +0000 Subject: [PATCH 1412/1848] Cleanup: removed no longer used templates. --- WEB-INF/templates/charts.tpl | 37 ---- WEB-INF/templates/client_add.tpl | 37 ---- WEB-INF/templates/client_delete.tpl | 25 --- WEB-INF/templates/client_edit.tpl | 41 ----- WEB-INF/templates/clients.tpl | 74 -------- WEB-INF/templates/entity_files.tpl | 47 ------ WEB-INF/templates/expense_delete.tpl | 39 ----- WEB-INF/templates/expense_edit.tpl | 189 --------------------- WEB-INF/templates/expenses.tpl | 241 --------------------------- WEB-INF/templates/file_delete.tpl | 18 -- WEB-INF/templates/file_edit.tpl | 29 ---- WEB-INF/templates/project_add.tpl | 49 ------ WEB-INF/templates/project_delete.tpl | 18 -- WEB-INF/templates/project_edit.tpl | 47 ------ WEB-INF/templates/projects.tpl | 114 ------------- WEB-INF/templates/swap_roles.tpl | 15 -- WEB-INF/templates/task_add.tpl | 36 ---- WEB-INF/templates/task_delete.tpl | 20 --- WEB-INF/templates/task_edit.tpl | 40 ----- WEB-INF/templates/tasks.tpl | 96 ----------- WEB-INF/templates/time.tpl | 234 -------------------------- WEB-INF/templates/user_add.tpl | 134 --------------- WEB-INF/templates/user_delete.tpl | 20 --- WEB-INF/templates/user_edit.tpl | 168 ------------------- WEB-INF/templates/users.tpl | 121 -------------- expense_files.php | 34 +--- initialize.php | 2 +- project_files.php | 34 +--- timesheet_delete.php | 28 +--- timesheet_files.php | 34 +--- 30 files changed, 18 insertions(+), 2003 deletions(-) delete mode 100644 WEB-INF/templates/charts.tpl delete mode 100644 WEB-INF/templates/client_add.tpl delete mode 100644 WEB-INF/templates/client_delete.tpl delete mode 100644 WEB-INF/templates/client_edit.tpl delete mode 100644 WEB-INF/templates/clients.tpl delete mode 100644 WEB-INF/templates/entity_files.tpl delete mode 100644 WEB-INF/templates/expense_delete.tpl delete mode 100644 WEB-INF/templates/expense_edit.tpl delete mode 100644 WEB-INF/templates/expenses.tpl delete mode 100644 WEB-INF/templates/file_delete.tpl delete mode 100644 WEB-INF/templates/file_edit.tpl delete mode 100644 WEB-INF/templates/project_add.tpl delete mode 100644 WEB-INF/templates/project_delete.tpl delete mode 100644 WEB-INF/templates/project_edit.tpl delete mode 100644 WEB-INF/templates/projects.tpl delete mode 100644 WEB-INF/templates/swap_roles.tpl delete mode 100644 WEB-INF/templates/task_add.tpl delete mode 100644 WEB-INF/templates/task_delete.tpl delete mode 100644 WEB-INF/templates/task_edit.tpl delete mode 100644 WEB-INF/templates/tasks.tpl delete mode 100644 WEB-INF/templates/time.tpl delete mode 100644 WEB-INF/templates/user_add.tpl delete mode 100644 WEB-INF/templates/user_delete.tpl delete mode 100644 WEB-INF/templates/user_edit.tpl delete mode 100644 WEB-INF/templates/users.tpl diff --git a/WEB-INF/templates/charts.tpl b/WEB-INF/templates/charts.tpl deleted file mode 100644 index 8e05e1985..000000000 --- a/WEB-INF/templates/charts.tpl +++ /dev/null @@ -1,37 +0,0 @@ -

-{$forms.chartForm.open} - - -{if $user_dropdown} - - {if $chart_selector} - - {/if} -{else} - {if $chart_selector} - - {/if} -{/if} - - -
{$i18n.label.user}: {$forms.chartForm.user.control}{$i18n.form.charts.chart}: {$forms.chartForm.type.control}{$i18n.form.charts.chart}: {$forms.chartForm.type.control}
- - - - - -
- - {section name=i loop=$totals} - {if $smarty.section.i.index <= 12} - - {/if} - {/section} -
{$totals[i].name|escape}
-
-

- - - -
{$i18n.form.charts.interval}: {$forms.chartForm.interval.control}
{$forms.chartForm.date.control}
-{$forms.chartForm.close} diff --git a/WEB-INF/templates/client_add.tpl b/WEB-INF/templates/client_add.tpl deleted file mode 100644 index db10ede45..000000000 --- a/WEB-INF/templates/client_add.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{$forms.clientForm.open} - - - - -
- - - - - - - - - - - - - - - - - - -{if $show_projects} - - - - - -{/if} - - - -
{$i18n.label.client_name} (*):{$forms.clientForm.name.control}
{$i18n.label.client_address}:{$forms.clientForm.address.control}
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->getDecimalMark()}00)
{$i18n.label.required_fields}
 
{$i18n.label.projects}:{$forms.clientForm.projects.control}
 
{$forms.clientForm.btn_submit.control}
-
-{$forms.clientForm.close} diff --git a/WEB-INF/templates/client_delete.tpl b/WEB-INF/templates/client_delete.tpl deleted file mode 100644 index f40b94c12..000000000 --- a/WEB-INF/templates/client_delete.tpl +++ /dev/null @@ -1,25 +0,0 @@ -{$forms.clientDeleteForm.open} - - - - -
- - - - - - - - - - - - - - - - -
{$i18n.form.client.client_to_delete}:{$client_to_delete|escape}
{$i18n.form.client.client_entries}:{$forms.clientDeleteForm.delete_client_entries.control}
 
{$forms.clientDeleteForm.btn_delete.control}  {$forms.clientDeleteForm.btn_cancel.control}
-
-{$forms.clientDeleteForm.close} diff --git a/WEB-INF/templates/client_edit.tpl b/WEB-INF/templates/client_edit.tpl deleted file mode 100644 index 2abf70dc1..000000000 --- a/WEB-INF/templates/client_edit.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{$forms.clientForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - -{if $show_projects} - - - - -{/if} - - - - -
{$i18n.label.client_name} (*):{$forms.clientForm.name.control}
{$i18n.label.client_address}:{$forms.clientForm.address.control}
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->getDecimalMark()}00)
{$i18n.label.status}:{$forms.clientForm.status.control}
{$i18n.label.required_fields}
 
{$i18n.label.projects}:{$forms.clientForm.projects.control}
 
{$forms.clientForm.btn_save.control} {$forms.clientForm.btn_copy.control}
-
-{$forms.clientForm.close} diff --git a/WEB-INF/templates/clients.tpl b/WEB-INF/templates/clients.tpl deleted file mode 100644 index 07b835c87..000000000 --- a/WEB-INF/templates/clients.tpl +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - -
-{if $user->can('manage_clients')} - - {if $inactive_clients} - - {/if} - - - - - - - {foreach $active_clients as $client} - - - - - - - {/foreach} -
{$i18n.form.clients.active_clients}
{$i18n.label.person_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - -

- - {if $inactive_clients} - - - - - - - - - {foreach $inactive_clients as $client} - - - - - - - {/foreach} -
{$i18n.form.clients.inactive_clients}
{$i18n.label.person_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - -

- {/if} -{else} - - - - - - {if $active_clients} - {foreach $active_clients as $client} - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}
-{/if} -
diff --git a/WEB-INF/templates/entity_files.tpl b/WEB-INF/templates/entity_files.tpl deleted file mode 100644 index ab9564852..000000000 --- a/WEB-INF/templates/entity_files.tpl +++ /dev/null @@ -1,47 +0,0 @@ - - - - -
- - - - -{if $can_edit} - - -{/if} - -{if $files} - {foreach $files as $file} - - - - {if $can_edit} - - - {/if} - - {/foreach} -{/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$file.name|escape}{$file.description|escape}{$i18n.label.edit}{$i18n.label.delete}
-
- -{if $can_edit} -{$forms.fileUploadForm.open} - - - - -
- - - - - - - -
{$i18n.label.description}:{$forms.fileUploadForm.description.control}{$forms.fileUploadForm.newfile.control}
{$forms.fileUploadForm.btn_submit.control}
-
-{$forms.fileUploadForm.close} -{/if} diff --git a/WEB-INF/templates/expense_delete.tpl b/WEB-INF/templates/expense_delete.tpl deleted file mode 100644 index 6e5bf12c8..000000000 --- a/WEB-INF/templates/expense_delete.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{$forms.expenseItemForm.open} - - - - -
- - -{if $user->isPluginEnabled('cl')} - -{/if} - -{if $show_project} - -{/if} - - - - -{if $user->isPluginEnabled('cl')} - -{/if} -{if $show_project} - -{/if} - - - -
{$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$i18n.label.cost}
{$expense_item.client_name|escape}{$expense_item.project_name|escape}{$expense_item.name|escape}{$expense_item.cost}
- - - - - - - -
 
{$forms.expenseItemForm.delete_button.control}  {$forms.expenseItemForm.cancel_button.control}
-
-{$forms.expenseItemForm.close} diff --git a/WEB-INF/templates/expense_edit.tpl b/WEB-INF/templates/expense_edit.tpl deleted file mode 100644 index 671e868cf..000000000 --- a/WEB-INF/templates/expense_edit.tpl +++ /dev/null @@ -1,189 +0,0 @@ - - -{$forms.expenseItemForm.open} - - - - -
- - - - -
- -{if $user->isPluginEnabled('cl')} - - - - -{/if} -{if $show_project} - - - - -{/if} -{if $predefined_expenses} - - - - - - - - -{/if} - - - - - - - - -{if ($user->can('manage_invoices') && $user->isPluginEnabled('ps'))} - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.client} {if $user->isOptionEnabled('client_required')}(*){/if}:{$forms.expenseItemForm.client.control}
{$i18n.label.project} (*):{$forms.expenseItemForm.project.control}
{$i18n.label.expense}:{$forms.expenseItemForm.predefined_expense.control}
{$i18n.label.quantity}:{$forms.expenseItemForm.quantity.control}
{$i18n.label.comment}:{$forms.expenseItemForm.item_name.control}
{$i18n.label.cost}:{$forms.expenseItemForm.cost.control} {$user->getCurrency()|escape}
 
{$i18n.label.date}:{$forms.expenseItemForm.date.control}
 
{$forms.expenseItemForm.btn_save.control} {$forms.expenseItemForm.btn_copy.control} {$forms.expenseItemForm.btn_delete.control}
-
-
-{$forms.expenseItemForm.close} diff --git a/WEB-INF/templates/expenses.tpl b/WEB-INF/templates/expenses.tpl deleted file mode 100644 index 3c5867279..000000000 --- a/WEB-INF/templates/expenses.tpl +++ /dev/null @@ -1,241 +0,0 @@ - - -{$forms.expensesForm.open} - - - - - -
- -{if $user_dropdown} - - - - -{/if} -{if $user->isPluginEnabled('cl')} - - - - -{/if} -{if $show_project} - - - - -{/if} -{if $predefined_expenses} - - - - - - - - -{/if} - - - - - - - - -{if $show_files} - - - - -{/if} -
{$i18n.label.user}:{$forms.expensesForm.user.control}
{$i18n.label.client}{if $user->isOptionEnabled('client_required')} (*){/if}:{$forms.expensesForm.client.control}
{$i18n.label.project} (*):{$forms.expensesForm.project.control}
{$i18n.label.expense}:{$forms.expensesForm.predefined_expense.control}
{$i18n.label.quantity}:{$forms.expensesForm.quantity.control}
{$i18n.label.comment} (*):{$forms.expensesForm.item_name.control}
{$i18n.label.cost} (*):{$forms.expensesForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.file}:{$forms.expensesForm.newfile.control}
-
- - -
{$forms.expensesForm.date.control}
-
- - - - - -
{$forms.expensesForm.btn_submit.control}
- - - - - -
-{if $expense_items} - - - {if $user->isPluginEnabled('cl')} - - {/if} - {if $show_project} - - {/if} - - - {if $show_files} - - {/if} - - - - {foreach $expense_items as $item} - - {if $user->isPluginEnabled('cl')} - - {/if} - {if $show_project} - - {/if} - - - {if $show_files} - {if $item.has_files} - - {else} - - {/if} - {/if} - - - - {/foreach} -
{$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$i18n.label.cost}
{$item.client|escape}{$item.project|escape}{$item.item|escape}{$item.cost}{$i18n.label.files}{$i18n.label.files} - {if $item.approved || $item.invoice_id} -   - {else} - {$i18n.label.edit} - {/if} - - {if $item.approved || $item.invoice_id} -   - {else} - {$i18n.label.delete} - {/if} -
- - - - -
{$i18n.label.day_total}: {$user->getCurrency()|escape} {$day_total}
-{/if} -
-{$forms.expensesForm.close} diff --git a/WEB-INF/templates/file_delete.tpl b/WEB-INF/templates/file_delete.tpl deleted file mode 100644 index 81107daa5..000000000 --- a/WEB-INF/templates/file_delete.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{$forms.fileDeleteForm.open} - - - - -
- - - - - - - - - -
{$file_to_delete|escape}
 
{$forms.fileDeleteForm.btn_delete.control}  {$forms.fileDeleteForm.btn_cancel.control}
-
-{$forms.fileDeleteForm.close} diff --git a/WEB-INF/templates/file_edit.tpl b/WEB-INF/templates/file_edit.tpl deleted file mode 100644 index 697a650ce..000000000 --- a/WEB-INF/templates/file_edit.tpl +++ /dev/null @@ -1,29 +0,0 @@ -{$forms.fileForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.fileForm.file_name.control}
{$i18n.label.description}:{$forms.fileForm.description.control}
{$i18n.label.required_fields}
 
{$forms.fileForm.btn_save.control}
-
-{$forms.fileForm.close} diff --git a/WEB-INF/templates/project_add.tpl b/WEB-INF/templates/project_add.tpl deleted file mode 100644 index 309b13788..000000000 --- a/WEB-INF/templates/project_add.tpl +++ /dev/null @@ -1,49 +0,0 @@ -{$forms.projectForm.open} - - - - -
- - - - - - - - - -{if $show_files} - - - - -{/if} -{if $show_users} - - - - - -{/if} -{if $show_tasks} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.projectForm.project_name.control}
{$i18n.label.description}:{$forms.projectForm.description.control}
{$i18n.label.file}:{$forms.projectForm.newfile.control}
 
{$i18n.label.users}:{$forms.projectForm.users.control}
 
{$i18n.label.tasks}:{$forms.projectForm.tasks.control}
{$i18n.label.required_fields}
 
{$forms.projectForm.btn_add.control}
-
-{$forms.projectForm.close} diff --git a/WEB-INF/templates/project_delete.tpl b/WEB-INF/templates/project_delete.tpl deleted file mode 100644 index 98d3e836d..000000000 --- a/WEB-INF/templates/project_delete.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{$forms.projectDeleteForm.open} - - - - -
- - - - - - - - - -
{$project_to_delete|escape}
 
{$forms.projectDeleteForm.btn_delete.control}  {$forms.projectDeleteForm.btn_cancel.control}
-
-{$forms.projectDeleteForm.close} diff --git a/WEB-INF/templates/project_edit.tpl b/WEB-INF/templates/project_edit.tpl deleted file mode 100644 index 2a2364f20..000000000 --- a/WEB-INF/templates/project_edit.tpl +++ /dev/null @@ -1,47 +0,0 @@ -{$forms.projectForm.open} - - - - -
- - - - - - - - - - - - - -{if $show_users} - - - - - -{/if} -{if $show_tasks} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.projectForm.project_name.control}
{$i18n.label.description}:{$forms.projectForm.description.control}
{$i18n.label.status}:{$forms.projectForm.status.control}
 
{$i18n.label.users}:{$forms.projectForm.users.control}
 
{$i18n.label.tasks}:{$forms.projectForm.tasks.control}
{$i18n.label.required_fields}
 
{$forms.projectForm.btn_save.control} {$forms.projectForm.btn_copy.control}
-
-{$forms.projectForm.close} diff --git a/WEB-INF/templates/projects.tpl b/WEB-INF/templates/projects.tpl deleted file mode 100644 index 19bbe2373..000000000 --- a/WEB-INF/templates/projects.tpl +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - -
-{if $user->can('manage_projects')} - - {if $inactive_projects} - - {/if} - {if $active_projects} - - - - {if $show_files} - - {/if} - - - - {foreach $active_projects as $project} - - - - {if $show_files} - {if $project.has_files} - - {else} - - {/if} - {/if} - - - - {/foreach} - {/if} -
{$i18n.form.projects.active_projects}
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- - {if $inactive_projects} - - - - - - {if $show_files} - - {/if} - - - - {foreach $inactive_projects as $project} - - - - {if $show_files} - {if $project.has_files} - - {else} - - {/if} - {/if} - - - - {/foreach} -
{$i18n.form.projects.inactive_projects}
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- {/if} -{else} - - - - - {if $show_files} - - {/if} - - {if $active_projects} - {foreach $active_projects as $project} - - - - {if $show_files} - {if $project.has_files} - - {else} - - {/if} - {/if} - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}{$i18n.label.files} 
-{/if} -
diff --git a/WEB-INF/templates/swap_roles.tpl b/WEB-INF/templates/swap_roles.tpl deleted file mode 100644 index 2d3086329..000000000 --- a/WEB-INF/templates/swap_roles.tpl +++ /dev/null @@ -1,15 +0,0 @@ -{$forms.swapForm.open} - -
- - - - - - - - -
{$i18n.form.swap.hint}
 
{$i18n.form.swap.swap_with}:{$forms.swapForm.swap_with.control}
{$forms.swapForm.btn_submit.control} {$forms.swapForm.btn_cancel.control}
-
-{$forms.swapForm.close} diff --git a/WEB-INF/templates/task_add.tpl b/WEB-INF/templates/task_add.tpl deleted file mode 100644 index d1892709a..000000000 --- a/WEB-INF/templates/task_add.tpl +++ /dev/null @@ -1,36 +0,0 @@ -{$forms.taskForm.open} - - - - -
- - - - - - - - - -{if $show_projects} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.taskForm.name.control}
{$i18n.label.description}:{$forms.taskForm.description.control}
 
{$i18n.label.projects}:{$forms.taskForm.projects.control}
{$i18n.label.required_fields}
 
{$forms.taskForm.btn_submit.control}
-
-{$forms.taskForm.close} diff --git a/WEB-INF/templates/task_delete.tpl b/WEB-INF/templates/task_delete.tpl deleted file mode 100644 index 9f16d7c3a..000000000 --- a/WEB-INF/templates/task_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.taskDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$task_to_delete|escape}
 
{$forms.taskDeleteForm.btn_delete.control}  {$forms.taskDeleteForm.btn_cancel.control}
-
-{$forms.taskDeleteForm.close} diff --git a/WEB-INF/templates/task_edit.tpl b/WEB-INF/templates/task_edit.tpl deleted file mode 100644 index 0c2b1a555..000000000 --- a/WEB-INF/templates/task_edit.tpl +++ /dev/null @@ -1,40 +0,0 @@ -{$forms.taskForm.open} - - - - -
- - - - - - - - - - - - - -{if $show_projects} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.taskForm.name.control}
{$i18n.label.description}:{$forms.taskForm.description.control}
{$i18n.label.status}:{$forms.taskForm.status.control}
 
{$i18n.label.projects}:{$forms.taskForm.projects.control}
{$i18n.label.required_fields}
 
{$forms.taskForm.btn_save.control} {$forms.taskForm.btn_copy.control}
-
-{$forms.taskForm.close} diff --git a/WEB-INF/templates/tasks.tpl b/WEB-INF/templates/tasks.tpl deleted file mode 100644 index 591820199..000000000 --- a/WEB-INF/templates/tasks.tpl +++ /dev/null @@ -1,96 +0,0 @@ - - -{$forms.tasksForm.open} - - - - -
-{if $user->can('manage_tasks')} - - - - - - - - -
{$forms.tasksForm.task_required.control} {$i18n.label.what_is_it}
{$forms.tasksForm.btn_save.control}
-
- - {if $inactive_tasks} - - {/if} - - - - - - - {if $active_tasks} - {foreach $active_tasks as $task} - - - - - - - {/foreach} - {/if} -
{$i18n.form.tasks.active_tasks}
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- - {if $inactive_tasks} - - - - - - - - - {foreach $inactive_tasks as $task} - - - - - - - {/foreach} -
{$i18n.form.tasks.inactive_tasks}
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- {/if} -{else} - - - - - - {if $active_tasks} - {foreach $active_tasks as $task} - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}
-{/if} -
-{$forms.tasksForm.close} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl deleted file mode 100644 index 69d214127..000000000 --- a/WEB-INF/templates/time.tpl +++ /dev/null @@ -1,234 +0,0 @@ -{include file="time_script.tpl"} - - - -{$forms.timeRecordForm.open} - -{if $show_navigation} - - - -{/if} - - - - -
- {$i18n.label.day_view} / {$i18n.label.week_view} -
- -{if $user_dropdown} - - - - -{/if} -{if $show_client} - - - - -{/if} -{if $show_billable} - - - - -{/if} -{if $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - - {/foreach} -{/if} -{if $show_project} - - - - -{/if} -{if $show_task} - - - - -{/if} -{if $show_start} - - - - - - - - -{/if} -{if $show_duration} - - - - -{/if} -{if $show_files} - - - - -{/if} -{if $template_dropdown} - - - - -{/if} -
{$i18n.label.user}:{$forms.timeRecordForm.user.control}
{$i18n.label.client}{if $user->isOptionEnabled('client_required')} (*){/if}:{$forms.timeRecordForm.client.control}
 
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project} (*):{$forms.timeRecordForm.project.control}
{$i18n.label.task}{if $task_required} (*){/if}:{$forms.timeRecordForm.task.control}
{$i18n.label.start}:{$forms.timeRecordForm.start.control} 
{$i18n.label.finish}:{$forms.timeRecordForm.finish.control} 
{$i18n.label.duration}:{$forms.timeRecordForm.duration.control} {if $user->getDecimalMark() == ','}{str_replace('.', ',', $i18n.form.time.duration_format)}{else}{$i18n.form.time.duration_format}{/if}
{$i18n.label.file}:{$forms.timeRecordForm.newfile.control}
{$i18n.label.template}:{$forms.timeRecordForm.template.control}
-
- - -
{$forms.timeRecordForm.date.control}
-
- - - - - - - - - -
{$i18n.label.note}:{$forms.timeRecordForm.note.control}
{$forms.timeRecordForm.btn_submit.control}
- - - - - -
-{if $time_records} - - - {if $show_client} - - {/if} - {if $show_record_custom_fields && $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - - {/foreach} - {/if} - {if $show_project} - - {/if} - {if $show_task} - - {/if} - {if $show_start} - - - {/if} - - {if $show_note_column} - - {/if} - {if $show_files} - - {/if} - - - - {foreach $time_records as $record} - - {if $show_client} - - {/if} - {* record custom fileds *} - {if $show_record_custom_fields && $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - {/foreach} - {/if} - {if $show_project} - - {/if} - {if $show_task} - - {/if} - {if $show_start} - - - {/if} - - {if $show_note_column} - - {/if} - {if $show_files} - {if $record.has_files} - - {else} - - {/if} - {/if} - - - - {if $show_note_row && $record.comment} - - - - - {/if} - {/foreach} -
{$i18n.label.client}{$timeField['label']|escape}{$i18n.label.project}{$i18n.label.task}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.note}
{$record.client|escape}{$record.$control_name|escape}{$record.project|escape}{$record.task|escape}{if $record.start}{$record.start}{else} {/if}{if $record.finish}{$record.finish}{else} {/if}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}{if $record.comment}{$record.comment|escape}{else} {/if}{$i18n.label.files}{$i18n.label.files} - {if $record.approved || $record.timesheet_id || $record.invoice_id} -   - {else} - {$i18n.label.edit} - {if ($record.duration == '0:00' && $record.start <> '')} - - - - - {/if} - {/if} - - {if $record.approved || $record.timesheet_id || $record.invoice_id} -   - {else} - {$i18n.label.delete} - {/if} -
{$i18n.label.note}:{$record.comment|escape}
-{/if} -
- - - - - - - {if $user->isPluginEnabled('mq')} - - - {if $over_balance} - - {else} - - {/if} - - - - {if $over_quota} - - {else} - - {/if} - - {/if} -
{$i18n.label.week_total}: {$week_total}{$i18n.label.day_total}: {$day_total}
{$i18n.label.month_total}: {$month_total}{$i18n.form.time.over_balance}: {$balance_remaining}{$i18n.form.time.remaining_balance}: {$balance_remaining}
{$i18n.label.quota}: {$month_quota}{$i18n.form.time.over_quota}: {$quota_remaining}{$i18n.form.time.remaining_quota}: {$quota_remaining}
- -{$forms.timeRecordForm.close} diff --git a/WEB-INF/templates/user_add.tpl b/WEB-INF/templates/user_add.tpl deleted file mode 100644 index 35040f3c4..000000000 --- a/WEB-INF/templates/user_add.tpl +++ /dev/null @@ -1,134 +0,0 @@ - - -{$forms.userForm.open} - -
- - - - - - - - -{if !$auth_external} - - - - - - - - -{/if} - - - - - - - - - -{if $show_quota} - - - - -{/if} -{if $custom_fields && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - - - {assign var="control_name" value='user_field_'|cat:$userField['id']} - - - {/foreach} -{/if} - - - - - -{if $show_projects} - - - - - - - -{/if} - - - - - - -
{$i18n.label.person_name} (*):{$forms.userForm.name.control}
{$i18n.label.login} (*):{$forms.userForm.login.control}
{$i18n.label.password} (*):{$forms.userForm.pas1.control}
{$i18n.label.confirm_password} (*):{$forms.userForm.pas2.control}
{$i18n.label.email}:{$forms.userForm.email.control}
{$i18n.form.users.role}:{$forms.userForm.role.control} {$forms.userForm.client.control}
{$i18n.label.quota} (%):{$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
{$userField['label']|escape}{if $userField['required']} (*){/if}:{$forms.userForm.$control_name.control}
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00):{$forms.userForm.rate.control}
 
{$i18n.label.projects}:{$forms.userForm.projects.control}
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
-
-{$forms.userForm.close} diff --git a/WEB-INF/templates/user_delete.tpl b/WEB-INF/templates/user_delete.tpl deleted file mode 100644 index e85d97f1f..000000000 --- a/WEB-INF/templates/user_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.userDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$user_to_delete|escape}
 
{$forms.userDeleteForm.btn_delete.control}  {$forms.userDeleteForm.btn_cancel.control}
-
-{$forms.userDeleteForm.close} diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl deleted file mode 100644 index 49fa4ae50..000000000 --- a/WEB-INF/templates/user_edit.tpl +++ /dev/null @@ -1,168 +0,0 @@ - - -{$forms.userForm.open} - -
- - - - - - - - -{if !$auth_external} - - - - - - - - -{/if} - - - - -{if $user->id != $user_id} - - - - - - - - -{/if} -{if $user->id == $user_id} - - - - -{/if} - -{if $show_quota} - - - - -{/if} -{if $custom_fields && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - - - {assign var="control_name" value='user_field_'|cat:$userField['id']} - - - {/foreach} -{/if} - - - - - -{if $show_projects} - - - - - - - -{/if} - - - - - - -
{$i18n.label.person_name} (*):{$forms.userForm.name.control}
{$i18n.label.login} (*):{$forms.userForm.login.control}
{$i18n.label.password} (*):{$forms.userForm.pas1.control}
{$i18n.label.confirm_password} (*):{$forms.userForm.pas2.control}
{$i18n.label.email}:{$forms.userForm.email.control}
{$i18n.form.users.role}:{$forms.userForm.role.control} {$forms.userForm.client.control}
{$i18n.label.status}:{$forms.userForm.status.control}
{$i18n.form.users.role}:{$user->role_name} {if $can_swap}{$i18n.form.user_edit.swap_roles}{/if}
{$i18n.label.quota} (%):{$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
{$userField['label']|escape}{if $userField['required']} (*){/if}:{$forms.userForm.$control_name.control}
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00):{$forms.userForm.rate.control}
 
{$i18n.label.projects}:{$forms.userForm.projects.control}
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
-
-{$forms.userForm.close} diff --git a/WEB-INF/templates/users.tpl b/WEB-INF/templates/users.tpl deleted file mode 100644 index c3f6861ea..000000000 --- a/WEB-INF/templates/users.tpl +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - -
-{if $user->can('manage_users')} - - {if $inactive_users} - - {/if} - {if $active_users} - - - - - {if $show_quota} - - {/if} - - - - {foreach $active_users as $u} - - - - - {if $show_quota} - - {/if} - {if $u.group_id != $user->group_id || $u.rank < $user->rank || ($u.rank == $user->rank && $u.id == $user->id)} - - {if $u.id != $user->id}{else}{/if} - {else} - - - {/if} - - {/foreach} - {/if} -
{$i18n.label.active_users}
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}{$i18n.label.quota}
- {if $uncompleted_indicators} - - {/if} - {$u.name|escape} - {$u.login|escape}{$u.role_name|escape}{$u.quota_percent}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- - {if $inactive_users} - - - - - - - {if $show_quota} - - {/if} - - - - {foreach $inactive_users as $u} - - - - - {if $show_quota} - - {/if} - {if $u.group_id != $user->group_id || $u.rank < $user->rank} - - - {else} - - - {/if} - - {/foreach} - -
{$i18n.label.inactive_users}
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}{$i18n.label.quota}
{$u.name|escape}{$u.login|escape}{$u.role_name|escape}{$u.quota_percent}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -
-
-
- {/if} -{else} - - - - - - - {foreach $active_users as $u} - - - - - - {/foreach} -
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}
- {if $uncompleted_indicators} - - {/if} - {$u.name|escape} - {$u.login|escape}{$u.role_name|escape}
-{/if} -
diff --git a/expense_files.php b/expense_files.php index feab9b611..5642cb383 100644 --- a/expense_files.php +++ b/expense_files.php @@ -1,30 +1,6 @@ addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -85,5 +61,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('files', $files); $smarty->assign('title', $i18n->get('title.expense_files')); -$smarty->assign('content_page_name', 'entity_files.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'entity_files2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index a863d270f..a222510c9 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5404"); +define("APP_VERSION", "1.19.23.5405"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/project_files.php b/project_files.php index 6ffe123f1..5dd816d6c 100644 --- a/project_files.php +++ b/project_files.php @@ -1,30 +1,6 @@ addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -85,5 +61,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('files', $files); $smarty->assign('title', $i18n->get('title.project_files').': '.$project['name']); -$smarty->assign('content_page_name', 'entity_files.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'entity_files2.tpl'); +$smarty->display('index2.tpl'); diff --git a/timesheet_delete.php b/timesheet_delete.php index 5e98a6cc9..ff1e4e180 100644 --- a/timesheet_delete.php +++ b/timesheet_delete.php @@ -1,30 +1,6 @@ addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_timesheet_id)); $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -85,5 +61,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('files', $files); $smarty->assign('title', $i18n->get('title.timesheet_files').': '.$timesheet['name']); -$smarty->assign('content_page_name', 'entity_files.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'entity_files2.tpl'); +$smarty->display('index2.tpl'); From 4500d03942456a4be84e82635412c0ebacf5d152 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 21:35:10 +0000 Subject: [PATCH 1413/1848] Some more cleanup. --- .../{access_denied.tpl => access_denied2.tpl} | 0 .../{file_download.tpl => file_download2.tpl} | 0 access_denied.php | 2 +- client_add1.php | 94 ------------------- client_delete1.php | 78 --------------- feature_disabled.php | 32 +------ file_download.php | 4 +- initialize.php | 2 +- 8 files changed, 8 insertions(+), 204 deletions(-) rename WEB-INF/templates/{access_denied.tpl => access_denied2.tpl} (100%) rename WEB-INF/templates/{file_download.tpl => file_download2.tpl} (100%) delete mode 100644 client_add1.php delete mode 100644 client_delete1.php diff --git a/WEB-INF/templates/access_denied.tpl b/WEB-INF/templates/access_denied2.tpl similarity index 100% rename from WEB-INF/templates/access_denied.tpl rename to WEB-INF/templates/access_denied2.tpl diff --git a/WEB-INF/templates/file_download.tpl b/WEB-INF/templates/file_download2.tpl similarity index 100% rename from WEB-INF/templates/file_download.tpl rename to WEB-INF/templates/file_download2.tpl diff --git a/access_denied.php b/access_denied.php index 7025d8739..2aa3c5d77 100644 --- a/access_denied.php +++ b/access_denied.php @@ -8,5 +8,5 @@ if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. $smarty->assign('title', $i18n->get('label.error')); -$smarty->assign('content_page_name', 'access_denied.tpl'); +$smarty->assign('content_page_name', 'access_denied2.tpl'); $smarty->display('index2.tpl'); diff --git a/client_add1.php b/client_add1.php deleted file mode 100644 index 820a32fde..000000000 --- a/client_add1.php +++ /dev/null @@ -1,94 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_address = trim($request->getParameter('address')); - $cl_tax = $request->getParameter('tax'); - $cl_projects = $request->getParameter('projects'); -} else { - // Do not assign all projects to a new client by default. This should help to reduce clutter. - // foreach ($projects as $project_item) - // $cl_projects[] = $project_item['id']; -} - -$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; - -$form = new Form('clientForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 350px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','style'=>'width: 350px; height: 80px;','value'=>$cl_address)); -$form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -if ($show_projects) - $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); - - if ($err->no()) { - if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array('name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'projects' => $cl_projects, - 'status' => ACTIVE))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"'); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('title', $i18n->get('title.add_client')); -$smarty->assign('content_page_name', 'client_add.tpl'); -$smarty->display('index.tpl'); diff --git a/client_delete1.php b/client_delete1.php deleted file mode 100644 index a5f00656e..000000000 --- a/client_delete1.php +++ /dev/null @@ -1,78 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -$id = (int)$request->getParameter('id'); -$client = ttClientHelper::getClient($id); -if (!$client) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$client_to_delete = $client['name']; - -$form = new Form('clientDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$id)); -$form->addInput(array('type'=>'combobox','name'=>'delete_client_entries', - 'data'=>array('0'=>$i18n->get('dropdown.do_not_delete'),'1'=>$i18n->get('dropdown.delete')))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if (ttClientHelper::delete($id, $request->getParameter('delete_client_entries'))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - - if ($request->getParameter('btn_cancel')) { - header('Location: clients.php'); - exit(); - } -} // isPost - -$smarty->assign('client_to_delete', $client_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.delete_client')); -$smarty->assign('content_page_name', 'client_delete.tpl'); -$smarty->display('index.tpl'); diff --git a/feature_disabled.php b/feature_disabled.php index 7f0bb81f5..c04afe734 100644 --- a/feature_disabled.php +++ b/feature_disabled.php @@ -1,30 +1,6 @@ isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. $smarty->assign('title', $i18n->get('label.error')); -$smarty->assign('content_page_name', 'access_denied.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'access_denied2.tpl'); +$smarty->display('index2.tpl'); diff --git a/file_download.php b/file_download.php index ac076b27e..0c323f7f3 100644 --- a/file_download.php +++ b/file_download.php @@ -83,5 +83,5 @@ } $smarty->assign('title', $i18n->get('title.download_file')); -$smarty->assign('content_page_name', 'file_download.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'file_download2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index a222510c9..0af6f6c3c 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5405"); +define("APP_VERSION", "1.19.23.5406"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 684c41fbf421859d01fbd7391d7bbb7fef430bc8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 7 Dec 2020 17:28:19 +0000 Subject: [PATCH 1414/1848] Removed no longer used mobile pages. --- WEB-INF/templates/mobile/access_denied.tpl | 1 - WEB-INF/templates/mobile/expense_delete.tpl | 39 -- WEB-INF/templates/mobile/expense_edit.tpl | 183 -------- WEB-INF/templates/mobile/project_add.tpl | 43 -- WEB-INF/templates/mobile/project_delete.tpl | 18 - WEB-INF/templates/mobile/project_edit.tpl | 47 -- WEB-INF/templates/mobile/task_add.tpl | 33 -- WEB-INF/templates/mobile/task_delete.tpl | 20 - WEB-INF/templates/mobile/task_edit.tpl | 37 -- WEB-INF/templates/mobile/time_delete.tpl | 32 -- WEB-INF/templates/mobile/time_edit.tpl | 76 --- WEB-INF/templates/mobile/user_add.tpl | 124 ----- WEB-INF/templates/mobile/user_delete.tpl | 20 - WEB-INF/templates/mobile/user_edit.tpl | 153 ------ initialize.php | 2 +- mobile/access_denied.php | 36 -- mobile/expense_delete.php | 88 ---- mobile/expense_edit.php | 238 ---------- mobile/expenses.php | 5 + mobile/feature_disabled.php | 36 -- mobile/index.php | 5 + mobile/project_add.php | 103 ---- mobile/project_delete.php | 75 --- mobile/project_edit.php | 142 ------ mobile/projects.php | 5 + mobile/task_add.php | 87 ---- mobile/task_delete.php | 78 ---- mobile/task_edit.php | 128 ----- mobile/tasks.php | 5 + mobile/time_delete.php | 89 ---- mobile/time_edit.php | 494 -------------------- mobile/user_add.php | 186 -------- mobile/user_delete.php | 87 ---- mobile/user_edit.php | 245 ---------- mobile/users.php | 5 + 35 files changed, 26 insertions(+), 2939 deletions(-) delete mode 100644 WEB-INF/templates/mobile/access_denied.tpl delete mode 100644 WEB-INF/templates/mobile/expense_delete.tpl delete mode 100644 WEB-INF/templates/mobile/expense_edit.tpl delete mode 100644 WEB-INF/templates/mobile/project_add.tpl delete mode 100644 WEB-INF/templates/mobile/project_delete.tpl delete mode 100644 WEB-INF/templates/mobile/project_edit.tpl delete mode 100644 WEB-INF/templates/mobile/task_add.tpl delete mode 100644 WEB-INF/templates/mobile/task_delete.tpl delete mode 100644 WEB-INF/templates/mobile/task_edit.tpl delete mode 100644 WEB-INF/templates/mobile/time_delete.tpl delete mode 100644 WEB-INF/templates/mobile/time_edit.tpl delete mode 100644 WEB-INF/templates/mobile/user_add.tpl delete mode 100644 WEB-INF/templates/mobile/user_delete.tpl delete mode 100644 WEB-INF/templates/mobile/user_edit.tpl delete mode 100644 mobile/access_denied.php delete mode 100644 mobile/expense_delete.php delete mode 100644 mobile/expense_edit.php delete mode 100644 mobile/feature_disabled.php delete mode 100644 mobile/project_add.php delete mode 100644 mobile/project_delete.php delete mode 100644 mobile/project_edit.php delete mode 100644 mobile/task_add.php delete mode 100644 mobile/task_delete.php delete mode 100644 mobile/task_edit.php delete mode 100644 mobile/time_delete.php delete mode 100644 mobile/time_edit.php delete mode 100644 mobile/user_add.php delete mode 100644 mobile/user_delete.php delete mode 100644 mobile/user_edit.php diff --git a/WEB-INF/templates/mobile/access_denied.tpl b/WEB-INF/templates/mobile/access_denied.tpl deleted file mode 100644 index c341a4039..000000000 --- a/WEB-INF/templates/mobile/access_denied.tpl +++ /dev/null @@ -1 +0,0 @@ - diff --git a/WEB-INF/templates/mobile/expense_delete.tpl b/WEB-INF/templates/mobile/expense_delete.tpl deleted file mode 100644 index bd14824e2..000000000 --- a/WEB-INF/templates/mobile/expense_delete.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{$forms.expenseItemForm.open} - - - - -
- - -{if $user->isPluginEnabled('cl')} - -{/if} - -{if $show_project} - -{/if} - - - - -{if $user->isPluginEnabled('cl')} - -{/if} -{if $show_project} - -{/if} - - - -
{$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$i18n.label.cost}
{$expense_item.client_name|escape}{$expense_item.project_name|escape}{$expense_item.name|escape}{$expense_item.cost}
- - - - - - - -
 
{$forms.expenseItemForm.delete_button.control}  {$forms.expenseItemForm.cancel_button.control}
-
-{$forms.expenseItemForm.close} diff --git a/WEB-INF/templates/mobile/expense_edit.tpl b/WEB-INF/templates/mobile/expense_edit.tpl deleted file mode 100644 index d4834ae1a..000000000 --- a/WEB-INF/templates/mobile/expense_edit.tpl +++ /dev/null @@ -1,183 +0,0 @@ - - -{$forms.expenseItemForm.open} - - - - -
- - - - -
- -{if $user->isPluginEnabled('cl')} - - - - -{/if} -{if $show_project} - - - - -{/if} -{if $predefined_expenses} - - - - - - - - -{/if} - - - - - - - - - - - - - - - - - - - -
{$i18n.label.client} {if $user->isOptionEnabled('client_required')}(*){/if}:{$forms.expenseItemForm.client.control}
{$i18n.label.project} (*):{$forms.expenseItemForm.project.control}
{$i18n.label.expense}:{$forms.expenseItemForm.predefined_expense.control}
{$i18n.label.quantity}:{$forms.expenseItemForm.quantity.control}
{$i18n.label.item}:{$forms.expenseItemForm.item_name.control}
{$i18n.label.cost}:{$forms.expenseItemForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.date}:{$forms.expenseItemForm.date.control}
 
{$forms.expenseItemForm.btn_save.control} {$forms.expenseItemForm.btn_copy.control} {$forms.expenseItemForm.btn_delete.control}
-
-
-{$forms.expenseItemForm.close} diff --git a/WEB-INF/templates/mobile/project_add.tpl b/WEB-INF/templates/mobile/project_add.tpl deleted file mode 100644 index d49b9a33e..000000000 --- a/WEB-INF/templates/mobile/project_add.tpl +++ /dev/null @@ -1,43 +0,0 @@ -{$forms.projectForm.open} - - - - -
- - - - - - - - - -{if $show_users} - - - - - -{/if} -{if $show_tasks} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.projectForm.project_name.control}
{$i18n.label.description}:{$forms.projectForm.description.control}
 
{$i18n.label.users}:{$forms.projectForm.users.control}
 
{$i18n.label.tasks}:{$forms.projectForm.tasks.control}
{$i18n.label.required_fields}
 
{$forms.projectForm.btn_add.control}
-
-{$forms.projectForm.close} diff --git a/WEB-INF/templates/mobile/project_delete.tpl b/WEB-INF/templates/mobile/project_delete.tpl deleted file mode 100644 index 98d3e836d..000000000 --- a/WEB-INF/templates/mobile/project_delete.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{$forms.projectDeleteForm.open} - - - - -
- - - - - - - - - -
{$project_to_delete|escape}
 
{$forms.projectDeleteForm.btn_delete.control}  {$forms.projectDeleteForm.btn_cancel.control}
-
-{$forms.projectDeleteForm.close} diff --git a/WEB-INF/templates/mobile/project_edit.tpl b/WEB-INF/templates/mobile/project_edit.tpl deleted file mode 100644 index 871f5c1dc..000000000 --- a/WEB-INF/templates/mobile/project_edit.tpl +++ /dev/null @@ -1,47 +0,0 @@ -{$forms.projectForm.open} - - - - -
- - - - - - - - - - - - - -{if $show_users} - - - - - -{/if} -{if $show_tasks} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.projectForm.project_name.control}
{$i18n.label.description}:{$forms.projectForm.description.control}
{$i18n.label.status}:{$forms.projectForm.status.control}
 
{$i18n.label.users}:{$forms.projectForm.users.control}
 
{$i18n.label.tasks}:{$forms.projectForm.tasks.control}
{$i18n.label.required_fields}
 
{$forms.projectForm.btn_save.control} {$forms.projectForm.btn_copy.control} {$forms.projectForm.btn_delete.control}
-
-{$forms.projectForm.close} diff --git a/WEB-INF/templates/mobile/task_add.tpl b/WEB-INF/templates/mobile/task_add.tpl deleted file mode 100644 index 68e415e1c..000000000 --- a/WEB-INF/templates/mobile/task_add.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{$forms.taskForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.taskForm.name.control}
{$i18n.label.description}:{$forms.taskForm.description.control}
{$i18n.label.projects}:{$forms.taskForm.projects.control}
{$i18n.label.required_fields}
 
{$forms.taskForm.btn_submit.control}
-
-{$forms.taskForm.close} diff --git a/WEB-INF/templates/mobile/task_delete.tpl b/WEB-INF/templates/mobile/task_delete.tpl deleted file mode 100644 index 9f16d7c3a..000000000 --- a/WEB-INF/templates/mobile/task_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.taskDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$task_to_delete|escape}
 
{$forms.taskDeleteForm.btn_delete.control}  {$forms.taskDeleteForm.btn_cancel.control}
-
-{$forms.taskDeleteForm.close} diff --git a/WEB-INF/templates/mobile/task_edit.tpl b/WEB-INF/templates/mobile/task_edit.tpl deleted file mode 100644 index f6672c739..000000000 --- a/WEB-INF/templates/mobile/task_edit.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{$forms.taskForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.taskForm.name.control}
{$i18n.label.description}:{$forms.taskForm.description.control}
{$i18n.label.status}:{$forms.taskForm.status.control}
{$i18n.label.projects}:{$forms.taskForm.projects.control}
{$i18n.label.required_fields}
 
{$forms.taskForm.btn_save.control} {$forms.taskForm.btn_copy.control} {$forms.taskForm.btn_delete.control}
-
-{$forms.taskForm.close} diff --git a/WEB-INF/templates/mobile/time_delete.tpl b/WEB-INF/templates/mobile/time_delete.tpl deleted file mode 100644 index 2e3ac7fea..000000000 --- a/WEB-INF/templates/mobile/time_delete.tpl +++ /dev/null @@ -1,32 +0,0 @@ -{$forms.timeRecordForm.open} - - - - -
- - -{if $show_project} - -{/if} - - - - -{if $show_project} - -{/if} - - - -
{$i18n.label.project}{$i18n.label.duration}{$i18n.label.note}
{$time_rec.project_name|escape}{if ($time_rec.duration == '0:00' && $time_rec.start <> '')}{$i18n.form.time.uncompleted}{else}{$time_rec.duration}{/if}{if $time_rec.comment}{$time_rec.comment|escape}{else} {/if}
- - - - - - - -
 
{$forms.timeRecordForm.delete_button.control}  {$forms.timeRecordForm.cancel_button.control}
-
-{$forms.timeRecordForm.close} diff --git a/WEB-INF/templates/mobile/time_edit.tpl b/WEB-INF/templates/mobile/time_edit.tpl deleted file mode 100644 index 3025a63f7..000000000 --- a/WEB-INF/templates/mobile/time_edit.tpl +++ /dev/null @@ -1,76 +0,0 @@ -{include file="time_script.tpl"} - -{* Conditional include of confirmSave handler. *} -{if $confirm_save} - -{/if} - -{$forms.timeRecordForm.open} - - - - -
- - - - -
- -{if $show_client} - - -{/if} -{if $show_billable} - -{/if} -{if $show_paid_status} - -{/if} -{if $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - {/foreach} -{/if} -{if $show_project} - - -{/if} -{if $show_task} - - -{/if} -{if $show_start} - - - - -{/if} -{if $show_duration} - - -{/if} - - -{if $template_dropdown} - - -{/if} - - - -
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project}:
{$forms.timeRecordForm.project.control}
{$i18n.label.task}{if $task_required} (*){/if}:
{$forms.timeRecordForm.task.control}
{$i18n.label.start}:
{$forms.timeRecordForm.start.control} 
{$i18n.label.finish}:
{$forms.timeRecordForm.finish.control} 
{$i18n.label.duration}:
{$forms.timeRecordForm.duration.control}
{$i18n.label.date}:
{$forms.timeRecordForm.date.control}
{$i18n.label.template}:
{$forms.timeRecordForm.template.control}
{$i18n.label.note}:
{$forms.timeRecordForm.note.control}
{$forms.timeRecordForm.btn_save.control} {$forms.timeRecordForm.btn_copy.control} {$forms.timeRecordForm.btn_delete.control}
-
-
-{$forms.timeRecordForm.close} diff --git a/WEB-INF/templates/mobile/user_add.tpl b/WEB-INF/templates/mobile/user_add.tpl deleted file mode 100644 index 9df99ff00..000000000 --- a/WEB-INF/templates/mobile/user_add.tpl +++ /dev/null @@ -1,124 +0,0 @@ - - -{$forms.userForm.open} - -
- - - - - - - - -{if !$auth_external} - - - - - - - - -{/if} - - - - - - - - - -{if $show_quota} - - - - -{/if} - - - - - -{if $show_projects} - - - - - - -{/if} - - - - - - -
{$i18n.label.person_name} (*):{$forms.userForm.name.control}
{$i18n.label.login} (*):{$forms.userForm.login.control}
{$i18n.label.password} (*):{$forms.userForm.pas1.control}
{$i18n.label.confirm_password} (*):{$forms.userForm.pas2.control}
{$i18n.label.email}:{$forms.userForm.email.control}
{$i18n.form.users.role}:{$forms.userForm.role.control} {$forms.userForm.client.control}
{$i18n.label.quota} (%):{$forms.userForm.quota_percent.control}
{$i18n.form.users.default_rate} (0{$user->decimal_mark}00):{$forms.userForm.rate.control}
{$i18n.label.projects}:{$forms.userForm.projects.control}
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
-
-{$forms.userForm.close} diff --git a/WEB-INF/templates/mobile/user_delete.tpl b/WEB-INF/templates/mobile/user_delete.tpl deleted file mode 100644 index e85d97f1f..000000000 --- a/WEB-INF/templates/mobile/user_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.userDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$user_to_delete|escape}
 
{$forms.userDeleteForm.btn_delete.control}  {$forms.userDeleteForm.btn_cancel.control}
-
-{$forms.userDeleteForm.close} diff --git a/WEB-INF/templates/mobile/user_edit.tpl b/WEB-INF/templates/mobile/user_edit.tpl deleted file mode 100644 index 03c5db2ef..000000000 --- a/WEB-INF/templates/mobile/user_edit.tpl +++ /dev/null @@ -1,153 +0,0 @@ - - - -{$forms.userForm.open} - -
- - - - - - - - -{if !$auth_external} - - - - - - - - -{/if} - - - - -{if $user->id != $user_id} - - - - - - - - -{/if} - -{if $show_quota} - - - - -{/if} - - - - - -{if $show_projects} - - - - - - -{/if} - - - - - - -
{$i18n.label.person_name} (*):{$forms.userForm.name.control}
{$i18n.label.login} (*):{$forms.userForm.login.control}
{$i18n.label.password} (*):{$forms.userForm.pas1.control}
{$i18n.label.confirm_password} (*):{$forms.userForm.pas2.control}
{$i18n.label.email}:{$forms.userForm.email.control}
{$i18n.form.users.role}:{$forms.userForm.role.control} {$forms.userForm.client.control}
{$i18n.label.status}:{$forms.userForm.status.control}
{$i18n.label.quota} (%):{$forms.userForm.quota_percent.control}
{$i18n.form.users.default_rate} (0{$user->decimal_mark}00):{$forms.userForm.rate.control}
{$i18n.label.projects}:{$forms.userForm.projects.control}
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control} {$forms.userForm.btn_delete.control}
-
-{$forms.userForm.close} diff --git a/initialize.php b/initialize.php index 0af6f6c3c..265d13aea 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5406"); +define("APP_VERSION", "1.19.23.5407"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/access_denied.php b/mobile/access_denied.php deleted file mode 100644 index 6e7174a26..000000000 --- a/mobile/access_denied.php +++ /dev/null @@ -1,36 +0,0 @@ -add($i18n->get('error.access_denied')); -if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. - -$smarty->assign('title', $i18n->get('label.error')); -$smarty->assign('content_page_name', 'mobile/access_denied.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/expense_delete.php b/mobile/expense_delete.php deleted file mode 100644 index 48e74dc0e..000000000 --- a/mobile/expense_delete.php +++ /dev/null @@ -1,88 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -// Get the expense item we are deleting. -$expense_item = ttExpenseHelper::getItem($cl_id); -if (!$expense_item || $expense_item['approved'] || $expense_item['invoice_id']) { - // Prohibit deleting not ours, approved, or invoiced items. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -if ($request->isPost()) { - if ($request->getParameter('delete_button')) { // Delete button pressed. - - // Determine if it is okay to delete the record. - $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); - if ($user->isDateLocked($item_date)) - $err->add($i18n->get('error.range_locked')); - - if ($err->no()) { - // Mark the record as deleted. - if (ttExpenseHelper::markDeleted($cl_id)) { - header('Location: expenses.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } - if ($request->getParameter('cancel_button')) { // Cancel button pressed. - header('Location: expenses.php'); - exit(); - } -} // isPost - -$form = new Form('expenseItemForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); - -$show_project = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); - -$smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('expense_item', $expense_item); -$smarty->assign('show_project', $show_project); -$smarty->assign('title', $i18n->get('title.delete_expense')); -$smarty->assign('content_page_name', 'mobile/expense_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php deleted file mode 100644 index 67813a6f1..000000000 --- a/mobile/expense_edit.php +++ /dev/null @@ -1,238 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -// Get the expense item we are editing. -$expense_item = ttExpenseHelper::getItem($cl_id); -if (!$expense_item || $expense_item['approved'] || $expense_item['invoice_id']) { - // Prohibit editing not ours, approved, or invoiced items. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); -$confirm_save = $user->getConfigOption('confirm_save'); -$trackingMode = $user->getTrackingMode(); -$show_project = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; - -// Initialize variables. -$cl_date = $cl_client = $cl_project = $cl_item_name = $cl_cost = null; -if ($request->isPost()) { - $cl_date = trim($request->getParameter('date')); - $cl_client = $request->getParameter('client'); - $cl_project = $request->getParameter('project'); - $cl_item_name = trim($request->getParameter('item_name')); - $cl_cost = trim($request->getParameter('cost')); -} else { - $cl_date = $item_date->toString($user->getDateFormat()); - $cl_client = $expense_item['client_id']; - $cl_project = $expense_item['project_id']; - $cl_item_name = $expense_item['name']; - $cl_cost = $expense_item['cost']; -} - -// Initialize elements of 'expenseItemForm'. -$form = new Form('expenseItemForm'); - -// Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $trackingMode && $user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -if ($show_project) { - // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} -// If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); -if ($predefined_expenses) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'recalculateCost();', - 'name'=>'predefined_expense', - 'style'=>'width: 250px;', - 'value'=>$cl_predefined_expense, - 'data'=>$predefined_expenses, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'item_name','style'=>'width: 250px;','value'=>$cl_item_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); -$form->addInput(array('type'=>'datefield','name'=>'date','maxlength'=>'20','value'=>$cl_date)); -// Hidden control for record id. -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -$on_click_action = 'browser_today.value=get_date();'; -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>$on_click_action,'value'=>$i18n->get('button.copy'))); -if ($confirm_save) $on_click_action .= 'return(confirmSave());'; -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>$on_click_action,'value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - // Validate user input. - if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - if ($show_project && !$cl_project) - $err->add($i18n->get('error.project')); - if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); - if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); - - // This is a new date for the expense item. - $new_date = new DateAndTime($user->getDateFormat(), $cl_date); - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($new_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating input data. - - // Save record. - if ($request->getParameter('btn_save')) { - // We need to: - // 1) Prohibit updating locked entries (that are in locked range). - // 2) Prohibit saving unlocked entries into locked range. - - // Now, step by step. - // 1) Prohibit saving locked entries in any form. - if ($user->isDateLocked($item_date)) - $err->add($i18n->get('error.range_locked')); - - // 2) Prohibit saving unlocked entries into locked range. - if ($err->no() && $user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // Now, an update. - if ($err->no()) { - if (ttExpenseHelper::update(array('id'=>$cl_id,'date'=>$new_date->toString(DB_DATEFORMAT), - 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost))) { - header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } - } - } - - // Save as new record. - if ($request->getParameter('btn_copy')) { - // We need to prohibit saving into locked interval. - if ($user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // Now, a new insert. - if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'client_id'=>$cl_client, - 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { - header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } - - if ($request->getParameter('btn_delete')) { - header("Location: expense_delete.php?id=$cl_id"); - exit(); - } -} // isPost - -if ($confirm_save) { - $smarty->assign('confirm_save', true); - $smarty->assign('entry_date', $cl_date); -} -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_project', $show_project); -$smarty->assign('predefined_expenses', $predefined_expenses); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('title', $i18n->get('title.edit_expense')); -$smarty->assign('content_page_name', 'mobile/expense_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/expenses.php b/mobile/expenses.php index 05d469985..463671f4a 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -34,6 +34,11 @@ import('ttTimeHelper'); import('ttExpenseHelper'); +// Mobile pages are no longer separate. Redirect to main page. +header('Location: ../expenses.php'); +exit(); +// Below is no longer used code. + // Access checks. if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses'))) { header('Location: access_denied.php'); diff --git a/mobile/feature_disabled.php b/mobile/feature_disabled.php deleted file mode 100644 index cf399568e..000000000 --- a/mobile/feature_disabled.php +++ /dev/null @@ -1,36 +0,0 @@ -add($i18n->get('error.feature_disabled')); -if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. - -$smarty->assign('title', $i18n->get('label.error')); -$smarty->assign('content_page_name', 'mobile/access_denied.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/index.php b/mobile/index.php index 8fc64b35e..88408af23 100644 --- a/mobile/index.php +++ b/mobile/index.php @@ -28,6 +28,11 @@ require_once('../initialize.php'); +// Mobile pages are no longer separate. Redirect to main page. +header('Location: ../index.php'); +exit(); +// Below is no longer used code. + // Redirects for admin and client roles. if ($auth->isAuthenticated()) { if ($user->can('administer_site')) { diff --git a/mobile/project_add.php b/mobile/project_add.php deleted file mode 100644 index c152006f3..000000000 --- a/mobile/project_add.php +++ /dev/null @@ -1,103 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$users = ttGroupHelper::getActiveUsers(); -foreach ($users as $user_item) - $all_users[$user_item['id']] = $user_item['name']; - -$tasks = ttGroupHelper::getActiveTasks(); -foreach ($tasks as $task_item) - $all_tasks[$task_item['id']] = $task_item['name']; -$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('project_name')); - $cl_description = trim($request->getParameter('description')); - $cl_users = $request->getParameter('users', array()); - $cl_tasks = $request->getParameter('tasks', array()); -} else { - foreach ($users as $user_item) - $cl_users[] = $user_item['id']; - foreach ($tasks as $task_item) - $cl_tasks[] = $task_item['id']; -} - -$form = new Form('projectForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); -$form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if ($show_tasks) - $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); - - if ($err->no()) { - if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array('name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE))) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', $show_tasks); -$smarty->assign('title', $i18n->get('title.add_project')); -$smarty->assign('content_page_name', 'mobile/project_add.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/project_delete.php b/mobile/project_delete.php deleted file mode 100644 index ac957e249..000000000 --- a/mobile/project_delete.php +++ /dev/null @@ -1,75 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_project_id = (int)$request->getParameter('id'); -$project = ttProjectHelper::get($cl_project_id); -if (!$project) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$project_to_delete = $project['name']; - -$form = new Form('projectDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if (ttProjectHelper::delete($cl_project_id)) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } elseif ($request->getParameter('btn_cancel')) { - header('Location: projects.php'); - exit(); - } -} // isPost - -$smarty->assign('project_to_delete', $project_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_project')); -$smarty->assign('content_page_name', 'mobile/project_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/project_edit.php b/mobile/project_edit.php deleted file mode 100644 index 31da38903..000000000 --- a/mobile/project_edit.php +++ /dev/null @@ -1,142 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_project_id = (int)$request->getParameter('id'); -$project = ttProjectHelper::get($cl_project_id); -if (!$project) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$users = ttGroupHelper::getActiveUsers(); -foreach ($users as $user_item) - $all_users[$user_item['id']] = $user_item['name']; - -$tasks = ttGroupHelper::getActiveTasks(); -foreach ($tasks as $task_item) - $all_tasks[$task_item['id']] = $task_item['name']; -$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('project_name')); - $cl_description = trim($request->getParameter('description')); - $cl_status = $request->getParameter('status'); - $cl_users = $request->getParameter('users', array()); - $cl_tasks = $request->getParameter('tasks', array()); -} else { - $cl_name = $project['name']; - $cl_description = $project['description']; - $cl_status = $project['status']; - $cl_users = ttProjectHelper::getAssignedUsers($cl_project_id); - $cl_tasks = explode(',', $project['tasks']); -} - -$form = new Form('projectForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if ($show_tasks) - $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $existing_project = ttProjectHelper::getProjectByName($cl_name); - if (!$existing_project || ($cl_project_id == $existing_project['id'])) { - // Update project information. - if (ttProjectHelper::update(array( - 'id' => $cl_project_id, - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'users' => $cl_users, - 'tasks' => $cl_tasks))) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array('name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE))) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_delete')) { - header("Location: project_delete.php?id=$cl_project_id"); - exit(); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', $show_tasks); -$smarty->assign('title', $i18n->get('title.edit_project')); -$smarty->assign('content_page_name', 'mobile/project_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/projects.php b/mobile/projects.php index 6a5ac572a..ee5d8dc18 100644 --- a/mobile/projects.php +++ b/mobile/projects.php @@ -31,6 +31,11 @@ import('ttTeamHelper'); import('ttGroupHelper'); +// Mobile pages are no longer separate. Redirect to main page. +header('Location: ../projects.php'); +exit(); +// Below is no longer used code. + // Access checks. if (!(ttAccessAllowed('view_own_projects') || ttAccessAllowed('manage_projects'))) { header('Location: access_denied.php'); diff --git a/mobile/task_add.php b/mobile/task_add.php deleted file mode 100644 index db73d1c77..000000000 --- a/mobile/task_add.php +++ /dev/null @@ -1,87 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_description = trim($request->getParameter('description')); - $cl_projects = $request->getParameter('projects'); -} else { - foreach ($projects as $project_item) - $cl_projects[] = $project_item['id']; -} - -$form = new Form('taskForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); -$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - - if ($err->no()) { - if (!ttTaskHelper::getTaskByName($cl_name)) { - if (ttTaskHelper::insert(array( - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => ACTIVE, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.taskForm.name.focus()"'); -$smarty->assign('title', $i18n->get('title.add_task')); -$smarty->assign('content_page_name', 'mobile/task_add.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/task_delete.php b/mobile/task_delete.php deleted file mode 100644 index dd0dae935..000000000 --- a/mobile/task_delete.php +++ /dev/null @@ -1,78 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_task_id = (int)$request->getParameter('id'); -$task = ttTaskHelper::get($cl_task_id); -if (!$task) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$task_to_delete = $task['name']; - -$form = new Form('taskDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_task_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if(ttTaskHelper::get($cl_task_id)) { - if (ttTaskHelper::delete($cl_task_id)) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.db')); - } elseif ($request->getParameter('btn_cancel')) { - header('Location: tasks.php'); - exit(); - } -} // isPost - -$smarty->assign('task_to_delete', $task_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_task')); -$smarty->assign('content_page_name', 'mobile/task_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/task_edit.php b/mobile/task_edit.php deleted file mode 100644 index 02a947676..000000000 --- a/mobile/task_edit.php +++ /dev/null @@ -1,128 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_task_id = (int)$request->getParameter('id'); -$task = ttTaskHelper::get($cl_task_id); -if (!$task) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_description = trim($request->getParameter('description')); - $cl_status = $request->getParameter('status'); - $cl_projects = $request->getParameter('projects'); -} else { - $cl_name = $task['name']; - $cl_description = $task['description']; - $cl_status = $task['status']; - $assigned_projects = ttTaskHelper::getAssignedProjects($cl_task_id); - foreach ($assigned_projects as $project_item) - $cl_projects[] = $project_item['id']; -} - -$form = new Form('taskForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_task_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $existing_task = ttTaskHelper::getTaskByName($cl_name); - if (!$existing_task || ($cl_task_id == $existing_task['id'])) { - // Update task information. - if (ttTaskHelper::update(array( - 'task_id' => $cl_task_id, - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttTaskHelper::getTaskByName($cl_name)) { - if (ttTaskHelper::insert(array( - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_delete')) { - header("Location: task_delete.php?id=$cl_task_id"); - exit(); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.edit_task')); -$smarty->assign('content_page_name', 'mobile/task_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/tasks.php b/mobile/tasks.php index 2745df23a..960990166 100644 --- a/mobile/tasks.php +++ b/mobile/tasks.php @@ -30,6 +30,11 @@ import('form.Form'); import('ttGroupHelper'); +// Mobile pages are no longer separate. Redirect to main page. +header('Location: ../tasks.php'); +exit(); +// Below is no longer used code. + // Access checks. if (!(ttAccessAllowed('view_own_tasks') || ttAccessAllowed('manage_tasks'))) { header('Location: access_denied.php'); diff --git a/mobile/time_delete.php b/mobile/time_delete.php deleted file mode 100644 index e80c5c733..000000000 --- a/mobile/time_delete.php +++ /dev/null @@ -1,89 +0,0 @@ -getParameter('id'); -$time_rec = ttTimeHelper::getRecord($cl_id); -if (!$time_rec || $time_rec['approved'] || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { - // Prohibit deleting not ours, approved, assigned to timesheet, or invoiced records. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$trackingMode = $user->getTrackingMode(); -$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; - -if ($request->isPost()) { - if ($request->getParameter('delete_button')) { // Delete button pressed. - - // Determine if it's okay to delete the record. - $item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); - - // Determine if the record is uncompleted. - $uncompleted = ($time_rec['duration'] == '0:00'); - - if ($user->isDateLocked($item_date) && !$uncompleted) - $err->add($i18n->get('error.range_locked')); - - if ($err->no()) { - // Delete the record. - if (ttTimeHelper::delete($cl_id)) { - header('Location: time.php'); - exit(); - } else { - $err->add($i18n->get('error.db')); - } - } - } - if ($request->getParameter('cancel_button')) { // Cancel button pressed. - header('Location: time.php'); - exit(); - } -} // isPost - -$form = new Form('timeRecordForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); -$smarty->assign('time_rec', $time_rec); -$smarty->assign('show_project', $showProject); -$smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('title', $i18n->get('title.delete_time_record')); -$smarty->assign('content_page_name', 'mobile/time_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/time_edit.php b/mobile/time_edit.php deleted file mode 100644 index fb3a918dc..000000000 --- a/mobile/time_edit.php +++ /dev/null @@ -1,494 +0,0 @@ -getParameter('id'); -$time_rec = ttTimeHelper::getRecord($cl_id); -if (!$time_rec || $time_rec['approved'] || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { - // Prohibit editing not ours, approved, assigned to timesheet, or invoiced records. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$user_id = $user->getUser(); -$config = new ttConfigHelper($user->getConfig()); - -$showClient = $user->isPluginEnabled('cl'); -$showBillable = $user->isPluginEnabled('iv'); -$showPaidStatus = $user->isPluginEnabled('ps') && $user->can('manage_invoices'); -$trackingMode = $user->getTrackingMode(); -$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; -$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; -if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); -$recordType = $user->getRecordType(); -$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; -$showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('../plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -$item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); -$confirm_save = $user->getConfigOption('confirm_save'); - -// Initialize variables. -$cl_start = $cl_finish = $cl_duration = $cl_date = $cl_note = $cl_project = $cl_task = $cl_billable = null; -if ($request->isPost()) { - $cl_start = trim($request->getParameter('start')); - $cl_finish = trim($request->getParameter('finish')); - $cl_duration = trim($request->getParameter('duration')); - $cl_date = $request->getParameter('date'); - $cl_note = trim($request->getParameter('note')); - // If we have user custom fields - collect input. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($request->getParameter($control_name))); - } - } - $cl_client = $request->getParameter('client'); - $cl_project = $request->getParameter('project'); - $cl_task = $request->getParameter('task'); - $cl_billable = 1; - if ($showBillable) - $cl_billable = $request->getParameter('billable'); - if ($showPaidStatus) - $cl_paid = $request->getParameter('paid'); -} else { - $cl_client = $time_rec['client_id']; - $cl_project = $time_rec['project_id']; - $cl_task = $time_rec['task_id']; - $cl_start = $time_rec['start']; - $cl_finish = $time_rec['finish']; - $cl_duration = $time_rec['duration']; - $cl_date = $item_date->toString($user->getDateFormat()); - $cl_note = $time_rec['comment']; - - // If we have time custom fields - collect values from database. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => $custom_fields->getTimeFieldValue($cl_id, $timeField['id'], $timeField['type'])); - } - } - - $cl_billable = $time_rec['billable']; - $cl_paid = $time_rec['paid']; - - // Add an info message to the form if we are editing an uncompleted record. - if (strlen($cl_start) > 0 && $cl_start == $cl_finish && $cl_duration == '0:00') { - $cl_finish = ''; - $cl_duration = ''; - $msg->add($i18n->get('form.time_edit.uncompleted')); - } -} - -// Initialize elements of 'timeRecordForm'. -$form = new Form('timeRecordForm'); - -// Dropdown for clients in MODE_TIME. Use all active clients. -// Note: for other tracking modes the control is added further below. -if (MODE_TIME == $trackingMode && $showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -// Billable checkbox. -if ($showBillable) - $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); - -// Paid status checkbox. -if ($showPaidStatus) - $form->addInput(array('type'=>'checkbox','name'=>'paid','value'=>$cl_paid)); - -// If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$timeCustomFields[$timeField['id']]['value'])); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($timeField['id']), - 'value'=>$timeCustomFields[$timeField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -// If we show project dropdown, add controls for project and client. -if ($showProject) { - // Dropdown for projects assigned to user. - $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); - $project_list = $user->getAssignedProjects($options); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);prepopulateNote();', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - if (is_array($projects_assigned_to_client) && is_array($projects_assigned_to_user)) - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} - -// Task dropdown. -if ($showTask) { - $task_list = ttGroupHelper::getActiveTasks(); - $form->addInput(array('type'=>'combobox', - 'name'=>'task', - 'style'=>'width: 250px;', - 'value'=>$cl_task, - 'data'=>$task_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); -} - -// Start and finish controls. -if ($showStart) { - $form->addInput(array('type'=>'text','name'=>'start','value'=>$cl_start,'onchange'=>"formDisable('start');")); - $form->addInput(array('type'=>'text','name'=>'finish','value'=>$cl_finish,'onchange'=>"formDisable('finish');")); - if ($user->punch_mode && !$user->canOverridePunchMode()) { - // Make the start and finish fields read-only. - $form->getElement('start')->setEnabled(false); - $form->getElement('finish')->setEnabled(false); - } -} - -// Duration control. -if ($showDuration) - $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); - -// Date field. -$form->addInput(array('type'=>'datefield','name'=>'date','maxlength'=>'20','value'=>$cl_date)); - -// If we have templates, add a dropdown to select one. -if ($user->isPluginEnabled('tp')){ - $template_list = ttGroupHelper::getActiveTemplates(); - if (count($template_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillNote(this.value);', - 'name'=>'template', - 'style'=>'width: 250px;', - 'data'=>$template_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $smarty->assign('template_dropdown', 1); - $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); - $smarty->assign('prepopulate_note', $config->getDefinedValue('prepopulate_note')); - $smarty->assign('template_list', $template_list); - } -} - -// Note control. -$form->addInput(array('type'=>'textarea','name'=>'note','class'=>'mobile-textarea','value'=>$cl_note)); - -// Hidden control for record id. -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); - -// A hidden control for today's date from user's browser. -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save click. - -// Copy button. -$on_click_action = 'browser_today.value=get_date();'; -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>$on_click_action,'value'=>$i18n->get('button.copy'))); - -// Save button. -if ($confirm_save) $on_click_action .= 'return(confirmSave());'; -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>$on_click_action,'value'=>$i18n->get('button.save'))); - -// Delete button. -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - - // Validate user input. - if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - // Validate input in time custom fields. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($timeCustomFields as $timeField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); - } - } - if ($showProject) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } - if ($showTask && $task_required) { - if (!$cl_task) $err->add($i18n->get('error.task')); - } - if (!$cl_duration) { - if ('0' == $cl_duration) - $err->add($i18n->get('error.field'), $i18n->get('label.duration')); - elseif ($cl_start || $cl_finish) { - if (!ttTimeHelper::isValidTime($cl_start)) - $err->add($i18n->get('error.field'), $i18n->get('label.start')); - if ($cl_finish) { - if (!ttTimeHelper::isValidTime($cl_finish)) - $err->add($i18n->get('error.field'), $i18n->get('label.finish')); - if (!ttTimeHelper::isValidInterval($cl_start, $cl_finish)) - $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); - } - } else { - if ($showStart) { - $err->add($i18n->get('error.empty'), $i18n->get('label.start')); - $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); - } - if ($showDuration) - $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); - } - } else { - if (false === ttTimeHelper::postedDurationToMinutes($cl_duration)) - $err->add($i18n->get('error.field'), $i18n->get('label.duration')); - } - if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); - if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); - if ($user->isPluginEnabled('tp') && !ttValidTemplateText($cl_note)) { - $err->add($i18n->get('error.field'), $i18n->get('label.note')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating user input. - - // This is a new date for the time record. - $new_date = new DateAndTime($user->getDateFormat(), $cl_date); - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($new_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - - // Save record. - if ($request->getParameter('btn_save')) { - // We need to: - // 1) Prohibit saving locked entries in any form. - // 2) Prohibit saving completed unlocked entries into locked range. - // 3) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. - - // Now, step by step. - if ($err->no()) { - // 1) Prohibit saving locked entries in any form. - if ($user->isDateLocked($item_date)) - $err->add($i18n->get('error.range_locked')); - - // 2) Prohibit saving completed unlocked entries into locked range. - if ($err->no() && $user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // 3) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. - $uncompleted = ($cl_finish == '' && $cl_duration == ''); - if ($uncompleted) { - $not_completed_rec = ttTimeHelper::getUncompleted($user_id); - if ($not_completed_rec && ($time_rec['id'] <> $not_completed_rec['id'])) { - // We have another not completed record. - $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); - } - } - } - - // Prohibit creating an overlapping record. - if ($err->no()) { - if (ttTimeHelper::overlaps($user_id, $new_date->toString(DB_DATEFORMAT), $cl_start, $cl_finish, $cl_id)) - $err->add($i18n->get('error.overlap')); - } - - // Now, an update. - if ($err->no()) { - $res = ttTimeHelper::update(array( - 'id'=>$cl_id, - 'date'=>$new_date->toString(DB_DATEFORMAT), - 'client'=>$cl_client, - 'project'=>$cl_project, - 'task'=>$cl_task, - 'start'=>$cl_start, - 'finish'=>$cl_finish, - 'duration'=>$cl_duration, - 'note'=>$cl_note, - 'billable'=>$cl_billable, - 'paid'=>$cl_paid)); - - // Update time custom fields if we have them. - if ($res && $custom_fields && $custom_fields->timeFields) { - $res = $custom_fields->updateTimeFields($cl_id, $timeCustomFields); - } - if ($res) - { - header('Location: time.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } - } - } - - // Copy record. - if ($request->getParameter('btn_copy')) { - // We need to: - // 1) Prohibit saving into locked range. - // 2) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. - - // Now, step by step. - if ($err->no()) { - // 1) Prohibit saving into locked range. - if ($user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // 2) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. - $uncompleted = ($cl_finish == '' && $cl_duration == ''); - if ($uncompleted) { - $not_completed_rec = ttTimeHelper::getUncompleted($user_id); - if ($not_completed_rec) { - // We have another not completed record. - $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); - } - } - } - - // Prohibit creating an overlapping record. - if ($err->no()) { - if (ttTimeHelper::overlaps($user_id, $new_date->toString(DB_DATEFORMAT), $cl_start, $cl_finish)) - $err->add($i18n->get('error.overlap')); - } - - // Now, a new insert. - if ($err->no()) { - - $id = ttTimeHelper::insert(array( - 'date'=>$new_date->toString(DB_DATEFORMAT), - 'client'=>$cl_client, - 'project'=>$cl_project, - 'task'=>$cl_task, - 'start'=>$cl_start, - 'finish'=>$cl_finish, - 'duration'=>$cl_duration, - 'note'=>$cl_note, - 'billable'=>$cl_billable, - 'paid'=>$cl_paid)); - - // Insert time custom fields if we have them. - $res = true; - if ($id && $custom_fields && $custom_fields->timeFields) { - $res = $custom_fields->insertTimeFields($id, $timeCustomFields); - } - if ($id && $res) { - header('Location: time.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } - $err->add($i18n->get('error.db')); - } - } - - if ($request->getParameter('btn_delete')) { - header("Location: time_delete.php?id=$cl_id"); - exit(); - } -} // isPost - -if ($confirm_save) { - $smarty->assign('confirm_save', true); - $smarty->assign('entry_date', $cl_date); -} -$smarty->assign('show_client', $showClient); -$smarty->assign('show_billable', $showBillable);+ -$smarty->assign('show_paid_status', $showPaidStatus); -$smarty->assign('show_project', $showProject); -$smarty->assign('show_task', $showTask); -$smarty->assign('task_required', $taskRequired); -$smarty->assign('show_start', $showStart); -$smarty->assign('show_duration', $showDuration); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="fillDropdowns()"'); -$smarty->assign('title', $i18n->get('title.edit_time_record')); -$smarty->assign('content_page_name', 'mobile/time_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/user_add.php b/mobile/user_add.php deleted file mode 100644 index ed017de8a..000000000 --- a/mobile/user_add.php +++ /dev/null @@ -1,186 +0,0 @@ -isPluginEnabled('mq'); -if ($user->isPluginEnabled('cl')) - $clients = ttGroupHelper::getActiveClients(); - -$assigned_projects = array(); -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_login = trim($request->getParameter('login')); - if (!$auth->isPasswordExternal()) { - $cl_password1 = $request->getParameter('pas1'); - $cl_password2 = $request->getParameter('pas2'); - } - $cl_email = trim($request->getParameter('email')); - $cl_role_id = $request->getParameter('role'); - $cl_client_id = $request->getParameter('client'); - $cl_rate = $request->getParameter('rate'); - $cl_quota_percent = $request->getParameter('quota_percent'); - $cl_projects = $request->getParameter('projects'); - if (is_array($cl_projects)) { - foreach ($cl_projects as $p) { - if (ttValidFloat($request->getParameter('rate_'.$p), true)) { - $project_with_rate = array(); - $project_with_rate['id'] = $p; - $project_with_rate['rate'] = $request->getParameter('rate_'.$p); - $assigned_projects[] = $project_with_rate; - } else - $err->add($i18n->get('error.field'), 'rate_'.$p); - } - } -} - -$form = new Form('userForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','value'=>$cl_login)); -if (!$auth->isPasswordExternal()) { - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas1','value'=>$cl_password1)); - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas2','value'=>$cl_password2)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email)); - -$active_roles = ttTeamHelper::getActiveRolesForUser(); -$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles,'datakeys'=>array('id', 'name'))); -if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); - -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -if ($show_quota) - $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); - -$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); -if ($show_projects) { - $projects = ttGroupHelper::getActiveProjects(); - if (count($projects) == 0) $show_projects = false; -} - -// Define classes for the projects table. -class NameCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200,'valign'=>'top')); - $this->setValue(''); - return $this->toString(); - } -} -class RateCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - global $assigned_projects; - $field = new FloatField('rate_'.$table->getValueAtName($row, 'id')); - $field->setFormName($table->getFormName()); - $field->setSize(5); - $field->setFormat('.2'); - foreach ($assigned_projects as $p) { - if ($p['id'] == $table->getValueAtName($row,'id')) $field->setValue($p['rate']); - } - $this->setValue($field->getHtml()); - return $this->toString(); - } -} -// Create projects table. -$table = new Table('projects'); -$table->setIAScript('setDefaultRate'); -$table->setTableOptions(array('width'=>'250','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); -$table->setData($projects); -$table->setKeyField('id'); -$table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); -$form->addInputElement($table); - -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); - if (!$auth->isPasswordExternal()) { - if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); - } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); - if (!ttUserHelper::canAdd()) $err->add($i18n->get('error.user_count')); - - if ($err->no()) { - if (!ttUserHelper::getUserByLogin($cl_login)) { - $fields = array( - 'name' => $cl_name, - 'login' => $cl_login, - 'password' => $cl_password1, - 'rate' => $cl_rate, - 'quota_percent' => $cl_quota_percent, - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'role_id' => $cl_role_id, - 'client_id' => $cl_client_id, - 'projects' => $assigned_projects, - 'email' => $cl_email); - if (ttUserHelper::insert($fields)) { - header('Location: users.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.user_exists')); - } -} // isPost - -$smarty->assign('auth_external', $auth->isPasswordExternal()); -$smarty->assign('active_roles', $active_roles); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); -$smarty->assign('show_quota', $show_quota); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('title', $i18n->get('title.add_user')); -$smarty->assign('content_page_name', 'mobile/user_add.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/user_delete.php b/mobile/user_delete.php deleted file mode 100644 index 132f73022..000000000 --- a/mobile/user_delete.php +++ /dev/null @@ -1,87 +0,0 @@ -getParameter('id'); -$user_details = $user->getUserDetails($user_id); -if (!$user_details) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$smarty->assign('user_to_delete', $user_details['name']." (".$user_details['login'].")"); - -// Create confirmation form. -$form = new Form('userDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$user_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if ($user->markUserDeleted($user_id)) { - // If we deleted the "on behalf" user reset its info in session. - if ($user_id == $user->behalf_id) { - unset($_SESSION['behalf_id']); - unset($_SESSION['behalf_name']); - } - // If we deleted our own account, do housekeeping and logout. - if ($user->id == $user_id) { - // Remove LOGIN_COOKIE_NAME cookie that stores login name. - unset($_COOKIE[LOGIN_COOKIE_NAME]); - setcookie(LOGIN_COOKIE_NAME, NULL, -1); - - $auth->doLogout(); - header('Location: login.php'); - } else { - header('Location: users.php'); - } - exit(); - } else { - $err->add($i18n->get('error.db')); - } - } - if ($request->getParameter('btn_cancel')) { - header('Location: users.php'); - exit(); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.delete_user')); -$smarty->assign('content_page_name', 'mobile/user_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/user_edit.php b/mobile/user_edit.php deleted file mode 100644 index 58de5e8ab..000000000 --- a/mobile/user_edit.php +++ /dev/null @@ -1,245 +0,0 @@ -getParameter('id'); -$user_details = $user->getUserDetails($user_id); -if (!$user_details) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$show_quota = $user->isPluginEnabled('mq'); -if ($user->isPluginEnabled('cl')) - $clients = ttGroupHelper::getActiveClients(); - -$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); -if ($show_projects) { - $projects = ttGroupHelper::getActiveProjects(); - if (count($projects) == 0) $show_projects = false; -} -$assigned_projects = array(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_login = trim($request->getParameter('login')); - if (!$auth->isPasswordExternal()) { - $cl_password1 = $request->getParameter('pas1'); - $cl_password2 = $request->getParameter('pas2'); - } - $cl_email = trim($request->getParameter('email')); - $cl_role_id = $request->getParameter('role'); - $cl_client_id = $request->getParameter('client'); - $cl_status = $request->getParameter('status'); - $cl_rate = $request->getParameter('rate'); - $cl_quota_percent = $request->getParameter('quota_percent'); - $cl_projects = $request->getParameter('projects'); - if (is_array($cl_projects)) { - foreach ($cl_projects as $p) { - if (ttValidFloat($request->getParameter('rate_'.$p), true)) { - $project_with_rate = array(); - $project_with_rate['id'] = $p; - $project_with_rate['rate'] = $request->getParameter('rate_'.$p); - $assigned_projects[] = $project_with_rate; - } else - $err->add($i18n->get('error.field'), 'rate_'.$p); - } - } -} else { - $cl_name = $user_details['name']; - $cl_login = $user_details['login']; - $cl_email = $user_details['email']; - $cl_rate = str_replace('.', $user->getDecimalMark(), $user_details['rate']); - $cl_quota_percent = str_replace('.', $user->getDecimalMark(), $user_details['quota_percent']); - $cl_role_id = $user_details['role_id']; - $cl_client_id = $user_details['client_id']; - $cl_status = $user_details['status']; - $cl_projects = array(); - $assigned_projects = ttProjectHelper::getAssignedProjects($user_id); - foreach($assigned_projects as $p) { - $cl_projects[] = $p['id']; - } -} - -$form = new Form('userForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','value'=>$cl_login)); -if (!$auth->isPasswordExternal()) { - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas1','value'=>$cl_password1)); - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas2','value'=>$cl_password2)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email)); - -$active_roles = ttTeamHelper::getActiveRolesForUser(); -$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles,'datakeys'=>array('id', 'name'))); -if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); - -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -if ($show_quota) - $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); - -// Define classes for the projects table. -class NameCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200,'valign'=>'top')); - $this->setValue(''); - return $this->toString(); - } -} -class RateCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - global $assigned_projects; - $field = new FloatField('rate_'.$table->getValueAtName($row,'id')); - $field->setFormName($table->getFormName()); - $field->setSize(5); - $field->setFormat('.2'); - foreach ($assigned_projects as $p) { - if ($p['id'] == $table->getValueAtName($row,'id')) $field->setValue($p['rate']); - } - $this->setValue($field->getHtml()); - return $this->toString(); - } -} -// Create projects table. -$table = new Table('projects'); -$table->setIAScript('setRate'); -$table->setTableOptions(array('width'=>'250','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); -$table->setData($projects); -$table->setKeyField('id'); -$table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); -$form->addInputElement($table); - -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$user_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); - if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { - if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); - } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); - - if ($err->no()) { - $existing_user = ttUserHelper::getUserByLogin($cl_login); - if (!$existing_user || ($user_id == $existing_user['id'])) { - - $fields = array( - 'name' => $cl_name, - 'login' => $cl_login, - 'password' => $cl_password1, - 'email' => $cl_email, - 'status' => $cl_status, - 'rate' => $cl_rate, - 'quota_percent' => $cl_quota_percent, - 'projects' => $assigned_projects); - if (in_array('manage_users', $user->rights)) { - $fields['role_id'] = $cl_role_id; - $fields['client_id'] = $cl_client_id; - } - - if (ttUserHelper::update($user_id, $fields)) { - - // If our own login changed, set new one in cookie to remember it. - if (($user_id == $user->id) && ($user->login != $cl_login)) { - setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); - } - - // In case the name of the "on behalf" user has changed - set it in session. - if (($user->behalf_id == $user_id) && ($user->behalf_name != $cl_name)) { - $_SESSION['behalf_name'] = $cl_name; - } - - // If we deactivated our own account, do housekeeping and logout. - if ($user->id == $user_id && !is_null($cl_status) && $cl_status == INACTIVE) { - // Remove LOGIN_COOKIE_NAME cookie that stores login name. - unset($_COOKIE[LOGIN_COOKIE_NAME]); - setcookie(LOGIN_COOKIE_NAME, NULL, -1); - - $auth->doLogout(); - header('Location: login.php'); - exit(); - } - - header('Location: users.php'); - exit(); - - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.user_exists')); - } - } - - if ($request->getParameter('btn_delete')) { - header("Location: user_delete.php?id=$user_id"); - exit(); - } -} // isPost - -$rates = ttProjectHelper::getRates($user_id); -$smarty->assign('rates', $rates); - -$smarty->assign('auth_external', $auth->isPasswordExternal()); -$smarty->assign('active_roles', $active_roles); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); -$smarty->assign('show_quota', $show_quota); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('user_id', $user_id); -$smarty->assign('title', $i18n->get('title.edit_user')); -$smarty->assign('content_page_name', 'mobile/user_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/users.php b/mobile/users.php index d51cafcab..0e52072fb 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -32,6 +32,11 @@ import('ttGroupHelper'); import('ttTimeHelper'); +// Mobile pages are no longer separate. Redirect to main page. +header('Location: ../users.php'); +exit(); +// Below is no longer used code. + // Access checks. if (!(ttAccessAllowed('view_users') || ttAccessAllowed('manage_users'))) { header('Location: access_denied.php'); From 5ba5e875dcf313422b5ab1ad90fc112218deea40 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 7 Dec 2020 18:13:07 +0000 Subject: [PATCH 1415/1848] Cosmetic style improvement. --- default.css | 2 ++ initialize.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index 595967e64..95f56094b 100644 --- a/default.css +++ b/default.css @@ -424,6 +424,8 @@ div.section-header { text-align: center; margin-left: auto; margin-right: auto; + margin-top: .5rem; + margin-bottom: .5rem; } /* div for a group of items in site map */ diff --git a/initialize.php b/initialize.php index 265d13aea..47f069ba8 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5407"); +define("APP_VERSION", "1.19.23.5408"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 1a4d9c3418ce261883057554887f2b36f0c5425b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 8 Dec 2020 13:00:38 +0000 Subject: [PATCH 1416/1848] Improved mobile presentation of vertically stacked checkboxes. --- WEB-INF/templates/client_add2.tpl | 2 +- WEB-INF/templates/client_edit2.tpl | 2 +- WEB-INF/templates/project_add2.tpl | 4 ++-- WEB-INF/templates/project_edit2.tpl | 4 ++-- WEB-INF/templates/task_add2.tpl | 2 +- WEB-INF/templates/task_edit2.tpl | 2 +- default.css | 6 ++++++ initialize.php | 2 +- 8 files changed, 15 insertions(+), 9 deletions(-) diff --git a/WEB-INF/templates/client_add2.tpl b/WEB-INF/templates/client_add2.tpl index 2704a133c..ac7a63efc 100644 --- a/WEB-INF/templates/client_add2.tpl +++ b/WEB-INF/templates/client_add2.tpl @@ -28,7 +28,7 @@ License: See license.txt *}
{$i18n.label.projects}:
{$i18n.label.projects}:{$forms.clientForm.projects.control}{$forms.clientForm.projects.control}
{$i18n.label.projects}:
{$i18n.label.projects}:{$forms.clientForm.projects.control}{$forms.clientForm.projects.control}
{$i18n.label.users}:
{$i18n.label.users}:{$forms.projectForm.users.control}{$forms.projectForm.users.control}
{$i18n.label.tasks}:
{$i18n.label.tasks}:{$forms.projectForm.tasks.control}{$forms.projectForm.tasks.control}
{$i18n.label.users}:
{$i18n.label.users}:{$forms.projectForm.users.control}{$forms.projectForm.users.control}
{$i18n.label.tasks}:
{$i18n.label.tasks}:{$forms.projectForm.tasks.control}{$forms.projectForm.tasks.control}
{$i18n.label.projects}:
{$i18n.label.projects}:{$forms.taskForm.projects.control}{$forms.taskForm.projects.control}
{$i18n.label.projects}:
{$i18n.label.projects}:{$forms.taskForm.projects.control}{$forms.taskForm.projects.control}
'."\n"; $html .= '
'; $html .= '
'; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index c006350fd..b01ffe687 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -347,7 +347,9 @@ function getAssignedProjects($options = null) $group_id = $this->getGroup(); $org_id = $this->org_id; - if ($options['include_files']) { + $filePart = ''; + $fileJoin = ''; + if (isset($options['include_files'])) { $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; $fileJoin = " left join (select distinct entity_id from tt_files". " where entity_type = 'project' and group_id = $group_id and org_id = $org_id and status = 1) Sub1". diff --git a/initialize.php b/initialize.php index 55b1a1034..1aa264cca 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5411"); +define("APP_VERSION", "1.19.23.5412"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 6a5b24018a7c9d5744c84e8135d588b81b9ae6cf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 20 Feb 2021 23:11:47 +0000 Subject: [PATCH 1421/1848] Updated smarty to version 3.1.39 for better php8 support. --- WEB-INF/lib/smarty/Smarty.class.php | 7 +++---- WEB-INF/lib/smarty/SmartyBC.class.php | 2 +- .../smarty_internal_compile_function.php | 5 +++++ ...internal_compile_private_special_variable.php | 8 ++++++-- .../smarty_internal_config_file_compiler.php | 4 ++-- .../sysplugins/smarty_internal_errorhandler.php | 2 +- .../smarty_internal_parsetree_template.php | 16 ++++++++-------- WEB-INF/templates/time2.tpl | 2 ++ initialize.php | 2 +- 9 files changed, 29 insertions(+), 19 deletions(-) diff --git a/WEB-INF/lib/smarty/Smarty.class.php b/WEB-INF/lib/smarty/Smarty.class.php index 9e0ca7670..375bab133 100644 --- a/WEB-INF/lib/smarty/Smarty.class.php +++ b/WEB-INF/lib/smarty/Smarty.class.php @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * version 3.0 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -27,7 +27,6 @@ * @author Uwe Tews * @author Rodney Rehm * @package Smarty - * @version 3.1.34-dev */ /** * set SMARTY_DIR to absolute path to Smarty library files. @@ -112,7 +111,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.36'; + const SMARTY_VERSION = '3.1.39'; /** * define variable scopes */ @@ -800,7 +799,7 @@ public function addTemplateDir($template_dir, $key = null, $isConfig = false) * @param mixed $index index of directory to get, null to get all * @param bool $isConfig true for config_dir * - * @return array list of template directories, or directory of $index + * @return array|string list of template directories, or directory of $index */ public function getTemplateDir($index = null, $isConfig = false) { diff --git a/WEB-INF/lib/smarty/SmartyBC.class.php b/WEB-INF/lib/smarty/SmartyBC.class.php index 836f98153..0550e46dc 100644 --- a/WEB-INF/lib/smarty/SmartyBC.class.php +++ b/WEB-INF/lib/smarty/SmartyBC.class.php @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * version 3.0 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php index 6e408ca72..d0f2b0f4a 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php @@ -58,6 +58,11 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler) } unset($_attr[ 'nocache' ]); $_name = trim($_attr[ 'name' ], '\'"'); + + if (!preg_match('/^[a-zA-Z0-9_\x80-\xff]+$/', $_name)) { + $compiler->trigger_template_error("Function name contains invalid characters: {$_name}", null, true); + } + $compiler->parent_compiler->tpl_function[ $_name ] = array(); $save = array( $_attr, $compiler->parser->current_buffer, $compiler->template->compiled->has_nocache_code, diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_special_variable.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_special_variable.php index b317c9f33..d53ef51ff 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_special_variable.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_special_variable.php @@ -81,6 +81,10 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $ case 'template': return 'basename($_smarty_tpl->source->filepath)'; case 'template_object': + if (isset($compiler->smarty->security_policy)) { + $compiler->trigger_template_error("(secure mode) template_object not permitted"); + break; + } return '$_smarty_tpl'; case 'current_dir': return 'dirname($_smarty_tpl->source->filepath)'; @@ -94,9 +98,9 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $ break; } if (strpos($_index[ 1 ], '$') === false && strpos($_index[ 1 ], '\'') === false) { - return "@constant('{$_index[1]}')"; + return "(defined('{$_index[1]}') ? constant('{$_index[1]}') : null)"; } else { - return "@constant({$_index[1]})"; + return "(defined({$_index[1]}) ? constant({$_index[1]}) : null)"; } // no break case 'config': diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php index a842fa8f3..90c5dcefa 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php @@ -115,7 +115,7 @@ public function compileTemplate(Smarty_Internal_Template $template) $this->smarty->_debug->start_compile($this->template); } // init the lexer/parser to compile the config file - /* @var Smarty_Internal_ConfigFileLexer $this ->lex */ + /* @var Smarty_Internal_ConfigFileLexer $this->lex */ $this->lex = new $this->lexer_class( str_replace( array( @@ -127,7 +127,7 @@ public function compileTemplate(Smarty_Internal_Template $template) ) . "\n", $this ); - /* @var Smarty_Internal_ConfigFileParser $this ->parser */ + /* @var Smarty_Internal_ConfigFileParser $this->parser */ $this->parser = new $this->parser_class($this->lex, $this); if (function_exists('mb_internal_encoding') && function_exists('ini_get') diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php index 0ba00659d..56dca18fa 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php @@ -65,7 +65,7 @@ public static function muteExpectedErrors() * * @return bool */ - public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) + public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext = array()) { $_is_muted_directory = false; // add the SMARTY_DIR to the list of muted directories diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php index 477232ef8..ab4c3ec3b 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php @@ -127,12 +127,12 @@ public function to_smarty_php(Smarty_Internal_Templateparser $parser) } private function getChunkedSubtrees() { - $chunks = []; + $chunks = array(); $currentMode = null; - $currentChunk = []; + $currentChunk = array(); for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) { - if ($this->subtrees[ $key ]->data === '' && in_array($currentMode, ['textstripped', 'text', 'tag'])) { + if ($this->subtrees[ $key ]->data === '' && in_array($currentMode, array('textstripped', 'text', 'tag'))) { continue; } @@ -150,19 +150,19 @@ private function getChunkedSubtrees() { if ($newMode == $currentMode) { $currentChunk[] = $this->subtrees[ $key ]; } else { - $chunks[] = [ + $chunks[] = array( 'mode' => $currentMode, 'subtrees' => $currentChunk - ]; + ); $currentMode = $newMode; - $currentChunk = [$this->subtrees[ $key ]]; + $currentChunk = array($this->subtrees[ $key ]); } } if ($currentMode && $currentChunk) { - $chunks[] = [ + $chunks[] = array( 'mode' => $currentMode, 'subtrees' => $currentChunk - ]; + ); } return $chunks; } diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time2.tpl index 487bff7cf..65216efb8 100644 --- a/WEB-INF/templates/time2.tpl +++ b/WEB-INF/templates/time2.tpl @@ -234,3 +234,5 @@ License: See license.txt *} {/if}
+ +{$smarty.version} diff --git a/initialize.php b/initialize.php index 1aa264cca..771995d88 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5412"); +define("APP_VERSION", "1.19.23.5413"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 85823f48d86f438909af947b57038a1090283030 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 26 Feb 2021 16:24:51 +0000 Subject: [PATCH 1422/1848] A minor fix to dbinstall.php to address a migration issue with custom fields. --- dbinstall.php | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dbinstall.php b/dbinstall.php index 59d3923f8..9960e1ade 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -691,10 +691,10 @@ function ttGenerateKeys() { print "Updated $clients_updated clients...
\n"; } - // The update_custom_fields function updates option_id field field in tt_custom_field_log table. + // The update_custom_fields function updates option_id field in tt_custom_field_log table. if ($_POST['update_custom_fields']) { $mdb2 = getConnection(); - $sql = "update tt_custom_field_log set option_id = value where field_id in (select id from tt_custom_fields where type = 2)"; + $sql = "update tt_custom_field_log set option_id = value where option_id is null and value is not null and field_id in (select id from tt_custom_fields where type = 2)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); diff --git a/initialize.php b/initialize.php index 771995d88..5323d00b8 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5413"); +define("APP_VERSION", "1.19.23.5414"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 40f3d9345adc20e6f28eb9f59e2489aff87fecf5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 16:00:53 +0000 Subject: [PATCH 1423/1848] Fixed a critical security vulnerability with password resets. --- WEB-INF/templates/report.tpl | 4 ++++ initialize.php | 2 +- password_reset.php | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index f7ef4ff2e..0a13ea83a 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -117,6 +117,7 @@ {if $bean->getAttribute('chtimesheet')}
 
{$i18n.label.edit}
diff --git a/initialize.php b/initialize.php index 5323d00b8..e2aeb6c85 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5414"); +define("APP_VERSION", "1.19.24.5415"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/password_reset.php b/password_reset.php index 5beafb7fc..53099b9af 100644 --- a/password_reset.php +++ b/password_reset.php @@ -46,7 +46,10 @@ if ($err->no()) { // Prepare and save a temporary reference for user. - $temp_ref = md5(uniqid()); + $cryptographically_strong = true; + $random_bytes = openssl_random_pseudo_bytes(16, $cryptographically_strong); + if ($random_bytes === false) die ("openssl_random_pseudo_bytes function call failed..."); + $temp_ref = bin2hex($random_bytes); ttUserHelper::saveTmpRef($temp_ref, $user->id); $user_i18n = null; From 1339c3a043a916cd7f5142c3aec4a956b598f69c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 16:19:09 +0000 Subject: [PATCH 1424/1848] Added protection against brute force guessing of random codes used in password resets. --- WEB-INF/lib/ttUserHelper.class.php | 5 +++++ initialize.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index eac057304..accabe1fe 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -82,6 +82,11 @@ static function getUserByEmail($email) { static function getUserIdByTmpRef($ref) { $mdb2 = getConnection(); + // Some protection for brute force attacks to guess a reference for user. + // This limits an available window for brute force guessing to 1 hour. + $sql = "delete from tt_tmp_refs where created < now() - interval 1 hour"; + $affected = $mdb2->exec($sql); + $sql = "select user_id from tt_tmp_refs where ref = ".$mdb2->quote($ref); $res = $mdb2->query($sql); diff --git a/initialize.php b/initialize.php index e2aeb6c85..63215b71e 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.24.5415"); +define("APP_VERSION", "1.19.24.5416"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 9a8ee13a037931d29130379c9ad193613b45998c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 17:35:22 +0000 Subject: [PATCH 1425/1848] Fixed SQL injection vulnerability in group_edit.php. --- group_edit.php | 6 ++++-- initialize.php | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/group_edit.php b/group_edit.php index c8ad2e142..f60a11331 100644 --- a/group_edit.php +++ b/group_edit.php @@ -32,15 +32,17 @@ import('ttRoleHelper'); import('ttConfigHelper'); +$id = (int)$request->getParameter('id'); + // Access checks. // There are 4 distinct situations: // 1) Editing home group in get or post. // 2) Editing a subgroup in get or post. // We'll check access separately as it is about different right checks. if ($request->isGet()) { - $group_id = $request->getParameter('id') ? $request->getParameter('id') : $user->getGroup(); + $group_id = $request->getParameter('id') ? (int)$request->getParameter('id') : $user->getGroup(); } else { - $group_id = $request->getParameter('group') ? $request->getParameter('group') : $user->getGroup(); + $group_id = $request->getParameter('group') ? (int)$request->getParameter('group') : $user->getGroup(); } $home_group = $user->group_id == $group_id; if ($home_group) { diff --git a/initialize.php b/initialize.php index 63215b71e..f069495f9 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.24.5416"); +define("APP_VERSION", "1.19.25.5417"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 2b34dc2006121e466513b50015262c6936c876bf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 17:37:58 +0000 Subject: [PATCH 1426/1848] Removed garbage introduced in previous commit. --- group_edit.php | 2 -- initialize.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/group_edit.php b/group_edit.php index f60a11331..49bd1e613 100644 --- a/group_edit.php +++ b/group_edit.php @@ -32,8 +32,6 @@ import('ttRoleHelper'); import('ttConfigHelper'); -$id = (int)$request->getParameter('id'); - // Access checks. // There are 4 distinct situations: // 1) Editing home group in get or post. diff --git a/initialize.php b/initialize.php index f069495f9..7863d0aba 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.25.5417"); +define("APP_VERSION", "1.19.25.5418"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From fdf67755ae8396162b19332e3b10763c9ea274b2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 17:49:19 +0000 Subject: [PATCH 1427/1848] More protection against sql injections. --- group_edit.php | 28 ++-------------------------- groups.php | 30 +++--------------------------- initialize.php | 2 +- 3 files changed, 6 insertions(+), 54 deletions(-) diff --git a/group_edit.php b/group_edit.php index 49bd1e613..d972ba387 100644 --- a/group_edit.php +++ b/group_edit.php @@ -1,30 +1,6 @@ isPost()) { - $group_id = $request->getParameter('group'); + $group_id = (int)$request->getParameter('group'); $user->setOnBehalfGroup($group_id); } else { $group_id = $user->getGroup(); diff --git a/initialize.php b/initialize.php index 7863d0aba..40ccda78d 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.25.5418"); +define("APP_VERSION", "1.19.25.5419"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 00885b9872c31eb3298b047ee2a27b278248d4c5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 18:22:24 +0000 Subject: [PATCH 1428/1848] Added casts to int to sanitize some post parameters. --- admin_group_add.php | 28 ++-------------------------- admin_group_delete.php | 28 ++-------------------------- admin_group_edit.php | 28 ++-------------------------- admin_groups.php | 28 ++-------------------------- admin_options.php | 28 ++-------------------------- cf_custom_field_add.php | 36 +++++------------------------------- initialize.php | 2 +- 7 files changed, 16 insertions(+), 162 deletions(-) diff --git a/admin_group_add.php b/admin_group_add.php index c42644f09..45aa32261 100644 --- a/admin_group_add.php +++ b/admin_group_add.php @@ -1,30 +1,6 @@ isPost()) { $cl_field_name = trim($request->getParameter('name')); - $cl_entity_type = $request->getParameter('entity'); - $cl_field_type = $request->getParameter('type'); - $cl_required = $request->getParameter('required'); - if (!$cl_required) - $cl_required = 0; + $cl_entity_type = (int)$request->getParameter('entity'); + $cl_field_type = (int)$request->getParameter('type'); + $cl_required = (int)$request->getParameter('required'); } $form = new Form('fieldForm'); diff --git a/initialize.php b/initialize.php index 40ccda78d..c5edb812a 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.25.5419"); +define("APP_VERSION", "1.19.25.5420"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From bc006920353e50e27d815a8f5d529269080db40e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 18:50:14 +0000 Subject: [PATCH 1429/1848] More sanitizing of user input. --- cf_custom_field_delete.php | 28 ++-------------------------- cf_custom_field_edit.php | 28 ++-------------------------- cf_custom_fields.php | 28 ++-------------------------- cf_dropdown_option_add.php | 28 ++-------------------------- cf_dropdown_option_delete.php | 30 +++--------------------------- cf_dropdown_option_edit.php | 30 +++--------------------------- cf_dropdown_options.php | 28 ++-------------------------- 7 files changed, 16 insertions(+), 184 deletions(-) diff --git a/cf_custom_field_delete.php b/cf_custom_field_delete.php index c8a133692..ba222c657 100644 --- a/cf_custom_field_delete.php +++ b/cf_custom_field_delete.php @@ -1,30 +1,6 @@ getParameter('id'); +$cl_id = (int)$request->getParameter('id'); $option = CustomFields::getOptionName($cl_id); if (!$option) { header('Location: access_denied.php'); diff --git a/cf_dropdown_option_edit.php b/cf_dropdown_option_edit.php index 4f1103d7b..4cea7358f 100644 --- a/cf_dropdown_option_edit.php +++ b/cf_dropdown_option_edit.php @@ -1,30 +1,6 @@ getParameter('id'); +$cl_id = (int)$request->getParameter('id'); $cl_name = CustomFields::getOptionName($cl_id); if (!$cl_name) { header('Location: access_denied.php'); diff --git a/cf_dropdown_options.php b/cf_dropdown_options.php index 3b4663f8c..06f53a7d8 100644 --- a/cf_dropdown_options.php +++ b/cf_dropdown_options.php @@ -1,30 +1,6 @@ Date: Sat, 27 Feb 2021 23:13:24 +0000 Subject: [PATCH 1430/1848] Added edit icons on reports to allow for quick edits. --- WEB-INF/lib/ttExpenseHelper.class.php | 66 ++++++++++++++++----------- WEB-INF/lib/ttReportHelper.class.php | 14 +++--- WEB-INF/lib/ttTimeHelper.class.php | 66 ++++++++++++++++----------- WEB-INF/lib/ttUserHelper.class.php | 28 +----------- WEB-INF/templates/report.tpl | 13 ++++-- expense_edit.php | 1 + initialize.php | 2 +- time_edit.php | 1 + 8 files changed, 102 insertions(+), 89 deletions(-) diff --git a/WEB-INF/lib/ttExpenseHelper.class.php b/WEB-INF/lib/ttExpenseHelper.class.php index 303ca5767..0de7eca11 100644 --- a/WEB-INF/lib/ttExpenseHelper.class.php +++ b/WEB-INF/lib/ttExpenseHelper.class.php @@ -1,30 +1,6 @@ isUserValid($user_id); + + if (!$user_valid) return false; + + // Set on behalf user. + $user->setOnBehalfUser($user_id); + // Get on behalf record. + return ttExpenseHelper::getItem($id); + } + + // getUserForItem - retrieves user id for an expense item. + static function getUserForItem($id) { + global $user; + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $mdb2 = getConnection(); + + // Obtain user_id for the expense item. + $sql = "select ei.user_id from tt_expense_items ei ". + " where ei.id = $id and ei.group_id = $group_id and ei.org_id = $org_id and ei.status = 1"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return false; + if (!$res->numRows()) return false; + + $val = $res->fetchRow(); + $user_id = $val['user_id']; + return $user_id; + } + // getItemForFileView - retrieves an expense item identified by its id for // attachment view operation. // diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 294225e0c..b24890e7d 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -350,9 +350,10 @@ static function getItems($options) { array_push($fields, "cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use project rate for user. array_push($fields, "null as expense"); } - // Add approved. - if ($options['show_approved']) - array_push($fields, 'l.approved'); + // Add the fields used to determine if we show an edit icon for record. + array_push($fields, 'l.approved'); + array_push($fields, 'l.timesheet_id'); + array_push($fields, 'l.invoice_id'); // Add paid status. if ($canViewReports && $options['show_paid']) array_push($fields, 'l.paid'); @@ -513,9 +514,10 @@ static function getItems($options) { array_push($fields, 'ei.name as note'); array_push($fields, 'ei.cost as cost'); array_push($fields, 'ei.cost as expense'); - // Add approved. - if ($options['show_approved']) - array_push($fields, 'ei.approved'); + // Add the fields used to determine if we show an edit icon for record. + array_push($fields, 'ei.approved'); + array_push($fields, 'null as timesheet_id'); + array_push($fields, 'ei.invoice_id'); // Add paid status. if ($canViewReports && $options['show_paid']) array_push($fields, 'ei.paid'); diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index faa1197cd..f0b1ea100 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -1,30 +1,6 @@ isUserValid($user_id); + + if (!$user_valid) return false; + + // Set on behalf user. + $user->setOnBehalfUser($user_id); + // Get on behalf record. + return ttTimeHelper::getRecord($id); + } + + // getUserForRecord - retrieves user id for a time record. + static function getUserForRecord($id) { + global $user; + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $mdb2 = getConnection(); + + // Obtain user_id for the time record. + $sql = "select l.user_id from tt_log l ". + " where l.id = $id and l.group_id = $group_id and l.org_id = $org_id and l.status = 1"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return false; + if (!$res->numRows()) return false; + + $val = $res->fetchRow(); + $user_id = $val['user_id']; + return $user_id; + } + // getRecordForFileView - retrieves a time record identified by its id for // attachment view operation. // diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index accabe1fe..d4fc8d804 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -1,30 +1,6 @@ getAttribute('chtimesheet')}

 
{$i18n.label.edit} {$i18n.label.edit}{$i18n.label.edit}
diff --git a/expense_edit.php b/expense_edit.php index 092f33c11..5d1e75044 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -21,6 +21,7 @@ $cl_id = (int)$request->getParameter('id'); // Get the expense item we are editing. $expense_item = ttExpenseHelper::getItem($cl_id); +if (!$expense_item) $expense_item = ttExpenseHelper::getOnBehalfItem($cl_id); if (!$expense_item || $expense_item['approved'] || $expense_item['invoice_id']) { // Prohibit editing not ours, approved, or invoiced items. header('Location: access_denied.php'); diff --git a/initialize.php b/initialize.php index c5edb812a..3a08a9e78 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.25.5420"); +define("APP_VERSION", "1.19.26.5421"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time_edit.php b/time_edit.php index 4065bf08f..774add2c6 100644 --- a/time_edit.php +++ b/time_edit.php @@ -18,6 +18,7 @@ } $cl_id = (int)$request->getParameter('id'); $time_rec = ttTimeHelper::getRecord($cl_id); +if (!$time_rec) $time_rec = ttTimeHelper::getOnBehalfRecord($cl_id); if (!$time_rec || $time_rec['approved'] || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { // Prohibit editing not ours, approved, assigned to timesheet, or invoiced records. header('Location: access_denied.php'); From 9c9e7d7976fed5b80c0d9dd74b7424f890584fc8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 5 Mar 2021 21:06:24 +0000 Subject: [PATCH 1431/1848] Sanitizing of user input on charts.php. --- WEB-INF/templates/time2.tpl | 2 -- charts.php | 4 ++-- initialize.php | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time2.tpl index 65216efb8..487bff7cf 100644 --- a/WEB-INF/templates/time2.tpl +++ b/WEB-INF/templates/time2.tpl @@ -234,5 +234,3 @@ License: See license.txt *} {/if}

- -{$smarty.version} diff --git a/charts.php b/charts.php index d4fb52b3b..026f97463 100644 --- a/charts.php +++ b/charts.php @@ -35,7 +35,7 @@ exit(); } if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid($request->getParameter('user'))) { + if (!$user->isUserValid((int)$request->getParameter('user'))) { header('Location: access_denied.php'); // Wrong user id on post. exit(); } @@ -45,7 +45,7 @@ // Determine user for which we display this page. $userChanged = $request->getParameter('user_changed'); if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/initialize.php b/initialize.php index 3a08a9e78..faa912032 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5421"); +define("APP_VERSION", "1.19.26.5422"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From d0af0f472a64e19dfb48473cca1c374363fb6471 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 5 Mar 2021 21:24:18 +0000 Subject: [PATCH 1432/1848] Some more sanitizing of post parameters. --- charts.php | 6 +++--- initialize.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/charts.php b/charts.php index 026f97463..9dc29f588 100644 --- a/charts.php +++ b/charts.php @@ -43,7 +43,7 @@ // End of access checks. // Determine user for which we display this page. -$userChanged = $request->getParameter('user_changed'); +$userChanged = (int)$request->getParameter('user_changed'); if ($request->isPost() && $userChanged) { $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); @@ -63,12 +63,12 @@ $_SESSION['date'] = $cl_date; if ($request->isPost()) { - $cl_interval = $request->getParameter('interval'); + $cl_interval = (int)$request->getParameter('interval'); if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; $_SESSION['chart_interval'] = $cl_interval; $uc->setValue(SYSC_CHART_INTERVAL, $cl_interval); - $cl_type = $request->getParameter('type'); + $cl_type = (int)$request->getParameter('type'); if (!$cl_type) $cl_type = ttChartHelper::adjustType($cl_type); $_SESSION['chart_type'] = $cl_type; $uc->setValue(SYSC_CHART_TYPE, $cl_type); diff --git a/initialize.php b/initialize.php index faa912032..f54941375 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5422"); +define("APP_VERSION", "1.19.26.5423"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 2eaab13803846b91c90d49680099968731d4718e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 6 Mar 2021 15:12:37 +0000 Subject: [PATCH 1433/1848] A bit more of sanitizing work for posts. --- WEB-INF/lib/ttUser.class.php | 14 ++++++++------ cron.php | 28 ++-------------------------- custom_css.php | 28 ++-------------------------- dbinstall.php | 28 ++-------------------------- display_options.php | 36 ++++++------------------------------ initialize.php | 2 +- 6 files changed, 21 insertions(+), 115 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index b01ffe687..fcfc1b9d5 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -617,6 +617,7 @@ function getUserDetails($user_id) { $mdb2 = getConnection(); $group_id = $this->getGroup(); $org_id = $this->org_id; + $uid = (int)$user_id; // Determine max rank. If we are searching in on behalf group // then rank restriction does not apply. @@ -624,7 +625,7 @@ function getUserDetails($user_id) { $sql = "select u.id, u.name, u.login, u.role_id, u.client_id, u.status, u.rate, u.quota_percent, u.email from tt_users u". " left join tt_roles r on (u.role_id = r.id)". - " where u.id = $user_id and u.group_id = $group_id and u.org_id = $org_id and u.status is not null". + " where u.id = $uid and u.group_id = $group_id and u.org_id = $org_id and u.status is not null". " and (r.rank < $max_rank or (r.rank = $max_rank and u.id = $this->id))"; // Users with lesser roles or self. $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -897,6 +898,7 @@ function setOnBehalfGroup($group_id) { // setOnBehalfUser sets on behalf user both the object and the session. function setOnBehalfUser($user_id) { + $uid = (int)$user_id; // In case we forgot to sanitize $user_id before getting here. // Unset things first. $this->behalf_id = null; @@ -906,16 +908,16 @@ function setOnBehalfUser($user_id) { unset($_SESSION['behalf_name']); // No need to set if user is us. - if ($user_id == $this->id) return; + if ($uid == $this->id) return; // No need to set if user id is not valid. - if (!$this->isUserValid($user_id)) return; + if (!$this->isUserValid($uid)) return; // We are good to set on behalf user. - $onBehalfUserName = ttUserHelper::getUserName($user_id); - $_SESSION['behalf_id'] = $user_id; + $onBehalfUserName = ttUserHelper::getUserName($uid); + $_SESSION['behalf_id'] = $uid; $_SESSION['behalf_name'] = $onBehalfUserName; - $this->behalf_id = $user_id; + $this->behalf_id = $uid; $this->behalf_name = $onBehalfUserName; $this->behalfUser = new ttBehalfUser($this->behalf_id, $this->org_id); diff --git a/cron.php b/cron.php index 331b4f36e..5adced71e 100644 --- a/cron.php +++ b/cron.php @@ -1,30 +1,6 @@ getConfigHelper(); if ($request->isPost()) { - $cl_time_note_on_separate_row = $request->getParameter('time_note_on_separate_row'); - $cl_time_not_complete_days = $request->getParameter('time_not_complete_days'); - $cl_record_custom_fields = $request->getParameter('record_custom_fields'); - $cl_report_note_on_separate_row = $request->getParameter('report_note_on_separate_row'); + $cl_time_note_on_separate_row = (bool)$request->getParameter('time_note_on_separate_row'); + $cl_time_not_complete_days = (bool)$request->getParameter('time_not_complete_days'); + $cl_record_custom_fields = (bool)$request->getParameter('record_custom_fields'); + $cl_report_note_on_separate_row = (bool)$request->getParameter('report_note_on_separate_row'); $cl_custom_css = trim($request->getParameter('custom_css')); } else { $cl_time_note_on_separate_row = $config->getDefinedValue('time_note_on_separate_row'); diff --git a/initialize.php b/initialize.php index f54941375..eb9fd4b94 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5423"); +define("APP_VERSION", "1.19.26.5424"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 477f47a63e8e476f6c84edff830bba03c7610667 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 6 Mar 2021 15:55:04 +0000 Subject: [PATCH 1434/1848] Some more sanitizing. --- expense_edit.php | 4 ++-- expenses.php | 6 +++--- initialize.php | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/expense_edit.php b/expense_edit.php index 5d1e75044..9c85bdb79 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -43,14 +43,14 @@ $cl_item_name = trim($request->getParameter('item_name')); $cl_cost = trim($request->getParameter('cost')); if ($user->isPluginEnabled('ps')) - $cl_paid = $request->getParameter('paid'); + $cl_paid = (bool)$request->getParameter('paid'); } else { $cl_date = $item_date->toString($user->getDateFormat()); $cl_client = $expense_item['client_id']; $cl_project = $expense_item['project_id']; $cl_item_name = $expense_item['name']; $cl_cost = $expense_item['cost']; - $cl_paid = $expense_item['paid']; + $cl_paid = (bool)$expense_item['paid']; } // Initialize elements of 'expenseItemForm'. diff --git a/expenses.php b/expenses.php index 170f0cd3b..e82d9d379 100644 --- a/expenses.php +++ b/expenses.php @@ -33,7 +33,7 @@ exit(); } if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid($request->getParameter('user'))) { + if (!$user->isUserValid((int)$request->getParameter('user'))) { header('Location: access_denied.php'); // Wrong user id on post. exit(); } @@ -41,9 +41,9 @@ // End of access checks. // Determine user for which we display this page. -$userChanged = $request->getParameter('user_changed'); +$userChanged = (int)$request->getParameter('user_changed'); if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/initialize.php b/initialize.php index eb9fd4b94..344ec8229 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5424"); +define("APP_VERSION", "1.19.26.5425"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 3a3c14ffd3a4266aeac52e7da19d7c0fa684792d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 6 Mar 2021 17:57:57 +0000 Subject: [PATCH 1435/1848] A bit more sanitizing of post parameters. --- export.php | 28 ++-------------------------- file_download.php | 28 ++-------------------------- group_add.php | 28 ++-------------------------- group_advanced_edit.php | 28 ++-------------------------- group_delete.php | 28 ++-------------------------- group_edit.php | 12 ++++++------ import.php | 28 ++-------------------------- initialize.php | 2 +- invoice_add.php | 30 +++--------------------------- invoice_delete.php | 28 ++-------------------------- invoice_send.php | 28 ++-------------------------- invoice_view.php | 28 ++-------------------------- invoices.php | 28 ++-------------------------- 13 files changed, 30 insertions(+), 294 deletions(-) diff --git a/export.php b/export.php index 2206def2d..2bcba2dce 100644 --- a/export.php +++ b/export.php @@ -1,30 +1,6 @@ getParameter('group_changed'); +$groupChanged = (bool)$request->getParameter('group_changed'); if ($request->isPost() && $groupChanged) { $user->setOnBehalfGroup($group_id); } @@ -62,11 +62,11 @@ $cl_tracking_mode = $request->getParameter('tracking_mode'); $cl_project_required = $request->getParameter('project_required'); $cl_record_type = $request->getParameter('record_type'); - $cl_punch_mode = $request->getParameter('punch_mode'); - $cl_allow_overlap = $request->getParameter('allow_overlap'); - $cl_future_entries = $request->getParameter('future_entries'); - $cl_uncompleted_indicators = $request->getParameter('uncompleted_indicators'); - $cl_confirm_save = $request->getParameter('confirm_save'); + $cl_punch_mode = (bool)$request->getParameter('punch_mode'); + $cl_allow_overlap = (bool)$request->getParameter('allow_overlap'); + $cl_future_entries = (bool)$request->getParameter('future_entries'); + $cl_uncompleted_indicators = (bool)$request->getParameter('uncompleted_indicators'); + $cl_confirm_save = (bool)$request->getParameter('confirm_save'); } else { $cl_currency = ($group['currency'] == '' ? CURRENCY_DEFAULT : $group['currency']); $cl_lang = $group['lang']; diff --git a/import.php b/import.php index 938fdb3dd..b743b3f5a 100644 --- a/import.php +++ b/import.php @@ -1,30 +1,6 @@ isPost()) { $cl_date = $request->getParameter('date'); - $cl_client = $request->getParameter('client'); + $cl_client = (int)$request->getParameter('client'); $cl_project = $request->getParameter('project'); $cl_number = trim($request->getParameter('number')); $cl_start = $request->getParameter('start'); diff --git a/invoice_delete.php b/invoice_delete.php index 89ea372a3..5b473dfa0 100644 --- a/invoice_delete.php +++ b/invoice_delete.php @@ -1,30 +1,6 @@ Date: Sat, 6 Mar 2021 21:19:21 +0000 Subject: [PATCH 1436/1848] Some more sanitizing work. --- locking.php | 28 ++---------------- login.php | 28 ++---------------- logout.php | 28 ++---------------- notification_add.php | 28 ++---------------- notification_delete.php | 28 ++---------------- notification_edit.php | 28 ++---------------- notifications.php | 28 ++---------------- password_change.php | 28 ++---------------- plugins.php | 64 +++++++++++++---------------------------- 9 files changed, 36 insertions(+), 252 deletions(-) diff --git a/locking.php b/locking.php index 9b23c876a..04c8d9419 100644 --- a/locking.php +++ b/locking.php @@ -1,30 +1,6 @@ doLogout(); diff --git a/notification_add.php b/notification_add.php index b7f743256..83cd7a538 100644 --- a/notification_add.php +++ b/notification_add.php @@ -1,30 +1,6 @@ isPost()) { // Plugins that user wants to save for the current group. - $cl_charts = $request->getParameter('charts'); - $cl_clients = $request->getParameter('clients'); - $cl_client_required = $request->getParameter('client_required'); - $cl_invoices = $request->getParameter('invoices'); - $cl_paid_status = $request->getParameter('paid_status'); - $cl_custom_fields = $request->getParameter('custom_fields'); - $cl_expenses = $request->getParameter('expenses'); - $cl_tax_expenses = $request->getParameter('tax_expenses'); - $cl_notifications = $request->getParameter('notifications'); - $cl_locking = $request->getParameter('locking'); - $cl_quotas = $request->getParameter('quotas'); - $cl_week_view = $request->getParameter('week_view'); - $cl_work_units = $request->getParameter('work_units'); - $cl_approval = $request->getParameter('approval'); - $cl_timesheets = $request->getParameter('timesheets'); - $cl_templates = $request->getParameter('templates'); - $cl_attachments = $request->getParameter('attachments'); - $cl_work = $request->getParameter('work'); + $cl_charts = (bool)$request->getParameter('charts'); + $cl_clients = (bool)$request->getParameter('clients'); + $cl_client_required = (bool)$request->getParameter('client_required'); + $cl_invoices = (bool)$request->getParameter('invoices'); + $cl_paid_status = (bool)$request->getParameter('paid_status'); + $cl_custom_fields = (bool)$request->getParameter('custom_fields'); + $cl_expenses = (bool)$request->getParameter('expenses'); + $cl_tax_expenses = (bool)$request->getParameter('tax_expenses'); + $cl_notifications = (bool)$request->getParameter('notifications'); + $cl_locking = (bool)$request->getParameter('locking'); + $cl_quotas = (bool)$request->getParameter('quotas'); + $cl_week_view = (bool)$request->getParameter('week_view'); + $cl_work_units = (bool)$request->getParameter('work_units'); + $cl_approval = (bool)$request->getParameter('approval'); + $cl_timesheets = (bool)$request->getParameter('timesheets'); + $cl_templates = (bool)$request->getParameter('templates'); + $cl_attachments = (bool)$request->getParameter('attachments'); + $cl_work = (bool)$request->getParameter('work'); } else { // Note: we get here in get, and also in post when group changes. // Which plugins do we have enabled in currently selected group? From 5a9248484ea3248963da71b955449ce6f354580b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 6 Mar 2021 21:27:05 +0000 Subject: [PATCH 1437/1848] Some cosmetic refactoring. --- initialize.php | 2 +- predefined_expense_add.php | 28 ++------------------------- predefined_expense_delete.php | 36 ++++++----------------------------- predefined_expense_edit.php | 30 +++-------------------------- predefined_expenses.php | 28 ++------------------------- 5 files changed, 14 insertions(+), 110 deletions(-) diff --git a/initialize.php b/initialize.php index 22d73352c..c454c8337 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5426"); +define("APP_VERSION", "1.19.26.5427"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/predefined_expense_add.php b/predefined_expense_add.php index 2a0ab6be9..e300fa43e 100644 --- a/predefined_expense_add.php +++ b/predefined_expense_add.php @@ -1,30 +1,6 @@ getParameter('id'); -$predefined_expense = ttPredefinedExpenseHelper::get($cl_predefined_expense_id); +$predefined_expense_id = (int)$request->getParameter('id'); +$predefined_expense = ttPredefinedExpenseHelper::get($predefined_expense_id); if (!$predefined_expense) { header('Location: access_denied.php'); exit(); @@ -51,13 +27,13 @@ $predefined_expense_to_delete = $predefined_expense['name']; $form = new Form('predefinedExpenseDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_predefined_expense_id)); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$predefined_expense_id)); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if (ttPredefinedExpenseHelper::delete($cl_predefined_expense_id)) { + if (ttPredefinedExpenseHelper::delete($predefined_expense_id)) { header('Location: predefined_expenses.php'); exit(); } else diff --git a/predefined_expense_edit.php b/predefined_expense_edit.php index 3f0cb0c8c..1eca3a2c7 100644 --- a/predefined_expense_edit.php +++ b/predefined_expense_edit.php @@ -1,30 +1,6 @@ getParameter('id'); +$predefined_expense_id = (int)$request->getParameter('id'); $predefined_expense = ttPredefinedExpenseHelper::get($predefined_expense_id); if (!$predefined_expense) { header('Location: access_denied.php'); diff --git a/predefined_expenses.php b/predefined_expenses.php index e1c14d802..9f94bd1cc 100644 --- a/predefined_expenses.php +++ b/predefined_expenses.php @@ -1,30 +1,6 @@ Date: Sat, 6 Mar 2021 22:24:50 +0000 Subject: [PATCH 1438/1848] Cosmetic. --- WEB-INF/lib/ttRoleHelper.class.php | 2 +- initialize.php | 2 +- profile_edit.php | 28 ++------------------------ quotas.php | 28 ++------------------------ report.php | 32 ++++-------------------------- report_send.php | 28 ++------------------------ reports.php | 28 ++------------------------ role_add.php | 28 ++------------------------ role_delete.php | 28 ++------------------------ role_edit.php | 28 ++------------------------ 10 files changed, 20 insertions(+), 212 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 7fa9f8fb2..a3753d238 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -149,7 +149,7 @@ static function delete($role_id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - // Mark the task as deleted. + // Mark the role as deleted. $sql = "update tt_roles set status = NULL where id = $role_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); diff --git a/initialize.php b/initialize.php index c454c8337..fc27cbaaa 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5427"); +define("APP_VERSION", "1.19.26.5428"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/profile_edit.php b/profile_edit.php index d0d3de5fe..26091823f 100644 --- a/profile_edit.php +++ b/profile_edit.php @@ -1,30 +1,6 @@ getAttribute('chapproved') && ($user->can('approve_reports') || $user->can('approve_all_reports'))) @@ -199,7 +175,7 @@ $item_ids = ttReportHelper::getFromSession(); $time_log_ids = $item_ids['report_item_ids']; $expense_item_ids = $item_ids['report_item_expense_ids']; - // The above code is here beacues the arrays are used in both "Mark paid" and "Assign to invoice" handlers below. + // The above code is here because the arrays are used in both "Mark paid" and "Assign to invoice" handlers below. } if ($err->no()) { diff --git a/report_send.php b/report_send.php index e837f3e50..a2747b957 100644 --- a/report_send.php +++ b/report_send.php @@ -1,30 +1,6 @@ Date: Sun, 7 Mar 2021 17:35:27 +0000 Subject: [PATCH 1439/1848] Finished work on sanitizing post parameters to reduce risk of SQL injections. --- initialize.php | 2 +- mobile/expenses.php | 30 +++--------------------------- mobile/index.php | 28 ++-------------------------- mobile/login.php | 28 ++-------------------------- mobile/projects.php | 28 ++-------------------------- mobile/tasks.php | 28 ++-------------------------- mobile/time.php | 34 +++++----------------------------- mobile/timer.php | 28 ++-------------------------- mobile/users.php | 28 ++-------------------------- roles.php | 28 ++-------------------------- site_map.php | 28 ++-------------------------- success.php | 28 ++-------------------------- template_add.php | 28 ++-------------------------- template_delete.php | 30 +++--------------------------- template_edit.php | 30 +++--------------------------- templates.php | 28 ++-------------------------- time.php | 6 +++--- timesheet_add.php | 28 ++-------------------------- timesheet_edit.php | 28 ++-------------------------- timesheet_view.php | 28 ++-------------------------- timesheets.php | 34 +++++----------------------------- tofile.php | 28 ++-------------------------- topdf.php | 28 ++-------------------------- week.php | 34 +++++----------------------------- week_view.php | 36 ++++++------------------------------ work_units.php | 34 +++++----------------------------- 26 files changed, 71 insertions(+), 647 deletions(-) diff --git a/initialize.php b/initialize.php index fc27cbaaa..fca2f15a5 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5428"); +define("APP_VERSION", "1.19.26.5429"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/expenses.php b/mobile/expenses.php index 463671f4a..4f3b097fd 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -1,30 +1,6 @@ isPost() && $request->getParameter('user')) { - if (!$user->isUserValid($request->getParameter('user'))) { + if (!$user->isUserValid((int)$request->getParameter('user'))) { header('Location: access_denied.php'); // Wrong user id on post. exit(); } diff --git a/mobile/index.php b/mobile/index.php index 88408af23..4da5fab10 100644 --- a/mobile/index.php +++ b/mobile/index.php @@ -1,30 +1,6 @@ isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { header('Location: access_denied.php'); // User changed, but no right or wrong user id. exit(); } @@ -64,7 +40,7 @@ // Determine user for whom we display this page. if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/mobile/timer.php b/mobile/timer.php index e301716a4..1d870b1ca 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -1,30 +1,6 @@ getParameter('id'); +$cl_template_id = (int)$request->getParameter('id'); $template = ttTemplateHelper::get($cl_template_id); if (!$template) { header('Location: access_denied.php'); diff --git a/template_edit.php b/template_edit.php index 117b8166b..e3fa38947 100644 --- a/template_edit.php +++ b/template_edit.php @@ -1,30 +1,6 @@ getParameter('id'); +$cl_template_id = (int)$request->getParameter('id'); $template = ttTemplateHelper::get($cl_template_id); if (!$template) { header('Location: access_denied.php'); diff --git a/templates.php b/templates.php index 45ea2e477..636d4bc10 100644 --- a/templates.php +++ b/templates.php @@ -1,30 +1,6 @@ isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { header('Location: access_denied.php'); // User changed, but no right or wrong user id. exit(); } @@ -36,7 +36,7 @@ // Determine user for whom we display this page. if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/timesheet_add.php b/timesheet_add.php index 7c7633c6c..536241d62 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -1,30 +1,6 @@ isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { header('Location: access_denied.php'); // Group changed, but no rght or wrong user id. exit(); } @@ -59,7 +35,7 @@ // Determine user for whom we display this page. if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/tofile.php b/tofile.php index 996ffe9fd..b10bdee02 100644 --- a/tofile.php +++ b/tofile.php @@ -1,30 +1,6 @@ isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { header('Location: access_denied.php'); // User changed, but no right or wrong user id. exit(); } @@ -66,7 +42,7 @@ // Determine user for whom we display this page. if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/week_view.php b/week_view.php index 149842e87..1718afd4b 100644 --- a/week_view.php +++ b/week_view.php @@ -1,30 +1,6 @@ getConfigHelper(); if ($request->isPost()) { - $cl_week_menu = $request->getParameter('week_menu'); - $cl_week_note = $request->getParameter('week_note'); - $cl_week_list = $request->getParameter('week_list'); - $cl_notes = $request->getParameter('notes'); + $cl_week_menu = (bool)$request->getParameter('week_menu'); + $cl_week_note = (bool)$request->getParameter('week_note'); + $cl_week_list = (bool)$request->getParameter('week_list'); + $cl_notes = (bool)$request->getParameter('notes'); } else { $cl_week_menu = $config->getDefinedValue('week_menu'); $cl_week_note = $config->getDefinedValue('week_note'); diff --git a/work_units.php b/work_units.php index e4d198d5c..826f899ab 100644 --- a/work_units.php +++ b/work_units.php @@ -1,30 +1,6 @@ getConfig()); if ($request->isPost()) { - $cl_minutes_in_unit = $request->getParameter('minutes_in_unit'); - $cl_1st_unit_threshold = $request->getParameter('1st_unit_threshold'); - $cl_totals_only = $request->getParameter('totals_only'); + $cl_minutes_in_unit = (int)$request->getParameter('minutes_in_unit'); + $cl_1st_unit_threshold = (int)$request->getParameter('1st_unit_threshold'); + $cl_totals_only = (bool)$request->getParameter('totals_only'); } else { $cl_minutes_in_unit = $user->getConfigInt('minutes_in_unit', 15); $cl_1st_unit_threshold = $user->getConfigInt('1st_unit_threshold', 0); From 464291697900e30ae782477930ef45a9cb8e4cc0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 7 Mar 2021 18:15:58 +0000 Subject: [PATCH 1440/1848] Removed some more no longer used mobile pages. --- WEB-INF/templates/mobile/expenses.tpl | 226 ------------------------- WEB-INF/templates/mobile/projects.tpl | 76 --------- WEB-INF/templates/mobile/tasks.tpl | 76 --------- WEB-INF/templates/mobile/users.tpl | 95 ----------- initialize.php | 2 +- mobile/expenses.php | 235 -------------------------- mobile/projects.php | 36 ---- mobile/tasks.php | 35 ---- mobile/users.php | 51 ------ 9 files changed, 1 insertion(+), 831 deletions(-) delete mode 100644 WEB-INF/templates/mobile/expenses.tpl delete mode 100644 WEB-INF/templates/mobile/projects.tpl delete mode 100644 WEB-INF/templates/mobile/tasks.tpl delete mode 100644 WEB-INF/templates/mobile/users.tpl delete mode 100644 mobile/expenses.php delete mode 100644 mobile/projects.php delete mode 100644 mobile/tasks.php delete mode 100644 mobile/users.php diff --git a/WEB-INF/templates/mobile/expenses.tpl b/WEB-INF/templates/mobile/expenses.tpl deleted file mode 100644 index 81d7a214a..000000000 --- a/WEB-INF/templates/mobile/expenses.tpl +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - - - -
<<{$timestring}>>
- -{$forms.expensesForm.open} - - - - - -
- -{if $user_dropdown} - - - - -{/if} -{if $user->isPluginEnabled('cl')} - - - - -{/if} -{if $show_project} - - - - -{/if} -{if $predefined_expenses} - - - - - - - - -{/if} - - - - - - - - -
{$i18n.label.user}:{$forms.expensesForm.user.control}
{$i18n.label.client}{if $user->isOptionEnabled('client_required')} (*){/if}:{$forms.expensesForm.client.control}
{$i18n.label.project} (*):{$forms.expensesForm.project.control}
{$i18n.label.expense}:{$forms.expensesForm.predefined_expense.control}
{$i18n.label.quantity}:{$forms.expensesForm.quantity.control}
{$i18n.label.item} (*):{$forms.expensesForm.item_name.control}
{$i18n.label.cost} (*):{$forms.expensesForm.cost.control} {$user->getCurrency()|escape}
-
- - - - - -
{$forms.expensesForm.btn_submit.control}
- - - - - -
-{if $expense_items} - - - {if $user->isPluginEnabled('cl')} - - {/if} - {if $show_project} - - {/if} - - - - {foreach $expense_items as $item} - - {if $user->isPluginEnabled('cl')} - - {/if} - {if $show_project} - - {/if} - - - - {/foreach} -
{$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$i18n.label.cost}
{$item.client|escape}{$item.project|escape} - {if $item.approved || $item.invoice_id} - {$item.item|escape} - {else} - {$item.item|escape} - {/if} - {$item.cost}
- - - - -
{$i18n.label.day_total}: {$user->getCurrency()|escape} {$day_total}
-{/if} -
-{$forms.expensesForm.close} diff --git a/WEB-INF/templates/mobile/projects.tpl b/WEB-INF/templates/mobile/projects.tpl deleted file mode 100644 index 96d27054f..000000000 --- a/WEB-INF/templates/mobile/projects.tpl +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - -
-{if $user->can('manage_projects')} - - {if $inactive_projects} - - {/if} - {if $active_projects} - - - - - {foreach $active_projects as $project} - - - - - {/foreach} - {/if} -
{$i18n.form.projects.active_projects}
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}
- - - - - -

-
-
- - {if $inactive_projects} - - - - - - - {foreach $inactive_projects as $project} - - - - - {/foreach} -
{$i18n.form.projects.inactive_projects}
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}
- - - - - -

-
-
- {/if} -{else} - - - - - - {if $active_projects} - {foreach $active_projects as $project} - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}
-{/if} -
diff --git a/WEB-INF/templates/mobile/tasks.tpl b/WEB-INF/templates/mobile/tasks.tpl deleted file mode 100644 index 3fbee1f7d..000000000 --- a/WEB-INF/templates/mobile/tasks.tpl +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - -
-{if $user->can('manage_tasks')} - - {if $inactive_tasks} - - {/if} - - - - - {if $active_tasks} - {foreach $active_tasks as $task} - - - - - {/foreach} - {/if} -
{$i18n.form.tasks.active_tasks}
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}
- - - - - -

-
-
- - {if $inactive_tasks} - - - - - - - {foreach $inactive_tasks as $task} - - - - - {/foreach} -
{$i18n.form.tasks.inactive_tasks}
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}
- - - - - -

-
-
- {/if} -{else} - - - - - - {if $active_tasks} - {foreach $active_tasks as $task} - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}
- {/if} -
diff --git a/WEB-INF/templates/mobile/users.tpl b/WEB-INF/templates/mobile/users.tpl deleted file mode 100644 index eaeb4770f..000000000 --- a/WEB-INF/templates/mobile/users.tpl +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - -
-{if $user->can('manage_users')} - - {if $inactive_users} - - {/if} - {if $active_users} - - - - - - {foreach $active_users as $u} - - - - - - {/foreach} - {/if} -
{$i18n.label.active_users}
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}
- {if $uncompleted_indicators} - - {/if} - {if $u.group_id != $user->group_id || $u.rank < $user->rank || ($u.rank == $user->rank && $u.id == $user->id)} - {$u.name|escape} - {else} - {$u.name|escape} - {/if} - {$u.login|escape}{$u.role_name|escape}
- - - - - -

-
-
- - {if $inactive_users} - - - - - - - - {foreach $inactive_users as $u} - - - - - - {/foreach} -
{$i18n.label.inactive_users}
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}
- {if $u.group_id != $user->group_id || $u.rank < $user->rank} - {$u.name|escape} - {else} - {$u.name|escape} - {/if} - {$u.login|escape}{$u.role_name|escape}
- - - - - -
-
-
- {/if} -{else} - - - - - - - {foreach $active_users as $u} - - - - - - {/foreach} -
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}
{$u.name|escape}{$u.login|escape}{$u.role_name|escape}
-{/if} -
diff --git a/initialize.php b/initialize.php index fca2f15a5..cbdfb3cc1 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5429"); +define("APP_VERSION", "1.19.26.5430"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/expenses.php b/mobile/expenses.php deleted file mode 100644 index 4f3b097fd..000000000 --- a/mobile/expenses.php +++ /dev/null @@ -1,235 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!$user->exists()) { - header('Location: access_denied.php'); // Nobody to enter expenses for. - exit(); -} -if ($user->behalf_id && (!$user->can('track_expenses') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('track_own_expenses') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. - exit(); -} -if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid((int)$request->getParameter('user'))) { - header('Location: access_denied.php'); // Wrong user id on post. - exit(); - } -} -// End of access checks. - -// Determine user for which we display this page. -$userChanged = $request->getParameter('user_changed'); -if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; - -// Determine previous and next dates for simple navigation. -$prev_date = date('Y-m-d', strtotime('-1 day', strtotime($cl_date))); -$next_date = date('Y-m-d', strtotime('+1 day', strtotime($cl_date))); - -$tracking_mode = $user->getTrackingMode(); -$show_project = MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode; - -// Initialize variables. -$cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); -$_SESSION['client'] = $cl_client; -$cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); -$_SESSION['project'] = $cl_project; -$cl_item_name = $request->getParameter('item_name'); -$cl_cost = $request->getParameter('cost'); - -// Elements of expensesForm. -$form = new Form('expensesForm'); - -if ($user->can('track_expenses')) { - $rank = $user->getMaxRankForGroup($user->getGroup()); - if ($user->can('track_own_expenses')) - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); - if (count($user_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.user_changed.value=1;this.form.submit();', - 'name'=>'user', - 'style'=>'width: 250px;', - 'value'=>$user_id, - 'data'=>$user_list, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $smarty->assign('user_dropdown', 1); - } -} - -// Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -if ($show_project) { - // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox', - // 'onchange'=>'fillTaskDropdown(this.value);', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} -// If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); -if ($predefined_expenses) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'recalculateCost();', - 'name'=>'predefined_expense', - 'style'=>'width: 250px;', - 'value'=>$cl_predefined_expense, - 'data'=>$predefined_expenses, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'item_name','style'=>'width: 250px;','value'=>$cl_item_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); -$form->addInput(array('type'=>'calendar','name'=>'date','highlight'=>'expenses','value'=>$cl_date)); // calendar -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); - -// Submit. -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - // Validate user input. - if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - if ($show_project && !$cl_project) - $err->add($i18n->get('error.project')); - if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating input data. - - // Prohibit creating entries in locked range. - if ($user->isDateLocked($selected_date)) - $err->add($i18n->get('error.range_locked')); - - // Insert record. - if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$cl_date,'client_id'=>$cl_client, - 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { - header('Location: expenses.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } elseif ($request->getParameter('onBehalfUser')) { - if($user->can('track_expenses')) { - unset($_SESSION['behalf_id']); - unset($_SESSION['behalf_name']); - - if($on_behalf_id != $user->id) { - $_SESSION['behalf_id'] = $on_behalf_id; - $_SESSION['behalf_name'] = ttUserHelper::getUserName($on_behalf_id); - } - header('Location: expenses.php'); - exit(); - } - } -} - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_project', $show_project); -$smarty->assign('next_date', $next_date); -$smarty->assign('prev_date', $prev_date); -$smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); -$smarty->assign('expense_items', ttExpenseHelper::getItems($cl_date)); -$smarty->assign('predefined_expenses', $predefined_expenses); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); -$smarty->assign('title', $i18n->get('title.expenses')); -$smarty->assign('content_page_name', 'mobile/expenses.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/projects.php b/mobile/projects.php deleted file mode 100644 index c234d984d..000000000 --- a/mobile/projects.php +++ /dev/null @@ -1,36 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -if($user->can('manage_projects')) { - $active_projects = ttGroupHelper::getActiveProjects(); - $inactive_projects = ttGroupHelper::getInactiveProjects(); -} else - $active_projects = $user->getAssignedProjects(); - -$smarty->assign('active_projects', $active_projects); -$smarty->assign('inactive_projects', $inactive_projects); -$smarty->assign('title', $i18n->get('title.projects')); -$smarty->assign('content_page_name', 'mobile/projects.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/tasks.php b/mobile/tasks.php deleted file mode 100644 index 98530477d..000000000 --- a/mobile/tasks.php +++ /dev/null @@ -1,35 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -if($user->can('manage_tasks')) { - $active_tasks = ttGroupHelper::getActiveTasks(); - $inactive_tasks = ttGroupHelper::getInactiveTasks(); -} else - $active_tasks = $user->getAssignedTasks(); - -$smarty->assign('active_tasks', $active_tasks); -$smarty->assign('inactive_tasks', $inactive_tasks); -$smarty->assign('title', $i18n->get('title.tasks')); -$smarty->assign('content_page_name', 'mobile/tasks.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/users.php b/mobile/users.php deleted file mode 100644 index 45be3fcdc..000000000 --- a/mobile/users.php +++ /dev/null @@ -1,51 +0,0 @@ -getMaxRankForGroup($user->getGroup()); -if ($user->can('view_users')) - $options = array('status'=>ACTIVE,'include_clients'=>true,'include_login'=>true,'include_role'=>true); -else /* if ($user->can('manage_users')) */ - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_self'=>true,'include_login'=>true,'include_role'=>true); -$active_users = $user->getUsers($options); - -// Prepare a list of inactive users. -if($user->can('manage_users')) { - $options = array('status'=>INACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_login'=>true,'include_role'=>true); - $inactive_users = $user->getUsers($options); -} - -$uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); -if ($uncompleted_indicators) { - // Check each active user if they have an uncompleted time entry. - foreach ($active_users as $key => $active_user) { - $active_users[$key]['has_uncompleted_entry'] = (bool) ttTimeHelper::getUncompleted($active_user['id']); - } - $smarty->assign('uncompleted_indicators', true); -} - -$smarty->assign('active_users', $active_users); -$smarty->assign('inactive_users', $inactive_users); -$smarty->assign('can_delete_manager', $can_delete_manager); -$smarty->assign('title', $i18n->get('title.users')); -$smarty->assign('content_page_name', 'mobile/users.tpl'); -$smarty->display('mobile/index.tpl'); From e77be7eea69df5d52e19f9f25b5b89a0e66a5b8e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Apr 2021 21:57:58 +0000 Subject: [PATCH 1441/1848] An attempt to mitigate cross site request forgery vulnerability. --- WEB-INF/config.php.dist | 5 +++++ WEB-INF/lib/common.lib.php | 39 ++++++++++++++++++++++++++++++++++++++ initialize.php | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 7b6eabbd2..1b7b32b0a 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -163,6 +163,11 @@ define('AUTH_MODULE', 'db'); // define('DEBUG', false); // Note: enabling DEBUG breaks redirects as debug output is printed before setting redirect header. Do not enable on production systems. +// HTTP_TARGET - defines http target for cross site request forgery protection. +// It can be used when you access the application via a proxy. +// define('HTTP_TARGET', 'localhost'); + + // Group managers can set monthly work hour quota for years between the following values. // define('MONTHLY_QUOTA_YEAR_START', 2010); // If nothing is specified, it falls back to 2015. // define('MONTHLY_QUOTA_YEAR_END', 2025); // If nothing is specified, it falls back to 2030. diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 389b29c94..52589c6e0 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -363,6 +363,10 @@ function ttAccessAllowed($required_right) exit(); } + // Protection against cross site request forgery. + if (!ttMitigateCSRF()) + return false; + // Check IP restriction, if set. if ($user->allow_ip && !$user->can('override_allow_ip')) { $access_allowed = false; @@ -388,6 +392,41 @@ function ttAccessAllowed($required_right) return false; } +// ttMitigateCSRF verifies request headers in an attempt to block cross site request forgery. +function ttMitigateCSRF() { + // No need to do anything for get requests. + global $request; + if ($request->isGet()) + return true; + + $origin = $_SERVER['HTTP_ORIGIN']; + if ($origin) { + $pos = strpos($origin, '//'); + $origin = substr($origin, $pos+2); // Strip protocol. + } + if (!$origin) { + // Try using referer. + $origin = $_SERVER['HTTP_REFERER']; + if ($origin) { + $pos = strpos($origin, '//'); + $origin = substr($origin, $pos+2); // Strip protocol. + $pos = strpos($origin, '/'); + $origin = substr($origin, 0, $pos); // Leave host only. + } + } + error_log("origin: ".$origin); + $target = defined('HTTP_TARGET') ? HTTP_TARGET : $_SERVER['HTTP_HOST']; + error_log("target: ".$target); + if (strcmp($origin, $target)) { + error_log("Potential cross site request forgery. Origin: '$origin' does not match target: '$target'."); + return false; // Origin and target do not match, + } + + // TODO: review and improve this function for custom ports. + return true; +} + + // ttStartsWith functions checks if a string starts with a given substring. function ttStartsWith($string, $startString) { diff --git a/initialize.php b/initialize.php index cbdfb3cc1..aadc0bb07 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5430"); +define("APP_VERSION", "1.19.27.5431"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From e3f8222ee308322942bcebcd86b78ecf19382563 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 12 Apr 2021 17:14:30 +0000 Subject: [PATCH 1442/1848] Tested CSRF fix for custom ports - it's working, also removed unnecessary logging. --- WEB-INF/config.php.dist | 2 +- WEB-INF/lib/common.lib.php | 5 +---- initialize.php | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 1b7b32b0a..3787cbc94 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -165,7 +165,7 @@ define('AUTH_MODULE', 'db'); // HTTP_TARGET - defines http target for cross site request forgery protection. // It can be used when you access the application via a proxy. -// define('HTTP_TARGET', 'localhost'); +// define('HTTP_TARGET', 'localhost:8080'); // Group managers can set monthly work hour quota for years between the following values. diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 52589c6e0..d5b43f57f 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -414,15 +414,12 @@ function ttMitigateCSRF() { $origin = substr($origin, 0, $pos); // Leave host only. } } - error_log("origin: ".$origin); $target = defined('HTTP_TARGET') ? HTTP_TARGET : $_SERVER['HTTP_HOST']; - error_log("target: ".$target); if (strcmp($origin, $target)) { error_log("Potential cross site request forgery. Origin: '$origin' does not match target: '$target'."); - return false; // Origin and target do not match, + return false; // Origin and target do not match. } - // TODO: review and improve this function for custom ports. return true; } diff --git a/initialize.php b/initialize.php index aadc0bb07..e8588857f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.27.5431"); +define("APP_VERSION", "1.19.27.5432"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ee6312e1a278cfbb240ae1419d6c63eeff0913f6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 13 Apr 2021 22:12:35 +0000 Subject: [PATCH 1443/1848] Added options for secure ldap authentication. --- WEB-INF/config.php.dist | 4 ++++ WEB-INF/lib/auth/Auth_ldap.class.php | 10 ++++++++++ initialize.php | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 3787cbc94..bbf647cec 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -144,6 +144,8 @@ define('AUTH_MODULE', 'db'); // 'base_dn' => 'ou=People,dc=example,dc=com', // Path of user's base distinguished name in LDAP catalog. // 'user_login_attribute' => 'uid', // LDAP attribute used for login. // 'default_domain' => 'example.com', // Default domain. +// 'tls_cacertdir' => null, // Path to a directory containing CA certificates for secure ldap. +// 'tls_cacertfile' => null, // CA certificate file name for secure ldap. // 'member_of' => array()); // List of groups, membership in which is required for user to be authenticated. @@ -154,6 +156,8 @@ define('AUTH_MODULE', 'db'); // 'type' => 'ad', // Type of server. // 'base_dn' => 'DC=example,DC=com', // Base distinguished name in LDAP catalog. // 'default_domain' => 'example.com', // Default domain. +// 'tls_cacertdir' => null, // Path to a directory containing CA certificates for secure ldap. +// 'tls_cacertfile' => null, // CA certificate file name for secure ldap. // 'member_of' => array()); // List of groups, membership in which is required for user to be authenticated. // Leave it empty if membership is not necessary. Otherwise list CN parts only. // For example: diff --git a/WEB-INF/lib/auth/Auth_ldap.class.php b/WEB-INF/lib/auth/Auth_ldap.class.php index 7f3495737..1ccbb0371 100644 --- a/WEB-INF/lib/auth/Auth_ldap.class.php +++ b/WEB-INF/lib/auth/Auth_ldap.class.php @@ -105,6 +105,16 @@ function authenticate($login, $password) if (isTrue('DEBUG')) { ldap_set_option($lc, LDAP_OPT_DEBUG_LEVEL, 7); } + // Additional options for secure ldap. + // This insert is based on https://www.anuko.com/forum/viewtopic.php?f=4&t=2091 + // I can't test it at the moment. If things break please let us know! + if (isset($this->params['tls_cacertdir'])) { + ldap_set_option(null, LDAP_OPT_X_TLS_CACERTDIR, $this->params['tls_cacertdir']); + } + if (isset($this->params['tls_cacertfile'])) { + ldap_set_option(null, LDAP_OPT_X_TLS_CACERTFILE, $this->params['tls_cacertfile']); + } + // End of addiitional options for secure ldap. // We need to handle Windows AD and OpenLDAP differently. if ($this->params['type'] == 'ad') { diff --git a/initialize.php b/initialize.php index e8588857f..a739b939e 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.27.5432"); +define("APP_VERSION", "1.19.28.5433"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 4fdaa18d343d0459391e62b40971843fbd0e5924 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Apr 2021 21:26:18 +0000 Subject: [PATCH 1444/1848] Resuming work on php8 warnings. --- WEB-INF/lib/ttTimeHelper.class.php | 2 ++ WEB-INF/templates/header2.tpl | 2 +- WEB-INF/templates/time2.tpl | 2 +- WEB-INF/templates/time_script.tpl | 16 +++++++++------- initialize.php | 2 +- time.php | 1 + 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index f0b1ea100..af2a436a5 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -895,6 +895,8 @@ static function getRecords($date, $includeFiles = false) { $time_fields = ", ".join(', ', $time_fields_array); } + $filePart = ''; + $fileJoin = ''; if ($includeFiles) { $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; $fileJoin = " left join (select distinct entity_id from tt_files". diff --git a/WEB-INF/templates/header2.tpl b/WEB-INF/templates/header2.tpl index 6bc5f65fe..74ccb1adc 100644 --- a/WEB-INF/templates/header2.tpl +++ b/WEB-INF/templates/header2.tpl @@ -6,7 +6,7 @@ -{if $i18n.language.rtl} +{if (isset($i18n.language.rtl) && $i18n.language.rtl)} {/if} {if $user->getCustomCss()} diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time2.tpl index 487bff7cf..4a26f9bef 100644 --- a/WEB-INF/templates/time2.tpl +++ b/WEB-INF/templates/time2.tpl @@ -93,7 +93,7 @@ License: See license.txt *}
{$forms.timeRecordForm.date.control}
- + {* No need to escape as it is done in the class. *}
{$title}{if $timestring}: {$timestring}{/if}
{$title}{if (isset($timestring) && $timestring)}: {$timestring}{/if}
{$user->getUserPartForHeader()}
{/if} diff --git a/plugins.php b/plugins.php index 2a5f2046a..9b3bc1a27 100644 --- a/plugins.php +++ b/plugins.php @@ -86,6 +86,7 @@ // We update plugin list for the current group. // Prepare plugins string. + $plugins = ''; if ($cl_charts) $plugins .= ',ch'; if ($cl_clients) From 86bca3c33d430d68a4dd9702b973f67ea12fbb61 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Apr 2021 15:27:02 +0000 Subject: [PATCH 1447/1848] Resuming work on php8 warnings. --- WEB-INF/lib/ttAdmin.class.php | 2 +- initialize.php | 2 +- register.php | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index 74d789d12..e40e31dba 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -311,7 +311,7 @@ static function createOrgManager($fields) { // The createOrg function creates an organization in Time Tracker. static function createOrg($fields) { - // There are 3 steps that we need to 2 when creating a new organization. + // There are 3 steps that we need to do when creating a new organization. // 1. Create a new group with null parent_id. // 2. Create pre-defined roles in it. // 3. Create a top manager account for new group. diff --git a/initialize.php b/initialize.php index be7ff2576..025e5dcf4 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5435"); +define("APP_VERSION", "1.19.28.5436"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/register.php b/register.php index 3430d4366..220376138 100644 --- a/register.php +++ b/register.php @@ -18,6 +18,8 @@ if (!defined('CURRENCY_DEFAULT')) define('CURRENCY_DEFAULT', '$'); +$cl_group_name = $cl_currency = $cl_lang = $cl_manager_name = $cl_manager_login = +$cl_password1 = $cl_password2 = $cl_manager_email = ''; if ($request->isPost()) { $cl_group_name = trim($request->getParameter('group_name')); $cl_currency = trim($request->getParameter('currency')); From ee71238364860fe3d693313cb72ca0f2c87c7be2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Apr 2021 16:15:10 +0000 Subject: [PATCH 1448/1848] Simplified ttRegistrator.class.php. --- WEB-INF/lib/ttRegistrator.class.php | 46 +++++------------------------ initialize.php | 2 +- 2 files changed, 8 insertions(+), 40 deletions(-) diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index aadd7d14f..ae499a9df 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -1,30 +1,6 @@ currency = $fields['currency']; $this->lang = $fields['lang']; if (!$this->lang) $this->lang = 'en'; - $this->created_by_id = (int) $fields['created_by_id']; $this->err = $err; // Validate passed in parameters. @@ -98,12 +69,10 @@ function register() { global $user; // Protection from too many recent bot registrations from user IP. - if (!$this->created_by_id) { // No problems for logged in user (site admin). - if ($this->registeredRecently()) { - $this->err->add($i18n->get('error.registered_recently')); - $this->err->add($i18n->get('error.access_denied')); - return false; - } + if ($this->registeredRecently()) { + $this->err->add($i18n->get('error.registered_recently')); + $this->err->add($i18n->get('error.access_denied')); + return false; } import('ttUserHelper'); @@ -134,8 +103,7 @@ function register() { } // Set created_by appropriately. - $created_by = $this->created_by_id ? $this->created_by_id : $this->user_id; - if (!$this->setCreatedBy($created_by)) + if (!$this->setCreatedBy($this->user_id)) return false; return true; diff --git a/initialize.php b/initialize.php index 025e5dcf4..d83cfe133 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5436"); +define("APP_VERSION", "1.19.28.5437"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 3c85735e2f3842d16ed99505e27bfe33de3fd2a5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Apr 2021 17:02:18 +0000 Subject: [PATCH 1449/1848] Addressed a few more php8 warnings. --- WEB-INF/lib/ttTimeHelper.class.php | 5 +++-- WEB-INF/templates/time2.tpl | 2 +- initialize.php | 2 +- time.php | 6 ++++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 78e7a2cf5..bd2fb9898 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -881,7 +881,8 @@ static function getRecords($date, $includeFiles = false) { $time_fields_array = array(); } - if ($custom_fields && $custom_fields->timeFields) { + $time_fields = ''; + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) { @@ -909,7 +910,7 @@ static function getRecords($date, $includeFiles = false) { if ($user->isPluginEnabled('cl')) $left_joins .= " left join tt_clients c on (l.client_id = c.id)"; - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; $cflTable = 'cfl'.$timeField['id']; diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time2.tpl index 4a26f9bef..14b8dcc69 100644 --- a/WEB-INF/templates/time2.tpl +++ b/WEB-INF/templates/time2.tpl @@ -36,7 +36,7 @@ License: See license.txt *}
- -
{$i18n.form.groups.hint}
- - - - - - - - - - -{if $groups} - {foreach $groups as $group} - - - - - - - - - {/foreach} -{/if} -
{$i18n.label.id}{$i18n.label.thing_name}{$i18n.label.date}{$i18n.label.language}
{$group.id}{$group.name|escape}{$group.date}{$group.lang}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -
-
-
-  {$i18n.label.or}  - -
-
diff --git a/WEB-INF/templates/admin_groups2.tpl b/WEB-INF/templates/admin_groups2.tpl new file mode 100644 index 000000000..467bff28b --- /dev/null +++ b/WEB-INF/templates/admin_groups2.tpl @@ -0,0 +1,36 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + +
{$i18n.form.groups.hint}
+{if $groups} + + + + + + + + + + {foreach $groups as $group} + + + + + + + + + {/foreach} +
{$i18n.label.id}{$i18n.label.thing_name}{$i18n.label.date}{$i18n.label.language}
{$group.id}{$group.name|escape}{$group.date}{$group.lang}{$i18n.label.edit}{$i18n.label.delete}
+{/if} +
+
+  {$i18n.label.or}  + +
+
diff --git a/admin_groups.php b/admin_groups.php index 8dffd3931..915f7d778 100644 --- a/admin_groups.php +++ b/admin_groups.php @@ -14,5 +14,5 @@ $smarty->assign('groups', ttOrgHelper::getOrgs()); $smarty->assign('title', $i18n->get('title.groups')); -$smarty->assign('content_page_name', 'admin_groups.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'admin_groups2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index 4b118fe69..ba1d0ea68 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5452"); +define("APP_VERSION", "1.19.28.5453"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From a17a11f21f4ad0f2df2fc7685aee61f91ac84c91 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 22 Apr 2021 20:41:29 +0000 Subject: [PATCH 1465/1848] Addressed a few more php8 warnings. --- WEB-INF/templates/header2.tpl | 6 +++--- admin_options.php | 1 + initialize.php | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/header2.tpl b/WEB-INF/templates/header2.tpl index 65af554ee..1d8627a66 100644 --- a/WEB-INF/templates/header2.tpl +++ b/WEB-INF/templates/header2.tpl @@ -12,7 +12,7 @@ {if $user->getCustomCss()} {/if} - Time Tracker{if $title} - {$title}{/if} + Time Tracker{if isset($title) && $title} - {$title}{/if} - - - - - -
-{if $user->can('manage_custom_fields')} - - - - - - - {if $options} - {foreach $options as $key=>$val} - - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}
{$val|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -
-
-
- -
-
-{/if} -
diff --git a/WEB-INF/templates/cf_dropdown_options2.tpl b/WEB-INF/templates/cf_dropdown_options2.tpl new file mode 100644 index 000000000..f7a6b28b5 --- /dev/null +++ b/WEB-INF/templates/cf_dropdown_options2.tpl @@ -0,0 +1,26 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + + + + + + + +{if isset($options)} + {foreach $options as $key=>$val} + + + + + + {/foreach} +{/if} +
{$i18n.label.thing_name}
{$val|escape}{$i18n.label.edit}{$i18n.label.delete}
+
+
+
diff --git a/cf_dropdown_options.php b/cf_dropdown_options.php index 06f53a7d8..2570f0ee0 100644 --- a/cf_dropdown_options.php +++ b/cf_dropdown_options.php @@ -28,5 +28,5 @@ $smarty->assign('field_id', $field_id); $smarty->assign('options', $options); $smarty->assign('title', $i18n->get('title.cf_dropdown_options')); -$smarty->assign('content_page_name', 'cf_dropdown_options.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'cf_dropdown_options2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index 0e9a60e36..64e508695 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5463"); +define("APP_VERSION", "1.19.28.5464"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 44545ac2977f87dc00ac5a179be97ce89c693a9f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Apr 2021 19:22:38 +0000 Subject: [PATCH 1476/1848] Made all cf_dropdown_option_* pages mobile friendly. --- WEB-INF/templates/cf_dropdown_option_add.tpl | 27 ------------------- WEB-INF/templates/cf_dropdown_option_add2.tpl | 16 +++++++++++ .../templates/cf_dropdown_option_delete.tpl | 22 --------------- .../templates/cf_dropdown_option_delete2.tpl | 7 +++++ WEB-INF/templates/cf_dropdown_option_edit.tpl | 27 ------------------- .../templates/cf_dropdown_option_edit2.tpl | 16 +++++++++++ cf_dropdown_option_add.php | 4 +-- cf_dropdown_option_delete.php | 4 +-- cf_dropdown_option_edit.php | 4 +-- 9 files changed, 45 insertions(+), 82 deletions(-) delete mode 100644 WEB-INF/templates/cf_dropdown_option_add.tpl create mode 100644 WEB-INF/templates/cf_dropdown_option_add2.tpl delete mode 100644 WEB-INF/templates/cf_dropdown_option_delete.tpl create mode 100644 WEB-INF/templates/cf_dropdown_option_delete2.tpl delete mode 100644 WEB-INF/templates/cf_dropdown_option_edit.tpl create mode 100644 WEB-INF/templates/cf_dropdown_option_edit2.tpl diff --git a/WEB-INF/templates/cf_dropdown_option_add.tpl b/WEB-INF/templates/cf_dropdown_option_add.tpl deleted file mode 100644 index bcc1cee72..000000000 --- a/WEB-INF/templates/cf_dropdown_option_add.tpl +++ /dev/null @@ -1,27 +0,0 @@ -{$forms.optionAddForm.open} - - - - -
-{if $user->can('manage_custom_fields')} - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.optionAddForm.name.control}
{$i18n.label.required_fields}
 
{$forms.optionAddForm.btn_add.control}
-{/if} -
-{$forms.optionAddForm.close} diff --git a/WEB-INF/templates/cf_dropdown_option_add2.tpl b/WEB-INF/templates/cf_dropdown_option_add2.tpl new file mode 100644 index 000000000..5ba70387b --- /dev/null +++ b/WEB-INF/templates/cf_dropdown_option_add2.tpl @@ -0,0 +1,16 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.optionAddForm.open} + + + + + + + + + +
{$forms.optionAddForm.name.control}
{$i18n.label.required_fields}
+
{$forms.optionAddForm.btn_add.control}
+{$forms.optionAddForm.close} diff --git a/WEB-INF/templates/cf_dropdown_option_delete.tpl b/WEB-INF/templates/cf_dropdown_option_delete.tpl deleted file mode 100644 index bec03cc32..000000000 --- a/WEB-INF/templates/cf_dropdown_option_delete.tpl +++ /dev/null @@ -1,22 +0,0 @@ -{$forms.optionDeleteForm.open} - - - - -
-{if $user->can('manage_custom_fields')} - - - - - - - - - - - -
{$option|escape}
 
{$forms.optionDeleteForm.btn_delete.control}  {$forms.optionDeleteForm.btn_cancel.control}
-{/if} -
-{$forms.optionDeleteForm.close} diff --git a/WEB-INF/templates/cf_dropdown_option_delete2.tpl b/WEB-INF/templates/cf_dropdown_option_delete2.tpl new file mode 100644 index 000000000..8fb56d618 --- /dev/null +++ b/WEB-INF/templates/cf_dropdown_option_delete2.tpl @@ -0,0 +1,7 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.optionDeleteForm.open} +
{$option|escape}
+
{$forms.optionDeleteForm.btn_delete.control} {$forms.optionDeleteForm.btn_cancel.control}
+{$forms.optionDeleteForm.close} diff --git a/WEB-INF/templates/cf_dropdown_option_edit.tpl b/WEB-INF/templates/cf_dropdown_option_edit.tpl deleted file mode 100644 index c2b0bae9c..000000000 --- a/WEB-INF/templates/cf_dropdown_option_edit.tpl +++ /dev/null @@ -1,27 +0,0 @@ -{$forms.optionEditForm.open} - - - - -
-{if $user->can('manage_custom_fields')} - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.optionEditForm.name.control}
{$i18n.label.required_fields}
 
{$forms.optionEditForm.btn_save.control}
-{/if} -
-{$forms.optionEditForm.close} diff --git a/WEB-INF/templates/cf_dropdown_option_edit2.tpl b/WEB-INF/templates/cf_dropdown_option_edit2.tpl new file mode 100644 index 000000000..f7f987cd8 --- /dev/null +++ b/WEB-INF/templates/cf_dropdown_option_edit2.tpl @@ -0,0 +1,16 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.optionEditForm.open} + + + + + + + + + +
{$forms.optionEditForm.name.control}
{$i18n.label.required_fields}
+
{$forms.optionEditForm.btn_save.control}
+{$forms.optionEditForm.close} diff --git a/cf_dropdown_option_add.php b/cf_dropdown_option_add.php index 537ad3313..c9e168730 100644 --- a/cf_dropdown_option_add.php +++ b/cf_dropdown_option_add.php @@ -49,5 +49,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.optionAddForm.name.focus()"'); $smarty->assign('title', $i18n->get('title.cf_add_dropdown_option')); -$smarty->assign('content_page_name', 'cf_dropdown_option_add.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'cf_dropdown_option_add2.tpl'); +$smarty->display('index2.tpl'); diff --git a/cf_dropdown_option_delete.php b/cf_dropdown_option_delete.php index e6eeeeb75..e23288bd5 100644 --- a/cf_dropdown_option_delete.php +++ b/cf_dropdown_option_delete.php @@ -53,5 +53,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.optionDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.cf_delete_dropdown_option')); -$smarty->assign('content_page_name', 'cf_dropdown_option_delete.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'cf_dropdown_option_delete2.tpl'); +$smarty->display('index2.tpl'); diff --git a/cf_dropdown_option_edit.php b/cf_dropdown_option_edit.php index 4cea7358f..985aab7d3 100644 --- a/cf_dropdown_option_edit.php +++ b/cf_dropdown_option_edit.php @@ -51,5 +51,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.optionEditForm.name.focus()"'); $smarty->assign('title', $i18n->get('title.cf_edit_dropdown_option')); -$smarty->assign('content_page_name', 'cf_dropdown_option_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'cf_dropdown_option_edit2.tpl'); +$smarty->display('index2.tpl'); From b9fe140cc0d5b3f958a5cb5c30abd71c89e03097 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Apr 2021 19:28:40 +0000 Subject: [PATCH 1477/1848] Limited name length for a dropdown option on forms to match db limit. --- cf_dropdown_option_add.php | 2 +- cf_dropdown_option_edit.php | 2 +- initialize.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cf_dropdown_option_add.php b/cf_dropdown_option_add.php index c9e168730..f1bf00908 100644 --- a/cf_dropdown_option_add.php +++ b/cf_dropdown_option_add.php @@ -26,7 +26,7 @@ $form = new Form('optionAddForm'); if ($err->no()) { $form->addInput(array('type'=>'hidden','name'=>'field_id','value'=>$cl_field_id)); - $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>'')); + $form->addInput(array('type'=>'text','maxlength'=>'32','name'=>'name','value'=>'')); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); } diff --git a/cf_dropdown_option_edit.php b/cf_dropdown_option_edit.php index 985aab7d3..c73200ffc 100644 --- a/cf_dropdown_option_edit.php +++ b/cf_dropdown_option_edit.php @@ -25,7 +25,7 @@ $form = new Form('optionEditForm'); if ($err->no()) { - $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); + $form->addInput(array('type'=>'text','maxlength'=>'32','name'=>'name','value'=>$cl_name)); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); } diff --git a/initialize.php b/initialize.php index 64e508695..247c74c1c 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5464"); +define("APP_VERSION", "1.19.28.5465"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 9fca36776e184248152923ce5b5f519d0210fe94 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Apr 2021 22:06:50 +0000 Subject: [PATCH 1478/1848] Fixed a php8 error with adding a client without projects, also eliminated a few php8 warnings. --- WEB-INF/lib/ttClientHelper.class.php | 33 +++++----------------------- charts.php | 4 ++-- client_add.php | 2 ++ client_edit.php | 3 ++- initialize.php | 2 +- 5 files changed, 12 insertions(+), 32 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 7105595d8..6264a6bb0 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -1,30 +1,6 @@ query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - if ($val['id']) { + if (isset($val['id']) && $val['id'] > 0) { return $val; } } @@ -190,6 +166,7 @@ static function insert($fields) $address = $fields['address']; $tax = $fields['tax']; $projects = $fields['projects']; + $comma_separated = null; if ($projects) $comma_separated = implode(',', $projects); // This is a comma-separated list of associated projects ids. $status = $fields['status']; @@ -205,7 +182,7 @@ static function insert($fields) return false; $last_id = $mdb2->lastInsertID('tt_clients', 'id'); - if (count($projects) > 0) + if (isset($projects) && count($projects) > 0) foreach ($projects as $p_id) { $sql = "insert into tt_client_project_binds (client_id, project_id, group_id, org_id) values($last_id, $p_id, $group_id, $org_id)"; $affected = $mdb2->exec($sql); diff --git a/charts.php b/charts.php index 9dc29f588..25e6695d4 100644 --- a/charts.php +++ b/charts.php @@ -74,13 +74,13 @@ $uc->setValue(SYSC_CHART_TYPE, $cl_type); } else { // Initialize chart interval. - $cl_interval = $_SESSION['chart_interval']; + $cl_interval = @$_SESSION['chart_interval']; if (!$cl_interval) $cl_interval = $uc->getValue(SYSC_CHART_INTERVAL); if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; $_SESSION['chart_interval'] = $cl_interval; // Initialize chart type. - $cl_type = $_SESSION['chart_type']; + $cl_type = @$_SESSION['chart_type']; if (!$cl_type) $cl_type = $uc->getValue(SYSC_CHART_TYPE); $cl_type = ttChartHelper::adjustType($cl_type); $_SESSION['chart_type'] = $cl_type; diff --git a/client_add.php b/client_add.php index 114e89ea0..1b91a4080 100644 --- a/client_add.php +++ b/client_add.php @@ -19,6 +19,8 @@ $projects = ttGroupHelper::getActiveProjects(); +$cl_name = $cl_address = $cl_tax = ''; +$cl_projects = array(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_address = trim($request->getParameter('address')); diff --git a/client_edit.php b/client_edit.php index 2924346bf..c7e0a92e3 100644 --- a/client_edit.php +++ b/client_edit.php @@ -26,7 +26,8 @@ // End of access checks. $projects = ttGroupHelper::getActiveProjects(); - +$cl_name = $cl_address = $cl_tax = $cl_status = null; +$cl_projects = array(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_address = trim($request->getParameter('address')); diff --git a/initialize.php b/initialize.php index 247c74c1c..356c05dd2 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5465"); +define("APP_VERSION", "1.19.28.5466"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 8861204def014a748638458ae11c708cb68174bf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Apr 2021 17:26:13 +0000 Subject: [PATCH 1479/1848] Made display_options.php mobile friendly. --- WEB-INF/lib/ttClientHelper.class.php | 2 +- WEB-INF/templates/display_options.tpl | 36 ------------------ WEB-INF/templates/display_options2.tpl | 51 ++++++++++++++++++++++++++ default.css | 2 +- display_options.php | 6 +-- initialize.php | 2 +- 6 files changed, 57 insertions(+), 42 deletions(-) delete mode 100644 WEB-INF/templates/display_options.tpl create mode 100644 WEB-INF/templates/display_options2.tpl diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 6264a6bb0..3c5f0d646 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -207,7 +207,7 @@ static function update($fields) $address = $fields['address']; $tax = $fields['tax']; $status = $fields['status']; - $projects = $fields['projects']; + $projects = isset($fields['projects']) ? $fields['projects'] : array(); $tax = str_replace(',', '.', $tax); if ($tax == '') $tax = 0; diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl deleted file mode 100644 index 025b7d984..000000000 --- a/WEB-INF/templates/display_options.tpl +++ /dev/null @@ -1,36 +0,0 @@ -{$forms.displayOptionsForm.open} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
{$i18n.title.time}
{$forms.displayOptionsForm.time_note_on_separate_row.control} {$i18n.label.what_is_it}
{$forms.displayOptionsForm.time_not_complete_days.control} {$i18n.label.what_is_it}
{$forms.displayOptionsForm.record_custom_fields.control} {$i18n.label.what_is_it}
 
{$i18n.title.reports}
{$forms.displayOptionsForm.report_note_on_separate_row.control} {$i18n.label.what_is_it}
 
{$i18n.form.display_options.custom_css}
{$forms.displayOptionsForm.custom_css.control}
 
{$forms.displayOptionsForm.btn_save.control}
-{$forms.displayOptionsForm.close} diff --git a/WEB-INF/templates/display_options2.tpl b/WEB-INF/templates/display_options2.tpl new file mode 100644 index 000000000..e4da2cfac --- /dev/null +++ b/WEB-INF/templates/display_options2.tpl @@ -0,0 +1,51 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.displayOptionsForm.open} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$i18n.title.time}
{$forms.displayOptionsForm.time_note_on_separate_row.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.displayOptionsForm.time_not_complete_days.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.displayOptionsForm.record_custom_fields.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.title.reports}
{$forms.displayOptionsForm.report_note_on_separate_row.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.form.display_options.custom_css}
{$forms.displayOptionsForm.custom_css.control}
+
{$forms.displayOptionsForm.btn_save.control}
+{$forms.displayOptionsForm.close} diff --git a/default.css b/default.css index 6d649b69b..23098db42 100644 --- a/default.css +++ b/default.css @@ -296,7 +296,7 @@ input[type="text"].project-rate-field { } /* textareas for fields */ -#description, #address, #item_name { +#description, #address, #item_name, #custom_css { width: 220px; border-radius: 4px; border: 1px solid #c9c9c9; diff --git a/display_options.php b/display_options.php index 1d3948fd9..53a86ca9e 100644 --- a/display_options.php +++ b/display_options.php @@ -48,7 +48,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'report_note_on_separate_row','value'=>$cl_report_note_on_separate_row)); // TODO: add PDF break controller here. -$form->addInput(array('type'=>'textarea','name'=>'custom_css','style'=>'width: 250px; height: 40px;','value'=>$cl_custom_css)); +$form->addInput(array('type'=>'textarea','name'=>'custom_css','value'=>$cl_custom_css)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()){ @@ -74,5 +74,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.display_options')); -$smarty->assign('content_page_name', 'display_options.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'display_options2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index 356c05dd2..dd9e8a636 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5466"); +define("APP_VERSION", "1.19.28.5467"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From a9894c63fd4d188e74dce2b518e8b225e059839d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Apr 2021 19:27:55 +0000 Subject: [PATCH 1480/1848] Made export.php and success.php mobile friendly. --- WEB-INF/lib/ttGroupExportHelper.class.php | 28 ++----------------- WEB-INF/templates/export.tpl | 23 --------------- WEB-INF/templates/export2.tpl | 16 +++++++++++ .../templates/{success.tpl => success2.tpl} | 0 WEB-INF/templates/time2.tpl | 4 +-- expense_edit.php | 3 +- export.php | 4 +-- initialize.php | 2 +- success.php | 4 +-- time.php | 2 +- 10 files changed, 27 insertions(+), 59 deletions(-) delete mode 100644 WEB-INF/templates/export.tpl create mode 100644 WEB-INF/templates/export2.tpl rename WEB-INF/templates/{success.tpl => success2.tpl} (100%) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index a510da274..b880ef6d3 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -1,30 +1,6 @@ -
-{if $user->can('export_data')} - - - - - - - - - - - - -
{$i18n.form.export.hint}
 
{$i18n.form.export.compression}:{$forms.exportForm.compression.control}
{$forms.exportForm.btn_submit.control}
-{/if} -
-{$forms.exportForm.close} diff --git a/WEB-INF/templates/export2.tpl b/WEB-INF/templates/export2.tpl new file mode 100644 index 000000000..171aa9b1b --- /dev/null +++ b/WEB-INF/templates/export2.tpl @@ -0,0 +1,16 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +
{$i18n.form.export.hint}
+ +{$forms.exportForm.open} + + + + + + + +
{$forms.exportForm.compression.control}
+
{$forms.exportForm.btn_submit.control}
+{$forms.exportForm.close} diff --git a/WEB-INF/templates/success.tpl b/WEB-INF/templates/success2.tpl similarity index 100% rename from WEB-INF/templates/success.tpl rename to WEB-INF/templates/success2.tpl diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time2.tpl index 14b8dcc69..f1ba587dc 100644 --- a/WEB-INF/templates/time2.tpl +++ b/WEB-INF/templates/time2.tpl @@ -117,7 +117,7 @@ License: See license.txt *} {if $show_client}
{$i18n.label.client}{$timeField['label']|escape}{$record.client|escape}{$record.$control_name|escape}
- - - -
- - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.groupForm.group_name.control}
{$i18n.label.description}:{$forms.groupForm.description.control}
{$i18n.label.required_fields}
 
{$forms.groupForm.btn_add.control}
-
-{$forms.groupForm.close} diff --git a/WEB-INF/templates/group_add2.tpl b/WEB-INF/templates/group_add2.tpl new file mode 100644 index 000000000..cc4231ebf --- /dev/null +++ b/WEB-INF/templates/group_add2.tpl @@ -0,0 +1,22 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.groupForm.open} + + + + + + + + + + + + + + + +
{$forms.groupForm.group_name.control}
{$forms.groupForm.description.control}
{$i18n.label.required_fields}
+
{$forms.groupForm.btn_add.control}
+{$forms.groupForm.close} diff --git a/WEB-INF/templates/group_advanced_edit.tpl b/WEB-INF/templates/group_advanced_edit.tpl deleted file mode 100644 index a9369787e..000000000 --- a/WEB-INF/templates/group_advanced_edit.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{$forms.groupAdvancedForm.open} - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.group_name} (*):{$forms.groupAdvancedForm.group_name.control}
{$i18n.label.description}:{$forms.groupAdvancedForm.description.control}
{$i18n.label.bcc}:{$forms.groupAdvancedForm.bcc_email.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.allow_ip}:{$forms.groupAdvancedForm.allow_ip.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
 
{$forms.groupAdvancedForm.btn_save.control}
-
-{$forms.groupForm.close} diff --git a/WEB-INF/templates/group_advanced_edit2.tpl b/WEB-INF/templates/group_advanced_edit2.tpl new file mode 100644 index 000000000..1f55adf77 --- /dev/null +++ b/WEB-INF/templates/group_advanced_edit2.tpl @@ -0,0 +1,40 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.groupAdvancedForm.open} + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$forms.groupAdvancedForm.group_name.control}
{$forms.groupAdvancedForm.description.control}
{$forms.groupAdvancedForm.bcc_email.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.groupAdvancedForm.allow_ip.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.label.required_fields}
+
{$forms.groupAdvancedForm.btn_save.control}
+{$forms.groupAdvancedForm.close} diff --git a/group_add.php b/group_add.php index 408b62168..8436acd80 100644 --- a/group_add.php +++ b/group_add.php @@ -13,6 +13,7 @@ } // End of access checks. +$cl_name = $cl_description = ''; if ($request->isPost()) { $cl_name = trim($request->getParameter('group_name')); $cl_description = trim($request->getParameter('description')); @@ -20,7 +21,7 @@ $form = new Form('groupForm'); $form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'group_name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -45,5 +46,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.groupForm.group_name.focus()"'); $smarty->assign('title', $i18n->get('title.add_group')); -$smarty->assign('content_page_name', 'group_add.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'group_add2.tpl'); +$smarty->display('index2.tpl'); diff --git a/group_advanced_edit.php b/group_advanced_edit.php index 7ea077183..efb7a49e7 100644 --- a/group_advanced_edit.php +++ b/group_advanced_edit.php @@ -30,8 +30,8 @@ } $form = new Form('groupAdvancedForm'); -$form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'group_name','value'=>$cl_group,'enable'=>$advanced_settings)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'text','maxlength'=>'200','name'=>'group_name','value'=>$cl_group)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'bcc_email','value'=>$cl_bcc_email)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'allow_ip','value'=>$cl_allow_ip)); @@ -62,5 +62,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_group')); -$smarty->assign('content_page_name', 'group_advanced_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'group_advanced_edit2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index 235e90f0e..0b3e606a7 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5468"); +define("APP_VERSION", "1.19.28.5469"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 2c67b96e2425c21f30c179869a1018ef76c54538 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Apr 2021 20:52:16 +0000 Subject: [PATCH 1482/1848] Made group_delete.php mobile friendly. --- WEB-INF/templates/group_delete.tpl | 22 ---------------------- WEB-INF/templates/group_delete2.tpl | 8 ++++++++ group_delete.php | 4 ++-- initialize.php | 2 +- 4 files changed, 11 insertions(+), 25 deletions(-) delete mode 100644 WEB-INF/templates/group_delete.tpl create mode 100644 WEB-INF/templates/group_delete2.tpl diff --git a/WEB-INF/templates/group_delete.tpl b/WEB-INF/templates/group_delete.tpl deleted file mode 100644 index a14373f55..000000000 --- a/WEB-INF/templates/group_delete.tpl +++ /dev/null @@ -1,22 +0,0 @@ -{$forms.groupForm.open} - - - - -
- - - - - - - - - - - - - -
{$i18n.form.group_delete.hint}
 
{$group_to_delete|escape}
 
{$forms.groupForm.btn_delete.control}  {$forms.groupForm.btn_cancel.control}
-
-{$forms.groupForm.close} diff --git a/WEB-INF/templates/group_delete2.tpl b/WEB-INF/templates/group_delete2.tpl new file mode 100644 index 000000000..5a02f29af --- /dev/null +++ b/WEB-INF/templates/group_delete2.tpl @@ -0,0 +1,8 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.groupForm.open} +
{$i18n.form.group_delete.hint}
+
{$group_to_delete|escape}
+
{$forms.groupForm.btn_delete.control} {$forms.groupForm.btn_cancel.control}
+{$forms.groupForm.close} diff --git a/group_delete.php b/group_delete.php index 377bb80e9..c1e47d02c 100644 --- a/group_delete.php +++ b/group_delete.php @@ -64,5 +64,5 @@ $smarty->assign('group_to_delete', $group_name); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.delete_group')); -$smarty->assign('content_page_name', 'group_delete.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'group_delete2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index 0b3e606a7..23a89ec2e 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5469"); +define("APP_VERSION", "1.19.28.5470"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 3657f7e6c8c58ce520324942cc72f1361a4a13b3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Apr 2021 13:56:08 +0000 Subject: [PATCH 1483/1848] Eliminated a few more php8 warnings. --- WEB-INF/lib/ttGroupExportHelper.class.php | 30 +++++++++++------------ initialize.php | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index b880ef6d3..a464f2e25 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -292,7 +292,7 @@ function writeData() { $user_part .= " login=\"".htmlspecialchars($user_item['login'])."\""; $user_part .= " password=\"".$user_item['password']."\""; $user_part .= " role_id=\"".$role_id."\""; - $user_part .= " client_id=\"".$this->clientMap[$user_item['client_id']]."\""; + $user_part .= " client_id=\"".@$this->clientMap[$user_item['client_id']]."\""; $user_part .= " rate=\"".$user_item['rate']."\""; $user_part .= " quota_percent=\"".$user_item['quota_percent']."\""; $user_part .= " email=\"".$user_item['email']."\""; @@ -330,8 +330,8 @@ function writeData() { foreach ($timesheets as $timesheet_item) { $timesheet_part = $this->indentation.' '."timesheetMap[$timesheet_item['id']]."\""; $timesheet_part .= " user_id=\"".$this->userMap[$timesheet_item['user_id']]."\""; - $timesheet_part .= " client_id=\"".$this->clientMap[$timesheet_item['client_id']]."\""; - $timesheet_part .= " project_id=\"".$this->projectMap[$timesheet_item['project_id']]."\""; + $timesheet_part .= " client_id=\"".@$this->clientMap[$timesheet_item['client_id']]."\""; + $timesheet_part .= " project_id=\"".@$this->projectMap[$timesheet_item['project_id']]."\""; $timesheet_part .= " name=\"".htmlspecialchars($timesheet_item['name'])."\""; $timesheet_part .= " comment=\"".htmlspecialchars($timesheet_item['comment'])."\""; $timesheet_part .= " start_date=\"".$timesheet_item['start_date']."\""; @@ -355,7 +355,7 @@ function writeData() { $invoice_part = $this->indentation.' '."invoiceMap[$invoice_item['id']]."\""; $invoice_part .= " name=\"".htmlspecialchars($invoice_item['name'])."\""; $invoice_part .= " date=\"".$invoice_item['date']."\""; - $invoice_part .= " client_id=\"".$this->clientMap[$invoice_item['client_id']]."\""; + $invoice_part .= " client_id=\"".@$this->clientMap[$invoice_item['client_id']]."\""; $invoice_part .= " status=\"".$invoice_item['status']."\""; $invoice_part .= ">\n"; fwrite($this->file, $invoice_part); @@ -380,11 +380,11 @@ function writeData() { $log_part .= " date=\"".$record['date']."\""; $log_part .= " start=\"".$record['start']."\""; $log_part .= " duration=\"".$record['duration']."\""; - $log_part .= " client_id=\"".$this->clientMap[$record['client_id']]."\""; - $log_part .= " project_id=\"".$this->projectMap[$record['project_id']]."\""; - $log_part .= " task_id=\"".$this->taskMap[$record['task_id']]."\""; - $log_part .= " timesheet_id=\"".$this->timesheetMap[$record['timesheet_id']]."\""; - $log_part .= " invoice_id=\"".$this->invoiceMap[$record['invoice_id']]."\""; + $log_part .= " client_id=\"".@$this->clientMap[$record['client_id']]."\""; + $log_part .= " project_id=\"".@$this->projectMap[$record['project_id']]."\""; + $log_part .= " task_id=\"".@$this->taskMap[$record['task_id']]."\""; + $log_part .= " timesheet_id=\"".@$this->timesheetMap[$record['timesheet_id']]."\""; + $log_part .= " invoice_id=\"".@$this->invoiceMap[$record['invoice_id']]."\""; $log_part .= " comment=\"".$this->encodeLineBreaks($record['comment'])."\""; $log_part .= " billable=\"".$record['billable']."\""; $log_part .= " approved=\"".$record['approved']."\""; @@ -440,7 +440,7 @@ function writeData() { foreach ($custom_field_log as $entry) { $custom_field_log_part = $this->indentation.' '."logMap[$entry['log_id']]."\""; $custom_field_log_part .= " field_id=\"".$this->customFieldMap[$entry['field_id']]."\""; - $custom_field_log_part .= " option_id=\"".$this->customFieldOptionMap[$entry['option_id']]."\""; + $custom_field_log_part .= " option_id=\"".@$this->customFieldOptionMap[$entry['option_id']]."\""; $custom_field_log_part .= " value=\"".htmlspecialchars($entry['value'])."\""; $custom_field_log_part .= " status=\"".$entry['status']."\""; $custom_field_log_part .= ">\n"; @@ -460,11 +460,11 @@ function writeData() { foreach ($expense_items as $expense_item) { $expense_item_part = $this->indentation.' '."userMap[$expense_item['user_id']]."\""; - $expense_item_part .= " client_id=\"".$this->clientMap[$expense_item['client_id']]."\""; + $expense_item_part .= " client_id=\"".@$this->clientMap[$expense_item['client_id']]."\""; $expense_item_part .= " project_id=\"".$this->projectMap[$expense_item['project_id']]."\""; $expense_item_part .= " name=\"".$this->encodeLineBreaks($expense_item['name'])."\""; $expense_item_part .= " cost=\"".$expense_item['cost']."\""; - $expense_item_part .= " invoice_id=\"".$this->invoiceMap[$expense_item['invoice_id']]."\""; + $expense_item_part .= " invoice_id=\"".@$this->invoiceMap[$expense_item['invoice_id']]."\""; $expense_item_part .= " approved=\"".$expense_item['approved']."\""; $expense_item_part .= " paid=\"".$expense_item['paid']."\""; $expense_item_part .= " status=\"".$expense_item['status']."\""; @@ -558,9 +558,9 @@ function writeData() { $fav_report_part .= " name=\"".htmlspecialchars($fav_report['name'])."\""; $fav_report_part .= " user_id=\"".$this->userMap[$fav_report['user_id']]."\""; $fav_report_part .= " report_spec=\"".$this->remapReportSpec($fav_report['report_spec'])."\""; - $fav_report_part .= " client_id=\"".$this->clientMap[$fav_report['client_id']]."\""; - $fav_report_part .= " project_id=\"".$this->projectMap[$fav_report['project_id']]."\""; - $fav_report_part .= " task_id=\"".$this->taskMap[$fav_report['task_id']]."\""; + $fav_report_part .= " client_id=\"".@$this->clientMap[$fav_report['client_id']]."\""; + $fav_report_part .= " project_id=\"".@$this->projectMap[$fav_report['project_id']]."\""; + $fav_report_part .= " task_id=\"".@$this->taskMap[$fav_report['task_id']]."\""; $fav_report_part .= " billable=\"".$fav_report['billable']."\""; $fav_report_part .= " approved=\"".$fav_report['approved']."\""; $fav_report_part .= " invoice=\"".$fav_report['invoice']."\""; diff --git a/initialize.php b/initialize.php index 23a89ec2e..242f96743 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5470"); +define("APP_VERSION", "1.19.28.5471"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 43464679be7b99d1f72834f94c18b2f3497b7092 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Apr 2021 14:26:59 +0000 Subject: [PATCH 1484/1848] Addressed a few more of php8 warnings. --- WEB-INF/lib/ttGroupHelper.class.php | 29 +++-------------------------- WEB-INF/lib/ttUser.class.php | 2 ++ initialize.php | 2 +- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 6da527085..defdb61d4 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -1,30 +1,6 @@ quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 3a2f1fa49..cf1065f06 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -842,6 +842,7 @@ function setOnBehalfGroup($group_id) { $this->behalf_id = null; $this->behalf_name = null; unset($this->behalfGroup); + $this->behalfGroup = null; unset($_SESSION['behalf_group_id']); unset($_SESSION['behalf_group_name']); unset($_SESSION['behalf_id']); @@ -849,6 +850,7 @@ function setOnBehalfGroup($group_id) { // Destroy report bean if it was set in session. $form = new Form('dummyForm'); + global $request; $bean = new ActionForm('reportBean', $form, $request); if ($bean->isSaved()) { $bean->destroyBean(); diff --git a/initialize.php b/initialize.php index 242f96743..037c86626 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5471"); +define("APP_VERSION", "1.19.28.5472"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From e3150e28352c26ad2c7d04faead7830b4096c0f6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Apr 2021 17:17:12 +0000 Subject: [PATCH 1485/1848] Made group_edit.php mobile friendly. --- WEB-INF/templates/group_edit.tpl | 123 --------------------- WEB-INF/templates/group_edit2.tpl | 171 ++++++++++++++++++++++++++++++ group_edit.php | 13 ++- initialize.php | 2 +- 4 files changed, 178 insertions(+), 131 deletions(-) delete mode 100644 WEB-INF/templates/group_edit.tpl create mode 100644 WEB-INF/templates/group_edit2.tpl diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl deleted file mode 100644 index e9b6deb56..000000000 --- a/WEB-INF/templates/group_edit.tpl +++ /dev/null @@ -1,123 +0,0 @@ - - -{$forms.groupForm.open} -{include file="datetime_format_preview.tpl"} - - - - - -
- -{if $user->can('manage_subgroups')} - {if $group_dropdown} - - - - - {/if} - - - - -{/if} - - - - -{if $user->can('manage_roles')} - - - - -{/if} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{if $user->can('manage_advanced_settings')} - - - - -{/if} - - - - - {* initialize preview text *} - - - - - - - - -
{$i18n.label.group}:{$forms.groupForm.group.control}
{$i18n.label.subgroups}:{$i18n.label.configure}
{$i18n.label.currency}:{$forms.groupForm.currency.control}
{$i18n.label.roles}:{$i18n.label.configure}
{$i18n.label.language}:{$forms.groupForm.lang.control}
{$i18n.label.decimal_mark}:{$forms.groupForm.decimal_mark.control}  
{$i18n.label.date_format}:{$forms.groupForm.date_format.control}  
{$i18n.label.time_format}:{$forms.groupForm.time_format.control}  
{$i18n.label.week_start}:{$forms.groupForm.start_week.control}
{$i18n.form.group_edit.display_options}:{$i18n.label.configure}
{$i18n.form.group_edit.holidays}:{$forms.groupForm.holidays.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.tracking_mode}:{$forms.groupForm.tracking_mode.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.record_type}:{$forms.groupForm.record_type.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.punch_mode}:{$forms.groupForm.punch_mode.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.allow_overlap}:{$forms.groupForm.allow_overlap.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.future_entries}:{$forms.groupForm.future_entries.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.uncompleted_indicators}:{$forms.groupForm.uncompleted_indicators.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.confirm_save}:{$forms.groupForm.confirm_save.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.advanced_settings}:{$i18n.label.configure}
{$i18n.label.required_fields}
 
{$forms.groupForm.btn_save.control} {$forms.groupForm.btn_delete.control}
-
-{$forms.groupForm.close} diff --git a/WEB-INF/templates/group_edit2.tpl b/WEB-INF/templates/group_edit2.tpl new file mode 100644 index 000000000..0c44d3915 --- /dev/null +++ b/WEB-INF/templates/group_edit2.tpl @@ -0,0 +1,171 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + +{$forms.groupForm.open} +{include file="datetime_format_preview.tpl"} + +{if $user->can('manage_subgroups')} + {if isset($group_dropdown) && $group_dropdown} + + + + + + + {/if} + + + + + + +{/if} + + + + + + +{if $user->can('manage_roles')} + + + + + + +{/if} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{if $user->can('manage_advanced_settings')} + + + + + + +{/if} +
{$forms.groupForm.group.control}
{$i18n.label.subgroups}:
{$i18n.label.subgroups}:{$i18n.label.configure}
{$forms.groupForm.currency.control}
{$i18n.label.roles}:
{$i18n.label.roles}:{$i18n.label.configure}
{$forms.groupForm.lang.control}
{$forms.groupForm.decimal_mark.control}  
{$forms.groupForm.date_format.control}  
{$forms.groupForm.time_format.control}  
{$forms.groupForm.start_week.control}
{$i18n.form.group_edit.display_options}:
{$i18n.form.group_edit.display_options}:{$i18n.label.configure}
{$forms.groupForm.holidays.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.groupForm.tracking_mode.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.groupForm.record_type.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.groupForm.punch_mode.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.groupForm.allow_overlap.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.groupForm.future_entries.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.groupForm.uncompleted_indicators.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.groupForm.confirm_save.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.form.group_edit.advanced_settings}:
{$i18n.form.group_edit.advanced_settings}:{$i18n.label.configure}
+
{$forms.groupForm.btn_save.control} {$forms.groupForm.btn_delete.control}
+{$forms.groupForm.close} diff --git a/group_edit.php b/group_edit.php index e87f4015e..e1a7a5234 100644 --- a/group_edit.php +++ b/group_edit.php @@ -91,7 +91,6 @@ $form->addInput(array('type'=>'combobox', 'onchange'=>'document.groupForm.group_changed.value=1;document.groupForm.submit();', 'name'=>'group', - 'style'=>'width: 250px;', 'value'=>$group_id, 'data'=>$groups, 'datakeys'=>array('id','name'))); @@ -116,7 +115,7 @@ $longname_lang[] = array('id'=>I18n::getLangFromFilename($lfile),'name'=>$lname); } $longname_lang = mu_sort($longname_lang, 'name'); -$form->addInput(array('type'=>'combobox','name'=>'lang','style'=>'width: 200px','data'=>$longname_lang,'datakeys'=>array('id','name'),'value'=>$cl_lang)); +$form->addInput(array('type'=>'combobox','name'=>'lang','data'=>$longname_lang,'datakeys'=>array('id','name'),'value'=>$cl_lang)); $DECIMAL_MARK_OPTIONS = array(array('id'=>'.','name'=>'.'),array('id'=>',','name'=>',')); $form->addInput(array('type'=>'combobox','name'=>'decimal_mark','style'=>'width: 150px','data'=>$DECIMAL_MARK_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_decimal_mark, @@ -141,7 +140,7 @@ foreach ($i18n->weekdayNames as $id => $week_dn) { $week_start_options[] = array('id' => $id, 'name' => $week_dn); } -$form->addInput(array('type'=>'combobox','name'=>'start_week','style'=>'width: 150px;','data'=>$week_start_options,'datakeys'=>array('id','name'),'value'=>$cl_start_week)); +$form->addInput(array('type'=>'combobox','name'=>'start_week','data'=>$week_start_options,'datakeys'=>array('id','name'),'value'=>$cl_start_week)); // Show holidays control. $form->addInput(array('type'=>'text','name'=>'holidays','value'=>$cl_holidays)); @@ -151,7 +150,7 @@ $tracking_mode_options[MODE_TIME] = $i18n->get('form.group_edit.mode_time'); $tracking_mode_options[MODE_PROJECTS] = $i18n->get('form.group_edit.mode_projects'); $tracking_mode_options[MODE_PROJECTS_AND_TASKS] = $i18n->get('form.group_edit.mode_projects_and_tasks'); -$form->addInput(array('type'=>'combobox','name'=>'tracking_mode','style'=>'width: 150px;','data'=>$tracking_mode_options,'value'=>$cl_tracking_mode)); +$form->addInput(array('type'=>'combobox','name'=>'tracking_mode','data'=>$tracking_mode_options,'value'=>$cl_tracking_mode)); $form->addInput(array('type'=>'checkbox','name'=>'project_required','value'=>$cl_project_required)); // Prepare record type choices. @@ -159,7 +158,7 @@ $record_type_options[TYPE_ALL] = $i18n->get('form.group_edit.type_all'); $record_type_options[TYPE_START_FINISH] = $i18n->get('form.group_edit.type_start_finish'); $record_type_options[TYPE_DURATION] = $i18n->get('form.group_edit.type_duration'); -$form->addInput(array('type'=>'combobox','name'=>'record_type','style'=>'width: 150px;','data'=>$record_type_options,'value'=>$cl_record_type)); +$form->addInput(array('type'=>'combobox','name'=>'record_type','data'=>$record_type_options,'value'=>$cl_record_type)); // Punch mode checkbox. $form->addInput(array('type'=>'checkbox','name'=>'punch_mode','value'=>$cl_punch_mode)); @@ -229,5 +228,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="handlePluginCheckboxes();"'); $smarty->assign('title', $i18n->get('title.edit_group')); -$smarty->assign('content_page_name', 'group_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'group_edit2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index 037c86626..57f1171d6 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5472"); +define("APP_VERSION", "1.19.28.5473"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 868be205b73b1ae68715d7aa091623616d8efa72 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Apr 2021 17:24:11 +0000 Subject: [PATCH 1486/1848] Moved script to the bottom of group_edit.php to populate format examples. --- WEB-INF/templates/group_edit2.tpl | 27 +++++++++++++++------------ initialize.php | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/WEB-INF/templates/group_edit2.tpl b/WEB-INF/templates/group_edit2.tpl index 0c44d3915..e653e6756 100644 --- a/WEB-INF/templates/group_edit2.tpl +++ b/WEB-INF/templates/group_edit2.tpl @@ -3,20 +3,9 @@ License: See license.txt *} + {$forms.groupForm.open} {include file="datetime_format_preview.tpl"} @@ -169,3 +158,17 @@ adjustDecimalPreview();
{$forms.groupForm.btn_save.control} {$forms.groupForm.btn_delete.control}
{$forms.groupForm.close} + + diff --git a/initialize.php b/initialize.php index 57f1171d6..e161a3122 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5473"); +define("APP_VERSION", "1.19.28.5474"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 56646678f4da660c3a5cd94358bc48e614f8c68b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Apr 2021 19:20:41 +0000 Subject: [PATCH 1487/1848] Better separation of styles from code on group_edit.php. --- WEB-INF/templates/group_edit2.tpl | 6 +++--- default.css | 10 ++++++++++ group_edit.php | 6 +++--- initialize.php | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/group_edit2.tpl b/WEB-INF/templates/group_edit2.tpl index e653e6756..05a134dd9 100644 --- a/WEB-INF/templates/group_edit2.tpl +++ b/WEB-INF/templates/group_edit2.tpl @@ -48,19 +48,19 @@ function chLocation(newLocation) { document.location = newLocation; }
{$forms.groupForm.decimal_mark.control}  {$forms.groupForm.decimal_mark.control}  
{$forms.groupForm.date_format.control}  {$forms.groupForm.date_format.control}  
{$forms.groupForm.time_format.control}  {$forms.groupForm.time_format.control}  
- - - - -
{$i18n.label.group}: {$forms.subgroupsForm.group.control}
 
-{/if} -{if $subgroups} - - - - - - - - {foreach $subgroups as $subgroup} - - - - - - - {/foreach} -
{$i18n.label.thing_name}{$i18n.label.description}
{$subgroup.name|escape}{$subgroup.description|escape}{$i18n.label.edit}{$i18n.label.delete}
-{/if} -{$forms.subgroupsForm.close} - - - - - -
-
-
- -
-
diff --git a/WEB-INF/templates/groups2.tpl b/WEB-INF/templates/groups2.tpl new file mode 100644 index 000000000..b5ed9a7b2 --- /dev/null +++ b/WEB-INF/templates/groups2.tpl @@ -0,0 +1,45 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + +{$forms.subgroupsForm.open} +{if isset($group_dropdown) && $group_dropdown} + + + + + + + +
{$forms.subgroupsForm.group.control}
+{/if} + +
+ +{if $subgroups} + + + + + + + + {foreach $subgroups as $subgroup} + + + + + + + {/foreach} +
{$i18n.label.thing_name}{{$i18n.label.description}}
{$subgroup.name|escape}{$subgroup.description|escape}{$i18n.label.edit}{$i18n.label.delete}
+{/if} +{$forms.subgroupsForm.close} +
+
+ +
+
diff --git a/group_edit.php b/group_edit.php index cea5a6a41..d639dfeaa 100644 --- a/group_edit.php +++ b/group_edit.php @@ -41,7 +41,10 @@ // Set on behalf group accordingly. $groupChanged = (bool)$request->getParameter('group_changed'); if ($request->isPost() && $groupChanged) { - $user->setOnBehalfGroup($group_id); + $user->setOnBehalfGroup($group_id); // User changed the group in a post using group selector on group_edit.php. +} +if ($request->isGet() && !$homeGroup) { + $user->setOnBehalfGroup($group_id); // User got here in a get by clicking an edit icon for a subgroup on groups.php. } $groups = $user->getGroupsForDropdown(); diff --git a/groups.php b/groups.php index 8d99e17fd..5773220a2 100644 --- a/groups.php +++ b/groups.php @@ -30,7 +30,6 @@ $form->addInput(array('type'=>'combobox', 'onchange'=>'this.form.submit();', 'name'=>'group', - 'style'=>'width: 250px;', 'value'=>$group_id, 'data'=>$groups, 'datakeys'=>array('id','name'))); @@ -40,5 +39,5 @@ $smarty->assign('subgroups', $user->getSubgroups($group_id)); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('label.subgroups')); -$smarty->assign('content_page_name', 'groups.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'groups2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index ec49622fe..592109c93 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5475"); +define("APP_VERSION", "1.19.28.5476"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 1f2ff265c20002d27fb686afd3cd9ffcbb6503ad Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Apr 2021 20:23:41 +0000 Subject: [PATCH 1489/1848] Fixed a problem with misspelled variable name. --- group_edit.php | 2 +- initialize.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/group_edit.php b/group_edit.php index d639dfeaa..097c34054 100644 --- a/group_edit.php +++ b/group_edit.php @@ -43,7 +43,7 @@ if ($request->isPost() && $groupChanged) { $user->setOnBehalfGroup($group_id); // User changed the group in a post using group selector on group_edit.php. } -if ($request->isGet() && !$homeGroup) { +if ($request->isGet() && !$home_group) { $user->setOnBehalfGroup($group_id); // User got here in a get by clicking an edit icon for a subgroup on groups.php. } diff --git a/initialize.php b/initialize.php index 592109c93..1e43f4cc4 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5476"); +define("APP_VERSION", "1.19.28.5477"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 188d9339bd3ee08a9c4fb52a55d486316d0019b8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Apr 2021 12:45:01 +0000 Subject: [PATCH 1490/1848] Made import.php mobile friendly, eliminated some php8 warnings. --- WEB-INF/lib/ttOrgImportHelper.class.php | 63 ++++++++----------------- WEB-INF/templates/import.tpl | 17 ------- WEB-INF/templates/import2.tpl | 15 ++++++ import.php | 4 +- initialize.php | 2 +- 5 files changed, 37 insertions(+), 64 deletions(-) delete mode 100644 WEB-INF/templates/import.tpl create mode 100644 WEB-INF/templates/import2.tpl diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index ac970426f..744b67e4b 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -1,30 +1,6 @@ $this->current_group_id, 'org_id' => $this->org_id, 'role_id' => $role_id, - 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'client_id' => @$this->currentGroupClientMap[$attrs['CLIENT_ID']], 'name' => $attrs['NAME'], 'login' => $attrs['LOGIN'], 'password' => $attrs['PASSWORD'], @@ -285,8 +261,8 @@ function startElement($parser, $name, $attrs) { 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, - 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], - 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], + 'client_id' => @$this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'project_id' => @$this->currentGroupProjectMap[$attrs['PROJECT_ID']], 'name' => $attrs['NAME'], 'comment' => $attrs['COMMENT'], 'start_date' => $attrs['START_DATE'], @@ -311,7 +287,7 @@ function startElement($parser, $name, $attrs) { 'org_id' => $this->org_id, 'name' => $attrs['NAME'], 'date' => $attrs['DATE'], - 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'client_id' => @$this->currentGroupClientMap[$attrs['CLIENT_ID']], 'status' => $attrs['STATUS'])); if ($invoice_id) { // Add a mapping. @@ -330,13 +306,13 @@ function startElement($parser, $name, $attrs) { 'org_id' => $this->org_id, 'date' => $attrs['DATE'], 'start' => $attrs['START'], - 'finish' => $attrs['FINISH'], + 'finish' => @$attrs['FINISH'], 'duration' => $attrs['DURATION'], - 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], - 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], - 'task_id' => $this->currentGroupTaskMap[$attrs['TASK_ID']], - 'timesheet_id' => $this->currentGroupTimesheetMap[$attrs['TIMESHEET_ID']], - 'invoice_id' => $this->currentGroupInvoiceMap[$attrs['INVOICE_ID']], + 'client_id' => @$this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'project_id' => @$this->currentGroupProjectMap[$attrs['PROJECT_ID']], + 'task_id' => @$this->currentGroupTaskMap[$attrs['TASK_ID']], + 'timesheet_id' => @$this->currentGroupTimesheetMap[$attrs['TIMESHEET_ID']], + 'invoice_id' => @$this->currentGroupInvoiceMap[$attrs['INVOICE_ID']], 'comment' => (isset($attrs['COMMENT']) ? $attrs['COMMENT'] : ''), 'billable' => $attrs['BILLABLE'], 'approved' => $attrs['APPROVED'], @@ -387,7 +363,7 @@ function startElement($parser, $name, $attrs) { 'org_id' => $this->org_id, 'log_id' => $this->currentGroupLogMap[$attrs['LOG_ID']], 'field_id' => $this->currentGroupCustomFieldMap[$attrs['FIELD_ID']], - 'option_id' => $this->currentGroupCustomFieldOptionMap[$attrs['OPTION_ID']], + 'option_id' => @$this->currentGroupCustomFieldOptionMap[$attrs['OPTION_ID']], 'value' => $attrs['VALUE'], 'status' => $attrs['STATUS']))) { $this->errors->add($i18n->get('error.db')); @@ -402,12 +378,12 @@ function startElement($parser, $name, $attrs) { 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, - 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'client_id' => @$this->currentGroupClientMap[$attrs['CLIENT_ID']], 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], - 'timesheet_id' => $this->currentGroupTimesheetMap[$attrs['TIMESHEET_ID']], + 'timesheet_id' => @$this->currentGroupTimesheetMap[$attrs['TIMESHEET_ID']], 'name' => $attrs['NAME'], 'cost' => $attrs['COST'], - 'invoice_id' => $this->currentGroupInvoiceMap[$attrs['INVOICE_ID']], + 'invoice_id' => @$this->currentGroupInvoiceMap[$attrs['INVOICE_ID']], 'approved' => $attrs['APPROVED'], 'paid' => $attrs['PAID'], 'status' => $attrs['STATUS'])); @@ -477,9 +453,9 @@ function startElement($parser, $name, $attrs) { 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, 'report_spec' => $this->remapReportSpec($attrs['REPORT_SPEC']), - 'client' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], - 'project' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], - 'task' => $this->currentGroupTaskMap[$attrs['TASK_ID']], + 'client' => @$this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'project' => @$this->currentGroupProjectMap[$attrs['PROJECT_ID']], + 'task' => @$this->currentGroupTaskMap[$attrs['TASK_ID']], 'billable' => $attrs['BILLABLE'], 'approved' => $attrs['APPROVED'], 'invoice' => $attrs['INVOICE'], @@ -850,7 +826,6 @@ private function insertTask($fields) $org_id = (int) $fields['org_id']; $name = $fields['name']; $description = $fields['description']; - $projects = $fields['projects']; $status = $fields['status']; $sql = "insert into tt_tasks (group_id, org_id, name, description, status) diff --git a/WEB-INF/templates/import.tpl b/WEB-INF/templates/import.tpl deleted file mode 100644 index d65b64963..000000000 --- a/WEB-INF/templates/import.tpl +++ /dev/null @@ -1,17 +0,0 @@ -{$forms.importForm.open} - - - - -
- - - - - - - - -
{$i18n.form.import.hint}
 
{$i18n.form.import.file}:{$forms.importForm.xmlfile.control}
{$forms.importForm.btn_submit.control}
-
-{$forms.importForm.close} diff --git a/WEB-INF/templates/import2.tpl b/WEB-INF/templates/import2.tpl new file mode 100644 index 000000000..5d7cd33ac --- /dev/null +++ b/WEB-INF/templates/import2.tpl @@ -0,0 +1,15 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +
{$i18n.form.import.hint}
+{$forms.importForm.open} + + + + + + + +
{$forms.importForm.xmlfile.control}
+
{$forms.importForm.btn_submit.control}
+{$forms.importForm.open} diff --git a/import.php b/import.php index b743b3f5a..c4b59c240 100644 --- a/import.php +++ b/import.php @@ -25,5 +25,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray()) ); $smarty->assign('title', $i18n->get('title.import')); -$smarty->assign('content_page_name', 'import.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'import2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index 1e43f4cc4..ee1a079f7 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5477"); +define("APP_VERSION", "1.19.28.5478"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From c330fe620dd9620f71c818a569d183a872fe776e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Apr 2021 13:26:44 +0000 Subject: [PATCH 1491/1848] Fixed conditions for a couple of php8 warnings. --- initialize.php | 2 +- time.php | 2 +- time_edit.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/initialize.php b/initialize.php index ee1a079f7..15416eaed 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5478"); +define("APP_VERSION", "1.19.28.5479"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index f6cd1daf1..d96c497e3 100644 --- a/time.php +++ b/time.php @@ -212,6 +212,7 @@ } // If we show project dropdown, add controls for project and client. +$project_list = $client_list = array(); if ($showProject) { // Dropdown for projects assigned to user. $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); @@ -226,7 +227,6 @@ $largeScreenCalendarRowSpan += 2; // Client dropdown. - $client_list = array(); if ($showClient) { $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. diff --git a/time_edit.php b/time_edit.php index f4a955776..8e9f31e56 100644 --- a/time_edit.php +++ b/time_edit.php @@ -155,6 +155,7 @@ } // If we show project dropdown, add controls for project and client. +$project_list = $client_list = array(); if ($showProject) { // Dropdown for projects assigned to user. $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); @@ -168,7 +169,6 @@ 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Client dropdown. - $client_list = array(); if ($showClient) { $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. From e7152bc13119a7742c08c27ab1ef1f0033aed455 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Apr 2021 14:07:21 +0000 Subject: [PATCH 1492/1848] Made invoice_add.php mobile friendly. --- WEB-INF/lib/ttInvoiceHelper.class.php | 32 +++------------ WEB-INF/templates/invoice_add.tpl | 53 ------------------------- WEB-INF/templates/invoice_add2.tpl | 57 +++++++++++++++++++++++++++ initialize.php | 2 +- invoice_add.php | 5 ++- 5 files changed, 66 insertions(+), 83 deletions(-) delete mode 100644 WEB-INF/templates/invoice_add.tpl create mode 100644 WEB-INF/templates/invoice_add2.tpl diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 0afd0c9aa..8c1e6aafa 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -1,30 +1,6 @@ query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - if ($val['id']) { + if (isset($val['id']) && $val['id'] > 0) { return $val; } } @@ -255,6 +231,8 @@ static function invoiceableItemsExist($fields) { $end_date = new DateAndTime($user->date_format, $fields['end_date']); $end = $end_date->toString(DB_DATEFORMAT); + $project_id = null; + $project_part = ''; if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; // Our query is different depending on tracking mode. diff --git a/WEB-INF/templates/invoice_add.tpl b/WEB-INF/templates/invoice_add.tpl deleted file mode 100644 index f5211eeef..000000000 --- a/WEB-INF/templates/invoice_add.tpl +++ /dev/null @@ -1,53 +0,0 @@ -{$forms.invoiceForm.open} - - - - -
- - - - - - - - - - - - - -{if $show_project} - - - - -{/if} - - - - - - - - - - - - - - - - -
{$i18n.form.invoice.number} (*):{$forms.invoiceForm.number.control}
{$i18n.label.date} (*):{$forms.invoiceForm.date.control}
{$i18n.label.client} (*):{$forms.invoiceForm.client.control}
{$i18n.label.project}:{$forms.invoiceForm.project.control}
{$i18n.label.start_date} (*):{$forms.invoiceForm.start.control}
{$i18n.label.end_date} (*):{$forms.invoiceForm.finish.control}
{$i18n.label.required_fields}
 
{$forms.invoiceForm.btn_submit.control}
-
-{$forms.invoiceForm.close} - - diff --git a/WEB-INF/templates/invoice_add2.tpl b/WEB-INF/templates/invoice_add2.tpl new file mode 100644 index 000000000..78e4f5ba2 --- /dev/null +++ b/WEB-INF/templates/invoice_add2.tpl @@ -0,0 +1,57 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.invoiceForm.open} + + + + + + + + + + + + + + + + + + + +{if isset($show_project) && $show_project} + + + + + + +{/if} + + + + + + + + + + + + + + +
{$forms.invoiceForm.number.control}
{$forms.invoiceForm.date.control}
{$forms.invoiceForm.client.control}
{$forms.invoiceForm.project.control}
{$forms.invoiceForm.start.control}
{$forms.invoiceForm.finish.control}
{$i18n.label.required_fields}
+
{$forms.invoiceForm.btn_submit.control}
+{$forms.invoiceForm.close} + + diff --git a/initialize.php b/initialize.php index 15416eaed..2c6863908 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5479"); +define("APP_VERSION", "1.19.28.5480"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/invoice_add.php b/invoice_add.php index 9c5cd641a..9d127cd3d 100644 --- a/invoice_add.php +++ b/invoice_add.php @@ -19,6 +19,7 @@ } // End of access checks. +$cl_date = $cl_client = $cl_project = $cl_number = $cl_start = $cl_finish = null; if ($request->isPost()) { $cl_date = $request->getParameter('date'); $cl_client = (int)$request->getParameter('client'); @@ -79,5 +80,5 @@ $smarty->assign('onload', 'onLoad="document.invoiceForm.number.focus()"'); $smarty->assign('show_project', $show_project); $smarty->assign('title', $i18n->get('title.add_invoice')); -$smarty->assign('content_page_name', 'invoice_add.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'invoice_add2.tpl'); +$smarty->display('index2.tpl'); From a2b54e5b995e6f5df919767b25685dbee3189ac4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Apr 2021 14:42:35 +0000 Subject: [PATCH 1493/1848] Made invoice_delete.php mobile friendly. --- WEB-INF/lib/ttGroupHelper.class.php | 1 + WEB-INF/lib/ttInvoiceHelper.class.php | 1 + WEB-INF/templates/invoice_delete.tpl | 34 --------------------------- WEB-INF/templates/invoice_delete2.tpl | 31 ++++++++++++++++++++++++ initialize.php | 2 +- invoice_add.php | 6 ++--- invoice_delete.php | 4 ++-- invoices.php | 1 + 8 files changed, 40 insertions(+), 40 deletions(-) delete mode 100644 WEB-INF/templates/invoice_delete.tpl create mode 100644 WEB-INF/templates/invoice_delete2.tpl diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index defdb61d4..0dd3dd412 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -403,6 +403,7 @@ static function getActiveInvoices($sort_options = false) $addPaidStatus = $user->isPluginEnabled('ps'); $result = array(); + $client_part = ''; if ($user->isClient()) $client_part = "and i.client_id = $user->client_id"; diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 8c1e6aafa..2802b57e7 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -16,6 +16,7 @@ static function getInvoice($invoice_id) { $group_id = $user->getGroup(); $org_id = $user->org_id; + $client_part = ''; if ($user->isClient()) $client_part = "and client_id = $user->client_id"; $sql = "select * from tt_invoices". diff --git a/WEB-INF/templates/invoice_delete.tpl b/WEB-INF/templates/invoice_delete.tpl deleted file mode 100644 index 3e0c0700d..000000000 --- a/WEB-INF/templates/invoice_delete.tpl +++ /dev/null @@ -1,34 +0,0 @@ - - -{$forms.invoiceDeleteForm.open} - - - - -
- - - - - - - - - - - - - - -
{$i18n.form.invoice.invoice_to_delete}:{$invoice_to_delete|escape}
{$i18n.form.invoice.invoice_entries}:{$forms.invoiceDeleteForm.delete_invoice_entries.control}
 
{$forms.invoiceDeleteForm.btn_delete.control}  {$forms.invoiceDeleteForm.btn_cancel.control}
-
-{$forms.invoiceDeleteForm.close} diff --git a/WEB-INF/templates/invoice_delete2.tpl b/WEB-INF/templates/invoice_delete2.tpl new file mode 100644 index 000000000..6fb7cb6c4 --- /dev/null +++ b/WEB-INF/templates/invoice_delete2.tpl @@ -0,0 +1,31 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + +{$forms.invoiceDeleteForm.open} + + + + + + + + + + + + + +
{$i18n.form.invoice.invoice_to_delete}:
{$i18n.form.invoice.invoice_to_delete}:{$invoice_to_delete|escape}
{$forms.invoiceDeleteForm.delete_invoice_entries.control}
+
{$forms.invoiceDeleteForm.btn_delete.control} {$forms.invoiceDeleteForm.btn_cancel.control}
+{$forms.invoiceDeleteForm.close} diff --git a/initialize.php b/initialize.php index 2c6863908..979fec7c0 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5480"); +define("APP_VERSION", "1.19.28.5481"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/invoice_add.php b/invoice_add.php index 9d127cd3d..bc337a000 100644 --- a/invoice_add.php +++ b/invoice_add.php @@ -35,15 +35,15 @@ // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { $clients = ttGroupHelper::getActiveClients(); - $form->addInput(array('type'=>'combobox','name'=>'client','style'=>'width: 250px;','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->get('dropdown.select')))); + $form->addInput(array('type'=>'combobox','name'=>'client','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->get('dropdown.select')))); } // Dropdown for projects. $show_project = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); if ($show_project) { $projects = ttGroupHelper::getActiveProjects(); - $form->addInput(array('type'=>'combobox','name'=>'project','style'=>'width: 250px;','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_project,'empty'=>array(''=>$i18n->get('dropdown.all')))); + $form->addInput(array('type'=>'combobox','name'=>'project','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_project,'empty'=>array(''=>$i18n->get('dropdown.all')))); } -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'number','style'=>'width: 250px;','value'=>$cl_number)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'number','value'=>$cl_number)); $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start','value'=>$cl_start)); $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'finish','value'=>$cl_finish)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); diff --git a/invoice_delete.php b/invoice_delete.php index 5b473dfa0..7e80b1265 100644 --- a/invoice_delete.php +++ b/invoice_delete.php @@ -51,5 +51,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.invoiceDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_invoice')); -$smarty->assign('content_page_name', 'invoice_delete.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'invoice_delete2.tpl'); +$smarty->display('index2.tpl'); diff --git a/invoices.php b/invoices.php index 305dcefdc..3f5faaf73 100644 --- a/invoices.php +++ b/invoices.php @@ -17,6 +17,7 @@ } // End of access checks. +$sort_option_1 = $sort_order_1 = $sort_option_2 = $sort_order_2 = null; if ($request->isPost()) { $sort_option_1 = $request->getParameter('sort_option_1'); $sort_order_1 = $request->getParameter('sort_order_1'); From 0f5cf0125c31ac88f541879e8a14efd12c7ecbad Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Apr 2021 18:28:09 +0000 Subject: [PATCH 1494/1848] Made invoice-view.php mobile friendly. --- WEB-INF/templates/invoice_view.tpl | 90 ------------------------ WEB-INF/templates/invoice_view2.tpl | 104 ++++++++++++++++++++++++++++ default.css | 24 +++++++ initialize.php | 2 +- invoice_view.php | 6 +- rtl.css | 8 +++ 6 files changed, 141 insertions(+), 93 deletions(-) delete mode 100644 WEB-INF/templates/invoice_view.tpl create mode 100644 WEB-INF/templates/invoice_view2.tpl diff --git a/WEB-INF/templates/invoice_view.tpl b/WEB-INF/templates/invoice_view.tpl deleted file mode 100644 index 0d8c31ffe..000000000 --- a/WEB-INF/templates/invoice_view.tpl +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - -
- - - - - -
{$i18n.title.invoice} {$invoice_name|escape}
{$i18n.label.date}: {$invoice_date}
{$i18n.label.client}: {$client_name|escape}
{$i18n.label.client_address}: {$client_address|escape}
-
-{if $invoice_items} - - - - - {if $show_project} - - {/if} - {if $show_task} - - {/if} - - - - {if $user->isPluginEnabled('ps')} - - {/if} - - {foreach $invoice_items as $invoice_item} - - - - {if $show_project} - - {/if} - {if $show_task} - - {/if} - - - - {if $user->isPluginEnabled('ps')} - - {/if} - - {/foreach} - - {if $tax} - - - - - - - - - {/if} - - - - -
{$i18n.label.date}{$i18n.form.invoice.person}{$i18n.label.project}{$i18n.label.task}{$i18n.label.note}{$i18n.label.duration}{$i18n.label.cost}{$i18n.label.paid}
{$invoice_item.date}{$invoice_item.user_name|escape}{$invoice_item.project_name|escape}{$invoice_item.task_name|escape}{$invoice_item.note|escape}{$invoice_item.duration}{$invoice_item.cost}{if $invoice_item.paid}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
 
{$i18n.label.subtotal}:{$subtotal|escape}
{$i18n.label.tax}:{$tax|escape}
{$i18n.label.total}:{$total|escape}
- - {if $show_mark_paid} - {$forms.invoiceForm.open} - - - - -
- - -
{$i18n.label.mark_paid}: {$forms.invoiceForm.mark_paid_action_options.control} {$forms.invoiceForm.btn_mark_paid.control}
-
- {$forms.invoiceForm.close} - {/if} -{/if} -

- -
diff --git a/WEB-INF/templates/invoice_view2.tpl b/WEB-INF/templates/invoice_view2.tpl new file mode 100644 index 000000000..64caae8d2 --- /dev/null +++ b/WEB-INF/templates/invoice_view2.tpl @@ -0,0 +1,104 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + +
{$i18n.title.invoice} {$invoice_name|escape}
+ + + + + + + + +{if isset($client_address)} + + + + +{/if} +
{$i18n.label.date}:{$invoice_date}
{$i18n.label.client}:{$client_name|escape}
{$i18n.label.client_address}:{$client_address|escape}
+
+ +{if $invoice_items} + + + + + {if $show_project} + + {/if} + {if $show_task} + + {/if} + + + + {if $user->isPluginEnabled('ps')} + + {/if} + + {foreach $invoice_items as $invoice_item} + + + + {if $show_project} + + {/if} + {if $show_task} + + {/if} + + + + {if $show_paid_column} + + {/if} + + {/foreach} + {if $tax} + + + + {if $show_paid_column} + + {/if} + + + + + {if $show_paid_column} + + {/if} + + {/if} + + + + {if $show_paid_column} + + {/if} + +
{$i18n.label.date}{$i18n.form.invoice.person}{$i18n.label.project}{$i18n.label.task}{$i18n.label.note}{$i18n.label.duration}{$i18n.label.cost}{$i18n.label.paid}
{$invoice_item.date}{$invoice_item.user_name|escape}{$invoice_item.project_name|escape}{$invoice_item.task_name|escape}{$invoice_item.note|escape}{$invoice_item.duration}{$invoice_item.cost}{if $invoice_item.paid}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.subtotal}:{$subtotal|escape}
{$i18n.label.tax}:{$tax|escape}
{$i18n.label.total}:{$total|escape}
+{/if} + +{if $show_mark_paid} +{$forms.invoiceForm.open} + + + + + + + +
{$forms.invoiceForm.mark_paid_action_options.control} {$forms.invoiceForm.btn_mark_paid.control}
+{$forms.invoiceForm.close} +{/if} +
+
+ +
+
diff --git a/default.css b/default.css index 65f3be3b9..62be70136 100644 --- a/default.css +++ b/default.css @@ -175,6 +175,16 @@ div.page-hint { white-space: nowrap; } +/* money value cell in tables */ +.money-value-cell { + text-align: right; +} + +/* yes-no cell in tables */ +.yes-no-cell { + text-align: middle; +} + /* text cell for note header when we display notes on separate rows */ .note-header-cell { text-align: right; @@ -305,6 +315,11 @@ input[type="text"].project-rate-field { width: 136px; } +/* dropdown control with an associated button */ +.dropdown-field-with-button { + width: 136px; +} + /* textareas for fields */ #description, #address, #item_name, #custom_css { width: 220px; @@ -449,6 +464,15 @@ div.section-header { margin-bottom: .5rem; } +/* invoice-header div */ +div.invoice-header { + font-size: 2rem; +} + +th.invoice-label { + text-align: right; +} + /* div for a group of items in site map */ div.sitemap-item-group { margin-top: 2rem; diff --git a/initialize.php b/initialize.php index 979fec7c0..a716293b4 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5481"); +define("APP_VERSION", "1.19.28.5482"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/invoice_view.php b/invoice_view.php index a4d0cc50f..0e6cf1ebc 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -75,6 +75,7 @@ $mark_paid_action_options = array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')); $form->addInput(array('type'=>'combobox', 'name'=>'mark_paid_action_options', + 'class'=>'dropdown-field-with-button', 'data'=>$mark_paid_action_options, 'value'=>$cl_mark_paid_action_option)); $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->get('button.submit'))); @@ -103,8 +104,9 @@ $smarty->assign('client_address', $client['address']); $smarty->assign('show_project', MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode); $smarty->assign('show_task', MODE_PROJECTS_AND_TASKS == $trackingMode); +$smarty->assign('show_paid_column', $user->isPluginEnabled('ps')); $smarty->assign('invoice_items', $invoice_items); $smarty->assign('colspan', $colspan); $smarty->assign('title', $i18n->get('title.view_invoice')); -$smarty->assign('content_page_name', 'invoice_view.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'invoice_view2.tpl'); +$smarty->display('index2.tpl'); diff --git a/rtl.css b/rtl.css index b47b925ad..e85b8b5e5 100644 --- a/rtl.css +++ b/rtl.css @@ -36,6 +36,14 @@ html { text-align: left; } +.money-value-cell { + text-align: left; +} + .note-header-cell { text-align: left; } + +th.invoice-label { + text-align: left; +} From f37182bf1b9c66450058b48466005e544465d110 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 26 Apr 2021 20:07:56 +0000 Subject: [PATCH 1495/1848] Made invoices.php mobile friendly. --- WEB-INF/lib/ttInvoiceHelper.class.php | 2 + WEB-INF/templates/invoice_view2.tpl | 2 +- WEB-INF/templates/invoices.tpl | 60 --------------------------- WEB-INF/templates/invoices2.tpl | 56 +++++++++++++++++++++++++ initialize.php | 2 +- invoice_view.php | 3 +- invoices.php | 10 +++-- 7 files changed, 67 insertions(+), 68 deletions(-) delete mode 100644 WEB-INF/templates/invoices.tpl create mode 100644 WEB-INF/templates/invoices2.tpl diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 2802b57e7..9a20730ae 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -313,6 +313,8 @@ static function createInvoice($fields) { $end_date = new DateAndTime($user->date_format, $fields['end_date']); $end = $end_date->toString(DB_DATEFORMAT); + $project_id = null; + $project_part = ''; if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; // Create a new invoice record. diff --git a/WEB-INF/templates/invoice_view2.tpl b/WEB-INF/templates/invoice_view2.tpl index 64caae8d2..afa508724 100644 --- a/WEB-INF/templates/invoice_view2.tpl +++ b/WEB-INF/templates/invoice_view2.tpl @@ -59,7 +59,7 @@ License: See license.txt *} {/if}
{$i18n.label.subtotal}: {$subtotal|escape}
- - - -
- - -
{$i18n.label.sort}:{$forms.invoicesForm.sort_option_1.control}{$forms.invoicesForm.sort_order_1.control}{$forms.invoicesForm.sort_option_2.control}{$forms.invoicesForm.sort_order_2.control}
-
- - {$forms.invoicesForm.close} -{/if} - - - - - -
-{if $user->can('manage_invoices') || $user->can('view_client_invoices')} - - - - - - {if $user->isPluginEnabled('ps')} - - {/if} - {if !$user->isClient()} - - {/if} - - {foreach $invoices as $invoice} - - - - - {if $user->isPluginEnabled('ps')} - - {/if} - {if !$user->isClient()} - - {/if} - - {/foreach} -
{$i18n.label.invoice}{$i18n.label.client}{$i18n.label.date}{$i18n.label.paid}
{$invoice.name|escape}{$invoice.client|escape}{$invoice.date}{if $invoice.paid}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.delete}
- - {if !$user->isClient()} - - -

- {/if} -{/if} -
diff --git a/WEB-INF/templates/invoices2.tpl b/WEB-INF/templates/invoices2.tpl new file mode 100644 index 000000000..003266cb0 --- /dev/null +++ b/WEB-INF/templates/invoices2.tpl @@ -0,0 +1,56 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + +{if $show_sorting_options} +{$forms.invoicesForm.open} + + + + + + + + + + + + + +
{$forms.invoicesForm.sort_option_1.control} {$forms.invoicesForm.sort_order_1.control}
{$forms.invoicesForm.sort_option_2.control} {$forms.invoicesForm.sort_order_2.control}
+{$forms.invoicesForm.close} +{/if} + + + + + + +{if $user->isPluginEnabled('ps')} + +{/if} +{if !$user->isClient()} + +{/if} + +{foreach $invoices as $invoice} + + + + + {if $user->isPluginEnabled('ps')} + + {/if} + {if !$user->isClient()} + + {/if} + +{/foreach} +
{$i18n.label.invoice}{$i18n.label.client}{$i18n.label.date}{$i18n.label.paid}
{$invoice.name|escape}{$invoice.client|escape}{$invoice.date}{if $invoice.paid}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.delete}
+ +{if !$user->isClient()} +
+{/if} diff --git a/initialize.php b/initialize.php index a716293b4..4c84012d6 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5482"); +define("APP_VERSION", "1.19.28.5483"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/invoice_view.php b/invoice_view.php index 0e6cf1ebc..621ae4a0c 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -76,8 +76,7 @@ $form->addInput(array('type'=>'combobox', 'name'=>'mark_paid_action_options', 'class'=>'dropdown-field-with-button', - 'data'=>$mark_paid_action_options, - 'value'=>$cl_mark_paid_action_option)); + 'data'=>$mark_paid_action_options)); $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->get('button.submit'))); $smarty->assign('show_mark_paid', true); } diff --git a/invoices.php b/invoices.php index 3f5faaf73..bbca99cc7 100644 --- a/invoices.php +++ b/invoices.php @@ -36,14 +36,14 @@ $form->addInput(array('type'=>'combobox', 'name'=>'sort_option_1', + 'class'=>'dropdown-field-with-button', 'onchange'=>'this.form.sorting_changed.value=1;this.form.submit();', - //'style'=>'width: 250px;', 'data'=>$sort_options, 'value'=>$sort_option_1)); $form->addInput(array('type'=>'combobox', 'name'=>'sort_option_2', + 'class'=>'dropdown-field-with-button', 'onchange'=>'this.form.sorting_changed.value=1;this.form.submit();', - //'style'=>'width: 250px;', 'data'=>$sort_options, 'value'=>$sort_option_2, 'empty'=>array(''=>$i18n->get('dropdown.no')))); @@ -54,11 +54,13 @@ $form->addInput(array('type'=>'combobox', 'name'=>'sort_order_1', + 'class'=>'dropdown-field-with-button', 'onchange'=>'this.form.sorting_changed.value=1;this.form.submit();', 'data'=>$sort_order, 'value'=>$sort_order_1)); $form->addInput(array('type'=>'combobox', 'name'=>'sort_order_2', + 'class'=>'dropdown-field-with-button', 'onchange'=>'this.form.sorting_changed.value=1;this.form.submit();', 'data'=>$sort_order, 'value'=>$sort_order_2)); @@ -88,5 +90,5 @@ $smarty->assign('show_sorting_options', count($invoices) > 1); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.invoices')); -$smarty->assign('content_page_name', 'invoices.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'invoices2.tpl'); +$smarty->display('index2.tpl'); From 1a5296eb93a70f1c97f183b40e8c2e0b940651af Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Apr 2021 16:39:47 +0000 Subject: [PATCH 1496/1848] Made locking.php mobile friendly. --- WEB-INF/templates/locking.tpl | 20 -------------------- WEB-INF/templates/locking2.tpl | 17 +++++++++++++++++ initialize.php | 2 +- locking.php | 4 ++-- 4 files changed, 20 insertions(+), 23 deletions(-) delete mode 100644 WEB-INF/templates/locking.tpl create mode 100644 WEB-INF/templates/locking2.tpl diff --git a/WEB-INF/templates/locking.tpl b/WEB-INF/templates/locking.tpl deleted file mode 100644 index 0d76e46cc..000000000 --- a/WEB-INF/templates/locking.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.lockingForm.open} - - - - -
- - - - - - - - - - - -
{$i18n.label.schedule}:{$forms.lockingForm.lock_spec.control} {$i18n.label.what_is_it}
 
{$forms.lockingForm.btn_save.control}
-
-{$forms.lockingForm.close} diff --git a/WEB-INF/templates/locking2.tpl b/WEB-INF/templates/locking2.tpl new file mode 100644 index 000000000..8ecf48cc9 --- /dev/null +++ b/WEB-INF/templates/locking2.tpl @@ -0,0 +1,17 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.lockingForm.open} + + + + + + + +
{$forms.lockingForm.lock_spec.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
+
{$forms.lockingForm.btn_save.control}
+{$forms.lockingForm.close} diff --git a/initialize.php b/initialize.php index 4c84012d6..876ecefb9 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5483"); +define("APP_VERSION", "1.19.28.5484"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/locking.php b/locking.php index 04c8d9419..5277ec90d 100644 --- a/locking.php +++ b/locking.php @@ -37,5 +37,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.locking')); -$smarty->assign('content_page_name', 'locking.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'locking2.tpl'); +$smarty->display('index2.tpl'); From ede52c729188fb8129565e906d992b31e4f70806 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Apr 2021 17:05:20 +0000 Subject: [PATCH 1497/1848] Made mail.tpl mobile friendly. --- WEB-INF/templates/mail.tpl | 39 ------------------------------------- WEB-INF/templates/mail2.tpl | 34 ++++++++++++++++++++++++++++++++ default.css | 4 ++-- initialize.php | 2 +- invoice_send.php | 12 ++++++------ report_send.php | 12 ++++++------ 6 files changed, 49 insertions(+), 54 deletions(-) delete mode 100644 WEB-INF/templates/mail.tpl create mode 100644 WEB-INF/templates/mail2.tpl diff --git a/WEB-INF/templates/mail.tpl b/WEB-INF/templates/mail.tpl deleted file mode 100644 index 13e2be598..000000000 --- a/WEB-INF/templates/mail.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{$forms.mailForm.open} - - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.form.mail.to} (*):{$forms.mailForm.receiver.control}
{$i18n.label.cc}:{$forms.mailForm.cc.control}
{$i18n.label.subject} (*):{$forms.mailForm.subject.control}
{$i18n.label.comment}:{$forms.mailForm.comment.control}
{$i18n.label.required_fields}
{$forms.mailForm.btn_send.control}
-
-
-{$forms.mailForm.close} diff --git a/WEB-INF/templates/mail2.tpl b/WEB-INF/templates/mail2.tpl new file mode 100644 index 000000000..3a3cf132f --- /dev/null +++ b/WEB-INF/templates/mail2.tpl @@ -0,0 +1,34 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.mailForm.open} + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$forms.mailForm.receiver.control}
{$forms.mailForm.cc.control}
{$forms.mailForm.subject.control}
{$forms.mailForm.comment.control}
{$i18n.label.required_fields}
+
{$forms.mailForm.btn_send.control}
+{$forms.mailForm.close} diff --git a/default.css b/default.css index 62be70136..85ead1d9f 100644 --- a/default.css +++ b/default.css @@ -321,7 +321,7 @@ input[type="text"].project-rate-field { } /* textareas for fields */ -#description, #address, #item_name, #custom_css { +#description, #address, #item_name, #comment, #custom_css { width: 220px; border-radius: 4px; border: 1px solid #c9c9c9; @@ -329,7 +329,7 @@ input[type="text"].project-rate-field { } /* textareas with focus */ -#description:focus, #address:focus, #item_name:focus { +#description:focus, #address:focus, #item_name:focus, #comment:focus, #custom_css:focus { background-color: yellow; border: 1px solid black; outline: none; diff --git a/initialize.php b/initialize.php index 876ecefb9..c42cf9cb4 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5484"); +define("APP_VERSION", "1.19.28.5485"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/invoice_send.php b/invoice_send.php index 3a4aa25f9..c3126eb9c 100644 --- a/invoice_send.php +++ b/invoice_send.php @@ -39,10 +39,10 @@ $form = new Form('mailForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_invoice_id)); -$form->addInput(array('type'=>'text','name'=>'receiver','style'=>'width: 300px;','value'=>$cl_receiver)); -$form->addInput(array('type'=>'text','name'=>'cc','style'=>'width: 300px;','value'=>$cl_cc)); -$form->addInput(array('type'=>'text','name'=>'subject','style'=>'width: 300px;','value'=>$cl_subject)); -$form->addInput(array('type'=>'textarea','name'=>'comment','maxlength'=>'250','style'=>'width: 300px; height: 60px;')); +$form->addInput(array('type'=>'text','name'=>'receiver','value'=>$cl_receiver)); +$form->addInput(array('type'=>'text','name'=>'cc','value'=>$cl_cc)); +$form->addInput(array('type'=>'text','name'=>'subject','value'=>$cl_subject)); +$form->addInput(array('type'=>'textarea','name'=>'comment','maxlength'=>'250')); $form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('button.send'))); if ($request->isPost()) { @@ -80,5 +80,5 @@ $smarty->assign('title', $i18n->get('title.send_invoice')); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.mailForm.'.($cl_receiver?'comment':'receiver').'.focus()"'); -$smarty->assign('content_page_name', 'mail.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'mail2.tpl'); +$smarty->display('index2.tpl'); diff --git a/report_send.php b/report_send.php index a2747b957..67e7136c6 100644 --- a/report_send.php +++ b/report_send.php @@ -28,10 +28,10 @@ } $form = new Form('mailForm'); -$form->addInput(array('type'=>'text','name'=>'receiver','style'=>'width: 300px;','value'=>$cl_receiver)); -$form->addInput(array('type'=>'text','name'=>'cc','style'=>'width: 300px;','value'=>$cl_cc)); -$form->addInput(array('type'=>'text','name'=>'subject','style'=>'width: 300px;','value'=>$cl_subject)); -$form->addInput(array('type'=>'textarea','name'=>'comment','maxlength'=>'250','style'=>'width: 300px; height: 60px;')); +$form->addInput(array('type'=>'text','name'=>'receiver','value'=>$cl_receiver)); +$form->addInput(array('type'=>'text','name'=>'cc','value'=>$cl_cc)); +$form->addInput(array('type'=>'text','name'=>'subject','value'=>$cl_subject)); +$form->addInput(array('type'=>'textarea','name'=>'comment','maxlength'=>'250')); $form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('button.send'))); if ($request->isPost()) { @@ -74,5 +74,5 @@ $smarty->assign('title', $i18n->get('title.send_report')); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.mailForm.'.($cl_receiver?'comment':'receiver').'.focus()"'); -$smarty->assign('content_page_name', 'mail.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'mail2.tpl'); +$smarty->display('index2.tpl'); From 47bed4f70c41b643cc87d74dd17bd3e56dd6958d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Apr 2021 17:15:05 +0000 Subject: [PATCH 1498/1848] Removed a couple of php8 warnings. --- WEB-INF/lib/ttUserConfig.class.php | 30 +++-------------------------- WEB-INF/templates/invoice_view2.tpl | 2 +- initialize.php | 2 +- 3 files changed, 5 insertions(+), 29 deletions(-) diff --git a/WEB-INF/lib/ttUserConfig.class.php b/WEB-INF/lib/ttUserConfig.class.php index d0907bb6d..c14430581 100644 --- a/WEB-INF/lib/ttUserConfig.class.php +++ b/WEB-INF/lib/ttUserConfig.class.php @@ -1,30 +1,6 @@ mdb2->quote($name)); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - return $val['param_value']; + return @$val['param_value']; } return false; } diff --git a/WEB-INF/templates/invoice_view2.tpl b/WEB-INF/templates/invoice_view2.tpl index afa508724..801245559 100644 --- a/WEB-INF/templates/invoice_view2.tpl +++ b/WEB-INF/templates/invoice_view2.tpl @@ -85,7 +85,7 @@ License: See license.txt *}
{/if} -{if $show_mark_paid} +{if isset($show_mark_paid)} {$forms.invoiceForm.open} diff --git a/initialize.php b/initialize.php index c42cf9cb4..e5dc29655 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5485"); +define("APP_VERSION", "1.19.28.5486"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 392a47b0feb0894dad0497063367270e1c47c648 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Apr 2021 18:11:24 +0000 Subject: [PATCH 1499/1848] Made notification_add.php mobile friendly. --- WEB-INF/templates/notification_add.tpl | 46 ------------------- WEB-INF/templates/notification_add2.tpl | 59 +++++++++++++++++++++++++ initialize.php | 2 +- notification_add.php | 17 +++---- 4 files changed, 69 insertions(+), 55 deletions(-) delete mode 100644 WEB-INF/templates/notification_add.tpl create mode 100644 WEB-INF/templates/notification_add2.tpl diff --git a/WEB-INF/templates/notification_add.tpl b/WEB-INF/templates/notification_add.tpl deleted file mode 100644 index b3aaed8e7..000000000 --- a/WEB-INF/templates/notification_add.tpl +++ /dev/null @@ -1,46 +0,0 @@ -{$forms.notificationForm.open} -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.fav_report} (*):{$forms.notificationForm.fav_report.control}
{$i18n.label.schedule} (*):{$forms.notificationForm.cron_spec.control} {$i18n.label.what_is_it}
{$i18n.label.email} (*):{$forms.notificationForm.email.control}
{$i18n.label.cc}:{$forms.notificationForm.cc.control}
{$i18n.label.subject}:{$forms.notificationForm.subject.control}
{$i18n.label.comment}:{$forms.notificationForm.comment.control}
{$i18n.label.condition}:{$forms.notificationForm.report_condition.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
 
{$forms.notificationForm.btn_add.control}
-
-{$forms.notificationForm.close} diff --git a/WEB-INF/templates/notification_add2.tpl b/WEB-INF/templates/notification_add2.tpl new file mode 100644 index 000000000..b7e609126 --- /dev/null +++ b/WEB-INF/templates/notification_add2.tpl @@ -0,0 +1,59 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + +{$forms.notificationForm.open} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$forms.notificationForm.fav_report.control}
{$forms.notificationForm.cron_spec.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.notificationForm.email.control}
{$forms.notificationForm.cc.control}
{$forms.notificationForm.subject.control}
{$forms.notificationForm.comment.control}
{$forms.notificationForm.report_condition.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.label.required_fields}
+
{$forms.notificationForm.btn_add.control}
+{$forms.notificationForm.close} diff --git a/initialize.php b/initialize.php index e5dc29655..95dd0b39d 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5486"); +define("APP_VERSION", "1.19.28.5487"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/notification_add.php b/notification_add.php index 83cd7a538..1290bfa23 100644 --- a/notification_add.php +++ b/notification_add.php @@ -22,6 +22,7 @@ header('Location: access_denied.php'); // No users in subgroup. exit(); } +$cl_fav_report_id = null; if ($request->isPost() && $request->getParameter('fav_report')) { $cl_fav_report_id = (int) $request->getParameter('fav_report'); if (!ttFavReportHelper::get($cl_fav_report_id)) { @@ -33,6 +34,7 @@ $fav_reports = ttFavReportHelper::getReports(); +$cl_cron_spec = $cl_email = $cl_cc = $cl_subject = $cl_comment = $cl_report_condition = null; if ($request->isPost()) { $cl_cron_spec = trim($request->getParameter('cron_spec')); $cl_email = trim($request->getParameter('email')); @@ -47,18 +49,17 @@ $form = new Form('notificationForm'); $form->addInput(array('type'=>'combobox', 'name'=>'fav_report', - 'style'=>'width: 250px;', 'value'=>$cl_fav_report_id, 'data'=>$fav_reports, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')) )); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'cron_spec','style'=>'width: 250px;','value'=>$cl_cron_spec)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','style'=>'width: 250px;','value'=>$cl_email)); -$form->addInput(array('type'=>'text','name'=>'cc','style'=>'width: 300px;','value'=>$cl_cc)); -$form->addInput(array('type'=>'text','name'=>'subject','style'=>'width: 300px;','value'=>$cl_subject)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'cron_spec','value'=>$cl_cron_spec)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email)); +$form->addInput(array('type'=>'text','name'=>'cc','value'=>$cl_cc)); +$form->addInput(array('type'=>'text','name'=>'subject','value'=>$cl_subject)); $form->addInput(array('type'=>'textarea','name'=>'comment','value'=>$cl_comment)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'report_condition','style'=>'width: 250px;','value'=>$cl_report_condition)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'report_condition','value'=>$cl_report_condition)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -94,5 +95,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.add_notification')); -$smarty->assign('content_page_name', 'notification_add.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'notification_add2.tpl'); +$smarty->display('index2.tpl'); From cc9b41611784a6e14274cff131aa9b1bba219282 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Apr 2021 19:21:39 +0000 Subject: [PATCH 1500/1848] Made notification_edit.php and notification_delete.php mobile friendly. --- WEB-INF/templates/notification_delete.tpl | 18 ------- WEB-INF/templates/notification_delete2.tpl | 7 +++ WEB-INF/templates/notification_edit.tpl | 46 ----------------- WEB-INF/templates/notification_edit2.tpl | 59 ++++++++++++++++++++++ initialize.php | 2 +- notification_delete.php | 4 +- notification_edit.php | 15 +++--- 7 files changed, 76 insertions(+), 75 deletions(-) delete mode 100644 WEB-INF/templates/notification_delete.tpl create mode 100644 WEB-INF/templates/notification_delete2.tpl delete mode 100644 WEB-INF/templates/notification_edit.tpl create mode 100644 WEB-INF/templates/notification_edit2.tpl diff --git a/WEB-INF/templates/notification_delete.tpl b/WEB-INF/templates/notification_delete.tpl deleted file mode 100644 index fac015c3a..000000000 --- a/WEB-INF/templates/notification_delete.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{$forms.notificationDeleteForm.open} - - - - -
- - - - - - - - - -
{$notification_to_delete|escape}
 
{$forms.notificationDeleteForm.btn_delete.control}  {$forms.notificationDeleteForm.btn_cancel.control}
-
-{$forms.notificationDeleteForm.close} diff --git a/WEB-INF/templates/notification_delete2.tpl b/WEB-INF/templates/notification_delete2.tpl new file mode 100644 index 000000000..bd413463d --- /dev/null +++ b/WEB-INF/templates/notification_delete2.tpl @@ -0,0 +1,7 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.notificationDeleteForm.open} +
{$notification_to_delete|escape}
+
{$forms.notificationDeleteForm.btn_delete.control} {$forms.notificationDeleteForm.btn_cancel.control}
+{$forms.notificationDeleteForm.close} diff --git a/WEB-INF/templates/notification_edit.tpl b/WEB-INF/templates/notification_edit.tpl deleted file mode 100644 index 7c46761ea..000000000 --- a/WEB-INF/templates/notification_edit.tpl +++ /dev/null @@ -1,46 +0,0 @@ -{$forms.notificationForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.fav_report} (*):{$forms.notificationForm.fav_report.control}
{$i18n.label.schedule} (*):{$forms.notificationForm.cron_spec.control} {$i18n.label.what_is_it}
{$i18n.label.email} (*):{$forms.notificationForm.email.control}
{$i18n.label.cc}:{$forms.notificationForm.cc.control}
{$i18n.label.subject}:{$forms.notificationForm.subject.control}
{$i18n.label.comment}:{$forms.notificationForm.comment.control}
{$i18n.label.condition}:{$forms.notificationForm.report_condition.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
 
{$forms.notificationForm.btn_submit.control}
-
-{$forms.notificationForm.close} diff --git a/WEB-INF/templates/notification_edit2.tpl b/WEB-INF/templates/notification_edit2.tpl new file mode 100644 index 000000000..1a0967cc6 --- /dev/null +++ b/WEB-INF/templates/notification_edit2.tpl @@ -0,0 +1,59 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + +{$forms.notificationForm.open} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$forms.notificationForm.fav_report.control}
{$forms.notificationForm.cron_spec.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.notificationForm.email.control}
{$forms.notificationForm.cc.control}
{$forms.notificationForm.subject.control}
{$forms.notificationForm.comment.control}
{$forms.notificationForm.report_condition.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.label.required_fields}
+
{$forms.notificationForm.btn_submit.control}
+{$forms.notificationForm.close} diff --git a/initialize.php b/initialize.php index 95dd0b39d..84fbb24b3 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5487"); +define("APP_VERSION", "1.19.28.5488"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/notification_delete.php b/notification_delete.php index 93820427c..741826c03 100644 --- a/notification_delete.php +++ b/notification_delete.php @@ -51,5 +51,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.notificationDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_notification')); -$smarty->assign('content_page_name', 'notification_delete.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'notification_delete2.tpl'); +$smarty->display('index2.tpl'); diff --git a/notification_edit.php b/notification_edit.php index 3043bd8a6..43dbabcff 100644 --- a/notification_edit.php +++ b/notification_edit.php @@ -61,17 +61,16 @@ $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$notification_id)); $form->addInput(array('type'=>'combobox', 'name'=>'fav_report', - 'style'=>'width: 250px;', 'value'=>$cl_fav_report_id, 'data'=>$fav_reports, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'cron_spec','style'=>'width: 250px;','value'=>$cl_cron_spec)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','style'=>'width: 250px;','value'=>$cl_email)); -$form->addInput(array('type'=>'text','name'=>'cc','style'=>'width: 300px;','value'=>$cl_cc)); -$form->addInput(array('type'=>'text','name'=>'subject','style'=>'width: 300px;','value'=>$cl_subject)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'cron_spec','value'=>$cl_cron_spec)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email)); +$form->addInput(array('type'=>'text','name'=>'cc','value'=>$cl_cc)); +$form->addInput(array('type'=>'text','name'=>'subject','value'=>$cl_subject)); $form->addInput(array('type'=>'textarea','name'=>'comment','value'=>$cl_comment)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'report_condition','style'=>'width: 250px;','value'=>$cl_report_condition)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'report_condition','value'=>$cl_report_condition)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.save'))); if ($request->isPost()) { @@ -107,5 +106,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_notification')); -$smarty->assign('content_page_name', 'notification_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'notification_edit2.tpl'); +$smarty->display('index2.tpl'); From 13eb03fdd263cf11bfe5c9b300205eb53ab81a26 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 27 Apr 2021 19:59:57 +0000 Subject: [PATCH 1501/1848] Made notifications.php mobile friendly. --- WEB-INF/templates/notifications.tpl | 36 ---------------------------- WEB-INF/templates/notifications2.tpl | 28 ++++++++++++++++++++++ initialize.php | 2 +- notifications.php | 4 ++-- 4 files changed, 31 insertions(+), 39 deletions(-) delete mode 100644 WEB-INF/templates/notifications.tpl create mode 100644 WEB-INF/templates/notifications2.tpl diff --git a/WEB-INF/templates/notifications.tpl b/WEB-INF/templates/notifications.tpl deleted file mode 100644 index d54579027..000000000 --- a/WEB-INF/templates/notifications.tpl +++ /dev/null @@ -1,36 +0,0 @@ -{$forms.notificationsForm.open} - - - - -
-{if $user->can('manage_advanced_settings')} - - - - - - - - - - {if $notifications} - {foreach $notifications as $notification} - - - - - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.schedule}{$i18n.label.email}{$i18n.label.condition}
{$notification['name']|escape}{$notification['cron_spec']|escape}{$notification['email']|escape}{$notification['report_condition']|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - -

{$forms.notificationsForm.btn_add.control}
-{/if} -
-{$forms.notificationsForm.close} diff --git a/WEB-INF/templates/notifications2.tpl b/WEB-INF/templates/notifications2.tpl new file mode 100644 index 000000000..a1be398ea --- /dev/null +++ b/WEB-INF/templates/notifications2.tpl @@ -0,0 +1,28 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.notificationsForm.open} + + + + + + + + + +{if $notifications} + {foreach $notifications as $notification} + + + + + + + + + {/foreach} +{/if} +
{$i18n.label.thing_name}{$i18n.label.schedule}{$i18n.label.email}{$i18n.label.condition}
{$notification['name']|escape}{$notification['cron_spec']|escape}{$notification['email']|escape}{$notification['report_condition']|escape}{$i18n.label.edit}{$i18n.label.delete}
+
{$forms.notificationsForm.btn_add.control}
+{$forms.notificationsForm.close} diff --git a/initialize.php b/initialize.php index 84fbb24b3..685ceaf3d 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5488"); +define("APP_VERSION", "1.19.28.5489"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/notifications.php b/notifications.php index 5945320ef..23d1feb16 100644 --- a/notifications.php +++ b/notifications.php @@ -40,5 +40,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('notifications', $notifications); $smarty->assign('title', $i18n->get('title.notifications')); -$smarty->assign('content_page_name', 'notifications.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'notifications2.tpl'); +$smarty->display('index2.tpl'); From 4d15fb0ace9b097e76156a726fe8b7473b349c9d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 28 Apr 2021 14:35:41 +0000 Subject: [PATCH 1502/1848] Made plugins.php mobile friendly. --- WEB-INF/templates/plugins.tpl | 182 ----------------------------- WEB-INF/templates/plugins2.tpl | 205 +++++++++++++++++++++++++++++++++ initialize.php | 2 +- plugins.php | 4 +- 4 files changed, 208 insertions(+), 185 deletions(-) delete mode 100644 WEB-INF/templates/plugins.tpl create mode 100644 WEB-INF/templates/plugins2.tpl diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl deleted file mode 100644 index 6de5ede7b..000000000 --- a/WEB-INF/templates/plugins.tpl +++ /dev/null @@ -1,182 +0,0 @@ - - -{$forms.pluginsForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$forms.pluginsForm.charts.control}
{$forms.pluginsForm.clients.control} {$forms.pluginsForm.client_required.control}
{$forms.pluginsForm.invoices.control}
{$forms.pluginsForm.paid_status.control}
{$forms.pluginsForm.custom_fields.control} {if $user->isPluginEnabled('cf')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.expenses.control} {$forms.pluginsForm.tax_expenses.control} {if $user->isPluginEnabled('ex')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.notifications.control} {$i18n.label.what_is_it}{if $user_exists && $user->isPluginEnabled('no')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.locking.control} {if $user->isPluginEnabled('lk')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.quotas.control} {if $user->isPluginEnabled('mq')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.week_view.control} {if $user->isPluginEnabled('wv')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.work_units.control} {if $user->isPluginEnabled('wu')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.approval.control} {$i18n.label.what_is_it}
{$forms.pluginsForm.timesheets.control} {$i18n.label.what_is_it}
{$forms.pluginsForm.templates.control} {$i18n.label.what_is_it} {if $user->isPluginEnabled('tp')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.attachments.control} {$i18n.label.what_is_it}
{$forms.pluginsForm.work.control} {$i18n.label.what_is_it}
 
{$forms.pluginsForm.btn_save.control}
-
-{$forms.pluginsForm.close} diff --git a/WEB-INF/templates/plugins2.tpl b/WEB-INF/templates/plugins2.tpl new file mode 100644 index 000000000..370c93c59 --- /dev/null +++ b/WEB-INF/templates/plugins2.tpl @@ -0,0 +1,205 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + +{$forms.pluginsForm.open} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$forms.pluginsForm.charts.control}
{$forms.pluginsForm.clients.control} {$forms.pluginsForm.client_required.control}
{$forms.pluginsForm.invoices.control}
{$forms.pluginsForm.paid_status.control}
{$forms.pluginsForm.custom_fields.control} {if $user->isPluginEnabled('cf')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.expenses.control} {$forms.pluginsForm.tax_expenses.control} {if $user->isPluginEnabled('ex')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.notifications.control} {$i18n.label.what_is_it}{if $user_exists && $user->isPluginEnabled('no')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.locking.control} {if $user->isPluginEnabled('lk')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.quotas.control} {if $user->isPluginEnabled('mq')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.week_view.control} {if $user->isPluginEnabled('wv')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.work_units.control} {if $user->isPluginEnabled('wu')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.approval.control} {$i18n.label.what_is_it}
{$forms.pluginsForm.timesheets.control} {$i18n.label.what_is_it}
{$forms.pluginsForm.templates.control} {$i18n.label.what_is_it} {if $user->isPluginEnabled('tp')}{$i18n.label.configure}{/if}
{$forms.pluginsForm.attachments.control} {$i18n.label.what_is_it}
{$forms.pluginsForm.work.control} {$i18n.label.what_is_it}
+
{$forms.pluginsForm.btn_save.control}
+{$forms.pluginsForm.close} diff --git a/initialize.php b/initialize.php index 685ceaf3d..67ff18007 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5489"); +define("APP_VERSION", "1.19.28.5490"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins.php b/plugins.php index 9b3bc1a27..730889bc0 100644 --- a/plugins.php +++ b/plugins.php @@ -141,5 +141,5 @@ $smarty->assign('onload', 'onLoad="handlePluginCheckboxes();"'); $smarty->assign('user_exists', $user->exists()); $smarty->assign('title', $i18n->get('title.plugins')); -$smarty->assign('content_page_name', 'plugins.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'plugins2.tpl'); +$smarty->display('index2.tpl'); From b3eba2ab830fa80bd26eb58a3120b9a015b12b53 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 28 Apr 2021 16:18:20 +0000 Subject: [PATCH 1503/1848] Made predefined_expense_add.php mobile friendly. --- WEB-INF/templates/predefined_expense_add.tpl | 26 ------------------- WEB-INF/templates/predefined_expense_add2.tpl | 21 +++++++++++++++ default.css | 5 ++++ initialize.php | 2 +- predefined_expense_add.php | 9 ++++--- 5 files changed, 32 insertions(+), 31 deletions(-) delete mode 100644 WEB-INF/templates/predefined_expense_add.tpl create mode 100644 WEB-INF/templates/predefined_expense_add2.tpl diff --git a/WEB-INF/templates/predefined_expense_add.tpl b/WEB-INF/templates/predefined_expense_add.tpl deleted file mode 100644 index fd2983a70..000000000 --- a/WEB-INF/templates/predefined_expense_add.tpl +++ /dev/null @@ -1,26 +0,0 @@ -{$forms.predefinedExpenseForm.open} - - - - -
- - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.predefinedExpenseForm.name.control}
{$i18n.label.cost} (*):{$forms.predefinedExpenseForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.required_fields}
 
{$forms.predefinedExpenseForm.btn_add.control}
-
-{$forms.predefinedExpenseForm.close} diff --git a/WEB-INF/templates/predefined_expense_add2.tpl b/WEB-INF/templates/predefined_expense_add2.tpl new file mode 100644 index 000000000..5e7473848 --- /dev/null +++ b/WEB-INF/templates/predefined_expense_add2.tpl @@ -0,0 +1,21 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.predefinedExpenseForm.open} + + + + + + + + + + + + + + +
{$forms.predefinedExpenseForm.name.control}
{$forms.predefinedExpenseForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.required_fields}
+
{$forms.predefinedExpenseForm.btn_add.control}
+{$forms.predefinedExpenseForm.close} diff --git a/default.css b/default.css index 85ead1d9f..da59f9f5f 100644 --- a/default.css +++ b/default.css @@ -300,6 +300,11 @@ input[type="text"], input[type="password"], input[type="file"] { width: 220px; } +/* text field input with an associated hint */ +input.text-field-with-hint[type="text"] { + width: 136px; +} + /* project rate input control */ input[type="text"].project-rate-field { width: 50px; diff --git a/initialize.php b/initialize.php index 67ff18007..86f184b68 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5490"); +define("APP_VERSION", "1.19.28.5491"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/predefined_expense_add.php b/predefined_expense_add.php index e300fa43e..b3896585f 100644 --- a/predefined_expense_add.php +++ b/predefined_expense_add.php @@ -17,14 +17,15 @@ } // End of access checks. +$cl_name = $cl_cost = null; if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_cost = trim($request->getParameter('cost')); } $form = new Form('predefinedExpenseForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); +$form->addInput(array('class'=>'text-field-with-hint','type'=>'text','maxlength'=>'40','name'=>'cost','value'=>$cl_cost)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -44,5 +45,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.add_predefined_expense')); -$smarty->assign('content_page_name', 'predefined_expense_add.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'predefined_expense_add2.tpl'); +$smarty->display('index2.tpl'); From 5d1ee9ce5942920336ba71d2d441801c2dc8f13c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 28 Apr 2021 16:49:48 +0000 Subject: [PATCH 1504/1848] Made all predefined_expense* pages mobile friendly. --- .../templates/predefined_expense_delete.tpl | 18 ----------- .../templates/predefined_expense_delete2.tpl | 7 +++++ WEB-INF/templates/predefined_expense_edit.tpl | 26 ---------------- .../templates/predefined_expense_edit2.tpl | 21 +++++++++++++ WEB-INF/templates/predefined_expenses.tpl | 30 ------------------- WEB-INF/templates/predefined_expenses2.tpl | 24 +++++++++++++++ initialize.php | 2 +- predefined_expense_add.php | 2 +- predefined_expense_delete.php | 4 +-- predefined_expense_edit.php | 8 ++--- predefined_expenses.php | 4 +-- 11 files changed, 62 insertions(+), 84 deletions(-) delete mode 100644 WEB-INF/templates/predefined_expense_delete.tpl create mode 100644 WEB-INF/templates/predefined_expense_delete2.tpl delete mode 100644 WEB-INF/templates/predefined_expense_edit.tpl create mode 100644 WEB-INF/templates/predefined_expense_edit2.tpl delete mode 100644 WEB-INF/templates/predefined_expenses.tpl create mode 100644 WEB-INF/templates/predefined_expenses2.tpl diff --git a/WEB-INF/templates/predefined_expense_delete.tpl b/WEB-INF/templates/predefined_expense_delete.tpl deleted file mode 100644 index e91692f4c..000000000 --- a/WEB-INF/templates/predefined_expense_delete.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{$forms.predefinedExpenseDeleteForm.open} - - - - -
- - - - - - - - - -
{$predefined_expense_to_delete|escape}
 
{$forms.predefinedExpenseDeleteForm.btn_delete.control}  {$forms.predefinedExpenseDeleteForm.btn_cancel.control}
-
-{$forms.predefinedExpenseDeleteForm.close} diff --git a/WEB-INF/templates/predefined_expense_delete2.tpl b/WEB-INF/templates/predefined_expense_delete2.tpl new file mode 100644 index 000000000..23a7193c8 --- /dev/null +++ b/WEB-INF/templates/predefined_expense_delete2.tpl @@ -0,0 +1,7 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.predefinedExpenseDeleteForm.open} +
{$predefined_expense_to_delete|escape}
+
{$forms.predefinedExpenseDeleteForm.btn_delete.control} {$forms.predefinedExpenseDeleteForm.btn_cancel.control}
+{$forms.predefinedExpenseDeleteForm.close} diff --git a/WEB-INF/templates/predefined_expense_edit.tpl b/WEB-INF/templates/predefined_expense_edit.tpl deleted file mode 100644 index f53b512ad..000000000 --- a/WEB-INF/templates/predefined_expense_edit.tpl +++ /dev/null @@ -1,26 +0,0 @@ -{$forms.predefinedExpenseForm.open} - - - - -
- - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.predefinedExpenseForm.name.control}
{$i18n.label.cost} (*):{$forms.predefinedExpenseForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.required_fields}
 
{$forms.predefinedExpenseForm.btn_submit.control}
-
-{$forms.predefinedExpenseForm.close} diff --git a/WEB-INF/templates/predefined_expense_edit2.tpl b/WEB-INF/templates/predefined_expense_edit2.tpl new file mode 100644 index 000000000..06af4a315 --- /dev/null +++ b/WEB-INF/templates/predefined_expense_edit2.tpl @@ -0,0 +1,21 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.predefinedExpenseForm.open} + + + + + + + + + + + + + + +
{$forms.predefinedExpenseForm.name.control}
{$forms.predefinedExpenseForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.required_fields}
+
{$forms.predefinedExpenseForm.btn_submit.control}
+{$forms.predefinedExpenseForm.close} diff --git a/WEB-INF/templates/predefined_expenses.tpl b/WEB-INF/templates/predefined_expenses.tpl deleted file mode 100644 index d35fac0b4..000000000 --- a/WEB-INF/templates/predefined_expenses.tpl +++ /dev/null @@ -1,30 +0,0 @@ -{$forms.predefinedExpensesForm.open} - - - - -
- - - - - - - - {if $predefined_expenses} - {foreach $predefined_expenses as $predefined_expense} - - - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.cost}
{$predefined_expense['name']|escape}{$predefined_expense['cost']|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - -

{$forms.predefinedExpensesForm.btn_add.control}
-
-{$forms.predefinedExpensesForm.close} diff --git a/WEB-INF/templates/predefined_expenses2.tpl b/WEB-INF/templates/predefined_expenses2.tpl new file mode 100644 index 000000000..c0d45af9e --- /dev/null +++ b/WEB-INF/templates/predefined_expenses2.tpl @@ -0,0 +1,24 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.predefinedExpensesForm.open} + + + + + + + +{if $predefined_expenses} + {foreach $predefined_expenses as $predefined_expense} + + + + + + + {/foreach} +{/if} +
{$i18n.label.thing_name}{$i18n.label.cost}
{$predefined_expense['name']|escape}{$predefined_expense['cost']|escape}{$i18n.label.edit}{$i18n.label.delete}
+
{$forms.predefinedExpensesForm.btn_add.control}
+{$forms.predefinedExpensesForm.close} diff --git a/initialize.php b/initialize.php index 86f184b68..e8f76c489 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5491"); +define("APP_VERSION", "1.19.28.5492"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/predefined_expense_add.php b/predefined_expense_add.php index b3896585f..8cac318f1 100644 --- a/predefined_expense_add.php +++ b/predefined_expense_add.php @@ -25,7 +25,7 @@ $form = new Form('predefinedExpenseForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('class'=>'text-field-with-hint','type'=>'text','maxlength'=>'40','name'=>'cost','value'=>$cl_cost)); +$form->addInput(array('type'=>'text','class'=>'text-field-with-hint','maxlength'=>'40','name'=>'cost','value'=>$cl_cost)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { diff --git a/predefined_expense_delete.php b/predefined_expense_delete.php index e965b0be2..26b726fc1 100644 --- a/predefined_expense_delete.php +++ b/predefined_expense_delete.php @@ -48,5 +48,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.predefinedExpenseDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_predefined_expense')); -$smarty->assign('content_page_name', 'predefined_expense_delete.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'predefined_expense_delete2.tpl'); +$smarty->display('index2.tpl'); diff --git a/predefined_expense_edit.php b/predefined_expense_edit.php index 1eca3a2c7..d1b557553 100644 --- a/predefined_expense_edit.php +++ b/predefined_expense_edit.php @@ -33,8 +33,8 @@ $form = new Form('predefinedExpenseForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$predefined_expense_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); +$form->addInput(array('type'=>'text','class'=>'text-field-with-hint','maxlength'=>'40','name'=>'cost','value'=>$cl_cost)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { @@ -55,5 +55,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_predefined_expense')); -$smarty->assign('content_page_name', 'predefined_expense_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'predefined_expense_edit2.tpl'); +$smarty->display('index2.tpl'); diff --git a/predefined_expenses.php b/predefined_expenses.php index 9f94bd1cc..c44aee27b 100644 --- a/predefined_expenses.php +++ b/predefined_expenses.php @@ -33,5 +33,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('predefined_expenses', $predefinedExpenses); $smarty->assign('title', $i18n->get('title.predefined_expenses')); -$smarty->assign('content_page_name', 'predefined_expenses.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'predefined_expenses2.tpl'); +$smarty->display('index2.tpl'); From 0c78f71bded9c920746b8012ab88541f63795930 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 28 Apr 2021 17:12:00 +0000 Subject: [PATCH 1505/1848] Made profile_edit.php mobile friendly. --- WEB-INF/templates/profile_edit.tpl | 43 ----------------------------- WEB-INF/templates/profile_edit2.tpl | 43 +++++++++++++++++++++++++++++ initialize.php | 2 +- profile_edit.php | 5 ++-- 4 files changed, 47 insertions(+), 46 deletions(-) delete mode 100644 WEB-INF/templates/profile_edit.tpl create mode 100644 WEB-INF/templates/profile_edit2.tpl diff --git a/WEB-INF/templates/profile_edit.tpl b/WEB-INF/templates/profile_edit.tpl deleted file mode 100644 index 1fb040005..000000000 --- a/WEB-INF/templates/profile_edit.tpl +++ /dev/null @@ -1,43 +0,0 @@ -{$forms.profileForm.open} - - - - - -
- - - - - - - - - -{if !$auth_external} - - - - - - - - -{/if} - - - - - - - - - - - - - - -
{$i18n.label.person_name} (*):{$forms.profileForm.name.control}
{$i18n.label.login} (*):{$forms.profileForm.login.control}
{$i18n.label.password} (*):{$forms.profileForm.password1.control}
{$i18n.label.confirm_password} (*):{$forms.profileForm.password2.control}
{$i18n.label.email}:{$forms.profileForm.email.control}
{$i18n.label.required_fields}
 
{$forms.profileForm.btn_save.control}
-
-{$forms.profileForm.close} diff --git a/WEB-INF/templates/profile_edit2.tpl b/WEB-INF/templates/profile_edit2.tpl new file mode 100644 index 000000000..772172485 --- /dev/null +++ b/WEB-INF/templates/profile_edit2.tpl @@ -0,0 +1,43 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.profileForm.open} + + + + + + + + + + + + + +{if !$auth_external} + + + + + + + + + + + + + +{/if} + + + + + + + + +
{$forms.profileForm.name.control}
{$forms.profileForm.login.control}
{$forms.profileForm.password1.control}
{$forms.profileForm.password2.control}
{$forms.profileForm.email.control}
{$i18n.label.required_fields}
+
{$forms.profileForm.btn_save.control}
+{$forms.profileForm.close} diff --git a/initialize.php b/initialize.php index e8f76c489..3e27129ac 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5492"); +define("APP_VERSION", "1.19.28.5493"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/profile_edit.php b/profile_edit.php index 26091823f..f85473fe4 100644 --- a/profile_edit.php +++ b/profile_edit.php @@ -22,6 +22,7 @@ if ($user->behalf_id) $user_details = $user->getUserDetails($user->behalf_id); $current_login = $user->behalf_id ? $user_details['login'] : $user->login; +$cl_name = $cl_login = $cl_password1 = $cl_password2 = $cl_email = null; if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_login = trim($request->getParameter('login')); @@ -86,5 +87,5 @@ $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.profile')); -$smarty->assign('content_page_name', 'profile_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'profile_edit2.tpl'); +$smarty->display('index2.tpl'); From 637d9472cfd46f74f058a6b2c0dc5ca19cb5a965 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 28 Apr 2021 22:11:45 +0000 Subject: [PATCH 1506/1848] Made quotas.php mobile friendly. --- WEB-INF/templates/quotas.tpl | 60 ----------------------------------- WEB-INF/templates/quotas2.tpl | 50 +++++++++++++++++++++++++++++ default.css | 15 +++++++++ initialize.php | 2 +- quotas.php | 10 +++--- rtl.css | 4 +++ 6 files changed, 75 insertions(+), 66 deletions(-) delete mode 100644 WEB-INF/templates/quotas.tpl create mode 100644 WEB-INF/templates/quotas2.tpl diff --git a/WEB-INF/templates/quotas.tpl b/WEB-INF/templates/quotas.tpl deleted file mode 100644 index 1dba4f239..000000000 --- a/WEB-INF/templates/quotas.tpl +++ /dev/null @@ -1,60 +0,0 @@ - - -
{$i18n.form.quota.hint}
- -{$forms.monthlyQuotasForm.open} -
- - - - -
- - - - - -
{$i18n.form.quota.workday_hours}:{$forms.monthlyQuotasForm.workdayHours.control}
-
-
- - - - - - - - - -
{$i18n.form.quota.year}:{$forms.monthlyQuotasForm.year.control}
 
- - - - - -{foreach $months as $month} - - - - -{/foreach} - - -
{$i18n.form.quota.month}{$i18n.label.quota}
{$month}:{$forms.monthlyQuotasForm.$month.control}
 
-
-{$forms.monthlyQuotasForm.close} - - diff --git a/WEB-INF/templates/quotas2.tpl b/WEB-INF/templates/quotas2.tpl new file mode 100644 index 000000000..625fb6d9b --- /dev/null +++ b/WEB-INF/templates/quotas2.tpl @@ -0,0 +1,50 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +
{$i18n.form.quota.hint}
+ +{$forms.monthlyQuotasForm.open} + + + + + + + + + + + + + +
{$forms.monthlyQuotasForm.workdayHours.control}
{$forms.monthlyQuotasForm.year.control}
+
+ + + + + +{foreach $months as $month} + + + + +{/foreach} +
{$i18n.form.quota.month}{$i18n.label.quota}
{$month}:{$forms.monthlyQuotasForm.$month.control}
+
+{$forms.monthlyQuotasForm.close} + + diff --git a/default.css b/default.css index da59f9f5f..6f64eea5c 100644 --- a/default.css +++ b/default.css @@ -190,6 +190,11 @@ div.page-hint { text-align: right; } +/* cell containing text labels */ +.label-cell { + text-align: right; +} + /* control labels for large screens */ .large-screen-label { text-align: right; @@ -310,6 +315,11 @@ input[type="text"].project-rate-field { width: 50px; } +/* project rate input control */ +input[type="text"].quota-field { + width: 70px; +} + /* dropdown control */ .dropdown-field { width: 236px; @@ -325,6 +335,11 @@ input[type="text"].project-rate-field { width: 136px; } +/* a short dropdown control for small strings */ +.dropdown-field-short { + width: 85px; +} + /* textareas for fields */ #description, #address, #item_name, #comment, #custom_css { width: 220px; diff --git a/initialize.php b/initialize.php index 3e27129ac..41719a786 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5493"); +define("APP_VERSION", "1.19.28.5494"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/quotas.php b/quotas.php index 95eb894bf..c49fbf1f7 100644 --- a/quotas.php +++ b/quotas.php @@ -92,8 +92,8 @@ $workdayHours = ttTimeHelper::toAbsDuration($user->getWorkdayMinutes(), true); $form = new Form('monthlyQuotasForm'); -$form->addInput(array('type'=>'text', 'name'=>'workdayHours', 'value'=>$workdayHours, 'style'=>'width:60px')); -$form->addInput(array('type'=>'combobox','name'=>'year','data'=>$years,'datakeys'=>array('id','name'),'value'=>$selectedYear,'onchange'=>'yearChange(this.value);')); +$form->addInput(array('type'=>'text','class'=>'quota-field','name'=>'workdayHours','value'=>$workdayHours)); +$form->addInput(array('type'=>'combobox','class'=>'dropdown-field-short','name'=>'year','data'=>$years,'datakeys'=>array('id','name'),'value'=>$selectedYear,'onchange'=>'yearChange(this.value);')); for ($i=0; $i < count($months); $i++) { $value = ""; if (array_key_exists($i+1, $monthsData)){ @@ -101,11 +101,11 @@ $value = ttTimeHelper::toAbsDuration($value, true); } $name = $months[$i]; - $form->addInput(array('type'=>'text','name'=>$name,'maxlength'=>6,'value'=> $value,'style'=>'width:70px')); + $form->addInput(array('type'=>'text','class'=>'quota-field','name'=>$name,'maxlength'=>6,'value'=> $value)); } $smarty->assign('months', $months); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.monthly_quotas')); -$smarty->assign('content_page_name', 'quotas.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'quotas2.tpl'); +$smarty->display('index2.tpl'); diff --git a/rtl.css b/rtl.css index e85b8b5e5..310ab1e25 100644 --- a/rtl.css +++ b/rtl.css @@ -44,6 +44,10 @@ html { text-align: left; } +.label-cell { + text-align: left; +} + th.invoice-label { text-align: left; } From e96745aebafe236a065494bcf1882f67a92a04e3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Apr 2021 12:18:38 +0000 Subject: [PATCH 1507/1848] Made work_units.php mobile friendly. --- WEB-INF/templates/quotas2.tpl | 1 - WEB-INF/templates/work_units.tpl | 22 ------------------- WEB-INF/templates/work_units2.tpl | 35 +++++++++++++++++++++++++++++++ default.css | 5 +++++ initialize.php | 2 +- work_units.php | 8 +++---- 6 files changed, 45 insertions(+), 28 deletions(-) delete mode 100644 WEB-INF/templates/work_units.tpl create mode 100644 WEB-INF/templates/work_units2.tpl diff --git a/WEB-INF/templates/quotas2.tpl b/WEB-INF/templates/quotas2.tpl index 625fb6d9b..1c38bb322 100644 --- a/WEB-INF/templates/quotas2.tpl +++ b/WEB-INF/templates/quotas2.tpl @@ -2,7 +2,6 @@ License: See license.txt *}
{$i18n.form.quota.hint}
- {$forms.monthlyQuotasForm.open} diff --git a/WEB-INF/templates/work_units.tpl b/WEB-INF/templates/work_units.tpl deleted file mode 100644 index a4fb6b578..000000000 --- a/WEB-INF/templates/work_units.tpl +++ /dev/null @@ -1,22 +0,0 @@ -{$forms.workUnitsForm.open} -
- - - - - - - - - - - - - - - - - - -
{$i18n.form.work_units.minutes_in_unit}:{$forms.workUnitsForm.minutes_in_unit.control} {$i18n.label.what_is_it}
{$i18n.form.work_units.1st_unit_threshold}:{$forms.workUnitsForm.1st_unit_threshold.control} {$i18n.label.what_is_it}
{$i18n.label.totals_only}:{$forms.workUnitsForm.totals_only.control} {$i18n.label.what_is_it}
 
{$forms.workUnitsForm.btn_save.control}
-{$forms.weekViewForm.close} diff --git a/WEB-INF/templates/work_units2.tpl b/WEB-INF/templates/work_units2.tpl new file mode 100644 index 000000000..a2b5626f5 --- /dev/null +++ b/WEB-INF/templates/work_units2.tpl @@ -0,0 +1,35 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.workUnitsForm.open} + + + + + + + + + + + + + + + + + + + +
{$forms.workUnitsForm.minutes_in_unit.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.workUnitsForm.1st_unit_threshold.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.workUnitsForm.totals_only.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
+
{$forms.workUnitsForm.btn_save.control}
+{$forms.workUnitsForm.close} diff --git a/default.css b/default.css index 6f64eea5c..3b59185c4 100644 --- a/default.css +++ b/default.css @@ -320,6 +320,11 @@ input[type="text"].quota-field { width: 70px; } +/* project rate input control */ +input[type="text"].short-text-field { + width: 40px; +} + /* dropdown control */ .dropdown-field { width: 236px; diff --git a/initialize.php b/initialize.php index 41719a786..e38c689a6 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5494"); +define("APP_VERSION", "1.19.28.5495"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/work_units.php b/work_units.php index 826f899ab..ab2ac81af 100644 --- a/work_units.php +++ b/work_units.php @@ -30,8 +30,8 @@ } $form = new Form('workUnitsForm'); -$form->addInput(array('type'=>'text', 'name'=>'minutes_in_unit', 'value'=>$cl_minutes_in_unit, 'style'=>'width:40px')); -$form->addInput(array('type'=>'text', 'name'=>'1st_unit_threshold', 'value'=>$cl_1st_unit_threshold, 'style'=>'width:40px')); +$form->addInput(array('type'=>'text','class'=>'short-text-field','name'=>'minutes_in_unit', 'value'=>$cl_minutes_in_unit)); +$form->addInput(array('type'=>'text','class'=>'short-text-field','name'=>'1st_unit_threshold', 'value'=>$cl_1st_unit_threshold)); $form->addInput(array('type'=>'checkbox','name'=>'totals_only','value'=>$cl_totals_only)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); @@ -53,5 +53,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.work_units')); -$smarty->assign('content_page_name', 'work_units.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'work_units2.tpl'); +$smarty->display('index2.tpl'); From 058a826464349b6137cf81df8367da7ac00e1d4f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Apr 2021 12:37:56 +0000 Subject: [PATCH 1508/1848] Made week_view.php mobile friendly. --- WEB-INF/templates/week_view.tpl | 27 -------------------- WEB-INF/templates/week_view2.tpl | 44 ++++++++++++++++++++++++++++++++ initialize.php | 2 +- week_view.php | 4 +-- 4 files changed, 47 insertions(+), 30 deletions(-) delete mode 100644 WEB-INF/templates/week_view.tpl create mode 100644 WEB-INF/templates/week_view2.tpl diff --git a/WEB-INF/templates/week_view.tpl b/WEB-INF/templates/week_view.tpl deleted file mode 100644 index 17b02cb4e..000000000 --- a/WEB-INF/templates/week_view.tpl +++ /dev/null @@ -1,27 +0,0 @@ -{$forms.weekViewForm.open} - - - - - - - - - - - - - - - - - - - - - - - - -
{$forms.weekViewForm.week_menu.control} {$i18n.label.what_is_it}
{$forms.weekViewForm.week_note.control} {$i18n.label.what_is_it}
{$forms.weekViewForm.week_list.control} {$i18n.label.what_is_it}
{$forms.weekViewForm.notes.control} {$i18n.label.what_is_it}
 
{$forms.weekViewForm.btn_save.control}
-{$forms.weekViewForm.close} diff --git a/WEB-INF/templates/week_view2.tpl b/WEB-INF/templates/week_view2.tpl new file mode 100644 index 000000000..df74b402b --- /dev/null +++ b/WEB-INF/templates/week_view2.tpl @@ -0,0 +1,44 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.weekViewForm.open} + + + + + + + + + + + + + + + + + + + + + + + + + +
{$forms.weekViewForm.week_menu.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.weekViewForm.week_note.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.weekViewForm.week_list.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.weekViewForm.notes.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
+
{$forms.weekViewForm.btn_save.control}
+{$forms.weekViewForm.close} diff --git a/initialize.php b/initialize.php index e38c689a6..d7420664c 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5495"); +define("APP_VERSION", "1.19.28.5496"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/week_view.php b/week_view.php index 1718afd4b..d612239b0 100644 --- a/week_view.php +++ b/week_view.php @@ -45,5 +45,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.week_view')); -$smarty->assign('content_page_name', 'week_view.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'week_view2.tpl'); +$smarty->display('index2.tpl'); From edcdf661d0cdc3d0bda8f5174ef4c8cc51e95602 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Apr 2021 14:44:37 +0000 Subject: [PATCH 1509/1848] Made timesheets.php mobile friendly. --- WEB-INF/templates/swap_roles2.tpl | 1 + WEB-INF/templates/timesheets.tpl | 107 ----------------------------- WEB-INF/templates/timesheets2.tpl | 108 ++++++++++++++++++++++++++++++ timesheets.php | 5 +- 4 files changed, 111 insertions(+), 110 deletions(-) delete mode 100644 WEB-INF/templates/timesheets.tpl create mode 100644 WEB-INF/templates/timesheets2.tpl diff --git a/WEB-INF/templates/swap_roles2.tpl b/WEB-INF/templates/swap_roles2.tpl index 23633db55..a858db84b 100644 --- a/WEB-INF/templates/swap_roles2.tpl +++ b/WEB-INF/templates/swap_roles2.tpl @@ -9,6 +9,7 @@ License: See license.txt *}
{$forms.swapForm.swap_with.control}
{$forms.swapForm.btn_submit.control} {$forms.swapForm.btn_cancel.control}
{$forms.swapForm.close} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl deleted file mode 100644 index 318702a71..000000000 --- a/WEB-INF/templates/timesheets.tpl +++ /dev/null @@ -1,107 +0,0 @@ - - -{$forms.timesheetsForm.open} - -{if $user_dropdown} - -{/if} - - - -
{$i18n.label.user}: {$forms.timesheetsForm.user.control}
- -{if $inactive_timesheets} - -{/if} - - -{if $show_client} - -{/if} - - -{if $show_files} - -{/if} - - - -{foreach $active_timesheets as $timesheet} - - - {if $show_client} - - {/if} - - {if $timesheet.approve_status == null} - - {else} - - {/if} - {if $show_files} - {if $timesheet.has_files} - - {else} - - {/if} - {/if} - - - -{/foreach} -
{$i18n.form.timesheets.active_timesheets}
{$i18n.label.thing_name}{$i18n.label.client}{$i18n.label.submitted}{$i18n.label.approved}
{$timesheet.name|escape}{$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approve_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}
- - - -

- -{if $inactive_timesheets} - - - - - - {if $show_client} - - {/if} - - - {if $show_files} - - {/if} - - - - {foreach $inactive_timesheets as $timesheet} - - - {if $show_client} - - {/if} - - {if $timesheet.approve_status == null} - - {else} - - {/if} - {if $show_files} - {if $timesheet.has_files} - - {else} - - {/if} - {/if} - - - - {/foreach} -
{$i18n.form.timesheets.inactive_timesheets}
{$i18n.label.thing_name}{$i18n.label.client}{$i18n.label.submitted}{$i18n.label.approved}
{$timesheet.name|escape}{$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approve_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}
- - - -

-{/if} -
-{$forms.timesheetsForm.close} diff --git a/WEB-INF/templates/timesheets2.tpl b/WEB-INF/templates/timesheets2.tpl new file mode 100644 index 000000000..254162731 --- /dev/null +++ b/WEB-INF/templates/timesheets2.tpl @@ -0,0 +1,108 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + + +{if $user_dropdown} + {$forms.timesheetsForm.open} + + + + + + + {$forms.timesheetsForm.close} +{/if} +
{$forms.timesheetsForm.user.control}
+
+{if $active_timesheets} + {if $inactive_timesheets} +
{$i18n.form.timesheets.active_timesheets}
+ {/if} + + + + {if $show_client} + + {/if} + + {/if} + + + + {foreach $active_timesheets as $timesheet} + + + {if $show_client} + + {/if} + + {if $timesheet.approve_status == null} + + {else} + + {/if} + {if $show_files} + {if $timesheet.has_files} + + {else} + + {/if} + {/if} + + + + {/foreach} +
{$i18n.label.thing_name}{$i18n.label.client}{$i18n.label.submitted} + {$i18n.label.approved} + {if $show_files} +
{$timesheet.name|escape}{$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approve_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}
+{/if} +{if !$inactive_timesheets} +
+{/if} +{if $inactive_timesheets} +
{$i18n.form.timesheets.inactive_timesheets}
+ + + + {if $show_client} + + {/if} + + {/if} + + + + {foreach $inactive_timesheets as $timesheet} + + + {if $show_client} + + {/if} + + {if $timesheet.approve_status == null} + + {else} + + {/if} + {if $show_files} + {if $timesheet.has_files} + + {else} + + {/if} + {/if} + + + + {/foreach} +
{$i18n.label.thing_name}{$i18n.label.client}{$i18n.label.submitted} + {$i18n.label.approved} + {if $show_files} +
{$timesheet.name|escape}{$timesheet.client_name|escape}{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $timesheet.approve_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}
+
+{/if} diff --git a/timesheets.php b/timesheets.php index 88a4a718c..54bbc3396 100644 --- a/timesheets.php +++ b/timesheets.php @@ -59,7 +59,6 @@ $form->addInput(array('type'=>'combobox', 'onchange'=>'document.timesheetsForm.user_changed.value=1;document.timesheetsForm.submit();', 'name'=>'user', - 'style'=>'width: 250px;', 'value'=>$user_id, 'data'=>$user_list, 'datakeys'=>array('id','name'))); @@ -79,5 +78,5 @@ $smarty->assign('show_files', $showFiles); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.timesheets')); -$smarty->assign('content_page_name', 'timesheets.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'timesheets2.tpl'); +$smarty->display('index2.tpl'); From f20a75bdf5f15420984a4977207cf5296ff62e15 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Apr 2021 17:42:55 +0000 Subject: [PATCH 1510/1848] Made timesheet_add.php mobile friendly. --- WEB-INF/templates/timesheet_add.tpl | 49 ---------------------------- WEB-INF/templates/timesheet_add2.tpl | 49 ++++++++++++++++++++++++++++ initialize.php | 2 +- timesheet_add.php | 12 +++---- 4 files changed, 56 insertions(+), 56 deletions(-) delete mode 100644 WEB-INF/templates/timesheet_add.tpl create mode 100644 WEB-INF/templates/timesheet_add2.tpl diff --git a/WEB-INF/templates/timesheet_add.tpl b/WEB-INF/templates/timesheet_add.tpl deleted file mode 100644 index f4becf7f5..000000000 --- a/WEB-INF/templates/timesheet_add.tpl +++ /dev/null @@ -1,49 +0,0 @@ -{$forms.timesheetForm.open} - - - - -
- - - - - -{if $show_client} - - - - -{/if} -{if $show_project} - - - - -{/if} - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.timesheetForm.timesheet_name.control}
{$i18n.label.client}:{$forms.timesheetForm.client.control}
{$i18n.label.project}:{$forms.timesheetForm.project.control}
{$i18n.label.start_date} (*):{$forms.timesheetForm.start.control}
{$i18n.label.end_date} (*):{$forms.timesheetForm.finish.control}
{$i18n.label.comment}:{$forms.timesheetForm.comment.control}
{$i18n.label.required_fields}
 
{$forms.timesheetForm.btn_add.control}
-
-{$forms.timesheetForm.close} diff --git a/WEB-INF/templates/timesheet_add2.tpl b/WEB-INF/templates/timesheet_add2.tpl new file mode 100644 index 000000000..4f2d32d88 --- /dev/null +++ b/WEB-INF/templates/timesheet_add2.tpl @@ -0,0 +1,49 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + +{$forms.timesheetForm.open} + + + + + + + +{if $show_client} + + + + + + +{/if} + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$forms.timesheetForm.timesheet_name.control}
{$forms.timesheetForm.client.control}
{$forms.timesheetForm.project.control}
{$forms.timesheetForm.start.control}
{$forms.timesheetForm.finish.control}
{$forms.timesheetForm.comment.control}
{$i18n.label.required_fields}
+
{$forms.timesheetForm.btn_add.control}
+{$forms.timesheetForm.close} diff --git a/initialize.php b/initialize.php index d7420664c..bd82dfbfd 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5496"); +define("APP_VERSION", "1.19.28.5497"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/timesheet_add.php b/timesheet_add.php index 536241d62..5fb15df6e 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -29,23 +29,23 @@ $user_id = $user->getUser(); $form = new Form('timesheetForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'timesheet_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'timesheet_name','value'=>$cl_name)); // Dropdown for clients if the clients plugin is enabled. $showClient = $user->isPluginEnabled('cl'); if ($showClient) { $clients = ttGroupHelper::getActiveClients(); - $form->addInput(array('type'=>'combobox','name'=>'client','style'=>'width: 250px;','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->get('dropdown.select')))); + $form->addInput(array('type'=>'combobox','name'=>'client','data'=>$clients,'datakeys'=>array('id','name'),'value'=>$cl_client,'empty'=>array(''=>$i18n->get('dropdown.select')))); } // Dropdown for projects. $showProject = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); if ($showProject) { $projects = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox','name'=>'project','style'=>'width: 250px;','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_project,'empty'=>array(''=>$i18n->get('dropdown.all')))); + $form->addInput(array('type'=>'combobox','name'=>'project','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_project,'empty'=>array(''=>$i18n->get('dropdown.all')))); } $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start','value'=>$cl_start)); $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'finish','value'=>$cl_finish)); -$form->addInput(array('type'=>'textarea','name'=>'comment','style'=>'width: 250px; height: 40px;','value'=>$cl_comment)); +$form->addInput(array('type'=>'textarea','name'=>'comment','value'=>$cl_comment)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -80,5 +80,5 @@ $smarty->assign('show_client', $showClient); $smarty->assign('show_project', $showProject); $smarty->assign('title', $i18n->get('title.add_timesheet')); -$smarty->assign('content_page_name', 'timesheet_add.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'timesheet_add2.tpl'); +$smarty->display('index2.tpl'); From 3afdaab6c40a69cdfc1f3ad2099325e6f31fe300 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Apr 2021 18:53:28 +0000 Subject: [PATCH 1511/1848] Made timesheet_edit.php mobile friendly. --- WEB-INF/templates/timesheet_add2.tpl | 1 - WEB-INF/templates/timesheet_edit.tpl | 34 --------------------------- WEB-INF/templates/timesheet_edit2.tpl | 28 ++++++++++++++++++++++ initialize.php | 2 +- timesheet_edit.php | 8 +++---- 5 files changed, 33 insertions(+), 40 deletions(-) delete mode 100644 WEB-INF/templates/timesheet_edit.tpl create mode 100644 WEB-INF/templates/timesheet_edit2.tpl diff --git a/WEB-INF/templates/timesheet_add2.tpl b/WEB-INF/templates/timesheet_add2.tpl index 4f2d32d88..f69a8ff74 100644 --- a/WEB-INF/templates/timesheet_add2.tpl +++ b/WEB-INF/templates/timesheet_add2.tpl @@ -1,7 +1,6 @@ {* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt *} - {$forms.timesheetForm.open} diff --git a/WEB-INF/templates/timesheet_edit.tpl b/WEB-INF/templates/timesheet_edit.tpl deleted file mode 100644 index ec1123608..000000000 --- a/WEB-INF/templates/timesheet_edit.tpl +++ /dev/null @@ -1,34 +0,0 @@ -{$forms.timesheetForm.open} -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.timesheetForm.timesheet_name.control}
{$i18n.label.comment}:{$forms.timesheetForm.comment.control}
{$i18n.label.status}:{$forms.timesheetForm.status.control}
{$i18n.label.required_fields}
 
{$forms.timesheetForm.btn_save.control} {if $can_delete}{$forms.timesheetForm.btn_delete.control}{/if}
-
-{$forms.timesheetForm.close} diff --git a/WEB-INF/templates/timesheet_edit2.tpl b/WEB-INF/templates/timesheet_edit2.tpl new file mode 100644 index 000000000..62cf01a8c --- /dev/null +++ b/WEB-INF/templates/timesheet_edit2.tpl @@ -0,0 +1,28 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.timesheetForm.open} + + + + + + + + + + + + + + + + + + + + + +
{$forms.timesheetForm.timesheet_name.control}
{$forms.timesheetForm.comment.control}
{$forms.timesheetForm.status.control}
{$i18n.label.required_fields}
+
{$forms.timesheetForm.btn_save.control} {if $can_delete}{$forms.timesheetForm.btn_delete.control}{/if}
+{$forms.timesheetForm.close} diff --git a/initialize.php b/initialize.php index bd82dfbfd..21f1c89b3 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5497"); +define("APP_VERSION", "1.19.28.5498"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/timesheet_edit.php b/timesheet_edit.php index db6897b8a..c9676ed5a 100644 --- a/timesheet_edit.php +++ b/timesheet_edit.php @@ -40,8 +40,8 @@ $form = new Form('timesheetForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_timesheet_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'timesheet_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'comment','style'=>'width: 250px; height: 40px;','value'=>$cl_comment)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'timesheet_name','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'comment','value'=>$cl_comment)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); @@ -81,5 +81,5 @@ $smarty->assign('onload', 'onLoad="document.timesheetForm.timesheet_name.focus()"'); $smarty->assign('can_delete', $canDelete); $smarty->assign('title', $i18n->get('title.edit_timesheet')); -$smarty->assign('content_page_name', 'timesheet_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'timesheet_edit2.tpl'); +$smarty->display('index2.tpl'); From a6c1e3d3615edac1d98b994298feb00e2fa178b2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Apr 2021 21:42:14 +0000 Subject: [PATCH 1512/1848] Made timesheet_view and timesheet_delete.php mobile friendly. --- WEB-INF/lib/ttReportHelper.class.php | 7 +-- WEB-INF/templates/timesheet_delete.tpl | 18 ------ WEB-INF/templates/timesheet_delete2.tpl | 7 +++ WEB-INF/templates/timesheet_view.tpl | 84 ------------------------- WEB-INF/templates/timesheet_view2.tpl | 82 ++++++++++++++++++++++++ initialize.php | 2 +- timesheet_delete.php | 4 +- timesheet_view.php | 6 +- 8 files changed, 97 insertions(+), 113 deletions(-) delete mode 100644 WEB-INF/templates/timesheet_delete.tpl create mode 100644 WEB-INF/templates/timesheet_delete2.tpl delete mode 100644 WEB-INF/templates/timesheet_view.tpl create mode 100644 WEB-INF/templates/timesheet_view2.tpl diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 604f559d8..d95348e8b 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -2252,17 +2252,14 @@ static function makeGroupByHeaderPart($dropdown_value) { return null; } - // makeGroupByHeader builds a column header for a totals-only report using group_by1, - // group_by2, and group_by3 values passed in $options. + // makeGroupByHeader builds a column header for a totals-only report + // or a timesheet using group_by1, group_by2, and group_by3 values passed in $options. static function makeGroupByHeader($options) { $no_grouping = ($options['group_by1'] == null || $options['group_by1'] == 'no_grouping') && ($options['group_by2'] == null || $options['group_by2'] == 'no_grouping') && ($options['group_by3'] == null || $options['group_by3'] == 'no_grouping'); if ($no_grouping) return null; - // We only need to do it for a totals only report. - if (!$options['show_totals_only']) return null; - $group_by_header = ''; if ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') { // We have group_by1. diff --git a/WEB-INF/templates/timesheet_delete.tpl b/WEB-INF/templates/timesheet_delete.tpl deleted file mode 100644 index 87928052e..000000000 --- a/WEB-INF/templates/timesheet_delete.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{$forms.timesheetDeleteForm.open} - - - - -
- - - - - - - - - -
{$timesheet_to_delete|escape}
 
{$forms.timesheetDeleteForm.btn_delete.control}  {$forms.timesheetDeleteForm.btn_cancel.control}
-
-{$forms.timesheetDeleteForm.close} diff --git a/WEB-INF/templates/timesheet_delete2.tpl b/WEB-INF/templates/timesheet_delete2.tpl new file mode 100644 index 000000000..a3e7b7312 --- /dev/null +++ b/WEB-INF/templates/timesheet_delete2.tpl @@ -0,0 +1,7 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.timesheetDeleteForm.open} +
{$timesheet_to_delete|escape}
+
{$forms.timesheetDeleteForm.btn_delete.control} {$forms.timesheetDeleteForm.btn_cancel.control}
+{$forms.timesheetDeleteForm.close} diff --git a/WEB-INF/templates/timesheet_view.tpl b/WEB-INF/templates/timesheet_view.tpl deleted file mode 100644 index 77cc78bd5..000000000 --- a/WEB-INF/templates/timesheet_view.tpl +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - -
- - -{if $user->behalfUser} - -{/if} -{if $timesheet['client_id']} - -{/if} -{if $timesheet['project_id']} - -{/if} -{if $timesheet['comment']} - -{/if} -{if $timesheet['approve_status'] == null} - -{/if} -{if $timesheet['approve_status'] != null} - -{/if} -{if $timesheet['approve_comment']} - -{/if} -
{$timesheet['name']|escape}
{$i18n.label.user}: {$timesheet['user_name']|escape}
{$i18n.label.client}: {$timesheet['client_name']|escape}
{$i18n.label.project}: {$timesheet['project_name']|escape}
{$i18n.label.comment}: {$timesheet['comment']|escape}
{$i18n.label.submitted}: {if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.approved}: {if $timesheet.approve_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.note}: {$timesheet['approve_comment']|escape}
-
- - - - - - {foreach $subtotals as $subtotal} - - - - - {/foreach} - - - - - - -
{$group_by_header|escape}{$i18n.label.duration}
{if $subtotal['name']}{$subtotal['name']|escape}{else} {/if}{$subtotal['time']}
 
{$i18n.label.total}{$totals['time']}
 
- -{$forms.timesheetForm.open} - {if $show_submit} - - - - -
- - -
{if $show_approvers}{$i18n.form.mail.to}: {$forms.timesheetForm.approver.control}{/if} {$forms.timesheetForm.btn_submit.control}
-
- {/if} - {if $show_approve} - - - - -
- - - - -
{$i18n.label.comment}:
{$forms.timesheetForm.comment.control}
{$forms.timesheetForm.btn_approve.control} {$forms.timesheetForm.btn_disapprove.control}
-
- {/if} -{$forms.timesheetForm.close} - -
diff --git a/WEB-INF/templates/timesheet_view2.tpl b/WEB-INF/templates/timesheet_view2.tpl new file mode 100644 index 000000000..a7d8b0e14 --- /dev/null +++ b/WEB-INF/templates/timesheet_view2.tpl @@ -0,0 +1,82 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + +
{$timesheet['name']|escape}
+ +{if $user->behalfUser} + + + + +{/if} +{if $timesheet['client_id']} + + + + +{/if} +{if $timesheet['project_id']} + + + + +{/if} +{if $timesheet['comment']} + + + + +{/if} +{if $timesheet['approve_status'] == null} + + + + +{/if} +{if $timesheet['approve_status'] != null} + + + + +{/if} +{if $timesheet['approve_comment']} + + + + +{/if} +
{$i18n.label.user}:{$timesheet['user_name']|escape}
{$i18n.label.client}:{$timesheet['client_name']|escape}
{$i18n.label.project}:{$timesheet['project_name']|escape}
{$i18n.label.comment}:{$timesheet['comment']|escape}
{$i18n.label.submitted}:{if $timesheet.submit_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.approved}:{if $timesheet.approve_status}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
{$i18n.label.note}:{$timesheet['approve_comment']|escape}
+
+ + + + + + {foreach $subtotals as $subtotal} + + + + + {/foreach} + + + + +
{$group_by_header|escape}{$i18n.label.duration}
{if $subtotal['name']}{$subtotal['name']|escape}{else} {/if}{$subtotal['time']}
{$i18n.label.total}:{$totals['time']}
+ +{$forms.timesheetForm.open} +{if $show_submit} +
{if $show_approvers}{$i18n.form.mail.to}: {$forms.timesheetForm.approver.control}{/if} {$forms.timesheetForm.btn_submit.control}
+{/if} +{if $show_approve} + + + +
{$forms.timesheetForm.comment.control}
+
{$forms.timesheetForm.btn_approve.control} {$forms.timesheetForm.btn_disapprove.control}
+{/if} +{$forms.timesheetForm.close} diff --git a/initialize.php b/initialize.php index 21f1c89b3..7afef50d1 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5498"); +define("APP_VERSION", "1.19.28.5499"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/timesheet_delete.php b/timesheet_delete.php index ff1e4e180..b0b847973 100644 --- a/timesheet_delete.php +++ b/timesheet_delete.php @@ -47,5 +47,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.invoiceDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_timesheet')); -$smarty->assign('content_page_name', 'timesheet_delete.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'timesheet_delete2.tpl'); +$smarty->display('index2.tpl'); diff --git a/timesheet_view.php b/timesheet_view.php index ff5f169b6..a74424a6b 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -59,7 +59,7 @@ } if ($showApprove) { - $form->addInput(array('type'=>'textarea','name'=>'comment','maxlength'=>'250','style'=>'width: 300px; height: 60px;')); + $form->addInput(array('type'=>'textarea','name'=>'comment','maxlength'=>'250')); $form->addInput(array('type'=>'submit','name'=>'btn_approve','value'=>$i18n->get('button.approve'))); $form->addInput(array('type'=>'submit','name'=>'btn_disapprove','value'=>$i18n->get('button.disapprove'))); } @@ -126,5 +126,5 @@ $smarty->assign('show_approve', $showApprove); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.timesheet').": ".$timesheet['start_date']." - ".$timesheet['end_date']); -$smarty->assign('content_page_name', 'timesheet_view.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'timesheet_view2.tpl'); +$smarty->display('index2.tpl'); From 4585b7e2b5b026f44d4ddad35fd6e61e7958c300 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 May 2021 14:56:37 +0000 Subject: [PATCH 1513/1848] Made templates.php mobile friendly. --- WEB-INF/templates/templates.tpl | 68 ------------------------------ WEB-INF/templates/templates2.tpl | 69 +++++++++++++++++++++++++++++++ WEB-INF/templates/timesheets2.tpl | 8 +--- default.css | 1 + initialize.php | 2 +- templates.php | 4 +- 6 files changed, 75 insertions(+), 77 deletions(-) delete mode 100644 WEB-INF/templates/templates.tpl create mode 100644 WEB-INF/templates/templates2.tpl diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl deleted file mode 100644 index 282387830..000000000 --- a/WEB-INF/templates/templates.tpl +++ /dev/null @@ -1,68 +0,0 @@ -{$forms.templatesForm.open} - - - - -
- -{if $inactive_templates} - -{/if} - - - - - - - {foreach $active_templates as $template} - - - - - - - {/foreach} -
{$i18n.form.templates.active_templates}
{$i18n.label.thing_name}{$i18n.label.description}
{$template['name']|escape}{$template['description']|escape}{$i18n.label.edit}{$i18n.label.delete}
- - -

{$forms.templatesForm.btn_add.control}
-{if $inactive_templates} - - - - - - - - - {foreach $inactive_templates as $template} - - - - - - - {/foreach} -
{$i18n.form.templates.inactive_templates}
{$i18n.label.thing_name}{$i18n.label.description}
{$template['name']|escape}{$template['description']|escape}{$i18n.label.edit}{$i18n.label.delete}
- - -

{$forms.templatesForm.btn_add.control}
-{/if} -
- -{if $show_bind_with_projects_checkbox} - - - - -{/if} - - - - - - - -
{$forms.templatesForm.bind_templates_with_projects.control} {$i18n.label.what_is_it}
{$forms.templatesForm.prepopulate_note.control} {$i18n.label.what_is_it}
{$forms.templatesForm.btn_save.control}
-
-{$forms.templatesForm.close} diff --git a/WEB-INF/templates/templates2.tpl b/WEB-INF/templates/templates2.tpl new file mode 100644 index 000000000..b37de3051 --- /dev/null +++ b/WEB-INF/templates/templates2.tpl @@ -0,0 +1,69 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.templatesForm.open} +{if $inactive_templates} +
{$i18n.form.templates.active_templates}
+{/if} + + + + + + + + {foreach $active_templates as $template} + + + + + + + {/foreach} +
{$i18n.label.thing_name}{$i18n.label.description}
{$template['name']|escape}{$template['description']|escape}{$i18n.label.edit}{$i18n.label.delete}
+
{$forms.templatesForm.btn_add.control}
+ +{if $inactive_templates} +
{$i18n.form.templates.inactive_templates}
+ + + + + + + + {foreach $inactive_templates as $template} + + + + + + + {/foreach} +
{$i18n.label.thing_name}{$i18n.label.description}
{$template['name']|escape}{$template['description']|escape}{$i18n.label.edit}{$i18n.label.delete}
+
{$forms.templatesForm.btn_add.control}
+{/if} + +{if $show_bind_with_projects_checkbox} + + + + + + +{/if} + + + + + + +
{$forms.templatesForm.bind_templates_with_projects.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.templatesForm.prepopulate_note.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
+
{$forms.templatesForm.btn_save.control}
+{$forms.templatesForm.close} diff --git a/WEB-INF/templates/timesheets2.tpl b/WEB-INF/templates/timesheets2.tpl index 254162731..fe6a9603f 100644 --- a/WEB-INF/templates/timesheets2.tpl +++ b/WEB-INF/templates/timesheets2.tpl @@ -18,10 +18,9 @@ License: See license.txt *} {/if}
-{if $active_timesheets} - {if $inactive_timesheets} +{if $inactive_timesheets}
{$i18n.form.timesheets.active_timesheets}
- {/if} +{/if} @@ -60,10 +59,7 @@ License: See license.txt *} {/foreach}
{$i18n.label.thing_name}
-{/if} -{if !$inactive_timesheets}
-{/if} {if $inactive_timesheets}
{$i18n.form.timesheets.inactive_timesheets}
diff --git a/default.css b/default.css index 3b59185c4..2304d07b2 100644 --- a/default.css +++ b/default.css @@ -286,6 +286,7 @@ span.what-is-it-img { /* span for what is it text */ span.what-is-it-text { display: inline-block; + vertical-align: middle; } /* span for what format example */ diff --git a/initialize.php b/initialize.php index 7afef50d1..9cc24fc1b 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5499"); +define("APP_VERSION", "1.19.28.5500"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/templates.php b/templates.php index 636d4bc10..53d57b86f 100644 --- a/templates.php +++ b/templates.php @@ -59,5 +59,5 @@ $smarty->assign('inactive_templates', $inactiveTemplates); $smarty->assign('show_bind_with_projects_checkbox', $showBindWithProjectsCheckbox); $smarty->assign('title', $i18n->get('title.templates')); -$smarty->assign('content_page_name', 'templates.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'templates2.tpl'); +$smarty->display('index2.tpl'); From 64bdd80ce896ffc5b2d14d3619068a767437dde4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 May 2021 15:21:25 +0000 Subject: [PATCH 1514/1848] Made template_delete.php mobile friendly. --- WEB-INF/templates/template_delete.tpl | 18 ------------------ WEB-INF/templates/template_delete2.tpl | 7 +++++++ initialize.php | 3 +-- template_delete.php | 4 ++-- 4 files changed, 10 insertions(+), 22 deletions(-) delete mode 100644 WEB-INF/templates/template_delete.tpl create mode 100644 WEB-INF/templates/template_delete2.tpl diff --git a/WEB-INF/templates/template_delete.tpl b/WEB-INF/templates/template_delete.tpl deleted file mode 100644 index 2dc4114aa..000000000 --- a/WEB-INF/templates/template_delete.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{$forms.templateDeleteForm.open} -
- - - -
- - - - - - - - - -
{$template_to_delete|escape}
 
{$forms.templateDeleteForm.btn_delete.control}  {$forms.templateDeleteForm.btn_cancel.control}
-
-{$forms.templateDeleteForm.close} diff --git a/WEB-INF/templates/template_delete2.tpl b/WEB-INF/templates/template_delete2.tpl new file mode 100644 index 000000000..a7ca2e75f --- /dev/null +++ b/WEB-INF/templates/template_delete2.tpl @@ -0,0 +1,7 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.templateDeleteForm.open} +
{$template_to_delete|escape}
+
{$forms.templateDeleteForm.btn_delete.control} {$forms.templateDeleteForm.btn_cancel.control}
+{$forms.templateDeleteForm.close} diff --git a/initialize.php b/initialize.php index 9cc24fc1b..c10e5278f 100644 --- a/initialize.php +++ b/initialize.php @@ -12,8 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -// require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5500"); +define("APP_VERSION", "1.19.28.5501"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/template_delete.php b/template_delete.php index a4996e05b..792cadbd0 100644 --- a/template_delete.php +++ b/template_delete.php @@ -47,5 +47,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.templateDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_template')); -$smarty->assign('content_page_name', 'template_delete.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'template_delete2.tpl'); +$smarty->display('index2.tpl'); From e4775fa7fba7660febf591d8fc72339593e2b625 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 May 2021 16:24:21 +0000 Subject: [PATCH 1515/1848] Made template_add.php mobile friendly. --- WEB-INF/templates/template_add.tpl | 37 ----------------------------- WEB-INF/templates/template_add2.tpl | 37 +++++++++++++++++++++++++++++ default.css | 4 ++-- initialize.php | 2 +- template_add.php | 10 ++++---- 5 files changed, 45 insertions(+), 45 deletions(-) delete mode 100644 WEB-INF/templates/template_add.tpl create mode 100644 WEB-INF/templates/template_add2.tpl diff --git a/WEB-INF/templates/template_add.tpl b/WEB-INF/templates/template_add.tpl deleted file mode 100644 index bfd624028..000000000 --- a/WEB-INF/templates/template_add.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{$forms.templateForm.open} - - - - -
- - - - - - - - - - - - - -{if $show_projects} - - - - - -{/if} - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.templateForm.name.control}
{$i18n.label.description}:{$forms.templateForm.description.control}
{$i18n.label.template} (*):{$forms.templateForm.content.control}
 
{$i18n.label.projects}:{$forms.templateForm.projects.control}
{$i18n.label.required_fields}
 
{$forms.templateForm.btn_add.control}
-
-{$forms.templateForm.close} diff --git a/WEB-INF/templates/template_add2.tpl b/WEB-INF/templates/template_add2.tpl new file mode 100644 index 000000000..554267b20 --- /dev/null +++ b/WEB-INF/templates/template_add2.tpl @@ -0,0 +1,37 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.templateForm.open} + + + + + + + + + + + + + + + + + + + +{if $show_projects} + + + + + + + +{/if} + + +
{$forms.templateForm.name.control}
{$forms.templateForm.description.control}
{$forms.templateForm.content.control}
{$forms.templateForm.projects.control}
{$i18n.label.required_fields}
+
{$forms.templateForm.btn_add.control}
+{$forms.templateForm.close} diff --git a/default.css b/default.css index 2304d07b2..c2c9e1d13 100644 --- a/default.css +++ b/default.css @@ -347,7 +347,7 @@ input[type="text"].short-text-field { } /* textareas for fields */ -#description, #address, #item_name, #comment, #custom_css { +#description, #address, #item_name, #comment, #custom_css, #content { width: 220px; border-radius: 4px; border: 1px solid #c9c9c9; @@ -355,7 +355,7 @@ input[type="text"].short-text-field { } /* textareas with focus */ -#description:focus, #address:focus, #item_name:focus, #comment:focus, #custom_css:focus { +#description:focus, #address:focus, #item_name:focus, #comment:focus, #custom_css:focus, #content:focus { background-color: yellow; border: 1px solid black; outline: none; diff --git a/initialize.php b/initialize.php index c10e5278f..d3103443c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5501"); +define("APP_VERSION", "1.19.28.5502"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/template_add.php b/template_add.php index e68671478..6347d22e3 100644 --- a/template_add.php +++ b/template_add.php @@ -35,9 +35,9 @@ } $form = new Form('templateForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'content','style'=>'width: 250px; height: 80px;','value'=>$cl_content)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'content','value'=>$cl_content)); $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); @@ -65,5 +65,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_projects', $bindTemplatesWithProjects && count($projects) > 0); $smarty->assign('title', $i18n->get('title.add_template')); -$smarty->assign('content_page_name', 'template_add.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'template_add2.tpl'); +$smarty->display('index2.tpl'); From e217bd8b4649f5991df068319fe79673ec8e98ae Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 May 2021 16:36:39 +0000 Subject: [PATCH 1516/1848] Made template_edit.php mobile friendly. --- WEB-INF/templates/template_edit.tpl | 41 -------------------------- WEB-INF/templates/template_edit2.tpl | 43 ++++++++++++++++++++++++++++ initialize.php | 2 +- template_edit.php | 10 +++---- 4 files changed, 49 insertions(+), 47 deletions(-) delete mode 100644 WEB-INF/templates/template_edit.tpl create mode 100644 WEB-INF/templates/template_edit2.tpl diff --git a/WEB-INF/templates/template_edit.tpl b/WEB-INF/templates/template_edit.tpl deleted file mode 100644 index f4db77878..000000000 --- a/WEB-INF/templates/template_edit.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{$forms.templateForm.open} - - - - -
- - - - - - - - - - - - - - - - - -{if $show_projects} - - - - - -{/if} - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.templateForm.name.control}
{$i18n.label.description}:{$forms.templateForm.description.control}
{$i18n.label.template} (*):{$forms.templateForm.content.control}
{$i18n.label.status}:{$forms.templateForm.status.control}
 
{$i18n.label.projects}:{$forms.templateForm.projects.control}
{$i18n.label.required_fields}
 
{$forms.templateForm.btn_submit.control}
-
-{$forms.templateForm.close} diff --git a/WEB-INF/templates/template_edit2.tpl b/WEB-INF/templates/template_edit2.tpl new file mode 100644 index 000000000..bdcbb279f --- /dev/null +++ b/WEB-INF/templates/template_edit2.tpl @@ -0,0 +1,43 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.templateForm.open} + + + + + + + + + + + + + + + + + + + + + + + + + +{if $show_projects} + + + + + + + +{/if} + + +
{$forms.templateForm.name.control}
{$forms.templateForm.description.control}
{$forms.templateForm.content.control}
{$forms.templateForm.status.control}
{$forms.templateForm.projects.control}
{$i18n.label.required_fields}
+
{$forms.templateForm.btn_submit.control}
+{$forms.templateForm.close} diff --git a/initialize.php b/initialize.php index d3103443c..773abee87 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5502"); +define("APP_VERSION", "1.19.28.5503"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/template_edit.php b/template_edit.php index e3fa38947..3451ff646 100644 --- a/template_edit.php +++ b/template_edit.php @@ -49,9 +49,9 @@ $form = new Form('templateForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_template_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'content','style'=>'width: 250px; height: 80px;','value'=>$cl_content)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'content','value'=>$cl_content)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); @@ -83,5 +83,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_projects', $bindTemplatesWithProjects && count($projects) > 0); $smarty->assign('title', $i18n->get('title.edit_template')); -$smarty->assign('content_page_name', 'template_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'template_edit2.tpl'); +$smarty->display('index2.tpl'); From c63f9daaf1030ad81c544f7be58f11d7b5ee0113 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 May 2021 18:21:27 +0000 Subject: [PATCH 1517/1848] Made roles.php mobile friendly. --- WEB-INF/lib/ttTemplateHelper.class.php | 31 ++--------- WEB-INF/templates/roles.tpl | 71 -------------------------- WEB-INF/templates/roles2.tpl | 56 ++++++++++++++++++++ initialize.php | 2 +- roles.php | 4 +- rtl.css | 4 ++ 6 files changed, 66 insertions(+), 102 deletions(-) delete mode 100644 WEB-INF/templates/roles.tpl create mode 100644 WEB-INF/templates/roles2.tpl diff --git a/WEB-INF/lib/ttTemplateHelper.class.php b/WEB-INF/lib/ttTemplateHelper.class.php index cedda1671..6e6ad0a02 100644 --- a/WEB-INF/lib/ttTemplateHelper.class.php +++ b/WEB-INF/lib/ttTemplateHelper.class.php @@ -1,31 +1,6 @@ quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; $status = (int) $fields['status']; - $projects = $fields['projects']; + $projects = isset($fields['projects']) ? $fields['projects'] : array(); $sql = "update tt_templates set name = ".$mdb2->quote($name). ", description = ".$mdb2->quote($description). diff --git a/WEB-INF/templates/roles.tpl b/WEB-INF/templates/roles.tpl deleted file mode 100644 index 227392489..000000000 --- a/WEB-INF/templates/roles.tpl +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - -
- - {if $inactive_roles} - - {/if} - - - - - - - - {if $active_roles} - {foreach $active_roles as $role} - - - - - - - - {/foreach} - {/if} -
{$i18n.form.roles.active_roles}
{$i18n.label.thing_name}{$i18n.form.roles.rank}{$i18n.label.description}
{$role.name|escape}{$role.rank}{$role.description|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- - {if $inactive_roles} - - - - - - - - - - {foreach $inactive_roles as $role} - - - - - - - - {/foreach} -
{$i18n.form.roles.inactive_roles}
{$i18n.label.thing_name}{$i18n.form.roles.rank}{$i18n.label.description}
{$role.name|escape}{$role.rank}{$role.description|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- {/if} -
diff --git a/WEB-INF/templates/roles2.tpl b/WEB-INF/templates/roles2.tpl new file mode 100644 index 000000000..60985c520 --- /dev/null +++ b/WEB-INF/templates/roles2.tpl @@ -0,0 +1,56 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + + + +{if $inactive_roles} +
{$i18n.form.roles.active_roles}
+{/if} + + + + + + + + + {if $active_roles} + {foreach $active_roles as $role} + + + + + + + + {/foreach} + {/if} +
{$i18n.label.thing_name}{$i18n.form.roles.rank}{$i18n.label.description}
{$role.name|escape}{$role.rank}{$role.description|escape}{$i18n.label.edit}{$i18n.label.delete}
+
+ +{if $inactive_roles} +
{$i18n.form.roles.inactive_roles}
+ + + + + + + + + {if $active_roles} + {foreach $inactive_roles as $role} + + + + + + + + {/foreach} + {/if} +
{$i18n.label.thing_name}{$i18n.form.roles.rank}{$i18n.label.description}
{$role.name|escape}{$role.rank}{$role.description|escape}{$i18n.label.edit}{$i18n.label.delete}
+
+{/if} diff --git a/initialize.php b/initialize.php index 773abee87..b31e3252c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5503"); +define("APP_VERSION", "1.19.28.5504"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/roles.php b/roles.php index 569f2649a..f2795fb0f 100644 --- a/roles.php +++ b/roles.php @@ -17,5 +17,5 @@ $smarty->assign('active_roles', ttTeamHelper::getActiveRolesForUser()); $smarty->assign('inactive_roles', ttTeamHelper::getInactiveRolesForUser()); $smarty->assign('title', $i18n->get('title.roles')); -$smarty->assign('content_page_name', 'roles.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'roles2.tpl'); +$smarty->display('index2.tpl'); diff --git a/rtl.css b/rtl.css index 310ab1e25..890cdd75c 100644 --- a/rtl.css +++ b/rtl.css @@ -32,6 +32,10 @@ html { text-align: right; } +.number-cell { + text-align: left; +} + .time-cell { text-align: left; } From 13264199ec99529322632aa9ccffaae71d3c1029 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 May 2021 18:23:53 +0000 Subject: [PATCH 1518/1848] Forgot to check in one file in previous commit. --- default.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/default.css b/default.css index c2c9e1d13..103468576 100644 --- a/default.css +++ b/default.css @@ -170,6 +170,11 @@ div.page-hint { text-align: right; } +/* number cell in tables */ +.number-cell { + text-align: right; +} + /* date cell in tables */ .date-cell { white-space: nowrap; From eae83c07267650a8956876373670558c31e3c99c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 May 2021 15:43:19 +0000 Subject: [PATCH 1519/1848] Made role_delete.php mobile friendly. --- WEB-INF/templates/role_delete.tpl | 20 -------------------- WEB-INF/templates/role_delete2.tpl | 7 +++++++ initialize.php | 2 +- role_delete.php | 4 ++-- 4 files changed, 10 insertions(+), 23 deletions(-) delete mode 100644 WEB-INF/templates/role_delete.tpl create mode 100644 WEB-INF/templates/role_delete2.tpl diff --git a/WEB-INF/templates/role_delete.tpl b/WEB-INF/templates/role_delete.tpl deleted file mode 100644 index 9c85d2208..000000000 --- a/WEB-INF/templates/role_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.roleDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$role_to_delete|escape}
 
{$forms.roleDeleteForm.btn_delete.control}  {$forms.roleDeleteForm.btn_cancel.control}
-
-{$forms.roleDeleteForm.close} diff --git a/WEB-INF/templates/role_delete2.tpl b/WEB-INF/templates/role_delete2.tpl new file mode 100644 index 000000000..56c5dfa07 --- /dev/null +++ b/WEB-INF/templates/role_delete2.tpl @@ -0,0 +1,7 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.roleDeleteForm.open} +
{$role_to_delete|escape}
+
{$forms.roleDeleteForm.btn_delete.control} {$forms.roleDeleteForm.btn_cancel.control}
+{$forms.roleDeleteForm.close} diff --git a/initialize.php b/initialize.php index b31e3252c..2ecaae624 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5504"); +define("APP_VERSION", "1.19.28.5505"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/role_delete.php b/role_delete.php index e2f0805eb..805c89dba 100644 --- a/role_delete.php +++ b/role_delete.php @@ -46,5 +46,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_role')); -$smarty->assign('content_page_name', 'role_delete.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'role_delete2.tpl'); +$smarty->display('index2.tpl'); From 564bd846e6fa89e13fc02a4f3da0788549e3d699 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 May 2021 16:00:02 +0000 Subject: [PATCH 1520/1848] Made role_add.php mobile friendly. --- WEB-INF/templates/role_add.tpl | 33 --------------------------------- WEB-INF/templates/role_add2.tpl | 31 +++++++++++++++++++++++++++++++ initialize.php | 2 +- role_add.php | 10 +++++----- 4 files changed, 37 insertions(+), 39 deletions(-) delete mode 100644 WEB-INF/templates/role_add.tpl create mode 100644 WEB-INF/templates/role_add2.tpl diff --git a/WEB-INF/templates/role_add.tpl b/WEB-INF/templates/role_add.tpl deleted file mode 100644 index 6a56fd253..000000000 --- a/WEB-INF/templates/role_add.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{$forms.roleForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.roleForm.name.control}
{$i18n.label.description}:{$forms.roleForm.description.control}
{$i18n.form.roles.rank}:{$forms.roleForm.rank.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
{$forms.roleForm.btn_submit.control}
 
-
-{$forms.roleForm.close} diff --git a/WEB-INF/templates/role_add2.tpl b/WEB-INF/templates/role_add2.tpl new file mode 100644 index 000000000..3fb24fee0 --- /dev/null +++ b/WEB-INF/templates/role_add2.tpl @@ -0,0 +1,31 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.roleForm.open} + + + + + + + + + + + + + + + + + + + + + +
{$forms.roleForm.name.control}
{$forms.roleForm.description.control}
{$forms.roleForm.rank.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.label.required_fields}
+
{$forms.roleForm.btn_submit.control}
+{$forms.roleForm.close} diff --git a/initialize.php b/initialize.php index 2ecaae624..513c45d50 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5505"); +define("APP_VERSION", "1.19.28.5506"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/role_add.php b/role_add.php index a52d1a38b..54fd9bdb5 100644 --- a/role_add.php +++ b/role_add.php @@ -19,12 +19,12 @@ } $form = new Form('roleForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); for ($i = 0; $i < $user->rank; $i++) { $rank_data[] = $i; } -$form->addInput(array('type'=>'combobox','name'=>'rank','data'=>$rank_data)); +$form->addInput(array('type'=>'combobox','class'=>'dropdown-field-short','name'=>'rank','data'=>$rank_data)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { @@ -55,5 +55,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.add_role')); -$smarty->assign('content_page_name', 'role_add.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'role_add2.tpl'); +$smarty->display('index2.tpl'); From 0337da14eedd7a3ef4cb23ede2fbd1e423a5e393 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 May 2021 16:22:01 +0000 Subject: [PATCH 1521/1848] Made role_edit.php mobile friendly. --- WEB-INF/templates/role_edit.tpl | 45 --------------------------- WEB-INF/templates/role_edit2.tpl | 53 ++++++++++++++++++++++++++++++++ initialize.php | 2 +- role_edit.php | 10 +++--- 4 files changed, 59 insertions(+), 51 deletions(-) delete mode 100644 WEB-INF/templates/role_edit.tpl create mode 100644 WEB-INF/templates/role_edit2.tpl diff --git a/WEB-INF/templates/role_edit.tpl b/WEB-INF/templates/role_edit.tpl deleted file mode 100644 index 3ad9e6cfe..000000000 --- a/WEB-INF/templates/role_edit.tpl +++ /dev/null @@ -1,45 +0,0 @@ -{$forms.roleForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.roleForm.name.control}
{$i18n.label.description}:{$forms.roleForm.description.control}
{$i18n.form.roles.rank}:{$forms.roleForm.rank.control} {$i18n.label.what_is_it}
{$i18n.label.status}:{$forms.roleForm.status.control}
{$i18n.label.required_fields}
{$forms.roleForm.btn_save.control}
 
{$i18n.form.roles.assigned}:{$forms.roleForm.assigned_rights.control}{$forms.roleForm.btn_delete.control}
{$i18n.form.roles.not_assigned}:{$forms.roleForm.available_rights.control}{$forms.roleForm.btn_add.control}
-
-{$forms.roleForm.close} diff --git a/WEB-INF/templates/role_edit2.tpl b/WEB-INF/templates/role_edit2.tpl new file mode 100644 index 000000000..c44d8826a --- /dev/null +++ b/WEB-INF/templates/role_edit2.tpl @@ -0,0 +1,53 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.roleForm.open} + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$forms.roleForm.name.control}
{$forms.roleForm.description.control}
{$forms.roleForm.rank.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.roleForm.status.control}
{$i18n.label.required_fields}
+
{$forms.roleForm.btn_save.control}
+ + + + + + + + + + + + + + + +
{$forms.roleForm.assigned_rights.control}{$forms.roleForm.btn_delete.control}
{$forms.roleForm.available_rights.control}{$forms.roleForm.btn_add.control}
+{$forms.roleForm.close} diff --git a/initialize.php b/initialize.php index 513c45d50..bf735839c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5506"); +define("APP_VERSION", "1.19.28.5507"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/role_edit.php b/role_edit.php index bd18fd9cc..8f13acc0b 100644 --- a/role_edit.php +++ b/role_edit.php @@ -36,12 +36,12 @@ $form = new Form('roleForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_role_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); for ($i = 0; $i < $user->rank; $i++) { $rank_data[] = $i; } -$form->addInput(array('type'=>'combobox','name'=>'rank','data'=>$rank_data,'value'=>$cl_rank)); +$form->addInput(array('type'=>'combobox','class'=>'dropdown-field-short','name'=>'rank','data'=>$rank_data,'value'=>$cl_rank)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); @@ -115,5 +115,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_role')); -$smarty->assign('content_page_name', 'role_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'role_edit2.tpl'); +$smarty->display('index2.tpl'); From f6947733c46efa27086710424b1bf03b6c9dd289 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 May 2021 16:24:44 +0000 Subject: [PATCH 1522/1848] Removed style elements from role_edit.php. --- initialize.php | 2 +- role_edit.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/initialize.php b/initialize.php index bf735839c..c8f485ef7 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5507"); +define("APP_VERSION", "1.19.28.5508"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/role_edit.php b/role_edit.php index 8f13acc0b..03e1d2473 100644 --- a/role_edit.php +++ b/role_edit.php @@ -47,9 +47,9 @@ $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); // Multiple select controls for assigned and available rights. -$form->addInput(array('type'=>'combobox','name'=>'assigned_rights','style'=>'width: 250px;','multiple'=>true,'data'=>$assigned_rights)); +$form->addInput(array('type'=>'combobox','name'=>'assigned_rights','multiple'=>true,'data'=>$assigned_rights)); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('button.delete'))); -$form->addInput(array('type'=>'combobox','name'=>'available_rights','style'=>'width: 250px;','multiple'=>true,'data'=>$available_rights)); +$form->addInput(array('type'=>'combobox','name'=>'available_rights','multiple'=>true,'data'=>$available_rights)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { From 5ec2c49b85d39d378aaee9fac6684312ac7c270b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 May 2021 15:00:23 +0000 Subject: [PATCH 1523/1848] Improved mobile layout for role_edit.php. --- WEB-INF/templates/role_edit2.tpl | 18 ++++++------------ default.css | 5 +++++ initialize.php | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/WEB-INF/templates/role_edit2.tpl b/WEB-INF/templates/role_edit2.tpl index c44d8826a..096716e29 100644 --- a/WEB-INF/templates/role_edit2.tpl +++ b/WEB-INF/templates/role_edit2.tpl @@ -35,19 +35,13 @@ License: See license.txt *}
{$forms.roleForm.btn_save.control}
- - - - - - + + + - - - - - - + + +
{$forms.roleForm.assigned_rights.control}{$forms.roleForm.btn_delete.control}
{$i18n.form.roles.assigned}:
{$forms.roleForm.assigned_rights.control}
{$forms.roleForm.btn_delete.control}
{$forms.roleForm.available_rights.control}{$forms.roleForm.btn_add.control}
{$i18n.form.roles.not_assigned}:
{$forms.roleForm.available_rights.control}
{$forms.roleForm.btn_add.control}
{$forms.roleForm.close} diff --git a/default.css b/default.css index 103468576..48a3fb58a 100644 --- a/default.css +++ b/default.css @@ -258,6 +258,11 @@ div.record-list { text-align: left; } +/* a table cell containing input control */ +.td-with-horizontally-centered-input { + text-align: middle; +} + /* a table cell containing a set ov vertically stacked checkboxes */ .td-with-checkboxes { text-align: left; diff --git a/initialize.php b/initialize.php index c8f485ef7..db097d442 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5508"); +define("APP_VERSION", "1.19.28.5509"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 93e6bd31d1c913049894257b2325cf5f161b5651 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 May 2021 21:07:39 +0000 Subject: [PATCH 1524/1848] Moved timer.php from legacy mobile directory to root. --- WEB-INF/templates/timer2.tpl | 119 ++++++++++++++ initialize.php | 2 +- timer.php | 309 +++++++++++++++++++++++++++++++++++ 3 files changed, 429 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/templates/timer2.tpl create mode 100644 timer.php diff --git a/WEB-INF/templates/timer2.tpl b/WEB-INF/templates/timer2.tpl new file mode 100644 index 000000000..a8f9b1c97 --- /dev/null +++ b/WEB-INF/templates/timer2.tpl @@ -0,0 +1,119 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{include file="time_script.tpl"} + +

00:00 + + + +{if $uncompleted} + +{/if} + +{$forms.timeRecordForm.open} + +{if $show_client} + + + + + + +{/if} +{if $show_billable} + + + + + +{/if} +{if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + + + + + + {/foreach} +{/if} +{if $show_project} + + + + + + +{/if} +{if $show_task} + + + + + + +{/if} + + +
{$forms.timeRecordForm.client.control}
 
{$forms.timeRecordForm.$control_name.control}
{$forms.timeRecordForm.project.control}
{$forms.timeRecordForm.task.control}
{$i18n.label.required_fields}
+

{$forms.timeRecordForm.btn_start.control} {$forms.timeRecordForm.btn_stop.control}
+{$forms.timeRecordForm.close} + +
+ + + + + +
{$i18n.label.week_total}: {$week_total}{$i18n.label.day_total}: {$day_total}
+
diff --git a/initialize.php b/initialize.php index db097d442..d658db002 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5509"); +define("APP_VERSION", "1.19.28.5510"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/timer.php b/timer.php new file mode 100644 index 000000000..59c06d89b --- /dev/null +++ b/timer.php @@ -0,0 +1,309 @@ +isPluginEnabled('cl'); +$showBillable = $user->isPluginEnabled('iv'); +$trackingMode = $user->getTrackingMode(); +$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; +$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $user->getConfigOption('task_required'); + +// Initialize and store date in session. +$cl_date = $request->getParameter('date', @$_SESSION['date']); +$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); +if($selected_date->isError()) + $selected_date = new DateAndTime(DB_DATEFORMAT); +if(!$cl_date) + $cl_date = $selected_date->toString(DB_DATEFORMAT); +$_SESSION['date'] = $cl_date; +// TODO: for time page we may limit the day to today only. + +// Use custom fields plugin if it is enabled. +if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + $smarty->assign('custom_fields', $custom_fields); +} + +// Initialize variables. +$cl_start = trim($request->getParameter('browser_time')); +$cl_finish = trim($request->getParameter('browser_time')); +$cl_billable = 1; +if ($user->isPluginEnabled('iv')) { + if ($request->isPost()) { + $cl_billable = $request->getParameter('billable'); + $_SESSION['billable'] = (int) $cl_billable; + } else + if (isset($_SESSION['billable'])) + $cl_billable = $_SESSION['billable']; +} +$cl_client = $request->getParameter('client', @$_SESSION['client']); +$_SESSION['client'] = $cl_client; +$cl_project = $request->getParameter('project', @$_SESSION['project']); +$_SESSION['project'] = $cl_project; +$cl_task = $request->getParameter('task', @$_SESSION['task']); +$_SESSION['task'] = $cl_task; + +// Handle time custom fields. +$timeCustomFields = array(); +if (isset($custom_fields) && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); + $_SESSION[$control_name] = $cl_control_name; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($cl_control_name)); + } +} + +// Obtain uncompleted record. Assumtion is that only 1 uncompleted record is allowed. +$uncompleted = ttTimeHelper::getUncompleted($user->getUser()); +$enable_controls = ($uncompleted == null); + +// Elements of timeRecordForm. +$form = new Form('timeRecordForm'); + +// Dropdown for clients in MODE_TIME. Use all active clients. +if (MODE_TIME == $trackingMode && $showClient) { + $active_clients = ttGroupHelper::getActiveClients(true); + $form->addInput(array('type'=>'combobox', + 'onchange'=>'fillProjectDropdown(this.value);', + 'name'=>'client', + 'style'=>'width: 250px;', + 'enable'=>$enable_controls, + 'value'=>$cl_client, + 'data'=>$active_clients, + 'datakeys'=>array('id', 'name'), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + // Note: in other modes the client list is filtered to relevant clients only. See below. +} + +// Billable checkbox. +if ($showBillable) + $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable,'enable'=>$enable_controls)); + +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text', + 'name'=>$field_name, + 'enable'=>$enable_controls, + 'value'=>$timeCustomFields[$timeField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], + 'enable'=>$enable_controls, + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } + } +} + +// If we show project dropdown, add controls for project and client. +if ($showProject) { + // Dropdown for projects assigned to user. + $project_list = $user->getAssignedProjects(); + $form->addInput(array('type'=>'combobox', + 'onchange'=>'fillTaskDropdown(this.value);', + 'name'=>'project', + 'enable'=>$enable_controls, + 'value'=>$cl_project, + 'data'=>$project_list, + 'datakeys'=>array('id','name'), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + + // Client dropdown. + if ($showClient) { + $active_clients = ttGroupHelper::getActiveClients(true); + // We need an array of assigned project ids to do some trimming. + foreach($project_list as $project) + $projects_assigned_to_user[] = $project['id']; + + // Build a client list out of active clients. Use only clients that are relevant to user. + // Also trim their associated project list to only assigned projects (to user). + foreach($active_clients as $client) { + $projects_assigned_to_client = explode(',', $client['projects']); + $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); + if ($intersection) { + $client['projects'] = implode(',', $intersection); + $client_list[] = $client; + } + } + $form->addInput(array('type'=>'combobox', + 'onchange'=>'fillProjectDropdown(this.value);', + 'name'=>'client', + 'enable'=>$enable_controls, + 'value'=>$cl_client, + 'data'=>$client_list, + 'datakeys'=>array('id', 'name'), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } +} + +// Task dropdown. +if ($showTask) { + $task_list = ttGroupHelper::getActiveTasks(); + $form->addInput(array('type'=>'combobox', + 'name'=>'task', + 'enable'=>$enable_controls, + 'value'=>$cl_task, + 'data'=>$task_list, + 'datakeys'=>array('id','name'), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); +} + +// A hidden control for today's date from user's browser. +$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on button click. + +// A hidden control for current time from user's browser. +$form->addInput(array('type'=>'hidden','name'=>'browser_time','value'=>'')); // User current time, which gets filled in on button click. + +// Start and stop buttons. +$enable_start = $uncompleted ? false : true; +if (!$uncompleted) + $form->addInput(array('type'=>'submit','name'=>'btn_start','onclick'=>'browser_time.value=get_time()','value'=>$i18n->get('label.start'),'enable'=>$enable_start)); +else + $form->addInput(array('type'=>'submit','name'=>'btn_stop','onclick'=>'browser_time.value=get_time()','value'=>$i18n->get('label.finish'),'enable'=>!$enable_start)); + +// Submit. +if ($request->isPost()) { + if ($request->getParameter('btn_start')) { + // Start button clicked. We need to create a new uncompleted record with only the start time. + $cl_finish = null; + + // Validate user input. + if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) + $err->add($i18n->get('error.client')); + // Validate input in time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($timeCustomFields as $timeField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); + } + } + if ($showProject) { + if (!$cl_project) $err->add($i18n->get('error.project')); + } + if ($showTask && $taskRequired) { + if (!$cl_task) $err->add($i18n->get('error.task')); + } + // Finished validating user input. + + // Prohibit creating entries in future. + if (!$user->isOptionEnabled('future_entries')) { + $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); + if ($selected_date->after($browser_today)) + $err->add($i18n->get('error.future_date')); + } + + // Prohibit creating time entries in locked interval. + if ($user->isDateLocked($selected_date)) + $err->add($i18n->get('error.range_locked')); + + // Prohibit creating another uncompleted record. + if ($err->no() && $uncompleted) { + $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); + } + + // Prohibit creating an overlapping record. + if ($err->no()) { + if (ttTimeHelper::overlaps($user->getUser(), $cl_date, $cl_start, $cl_finish)) + $err->add($i18n->get('error.overlap')); + } + + if ($err->no()) { + $id = ttTimeHelper::insert(array( + 'date' => $cl_date, + 'client' => $cl_client, + 'project' => $cl_project, + 'task' => $cl_task, + 'start' => $cl_start, + 'finish' => $cl_finish, + 'duration' => $cl_duration, + 'note' => $cl_note, + 'billable' => $cl_billable)); + + // Insert time custom fields if we have them. + $result = true; + if ($id && $custom_fields && $custom_fields->timeFields) { + $result = $custom_fields->insertTimeFields($id, $timeCustomFields); + } + + if ($id && $result) { + header('Location: timer.php'); + exit(); + } + $err->add($i18n->get('error.db')); + } + } + if ($request->getParameter('btn_stop')) { + // Stop button clicked. We need to finish an uncompleted record in progress. + $record = ttTimeHelper::getRecord($uncompleted['id']); + + // Can we complete this record? + if (ttTimeHelper::isValidInterval($record['start'], $cl_finish) // finish time is greater than start time + && !ttTimeHelper::overlaps($user->getUser(), $cl_date, $record['start'], $cl_finish)) { // no overlap + $res = ttTimeHelper::update(array( + 'id'=>$record['id'], + 'date'=>$cl_date, + 'client'=>$record['client_id'], + 'project'=>$record['project_id'], + 'task'=>$record['task_id'], + 'start'=>$record['start'], + 'finish'=>$cl_finish, + 'note'=>$record['comment'], + 'billable'=>$record['billable'])); + if ($res) { + header('Location: timer.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } else { + // Cannot complete, redirect for manual edit. + header('Location: time_edit.php?id='.$record['id']); + exit(); + } + } +} // isPost + +$week_total = ttTimeHelper::getTimeForWeek($cl_date); +$smarty->assign('week_total', $week_total); +$smarty->assign('uncompleted', $uncompleted); +$smarty->assign('show_client', $showClient); +$smarty->assign('show_billable', $showBillable); +$smarty->assign('show_project', $showProject); +$smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); +$smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); +$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); +$smarty->assign('client_list', $client_list); +$smarty->assign('project_list', $project_list); +$smarty->assign('task_list', $task_list); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="fillDropdowns()"'); +$smarty->assign('timestring', $selected_date->toString($user->date_format)); +$smarty->assign('title', $i18n->get('title.time')); +$smarty->assign('content_page_name', 'timer2.tpl'); +$smarty->display('index2.tpl'); From 8bb32dd4cdd3480a9dfc7f8f6f56fe66d4aa6a21 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 May 2021 21:12:24 +0000 Subject: [PATCH 1525/1848] Removed all remaining legacy mobile pages. --- WEB-INF/templates/mobile/header.tpl | 128 -------- WEB-INF/templates/mobile/index.tpl | 3 - WEB-INF/templates/mobile/login.db.tpl | 7 - WEB-INF/templates/mobile/login.ldap.tpl | 7 - WEB-INF/templates/mobile/login.tpl | 17 - WEB-INF/templates/mobile/time.tpl | 107 ------- WEB-INF/templates/mobile/timer.tpl | 119 ------- initialize.php | 2 +- mobile/index.php | 33 -- mobile/login.php | 76 ----- mobile/time.php | 393 ------------------------ mobile/timer.php | 309 ------------------- timer.php | 1 - 13 files changed, 1 insertion(+), 1201 deletions(-) delete mode 100644 WEB-INF/templates/mobile/header.tpl delete mode 100644 WEB-INF/templates/mobile/index.tpl delete mode 100644 WEB-INF/templates/mobile/login.db.tpl delete mode 100644 WEB-INF/templates/mobile/login.ldap.tpl delete mode 100644 WEB-INF/templates/mobile/login.tpl delete mode 100644 WEB-INF/templates/mobile/time.tpl delete mode 100644 WEB-INF/templates/mobile/timer.tpl delete mode 100644 mobile/index.php delete mode 100644 mobile/login.php delete mode 100644 mobile/time.php delete mode 100644 mobile/timer.php diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl deleted file mode 100644 index d4cf2c53b..000000000 --- a/WEB-INF/templates/mobile/header.tpl +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - -{if $i18n.language.rtl} - -{/if} -{if $user->getCustomCss()} - -{/if} - Time Tracker{if $title} - {$title}{/if} - - - - - - - -{assign var="tab_width" value="300"} - - - -
- - - - -{if $user->custom_logo} - - -
-{else} - -{/if} - - - - -
- - - -{if $user->custom_logo} - -{else} - -{/if} - - -
-
- - -{if $authenticated} - {if $user->can('administer_site')} - - - - - - - - - {else} - - - - - - - - - {/if} -{/if} - - -{if $err->yes()} - - - - -
- {foreach $err->getErrors() as $error} - {$error.message}
{* No need to escape as they are not coming from user and may contain a link. *} - {/foreach} -
-{/if} - - - -{if $msg->yes()} - - - - -
- {foreach $msg->getErrors() as $message} - {$message.message}
{* No need to escape. *} - {/foreach} -
-{/if} - diff --git a/WEB-INF/templates/mobile/index.tpl b/WEB-INF/templates/mobile/index.tpl deleted file mode 100644 index babdac50e..000000000 --- a/WEB-INF/templates/mobile/index.tpl +++ /dev/null @@ -1,3 +0,0 @@ -{include file="mobile/header.tpl"} - -{if $content_page_name}{include file="$content_page_name"}{/if} diff --git a/WEB-INF/templates/mobile/login.db.tpl b/WEB-INF/templates/mobile/login.db.tpl deleted file mode 100644 index 2968b1dab..000000000 --- a/WEB-INF/templates/mobile/login.db.tpl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - -
{$i18n.label.login}:
{$forms.loginForm.login.control}
{$i18n.label.password}:
{$forms.loginForm.password.control}
{$forms.loginForm.btn_login.control}
diff --git a/WEB-INF/templates/mobile/login.ldap.tpl b/WEB-INF/templates/mobile/login.ldap.tpl deleted file mode 100644 index 2968b1dab..000000000 --- a/WEB-INF/templates/mobile/login.ldap.tpl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - -
{$i18n.label.login}:
{$forms.loginForm.login.control}
{$i18n.label.password}:
{$forms.loginForm.password.control}
{$forms.loginForm.btn_login.control}
diff --git a/WEB-INF/templates/mobile/login.tpl b/WEB-INF/templates/mobile/login.tpl deleted file mode 100644 index 1a2e888e4..000000000 --- a/WEB-INF/templates/mobile/login.tpl +++ /dev/null @@ -1,17 +0,0 @@ - - - - - -
- {$forms.loginForm.open} - {include file="mobile/login.`$smarty.const.AUTH_MODULE`.tpl"} - {$forms.loginForm.close} -
diff --git a/WEB-INF/templates/mobile/time.tpl b/WEB-INF/templates/mobile/time.tpl deleted file mode 100644 index 6b8bca0c6..000000000 --- a/WEB-INF/templates/mobile/time.tpl +++ /dev/null @@ -1,107 +0,0 @@ -{include file="time_script.tpl"} - - - - - - - - - -
<<{$timestring}>>
- - - - - -
-{if $time_records} - - {foreach $time_records as $record} - - {if $show_project} - - {/if} - - - - - {/foreach} -
{$record.project|escape}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{$record.duration}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.edit}{/if}{if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.delete}{/if}
- - - - - - - - - -
{$i18n.label.day_total}:{$day_total}
{$i18n.label.week_total}:{$week_total}
-{/if} -
- -{$forms.timeRecordForm.open} - - - - -
- - - - - -
- -{if $user_dropdown} - - -{/if} -{if $show_client} - - -{/if} -{if $show_billable} - -{/if} -{if $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - - {/foreach} -{/if} -{if $show_project} - - -{/if} -{if $show_task} - - -{/if} -{if $show_start} - - - - -{/if} -{if $show_duration} - - -{/if} -{if $template_dropdown} - - -{/if} - - -
{$i18n.label.user}:
{$forms.timeRecordForm.user.control}
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project}:
{$forms.timeRecordForm.project.control}
{$i18n.label.task}{if $task_required} (*){/if}:
{$forms.timeRecordForm.task.control}
{$i18n.label.start}:
{$forms.timeRecordForm.start.control} 
{$i18n.label.finish}:
{$forms.timeRecordForm.finish.control} 
{$i18n.label.duration}:
{$forms.timeRecordForm.duration.control}
{$i18n.label.template}:
{$forms.timeRecordForm.template.control}
{$i18n.label.note}:
{$forms.timeRecordForm.note.control}
-
{$forms.timeRecordForm.btn_submit.control}
-
-{$forms.timeRecordForm.close} diff --git a/WEB-INF/templates/mobile/timer.tpl b/WEB-INF/templates/mobile/timer.tpl deleted file mode 100644 index 1fee04af3..000000000 --- a/WEB-INF/templates/mobile/timer.tpl +++ /dev/null @@ -1,119 +0,0 @@ -{include file="time_script.tpl"} - -

00:00 - - - -{if $uncompleted} - -{/if} - -{$forms.timeRecordForm.open} - - - - -
- - - - - - - -
- -{if $show_client} - - -{/if} -{if $show_billable} - -{/if} -{if $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - - {/foreach} -{/if} -{if $show_project} - - -{/if} -{if $show_task} - - -{/if} -
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project}:
{$forms.timeRecordForm.project.control}
{$i18n.label.task}{if $task_required} (*){/if}:
{$forms.timeRecordForm.task.control}
-
{$forms.timeRecordForm.btn_start.control} {$forms.timeRecordForm.btn_stop.control}
-
-{$forms.timeRecordForm.close} - - - - - -
- {if $time_records} - - - - - - - - - -
{$i18n.label.day_total}:{$day_total}
{$i18n.label.week_total}:{$week_total}
- {/if} -
diff --git a/initialize.php b/initialize.php index d658db002..745d1e4ae 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5510"); +define("APP_VERSION", "1.19.28.5511"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/index.php b/mobile/index.php deleted file mode 100644 index 4da5fab10..000000000 --- a/mobile/index.php +++ /dev/null @@ -1,33 +0,0 @@ -isAuthenticated()) { - if ($user->can('administer_site')) { - header('Location: ../admin_groups.php'); - exit(); - } elseif ($user->isClient()) { - header('Location: ../reports.php'); - exit(); - } -} -// Redirect to time.php or mobile/time.php for other roles. -?> - - - - -

Your browser does not support JavaScript. This application will not work without it.

- - diff --git a/mobile/login.php b/mobile/login.php deleted file mode 100644 index 1375b21ae..000000000 --- a/mobile/login.php +++ /dev/null @@ -1,76 +0,0 @@ -isPost()) { - $cl_login = $request->getParameter('login'); -} else { - $cl_login = @$_COOKIE[LOGIN_COOKIE_NAME]; -} -$cl_password = $request->getParameter('password'); - -$form = new Form('loginForm'); -$form->addInput(array('type'=>'text','size'=>'25','maxlength'=>'100','name'=>'login','style'=>'width: 220px;','value'=>$cl_login)); -$form->addInput(array('type'=>'password','size'=>'25','maxlength'=>'50','name'=>'password','style'=>'width: 220px;','value'=>$cl_password)); -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_login click. -$form->addInput(array('type'=>'submit','name'=>'btn_login','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.login'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); - if (!ttValidString($cl_password)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); - - if ($err->no()) { - - // Use the "limit" plugin if we have one. Ignore include errors. - // The "limit" plugin is not required for normal operation of Time Tracker. - @include('../plugins/limit/access_check.php'); - - if ($auth->doLogin($cl_login, $cl_password)) { - - // Set current user date (as determined by user browser) into session. - $current_user_date = $request->getParameter('browser_today', null); - if ($current_user_date) - $_SESSION['date'] = $current_user_date; - - // Remember user login in a cookie. - setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); - - $user = new ttUser(null, $auth->getUserId()); - // Redirect, depending on user role. - if ($user->can('administer_site')) { - header('Location: ../admin_groups.php'); - } elseif ($user->isClient()) { - header('Location: ../reports.php'); - } else { - header('Location: time.php'); - } - exit(); - } else - $err->add($i18n->get('error.auth')); - } -} // isPost - -if(!isTrue('MULTIORG_MODE') && !ttOrgHelper::getOrgs()) - $err->add($i18n->get('error.no_groups')); - -// Determine whether to show login hint. It is currently used only for Windows LDAP authentication. -$show_hint = ('ad' == $GLOBALS['AUTH_MODULE_PARAMS']['type']); - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_hint', $show_hint); -$smarty->assign('onload', 'onLoad="document.loginForm.'.(!$cl_login?'login':'password').'.focus()"'); -$smarty->assign('title', $i18n->get('title.login')); -$smarty->assign('content_page_name', 'mobile/login.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/time.php b/mobile/time.php deleted file mode 100644 index 387a56a89..000000000 --- a/mobile/time.php +++ /dev/null @@ -1,393 +0,0 @@ -behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. - exit(); -} -if ($request->isPost()) { - $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { - header('Location: access_denied.php'); // User changed, but no right or wrong user id. - exit(); - } -} -// End of access checks. - -// Determine user for whom we display this page. -if ($request->isPost() && $userChanged) { - $user_id = (int)$request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -$group_id = $user->getGroup(); -$config = new ttConfigHelper($user->getConfig()); - -$showClient = $user->isPluginEnabled('cl'); -$showBillable = $user->isPluginEnabled('iv'); -$trackingMode = $user->getTrackingMode(); -$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; -$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; -if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); -$recordType = $user->getRecordType(); -$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; -$showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; - -// Determine previous and next dates for simple navigation. -$prev_date = date('Y-m-d', strtotime('-1 day', strtotime($cl_date))); -$next_date = date('Y-m-d', strtotime('+1 day', strtotime($cl_date))); - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('../plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -// Initialize variables. -$cl_start = trim($request->getParameter('start')); -$cl_finish = trim($request->getParameter('finish')); -$cl_duration = trim($request->getParameter('duration')); -$cl_note = trim($request->getParameter('note')); -$cl_billable = 1; -if ($showBillable) { - if ($request->isPost()) { - $cl_billable = $request->getParameter('billable'); - $_SESSION['billable'] = (int) $cl_billable; - } else - if (isset($_SESSION['billable'])) - $cl_billable = $_SESSION['billable']; -} -$cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); -$_SESSION['client'] = $cl_client; -$cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); -$_SESSION['project'] = $cl_project; -$cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); -$_SESSION['task'] = $cl_task; - -// Handle time custom fields. -$timeCustomFields = array(); -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); - $_SESSION[$control_name] = $cl_control_name; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($cl_control_name)); - } -} - -// Elements of timeRecordForm. -$form = new Form('timeRecordForm'); - -// Dropdown for user and a hidden control to indicate user change. -if ($user->can('track_time')) { - $rank = $user->getMaxRankForGroup($group_id); - if ($user->can('track_own_time')) - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); - if (count($user_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'document.timeRecordForm.user_changed.value=1;document.timeRecordForm.submit();', - 'name'=>'user', - 'style'=>'width: 250px;', - 'value'=>$user_id, - 'data'=>$user_list, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $smarty->assign('user_dropdown', 1); - } -} - -// Dropdown for clients in MODE_TIME. Use all active clients. -// Note: for other tracking modes the control is added further below. -if (MODE_TIME == $trackingMode && $showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -// Billable checkbox. -if ($showBillable) - $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); - -// If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($timeField['id']), - 'value'=>$timeCustomFields[$timeField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -// If we show project dropdown, add controls for project and client. -if ($showProject) { - // Dropdown for projects assigned to user. - $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); - $project_list = $user->getAssignedProjects($options); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);prepopulateNote();', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Client dropdown. - if ($showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - if (is_array($projects_assigned_to_client) && is_array($projects_assigned_to_user)) - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} - -// Task dropdown. -if ($showTask) { - $task_list = ttGroupHelper::getActiveTasks(); - $form->addInput(array('type'=>'combobox', - 'name'=>'task', - 'style'=>'width: 250px;', - 'value'=>$cl_task, - 'data'=>$task_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); -} - -// Start and finish controls. -if ($showStart) { - $form->addInput(array('type'=>'text','name'=>'start','value'=>$cl_start,'onchange'=>"formDisable('start');")); - $form->addInput(array('type'=>'text','name'=>'finish','value'=>$cl_finish,'onchange'=>"formDisable('finish');")); - if ($user->punch_mode && !$user->canOverridePunchMode()) { - // Make the start and finish fields read-only. - $form->getElement('start')->setEnabled(false); - $form->getElement('finish')->setEnabled(false); - } -} - -// Duration control. -if ($showDuration) - $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); - -// If we have templates, add a dropdown to select one. -if ($user->isPluginEnabled('tp')){ - $template_list = ttGroupHelper::getActiveTemplates(); - if (count($template_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillNote(this.value);', - 'name'=>'template', - 'style'=>'width: 250px;', - 'data'=>$template_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $smarty->assign('template_dropdown', 1); - $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); - $smarty->assign('prepopulate_note', $config->getDefinedValue('prepopulate_note')); - $smarty->assign('template_list', $template_list); - } -} - -// Note control. -$form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height: 60px;','value'=>$cl_note)); - -// A hidden control for today's date from user's browser. -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. - -// Submit button. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - // Submit button clicked. - // Validate user input. - if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - // Validate input in time custom fields. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($timeCustomFields as $timeField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); - } - } - if ($showProject) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } - if ($showTask && $taskRequired) { - if (!$cl_task) $err->add($i18n->get('error.task')); - } - if (strlen($cl_duration) == 0) { - if ($cl_start || $cl_finish) { - if (!ttTimeHelper::isValidTime($cl_start)) - $err->add($i18n->get('error.field'), $i18n->get('label.start')); - if ($cl_finish) { - if (!ttTimeHelper::isValidTime($cl_finish)) - $err->add($i18n->get('error.field'), $i18n->get('label.finish')); - if (!ttTimeHelper::isValidInterval($cl_start, $cl_finish)) - $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); - } - } else { - if ($showStart) { - $err->add($i18n->get('error.empty'), $i18n->get('label.start')); - $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); - } - if ($showDuration) - $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); - } - } else { - if (false === ttTimeHelper::postedDurationToMinutes($cl_duration)) - $err->add($i18n->get('error.field'), $i18n->get('label.duration')); - } - if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); - if ($user->isPluginEnabled('tp') && !ttValidTemplateText($cl_note)) { - $err->add($i18n->get('error.field'), $i18n->get('label.note')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating user input. - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - - // Prohibit creating entries in locked range. - if ($user->isDateLocked($selected_date)) - $err->add($i18n->get('error.range_locked')); - - // Prohibit creating another uncompleted record. - if ($err->no()) { - if (($not_completed_rec = ttTimeHelper::getUncompleted($user_id)) && (($cl_finish == '') && ($cl_duration == ''))) - $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); - } - - // Prohibit creating an overlapping record. - if ($err->no()) { - if (ttTimeHelper::overlaps($user_id, $cl_date, $cl_start, $cl_finish)) - $err->add($i18n->get('error.overlap')); - } - - if ($err->no()) { - $id = ttTimeHelper::insert(array( - 'date' => $cl_date, - 'client' => $cl_client, - 'project' => $cl_project, - 'task' => $cl_task, - 'start' => $cl_start, - 'finish' => $cl_finish, - 'duration' => $cl_duration, - 'note' => $cl_note, - 'billable' => $cl_billable)); - - // Insert time custom fields if we have them. - $result = true; - if ($id && $custom_fields && $custom_fields->timeFields) { - $result = $custom_fields->insertTimeFields($id, $timeCustomFields); - } - - if ($id && $result) { - header('Location: time.php'); - exit(); - } - $err->add($i18n->get('error.db')); - } - } -} // isPost - -$smarty->assign('next_date', $next_date); -$smarty->assign('prev_date', $prev_date); -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); -$smarty->assign('week_total', ttTimeHelper::getTimeForWeek($selected_date)); -$smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); -$smarty->assign('show_client', $showClient); -$smarty->assign('show_billable', $showBillable); -$smarty->assign('show_project', $showProject); -$smarty->assign('show_task', $showTask); -$smarty->assign('task_required', $taskRequired); -$smarty->assign('show_start', $showStart); -$smarty->assign('show_duration', $showDuration); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="fillDropdowns();prepopulateNote();"'); -$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); -$smarty->assign('title', $i18n->get('title.time')); -$smarty->assign('content_page_name', 'mobile/time.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/timer.php b/mobile/timer.php deleted file mode 100644 index 1d870b1ca..000000000 --- a/mobile/timer.php +++ /dev/null @@ -1,309 +0,0 @@ -isPluginEnabled('cl'); -$showBillable = $user->isPluginEnabled('iv'); -$trackingMode = $user->getTrackingMode(); -$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; -$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; -if ($showTask) $taskRequired = $user->getConfigOption('task_required'); - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; -// TODO: for time page we may limit the day to today only. - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('../plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -// Initialize variables. -$cl_start = trim($request->getParameter('browser_time')); -$cl_finish = trim($request->getParameter('browser_time')); -$cl_billable = 1; -if ($user->isPluginEnabled('iv')) { - if ($request->isPost()) { - $cl_billable = $request->getParameter('billable'); - $_SESSION['billable'] = (int) $cl_billable; - } else - if (isset($_SESSION['billable'])) - $cl_billable = $_SESSION['billable']; -} -$cl_client = $request->getParameter('client', @$_SESSION['client']); -$_SESSION['client'] = $cl_client; -$cl_project = $request->getParameter('project', @$_SESSION['project']); -$_SESSION['project'] = $cl_project; -$cl_task = $request->getParameter('task', @$_SESSION['task']); -$_SESSION['task'] = $cl_task; - -$timeCustomFields = array(); -// If we have time custom fields - collect input. -if ($request->isPost()) { - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($request->getParameter($control_name))); - } - } -} - -// Obtain uncompleted record. Assumtion is that only 1 uncompleted record is allowed. -$uncompleted = ttTimeHelper::getUncompleted($user->getUser()); -$enable_controls = ($uncompleted == null); - -// Elements of timeRecordForm. -$form = new Form('timeRecordForm'); - -// Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $trackingMode && $showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'enable'=>$enable_controls, - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -// Billable checkbox. -if ($showBillable) - $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable,'enable'=>$enable_controls)); - -// If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($timeField['id']), - 'value'=>$timeCustomFields[$timeField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -// If we show project dropdown, add controls for project and client. -if ($showProject) { - // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);', - 'name'=>'project', - 'style'=>'width: 250px;', - 'enable'=>$enable_controls, - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Client dropdown. - if ($showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'enable'=>$enable_controls, - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} - -// Task dropdown. -if ($showTask) { - $task_list = ttGroupHelper::getActiveTasks(); - $form->addInput(array('type'=>'combobox', - 'name'=>'task', - 'style'=>'width: 250px;', - 'enable'=>$enable_controls, - 'value'=>$cl_task, - 'data'=>$task_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); -} - -// A hidden control for today's date from user's browser. -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on button click. - -// A hidden control for current time from user's browser. -$form->addInput(array('type'=>'hidden','name'=>'browser_time','value'=>'')); // User current time, which gets filled in on button click. - -// Start and stop buttons. -$enable_start = $uncompleted ? false : true; -if (!$uncompleted) - $form->addInput(array('type'=>'submit','name'=>'btn_start','onclick'=>'browser_time.value=get_time()','value'=>$i18n->get('label.start'),'enable'=>$enable_start)); -else - $form->addInput(array('type'=>'submit','name'=>'btn_stop','onclick'=>'browser_time.value=get_time()','value'=>$i18n->get('label.finish'),'enable'=>!$enable_start)); - -// Submit. -if ($request->isPost()) { - if ($request->getParameter('btn_start')) { - // Start button clicked. We need to create a new uncompleted record with only the start time. - $cl_finish = null; - - // Validate user input. - if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - // Validate input in time custom fields. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($timeCustomFields as $timeField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); - } - } - if ($showProject) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } - if ($showTask && $taskRequired) { - if (!$cl_task) $err->add($i18n->get('error.task')); - } - // Finished validating user input. - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - - // Prohibit creating time entries in locked interval. - if ($user->isDateLocked($selected_date)) - $err->add($i18n->get('error.range_locked')); - - // Prohibit creating another uncompleted record. - if ($err->no() && $uncompleted) { - $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); - } - - // Prohibit creating an overlapping record. - if ($err->no()) { - if (ttTimeHelper::overlaps($user->getUser(), $cl_date, $cl_start, $cl_finish)) - $err->add($i18n->get('error.overlap')); - } - - if ($err->no()) { - $id = ttTimeHelper::insert(array( - 'date' => $cl_date, - 'client' => $cl_client, - 'project' => $cl_project, - 'task' => $cl_task, - 'start' => $cl_start, - 'finish' => $cl_finish, - 'duration' => $cl_duration, - 'note' => $cl_note, - 'billable' => $cl_billable)); - - // Insert time custom fields if we have them. - $result = true; - if ($id && $custom_fields && $custom_fields->timeFields) { - $result = $custom_fields->insertTimeFields($id, $timeCustomFields); - } - - if ($id && $result) { - header('Location: timer.php'); - exit(); - } - $err->add($i18n->get('error.db')); - } - } - if ($request->getParameter('btn_stop')) { - // Stop button clicked. We need to finish an uncompleted record in progress. - $record = ttTimeHelper::getRecord($uncompleted['id']); - - // Can we complete this record? - if (ttTimeHelper::isValidInterval($record['start'], $cl_finish) // finish time is greater than start time - && !ttTimeHelper::overlaps($user->getUser(), $cl_date, $record['start'], $cl_finish)) { // no overlap - $res = ttTimeHelper::update(array( - 'id'=>$record['id'], - 'date'=>$cl_date, - 'client'=>$record['client_id'], - 'project'=>$record['project_id'], - 'task'=>$record['task_id'], - 'start'=>$record['start'], - 'finish'=>$cl_finish, - 'note'=>$record['comment'], - 'billable'=>$record['billable'])); - if ($res) { - header('Location: timer.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else { - // Cannot complete, redirect for manual edit. - header('Location: time_edit.php?id='.$record['id']); - exit(); - } - } -} // isPost - -$week_total = ttTimeHelper::getTimeForWeek($cl_date); -$smarty->assign('week_total', $week_total); -$smarty->assign('uncompleted', $uncompleted); -$smarty->assign('show_client', $showClient); -$smarty->assign('show_billable', $showBillable); -$smarty->assign('show_project', $showProject); -$smarty->assign('show_task', $showTask); -$smarty->assign('task_required', $taskRequired); -$smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="fillDropdowns()"'); -$smarty->assign('timestring', $selected_date->toString($user->date_format)); -$smarty->assign('title', $i18n->get('title.time')); -$smarty->assign('content_page_name', 'mobile/timer.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/timer.php b/timer.php index 59c06d89b..e77317d9a 100644 --- a/timer.php +++ b/timer.php @@ -89,7 +89,6 @@ $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', - 'style'=>'width: 250px;', 'enable'=>$enable_controls, 'value'=>$cl_client, 'data'=>$active_clients, From 1659eda0051747f5b714e5d693cd44d89a9c4a08 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 May 2021 14:20:40 +0000 Subject: [PATCH 1526/1848] Fixed population of time dropdown on timer.php. --- WEB-INF/lib/form/Combobox.class.php | 30 +++-------------------- WEB-INF/lib/form/Form.class.php | 28 ++------------------- WEB-INF/lib/form/FormElement.class.php | 34 ++++---------------------- initialize.php | 2 +- timer.php | 15 +++++++----- 5 files changed, 20 insertions(+), 89 deletions(-) diff --git a/WEB-INF/lib/form/Combobox.class.php b/WEB-INF/lib/form/Combobox.class.php index a0ae0e5a0..d494d0f6d 100644 --- a/WEB-INF/lib/form/Combobox.class.php +++ b/WEB-INF/lib/form/Combobox.class.php @@ -1,30 +1,6 @@ isEnabled()) $html .= " disabled"; - + $html .= ">\n"; if (is_array($this->mOptionsEmpty) && (count($this->mOptionsEmpty) > 0)) foreach ($this->mOptionsEmpty as $key=>$value) { diff --git a/WEB-INF/lib/form/Form.class.php b/WEB-INF/lib/form/Form.class.php index e991f725e..27a36e9ba 100644 --- a/WEB-INF/lib/form/Form.class.php +++ b/WEB-INF/lib/form/Form.class.php @@ -1,30 +1,6 @@ style; } function setEnabled($flag) { $this->enabled = $flag; } function isEnabled() { return $this->enabled; } - + function setOnChange($str) { $this->on_change = $str; } function setOnClick($str) { $this->on_click = $str; } function setPlaceholder($str) { $this->placeholder = $str; } diff --git a/initialize.php b/initialize.php index 745d1e4ae..bc2742a8a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5511"); +define("APP_VERSION", "1.19.28.5512"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/timer.php b/timer.php index e77317d9a..67388ce6a 100644 --- a/timer.php +++ b/timer.php @@ -60,12 +60,18 @@ $cl_task = $request->getParameter('task', @$_SESSION['task']); $_SESSION['task'] = $cl_task; +// Obtain uncompleted record. Assumption is that only 1 uncompleted record is allowed. +$uncompleted = ttTimeHelper::getUncompleted($user->getUser()); +$enable_controls = ($uncompleted == null); + // Handle time custom fields. $timeCustomFields = array(); if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $control_name = 'time_field_'.$timeField['id']; - $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); + // Note: disabled controls are not posted. Therefore, && $enable_controls condition below. + // This allows us to get values from session when controls are disabled and reset to null when not. + $cl_control_name = $request->getParameter($control_name, ($request->isPost() && $enable_controls ? null : @$_SESSION[$control_name])); $_SESSION[$control_name] = $cl_control_name; $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], 'control_name' => $control_name, @@ -76,10 +82,6 @@ } } -// Obtain uncompleted record. Assumtion is that only 1 uncompleted record is allowed. -$uncompleted = ttTimeHelper::getUncompleted($user->getUser()); -$enable_controls = ($uncompleted == null); - // Elements of timeRecordForm. $form = new Form('timeRecordForm'); @@ -98,8 +100,9 @@ } // Billable checkbox. -if ($showBillable) +if ($showBillable) { $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable,'enable'=>$enable_controls)); +} // If we have time custom fields - add controls for them. if ($custom_fields && $custom_fields->timeFields) { From b17d96f1d73429810d9980d0d3c82646bba635b5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 May 2021 14:40:14 +0000 Subject: [PATCH 1527/1848] Fixed some issues with control population on timer.php. --- initialize.php | 2 +- timer.php | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/initialize.php b/initialize.php index bc2742a8a..4e19892cb 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5512"); +define("APP_VERSION", "1.19.28.5513"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/timer.php b/timer.php index 67388ce6a..a2afacf9e 100644 --- a/timer.php +++ b/timer.php @@ -41,6 +41,10 @@ $smarty->assign('custom_fields', $custom_fields); } +// Obtain uncompleted record. Assumption is that only 1 uncompleted record is allowed. +$uncompleted = ttTimeHelper::getUncompleted($user->getUser()); +$enable_controls = ($uncompleted == null); + // Initialize variables. $cl_start = trim($request->getParameter('browser_time')); $cl_finish = trim($request->getParameter('browser_time')); @@ -53,16 +57,15 @@ if (isset($_SESSION['billable'])) $cl_billable = $_SESSION['billable']; } -$cl_client = $request->getParameter('client', @$_SESSION['client']); +// Note: disabled controls are not posted. Therefore, && $enable_controls condition below. +// This allows us to get values from session when controls are disabled and reset to null when not. +$cl_client = $request->getParameter('client', ($request->isPost() && $enable_controls ? null : @$_SESSION['client'])); $_SESSION['client'] = $cl_client; -$cl_project = $request->getParameter('project', @$_SESSION['project']); +$cl_project = $request->getParameter('project', ($request->isPost() && $enable_controls ? null : @$_SESSION['project'])); $_SESSION['project'] = $cl_project; -$cl_task = $request->getParameter('task', @$_SESSION['task']); +$cl_task = $request->getParameter('task', ($request->isPost() && $enable_controls ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; -// Obtain uncompleted record. Assumption is that only 1 uncompleted record is allowed. -$uncompleted = ttTimeHelper::getUncompleted($user->getUser()); -$enable_controls = ($uncompleted == null); // Handle time custom fields. $timeCustomFields = array(); From 78ad6891ac938c88ffd2b384bf59ecdc66e1aa89 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 May 2021 14:59:58 +0000 Subject: [PATCH 1528/1848] Fixed population of the billable checkbox on timer.php. --- initialize.php | 2 +- timer.php | 15 ++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/initialize.php b/initialize.php index 4e19892cb..1b85357a3 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5513"); +define("APP_VERSION", "1.19.28.5514"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/timer.php b/timer.php index a2afacf9e..d343f9294 100644 --- a/timer.php +++ b/timer.php @@ -48,17 +48,13 @@ // Initialize variables. $cl_start = trim($request->getParameter('browser_time')); $cl_finish = trim($request->getParameter('browser_time')); +// Disabled controls are not posted. Therefore, && $enable_controls condition in several places below. +// This allows us to get values from session when controls are disabled and reset to null when not. $cl_billable = 1; if ($user->isPluginEnabled('iv')) { - if ($request->isPost()) { - $cl_billable = $request->getParameter('billable'); - $_SESSION['billable'] = (int) $cl_billable; - } else - if (isset($_SESSION['billable'])) - $cl_billable = $_SESSION['billable']; + $cl_billable = $request->getParameter('billable', ($request->isPost() && $enable_controls ? null : @$_SESSION['billable'])); + $_SESSION['billable'] = $cl_billable; } -// Note: disabled controls are not posted. Therefore, && $enable_controls condition below. -// This allows us to get values from session when controls are disabled and reset to null when not. $cl_client = $request->getParameter('client', ($request->isPost() && $enable_controls ? null : @$_SESSION['client'])); $_SESSION['client'] = $cl_client; $cl_project = $request->getParameter('project', ($request->isPost() && $enable_controls ? null : @$_SESSION['project'])); @@ -66,14 +62,11 @@ $cl_task = $request->getParameter('task', ($request->isPost() && $enable_controls ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; - // Handle time custom fields. $timeCustomFields = array(); if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $control_name = 'time_field_'.$timeField['id']; - // Note: disabled controls are not posted. Therefore, && $enable_controls condition below. - // This allows us to get values from session when controls are disabled and reset to null when not. $cl_control_name = $request->getParameter($control_name, ($request->isPost() && $enable_controls ? null : @$_SESSION[$control_name])); $_SESSION[$control_name] = $cl_control_name; $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], From cd6a9f207afd99cf811a2e3de159496f22bc460f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 May 2021 15:48:10 +0000 Subject: [PATCH 1529/1848] Addressed several php8 warnings. --- WEB-INF/lib/ttTimeHelper.class.php | 4 ++-- WEB-INF/templates/timer2.tpl | 3 ++- initialize.php | 2 +- timer.php | 12 ++++++++---- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index bd2fb9898..58f2f4222 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -416,7 +416,7 @@ static function insert($fields) $date = $fields['date']; $start = $fields['start']; $finish = $fields['finish']; - $duration = $fields['duration']; + $duration = isset($fields['duration']) ? $fields['duration'] : null; if ($duration) { $minutes = ttTimeHelper::postedDurationToMinutes($duration); $duration = ttTimeHelper::minutesToDuration($minutes); @@ -479,7 +479,7 @@ static function update($fields) $task = $fields['task']; $start = $fields['start']; $finish = $fields['finish']; - $duration = $fields['duration']; + $duration = isset($fields['duration']) ? $fields['duration'] : null; if ($duration) { $minutes = ttTimeHelper::postedDurationToMinutes($duration); $duration = ttTimeHelper::minutesToDuration($minutes); diff --git a/WEB-INF/templates/timer2.tpl b/WEB-INF/templates/timer2.tpl index a8f9b1c97..b26e07c1d 100644 --- a/WEB-INF/templates/timer2.tpl +++ b/WEB-INF/templates/timer2.tpl @@ -106,7 +106,8 @@ startTimer();
{$i18n.label.required_fields}
-
{$forms.timeRecordForm.btn_start.control} {$forms.timeRecordForm.btn_stop.control}
+{if isset($forms.timeRecordForm.btn_start.control)}
{$forms.timeRecordForm.btn_start.control}
{/if} +{if isset($forms.timeRecordForm.btn_stop.control)}
{$forms.timeRecordForm.btn_stop.control}
{/if} {$forms.timeRecordForm.close}
diff --git a/initialize.php b/initialize.php index 1b85357a3..177770fdf 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5514"); +define("APP_VERSION", "1.19.28.5515"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/timer.php b/timer.php index d343f9294..aa51a4dc4 100644 --- a/timer.php +++ b/timer.php @@ -22,6 +22,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +$taskRequired = false; if ($showTask) $taskRequired = $user->getConfigOption('task_required'); // Initialize and store date in session. @@ -32,7 +33,7 @@ if(!$cl_date) $cl_date = $selected_date->toString(DB_DATEFORMAT); $_SESSION['date'] = $cl_date; -// TODO: for time page we may limit the day to today only. +// TODO: for timer page we may limit the day to today only. // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { @@ -48,6 +49,7 @@ // Initialize variables. $cl_start = trim($request->getParameter('browser_time')); $cl_finish = trim($request->getParameter('browser_time')); +$cl_duration = $cl_note = null; // Disabled controls are not posted. Therefore, && $enable_controls condition in several places below. // This allows us to get values from session when controls are disabled and reset to null when not. $cl_billable = 1; @@ -101,7 +103,7 @@ } // If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { +if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) { @@ -120,6 +122,7 @@ } // If we show project dropdown, add controls for project and client. +$project_list = $client_list = array(); if ($showProject) { // Dropdown for projects assigned to user. $project_list = $user->getAssignedProjects(); @@ -161,6 +164,7 @@ } // Task dropdown. +$task_list = array(); if ($showTask) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', @@ -195,7 +199,7 @@ if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); // Validate input in time custom fields. - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($timeCustomFields as $timeField) { // Validation is the same for text and dropdown fields. if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); @@ -245,7 +249,7 @@ // Insert time custom fields if we have them. $result = true; - if ($id && $custom_fields && $custom_fields->timeFields) { + if ($id && isset($custom_fields) && $custom_fields->timeFields) { $result = $custom_fields->insertTimeFields($id, $timeCustomFields); } From e6caf8fb9dc383066604b8623279763593088d0b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 May 2021 16:50:18 +0000 Subject: [PATCH 1530/1848] Work started on mobile friendly reports2.php. --- WEB-INF/templates/reports2.tpl | 488 +++++++++++++++++++++++++++++++ initialize.php | 2 +- reports.php | 2 + reports2.php | 504 +++++++++++++++++++++++++++++++++ 4 files changed, 995 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/templates/reports2.tpl create mode 100644 reports2.php diff --git a/WEB-INF/templates/reports2.tpl b/WEB-INF/templates/reports2.tpl new file mode 100644 index 000000000..14ccadd20 --- /dev/null +++ b/WEB-INF/templates/reports2.tpl @@ -0,0 +1,488 @@ + + +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.reportForm.open} + + + + + +
{$i18n.label.fav_report}:
{$forms.reportForm.favorite_report.control}
{$forms.reportForm.btn_generate.control} {$forms.reportForm.btn_delete.control}
+
+ +{if $show_client} + + + + + + +{/if} +{if $show_billable} + + + + + + +{/if} +{if $show_paid_status} + + + + + + +{/if} +{if $show_project} + + + + + + +{/if} +{if $show_task} + + + + + + +{/if} +
{$forms.reportForm.client.control}
{$forms.reportForm.include_records.control}
{$forms.reportForm.paid_status.control}
{$forms.reportForm.project.control}
{$forms.reportForm.task.control}
+{$forms.reportForm.close} + + + + + + + + + + + + + + +{$forms.reportForm.open} + + + + +
+ + + + + +{if $show_active_users} + + + + + + +{/if} +{if $show_inactive_users} + + + + + + +{/if} + + + + + + + + + + + + + + + + + + + +{if isset($custom_fields) && $custom_fields->timeFields} + + {foreach $custom_fields->timeFields as $timeField} + + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + + + + {/foreach} +{/if} +{if isset($custom_fields) && $custom_fields->userFields} + + {foreach $custom_fields->userFields as $userField} + + + {assign var="control_name" value='user_field_'|cat:$userField['id']} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + + + + {/foreach} +{/if} + + + + + + + + + +
+ +{if $show_approved} + + +{/if} +{if $show_invoice_dropdown} + + +{/if} +{if $show_timesheet_dropdown} + + +{/if} +
{$i18n.label.approved}
{$forms.reportForm.approved.control}
{$i18n.label.invoice}
{$forms.reportForm.invoice.control}
{$i18n.label.timesheet}
{$forms.reportForm.timesheet.control}
+
{if $show_inactive_users}{$i18n.label.active_users}{else}{$i18n.label.users}{/if}
{$forms.reportForm.users_active.control}
{$i18n.label.inactive_users}
{$forms.reportForm.users_inactive.control}
{$i18n.form.reports.select_period} {$i18n.form.reports.set_period}
{$forms.reportForm.period.control}{$i18n.label.start_date}:{$forms.reportForm.start_date.control}
{$i18n.label.end_date}:{$forms.reportForm.end_date.control}
{$i18n.form.reports.show_fields}
+ + + + + + + +
+ +{if $show_client} + +{/if} +{if $show_project} + +{/if} +{if $show_timesheet_checkbox} + +{/if} +
+
+ +{if $show_start} + +{/if} +{if $show_task} + +{/if} +{if $show_ip} + +{/if} +{if $show_work_units} + +{/if} +
+
+ +{if $show_finish} + +{/if} + +{if $show_approved} + +{/if} +{if $show_invoice_checkbox} + +{/if} +
+
+ + + +{if $show_paid_status} + +{/if} +{if $show_files} + +{/if} +
+
+
{$i18n.form.reports.time_fields}
{$timeField['label']|escape}:{$forms.reportForm.$control_name.control}{$forms.reportForm.$checkbox_control_name.control}
{$i18n.form.reports.user_fields}
{$userField['label']|escape}:{$forms.reportForm.$control_name.control}{$forms.reportForm.$checkbox_control_name.control}
{$i18n.form.reports.group_by}
{$forms.reportForm.group_by1.control}{$forms.reportForm.group_by2.control}{$forms.reportForm.group_by3.control}
+ +
+ + + + +
+ + + + + +
{$i18n.form.reports.save_as_favorite}:{$forms.reportForm.new_fav_report.control}{$forms.reportForm.btn_save.control}
+
+
+ + + +
{$forms.reportForm.btn_generate.control}
+
+{$forms.reportForm.close} diff --git a/initialize.php b/initialize.php index 177770fdf..14a7712e3 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5515"); +define("APP_VERSION", "1.19.28.5516"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports.php b/reports.php index 66b958fb3..6e3849584 100644 --- a/reports.php +++ b/reports.php @@ -72,6 +72,7 @@ // Add project dropdown. $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; +$project_list = array(); if ($showProject) { if ($user->can('view_reports') || $user->can('view_all_reports')) { $project_list = ttProjectHelper::getProjects(); // All active and inactive projects. @@ -94,6 +95,7 @@ // Add task dropdown. $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +$task_list = array(); if ($showTask) { $task_list = ttGroupHelper::getActiveTasks(); if (count($task_list) == 0) $showTask = false; diff --git a/reports2.php b/reports2.php new file mode 100644 index 000000000..b52c0e5aa --- /dev/null +++ b/reports2.php @@ -0,0 +1,504 @@ +exists()) { + header('Location: access_denied.php'); // No users in subgroup. + exit(); +} +// End of access checks. + +$trackingMode = $user->getTrackingMode(); + +// Use custom fields plugin if it is enabled. +if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + $smarty->assign('custom_fields', $custom_fields); +} + +$form = new Form('reportForm'); + +// Get saved favorite reports for user. +$report_list = ttFavReportHelper::getReports(); +$form->addInput(array('type'=>'combobox', + 'name'=>'favorite_report', + 'onchange'=>'this.form.fav_report_changed.value=1;this.form.submit();', + 'data'=>$report_list, + 'datakeys'=>array('id','name'), + 'empty'=>array('-1'=>$i18n->get('dropdown.no')))); +$form->addInput(array('type'=>'hidden','name'=>'fav_report_changed')); +// Generate and Delete buttons. +$form->addInput(array('type'=>'submit','name'=>'btn_generate','value'=>$i18n->get('button.generate'))); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'),'onclick'=>"return confirm('".$i18n->get('form.reports.confirm_delete')."')")); + +// Dropdown for clients if the clients plugin is enabled. +$showClient = $user->isPluginEnabled('cl') && !$user->isClient(); +$client_list = array(); +if ($showClient) { + if ($user->can('view_reports') || $user->can('view_all_reports')) { + $client_list = ttClientHelper::getClients(); // TODO: improve getClients for "view_reports" + // by filtering out not relevant clients. + } else + $client_list = ttClientHelper::getClientsForUser(); + if (count($client_list) == 0) $showClient = false; +} +if ($showClient) { + $form->addInput(array('type'=>'combobox', + 'onchange'=>'fillProjectDropdown(this.value);', + 'name'=>'client', + 'data'=>$client_list, + 'datakeys'=>array('id', 'name'), + 'empty'=>array(''=>$i18n->get('dropdown.all')))); +} + +// Add project dropdown. +$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; +$project_list = array(); +if ($showProject) { + if ($user->can('view_reports') || $user->can('view_all_reports')) { + $project_list = ttProjectHelper::getProjects(); // All active and inactive projects. + } elseif ($user->isClient()) { + $project_list = ttProjectHelper::getProjectsForClient(); + } else { + $project_list = ttProjectHelper::getAssignedProjects($user->getUser()); + } + if (count($project_list) == 0) $showProject = false; +} +if ($showProject) { + $form->addInput(array('type'=>'combobox', + 'onchange'=>'fillTaskDropdown(this.value);selectAssignedUsers(this.value);', + 'name'=>'project', + 'data'=>$project_list, + 'datakeys'=>array('id','name'), + 'empty'=>array(''=>$i18n->get('dropdown.all')))); +} + +// Add task dropdown. +$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +$task_list = array(); +if ($showTask) { + $task_list = ttGroupHelper::getActiveTasks(); + if (count($task_list) == 0) $showTask = false; +} +if ($showTask) { + $form->addInput(array('type'=>'combobox', + 'name'=>'task', + 'data'=>$task_list, + 'datakeys'=>array('id','name'), + 'empty'=>array(''=>$i18n->get('dropdown.all')))); +} + +// Add billable dropdown. +$showBillable = $user->isPluginEnabled('iv'); +if ($showBillable) { + $include_options = array('1'=>$i18n->get('form.reports.include_billable'), + '2'=>$i18n->get('form.reports.include_not_billable')); + $form->addInput(array('type'=>'combobox', + 'name'=>'include_records', // TODO: how about a better name here? + 'data'=>$include_options, + 'empty'=>array(''=>$i18n->get('dropdown.all')))); +} + +// Add invoiced / not invoiced selector. +$showInvoiceDropdown = $user->isPluginEnabled('iv') && $user->can('manage_invoices'); +if ($showInvoiceDropdown) { + $invoice_options = array('1'=>$i18n->get('form.reports.include_invoiced'), + '2'=>$i18n->get('form.reports.include_not_invoiced')); + $form->addInput(array('type'=>'combobox', + 'name'=>'invoice', + 'style'=>'width: 250px;', + 'data'=>$invoice_options, + 'empty'=>array(''=>$i18n->get('dropdown.all')))); +} +$showInvoiceCheckbox = $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->isClient()); + +// Add paid status selector. +$showPaidStatus = $user->isPluginEnabled('ps') && $user->can('manage_invoices'); +if ($showPaidStatus) { + $form->addInput(array('type'=>'combobox', + 'name'=>'paid_status', + 'data'=>array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')), + 'empty'=>array(''=>$i18n->get('dropdown.all')) + )); +} + +// Add approved / not approved selector. +$showApproved = $user->isPluginEnabled('ap') && + ($user->can('view_own_reports') || $user->can('view_reports') || + $user->can('view_all_reports') || ($user->can('view_client_reports') && $user->can('view_client_unapproved'))); +if ($showApproved) { + $form->addInput(array('type'=>'combobox', + 'name'=>'approved', + 'style'=>'width: 250px;', + 'data'=>array('1'=>$i18n->get('dropdown.approved'),'2'=>$i18n->get('dropdown.not_approved')), + 'empty'=>array(''=>$i18n->get('dropdown.all')) + )); +} + +// Add timesheet assignment selector. +$showTimesheetDropdown = $user->isPluginEnabled('ts'); +if ($showTimesheetDropdown) { + $form->addInput(array('type'=>'combobox', + 'name'=>'timesheet', + 'style'=>'width: 250px;', + 'data'=>array(TIMESHEET_NOT_ASSIGNED=>$i18n->get('form.reports.include_not_assigned'), + TIMESHEET_ASSIGNED=>$i18n->get('form.reports.include_assigned'), + TIMESHEET_PENDING=>$i18n->get('form.reports.include_pending'), + TIMESHEET_APPROVED=>$i18n->get('dropdown.approved'), + TIMESHEET_NOT_APPROVED=>$i18n->get('dropdown.not_approved')), + 'empty'=>array(''=>$i18n->get('dropdown.all')) + )); +} +$showTimesheetCheckbox = $user->isPluginEnabled('ts'); + +// Add user table. +$showUsers = $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient(); +$user_list = array(); +if ($showUsers) { + // Prepare user and assigned projects arrays. + if ($user->can('view_reports') || $user->can('view_all_reports')) { + $rank = $user->getMaxRankForGroup($user->getGroup()); + if ($user->can('view_all_reports')) $max_rank = MAX_RANK; + if ($user->can('view_own_reports')) { + $options_active = array('max_rank'=>$max_rank,'include_self'=>true,'status'=>ACTIVE); + $options_inactive = array('max_rank'=>$max_rank,'include_self'=>true,'status'=>INACTIVE); + } else { + $options_active = array('max_rank'=>$max_rank,'status'=>ACTIVE); + $options_inactive = array('max_rank'=>$max_rank,'status'=>INACTIVE); + } + $active_users = $user->getUsers($options_active); + $inactive_users = $user->getUsers($options_inactive); + } + elseif ($user->isClient()) { + $options_active = array('status'=>ACTIVE); + $options_inactive = array('status'=>INACTIVE); + $active_users = ttGroupHelper::getUsersForClient($options_active); + $inactive_users = ttGroupHelper::getUsersForClient($options_inactive); + } + + foreach ($active_users as $single_user) { + $user_list_active[$single_user['id']] = $single_user['name']; + $projects = ttProjectHelper::getAssignedProjects($single_user['id']); + if ($projects) { + foreach ($projects as $single_project) { + $assigned_projects[$single_user['id']][] = $single_project['id']; + } + } + } + $row_count = is_array($user_list_active) ? ceil(count($user_list_active)/3) : 1; + $form->addInput(array('type'=>'checkboxgroup', + 'name'=>'users_active', + 'data'=>$user_list_active, + 'layout'=>'V', + 'groupin'=>$row_count, + 'style'=>'width: 100%;')); + + $user_list_inactive = array(); + foreach ($inactive_users as $single_user) { + $user_list_inactive[$single_user['id']] = $single_user['name']; + $projects = ttProjectHelper::getAssignedProjects($single_user['id']); + if ($projects) { + foreach ($projects as $single_project) { + $assigned_projects[$single_user['id']][] = $single_project['id']; + } + } + } + $row_count = ceil(count($user_list_inactive)/3); + $form->addInput(array('type'=>'checkboxgroup', + 'name'=>'users_inactive', + 'data'=>$user_list_inactive, + 'layout'=>'V', + 'groupin'=>$row_count, + 'style'=>'width: 100%;')); +} + +// Add control for time period. +$form->addInput(array('type'=>'combobox', + 'name'=>'period', + 'style'=>'width: 250px;', + 'data'=>array(INTERVAL_THIS_MONTH=>$i18n->get('dropdown.current_month'), + INTERVAL_LAST_MONTH=>$i18n->get('dropdown.previous_month'), + INTERVAL_THIS_WEEK=>$i18n->get('dropdown.current_week'), + INTERVAL_LAST_WEEK=>$i18n->get('dropdown.previous_week'), + INTERVAL_THIS_DAY=>$i18n->get('dropdown.current_day'), + INTERVAL_LAST_DAY=>$i18n->get('dropdown.previous_day')), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); +// Add controls for start and end dates. +$form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start_date')); +$form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'end_date')); + +// Add checkboxes for "Show fields" block. +if ($showClient) + $form->addInput(array('type'=>'checkbox','name'=>'chclient')); +if ($showProject) + $form->addInput(array('type'=>'checkbox','name'=>'chproject')); +if ($showTask) + $form->addInput(array('type'=>'checkbox','name'=>'chtask')); +if ($showInvoiceCheckbox) + $form->addInput(array('type'=>'checkbox','name'=>'chinvoice')); +if ($showPaidStatus) + $form->addInput(array('type'=>'checkbox','name'=>'chpaid')); +$showIP = $user->can('view_reports') || $user->can('view_all_reports'); +if ($showIP) + $form->addInput(array('type'=>'checkbox','name'=>'chip')); +$recordType = $user->getRecordType(); +$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; +$showFinish = $showStart; +if ($showStart) + $form->addInput(array('type'=>'checkbox','name'=>'chstart')); +if ($showFinish) + $form->addInput(array('type'=>'checkbox','name'=>'chfinish')); +$form->addInput(array('type'=>'checkbox','name'=>'chduration')); +$form->addInput(array('type'=>'checkbox','name'=>'chnote')); +$form->addInput(array('type'=>'checkbox','name'=>'chcost')); +$showWorkUnits = $user->isPluginEnabled('wu'); +if ($showWorkUnits) + $form->addInput(array('type'=>'checkbox','name'=>'chunits')); +if ($showTimesheetCheckbox) + $form->addInput(array('type'=>'checkbox','name'=>'chtimesheet')); +if ($showApproved) + $form->addInput(array('type'=>'checkbox','name'=>'chapproved')); +$showFiles = $user->isPluginEnabled('at'); +if ($showFiles) + $form->addInput(array('type'=>'checkbox','name'=>'chfiles')); + +// Add a hidden control for timesheet_user_id (who to generate a timesheet for). +if ($showTimesheetCheckbox) + $form->addInput(array('type'=>'hidden','name'=>'timesheet_user_id')); + +// If we have time custom fields - add controls for them. +if (isset($custom_fields) && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;')); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'style'=>'width: 250px;', + 'data'=>CustomFields::getOptions($timeField['id']), + 'empty'=>array(''=>$i18n->get('dropdown.all')))); + } + // Also add a checkbox (to print the field or not). + $form->addInput(array('type'=>'checkbox','name'=>$checkbox_field_name)); + } +} + +// If we have user custom fields - add controls for them. +if (isset($custom_fields) && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($userField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;')); + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'style'=>'width: 250px;', + 'data'=>CustomFields::getOptions($userField['id']), + 'empty'=>array(''=>$i18n->get('dropdown.all')))); + } + // Also add a checkbox (to print the field or not). + $form->addInput(array('type'=>'checkbox','name'=>$checkbox_field_name)); + } +} + +// Add group by control. +$group_by_options['no_grouping'] = $i18n->get('form.reports.group_by_no'); +$group_by_options['date'] = $i18n->get('form.reports.group_by_date'); +if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) + $group_by_options['user'] = $i18n->get('form.reports.group_by_user'); +if ($user->isPluginEnabled('cl') && !($user->isClient() && $user->client_id)) + $group_by_options['client'] = $i18n->get('form.reports.group_by_client'); +if (MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode) + $group_by_options['project'] = $i18n->get('form.reports.group_by_project'); +if (MODE_PROJECTS_AND_TASKS == $trackingMode) + $group_by_options['task'] = $i18n->get('form.reports.group_by_task'); +// If we have time custom fields - add group by options for them. +if (isset($custom_fields) && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $group_by_options[$field_name] = $timeField['label']; + } +} +// If we have user custom fields - add group by options for them. +if (isset($custom_fields) && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $group_by_options[$field_name] = $userField['label']; + } +} +$group_by_options_size = sizeof($group_by_options); +$form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by1','data'=>$group_by_options)); +if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by2','data'=>$group_by_options)); +if ($group_by_options_size > 3) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by3','data'=>$group_by_options)); +$form->addInput(array('type'=>'checkbox','name'=>'chtotalsonly')); + +// Add text field for a new favorite report name. +$form->addInput(array('type'=>'text','name'=>'new_fav_report','maxlength'=>'30','style'=>'width: 250px;')); +// Save button. +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +$form->addInput(array('type'=>'submit','name'=>'btn_generate','value'=>$i18n->get('button.generate'))); + +// Create a bean (which is a mechanism to remember form values in session). +$bean = new ActionForm('reportBean', $form, $request); +// At this point form values are obtained from session if they are there. + +if ($request->isGet() && !$bean->isSaved()) { + // No previous form data were found in session. Use the following default values. + $form->setValueByElement('users_active', array_keys((array)$user_list_active)); + $period = new Period(INTERVAL_THIS_MONTH, new DateAndTime($user->getDateFormat())); + $form->setValueByElement('start_date', $period->getStartDate()); + $form->setValueByElement('end_date', $period->getEndDate()); + + $form->setValueByElement('chclient', '1'); + $form->setValueByElement('chstart', '1'); + $form->setValueByElement('chfinish', '1'); + $form->setValueByElement('chduration', '1'); + + $form->setValueByElement('chproject', '1'); + $form->setValueByElement('chtask', '1'); + $form->setValueByElement('chnote', '1'); + $form->setValueByElement('chcost', '0'); + + $form->setValueByElement('chtimesheet', '0'); + $form->setValueByElement('chip', '0'); + $form->setValueByElement('chapproved', '0'); + $form->setValueByElement('chpaid', '0'); + + $form->setValueByElement('chunits', '0'); + $form->setValueByElement('chinvoice', '0'); + $form->setValueByElement('chfiles', '1'); + + $form->setValueByElement('chtotalsonly', '0'); +} + +$form->setValueByElement('fav_report_changed',''); + +// Disable the Delete button when no favorite report is selected. +if (!$bean->getAttribute('favorite_report') || ($bean->getAttribute('favorite_report') == -1)) + $form->getElement('btn_delete')->setEnabled(false); + +if ($request->isPost()) { + if((!$bean->getAttribute('btn_generate') && ($request->getParameter('fav_report_changed')))) { + // User changed favorite report. We need to load new values into the form. + if ($bean->getAttribute('favorite_report')) { + // This loads new favorite report options into the bean (into our form). + ttFavReportHelper::loadReport($bean); + + // If user selected no favorite report - mark all user checkboxes (most probable scenario). + if ($bean->getAttribute('favorite_report') == -1) { + $form->setValueByElement('users_active', array_keys($user_list_active)); + $form->setValueByElement('users_inactive', false); + } + + // Save form data in session for future use. + $bean->saveBean(); + header('Location: reports.php'); + exit(); + } + } elseif ($bean->getAttribute('btn_save')) { + // User clicked the Save button. We need to save form options as new favorite report. + if (!ttValidString($bean->getAttribute('new_fav_report'))) $err->add($i18n->get('error.field'), $i18n->get('form.reports.save_as_favorite')); + + if ($err->no()) { + $id = ttFavReportHelper::saveReport($bean); + if (!$id) + $err->add($i18n->get('error.db')); + if ($err->no()) { + $bean->setAttribute('favorite_report', $id); + $bean->saveBean(); + header('Location: reports.php'); + exit(); + } + } + } elseif($bean->getAttribute('btn_delete')) { + // Delete button pressed. User wants to delete a favorite report. + if ($bean->getAttribute('favorite_report')) { + ttFavReportHelper::deleteReport($bean->getAttribute('favorite_report')); + // Load default report. + $bean->setAttribute('favorite_report',''); + $bean->setAttribute('new_fav_report', $report_list[0]['name']); + ttFavReportHelper::loadReport($bean); + $form->setValueByElement('users', array_keys($user_list)); + $bean->saveBean(); + header('Location: reports.php'); + exit(); + } + } else { + // Generate button pressed. Check some values. + if (!$bean->getAttribute('period')) { + $start_date = new DateAndTime($user->getDateFormat(), $bean->getAttribute('start_date')); + + if ($start_date->isError() || !$bean->getAttribute('start_date')) + $err->add($i18n->get('error.field'), $i18n->get('label.start_date')); + + $end_date = new DateAndTime($user->getDateFormat(), $bean->getAttribute('end_date')); + if ($end_date->isError() || !$bean->getAttribute('end_date')) + $err->add($i18n->get('error.field'), $i18n->get('label.end_date')); + + if ($start_date->compare($end_date) > 0) + $err->add($i18n->get('error.interval'), $i18n->get('label.end_date'), $i18n->get('label.start_date')); + } + $group_by1 = $bean->getAttribute('group_by1'); + $group_by2 = $bean->getAttribute('group_by2'); + $group_by3 = $bean->getAttribute('group_by3'); + if (($group_by3 != null && $group_by3 != 'no_grouping') && ($group_by3 == $group_by1 || $group_by3 == $group_by2)) + $err->add($i18n->get('error.field'), $i18n->get('form.reports.group_by')); + if (($group_by2 != null && $group_by2 != 'no_grouping') && ($group_by2 == $group_by1 || $group_by3 == $group_by2)) + $err->add($i18n->get('error.field'), $i18n->get('form.reports.group_by')); + // Check remaining values. + if (!ttReportHelper::verifyBean($bean)) $err->add($i18n->get('error.sys')); + + if ($err->no()) { + $bean->saveBean(); + // Now we can go ahead and create a report. + header('Location: report.php'); + exit(); + } + } +} // isPost + +$smarty->assign('client_list', $client_list); +$smarty->assign('show_client', $showClient); +$smarty->assign('show_project', $showProject); +$smarty->assign('show_task', $showTask); +$smarty->assign('show_billable', $showBillable); +$smarty->assign('show_approved', $showApproved); +$smarty->assign('show_invoice_dropdown', $showInvoiceDropdown); +$smarty->assign('show_invoice_checkbox', $showInvoiceCheckbox); +$smarty->assign('show_paid_status', $showPaidStatus); +$smarty->assign('show_timesheet_dropdown', $showTimesheetDropdown); +$smarty->assign('show_timesheet_checkbox', $showTimesheetCheckbox); +$smarty->assign('show_active_users', $showUsers && $active_users); +$smarty->assign('show_inactive_users', $showUsers && $inactive_users); +$smarty->assign('show_start', $showStart); +$smarty->assign('show_finish', $showFinish); +$smarty->assign('show_work_units', $showWorkUnits); +$smarty->assign('show_ip', $showIP); +$smarty->assign('show_files', $showFiles); +$smarty->assign('project_list', $project_list); +$smarty->assign('task_list', $task_list); +$smarty->assign('assigned_projects', $assigned_projects); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="handleCheckboxes();fillDropdowns()"'); +$smarty->assign('title', $i18n->get('title.reports')); +$smarty->assign('content_page_name', 'reports2.tpl'); +$smarty->display('index2.tpl'); From 0fda49817205ef9e23e14784ec6e1f58b26536e1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 4 May 2021 18:13:05 +0000 Subject: [PATCH 1531/1848] A bit more progress on making reports2.php mobile friendly. --- WEB-INF/templates/reports2.tpl | 43 +++++++++++++++++++--------------- initialize.php | 2 +- reports2.php | 3 --- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/WEB-INF/templates/reports2.tpl b/WEB-INF/templates/reports2.tpl index 14ccadd20..63b156340 100644 --- a/WEB-INF/templates/reports2.tpl +++ b/WEB-INF/templates/reports2.tpl @@ -270,6 +270,14 @@ License: See license.txt *}
{$forms.reportForm.invoice.control}
{$forms.reportForm.approved.control}
{$forms.reportForm.timesheet.control}
{$forms.reportForm.close} @@ -315,25 +339,6 @@ License: See license.txt *}
- - - - {if $show_active_users} diff --git a/initialize.php b/initialize.php index 14a7712e3..b61750b8f 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5516"); +define("APP_VERSION", "1.19.28.5517"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports2.php b/reports2.php index b52c0e5aa..c5ac71ab8 100644 --- a/reports2.php +++ b/reports2.php @@ -123,7 +123,6 @@ '2'=>$i18n->get('form.reports.include_not_invoiced')); $form->addInput(array('type'=>'combobox', 'name'=>'invoice', - 'style'=>'width: 250px;', 'data'=>$invoice_options, 'empty'=>array(''=>$i18n->get('dropdown.all')))); } @@ -146,7 +145,6 @@ if ($showApproved) { $form->addInput(array('type'=>'combobox', 'name'=>'approved', - 'style'=>'width: 250px;', 'data'=>array('1'=>$i18n->get('dropdown.approved'),'2'=>$i18n->get('dropdown.not_approved')), 'empty'=>array(''=>$i18n->get('dropdown.all')) )); @@ -157,7 +155,6 @@ if ($showTimesheetDropdown) { $form->addInput(array('type'=>'combobox', 'name'=>'timesheet', - 'style'=>'width: 250px;', 'data'=>array(TIMESHEET_NOT_ASSIGNED=>$i18n->get('form.reports.include_not_assigned'), TIMESHEET_ASSIGNED=>$i18n->get('form.reports.include_assigned'), TIMESHEET_PENDING=>$i18n->get('form.reports.include_pending'), From fa4ef4971d92832a9029f501ca09079ef9e8ea90 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 May 2021 20:42:02 +0000 Subject: [PATCH 1532/1848] A bit more progress on mobile friendly reports2.php. --- WEB-INF/templates/reports2.tpl | 68 ++++++++++++++++++---------------- initialize.php | 2 +- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/WEB-INF/templates/reports2.tpl b/WEB-INF/templates/reports2.tpl index 63b156340..3824e3ef2 100644 --- a/WEB-INF/templates/reports2.tpl +++ b/WEB-INF/templates/reports2.tpl @@ -253,6 +253,43 @@ License: See license.txt *}
- -{if $show_approved} - - -{/if} -{if $show_invoice_dropdown} - - -{/if} -{if $show_timesheet_dropdown} - - -{/if} -
{$i18n.label.approved}
{$forms.reportForm.approved.control}
{$i18n.label.invoice}
{$forms.reportForm.invoice.control}
{$i18n.label.timesheet}
{$forms.reportForm.timesheet.control}
-
{if $show_inactive_users}{$i18n.label.active_users}{else}{$i18n.label.users}{/if}
+ + + + + + + + + + + + + + + + + + + + + +
{$i18n.form.reports.select_period}
{$forms.reportForm.period.control}
{$i18n.form.reports.set_period}
{$forms.reportForm.start_date.control}
{$forms.reportForm.end_date.control}
+
+{if $show_active_users} +
{if $show_inactive_users}{$i18n.label.active_users}{else}{$i18n.label.users}{/if}
+ + +
{$forms.reportForm.users_active.control}
+
+{/if} +{if $show_inactive_users} +
{$i18n.label.inactive_users}
+ + +
{$forms.reportForm.users_inactive.control}
+
+{/if} {if $show_client} @@ -339,37 +376,6 @@ License: See license.txt *} {/if} +{if $show_billable} + + + + + +{/if} +{if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + + + + + + {/foreach} +{/if} +{if $show_project} + + + + + + +{/if} +{if $show_task} + + + + + + +{/if} +{if $show_week_note} + + + + + + +{/if}
-{if $show_active_users} - - - - - - -{/if} -{if $show_inactive_users} - - - - - - -{/if} - - - - - - - - - - - - - - - {/if}
{if $show_inactive_users}{$i18n.label.active_users}{else}{$i18n.label.users}{/if}
{$forms.reportForm.users_active.control}
{$i18n.label.inactive_users}
{$forms.reportForm.users_inactive.control}
{$i18n.form.reports.select_period} {$i18n.form.reports.set_period}
{$forms.reportForm.period.control}{$i18n.label.start_date}:{$forms.reportForm.start_date.control}
{$i18n.label.end_date}:{$forms.reportForm.end_date.control}
{$i18n.form.reports.show_fields}
diff --git a/initialize.php b/initialize.php index b61750b8f..d55fd2b71 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5517"); +define("APP_VERSION", "1.19.28.5518"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 0327d8ca4bffc65e7fbd8d32f9e9fbfe8335c4f6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 May 2021 21:15:32 +0000 Subject: [PATCH 1533/1848] More progress on reports2.tpl. --- WEB-INF/templates/reports2.tpl | 176 +++++++++++++++++++++------------ initialize.php | 2 +- 2 files changed, 113 insertions(+), 65 deletions(-) diff --git a/WEB-INF/templates/reports2.tpl b/WEB-INF/templates/reports2.tpl index 3824e3ef2..1caa61d6f 100644 --- a/WEB-INF/templates/reports2.tpl +++ b/WEB-INF/templates/reports2.tpl @@ -356,90 +356,138 @@ License: See license.txt *}
-{$forms.reportForm.close} - - - - - - - - - - - - - - -{$forms.reportForm.open} - - - {/if} {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} + {if $use_checkboxes}{/if} + {* column for edit icons *} {foreach $report_items as $item} {* print subtotal for a block of grouped values *} @@ -107,7 +112,7 @@ {if $use_checkboxes}{/if} {* column for edit icons *} - + {/if} {$first_pass = false} {/if} @@ -154,7 +159,7 @@ {if 2 == $item.type}{/if} {/if} {if $item.approved || $item.timesheet_id || $item.invoice_id} - + {else} {if 1 == $item.type}{/if} {if 2 == $item.type}{/if} @@ -209,7 +214,7 @@ {/if} {* print totals *} - + {/if} diff --git a/initialize.php b/initialize.php index a991b8fc4..8155661fa 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5527"); +define("APP_VERSION", "1.19.28.5528"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/report.php b/report.php index 527e8ac7f..916b02f8e 100644 --- a/report.php +++ b/report.php @@ -304,6 +304,8 @@ if ($bean->getAttribute('chinvoice')) $colspan++; if ($bean->getAttribute('chtimesheet')) $colspan++; if ($bean->getAttribute('chfiles')) $colspan++; +if ($use_checkboxes) $colspan++; +$colspan++; // One more column for edit icons. // Assign variables that are used to alternate color of rows for different dates. $smarty->assign('prev_date', ''); From 860ae31a56fc0c3ada3f51f0e43c32d66548fc8e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 May 2021 20:03:13 +0000 Subject: [PATCH 1543/1848] Fixed one more colspan issue on report.php. --- initialize.php | 2 +- report.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/initialize.php b/initialize.php index 8155661fa..2ff973341 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5528"); +define("APP_VERSION", "1.19.28.5529"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/report.php b/report.php index 916b02f8e..cb959d488 100644 --- a/report.php +++ b/report.php @@ -275,7 +275,7 @@ } $totals = ttReportHelper::getTotals($options); -// Determine column span for note field. +// Determine column span for note field and empty rows. $colspan = 0; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $colspan++; if (isset($custom_fields) && $custom_fields->userFields) { @@ -296,6 +296,7 @@ if ($bean->getAttribute('chstart')) $colspan++; if ($bean->getAttribute('chfinish')) $colspan++; if ($bean->getAttribute('chduration')) $colspan++; +if (!$user->getConfigOption('report_note_on_separate_row') && $bean->getAttribute('chnote')) $colspan++; if ($bean->getAttribute('chunits')) $colspan++; if ($bean->getAttribute('chcost')) $colspan++; if ($bean->getAttribute('chapproved')) $colspan++; From 6cf84621339c2c41c2e8434c3c1ac14d82cd30b9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 May 2021 20:29:04 +0000 Subject: [PATCH 1544/1848] Fixe html closing tags on report2.tpl. --- WEB-INF/templates/report2.tpl | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/report2.tpl b/WEB-INF/templates/report2.tpl index 8c491b196..7224b2983 100644 --- a/WEB-INF/templates/report2.tpl +++ b/WEB-INF/templates/report2.tpl @@ -167,7 +167,7 @@ License: See license.txt *} {if $note_on_separate_row && $bean->getAttribute('chnote') && $item.note} - {/if} @@ -216,7 +216,7 @@ License: See license.txt *} {* print totals *} - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} {* user custom fileds *} {if isset($custom_fields) && $custom_fields->userFields} diff --git a/initialize.php b/initialize.php index 2ff973341..e7773d3d7 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5529"); +define("APP_VERSION", "1.19.28.5530"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From c99954245edfe4bd80b44048afd1c15d67096094 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 May 2021 13:05:15 +0000 Subject: [PATCH 1545/1848] Starting to work on mobile friendly week view. --- WEB-INF/templates/week2.tpl | 236 +++++++++++++++ initialize.php | 2 +- week2.php | 559 ++++++++++++++++++++++++++++++++++++ 3 files changed, 796 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/templates/week2.tpl create mode 100644 week2.php diff --git a/WEB-INF/templates/week2.tpl b/WEB-INF/templates/week2.tpl new file mode 100644 index 000000000..b46e9804f --- /dev/null +++ b/WEB-INF/templates/week2.tpl @@ -0,0 +1,236 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{include file="time_script.tpl"} + + + + + + +{if $show_navigation} + +{/if} + +{$forms.weekTimeForm.open} +
{$forms.weekTimeForm.date.control}
+
- - - - - +
{$i18n.form.reports.show_fields}
- - - - - - - -
- +
+
+ {if $show_client} - + + + + + + {/if} {if $show_project} - + + + + + + {/if} -{if $show_timesheet_checkbox} - +{if $show_task} + + + + + + {/if} -
{$i18n.form.reports.show_fields}
{$forms.reportForm.chclient.control}
{$forms.reportForm.chproject.control}
{$forms.reportForm.chtask.control}
-
- {if $show_start} - + + + + + + {/if} -{if $show_task} - +{if $show_finish} + + + + + + +{/if} + + + + + + + + + + + + +{if $show_timesheet_checkbox} + + + + + + {/if} {if $show_ip} - + + + + + + {/if} {if $show_work_units} - -{/if} -
{$forms.reportForm.chstart.control}
{$forms.reportForm.chfinish.control}
{$forms.reportForm.chduration.control}
{$forms.reportForm.chcost.control}
{$forms.reportForm.chtimesheet.control}
{$forms.reportForm.chip.control}
-
- -{if $show_finish} - + + + + + + {/if} - {if $show_approved} - + + + + + + {/if} {if $show_invoice_checkbox} - + + + + + + {/if} -
{$forms.reportForm.chunits.control}
{$forms.reportForm.chapproved.control}
{$forms.reportForm.chinvoice.control}
-
- - - {if $show_paid_status} - + + + + + + {/if} {if $show_files} - + + + + + + {/if} -
{$forms.reportForm.chpaid.control}
{$forms.reportForm.chfiles.control}
-
-
+{$forms.reportForm.close} + + + + + + + + + + + + + + +{$forms.reportForm.open} + + + + + + + + + {if $show_work_units} diff --git a/initialize.php b/initialize.php index d2838d03e..c6cdd3b6e 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5523"); +define("APP_VERSION", "1.19.28.5524"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From fa6b5f9e9cbb5a73cf9ddbb7cc428527f32e84f2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 May 2021 23:15:05 +0000 Subject: [PATCH 1539/1848] A bit more progress on making mobile friendly report2.php. --- WEB-INF/templates/report2.tpl | 112 +++++++++++++++++++++++++++------- initialize.php | 2 +- 2 files changed, 90 insertions(+), 24 deletions(-) diff --git a/WEB-INF/templates/report2.tpl b/WEB-INF/templates/report2.tpl index 1e0fd466b..21eaa4ed0 100644 --- a/WEB-INF/templates/report2.tpl +++ b/WEB-INF/templates/report2.tpl @@ -29,41 +29,107 @@ {if $bean->getAttribute('chcost')}{/if}
+ {if isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} diff --git a/initialize.php b/initialize.php index d55fd2b71..be497f91b 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5518"); +define("APP_VERSION", "1.19.28.5519"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 15fbcff42d84da9d5089a7b08495e314daad59da Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 5 May 2021 22:33:03 +0000 Subject: [PATCH 1534/1848] Made mobile friendly reports2.php working. --- WEB-INF/resources/ru.lang.php | 4 +- WEB-INF/templates/reports2.tpl | 152 +++++++++++++-------------------- initialize.php | 2 +- reports2.php | 15 ++-- 4 files changed, 69 insertions(+), 104 deletions(-) diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 835b90048..db94bf685 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -429,8 +429,8 @@ 'form.reports.select_period' => 'Выберите интервал времени', 'form.reports.set_period' => 'или укажите даты', 'form.reports.show_fields' => 'Показывать поля', -'form.reports.time_fields' => 'Time fields', -'form.reports.user_fields' => 'Поля времени', +'form.reports.time_fields' => 'Поля времени', +'form.reports.user_fields' => 'Поля пользователя', 'form.reports.group_by' => 'Группировать по', 'form.reports.group_by_no' => '--- без группировки ---', 'form.reports.group_by_date' => 'дате', diff --git a/WEB-INF/templates/reports2.tpl b/WEB-INF/templates/reports2.tpl index 1caa61d6f..a4c926ad1 100644 --- a/WEB-INF/templates/reports2.tpl +++ b/WEB-INF/templates/reports2.tpl @@ -405,41 +405,41 @@ License: See license.txt *} - +{if $show_work_units} + - - + + -{if $show_timesheet_checkbox} - +{/if} + - - + + -{/if} -{if $show_ip} - +{if $show_approved} + - - + + {/if} -{if $show_work_units} - +{if $show_paid_status} + - - + + {/if} -{if $show_approved} - +{if $show_ip} + - - + + {/if} @@ -451,11 +451,11 @@ License: See license.txt *} {/if} -{if $show_paid_status} - +{if $show_timesheet_checkbox} + - - + + {/if} @@ -468,80 +468,50 @@ License: See license.txt *} {/if}
{$i18n.form.reports.time_fields}
{$forms.reportForm.chduration.control}
{$forms.reportForm.chcost.control}{$forms.reportForm.chunits.control}
{$forms.reportForm.chtimesheet.control}{$forms.reportForm.chcost.control}
{$forms.reportForm.chip.control}{$forms.reportForm.chapproved.control}
{$forms.reportForm.chunits.control}{$forms.reportForm.chpaid.control}
{$forms.reportForm.chapproved.control}{$forms.reportForm.chip.control}
{$forms.reportForm.chpaid.control}{$forms.reportForm.chtimesheet.control}
-{$forms.reportForm.close} - - - - - - - - - - - - - - -{$forms.reportForm.open} - - - -
- +
+
{if isset($custom_fields) && $custom_fields->timeFields} - + {foreach $custom_fields->timeFields as $timeField} - - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - - - + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + + + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + + + {/foreach} {/if} {if isset($custom_fields) && $custom_fields->userFields} - + {foreach $custom_fields->userFields as $userField} - - - {assign var="control_name" value='user_field_'|cat:$userField['id']} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - - - + {assign var="control_name" value='user_field_'|cat:$userField['id']} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + + + + + + {/foreach} {/if} - - - - - - - - - -
{$i18n.form.reports.time_fields}
{$i18n.form.reports.time_fields}
{$timeField['label']|escape}:{$forms.reportForm.$control_name.control}{$forms.reportForm.$checkbox_control_name.control}
{$forms.reportForm.$control_name.control} {$forms.reportForm.$checkbox_control_name.control}
{$i18n.form.reports.user_fields}
{$i18n.form.reports.user_fields}
{$userField['label']|escape}:{$forms.reportForm.$control_name.control}{$forms.reportForm.$checkbox_control_name.control}
{$forms.reportForm.$control_name.control} {$forms.reportForm.$checkbox_control_name.control}
{$i18n.form.reports.group_by}
{$forms.reportForm.group_by1.control}{$forms.reportForm.group_by2.control}{$forms.reportForm.group_by3.control}
- -
- - - - -
- - - - - -
{$i18n.form.reports.save_as_favorite}:{$forms.reportForm.new_fav_report.control}{$forms.reportForm.btn_save.control}
-
-
- - - -
{$forms.reportForm.btn_generate.control}
-
+
+ + + + + + +
{$i18n.form.reports.group_by}
{$forms.reportForm.group_by1.control}
{$forms.reportForm.group_by2.control}
{$forms.reportForm.group_by3.control}
+
+ + + + +
{$forms.reportForm.new_fav_report.control} {$forms.reportForm.btn_save.control}
+
{$forms.reportForm.btn_generate.control}
{$forms.reportForm.close} diff --git a/initialize.php b/initialize.php index be497f91b..72ad717a5 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5519"); +define("APP_VERSION", "1.19.28.5520"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports2.php b/reports2.php index c5ac71ab8..71f455bea 100644 --- a/reports2.php +++ b/reports2.php @@ -204,8 +204,7 @@ 'name'=>'users_active', 'data'=>$user_list_active, 'layout'=>'V', - 'groupin'=>$row_count, - 'style'=>'width: 100%;')); + 'groupin'=>$row_count)); $user_list_inactive = array(); foreach ($inactive_users as $single_user) { @@ -222,14 +221,12 @@ 'name'=>'users_inactive', 'data'=>$user_list_inactive, 'layout'=>'V', - 'groupin'=>$row_count, - 'style'=>'width: 100%;')); + 'groupin'=>$row_count)); } // Add control for time period. $form->addInput(array('type'=>'combobox', 'name'=>'period', - 'style'=>'width: 250px;', 'data'=>array(INTERVAL_THIS_MONTH=>$i18n->get('dropdown.current_month'), INTERVAL_LAST_MONTH=>$i18n->get('dropdown.previous_month'), INTERVAL_THIS_WEEK=>$i18n->get('dropdown.current_week'), @@ -286,10 +283,9 @@ $field_name = 'time_field_'.$timeField['id']; $checkbox_field_name = 'show_'.$field_name; if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;')); + $form->addInput(array('type'=>'text','name'=>$field_name)); } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', 'data'=>CustomFields::getOptions($timeField['id']), 'empty'=>array(''=>$i18n->get('dropdown.all')))); } @@ -304,10 +300,9 @@ $field_name = 'user_field_'.$userField['id']; $checkbox_field_name = 'show_'.$field_name; if ($userField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;')); + $form->addInput(array('type'=>'text','name'=>$field_name,)); } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', 'data'=>CustomFields::getOptions($userField['id']), 'empty'=>array(''=>$i18n->get('dropdown.all')))); } @@ -348,7 +343,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'chtotalsonly')); // Add text field for a new favorite report name. -$form->addInput(array('type'=>'text','name'=>'new_fav_report','maxlength'=>'30','style'=>'width: 250px;')); +$form->addInput(array('type'=>'text','name'=>'new_fav_report','maxlength'=>'30')); // Save button. $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); From 189a237fdcd6d7c269de1d3a8120bd0d3ca52b60 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 May 2021 13:08:10 +0000 Subject: [PATCH 1535/1848] Switched to using mobile friendly reports.php developed earlier. --- initialize.php | 2 +- reports.php | 28 +-- reports2.php | 496 ------------------------------------------------- 3 files changed, 8 insertions(+), 518 deletions(-) delete mode 100644 reports2.php diff --git a/initialize.php b/initialize.php index 72ad717a5..6494e97e1 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5520"); +define("APP_VERSION", "1.19.28.5521"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports.php b/reports.php index 6e3849584..71f455bea 100644 --- a/reports.php +++ b/reports.php @@ -40,7 +40,6 @@ $form->addInput(array('type'=>'combobox', 'name'=>'favorite_report', 'onchange'=>'this.form.fav_report_changed.value=1;this.form.submit();', - 'style'=>'width: 250px;', 'data'=>$report_list, 'datakeys'=>array('id','name'), 'empty'=>array('-1'=>$i18n->get('dropdown.no')))); @@ -64,7 +63,6 @@ $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', - 'style'=>'width: 250px;', 'data'=>$client_list, 'datakeys'=>array('id', 'name'), 'empty'=>array(''=>$i18n->get('dropdown.all')))); @@ -87,7 +85,6 @@ $form->addInput(array('type'=>'combobox', 'onchange'=>'fillTaskDropdown(this.value);selectAssignedUsers(this.value);', 'name'=>'project', - 'style'=>'width: 250px;', 'data'=>$project_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.all')))); @@ -103,7 +100,6 @@ if ($showTask) { $form->addInput(array('type'=>'combobox', 'name'=>'task', - 'style'=>'width: 250px;', 'data'=>$task_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.all')))); @@ -116,7 +112,6 @@ '2'=>$i18n->get('form.reports.include_not_billable')); $form->addInput(array('type'=>'combobox', 'name'=>'include_records', // TODO: how about a better name here? - 'style'=>'width: 250px;', 'data'=>$include_options, 'empty'=>array(''=>$i18n->get('dropdown.all')))); } @@ -128,7 +123,6 @@ '2'=>$i18n->get('form.reports.include_not_invoiced')); $form->addInput(array('type'=>'combobox', 'name'=>'invoice', - 'style'=>'width: 250px;', 'data'=>$invoice_options, 'empty'=>array(''=>$i18n->get('dropdown.all')))); } @@ -139,7 +133,6 @@ if ($showPaidStatus) { $form->addInput(array('type'=>'combobox', 'name'=>'paid_status', - 'style'=>'width: 250px;', 'data'=>array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')), 'empty'=>array(''=>$i18n->get('dropdown.all')) )); @@ -152,7 +145,6 @@ if ($showApproved) { $form->addInput(array('type'=>'combobox', 'name'=>'approved', - 'style'=>'width: 250px;', 'data'=>array('1'=>$i18n->get('dropdown.approved'),'2'=>$i18n->get('dropdown.not_approved')), 'empty'=>array(''=>$i18n->get('dropdown.all')) )); @@ -163,7 +155,6 @@ if ($showTimesheetDropdown) { $form->addInput(array('type'=>'combobox', 'name'=>'timesheet', - 'style'=>'width: 250px;', 'data'=>array(TIMESHEET_NOT_ASSIGNED=>$i18n->get('form.reports.include_not_assigned'), TIMESHEET_ASSIGNED=>$i18n->get('form.reports.include_assigned'), TIMESHEET_PENDING=>$i18n->get('form.reports.include_pending'), @@ -213,8 +204,7 @@ 'name'=>'users_active', 'data'=>$user_list_active, 'layout'=>'V', - 'groupin'=>$row_count, - 'style'=>'width: 100%;')); + 'groupin'=>$row_count)); $user_list_inactive = array(); foreach ($inactive_users as $single_user) { @@ -231,14 +221,12 @@ 'name'=>'users_inactive', 'data'=>$user_list_inactive, 'layout'=>'V', - 'groupin'=>$row_count, - 'style'=>'width: 100%;')); + 'groupin'=>$row_count)); } // Add control for time period. $form->addInput(array('type'=>'combobox', 'name'=>'period', - 'style'=>'width: 250px;', 'data'=>array(INTERVAL_THIS_MONTH=>$i18n->get('dropdown.current_month'), INTERVAL_LAST_MONTH=>$i18n->get('dropdown.previous_month'), INTERVAL_THIS_WEEK=>$i18n->get('dropdown.current_week'), @@ -295,10 +283,9 @@ $field_name = 'time_field_'.$timeField['id']; $checkbox_field_name = 'show_'.$field_name; if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;')); + $form->addInput(array('type'=>'text','name'=>$field_name)); } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', 'data'=>CustomFields::getOptions($timeField['id']), 'empty'=>array(''=>$i18n->get('dropdown.all')))); } @@ -313,10 +300,9 @@ $field_name = 'user_field_'.$userField['id']; $checkbox_field_name = 'show_'.$field_name; if ($userField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;')); + $form->addInput(array('type'=>'text','name'=>$field_name,)); } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', 'data'=>CustomFields::getOptions($userField['id']), 'empty'=>array(''=>$i18n->get('dropdown.all')))); } @@ -357,7 +343,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'chtotalsonly')); // Add text field for a new favorite report name. -$form->addInput(array('type'=>'text','name'=>'new_fav_report','maxlength'=>'30','style'=>'width: 250px;')); +$form->addInput(array('type'=>'text','name'=>'new_fav_report','maxlength'=>'30')); // Save button. $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); @@ -506,5 +492,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="handleCheckboxes();fillDropdowns()"'); $smarty->assign('title', $i18n->get('title.reports')); -$smarty->assign('content_page_name', 'reports.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'reports2.tpl'); +$smarty->display('index2.tpl'); diff --git a/reports2.php b/reports2.php deleted file mode 100644 index 71f455bea..000000000 --- a/reports2.php +++ /dev/null @@ -1,496 +0,0 @@ -exists()) { - header('Location: access_denied.php'); // No users in subgroup. - exit(); -} -// End of access checks. - -$trackingMode = $user->getTrackingMode(); - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -$form = new Form('reportForm'); - -// Get saved favorite reports for user. -$report_list = ttFavReportHelper::getReports(); -$form->addInput(array('type'=>'combobox', - 'name'=>'favorite_report', - 'onchange'=>'this.form.fav_report_changed.value=1;this.form.submit();', - 'data'=>$report_list, - 'datakeys'=>array('id','name'), - 'empty'=>array('-1'=>$i18n->get('dropdown.no')))); -$form->addInput(array('type'=>'hidden','name'=>'fav_report_changed')); -// Generate and Delete buttons. -$form->addInput(array('type'=>'submit','name'=>'btn_generate','value'=>$i18n->get('button.generate'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'),'onclick'=>"return confirm('".$i18n->get('form.reports.confirm_delete')."')")); - -// Dropdown for clients if the clients plugin is enabled. -$showClient = $user->isPluginEnabled('cl') && !$user->isClient(); -$client_list = array(); -if ($showClient) { - if ($user->can('view_reports') || $user->can('view_all_reports')) { - $client_list = ttClientHelper::getClients(); // TODO: improve getClients for "view_reports" - // by filtering out not relevant clients. - } else - $client_list = ttClientHelper::getClientsForUser(); - if (count($client_list) == 0) $showClient = false; -} -if ($showClient) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.all')))); -} - -// Add project dropdown. -$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; -$project_list = array(); -if ($showProject) { - if ($user->can('view_reports') || $user->can('view_all_reports')) { - $project_list = ttProjectHelper::getProjects(); // All active and inactive projects. - } elseif ($user->isClient()) { - $project_list = ttProjectHelper::getProjectsForClient(); - } else { - $project_list = ttProjectHelper::getAssignedProjects($user->getUser()); - } - if (count($project_list) == 0) $showProject = false; -} -if ($showProject) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);selectAssignedUsers(this.value);', - 'name'=>'project', - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.all')))); -} - -// Add task dropdown. -$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; -$task_list = array(); -if ($showTask) { - $task_list = ttGroupHelper::getActiveTasks(); - if (count($task_list) == 0) $showTask = false; -} -if ($showTask) { - $form->addInput(array('type'=>'combobox', - 'name'=>'task', - 'data'=>$task_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.all')))); -} - -// Add billable dropdown. -$showBillable = $user->isPluginEnabled('iv'); -if ($showBillable) { - $include_options = array('1'=>$i18n->get('form.reports.include_billable'), - '2'=>$i18n->get('form.reports.include_not_billable')); - $form->addInput(array('type'=>'combobox', - 'name'=>'include_records', // TODO: how about a better name here? - 'data'=>$include_options, - 'empty'=>array(''=>$i18n->get('dropdown.all')))); -} - -// Add invoiced / not invoiced selector. -$showInvoiceDropdown = $user->isPluginEnabled('iv') && $user->can('manage_invoices'); -if ($showInvoiceDropdown) { - $invoice_options = array('1'=>$i18n->get('form.reports.include_invoiced'), - '2'=>$i18n->get('form.reports.include_not_invoiced')); - $form->addInput(array('type'=>'combobox', - 'name'=>'invoice', - 'data'=>$invoice_options, - 'empty'=>array(''=>$i18n->get('dropdown.all')))); -} -$showInvoiceCheckbox = $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->isClient()); - -// Add paid status selector. -$showPaidStatus = $user->isPluginEnabled('ps') && $user->can('manage_invoices'); -if ($showPaidStatus) { - $form->addInput(array('type'=>'combobox', - 'name'=>'paid_status', - 'data'=>array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')), - 'empty'=>array(''=>$i18n->get('dropdown.all')) - )); -} - -// Add approved / not approved selector. -$showApproved = $user->isPluginEnabled('ap') && - ($user->can('view_own_reports') || $user->can('view_reports') || - $user->can('view_all_reports') || ($user->can('view_client_reports') && $user->can('view_client_unapproved'))); -if ($showApproved) { - $form->addInput(array('type'=>'combobox', - 'name'=>'approved', - 'data'=>array('1'=>$i18n->get('dropdown.approved'),'2'=>$i18n->get('dropdown.not_approved')), - 'empty'=>array(''=>$i18n->get('dropdown.all')) - )); -} - -// Add timesheet assignment selector. -$showTimesheetDropdown = $user->isPluginEnabled('ts'); -if ($showTimesheetDropdown) { - $form->addInput(array('type'=>'combobox', - 'name'=>'timesheet', - 'data'=>array(TIMESHEET_NOT_ASSIGNED=>$i18n->get('form.reports.include_not_assigned'), - TIMESHEET_ASSIGNED=>$i18n->get('form.reports.include_assigned'), - TIMESHEET_PENDING=>$i18n->get('form.reports.include_pending'), - TIMESHEET_APPROVED=>$i18n->get('dropdown.approved'), - TIMESHEET_NOT_APPROVED=>$i18n->get('dropdown.not_approved')), - 'empty'=>array(''=>$i18n->get('dropdown.all')) - )); -} -$showTimesheetCheckbox = $user->isPluginEnabled('ts'); - -// Add user table. -$showUsers = $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient(); -$user_list = array(); -if ($showUsers) { - // Prepare user and assigned projects arrays. - if ($user->can('view_reports') || $user->can('view_all_reports')) { - $rank = $user->getMaxRankForGroup($user->getGroup()); - if ($user->can('view_all_reports')) $max_rank = MAX_RANK; - if ($user->can('view_own_reports')) { - $options_active = array('max_rank'=>$max_rank,'include_self'=>true,'status'=>ACTIVE); - $options_inactive = array('max_rank'=>$max_rank,'include_self'=>true,'status'=>INACTIVE); - } else { - $options_active = array('max_rank'=>$max_rank,'status'=>ACTIVE); - $options_inactive = array('max_rank'=>$max_rank,'status'=>INACTIVE); - } - $active_users = $user->getUsers($options_active); - $inactive_users = $user->getUsers($options_inactive); - } - elseif ($user->isClient()) { - $options_active = array('status'=>ACTIVE); - $options_inactive = array('status'=>INACTIVE); - $active_users = ttGroupHelper::getUsersForClient($options_active); - $inactive_users = ttGroupHelper::getUsersForClient($options_inactive); - } - - foreach ($active_users as $single_user) { - $user_list_active[$single_user['id']] = $single_user['name']; - $projects = ttProjectHelper::getAssignedProjects($single_user['id']); - if ($projects) { - foreach ($projects as $single_project) { - $assigned_projects[$single_user['id']][] = $single_project['id']; - } - } - } - $row_count = is_array($user_list_active) ? ceil(count($user_list_active)/3) : 1; - $form->addInput(array('type'=>'checkboxgroup', - 'name'=>'users_active', - 'data'=>$user_list_active, - 'layout'=>'V', - 'groupin'=>$row_count)); - - $user_list_inactive = array(); - foreach ($inactive_users as $single_user) { - $user_list_inactive[$single_user['id']] = $single_user['name']; - $projects = ttProjectHelper::getAssignedProjects($single_user['id']); - if ($projects) { - foreach ($projects as $single_project) { - $assigned_projects[$single_user['id']][] = $single_project['id']; - } - } - } - $row_count = ceil(count($user_list_inactive)/3); - $form->addInput(array('type'=>'checkboxgroup', - 'name'=>'users_inactive', - 'data'=>$user_list_inactive, - 'layout'=>'V', - 'groupin'=>$row_count)); -} - -// Add control for time period. -$form->addInput(array('type'=>'combobox', - 'name'=>'period', - 'data'=>array(INTERVAL_THIS_MONTH=>$i18n->get('dropdown.current_month'), - INTERVAL_LAST_MONTH=>$i18n->get('dropdown.previous_month'), - INTERVAL_THIS_WEEK=>$i18n->get('dropdown.current_week'), - INTERVAL_LAST_WEEK=>$i18n->get('dropdown.previous_week'), - INTERVAL_THIS_DAY=>$i18n->get('dropdown.current_day'), - INTERVAL_LAST_DAY=>$i18n->get('dropdown.previous_day')), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); -// Add controls for start and end dates. -$form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start_date')); -$form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'end_date')); - -// Add checkboxes for "Show fields" block. -if ($showClient) - $form->addInput(array('type'=>'checkbox','name'=>'chclient')); -if ($showProject) - $form->addInput(array('type'=>'checkbox','name'=>'chproject')); -if ($showTask) - $form->addInput(array('type'=>'checkbox','name'=>'chtask')); -if ($showInvoiceCheckbox) - $form->addInput(array('type'=>'checkbox','name'=>'chinvoice')); -if ($showPaidStatus) - $form->addInput(array('type'=>'checkbox','name'=>'chpaid')); -$showIP = $user->can('view_reports') || $user->can('view_all_reports'); -if ($showIP) - $form->addInput(array('type'=>'checkbox','name'=>'chip')); -$recordType = $user->getRecordType(); -$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; -$showFinish = $showStart; -if ($showStart) - $form->addInput(array('type'=>'checkbox','name'=>'chstart')); -if ($showFinish) - $form->addInput(array('type'=>'checkbox','name'=>'chfinish')); -$form->addInput(array('type'=>'checkbox','name'=>'chduration')); -$form->addInput(array('type'=>'checkbox','name'=>'chnote')); -$form->addInput(array('type'=>'checkbox','name'=>'chcost')); -$showWorkUnits = $user->isPluginEnabled('wu'); -if ($showWorkUnits) - $form->addInput(array('type'=>'checkbox','name'=>'chunits')); -if ($showTimesheetCheckbox) - $form->addInput(array('type'=>'checkbox','name'=>'chtimesheet')); -if ($showApproved) - $form->addInput(array('type'=>'checkbox','name'=>'chapproved')); -$showFiles = $user->isPluginEnabled('at'); -if ($showFiles) - $form->addInput(array('type'=>'checkbox','name'=>'chfiles')); - -// Add a hidden control for timesheet_user_id (who to generate a timesheet for). -if ($showTimesheetCheckbox) - $form->addInput(array('type'=>'hidden','name'=>'timesheet_user_id')); - -// If we have time custom fields - add controls for them. -if (isset($custom_fields) && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - $checkbox_field_name = 'show_'.$field_name; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name)); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'data'=>CustomFields::getOptions($timeField['id']), - 'empty'=>array(''=>$i18n->get('dropdown.all')))); - } - // Also add a checkbox (to print the field or not). - $form->addInput(array('type'=>'checkbox','name'=>$checkbox_field_name)); - } -} - -// If we have user custom fields - add controls for them. -if (isset($custom_fields) && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $field_name = 'user_field_'.$userField['id']; - $checkbox_field_name = 'show_'.$field_name; - if ($userField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,)); - } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'data'=>CustomFields::getOptions($userField['id']), - 'empty'=>array(''=>$i18n->get('dropdown.all')))); - } - // Also add a checkbox (to print the field or not). - $form->addInput(array('type'=>'checkbox','name'=>$checkbox_field_name)); - } -} - -// Add group by control. -$group_by_options['no_grouping'] = $i18n->get('form.reports.group_by_no'); -$group_by_options['date'] = $i18n->get('form.reports.group_by_date'); -if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) - $group_by_options['user'] = $i18n->get('form.reports.group_by_user'); -if ($user->isPluginEnabled('cl') && !($user->isClient() && $user->client_id)) - $group_by_options['client'] = $i18n->get('form.reports.group_by_client'); -if (MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode) - $group_by_options['project'] = $i18n->get('form.reports.group_by_project'); -if (MODE_PROJECTS_AND_TASKS == $trackingMode) - $group_by_options['task'] = $i18n->get('form.reports.group_by_task'); -// If we have time custom fields - add group by options for them. -if (isset($custom_fields) && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - $group_by_options[$field_name] = $timeField['label']; - } -} -// If we have user custom fields - add group by options for them. -if (isset($custom_fields) && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $field_name = 'user_field_'.$userField['id']; - $group_by_options[$field_name] = $userField['label']; - } -} -$group_by_options_size = sizeof($group_by_options); -$form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by1','data'=>$group_by_options)); -if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by2','data'=>$group_by_options)); -if ($group_by_options_size > 3) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by3','data'=>$group_by_options)); -$form->addInput(array('type'=>'checkbox','name'=>'chtotalsonly')); - -// Add text field for a new favorite report name. -$form->addInput(array('type'=>'text','name'=>'new_fav_report','maxlength'=>'30')); -// Save button. -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); - -$form->addInput(array('type'=>'submit','name'=>'btn_generate','value'=>$i18n->get('button.generate'))); - -// Create a bean (which is a mechanism to remember form values in session). -$bean = new ActionForm('reportBean', $form, $request); -// At this point form values are obtained from session if they are there. - -if ($request->isGet() && !$bean->isSaved()) { - // No previous form data were found in session. Use the following default values. - $form->setValueByElement('users_active', array_keys((array)$user_list_active)); - $period = new Period(INTERVAL_THIS_MONTH, new DateAndTime($user->getDateFormat())); - $form->setValueByElement('start_date', $period->getStartDate()); - $form->setValueByElement('end_date', $period->getEndDate()); - - $form->setValueByElement('chclient', '1'); - $form->setValueByElement('chstart', '1'); - $form->setValueByElement('chfinish', '1'); - $form->setValueByElement('chduration', '1'); - - $form->setValueByElement('chproject', '1'); - $form->setValueByElement('chtask', '1'); - $form->setValueByElement('chnote', '1'); - $form->setValueByElement('chcost', '0'); - - $form->setValueByElement('chtimesheet', '0'); - $form->setValueByElement('chip', '0'); - $form->setValueByElement('chapproved', '0'); - $form->setValueByElement('chpaid', '0'); - - $form->setValueByElement('chunits', '0'); - $form->setValueByElement('chinvoice', '0'); - $form->setValueByElement('chfiles', '1'); - - $form->setValueByElement('chtotalsonly', '0'); -} - -$form->setValueByElement('fav_report_changed',''); - -// Disable the Delete button when no favorite report is selected. -if (!$bean->getAttribute('favorite_report') || ($bean->getAttribute('favorite_report') == -1)) - $form->getElement('btn_delete')->setEnabled(false); - -if ($request->isPost()) { - if((!$bean->getAttribute('btn_generate') && ($request->getParameter('fav_report_changed')))) { - // User changed favorite report. We need to load new values into the form. - if ($bean->getAttribute('favorite_report')) { - // This loads new favorite report options into the bean (into our form). - ttFavReportHelper::loadReport($bean); - - // If user selected no favorite report - mark all user checkboxes (most probable scenario). - if ($bean->getAttribute('favorite_report') == -1) { - $form->setValueByElement('users_active', array_keys($user_list_active)); - $form->setValueByElement('users_inactive', false); - } - - // Save form data in session for future use. - $bean->saveBean(); - header('Location: reports.php'); - exit(); - } - } elseif ($bean->getAttribute('btn_save')) { - // User clicked the Save button. We need to save form options as new favorite report. - if (!ttValidString($bean->getAttribute('new_fav_report'))) $err->add($i18n->get('error.field'), $i18n->get('form.reports.save_as_favorite')); - - if ($err->no()) { - $id = ttFavReportHelper::saveReport($bean); - if (!$id) - $err->add($i18n->get('error.db')); - if ($err->no()) { - $bean->setAttribute('favorite_report', $id); - $bean->saveBean(); - header('Location: reports.php'); - exit(); - } - } - } elseif($bean->getAttribute('btn_delete')) { - // Delete button pressed. User wants to delete a favorite report. - if ($bean->getAttribute('favorite_report')) { - ttFavReportHelper::deleteReport($bean->getAttribute('favorite_report')); - // Load default report. - $bean->setAttribute('favorite_report',''); - $bean->setAttribute('new_fav_report', $report_list[0]['name']); - ttFavReportHelper::loadReport($bean); - $form->setValueByElement('users', array_keys($user_list)); - $bean->saveBean(); - header('Location: reports.php'); - exit(); - } - } else { - // Generate button pressed. Check some values. - if (!$bean->getAttribute('period')) { - $start_date = new DateAndTime($user->getDateFormat(), $bean->getAttribute('start_date')); - - if ($start_date->isError() || !$bean->getAttribute('start_date')) - $err->add($i18n->get('error.field'), $i18n->get('label.start_date')); - - $end_date = new DateAndTime($user->getDateFormat(), $bean->getAttribute('end_date')); - if ($end_date->isError() || !$bean->getAttribute('end_date')) - $err->add($i18n->get('error.field'), $i18n->get('label.end_date')); - - if ($start_date->compare($end_date) > 0) - $err->add($i18n->get('error.interval'), $i18n->get('label.end_date'), $i18n->get('label.start_date')); - } - $group_by1 = $bean->getAttribute('group_by1'); - $group_by2 = $bean->getAttribute('group_by2'); - $group_by3 = $bean->getAttribute('group_by3'); - if (($group_by3 != null && $group_by3 != 'no_grouping') && ($group_by3 == $group_by1 || $group_by3 == $group_by2)) - $err->add($i18n->get('error.field'), $i18n->get('form.reports.group_by')); - if (($group_by2 != null && $group_by2 != 'no_grouping') && ($group_by2 == $group_by1 || $group_by3 == $group_by2)) - $err->add($i18n->get('error.field'), $i18n->get('form.reports.group_by')); - // Check remaining values. - if (!ttReportHelper::verifyBean($bean)) $err->add($i18n->get('error.sys')); - - if ($err->no()) { - $bean->saveBean(); - // Now we can go ahead and create a report. - header('Location: report.php'); - exit(); - } - } -} // isPost - -$smarty->assign('client_list', $client_list); -$smarty->assign('show_client', $showClient); -$smarty->assign('show_project', $showProject); -$smarty->assign('show_task', $showTask); -$smarty->assign('show_billable', $showBillable); -$smarty->assign('show_approved', $showApproved); -$smarty->assign('show_invoice_dropdown', $showInvoiceDropdown); -$smarty->assign('show_invoice_checkbox', $showInvoiceCheckbox); -$smarty->assign('show_paid_status', $showPaidStatus); -$smarty->assign('show_timesheet_dropdown', $showTimesheetDropdown); -$smarty->assign('show_timesheet_checkbox', $showTimesheetCheckbox); -$smarty->assign('show_active_users', $showUsers && $active_users); -$smarty->assign('show_inactive_users', $showUsers && $inactive_users); -$smarty->assign('show_start', $showStart); -$smarty->assign('show_finish', $showFinish); -$smarty->assign('show_work_units', $showWorkUnits); -$smarty->assign('show_ip', $showIP); -$smarty->assign('show_files', $showFiles); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('assigned_projects', $assigned_projects); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="handleCheckboxes();fillDropdowns()"'); -$smarty->assign('title', $i18n->get('title.reports')); -$smarty->assign('content_page_name', 'reports2.tpl'); -$smarty->display('index2.tpl'); From df20820df4a743916596ce8e3d3f1b04182e4adf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 May 2021 13:50:04 +0000 Subject: [PATCH 1536/1848] Starting work on mobile friendly report2.php. --- WEB-INF/templates/report2.tpl | 360 ++++++++++++++++++++++++++++++++++ initialize.php | 2 +- report2.php | 313 +++++++++++++++++++++++++++++ 3 files changed, 674 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/templates/report2.tpl create mode 100644 report2.php diff --git a/WEB-INF/templates/report2.tpl b/WEB-INF/templates/report2.tpl new file mode 100644 index 000000000..1e0fd466b --- /dev/null +++ b/WEB-INF/templates/report2.tpl @@ -0,0 +1,360 @@ + + +
{$i18n.form.report.export} {if file_exists('WEB-INF/lib/tcpdf')}PDF,{/if} XML {$i18n.label.or} CSV
+{$forms.reportViewForm.open} + +{if $bean->getAttribute('chtotalsonly')} + + + + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chcost')}{/if} + + {foreach $subtotals as $subtotal} + + + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chcost')}{/if} + + {/foreach} + + + + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chcost')}{/if} + +
{$group_by_header|escape}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.cost}
{if $subtotal['name']}{$subtotal['name']|escape}{else} {/if}{$subtotal['time']}{$subtotal['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotal['cost']}{else}{$subtotal['expenses']}{/if}
{$i18n.label.total}:{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
+{/if} +{$forms.reportViewForm.close} + + + + +{$forms.reportViewForm.open} + + + + +
+ + +{if $bean->getAttribute('chtotalsonly')} + + + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chcost')}{/if} + + {foreach $subtotals as $subtotal} + + + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chcost')}{/if} + + {/foreach} + + + + + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chcost')}{/if} + +{else} + + + + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + + {* user custom fileds *} + {if isset($custom_fields) && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + + {* time custom fileds *} + {if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chstart')}{/if} + {if $bean->getAttribute('chfinish')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} + {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} + {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chip')}{/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chfiles')}{/if} + + {foreach $report_items as $item} + + {$cur_date = $item.date} + {if $print_subtotals} + {$cur_grouped_by = $item.grouped_by} + {if $cur_grouped_by != $prev_grouped_by && !$first_pass} + + {/if} + + {* user custom fileds *} + {if isset($custom_fields) && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + + {* time custom fileds *} + {if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chstart')}{/if} + {if $bean->getAttribute('chfinish')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} + {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} + {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chip')}{/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chfiles')}{/if} + {if $use_checkboxes}{/if} + {* column for edit icons *} + + + {/if} + {$first_pass = false} + {/if} + + {if $cur_date != $prev_date} + {if $report_row_class == 'rowReportItem'} {$report_row_class = 'rowReportItemAlt'} {else} {$report_row_class = 'rowReportItem'} {/if} + {/if} + + + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + + {* user custom fileds *} + {if isset($custom_fields) && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="control_name" value='user_field_'|cat:$userField['id']} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + + {* time custom fileds *} + {if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chstart')}{/if} + {if $bean->getAttribute('chfinish')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} + {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} + {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chip')}{/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chfiles')} + {if 1 == $item.type}{/if} + {if 2 == $item.type}{/if} + {/if} + {if $use_checkboxes} + {if 1 == $item.type}{/if} + {if 2 == $item.type}{/if} + {/if} + {if $item.approved || $item.timesheet_id || $item.invoice_id} + + {else} + {if 1 == $item.type}{/if} + {if 2 == $item.type}{/if} + {/if} + + {if $note_on_separate_row && $bean->getAttribute('chnote') && $item.note} + + + + + {/if} + {$prev_date = $item.date} + {if $print_subtotals} {$prev_grouped_by = $item.grouped_by} {/if} + {/foreach} + + {if $print_subtotals} + + {/if} + + {* user custom fileds *} + {if isset($custom_fields) && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + + {* time custom fileds *} + {if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chstart')}{/if} + {if $bean->getAttribute('chfinish')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} + {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} + {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chip')}{/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chfiles')}{/if} + {if $use_checkboxes}{/if} + {* column for edit icons *} + + {/if} + + + + + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + + {* user custom fileds *} + {if isset($custom_fields) && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + + {* time custom fileds *} + {if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chstart')}{/if} + {if $bean->getAttribute('chfinish')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} + {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} + {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chip')}{/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chfiles')}{/if} + {if $use_checkboxes}{/if} + {* column for edit icons *} + +{/if} +
{$group_by_header|escape}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.cost}
{if $subtotal['name']}{$subtotal['name']|escape}{else} {/if}{$subtotal['time']}{$subtotal['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotal['cost']}{else}{$subtotal['expenses']}{/if}
 
{$i18n.label.total}{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
{$i18n.label.date}{$i18n.label.user}{{$userField['label']|escape}}{$i18n.label.client}{$i18n.label.project}{$i18n.label.task}{{$timeField['label']|escape}}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.note}{$i18n.label.cost}{$i18n.label.approved}{$i18n.label.paid}{$i18n.label.ip}{$i18n.label.invoice}{$i18n.label.timesheet}
{$i18n.label.subtotal} + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{$subtotals[$prev_grouped_by]['user']|escape}{$subtotals[$prev_grouped_by]['client']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$subtotals[$prev_grouped_by]['time']}{$subtotals[$prev_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}
 
{$item.date}{$item.user|escape}{$item.$control_name|escape}{$item.client|escape}{$item.project|escape}{$item.task|escape}{$item.$control_name|escape}{$item.start}{$item.finish}{$item.duration}{$item.units}{$item.note|escape}{if $user->can('manage_invoices') || $user->isClient()}{$item.cost}{else}{$item.expense}{/if}{if $item.approved == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $item.modified}{$item.modified_ip} {$item.modified}{else}{$item.created_ip} {$item.created}{/if}{$item.invoice|escape}{$item.timesheet_name|escape}{if $item.has_files}{$i18n.label.files}{/if}{if $item.has_files}{$i18n.label.files}{/if} {$i18n.label.edit}{$i18n.label.edit}
{$i18n.label.note}:{$item.note|escape}
{$i18n.label.subtotal} + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{$subtotals[$cur_grouped_by]['user']|escape}{$subtotals[$cur_grouped_by]['client']|escape}{$subtotals[$cur_grouped_by]['project']|escape}{$subtotals[$cur_grouped_by]['task']|escape}{$subtotals[$cur_grouped_by]['time']}{$subtotals[$cur_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$cur_grouped_by]['cost']}{else}{$subtotals[$cur_grouped_by]['expenses']}{/if}
 
{$i18n.label.total}{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
+
+{if $report_items && ($use_mark_approved || $use_mark_paid || $use_assign_to_invoice || $use_assign_to_timesheet)} + + {if $use_mark_approved} + + + + {/if} + {if $use_mark_paid} + + + + {/if} + {if $use_assign_to_invoice} + + + + {/if} + {if $use_assign_to_timesheet} + + + + {/if} +
+ + +
{$i18n.label.mark_approved}: {$forms.reportViewForm.mark_approved_select_options.control} {$forms.reportViewForm.mark_approved_action_options.control} {$forms.reportViewForm.btn_mark_approved.control}
+
+ + +
{$i18n.label.mark_paid}: {$forms.reportViewForm.mark_paid_select_options.control} {$forms.reportViewForm.mark_paid_action_options.control} {$forms.reportViewForm.btn_mark_paid.control}
+
+ + +
{$i18n.form.report.assign_to_invoice}: {$forms.reportViewForm.assign_invoice_select_options.control} {$forms.reportViewForm.recent_invoice.control} {$forms.reportViewForm.btn_assign_invoice.control}
+
+ + +
{$i18n.form.report.assign_to_timesheet}: {$forms.reportViewForm.assign_timesheet_select_options.control} {$forms.reportViewForm.timesheet.control} {$forms.reportViewForm.btn_assign_timesheet.control}
+
+{/if} +{$forms.reportViewForm.close} + + + + + +
+ + + + +
+
diff --git a/initialize.php b/initialize.php index 6494e97e1..4ace7d553 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5521"); +define("APP_VERSION", "1.19.28.5522"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/report2.php b/report2.php new file mode 100644 index 000000000..d5fd4e165 --- /dev/null +++ b/report2.php @@ -0,0 +1,313 @@ +getConfig()); + +if ($user->isPluginEnabled('ap')) { + $cl_mark_approved_select_option = $request->getParameter('mark_approved_select_options', ($request->isPost() ? null : @$_SESSION['mark_approved_select_option'])); + $_SESSION['mark_approved_select_option'] = $cl_mark_approved_select_option; + $cl_mark_approved_action_option = $request->getParameter('mark_approved_action_options', ($request->isPost() ? null : @$_SESSION['mark_approved_action_option'])); + $_SESSION['mark_aproved_action_option'] = $cl_mark_approved_action_option; +} +if ($user->isPluginEnabled('ps')) { + $cl_mark_paid_select_option = $request->getParameter('mark_paid_select_options', ($request->isPost() ? null : @$_SESSION['mark_paid_select_option'])); + $_SESSION['mark_paid_select_option'] = $cl_mark_paid_select_option; + $cl_mark_paid_action_option = $request->getParameter('mark_paid_action_options', ($request->isPost() ? null : @$_SESSION['mark_paid_action_option'])); + $_SESSION['mark_paid_action_option'] = $cl_mark_paid_action_option; +} +if ($user->isPluginEnabled('iv')) { + $cl_assign_invoice_select_option = $request->getParameter('assign_invoice_select_options', ($request->isPost() ? null : @$_SESSION['assign_invoice_select_option'])); + $_SESSION['assign_invoice_select_option'] = $cl_assign_invoice_select_option; + $cl_recent_invoice_option = $request->getParameter('recent_invoice', ($request->isPost() ? null : @$_SESSION['recent_invoice_option'])); + $_SESSION['recent_invoice_option'] = $cl_recent_invoice_option; +} +if ($user->isPluginEnabled('ts')) { + $cl_assign_timesheet_select_option = $request->getParameter('assign_timesheet_select_options', ($request->isPost() ? null : @$_SESSION['assign_timesheet_select_option'])); + $_SESSION['assign_timesheet_select_option'] = $cl_assign_timesheet_select_option; + $cl_timesheet_option = $request->getParameter('timesheet', ($request->isPost() ? null : @$_SESSION['timesheet_option'])); + $_SESSION['timesheet_option'] = $cl_timesheet_option; +} + +// Use custom fields plugin if it is enabled. +if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + $smarty->assign('custom_fields', $custom_fields); +} + +$form = new Form('reportViewForm'); + +// Report settings are stored in session bean before we get here from reports.php. +$bean = new ActionForm('reportBean', new Form('reportForm'), $request); +// If we are in post, load the bean from session, as the constructor does it only in get. +if ($request->isPost()) $bean->loadBean(); + +$client_id = $bean->getAttribute('client'); +$options = ttReportHelper::getReportOptions($bean); + +// Do we need to show checkboxes? We show them in the following 4 situations: +// - We can approve items. +// - We can mark items as paid. +// - We can assign items to invoices. +// - We can assign items to a timesheet. +// Determine these conditions separately. +$useMarkApproved = $useMarkPaid = $useAssignToInvoice = $useAssignToTimesheet = false; +if ($bean->getAttribute('chapproved') && ($user->can('approve_reports') || $user->can('approve_all_reports'))) + $useMarkApproved = true; +if ($bean->getAttribute('chpaid') && $user->can('manage_invoices')) + $useMarkPaid = true; +if ($bean->getAttribute('chinvoice') && $client_id && 'no_grouping' == $bean->getAttribute('group_by1') && !$user->isClient() && $user->can('manage_invoices')) + $useAssignToInvoice = true; +if ($bean->getAttribute('chtimesheet')) { + $timesheets = ttTimesheetHelper::getMatchingTimesheets($options); + if ($timesheets) $useAssignToTimesheet = true; +} + +$use_checkboxes = $useMarkApproved || $useMarkPaid || $useAssignToInvoice || $useAssignToTimesheet; +$smarty->assign('use_checkboxes', $use_checkboxes); + +// Controls for "Mark approved" block. +$smarty->assign('use_mark_approved', false); +if ($useMarkApproved) { + $mark_approved_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); + $form->addInput(array('type'=>'combobox', + 'name'=>'mark_approved_select_options', + 'data'=>$mark_approved_select_options, + 'value'=>$cl_mark_approved_select_option)); + $mark_approved_action_options = array('1'=>$i18n->get('dropdown.approved'),'2'=>$i18n->get('dropdown.not_approved')); + $form->addInput(array('type'=>'combobox', + 'name'=>'mark_approved_action_options', + 'data'=>$mark_approved_action_options, + 'value'=>$cl_mark_approved_action_option)); + $form->addInput(array('type'=>'submit','name'=>'btn_mark_approved','value'=>$i18n->get('button.submit'))); + $smarty->assign('use_mark_approved', true); +} + +// Controls for "Mark paid" block. +$smarty->assign('use_mark_paid', false); +if ($useMarkPaid) { + $mark_paid_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); + $form->addInput(array('type'=>'combobox', + 'name'=>'mark_paid_select_options', + 'data'=>$mark_paid_select_options, + 'value'=>$cl_mark_paid_select_option)); + $mark_paid_action_options = array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')); + $form->addInput(array('type'=>'combobox', + 'name'=>'mark_paid_action_options', + 'data'=>$mark_paid_action_options, + 'value'=>$cl_mark_paid_action_option)); + $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->get('button.submit'))); + $smarty->assign('use_mark_paid', true); +} + +// Controls for "Assign to invoice" block. +$smarty->assign('use_assign_to_invoice', false); +if ($useAssignToInvoice) { + // Client is selected and we are displaying the invoice column. + $recent_invoices = ttGroupHelper::getRecentInvoices($client_id); + if ($recent_invoices) { + $assign_invoice_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); + $form->addInput(array('type'=>'combobox', + 'name'=>'assign_invoice_select_options', + 'data'=>$assign_invoice_select_options, + 'value'=>$cl_assign_invoice_select_option)); + $form->addInput(array('type'=>'combobox', + 'name'=>'recent_invoice', + 'data'=>$recent_invoices, + 'datakeys'=>array('id','name'), + 'value'=>$cl_recent_invoice_option, + 'empty'=>array(''=>$i18n->get('dropdown.select_invoice')))); + $form->addInput(array('type'=>'submit','name'=>'btn_assign_invoice','value'=>$i18n->get('button.submit'))); + $smarty->assign('use_assign_to_invoice', true); + } +} + +// Controls for "Assign to timesheet" block. +$smarty->assign('use_assign_to_timesheet', false); +if ($useAssignToTimesheet) { + $assign_timesheet_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); + $form->addInput(array('type'=>'combobox', + 'name'=>'assign_timesheet_select_options', + 'data'=>$assign_timesheet_select_options, + 'value'=>$cl_assign_timesheet_select_option)); + $form->addInput(array('type'=>'combobox', + 'name'=>'timesheet', + 'data'=>$timesheets, + 'datakeys'=>array('id','name'), + 'value'=>$cl_timesheet_option, + 'empty'=>array(''=>$i18n->get('dropdown.select_timesheet')))); + $form->addInput(array('type'=>'submit','name'=>'btn_assign_timesheet','value'=>$i18n->get('button.submit'))); + $smarty->assign('use_assign_to_timesheet', true); +} + +if ($request->isPost()) { + + // Validate parameters and at the same time build arrays of record ids. + if (($request->getParameter('btn_mark_approved') && 2 == $request->getParameter('mark_approved_select_options')) + || ($request->getParameter('btn_mark_paid') && 2 == $request->getParameter('mark_paid_select_options')) + || ($request->getParameter('btn_assign_invoice') && 2 == $request->getParameter('assign_invoice_select_options')) + || ($request->getParameter('btn_assign_timesheet') && 2 == $request->getParameter('assign_timesheet_select_options'))) { + // We act on selected records. Are there any? + foreach($_POST as $key => $val) { + if ('log_id_' == substr($key, 0, 7)) + $time_log_ids[] = substr($key, 7); + if ('item_id_' == substr($key, 0, 8)) + $expense_item_ids[] = substr($key, 8); + } + if (!$time_log_ids && !$expense_item_ids) $err->Add($i18n->get('error.record')); // There are no selected records. + // Validation of parameteres ended here. + } else { + // We are assigning all report items. Get the arrays from session. + // Note: getting from session assures we act only on previously displayed records. + // Rebuilding from $bean may get us a different set. + $item_ids = ttReportHelper::getFromSession(); + $time_log_ids = @$item_ids['report_item_ids']; + $expense_item_ids = @$item_ids['report_item_expense_ids']; + // The above code is here because the arrays are used in both "Mark paid" and "Assign to invoice" handlers below. + } + + if ($err->no()) { + if ($request->getParameter('btn_mark_approved')) { + // User clicked the "Mark approved" button to mark some or all items either approved or not approved. + + // Determine user action. + $mark_approved = $request->getParameter('mark_approved_action_options') == 1 ? true : false; + + // Mark as requested. + if ($time_log_ids || $expense_item_ids) { + ttReportHelper::markApproved($time_log_ids, $expense_item_ids, $mark_approved); + } + + // Re-display this form. + header('Location: report.php'); + exit(); + } + + if ($request->getParameter('btn_mark_paid')) { + // User clicked the "Mark paid" button to mark some or all items either paid or not paid. + + // Determine user action. + $mark_paid = $request->getParameter('mark_paid_action_options') == 1 ? true : false; + + // Mark as requested. + if ($time_log_ids || $expense_item_ids) { + ttReportHelper::markPaid($time_log_ids, $expense_item_ids, $mark_paid); + } + + // Re-display this form. + header('Location: report.php'); + exit(); + } + + if ($request->getParameter('btn_assign_invoice')) { + // User clicked the Submit button to assign all or some items to a recent invoice. + + // Determine invoice id. + $invoice_id = $request->getParameter('recent_invoice'); + + // Assign as requested. + if ($time_log_ids || $expense_item_ids) { + ttReportHelper::assignToInvoice($invoice_id, $time_log_ids, $expense_item_ids); + } + // Re-display this form. + header('Location: report.php'); + exit(); + } + + if ($request->getParameter('btn_assign_timesheet')) { + // User clicked the Submit button to assign all or some items to a timesheet. + + // Determine invoice id. + $timesheet_id = $request->getParameter('timesheet'); + + // Assign as requested. + if ($time_log_ids) { + ttReportHelper::assignToTimesheet($timesheet_id, $time_log_ids); + } + // Re-display this form. + header('Location: report.php'); + exit(); + } + } +} // isPost + +$report_items = ttReportHelper::getItems($options); +// Store record ids in session in case user wants to act on records such as marking them all paid. +if ($request->isGet() && $use_checkboxes) + ttReportHelper::putInSession($report_items); + +$subtotals = array(); +$smarty->assign('print_subtotals', false); +if (ttReportHelper::grouping($options)) { + $subtotals = ttReportHelper::getSubtotals($options); + $smarty->assign('group_by_header', ttReportHelper::makeGroupByHeader($options)); + if ($report_items) { + // Assign variables that are used to print subtotals. + $smarty->assign('print_subtotals', true); + $smarty->assign('first_pass', true); + $smarty->assign('prev_grouped_by', ''); + $smarty->assign('cur_grouped_by', ''); + } +} +$totals = ttReportHelper::getTotals($options); + +// Determine column span for note field. +$colspan = 0; +if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $colspan++; +if (isset($custom_fields) && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $checkbox_control_name = 'show_user_field_'.$userField['id']; + if ($bean->getAttribute($checkbox_control_name)) $colspan++; + } +} +if ($bean->getAttribute('chclient')) $colspan++; +if ($bean->getAttribute('chproject')) $colspan++; +if ($bean->getAttribute('chtask')) $colspan++; +if (isset($custom_fields) && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $checkbox_control_name = 'show_time_field_'.$timeField['id']; + if ($bean->getAttribute($checkbox_control_name)) $colspan++; + } +} +if ($bean->getAttribute('chstart')) $colspan++; +if ($bean->getAttribute('chfinish')) $colspan++; +if ($bean->getAttribute('chduration')) $colspan++; +if ($bean->getAttribute('chunits')) $colspan++; +if ($bean->getAttribute('chcost')) $colspan++; +if ($bean->getAttribute('chapproved')) $colspan++; +if ($bean->getAttribute('chpaid')) $colspan++; +if ($bean->getAttribute('chip')) $colspan++; +if ($bean->getAttribute('chinvoice')) $colspan++; +if ($bean->getAttribute('chtimesheet')) $colspan++; +if ($bean->getAttribute('chfiles')) $colspan++; + +// Assign variables that are used to alternate color of rows for different dates. +$smarty->assign('prev_date', ''); +$smarty->assign('cur_date', ''); +$smarty->assign('report_row_class', 'rowReportItem'); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('report_items', $report_items); +$smarty->assign('subtotals', $subtotals); +$smarty->assign('totals', $totals); +$smarty->assign('note_on_separate_row', $user->getConfigOption('report_note_on_separate_row')); +$smarty->assign('colspan', $colspan); +$smarty->assign('bean', $bean); +$smarty->assign('title', $i18n->get('title.report').": ".$totals['start_date']." - ".$totals['end_date']); +$smarty->assign('content_page_name', 'report2.tpl'); +$smarty->display('index2.tpl'); From beca535c23720c04501f1100cff9751517625fb2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 May 2021 14:18:45 +0000 Subject: [PATCH 1537/1848] Fixed a bug on totals only reports with visibility of use_mark_approved and similar controls. --- initialize.php | 2 +- report.php | 8 ++++---- report2.php | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/initialize.php b/initialize.php index 4ace7d553..d2838d03e 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5522"); +define("APP_VERSION", "1.19.28.5523"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/report.php b/report.php index e53374138..19f6b8c22 100644 --- a/report.php +++ b/report.php @@ -68,13 +68,13 @@ // - We can assign items to a timesheet. // Determine these conditions separately. $useMarkApproved = $useMarkPaid = $useAssignToInvoice = $useAssignToTimesheet = false; -if ($bean->getAttribute('chapproved') && ($user->can('approve_reports') || $user->can('approve_all_reports'))) +if (!$bean->getAttribute('chtotalsonly') && $bean->getAttribute('chapproved') && ($user->can('approve_reports') || $user->can('approve_all_reports'))) $useMarkApproved = true; -if ($bean->getAttribute('chpaid') && $user->can('manage_invoices')) +if (!$bean->getAttribute('chtotalsonly') && $bean->getAttribute('chpaid') && $user->can('manage_invoices')) $useMarkPaid = true; -if ($bean->getAttribute('chinvoice') && $client_id && 'no_grouping' == $bean->getAttribute('group_by1') && !$user->isClient() && $user->can('manage_invoices')) +if (!$bean->getAttribute('chtotalsonly') && $bean->getAttribute('chinvoice') && $client_id && 'no_grouping' == $bean->getAttribute('group_by1') && !$user->isClient() && $user->can('manage_invoices')) $useAssignToInvoice = true; -if ($bean->getAttribute('chtimesheet')) { +if (!$bean->getAttribute('chtotalsonly') && $bean->getAttribute('chtimesheet')) { $timesheets = ttTimesheetHelper::getMatchingTimesheets($options); if ($timesheets) $useAssignToTimesheet = true; } diff --git a/report2.php b/report2.php index d5fd4e165..3776ecb3d 100644 --- a/report2.php +++ b/report2.php @@ -68,13 +68,13 @@ // - We can assign items to a timesheet. // Determine these conditions separately. $useMarkApproved = $useMarkPaid = $useAssignToInvoice = $useAssignToTimesheet = false; -if ($bean->getAttribute('chapproved') && ($user->can('approve_reports') || $user->can('approve_all_reports'))) +if (!$bean->getAttribute('chtotalsonly') && $bean->getAttribute('chapproved') && ($user->can('approve_reports') || $user->can('approve_all_reports'))) $useMarkApproved = true; -if ($bean->getAttribute('chpaid') && $user->can('manage_invoices')) +if (!$bean->getAttribute('chtotalsonly') && $bean->getAttribute('chpaid') && $user->can('manage_invoices')) $useMarkPaid = true; -if ($bean->getAttribute('chinvoice') && $client_id && 'no_grouping' == $bean->getAttribute('group_by1') && !$user->isClient() && $user->can('manage_invoices')) +if (!$bean->getAttribute('chtotalsonly') && $bean->getAttribute('chinvoice') && $client_id && 'no_grouping' == $bean->getAttribute('group_by1') && !$user->isClient() && $user->can('manage_invoices')) $useAssignToInvoice = true; -if ($bean->getAttribute('chtimesheet')) { +if (!$bean->getAttribute('chtotalsonly') && $bean->getAttribute('chtimesheet')) { $timesheets = ttTimesheetHelper::getMatchingTimesheets($options); if ($timesheets) $useAssignToTimesheet = true; } From caf11264e9ae62724213cb159d745274047fb0ac Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 6 May 2021 14:33:04 +0000 Subject: [PATCH 1538/1848] Recovered show note option on reports.php. --- WEB-INF/templates/reports2.tpl | 6 ++++++ initialize.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/reports2.tpl b/WEB-INF/templates/reports2.tpl index a4c926ad1..3f272e112 100644 --- a/WEB-INF/templates/reports2.tpl +++ b/WEB-INF/templates/reports2.tpl @@ -405,6 +405,12 @@ License: See license.txt *}
{$forms.reportForm.chduration.control}
{$forms.reportForm.chnote.control}
{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
+{else} + + + + + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + {* user custom fileds *} + {if isset($custom_fields) && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + {* time custom fileds *} + {if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chstart')}{/if} + {if $bean->getAttribute('chfinish')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} + {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} + {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chip')}{/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chfiles')}{/if} + + {foreach $report_items as $item} + + {$cur_date = $item.date} + {if $print_subtotals} + {$cur_grouped_by = $item.grouped_by} + {if $cur_grouped_by != $prev_grouped_by && !$first_pass} + + + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + + {* user custom fileds *} + {if isset($custom_fields) && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + + {* time custom fileds *} + {if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + + {if $bean->getAttribute('chstart')}{/if} + {if $bean->getAttribute('chfinish')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} + {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} + {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chip')}{/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chfiles')}{/if} + {if $use_checkboxes}{/if} + {* column for edit icons *} + + + {/if} + {$first_pass = false} + {/if} + {/foreach} +
{$i18n.label.date}{$i18n.label.user}{{$userField['label']|escape}}{$i18n.label.client}{$i18n.label.project}{$i18n.label.task}{{$timeField['label']|escape}}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.note}{$i18n.label.cost}{$i18n.label.approved}{$i18n.label.paid}{$i18n.label.ip}{$i18n.label.invoice}{$i18n.label.timesheet}
{$i18n.label.subtotal}{$subtotals[$prev_grouped_by]['user']|escape}{$subtotals[$prev_grouped_by]['client']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$subtotals[$prev_grouped_by]['time']}{$subtotals[$prev_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}
 
{/if} {$forms.reportViewForm.close} -{$forms.reportViewForm.open} + +{$forms.reportViewForm.open}
{if $bean->getAttribute('chtotalsonly')} - - - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chcost')}{/if} - - {foreach $subtotals as $subtotal} - - - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chcost')}{/if} - - {/foreach} - - - - - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chcost')}{/if} - {else} diff --git a/initialize.php b/initialize.php index c6cdd3b6e..40135a55a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5524"); +define("APP_VERSION", "1.19.28.5525"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From c121f9cb5b9b88cc72d005e23fec1f3376fc7ecd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 May 2021 15:13:15 +0000 Subject: [PATCH 1540/1848] More progress on making mobile friendly report. --- WEB-INF/templates/report2.tpl | 168 ++++++++++++++++++++++++++++++---- default.css | 5 + initialize.php | 2 +- 3 files changed, 155 insertions(+), 20 deletions(-) diff --git a/WEB-INF/templates/report2.tpl b/WEB-INF/templates/report2.tpl index 21eaa4ed0..db065ac94 100644 --- a/WEB-INF/templates/report2.tpl +++ b/WEB-INF/templates/report2.tpl @@ -4,7 +4,7 @@
{$i18n.form.report.export} {if file_exists('WEB-INF/lib/tcpdf')}PDF,{/if} XML {$i18n.label.or} CSV
{$forms.reportViewForm.open} - +{* totals only report *} {if $bean->getAttribute('chtotalsonly')}
{$group_by_header|escape}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.cost}
{if $subtotal['name']}{$subtotal['name']|escape}{else} {/if}{$subtotal['time']}{$subtotal['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotal['cost']}{else}{$subtotal['expenses']}{/if}
 
{$i18n.label.total}{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
@@ -21,7 +21,7 @@ {if $bean->getAttribute('chcost')}{/if} {/foreach} - + {* print totals *} {if $bean->getAttribute('chduration')}{/if} @@ -30,7 +30,7 @@
{if $user->can('manage_invoices') || $user->isClient()}{$subtotal['cost']}{else}{$subtotal['expenses']}{/if}
{$i18n.label.total}:{$totals['time']}
{else} - +{* normal report *} @@ -66,15 +66,14 @@ {if $bean->getAttribute('chfiles')}{/if} {foreach $report_items as $item} - + {* print subtotal for a block of grouped values *} {$cur_date = $item.date} {if $print_subtotals} {$cur_grouped_by = $item.grouped_by} {if $cur_grouped_by != $prev_grouped_by && !$first_pass} - - - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - + + + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} {* user custom fileds *} {if isset($custom_fields) && $custom_fields->userFields} {foreach $custom_fields->userFields as $userField} @@ -82,10 +81,9 @@ {if $bean->getAttribute($checkbox_control_name)}{/if} {/foreach} {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} {* time custom fileds *} {if isset($custom_fields) && $custom_fields->timeFields} @@ -94,13 +92,12 @@ {if $bean->getAttribute($checkbox_control_name)}{/if} {/foreach} {/if} - {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chcost')}{/if} {if $bean->getAttribute('chapproved')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} @@ -108,13 +105,146 @@ {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} - {* column for edit icons *} - - + {* column for edit icons *} + + {/if} {$first_pass = false} {/if} + {* print regular row *} + + + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + {* user custom fileds *} + {if isset($custom_fields) && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="control_name" value='user_field_'|cat:$userField['id']} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + {* time custom fileds *} + {if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chstart')}{/if} + {if $bean->getAttribute('chfinish')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} + {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} + {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chip')}{/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chfiles')} + {if 1 == $item.type}{/if} + {if 2 == $item.type}{/if} + {/if} + {if $use_checkboxes} + {if 1 == $item.type}{/if} + {if 2 == $item.type}{/if} + {/if} + {if $item.approved || $item.timesheet_id || $item.invoice_id} + + {else} + {if 1 == $item.type}{/if} + {if 2 == $item.type}{/if} + {/if} + + {if $note_on_separate_row && $bean->getAttribute('chnote') && $item.note} + + + + {/if} + {$prev_date = $item.date} + {if $print_subtotals} {$prev_grouped_by = $item.grouped_by} {/if} {/foreach} + {* print a terminating subtotal *} + {if $print_subtotals} + + + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + + {* user custom fileds *} + {if isset($custom_fields) && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + {* time custom fileds *} + {if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chstart')}{/if} + {if $bean->getAttribute('chfinish')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} + {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} + {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chip')}{/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chfiles')}{/if} + {if $use_checkboxes}{/if} + {* column for edit icons *} + + {/if} + {* print totals *} + + + {/if} + {* user custom fileds *} + {if isset($custom_fields) && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chclient')}{/if} + {if $bean->getAttribute('chproject')}{/if} + {if $bean->getAttribute('chtask')}{/if} + {* time custom fileds *} + {if isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chstart')}{/if} + {if $bean->getAttribute('chfinish')}{/if} + {if $bean->getAttribute('chduration')}{/if} + {if $bean->getAttribute('chunits')}{/if} + {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} + {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chapproved')}{/if} + {if $bean->getAttribute('chpaid')}{/if} + {if $bean->getAttribute('chip')}{/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $bean->getAttribute('chtimesheet')}{/if} + {if $bean->getAttribute('chfiles')}{/if} + {if $use_checkboxes}{/if} + {* column for edit icons *} +
{$i18n.label.date}
{$i18n.label.subtotal}{$subtotals[$prev_grouped_by]['user']|escape}
{$i18n.label.subtotal}{$subtotals[$prev_grouped_by]['user']|escape}{$subtotals[$prev_grouped_by]['client']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$subtotals[$prev_grouped_by]['client']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$subtotals[$prev_grouped_by]['time']}{$subtotals[$prev_grouped_by]['units']}{$subtotals[$prev_grouped_by]['time']}{$subtotals[$prev_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}
 
 
{$item.date}{$item.user|escape}{$item.$control_name|escape}{$item.client|escape}{$item.project|escape}{$item.task|escape}{$item.$control_name|escape}{$item.start}{$item.finish}{$item.duration}{$item.units}{$item.note|escape}{if $user->can('manage_invoices') || $user->isClient()}{$item.cost}{else}{$item.expense}{/if}{if $item.approved == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $item.modified}{$item.modified_ip} {$item.modified}{else}{$item.created_ip} {$item.created}{/if}{$item.invoice|escape}{$item.timesheet_name|escape}{if $item.has_files}{$i18n.label.files}{/if}{if $item.has_files}{$i18n.label.files}{/if} {$i18n.label.edit}{$i18n.label.edit}
{$i18n.label.note} + {$item.note|escape}
{$i18n.label.subtotal}{$subtotals[$cur_grouped_by]['user']|escape}{$subtotals[$cur_grouped_by]['client']|escape}{$subtotals[$cur_grouped_by]['project']|escape}{$subtotals[$cur_grouped_by]['task']|escape}{$subtotals[$cur_grouped_by]['time']}{$subtotals[$cur_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$cur_grouped_by]['cost']}{else}{$subtotals[$cur_grouped_by]['expenses']}{/if}
 
{$i18n.label.total} + {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
{/if} {$forms.reportViewForm.close} diff --git a/default.css b/default.css index 48a3fb58a..533b3ff78 100644 --- a/default.css +++ b/default.css @@ -200,6 +200,11 @@ div.page-hint { text-align: right; } +/* cell containign a subtotal */ +.subtotal-cell { + font-weight: bold; +} + /* control labels for large screens */ .large-screen-label { text-align: right; diff --git a/initialize.php b/initialize.php index 40135a55a..44c2a02cd 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5525"); +define("APP_VERSION", "1.19.28.5526"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 05612acdd7987d0e3d15098ce197ea14284d0d46 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 7 May 2021 19:25:30 +0000 Subject: [PATCH 1541/1848] Made report.php mobile friendly. --- WEB-INF/templates/report.tpl | 331 ------------------------ WEB-INF/templates/report2.tpl | 306 ++-------------------- WEB-INF/templates/reports.tpl | 459 --------------------------------- WEB-INF/templates/reports2.tpl | 3 + default.css | 1 + initialize.php | 2 +- report.php | 14 +- report2.php | 313 ---------------------- 8 files changed, 35 insertions(+), 1394 deletions(-) delete mode 100644 WEB-INF/templates/report.tpl delete mode 100644 WEB-INF/templates/reports.tpl delete mode 100644 report2.php diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl deleted file mode 100644 index 02b59e9ef..000000000 --- a/WEB-INF/templates/report.tpl +++ /dev/null @@ -1,331 +0,0 @@ - - -{$forms.reportViewForm.open} - - - -
- - - - -
{$i18n.form.report.export} {if file_exists('WEB-INF/lib/tcpdf')}PDF,{/if} XML {$i18n.label.or} CSV
- - -{if $bean->getAttribute('chtotalsonly')} - - - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chcost')}{/if} - - {foreach $subtotals as $subtotal} - - - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chcost')}{/if} - - {/foreach} - - - - - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chcost')}{/if} - -{else} - - - - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - - {* user custom fileds *} - {if isset($custom_fields) && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} - - {* time custom fileds *} - {if isset($custom_fields) && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chstart')}{/if} - {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} - {if $bean->getAttribute('chapproved')}{/if} - {if $bean->getAttribute('chpaid')}{/if} - {if $bean->getAttribute('chip')}{/if} - {if $bean->getAttribute('chinvoice')}{/if} - {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')}{/if} - - {foreach $report_items as $item} - - {$cur_date = $item.date} - {if $print_subtotals} - {$cur_grouped_by = $item.grouped_by} - {if $cur_grouped_by != $prev_grouped_by && !$first_pass} - - {/if} - - {* user custom fileds *} - {if isset($custom_fields) && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} - - {* time custom fileds *} - {if isset($custom_fields) && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chstart')}{/if} - {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} - {if $bean->getAttribute('chapproved')}{/if} - {if $bean->getAttribute('chpaid')}{/if} - {if $bean->getAttribute('chip')}{/if} - {if $bean->getAttribute('chinvoice')}{/if} - {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')}{/if} - {if $use_checkboxes}{/if} - {* column for edit icons *} - - - {/if} - {$first_pass = false} - {/if} - - {if $cur_date != $prev_date} - {if $report_row_class == 'rowReportItem'} {$report_row_class = 'rowReportItemAlt'} {else} {$report_row_class = 'rowReportItem'} {/if} - {/if} - - - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - - {* user custom fileds *} - {if isset($custom_fields) && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - {assign var="control_name" value='user_field_'|cat:$userField['id']} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} - - {* time custom fileds *} - {if isset($custom_fields) && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chstart')}{/if} - {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} - {if $bean->getAttribute('chapproved')}{/if} - {if $bean->getAttribute('chpaid')}{/if} - {if $bean->getAttribute('chip')}{/if} - {if $bean->getAttribute('chinvoice')}{/if} - {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')} - {if 1 == $item.type}{/if} - {if 2 == $item.type}{/if} - {/if} - {if $use_checkboxes} - {if 1 == $item.type}{/if} - {if 2 == $item.type}{/if} - {/if} - {if $item.approved || $item.timesheet_id || $item.invoice_id} - - {else} - {if 1 == $item.type}{/if} - {if 2 == $item.type}{/if} - {/if} - - {if $note_on_separate_row && $bean->getAttribute('chnote') && $item.note} - - - - - {/if} - {$prev_date = $item.date} - {if $print_subtotals} {$prev_grouped_by = $item.grouped_by} {/if} - {/foreach} - - {if $print_subtotals} - - {/if} - - {* user custom fileds *} - {if isset($custom_fields) && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} - - {* time custom fileds *} - {if isset($custom_fields) && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chstart')}{/if} - {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} - {if $bean->getAttribute('chapproved')}{/if} - {if $bean->getAttribute('chpaid')}{/if} - {if $bean->getAttribute('chip')}{/if} - {if $bean->getAttribute('chinvoice')}{/if} - {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')}{/if} - {if $use_checkboxes}{/if} - {* column for edit icons *} - - {/if} - - - - - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - - {* user custom fileds *} - {if isset($custom_fields) && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} - - {* time custom fileds *} - {if isset($custom_fields) && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chstart')}{/if} - {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} - {if $bean->getAttribute('chapproved')}{/if} - {if $bean->getAttribute('chpaid')}{/if} - {if $bean->getAttribute('chip')}{/if} - {if $bean->getAttribute('chinvoice')}{/if} - {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')}{/if} - {if $use_checkboxes}{/if} - {* column for edit icons *} - -{/if} -
{$group_by_header|escape}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.cost}
{if $subtotal['name']}{$subtotal['name']|escape}{else} {/if}{$subtotal['time']}{$subtotal['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotal['cost']}{else}{$subtotal['expenses']}{/if}
 
{$i18n.label.total}{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
{$i18n.label.date}{$i18n.label.user}{{$userField['label']|escape}}{$i18n.label.client}{$i18n.label.project}{$i18n.label.task}{{$timeField['label']|escape}}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.note}{$i18n.label.cost}{$i18n.label.approved}{$i18n.label.paid}{$i18n.label.ip}{$i18n.label.invoice}{$i18n.label.timesheet}
{$i18n.label.subtotal} - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{$subtotals[$prev_grouped_by]['user']|escape}{$subtotals[$prev_grouped_by]['client']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$subtotals[$prev_grouped_by]['time']}{$subtotals[$prev_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}
 
{$item.date}{$item.user|escape}{$item.$control_name|escape}{$item.client|escape}{$item.project|escape}{$item.task|escape}{$item.$control_name|escape}{$item.start}{$item.finish}{$item.duration}{$item.units}{$item.note|escape}{if $user->can('manage_invoices') || $user->isClient()}{$item.cost}{else}{$item.expense}{/if}{if $item.approved == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $item.modified}{$item.modified_ip} {$item.modified}{else}{$item.created_ip} {$item.created}{/if}{$item.invoice|escape}{$item.timesheet_name|escape}{if $item.has_files}{$i18n.label.files}{/if}{if $item.has_files}{$i18n.label.files}{/if} {$i18n.label.edit}{$i18n.label.edit}
{$i18n.label.note}:{$item.note|escape}
{$i18n.label.subtotal} - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{$subtotals[$cur_grouped_by]['user']|escape}{$subtotals[$cur_grouped_by]['client']|escape}{$subtotals[$cur_grouped_by]['project']|escape}{$subtotals[$cur_grouped_by]['task']|escape}{$subtotals[$cur_grouped_by]['time']}{$subtotals[$cur_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$cur_grouped_by]['cost']}{else}{$subtotals[$cur_grouped_by]['expenses']}{/if}
 
{$i18n.label.total}{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
-
-{if $report_items && ($use_mark_approved || $use_mark_paid || $use_assign_to_invoice || $use_assign_to_timesheet)} - - {if $use_mark_approved} - - - - {/if} - {if $use_mark_paid} - - - - {/if} - {if $use_assign_to_invoice} - - - - {/if} - {if $use_assign_to_timesheet} - - - - {/if} -
- - -
{$i18n.label.mark_approved}: {$forms.reportViewForm.mark_approved_select_options.control} {$forms.reportViewForm.mark_approved_action_options.control} {$forms.reportViewForm.btn_mark_approved.control}
-
- - -
{$i18n.label.mark_paid}: {$forms.reportViewForm.mark_paid_select_options.control} {$forms.reportViewForm.mark_paid_action_options.control} {$forms.reportViewForm.btn_mark_paid.control}
-
- - -
{$i18n.form.report.assign_to_invoice}: {$forms.reportViewForm.assign_invoice_select_options.control} {$forms.reportViewForm.recent_invoice.control} {$forms.reportViewForm.btn_assign_invoice.control}
-
- - -
{$i18n.form.report.assign_to_timesheet}: {$forms.reportViewForm.assign_timesheet_select_options.control} {$forms.reportViewForm.timesheet.control} {$forms.reportViewForm.btn_assign_timesheet.control}
-
-{/if} -{$forms.reportViewForm.close} - - - - - -
- - - - -
-
diff --git a/WEB-INF/templates/report2.tpl b/WEB-INF/templates/report2.tpl index db065ac94..b66d86c05 100644 --- a/WEB-INF/templates/report2.tpl +++ b/WEB-INF/templates/report2.tpl @@ -247,310 +247,42 @@
{/if} -{$forms.reportViewForm.close} - - - - - - -{$forms.reportViewForm.open} - - - -
- - -{if $bean->getAttribute('chtotalsonly')} -{else} - - - - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - - {* user custom fileds *} - {if isset($custom_fields) && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} - - {* time custom fileds *} - {if isset($custom_fields) && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chstart')}{/if} - {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} - {if $bean->getAttribute('chapproved')}{/if} - {if $bean->getAttribute('chpaid')}{/if} - {if $bean->getAttribute('chip')}{/if} - {if $bean->getAttribute('chinvoice')}{/if} - {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')}{/if} - - {foreach $report_items as $item} - - {$cur_date = $item.date} - {if $print_subtotals} - {$cur_grouped_by = $item.grouped_by} - {if $cur_grouped_by != $prev_grouped_by && !$first_pass} - - {/if} - - {* user custom fileds *} - {if isset($custom_fields) && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} - - {* time custom fileds *} - {if isset($custom_fields) && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chstart')}{/if} - {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} - {if $bean->getAttribute('chapproved')}{/if} - {if $bean->getAttribute('chpaid')}{/if} - {if $bean->getAttribute('chip')}{/if} - {if $bean->getAttribute('chinvoice')}{/if} - {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')}{/if} - {if $use_checkboxes}{/if} - {* column for edit icons *} - - - {/if} - {$first_pass = false} - {/if} - - {if $cur_date != $prev_date} - {if $report_row_class == 'rowReportItem'} {$report_row_class = 'rowReportItemAlt'} {else} {$report_row_class = 'rowReportItem'} {/if} - {/if} - - - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - - {* user custom fileds *} - {if isset($custom_fields) && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - {assign var="control_name" value='user_field_'|cat:$userField['id']} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} - - {* time custom fileds *} - {if isset($custom_fields) && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chstart')}{/if} - {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} - {if $bean->getAttribute('chapproved')}{/if} - {if $bean->getAttribute('chpaid')}{/if} - {if $bean->getAttribute('chip')}{/if} - {if $bean->getAttribute('chinvoice')}{/if} - {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')} - {if 1 == $item.type}{/if} - {if 2 == $item.type}{/if} - {/if} - {if $use_checkboxes} - {if 1 == $item.type}{/if} - {if 2 == $item.type}{/if} - {/if} - {if $item.approved || $item.timesheet_id || $item.invoice_id} - - {else} - {if 1 == $item.type}{/if} - {if 2 == $item.type}{/if} - {/if} - - {if $note_on_separate_row && $bean->getAttribute('chnote') && $item.note} - - - - - {/if} - {$prev_date = $item.date} - {if $print_subtotals} {$prev_grouped_by = $item.grouped_by} {/if} - {/foreach} - - {if $print_subtotals} - - {/if} - - {* user custom fileds *} - {if isset($custom_fields) && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} - - {* time custom fileds *} - {if isset($custom_fields) && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chstart')}{/if} - {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} - {if $bean->getAttribute('chapproved')}{/if} - {if $bean->getAttribute('chpaid')}{/if} - {if $bean->getAttribute('chip')}{/if} - {if $bean->getAttribute('chinvoice')}{/if} - {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')}{/if} - {if $use_checkboxes}{/if} - {* column for edit icons *} - - {/if} - - - - - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - - {* user custom fileds *} - {if isset($custom_fields) && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chclient')}{/if} - {if $bean->getAttribute('chproject')}{/if} - {if $bean->getAttribute('chtask')}{/if} - - {* time custom fileds *} - {if isset($custom_fields) && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - {if $bean->getAttribute($checkbox_control_name)}{/if} - {/foreach} - {/if} - - {if $bean->getAttribute('chstart')}{/if} - {if $bean->getAttribute('chfinish')}{/if} - {if $bean->getAttribute('chduration')}{/if} - {if $bean->getAttribute('chunits')}{/if} - {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} - {if $bean->getAttribute('chapproved')}{/if} - {if $bean->getAttribute('chpaid')}{/if} - {if $bean->getAttribute('chip')}{/if} - {if $bean->getAttribute('chinvoice')}{/if} - {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')}{/if} - {if $use_checkboxes}{/if} - {* column for edit icons *} - -{/if} -
{$i18n.label.date}{$i18n.label.user}{{$userField['label']|escape}}{$i18n.label.client}{$i18n.label.project}{$i18n.label.task}{{$timeField['label']|escape}}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.note}{$i18n.label.cost}{$i18n.label.approved}{$i18n.label.paid}{$i18n.label.ip}{$i18n.label.invoice}{$i18n.label.timesheet}
{$i18n.label.subtotal} - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{$subtotals[$prev_grouped_by]['user']|escape}{$subtotals[$prev_grouped_by]['client']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$subtotals[$prev_grouped_by]['time']}{$subtotals[$prev_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}
 
{$item.date}{$item.user|escape}{$item.$control_name|escape}{$item.client|escape}{$item.project|escape}{$item.task|escape}{$item.$control_name|escape}{$item.start}{$item.finish}{$item.duration}{$item.units}{$item.note|escape}{if $user->can('manage_invoices') || $user->isClient()}{$item.cost}{else}{$item.expense}{/if}{if $item.approved == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $item.modified}{$item.modified_ip} {$item.modified}{else}{$item.created_ip} {$item.created}{/if}{$item.invoice|escape}{$item.timesheet_name|escape}{if $item.has_files}{$i18n.label.files}{/if}{if $item.has_files}{$i18n.label.files}{/if} {$i18n.label.edit}{$i18n.label.edit}
{$i18n.label.note}:{$item.note|escape}
{$i18n.label.subtotal} - {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{$subtotals[$cur_grouped_by]['user']|escape}{$subtotals[$cur_grouped_by]['client']|escape}{$subtotals[$cur_grouped_by]['project']|escape}{$subtotals[$cur_grouped_by]['task']|escape}{$subtotals[$cur_grouped_by]['time']}{$subtotals[$cur_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$cur_grouped_by]['cost']}{else}{$subtotals[$cur_grouped_by]['expenses']}{/if}
 
{$i18n.label.total}{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}
-
{if $report_items && ($use_mark_approved || $use_mark_paid || $use_assign_to_invoice || $use_assign_to_timesheet)} - +
+
{if $use_mark_approved} + - + + + {/if} {if $use_mark_paid} + - + + + {/if} {if $use_assign_to_invoice} + - + + + {/if} {if $use_assign_to_timesheet} + - + + + {/if}
{$forms.reportViewForm.mark_approved_select_options.control}
- - -
{$i18n.label.mark_approved}: {$forms.reportViewForm.mark_approved_select_options.control} {$forms.reportViewForm.mark_approved_action_options.control} {$forms.reportViewForm.btn_mark_approved.control}
-
{$forms.reportViewForm.mark_approved_action_options.control} {$forms.reportViewForm.btn_mark_approved.control}
{$forms.reportViewForm.mark_paid_select_options.control}
- - -
{$i18n.label.mark_paid}: {$forms.reportViewForm.mark_paid_select_options.control} {$forms.reportViewForm.mark_paid_action_options.control} {$forms.reportViewForm.btn_mark_paid.control}
-
{$forms.reportViewForm.mark_paid_action_options.control} {$forms.reportViewForm.btn_mark_paid.control}
{$forms.reportViewForm.assign_invoice_select_options.control}
- - -
{$i18n.form.report.assign_to_invoice}: {$forms.reportViewForm.assign_invoice_select_options.control} {$forms.reportViewForm.recent_invoice.control} {$forms.reportViewForm.btn_assign_invoice.control}
-
{$forms.reportViewForm.recent_invoice.control} {$forms.reportViewForm.btn_assign_invoice.control}
{$forms.reportViewForm.assign_timesheet_select_options.control}
- - -
{$i18n.form.report.assign_to_timesheet}: {$forms.reportViewForm.assign_timesheet_select_options.control} {$forms.reportViewForm.timesheet.control} {$forms.reportViewForm.btn_assign_timesheet.control}
-
{$forms.reportViewForm.timesheet.control} {$forms.reportViewForm.btn_assign_timesheet.control}
{/if} {$forms.reportViewForm.close} - - - - - -
- - - - -
-
+
diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl deleted file mode 100644 index 248584f5b..000000000 --- a/WEB-INF/templates/reports.tpl +++ /dev/null @@ -1,459 +0,0 @@ - - -{$forms.reportForm.open} -
- - - - -
- - - - - -
{$i18n.label.fav_report}:{$forms.reportForm.favorite_report.control}{$forms.reportForm.btn_generate.control} {$forms.reportForm.btn_delete.control}
-
-
- - - - - -
- - - - - - -{if $show_active_users} - - - - - - -{/if} -{if $show_inactive_users} - - - - - - -{/if} - - - - - - - - - - - - - - - - - - - -{if isset($custom_fields) && $custom_fields->timeFields} - - {foreach $custom_fields->timeFields as $timeField} - - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} - - - - {/foreach} -{/if} -{if isset($custom_fields) && $custom_fields->userFields} - - {foreach $custom_fields->userFields as $userField} - - - {assign var="control_name" value='user_field_'|cat:$userField['id']} - {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} - - - - {/foreach} -{/if} - - - - - - - - - -
- -{if $show_client} - - -{/if} -{if $show_project} - - -{/if} -{if $show_billable} - - -{/if} -{if $show_paid_status} - - -{/if} -
{$i18n.label.client}
{$forms.reportForm.client.control}
{$i18n.label.project}
{$forms.reportForm.project.control}
{$i18n.form.time.billable}
{$forms.reportForm.include_records.control}
{$i18n.label.paid_status}
{$forms.reportForm.paid_status.control}
-
- -{if $show_task} - - -{/if} -{if $show_approved} - - -{/if} -{if $show_invoice_dropdown} - - -{/if} -{if $show_timesheet_dropdown} - - -{/if} -
{$i18n.label.task}
{$forms.reportForm.task.control}
{$i18n.label.approved}
{$forms.reportForm.approved.control}
{$i18n.label.invoice}
{$forms.reportForm.invoice.control}
{$i18n.label.timesheet}
{$forms.reportForm.timesheet.control}
-
{if $show_inactive_users}{$i18n.label.active_users}{else}{$i18n.label.users}{/if}
{$forms.reportForm.users_active.control}
{$i18n.label.inactive_users}
{$forms.reportForm.users_inactive.control}
{$i18n.form.reports.select_period} {$i18n.form.reports.set_period}
{$forms.reportForm.period.control}{$i18n.label.start_date}:{$forms.reportForm.start_date.control}
{$i18n.label.end_date}:{$forms.reportForm.end_date.control}
{$i18n.form.reports.show_fields}
- - - - - - - -
- -{if $show_client} - -{/if} -{if $show_project} - -{/if} -{if $show_timesheet_checkbox} - -{/if} -
-
- -{if $show_start} - -{/if} -{if $show_task} - -{/if} -{if $show_ip} - -{/if} -{if $show_work_units} - -{/if} -
-
- -{if $show_finish} - -{/if} - -{if $show_approved} - -{/if} -{if $show_invoice_checkbox} - -{/if} -
-
- - - -{if $show_paid_status} - -{/if} -{if $show_files} - -{/if} -
-
-
{$i18n.form.reports.time_fields}
{$timeField['label']|escape}:{$forms.reportForm.$control_name.control}{$forms.reportForm.$checkbox_control_name.control}
{$i18n.form.reports.user_fields}
{$userField['label']|escape}:{$forms.reportForm.$control_name.control}{$forms.reportForm.$checkbox_control_name.control}
{$i18n.form.reports.group_by}
{$forms.reportForm.group_by1.control}{$forms.reportForm.group_by2.control}{$forms.reportForm.group_by3.control}
- -
- - - - -
- - - - - -
{$i18n.form.reports.save_as_favorite}:{$forms.reportForm.new_fav_report.control}{$forms.reportForm.btn_save.control}
-
-
- - - -
{$forms.reportForm.btn_generate.control}
-
-{$forms.reportForm.close} diff --git a/WEB-INF/templates/reports2.tpl b/WEB-INF/templates/reports2.tpl index 3f272e112..294d5ea7c 100644 --- a/WEB-INF/templates/reports2.tpl +++ b/WEB-INF/templates/reports2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + @@ -64,6 +67,8 @@ {if $bean->getAttribute('chinvoice')}
{$i18n.label.invoice}{$i18n.label.timesheet}
 
 
  {$i18n.label.edit}{$i18n.label.edit}
 
 
{$i18n.label.total} {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}
{$i18n.label.note} + {$i18n.label.note} {$item.note|escape}
 
{$i18n.label.total} + {$i18n.label.total}
+ +{if $user_dropdown} + + + + + + +{/if} +{if $show_client} + + + + + + +{/if} +
{$forms.weekTimeForm.date.control}
{$forms.weekTimeForm.user.control}
{$forms.weekTimeForm.client.control}
+{$forms.weekTimeForm.close} + + + + +{$forms.weekTimeForm.open} + +{if $show_navigation} + + + +{/if} + + + + +
+ {$i18n.label.day_view} / {$i18n.label.week_view} +
+ +{if $user_dropdown} + + + + +{/if} +{if $show_client} + + + + +{/if} +{if $show_billable} + + + + +{/if} +{if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + + {/foreach} +{/if} +{if $show_project} + + + + +{/if} +{if $show_task} + + + + +{/if} +{if $show_week_note} + + + + +{/if} +
{$i18n.label.user}:{$forms.weekTimeForm.user.control}
{$i18n.label.client}{if $user->isOptionEnabled('client_required')} (*){/if}:{$forms.weekTimeForm.client.control}
 
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:{$forms.weekTimeForm.$control_name.control}
{$i18n.label.project} (*):{$forms.weekTimeForm.project.control}
{$i18n.label.task}{if $task_required} (*){/if}:{$forms.weekTimeForm.task.control}
{$i18n.label.week_note}:{$forms.weekTimeForm.note.control}
+
+ + +
{$forms.weekTimeForm.date.control}
+
+ + + + +
{$forms.weekTimeForm.week_durations.control}
+ + + + + + +
{$forms.weekTimeForm.btn_submit.control}
 
+ +{if $show_week_list} + + + + +
+{if $time_records} + + + + {if $show_client} + + {/if} + {if $show_project} + + {/if} + {if $show_task} + + {/if} + {if $show_start} + + + {/if} + + + {if $show_files} + + {/if} + + + + {foreach $time_records as $record} + + + {if $show_client} + + {/if} + {if $show_project} + + {/if} + {if $show_task} + + {/if} + {if $show_start} + + + {/if} + + + {if $show_files} + {if $record.has_files} + + {else} + + {/if} + {/if} + + + + {/foreach} +
{$i18n.label.date}{$i18n.label.client}{$i18n.label.project}{$i18n.label.task}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.note}
{$record.date}{$record.client|escape}{$record.project|escape}{$record.task|escape}{if $record.start}{$record.start}{else} {/if}{if $record.finish}{$record.finish}{else} {/if}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}{if $record.comment}{$record.comment|escape}{else} {/if}{$i18n.label.files}{$i18n.label.files} + {if $record.approved || $record.timesheet_id || $record.invoice_id} +   + {else} + {$i18n.label.edit} + {/if} + + {if $record.approved || $record.timesheet_id || $record.invoice_id} +   + {else} + {$i18n.label.delete} + {/if} +
+{/if} +
+{/if} + +{if $time_records} + + {if $show_week_list} + + + + + {/if} + {if $user->isPluginEnabled('mq')} + + + {if $over_quota} + + {else} + + {/if} + + {/if} +
{$i18n.label.week_total}: {$week_total}
{$i18n.label.month_total}: {$month_total}{$i18n.form.time.over_quota}: {$quota_remaining}{$i18n.form.time.remaining_quota}: {$quota_remaining}
+{/if} +{$forms.weekTimeForm.close} diff --git a/initialize.php b/initialize.php index e7773d3d7..14c04798b 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5530"); +define("APP_VERSION", "1.19.28.5531"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/week2.php b/week2.php new file mode 100644 index 000000000..f97a515dc --- /dev/null +++ b/week2.php @@ -0,0 +1,559 @@ +isPluginEnabled('wv')) { + header('Location: feature_disabled.php'); + exit(); +} +if ($user->behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { + header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. + exit(); +} +if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. + exit(); +} +if ($request->isPost()) { + $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { + header('Location: access_denied.php'); // User changed, but no right or wrong user id. + exit(); + } +} +// End of access checks. + +// Determine user for whom we display this page. +if ($request->isPost() && $userChanged) { + $user_id = (int)$request->getParameter('user'); + $user->setOnBehalfUser($user_id); +} else { + $user_id = $user->getUser(); +} + +$group_id = $user->getGroup(); + +$showClient = $user->isPluginEnabled('cl'); +$showBillable = $user->isPluginEnabled('iv'); +$trackingMode = $user->getTrackingMode(); +$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; +$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $user->getConfigOption('task_required'); +$showWeekNote = $user->isOptionEnabled('week_note'); +$showWeekNotes = $user->isOptionEnabled('week_notes'); +$recordType = $user->getRecordType(); +$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; +$showFiles = $user->isPluginEnabled('at'); + +// Initialize and store date in session. +$cl_date = $request->getParameter('date', @$_SESSION['date']); +$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); +if($selected_date->isError()) + $selected_date = new DateAndTime(DB_DATEFORMAT); +if(!$cl_date) + $cl_date = $selected_date->toString(DB_DATEFORMAT); +$_SESSION['date'] = $cl_date; + +// Determine selected week start and end dates. +$weekStartDay = $user->getWeekStart(); +$t_arr = localtime($selected_date->getTimestamp()); +$t_arr[5] = $t_arr[5] + 1900; +if ($t_arr[6] < $weekStartDay) + $startWeekBias = $weekStartDay - 7; +else + $startWeekBias = $weekStartDay; +$startDate = new DateAndTime(); +$startDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+$startWeekBias,$t_arr[5])); +$endDate = new DateAndTime(); +$endDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+6+$startWeekBias,$t_arr[5])); +// The above is needed to set date range (timestring) in page title. + +// Use custom fields plugin if it is enabled. +if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + $smarty->assign('custom_fields', $custom_fields); +} + +// Use Monthly Quotas plugin, if applicable. +if ($user->isPluginEnabled('mq')){ + require_once('plugins/MonthlyQuota.class.php'); + $quota = new MonthlyQuota(); + $month_quota_minutes = $quota->getUserQuota($selected_date->mYear, $selected_date->mMonth); + $month_total = ttTimeHelper::getTimeForMonth($selected_date); + $minutes_left = $month_quota_minutes - ttTimeHelper::toMinutes($month_total); + + $smarty->assign('month_total', $month_total); + $smarty->assign('over_quota', $minutes_left < 0); + $smarty->assign('quota_remaining', ttTimeHelper::toAbsDuration($minutes_left)); +} + +// Initialize variables. +$cl_billable = 1; +if ($showBillable) { + if ($request->isPost()) { + $cl_billable = $request->getParameter('billable'); + $_SESSION['billable'] = (int) $cl_billable; + } else + if (isset($_SESSION['billable'])) + $cl_billable = $_SESSION['billable']; +} +$cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); +$_SESSION['client'] = $cl_client; +$cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); +$_SESSION['project'] = $cl_project; +$cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); +$_SESSION['task'] = $cl_task; +$cl_note = $request->getParameter('note', ($request->isPost() ? null : @$_SESSION['note'])); +$_SESSION['note'] = $cl_note; + +$timeCustomFields = array(); +// If we have time custom fields - collect input. +if ($request->isPost()) { + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } +} + +// Get the data we need to display week view. +// Get column headers, which are day numbers in month. +$dayHeaders = ttWeekViewHelper::getDayHeadersForWeek($startDate->toString(DB_DATEFORMAT)); +$lockedDays = ttWeekViewHelper::getLockedDaysForWeek($startDate->toString(DB_DATEFORMAT)); +// Get already existing records. +$records = ttWeekViewHelper::getRecordsForInterval($startDate->toString(DB_DATEFORMAT), $endDate->toString(DB_DATEFORMAT), $showFiles); +// Build data array for the table. Format is described in ttWeekViewHelper::getDataForWeekView function. +if ($records) + $dataArray = ttWeekViewHelper::getDataForWeekView($records, $dayHeaders); +else + $dataArray = ttWeekViewHelper::prePopulateFromPastWeeks($startDate->toString(DB_DATEFORMAT), $dayHeaders); + +// Build day totals (total durations for each day in week). +$dayTotals = ttWeekViewHelper::getDayTotals($dataArray, $dayHeaders); + +// Define rendering class for a label field to the left of durations. +class LabelCellRenderer extends DefaultCellRenderer { + function render(&$table, $value, $row, $column, $selected = false) { + global $user; + $showNotes = $user->isOptionEnabled('week_notes'); + + $this->setOptions(array('width'=>200,'valign'=>'middle')); + + // Special handling for a new week entry (row 0, or 0 and 1 if we show notes). + if (0 == $row) { + $this->setOptions(array('style'=>'text-align: center; font-weight: bold; vertical-align: top;')); + } else if ($showNotes && (1 == $row)) { + $this->setOptions(array('style'=>'text-align: right; vertical-align: top;')); + } else if ($showNotes && (0 != $row % 2)) { + $this->setOptions(array('style'=>'text-align: right;')); + } + // Special handling for not billable entries. + $ignoreRow = $showNotes ? 1 : 0; + if ($row > $ignoreRow) { + $row_id = $table->getValueAtName($row,'row_id'); + $billable = ttWeekViewHelper::parseFromWeekViewRow($row_id, 'bl'); + if (!$billable) { + if (($showNotes && (0 == $row % 2)) || !$showNotes) { + $this->setOptions(array('style'=>'color: red;')); // TODO: style it properly in CSS. + } + } + } + $this->setValue(htmlspecialchars($value)); // This escapes HTML for output. + return $this->toString(); + } +} + +// Define rendering class for a single cell for a time or a comment entry in week view table. +class WeekViewCellRenderer extends DefaultCellRenderer { + function render(&$table, $value, $row, $column, $selected = false) { + global $user; + $showNotes = $user->isOptionEnabled('week_notes'); + + $field_name = $table->getValueAt($row,$column)['control_id']; // Our text field names (and ids) are like x_y (row_column). + $field = new TextField($field_name); + // Disable control if the date is locked. + global $lockedDays; + if ($lockedDays[$column-1]) + $field->setEnabled(false); + $field->setFormName($table->getFormName()); + $field->setStyle('width: 60px;'); // TODO: need to style everything properly, eventually. + // Provide visual separation for new entry row. + $rowToSeparate = $showNotes ? 1 : 0; + if ($rowToSeparate == $row) { + $field->setStyle('width: 60px; margin-bottom: 40px'); + } + if ($showNotes) { + if (0 == $row % 2) { + $field->setValue($table->getValueAt($row,$column)['duration']); // Duration for even rows. + } else { + $field->setValue($table->getValueAt($row,$column)['note']); // Comment for odd rows. + $field->setTitle($table->getValueAt($row,$column)['note']); // Tooltip to help view the entire comment. + } + } else { + $field->setValue($table->getValueAt($row,$column)['duration']); + // $field->setTitle($table->getValueAt($row,$column)['note']); // Tooltip to see comment. TODO - value not available. + } + // Disable control when time entry mode is TYPE_START_FINISH and there is no value in control + // because we can't supply start and finish times in week view - there are no fields for them. + if (!$field->getValue() && TYPE_START_FINISH == $user->getRecordType()) { + $field->setEnabled(false); + } + $this->setValue($field->getHtml()); + return $this->toString(); + } +} + +// Elements of weekTimeForm. +$form = new Form('weekTimeForm'); +$largeScreenCalendarRowSpan = 1; // Number of rows calendar spans on large screens. + +if ($user->can('track_time')) { + $rank = $user->getMaxRankForGroup($group_id); + if ($user->can('track_own_time')) + $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); + else + $options = array('status'=>ACTIVE,'max_rank'=>$rank); + $user_list = $user->getUsers($options); + if (count($user_list) >= 1) { + $form->addInput(array('type'=>'combobox', + 'onchange'=>'document.weekTimeForm.user_changed.value=1;document.weekTimeForm.submit();', + 'name'=>'user', + 'style'=>'width: 250px;', + 'value'=>$user_id, + 'data'=>$user_list, + 'datakeys'=>array('id','name'))); + $form->addInput(array('type'=>'hidden','name'=>'user_changed')); + $largeScreenCalendarRowSpan += 2; + $smarty->assign('user_dropdown', 1); + } +} + +// Create week_durations table. +$table = new Table('week_durations'); +// $table->setCssClass('week_view_table'); // Currently not used. Fix this. +$table->setTableOptions(array('width'=>'100%','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); +$table->setRowOptions(array('class'=>'tableHeaderCentered')); +$table->setData($dataArray); +// Add columns to table. +$table->addColumn(new TableColumn('label', '', new LabelCellRenderer(), $dayTotals['label'])); +for ($i = 0; $i < 7; $i++) { + $table->addColumn(new TableColumn($dayHeaders[$i], $dayHeaders[$i], new WeekViewCellRenderer(), $dayTotals[$dayHeaders[$i]])); +} +$table->setInteractive(false); +$form->addInputElement($table); + +// Dropdown for clients in MODE_TIME. Use all active clients. +if (MODE_TIME == $trackingMode && $showClient) { + $active_clients = ttGroupHelper::getActiveClients(true); + $form->addInput(array('type'=>'combobox', + 'onchange'=>'fillProjectDropdown(this.value);', + 'name'=>'client', + 'style'=>'width: 250px;', + 'value'=>$cl_client, + 'data'=>$active_clients, + 'datakeys'=>array('id', 'name'), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + $largeScreenCalendarRowSpan += 2; + // Note: in other modes the client list is filtered to relevant clients only. See below. +} + +// Billable checkbox. +if ($user->isPluginEnabled('iv')) + $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); + +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'style'=>'width: 250px;', + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } + } +} + +// If we show project dropdown, add controls for project and client. +if ($showProject) { + // Dropdown for projects assigned to user. + $project_list = $user->getAssignedProjects(); + $form->addInput(array('type'=>'combobox', + 'onchange'=>'fillTaskDropdown(this.value);', + 'name'=>'project', + 'style'=>'width: 250px;', + 'value'=>$cl_project, + 'data'=>$project_list, + 'datakeys'=>array('id','name'), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + + // Dropdown for clients if the clients plugin is enabled. + if ($showClient) { + $active_clients = ttGroupHelper::getActiveClients(true); + // We need an array of assigned project ids to do some trimming. + foreach($project_list as $project) + $projects_assigned_to_user[] = $project['id']; + + // Build a client list out of active clients. Use only clients that are relevant to user. + // Also trim their associated project list to only assigned projects (to user). + foreach($active_clients as $client) { + $projects_assigned_to_client = explode(',', $client['projects']); + if (is_array($projects_assigned_to_client) && is_array($projects_assigned_to_user)) + $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); + if ($intersection) { + $client['projects'] = implode(',', $intersection); + $client_list[] = $client; + } + } + $form->addInput(array('type'=>'combobox', + 'onchange'=>'fillProjectDropdown(this.value);', + 'name'=>'client', + 'style'=>'width: 250px;', + 'value'=>$cl_client, + 'data'=>$client_list, + 'datakeys'=>array('id', 'name'), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } +} + +// Task dropdown. +if ($showTask) { + $task_list = ttGroupHelper::getActiveTasks(); + $form->addInput(array('type'=>'combobox', + 'name'=>'task', + 'style'=>'width: 250px;', + 'value'=>$cl_task, + 'data'=>$task_list, + 'datakeys'=>array('id','name'), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); +} + +// Week note control. +if ($showWeekNote) { + if (!defined('NOTE_INPUT_HEIGHT')) + define('NOTE_INPUT_HEIGHT', 40); + $form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_note)); +} + +// Calendar. +$form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); + +// A hidden control for today's date from user's browser. +$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'get_date()')); // User current date, which gets filled in on btn_submit click. + +// Submit button. +$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); + +// Submit. +if ($request->isPost()) { + if ($request->getParameter('btn_submit')) { + // Validate user input for row 0. + // Determine if a new entry was posted. + $newEntryPosted = false; + foreach($dayHeaders as $dayHeader) { + $control_id = '0_'.$dayHeader; + if ($request->getParameter($control_id)) { + $newEntryPosted = true; + break; + } + } + if ($newEntryPosted) { + if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) + $err->add($i18n->get('error.client')); + // Validate input in time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($timeCustomFields as $timeField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); + } + } + if ($showProject) { + if (!$cl_project) $err->add($i18n->get('error.project')); + } + if ($showTask && $taskRequired) { + if (!$cl_task) $err->add($i18n->get('error.task')); + } + } + // Finished validating user input for row 0. + + // Process the table of values. + if ($err->no()) { + + // Obtain values. Iterate through posted parameters one by one, + // see if value changed, apply one change at a time until we see an error. + $result = true; + $rowNumber = 0; + // Iterate through existing rows. + foreach ($dataArray as $row) { + // Iterate through days. + foreach ($dayHeaders as $key => $dayHeader) { + // Do not process locked days. + if ($lockedDays[$key]) continue; + // Make control id for the cell. + $control_id = $rowNumber.'_'.$dayHeader; + + // Handle durations and comments in separate blocks of code. + if (!$showWeekNotes || (0 == $rowNumber % 2)) { + // Handle durations row here. + + // Obtain existing and posted durations. + $postedDuration = $request->getParameter($control_id); + $existingDuration = $dataArray[$rowNumber][$dayHeader]['duration']; + // If posted value is not null, check and normalize it. + if ($postedDuration) { + if (false === ttTimeHelper::postedDurationToMinutes($postedDuration)) { + $err->add($i18n->get('error.field'), $i18n->get('label.duration')); + $result = false; break; // Break out. Stop any further processing. + } else { + $minutes = ttTimeHelper::postedDurationToMinutes($postedDuration); + $postedDuration = ttTimeHelper::minutesToDuration($minutes); + } + } + // Do not process if value has not changed. + if ($postedDuration == $existingDuration) + continue; + // Posted value is different. + if ($existingDuration == null) { + // Skip inserting 0 duration values. + if (0 == ttTimeHelper::toMinutes($postedDuration)) + continue; + // Insert a new record. + $fields = array(); + $fields['row_id'] = $dataArray[$rowNumber]['row_id']; + if (!$fields['row_id']) { + // Special handling for row 0, a new entry. Need to construct new row_id. + $record = array(); + $record['client_id'] = $cl_client; + $record['billable'] = $cl_billable ? '1' : '0'; + $record['project_id'] = $cl_project; + $record['task_id'] = $cl_task; + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) + $record[$field_name] = $timeCustomFields[$timeField['id']]['value']; + else if ($timeField['type'] == CustomFields::TYPE_DROPDOWN) + $record[$field_name.'_option_id'] = $timeCustomFields[$timeField['id']]['value']; + } + } + $fields['row_id'] = ttWeekViewHelper::makeRowIdentifier($record).'_0'; + // Note: no need to check for a possible conflict with an already existing row + // because we are doing an insert that does not affect already existing data. + + if ($showWeekNote) { + $fields['note'] = $request->getParameter('note'); + } + } + $fields['day_header'] = $dayHeader; + $fields['start_date'] = $startDate->toString(DB_DATEFORMAT); // To be able to determine date for the entry using $dayHeader. + $fields['duration'] = $postedDuration; + $fields['browser_today'] = $request->getParameter('browser_today', null); + if ($showWeekNotes) { + // Take note value from the control below duration. + $noteRowNumber = $rowNumber + 1; + $note_control_id = $noteRowNumber.'_'.$dayHeader; + $fields['note'] = $request->getParameter($note_control_id); + } + $result = ttWeekViewHelper::insertDurationFromWeekView($fields, $custom_fields, $err); + } elseif ($postedDuration == null || 0 == ttTimeHelper::toMinutes($postedDuration)) { + // Delete an already existing record here. + $result = ttTimeHelper::delete($dataArray[$rowNumber][$dayHeader]['tt_log_id']); + } else { + $fields = array(); + $fields['tt_log_id'] = $dataArray[$rowNumber][$dayHeader]['tt_log_id']; + $fields['duration'] = $postedDuration; + $result = ttWeekViewHelper::modifyDurationFromWeekView($fields, $err); + } + if (!$result) break; // Break out of the loop in case of first error. + + } else if ($showWeekNotes) { + // Handle commments row here. + + // Obtain existing and posted comments. + $postedComment = $request->getParameter($control_id); + $existingComment = $dataArray[$rowNumber][$dayHeader]['note']; + // If posted value is not null, check it. + if ($postedComment && !ttValidString($postedComment, true)) { + $err->add($i18n->get('error.field'), $i18n->get('label.note')); + $result = false; break; // Break out. Stop any further processing. + } + // Do not process if value has not changed. + if ($postedComment == $existingComment) + continue; + + // Posted value is different. + // TODO: handle new entries separately in the durations block above. + + // Here, only update the comment on an already existing record. + $fields = array(); + $fields['tt_log_id'] = $dataArray[$rowNumber][$dayHeader]['tt_log_id']; + if ($fields['tt_log_id']) { + $fields['comment'] = $postedComment; + $result = ttWeekViewHelper::modifyCommentFromWeekView($fields); + } + if (!$result) break; // Break out of the loop on first error. + } + } + if (!$result) break; // Break out of the loop on first error. + $rowNumber++; + } + if ($result) { + header('Location: week.php'); // Normal exit. + exit(); + } + } + } +} // isPost + +$week_total = ttTimeHelper::getTimeForWeek($selected_date); + +$smarty->assign('large_screen_calendar_row_span', $largeScreenCalendarRowSpan); +$smarty->assign('selected_date', $selected_date); +$smarty->assign('week_total', $week_total); +$smarty->assign('client_list', $client_list); +$smarty->assign('project_list', $project_list); +$smarty->assign('task_list', $task_list); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="fillDropdowns()"'); +$smarty->assign('timestring', $startDate->toString($user->date_format).' - '.$endDate->toString($user->date_format)); +$smarty->assign('time_records', $records); +$smarty->assign('show_navigation', !$user->isOptionEnabled('week_menu')); +$smarty->assign('show_client', $showClient); +$smarty->assign('show_billable', $showBillable); +$smarty->assign('show_project', $showProject); +$smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); +$smarty->assign('show_week_note', $showWeekNote); +$smarty->assign('show_week_list', $user->isOptionEnabled('week_list')); +$smarty->assign('show_start', $showStart); +$smarty->assign('show_files', $showFiles); +$smarty->assign('title', $i18n->get('menu.week')); +$smarty->assign('content_page_name', 'week2.tpl'); +$smarty->display('index2.tpl'); From e7ec5231bd04c2d5cc430746cac8572c06bc1653 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 May 2021 13:43:14 +0000 Subject: [PATCH 1546/1848] A bit more progress towards making week view mobile friendly. --- WEB-INF/templates/week2.tpl | 42 +++++++++++++++++++++++++++++++++++++ default.css | 4 ++-- initialize.php | 2 +- time.php | 4 +++- week2.php | 27 ++++++++++++------------ 5 files changed, 61 insertions(+), 18 deletions(-) diff --git a/WEB-INF/templates/week2.tpl b/WEB-INF/templates/week2.tpl index b46e9804f..b09a11988 100644 --- a/WEB-INF/templates/week2.tpl +++ b/WEB-INF/templates/week2.tpl @@ -51,6 +51,48 @@ function fillDropdowns() {
 
{$forms.weekTimeForm.$control_name.control}
{$forms.weekTimeForm.project.control}
{$forms.weekTimeForm.task.control}
{$forms.weekTimeForm.week_note.control}
{$forms.weekTimeForm.close} diff --git a/default.css b/default.css index e04cab3d5..48cd2c4e8 100644 --- a/default.css +++ b/default.css @@ -363,7 +363,7 @@ input[type="text"].short-text-field { } /* textareas for fields */ -#description, #address, #item_name, #comment, #custom_css, #content { +#description, #address, #item_name, #comment, #custom_css, #content, #week_note { width: 220px; border-radius: 4px; border: 1px solid #c9c9c9; @@ -371,7 +371,7 @@ input[type="text"].short-text-field { } /* textareas with focus */ -#description:focus, #address:focus, #item_name:focus, #comment:focus, #custom_css:focus, #content:focus { +#description:focus, #address:focus, #item_name:focus, #comment:focus, #custom_css:focus, #content:focus, #week_note:focus { background-color: yellow; border: 1px solid black; outline: none; diff --git a/initialize.php b/initialize.php index 14c04798b..09214a387 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5531"); +define("APP_VERSION", "1.19.28.5532"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index d96c497e3..9b366b543 100644 --- a/time.php +++ b/time.php @@ -192,8 +192,10 @@ } // Billable checkbox. -if ($showBillable) +if ($showBillable) { $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); + $largeScreenCalendarRowSpan += 2; +} // If we have time custom fields - add controls for them. if (isset($custom_fields) && $custom_fields->timeFields) { diff --git a/week2.php b/week2.php index f97a515dc..6fccba9cd 100644 --- a/week2.php +++ b/week2.php @@ -121,8 +121,8 @@ $_SESSION['project'] = $cl_project; $cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; -$cl_note = $request->getParameter('note', ($request->isPost() ? null : @$_SESSION['note'])); -$_SESSION['note'] = $cl_note; +$cl_note = $request->getParameter('week_note', ($request->isPost() ? null : @$_SESSION['week_note'])); +$_SESSION['week_note'] = $cl_note; $timeCustomFields = array(); // If we have time custom fields - collect input. @@ -242,7 +242,6 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'document.weekTimeForm.user_changed.value=1;document.weekTimeForm.submit();', 'name'=>'user', - 'style'=>'width: 250px;', 'value'=>$user_id, 'data'=>$user_list, 'datakeys'=>array('id','name'))); @@ -272,7 +271,6 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', - 'style'=>'width: 250px;', 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), @@ -282,22 +280,24 @@ function render(&$table, $value, $row, $column, $selected = false) { } // Billable checkbox. -if ($user->isPluginEnabled('iv')) +if ($showBillable) { $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); + $largeScreenCalendarRowSpan += 2; +} // If we have time custom fields - add controls for them. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); + $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$timeCustomFields[$timeField['id']]['value'])); } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', 'data'=>CustomFields::getOptions($timeField['id']), 'value'=>$timeCustomFields[$timeField['id']]['value'], 'empty'=>array(''=>$i18n->get('dropdown.select')))); } + $largeScreenCalendarRowSpan += 2; } } @@ -308,11 +308,11 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillTaskDropdown(this.value);', 'name'=>'project', - 'style'=>'width: 250px;', 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); + $largeScreenCalendarRowSpan += 2; // Dropdown for clients if the clients plugin is enabled. if ($showClient) { @@ -335,11 +335,11 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', - 'style'=>'width: 250px;', 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); + $largeScreenCalendarRowSpan += 2; } } @@ -348,18 +348,17 @@ function render(&$table, $value, $row, $column, $selected = false) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', - 'style'=>'width: 250px;', 'value'=>$cl_task, 'data'=>$task_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); + $largeScreenCalendarRowSpan += 2; } // Week note control. if ($showWeekNote) { - if (!defined('NOTE_INPUT_HEIGHT')) - define('NOTE_INPUT_HEIGHT', 40); - $form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_note)); + $form->addInput(array('type'=>'textarea','name'=>'week_note','value'=>$cl_note)); + $largeScreenCalendarRowSpan += 2; } // Calendar. @@ -468,7 +467,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // because we are doing an insert that does not affect already existing data. if ($showWeekNote) { - $fields['note'] = $request->getParameter('note'); + $fields['note'] = $request->getParameter('week_note'); } } $fields['day_header'] = $dayHeader; From d09c4858e797b620335255e38c84c9e423dc8e4c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 May 2021 15:57:52 +0000 Subject: [PATCH 1547/1848] Made week view mobile friendly. --- WEB-INF/templates/week2.tpl | 183 ++++++++++-------------------------- default.css | 4 +- initialize.php | 2 +- week.php | 39 ++++---- week2.php => week_old.php | 35 ++++--- 5 files changed, 90 insertions(+), 173 deletions(-) rename week2.php => week_old.php (96%) diff --git a/WEB-INF/templates/week2.tpl b/WEB-INF/templates/week2.tpl index b09a11988..7f77b0ad9 100644 --- a/WEB-INF/templates/week2.tpl +++ b/WEB-INF/templates/week2.tpl @@ -86,193 +86,108 @@ function fillDropdowns() {
{$forms.weekTimeForm.week_note.control}{$forms.weekTimeForm.comment.control}
-{$forms.weekTimeForm.close} - - - - -{$forms.weekTimeForm.open} - -{if $show_navigation} - - - -{/if} +
+
- {$i18n.label.day_view} / {$i18n.label.week_view} -
- - - -
- -{if $user_dropdown} - - - - -{/if} -{if $show_client} - - - - -{/if} -{if $show_billable} - - - - -{/if} -{if $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - - {/foreach} -{/if} -{if $show_project} - - - - -{/if} -{if $show_task} - - - - -{/if} -{if $show_week_note} - - - - -{/if} -
{$i18n.label.user}:{$forms.weekTimeForm.user.control}
{$i18n.label.client}{if $user->isOptionEnabled('client_required')} (*){/if}:{$forms.weekTimeForm.client.control}
 
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:{$forms.weekTimeForm.$control_name.control}
{$i18n.label.project} (*):{$forms.weekTimeForm.project.control}
{$i18n.label.task}{if $task_required} (*){/if}:{$forms.weekTimeForm.task.control}
{$i18n.label.week_note}:{$forms.weekTimeForm.note.control}
-
- - -
{$forms.weekTimeForm.date.control}
-
- -
{$forms.weekTimeForm.week_durations.control}
- - - - - - -
{$forms.weekTimeForm.btn_submit.control}
 
+
{$forms.weekTimeForm.btn_submit.control}
+{$forms.weekTimeForm.close} {if $show_week_list} - - - -
-{if $time_records} - - - +
+
{$i18n.label.date}
+ + {if $show_client} - + {/if} {if $show_project} - + {/if} {if $show_task} - + {/if} {if $show_start} - - + + {/if} - - + + {if $show_files} - + {/if} - - - + + + {foreach $time_records as $record} - - + + {if $show_client} - + {/if} {if $show_project} - + {/if} {if $show_task} - + {/if} {if $show_start} - - + + {/if} - - + + {if $show_files} {if $record.has_files} - + {else} - + {/if} {/if} - - + - + + {/foreach} -
{$i18n.label.date}{$i18n.label.client}{$i18n.label.client}{$i18n.label.project}{$i18n.label.project}{$i18n.label.task}{$i18n.label.task}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.note}{$i18n.label.duration}{$i18n.label.note}
{$record.date}
{$record.date}{$record.client|escape}{$record.client|escape}{$record.project|escape}{$record.project|escape}{$record.task|escape}{$record.task|escape}{if $record.start}{$record.start}{else} {/if}{if $record.finish}{$record.finish}{else} {/if}{if $record.start}{$record.start}{else} {/if}{if $record.finish}{$record.finish}{else} {/if}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}{if $record.comment}{$record.comment|escape}{else} {/if}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}{if $record.comment}{$record.comment|escape}{else} {/if}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files} + {if $record.approved || $record.timesheet_id || $record.invoice_id} -   +   {else} - {$i18n.label.edit} + {$i18n.label.edit} {/if} - + {if $record.approved || $record.timesheet_id || $record.invoice_id} -   +   {else} - {$i18n.label.delete} + {$i18n.label.delete} {/if} -
-{/if} -
{/if} - {if $time_records} - - {if $show_week_list} +
+
- - + + - {/if} {if $user->isPluginEnabled('mq')} - + {if $over_quota} - + {else} - + {/if} {/if}
{$i18n.label.week_total}: {$week_total}{$i18n.label.week_total}: {$week_total}
{$i18n.label.month_total}: {$month_total}{$i18n.label.month_total}: {$month_total}{$i18n.form.time.over_quota}: {$quota_remaining}{$i18n.form.time.over_quota}: {$quota_remaining}{$i18n.form.time.remaining_quota}: {$quota_remaining}{$i18n.form.time.remaining_quota}: {$quota_remaining}
{/if} -{$forms.weekTimeForm.close} diff --git a/default.css b/default.css index 48cd2c4e8..e04cab3d5 100644 --- a/default.css +++ b/default.css @@ -363,7 +363,7 @@ input[type="text"].short-text-field { } /* textareas for fields */ -#description, #address, #item_name, #comment, #custom_css, #content, #week_note { +#description, #address, #item_name, #comment, #custom_css, #content { width: 220px; border-radius: 4px; border: 1px solid #c9c9c9; @@ -371,7 +371,7 @@ input[type="text"].short-text-field { } /* textareas with focus */ -#description:focus, #address:focus, #item_name:focus, #comment:focus, #custom_css:focus, #content:focus, #week_note:focus { +#description:focus, #address:focus, #item_name:focus, #comment:focus, #custom_css:focus, #content:focus { background-color: yellow; border: 1px solid black; outline: none; diff --git a/initialize.php b/initialize.php index 09214a387..dc0c35452 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5532"); +define("APP_VERSION", "1.19.28.5533"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/week.php b/week.php index 01597704d..dbb61529a 100644 --- a/week.php +++ b/week.php @@ -121,8 +121,8 @@ $_SESSION['project'] = $cl_project; $cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; -$cl_note = $request->getParameter('note', ($request->isPost() ? null : @$_SESSION['note'])); -$_SESSION['note'] = $cl_note; +$cl_note = $request->getParameter('comment', ($request->isPost() ? null : @$_SESSION['comment'])); +$_SESSION['comment'] = $cl_note; $timeCustomFields = array(); // If we have time custom fields - collect input. @@ -229,6 +229,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Elements of weekTimeForm. $form = new Form('weekTimeForm'); +$largeScreenCalendarRowSpan = 1; // Number of rows calendar spans on large screens. if ($user->can('track_time')) { $rank = $user->getMaxRankForGroup($group_id); @@ -241,11 +242,11 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'document.weekTimeForm.user_changed.value=1;document.weekTimeForm.submit();', 'name'=>'user', - 'style'=>'width: 250px;', 'value'=>$user_id, 'data'=>$user_list, 'datakeys'=>array('id','name'))); $form->addInput(array('type'=>'hidden','name'=>'user_changed')); + $largeScreenCalendarRowSpan += 2; $smarty->assign('user_dropdown', 1); } } @@ -270,31 +271,33 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', - 'style'=>'width: 250px;', 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); + $largeScreenCalendarRowSpan += 2; // Note: in other modes the client list is filtered to relevant clients only. See below. } // Billable checkbox. -if ($user->isPluginEnabled('iv')) +if ($showBillable) { $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); + $largeScreenCalendarRowSpan += 2; +} // If we have time custom fields - add controls for them. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); + $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$timeCustomFields[$timeField['id']]['value'])); } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', 'data'=>CustomFields::getOptions($timeField['id']), 'value'=>$timeCustomFields[$timeField['id']]['value'], 'empty'=>array(''=>$i18n->get('dropdown.select')))); } + $largeScreenCalendarRowSpan += 2; } } @@ -305,11 +308,11 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillTaskDropdown(this.value);', 'name'=>'project', - 'style'=>'width: 250px;', 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); + $largeScreenCalendarRowSpan += 2; // Dropdown for clients if the clients plugin is enabled. if ($showClient) { @@ -332,11 +335,11 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', - 'style'=>'width: 250px;', 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); + $largeScreenCalendarRowSpan += 2; } } @@ -345,18 +348,17 @@ function render(&$table, $value, $row, $column, $selected = false) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', - 'style'=>'width: 250px;', 'value'=>$cl_task, 'data'=>$task_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); + $largeScreenCalendarRowSpan += 2; } // Week note control. if ($showWeekNote) { - if (!defined('NOTE_INPUT_HEIGHT')) - define('NOTE_INPUT_HEIGHT', 40); - $form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_note)); + $form->addInput(array('type'=>'textarea','name'=>'comment','value'=>$cl_note)); + $largeScreenCalendarRowSpan += 2; } // Calendar. @@ -465,7 +467,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // because we are doing an insert that does not affect already existing data. if ($showWeekNote) { - $fields['note'] = $request->getParameter('note'); + $fields['note'] = $request->getParameter('comment'); } } $fields['day_header'] = $dayHeader; @@ -476,7 +478,9 @@ function render(&$table, $value, $row, $column, $selected = false) { // Take note value from the control below duration. $noteRowNumber = $rowNumber + 1; $note_control_id = $noteRowNumber.'_'.$dayHeader; - $fields['note'] = $request->getParameter($note_control_id); + if ($request->getParameter($note_control_id)) { + $fields['note'] = $request->getParameter($note_control_id); // This overwrites week note. + } } $result = ttWeekViewHelper::insertDurationFromWeekView($fields, $custom_fields, $err); } elseif ($postedDuration == null || 0 == ttTimeHelper::toMinutes($postedDuration)) { @@ -531,6 +535,7 @@ function render(&$table, $value, $row, $column, $selected = false) { $week_total = ttTimeHelper::getTimeForWeek($selected_date); +$smarty->assign('large_screen_calendar_row_span', $largeScreenCalendarRowSpan); $smarty->assign('selected_date', $selected_date); $smarty->assign('week_total', $week_total); $smarty->assign('client_list', $client_list); @@ -551,5 +556,5 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('show_start', $showStart); $smarty->assign('show_files', $showFiles); $smarty->assign('title', $i18n->get('menu.week')); -$smarty->assign('content_page_name', 'week.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'week2.tpl'); +$smarty->display('index2.tpl'); diff --git a/week2.php b/week_old.php similarity index 96% rename from week2.php rename to week_old.php index 6fccba9cd..01597704d 100644 --- a/week2.php +++ b/week_old.php @@ -121,8 +121,8 @@ $_SESSION['project'] = $cl_project; $cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; -$cl_note = $request->getParameter('week_note', ($request->isPost() ? null : @$_SESSION['week_note'])); -$_SESSION['week_note'] = $cl_note; +$cl_note = $request->getParameter('note', ($request->isPost() ? null : @$_SESSION['note'])); +$_SESSION['note'] = $cl_note; $timeCustomFields = array(); // If we have time custom fields - collect input. @@ -229,7 +229,6 @@ function render(&$table, $value, $row, $column, $selected = false) { // Elements of weekTimeForm. $form = new Form('weekTimeForm'); -$largeScreenCalendarRowSpan = 1; // Number of rows calendar spans on large screens. if ($user->can('track_time')) { $rank = $user->getMaxRankForGroup($group_id); @@ -242,11 +241,11 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'document.weekTimeForm.user_changed.value=1;document.weekTimeForm.submit();', 'name'=>'user', + 'style'=>'width: 250px;', 'value'=>$user_id, 'data'=>$user_list, 'datakeys'=>array('id','name'))); $form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $largeScreenCalendarRowSpan += 2; $smarty->assign('user_dropdown', 1); } } @@ -271,33 +270,31 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', + 'style'=>'width: 250px;', 'value'=>$cl_client, 'data'=>$active_clients, 'datakeys'=>array('id', 'name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $largeScreenCalendarRowSpan += 2; // Note: in other modes the client list is filtered to relevant clients only. See below. } // Billable checkbox. -if ($showBillable) { +if ($user->isPluginEnabled('iv')) $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); - $largeScreenCalendarRowSpan += 2; -} // If we have time custom fields - add controls for them. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$timeCustomFields[$timeField['id']]['value'])); + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'style'=>'width: 250px;', 'data'=>CustomFields::getOptions($timeField['id']), 'value'=>$timeCustomFields[$timeField['id']]['value'], 'empty'=>array(''=>$i18n->get('dropdown.select')))); } - $largeScreenCalendarRowSpan += 2; } } @@ -308,11 +305,11 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillTaskDropdown(this.value);', 'name'=>'project', + 'style'=>'width: 250px;', 'value'=>$cl_project, 'data'=>$project_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $largeScreenCalendarRowSpan += 2; // Dropdown for clients if the clients plugin is enabled. if ($showClient) { @@ -335,11 +332,11 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', 'name'=>'client', + 'style'=>'width: 250px;', 'value'=>$cl_client, 'data'=>$client_list, 'datakeys'=>array('id', 'name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $largeScreenCalendarRowSpan += 2; } } @@ -348,17 +345,18 @@ function render(&$table, $value, $row, $column, $selected = false) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', + 'style'=>'width: 250px;', 'value'=>$cl_task, 'data'=>$task_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $largeScreenCalendarRowSpan += 2; } // Week note control. if ($showWeekNote) { - $form->addInput(array('type'=>'textarea','name'=>'week_note','value'=>$cl_note)); - $largeScreenCalendarRowSpan += 2; + if (!defined('NOTE_INPUT_HEIGHT')) + define('NOTE_INPUT_HEIGHT', 40); + $form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_note)); } // Calendar. @@ -467,7 +465,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // because we are doing an insert that does not affect already existing data. if ($showWeekNote) { - $fields['note'] = $request->getParameter('week_note'); + $fields['note'] = $request->getParameter('note'); } } $fields['day_header'] = $dayHeader; @@ -533,7 +531,6 @@ function render(&$table, $value, $row, $column, $selected = false) { $week_total = ttTimeHelper::getTimeForWeek($selected_date); -$smarty->assign('large_screen_calendar_row_span', $largeScreenCalendarRowSpan); $smarty->assign('selected_date', $selected_date); $smarty->assign('week_total', $week_total); $smarty->assign('client_list', $client_list); @@ -554,5 +551,5 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('show_start', $showStart); $smarty->assign('show_files', $showFiles); $smarty->assign('title', $i18n->get('menu.week')); -$smarty->assign('content_page_name', 'week2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'week.tpl'); +$smarty->display('index.tpl'); From 494d48957f43fc4ab1bb87e7e5b6371901ceb79d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 8 May 2021 17:43:22 +0000 Subject: [PATCH 1548/1848] It is hard to believe but the entire app is now mobile friendly. --- WEB-INF/templates/week.tpl | 200 ------------- WEB-INF/templates/week2.tpl | 9 +- initialize.php | 2 +- week_old.php | 555 ------------------------------------ 4 files changed, 2 insertions(+), 764 deletions(-) delete mode 100644 WEB-INF/templates/week.tpl delete mode 100644 week_old.php diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl deleted file mode 100644 index 92ce31d92..000000000 --- a/WEB-INF/templates/week.tpl +++ /dev/null @@ -1,200 +0,0 @@ -{include file="time_script.tpl"} - - - - - -{$forms.weekTimeForm.open} - -{if $show_navigation} - - - -{/if} - - - - -
- {$i18n.label.day_view} / {$i18n.label.week_view} -
- -{if $user_dropdown} - - - - -{/if} -{if $show_client} - - - - -{/if} -{if $show_billable} - - - - -{/if} -{if $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - - {/foreach} -{/if} -{if $show_project} - - - - -{/if} -{if $show_task} - - - - -{/if} -{if $show_week_note} - - - - -{/if} -
{$i18n.label.user}:{$forms.weekTimeForm.user.control}
{$i18n.label.client}{if $user->isOptionEnabled('client_required')} (*){/if}:{$forms.weekTimeForm.client.control}
 
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:{$forms.weekTimeForm.$control_name.control}
{$i18n.label.project} (*):{$forms.weekTimeForm.project.control}
{$i18n.label.task}{if $task_required} (*){/if}:{$forms.weekTimeForm.task.control}
{$i18n.label.week_note}:{$forms.weekTimeForm.note.control}
-
- - -
{$forms.weekTimeForm.date.control}
-
- - - - -
{$forms.weekTimeForm.week_durations.control}
- - - - - - -
{$forms.weekTimeForm.btn_submit.control}
 
- -{if $show_week_list} - - - - -
-{if $time_records} - - - - {if $show_client} - - {/if} - {if $show_project} - - {/if} - {if $show_task} - - {/if} - {if $show_start} - - - {/if} - - - {if $show_files} - - {/if} - - - - {foreach $time_records as $record} - - - {if $show_client} - - {/if} - {if $show_project} - - {/if} - {if $show_task} - - {/if} - {if $show_start} - - - {/if} - - - {if $show_files} - {if $record.has_files} - - {else} - - {/if} - {/if} - - - - {/foreach} -
{$i18n.label.date}{$i18n.label.client}{$i18n.label.project}{$i18n.label.task}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.note}
{$record.date}{$record.client|escape}{$record.project|escape}{$record.task|escape}{if $record.start}{$record.start}{else} {/if}{if $record.finish}{$record.finish}{else} {/if}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}{if $record.comment}{$record.comment|escape}{else} {/if}{$i18n.label.files}{$i18n.label.files} - {if $record.approved || $record.timesheet_id || $record.invoice_id} -   - {else} - {$i18n.label.edit} - {/if} - - {if $record.approved || $record.timesheet_id || $record.invoice_id} -   - {else} - {$i18n.label.delete} - {/if} -
-{/if} -
-{/if} - -{if $time_records} - - {if $show_week_list} - - - - - {/if} - {if $user->isPluginEnabled('mq')} - - - {if $over_quota} - - {else} - - {/if} - - {/if} -
{$i18n.label.week_total}: {$week_total}
{$i18n.label.month_total}: {$month_total}{$i18n.form.time.over_quota}: {$quota_remaining}{$i18n.form.time.remaining_quota}: {$quota_remaining}
-{/if} -{$forms.weekTimeForm.close} diff --git a/WEB-INF/templates/week2.tpl b/WEB-INF/templates/week2.tpl index 7f77b0ad9..7dbf5d1f9 100644 --- a/WEB-INF/templates/week2.tpl +++ b/WEB-INF/templates/week2.tpl @@ -18,13 +18,6 @@ function fillDropdowns() { } - - - {if $show_navigation}
{$i18n.label.day_view} / {$i18n.label.week_view} @@ -130,7 +123,7 @@ function fillDropdowns() {
{$record.date}{$record.client|escape} - {if $record.approved || $record.timesheet_id || $record.invoice_id} + {if (isset($record.approved) && $record.approved) || (isset($record.timesheet_id) && $record.timesheet_id) || (isset($record.invoice_id) && $record.invoice_id)}   {else} {$i18n.label.edit} {/if} - {if $record.approved || $record.timesheet_id || $record.invoice_id} + {if (isset($record.approved) && $record.approved) || (isset($record.timesheet_id) && $record.timesheet_id) || (isset($record.invoice_id) && $record.invoice_id)}   {else} {$i18n.label.delete} diff --git a/initialize.php b/initialize.php index 7d469b378..69580f622 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5535"); +define("APP_VERSION", "1.19.28.5536"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/week.php b/week.php index dbb61529a..63bd38235 100644 --- a/week.php +++ b/week.php @@ -55,6 +55,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +$taskRequired = false; if ($showTask) $taskRequired = $user->getConfigOption('task_required'); $showWeekNote = $user->isOptionEnabled('week_note'); $showWeekNotes = $user->isOptionEnabled('week_notes'); @@ -127,7 +128,7 @@ $timeCustomFields = array(); // If we have time custom fields - collect input. if ($request->isPost()) { - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $control_name = 'time_field_'.$timeField['id']; $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], @@ -286,7 +287,7 @@ function render(&$table, $value, $row, $column, $selected = false) { } // If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { +if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) { @@ -302,6 +303,7 @@ function render(&$table, $value, $row, $column, $selected = false) { } // If we show project dropdown, add controls for project and client. +$project_list = $client_list = array(); if ($showProject) { // Dropdown for projects assigned to user. $project_list = $user->getAssignedProjects(); @@ -344,6 +346,7 @@ function render(&$table, $value, $row, $column, $selected = false) { } // Task dropdown. +$task_list = array(); if ($showTask) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', @@ -387,7 +390,7 @@ function render(&$table, $value, $row, $column, $selected = false) { if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); // Validate input in time custom fields. - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($timeCustomFields as $timeField) { // Validation is the same for text and dropdown fields. if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); @@ -453,7 +456,7 @@ function render(&$table, $value, $row, $column, $selected = false) { $record['billable'] = $cl_billable ? '1' : '0'; $record['project_id'] = $cl_project; $record['task_id'] = $cl_task; - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) From c7d7520f3e7ac8de81432256d8ed1c77b776d448 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 9 May 2021 17:19:06 +0000 Subject: [PATCH 1551/1848] Addressed a couple more of php8 issues. --- WEB-INF/lib/form/Table.class.php | 38 +++++++++++++++++--------------- initialize.php | 2 +- user_edit.php | 1 + 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/WEB-INF/lib/form/Table.class.php b/WEB-INF/lib/form/Table.class.php index c83d90bd8..d617f8b39 100644 --- a/WEB-INF/lib/form/Table.class.php +++ b/WEB-INF/lib/form/Table.class.php @@ -36,7 +36,7 @@ class Table extends FormElement { var $mHeaders = array(); // column headers var $mFooters = array(); // column footers var $mInteractive = true; // adds a clickable checkbox column to table - var $mIAScript = null; // sctipt to execute when a checkbox is clicked + var $mIAScript = null; // script to execute when a checkbox is clicked var $mKeyField = ''; // identifies a column used as key to access row data var $mColumnFields = array(); // field names (from mData) for data in each column var $mBgColor = '#ffffff'; @@ -156,28 +156,30 @@ function getHtml() { } // Print rows. - for ($row = 0; $row < count($this->mData); $row++) { - $html .= "\n
- -
- - - - -{if $user->custom_logo} - - -
-{else} - -{/if} - - - - -
- - - -{if $user->custom_logo} - -{else} - -{/if} - - -
-
- - -{if $authenticated} - {if $user->can('administer_site')} - - - - - -
  - {$i18n.menu.logout} - {$i18n.menu.forum} - {$i18n.menu.help} -
- - - - - - - - - - {else} - - - - - -
  - {$i18n.menu.logout} - {if $user->exists() && $user->can('manage_own_settings')} - {$i18n.menu.profile} - {/if} - {if $user->can('manage_basic_settings')} - {$i18n.menu.group} - {/if} - {if $user->can('manage_features')} - {$i18n.menu.plugins} - {/if} - {$i18n.menu.forum} - {$i18n.menu.help} -
- - - - - - - - - - {/if} -{else} - - - - - -
  - {$i18n.menu.login} - {if isTrue('MULTIORG_MODE') && constant('AUTH_MODULE') == 'db'} - {$i18n.menu.register} - {/if} - {$i18n.menu.forum} - {$i18n.menu.help} -
-{/if} -
- - -{if $title} - - - {* No need to escape as it is done in the class. *} -
{$title}{if (isset($timestring) && $timestring)}: {$timestring}{/if}
{$user->getUserPartForHeader()}
-{/if} - - - -{if $err->yes()} - - - - -
- {foreach $err->getErrors() as $error} - {$error.message}
{* No need to escape as they are not coming from user and may contain a link. *} - {/foreach} -
-{/if} - - - -{if $msg->yes()} - - - - -
- {foreach $msg->getErrors() as $message} - {$message.message}
{* No need to escape. *} - {/foreach} -
-{/if} - diff --git a/WEB-INF/templates/index.tpl b/WEB-INF/templates/index.tpl deleted file mode 100644 index 75a751e08..000000000 --- a/WEB-INF/templates/index.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{include file="header.tpl"} - -{if $content_page_name}{include file="$content_page_name"}{/if} - -{include file="footer.tpl"} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/work/footer.tpl similarity index 99% rename from WEB-INF/templates/footer.tpl rename to WEB-INF/templates/work/footer.tpl index a5ae56f90..611067550 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/work/footer.tpl @@ -26,3 +26,4 @@
+ diff --git a/WEB-INF/templates/work/index.tpl b/WEB-INF/templates/work/index.tpl index 6817f3963..3c6500821 100644 --- a/WEB-INF/templates/work/index.tpl +++ b/WEB-INF/templates/work/index.tpl @@ -2,4 +2,4 @@ {if $content_page_name}{include file="$content_page_name"}{/if} -{include file="footer.tpl"} +{include file="work/footer.tpl"} diff --git a/initialize.php b/initialize.php index 7f27932dd..6260eb076 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5538"); +define("APP_VERSION", "1.19.28.5539"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ee3dae2396dc3051e9f79825759e57d51beb7985 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 14:00:32 +0000 Subject: [PATCH 1554/1848] Work in progress renaming template files. --- WEB-INF/templates/{access_denied2.tpl => access_denied.tpl} | 0 WEB-INF/templates/{admin_group_add2.tpl => admin_group_add.tpl} | 0 .../{admin_group_delete2.tpl => admin_group_delete.tpl} | 0 .../templates/{admin_group_edit2.tpl => admin_group_edit.tpl} | 0 WEB-INF/templates/{admin_groups2.tpl => admin_groups.tpl} | 0 WEB-INF/templates/{admin_options2.tpl => admin_options.tpl} | 0 access_denied.php | 2 +- admin_group_add.php | 2 +- admin_group_delete.php | 2 +- admin_group_edit.php | 2 +- admin_groups.php | 2 +- admin_options.php | 2 +- feature_disabled.php | 2 +- initialize.php | 2 +- 14 files changed, 8 insertions(+), 8 deletions(-) rename WEB-INF/templates/{access_denied2.tpl => access_denied.tpl} (100%) rename WEB-INF/templates/{admin_group_add2.tpl => admin_group_add.tpl} (100%) rename WEB-INF/templates/{admin_group_delete2.tpl => admin_group_delete.tpl} (100%) rename WEB-INF/templates/{admin_group_edit2.tpl => admin_group_edit.tpl} (100%) rename WEB-INF/templates/{admin_groups2.tpl => admin_groups.tpl} (100%) rename WEB-INF/templates/{admin_options2.tpl => admin_options.tpl} (100%) diff --git a/WEB-INF/templates/access_denied2.tpl b/WEB-INF/templates/access_denied.tpl similarity index 100% rename from WEB-INF/templates/access_denied2.tpl rename to WEB-INF/templates/access_denied.tpl diff --git a/WEB-INF/templates/admin_group_add2.tpl b/WEB-INF/templates/admin_group_add.tpl similarity index 100% rename from WEB-INF/templates/admin_group_add2.tpl rename to WEB-INF/templates/admin_group_add.tpl diff --git a/WEB-INF/templates/admin_group_delete2.tpl b/WEB-INF/templates/admin_group_delete.tpl similarity index 100% rename from WEB-INF/templates/admin_group_delete2.tpl rename to WEB-INF/templates/admin_group_delete.tpl diff --git a/WEB-INF/templates/admin_group_edit2.tpl b/WEB-INF/templates/admin_group_edit.tpl similarity index 100% rename from WEB-INF/templates/admin_group_edit2.tpl rename to WEB-INF/templates/admin_group_edit.tpl diff --git a/WEB-INF/templates/admin_groups2.tpl b/WEB-INF/templates/admin_groups.tpl similarity index 100% rename from WEB-INF/templates/admin_groups2.tpl rename to WEB-INF/templates/admin_groups.tpl diff --git a/WEB-INF/templates/admin_options2.tpl b/WEB-INF/templates/admin_options.tpl similarity index 100% rename from WEB-INF/templates/admin_options2.tpl rename to WEB-INF/templates/admin_options.tpl diff --git a/access_denied.php b/access_denied.php index 2aa3c5d77..7025d8739 100644 --- a/access_denied.php +++ b/access_denied.php @@ -8,5 +8,5 @@ if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. $smarty->assign('title', $i18n->get('label.error')); -$smarty->assign('content_page_name', 'access_denied2.tpl'); +$smarty->assign('content_page_name', 'access_denied.tpl'); $smarty->display('index2.tpl'); diff --git a/admin_group_add.php b/admin_group_add.php index 976b5c6db..178b2d1b2 100644 --- a/admin_group_add.php +++ b/admin_group_add.php @@ -101,6 +101,6 @@ $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.groupForm.group_name.focus()"'); -$smarty->assign('content_page_name', 'admin_group_add2.tpl'); +$smarty->assign('content_page_name', 'admin_group_add.tpl'); $smarty->assign('title', $i18n->get('title.add_group')); $smarty->display('index2.tpl'); diff --git a/admin_group_delete.php b/admin_group_delete.php index 83999da5d..1707d5956 100644 --- a/admin_group_delete.php +++ b/admin_group_delete.php @@ -42,5 +42,5 @@ $smarty->assign('group_to_delete', $group_name); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.delete_group')); -$smarty->assign('content_page_name', 'admin_group_delete2.tpl'); +$smarty->assign('content_page_name', 'admin_group_delete.tpl'); $smarty->display('index2.tpl'); diff --git a/admin_group_edit.php b/admin_group_edit.php index 5474ca2c3..35b0a531e 100644 --- a/admin_group_edit.php +++ b/admin_group_edit.php @@ -110,5 +110,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.groupForm.manager_name.focus()"'); $smarty->assign('title', $i18n->get('title.edit_group')); -$smarty->assign('content_page_name', 'admin_group_edit2.tpl'); +$smarty->assign('content_page_name', 'admin_group_edit.tpl'); $smarty->display('index2.tpl'); diff --git a/admin_groups.php b/admin_groups.php index 915f7d778..e3a5559c3 100644 --- a/admin_groups.php +++ b/admin_groups.php @@ -14,5 +14,5 @@ $smarty->assign('groups', ttOrgHelper::getOrgs()); $smarty->assign('title', $i18n->get('title.groups')); -$smarty->assign('content_page_name', 'admin_groups2.tpl'); +$smarty->assign('content_page_name', 'admin_groups.tpl'); $smarty->display('index2.tpl'); diff --git a/admin_options.php b/admin_options.php index bc1269336..00d292b97 100644 --- a/admin_options.php +++ b/admin_options.php @@ -72,5 +72,5 @@ $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.options')); -$smarty->assign('content_page_name', 'admin_options2.tpl'); +$smarty->assign('content_page_name', 'admin_options.tpl'); $smarty->display('index2.tpl'); diff --git a/feature_disabled.php b/feature_disabled.php index c04afe734..42f3e47ae 100644 --- a/feature_disabled.php +++ b/feature_disabled.php @@ -8,5 +8,5 @@ if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. $smarty->assign('title', $i18n->get('label.error')); -$smarty->assign('content_page_name', 'access_denied2.tpl'); +$smarty->assign('content_page_name', 'access_denied.tpl'); $smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index 6260eb076..87083f8ed 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5539"); +define("APP_VERSION", "1.19.28.5540"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 7e6f9a6e72593d24989acad71929f4187ce6c1e2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 14:48:36 +0000 Subject: [PATCH 1555/1848] A bit more of template file renaming. --- .../{cf_custom_field_add2.tpl => cf_custom_field_add.tpl} | 0 ...f_custom_field_delete2.tpl => cf_custom_field_delete.tpl} | 0 .../{cf_custom_field_edit2.tpl => cf_custom_field_edit.tpl} | 0 .../{cf_custom_fields2.tpl => cf_custom_fields.tpl} | 0 ...f_dropdown_option_add2.tpl => cf_dropdown_option_add.tpl} | 0 ...down_option_delete2.tpl => cf_dropdown_option_delete.tpl} | 0 ...dropdown_option_edit2.tpl => cf_dropdown_option_edit.tpl} | 0 .../{cf_dropdown_options2.tpl => cf_dropdown_options.tpl} | 0 WEB-INF/templates/{charts2.tpl => charts.tpl} | 0 WEB-INF/templates/index.tpl | 5 +++++ access_denied.php | 2 +- admin_group_add.php | 2 +- admin_group_delete.php | 2 +- admin_group_edit.php | 2 +- admin_groups.php | 2 +- admin_options.php | 2 +- cf_custom_field_add.php | 4 ++-- cf_custom_field_delete.php | 4 ++-- cf_custom_field_edit.php | 4 ++-- cf_custom_fields.php | 4 ++-- cf_dropdown_option_add.php | 4 ++-- cf_dropdown_option_delete.php | 4 ++-- cf_dropdown_option_edit.php | 4 ++-- cf_dropdown_options.php | 4 ++-- charts.php | 4 ++-- feature_disabled.php | 2 +- initialize.php | 2 +- 27 files changed, 31 insertions(+), 26 deletions(-) rename WEB-INF/templates/{cf_custom_field_add2.tpl => cf_custom_field_add.tpl} (100%) rename WEB-INF/templates/{cf_custom_field_delete2.tpl => cf_custom_field_delete.tpl} (100%) rename WEB-INF/templates/{cf_custom_field_edit2.tpl => cf_custom_field_edit.tpl} (100%) rename WEB-INF/templates/{cf_custom_fields2.tpl => cf_custom_fields.tpl} (100%) rename WEB-INF/templates/{cf_dropdown_option_add2.tpl => cf_dropdown_option_add.tpl} (100%) rename WEB-INF/templates/{cf_dropdown_option_delete2.tpl => cf_dropdown_option_delete.tpl} (100%) rename WEB-INF/templates/{cf_dropdown_option_edit2.tpl => cf_dropdown_option_edit.tpl} (100%) rename WEB-INF/templates/{cf_dropdown_options2.tpl => cf_dropdown_options.tpl} (100%) rename WEB-INF/templates/{charts2.tpl => charts.tpl} (100%) create mode 100644 WEB-INF/templates/index.tpl diff --git a/WEB-INF/templates/cf_custom_field_add2.tpl b/WEB-INF/templates/cf_custom_field_add.tpl similarity index 100% rename from WEB-INF/templates/cf_custom_field_add2.tpl rename to WEB-INF/templates/cf_custom_field_add.tpl diff --git a/WEB-INF/templates/cf_custom_field_delete2.tpl b/WEB-INF/templates/cf_custom_field_delete.tpl similarity index 100% rename from WEB-INF/templates/cf_custom_field_delete2.tpl rename to WEB-INF/templates/cf_custom_field_delete.tpl diff --git a/WEB-INF/templates/cf_custom_field_edit2.tpl b/WEB-INF/templates/cf_custom_field_edit.tpl similarity index 100% rename from WEB-INF/templates/cf_custom_field_edit2.tpl rename to WEB-INF/templates/cf_custom_field_edit.tpl diff --git a/WEB-INF/templates/cf_custom_fields2.tpl b/WEB-INF/templates/cf_custom_fields.tpl similarity index 100% rename from WEB-INF/templates/cf_custom_fields2.tpl rename to WEB-INF/templates/cf_custom_fields.tpl diff --git a/WEB-INF/templates/cf_dropdown_option_add2.tpl b/WEB-INF/templates/cf_dropdown_option_add.tpl similarity index 100% rename from WEB-INF/templates/cf_dropdown_option_add2.tpl rename to WEB-INF/templates/cf_dropdown_option_add.tpl diff --git a/WEB-INF/templates/cf_dropdown_option_delete2.tpl b/WEB-INF/templates/cf_dropdown_option_delete.tpl similarity index 100% rename from WEB-INF/templates/cf_dropdown_option_delete2.tpl rename to WEB-INF/templates/cf_dropdown_option_delete.tpl diff --git a/WEB-INF/templates/cf_dropdown_option_edit2.tpl b/WEB-INF/templates/cf_dropdown_option_edit.tpl similarity index 100% rename from WEB-INF/templates/cf_dropdown_option_edit2.tpl rename to WEB-INF/templates/cf_dropdown_option_edit.tpl diff --git a/WEB-INF/templates/cf_dropdown_options2.tpl b/WEB-INF/templates/cf_dropdown_options.tpl similarity index 100% rename from WEB-INF/templates/cf_dropdown_options2.tpl rename to WEB-INF/templates/cf_dropdown_options.tpl diff --git a/WEB-INF/templates/charts2.tpl b/WEB-INF/templates/charts.tpl similarity index 100% rename from WEB-INF/templates/charts2.tpl rename to WEB-INF/templates/charts.tpl diff --git a/WEB-INF/templates/index.tpl b/WEB-INF/templates/index.tpl new file mode 100644 index 000000000..410a7616a --- /dev/null +++ b/WEB-INF/templates/index.tpl @@ -0,0 +1,5 @@ +{include file="header2.tpl"} + +{if $content_page_name}{include file="$content_page_name"}{/if} + +{include file="footer2.tpl"} diff --git a/access_denied.php b/access_denied.php index 7025d8739..80900d570 100644 --- a/access_denied.php +++ b/access_denied.php @@ -9,4 +9,4 @@ $smarty->assign('title', $i18n->get('label.error')); $smarty->assign('content_page_name', 'access_denied.tpl'); -$smarty->display('index2.tpl'); +$smarty->display('index.tpl'); diff --git a/admin_group_add.php b/admin_group_add.php index 178b2d1b2..52850b608 100644 --- a/admin_group_add.php +++ b/admin_group_add.php @@ -103,4 +103,4 @@ $smarty->assign('onload', 'onLoad="document.groupForm.group_name.focus()"'); $smarty->assign('content_page_name', 'admin_group_add.tpl'); $smarty->assign('title', $i18n->get('title.add_group')); -$smarty->display('index2.tpl'); +$smarty->display('index.tpl'); diff --git a/admin_group_delete.php b/admin_group_delete.php index 1707d5956..0cea02b32 100644 --- a/admin_group_delete.php +++ b/admin_group_delete.php @@ -43,4 +43,4 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.delete_group')); $smarty->assign('content_page_name', 'admin_group_delete.tpl'); -$smarty->display('index2.tpl'); +$smarty->display('index.tpl'); diff --git a/admin_group_edit.php b/admin_group_edit.php index 35b0a531e..81588ebec 100644 --- a/admin_group_edit.php +++ b/admin_group_edit.php @@ -111,4 +111,4 @@ $smarty->assign('onload', 'onLoad="document.groupForm.manager_name.focus()"'); $smarty->assign('title', $i18n->get('title.edit_group')); $smarty->assign('content_page_name', 'admin_group_edit.tpl'); -$smarty->display('index2.tpl'); +$smarty->display('index.tpl'); diff --git a/admin_groups.php b/admin_groups.php index e3a5559c3..8dffd3931 100644 --- a/admin_groups.php +++ b/admin_groups.php @@ -15,4 +15,4 @@ $smarty->assign('groups', ttOrgHelper::getOrgs()); $smarty->assign('title', $i18n->get('title.groups')); $smarty->assign('content_page_name', 'admin_groups.tpl'); -$smarty->display('index2.tpl'); +$smarty->display('index.tpl'); diff --git a/admin_options.php b/admin_options.php index 00d292b97..84a0ed3a5 100644 --- a/admin_options.php +++ b/admin_options.php @@ -73,4 +73,4 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.options')); $smarty->assign('content_page_name', 'admin_options.tpl'); -$smarty->display('index2.tpl'); +$smarty->display('index.tpl'); diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index 14b233a52..6cfd87256 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -55,5 +55,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fieldForm.name.focus()"'); $smarty->assign('title', $i18n->get('title.cf_add_custom_field')); -$smarty->assign('content_page_name', 'cf_custom_field_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'cf_custom_field_add.tpl'); +$smarty->display('index.tpl'); diff --git a/cf_custom_field_delete.php b/cf_custom_field_delete.php index 7cfd72035..ba222c657 100644 --- a/cf_custom_field_delete.php +++ b/cf_custom_field_delete.php @@ -50,5 +50,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fieldDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.cf_delete_custom_field')); -$smarty->assign('content_page_name', 'cf_custom_field_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'cf_custom_field_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/cf_custom_field_edit.php b/cf_custom_field_edit.php index 36e76d4bf..3f959ee22 100644 --- a/cf_custom_field_edit.php +++ b/cf_custom_field_edit.php @@ -68,5 +68,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fieldForm.name.focus()"'); $smarty->assign('title', $i18n->get('title.cf_edit_custom_field')); -$smarty->assign('content_page_name', 'cf_custom_field_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'cf_custom_field_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/cf_custom_fields.php b/cf_custom_fields.php index 7d670636e..6552bb7f6 100644 --- a/cf_custom_fields.php +++ b/cf_custom_fields.php @@ -34,5 +34,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('custom_fields', $fields); $smarty->assign('title', $i18n->get('title.cf_custom_fields')); -$smarty->assign('content_page_name', 'cf_custom_fields2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'cf_custom_fields.tpl'); +$smarty->display('index.tpl'); diff --git a/cf_dropdown_option_add.php b/cf_dropdown_option_add.php index f1bf00908..582794ae5 100644 --- a/cf_dropdown_option_add.php +++ b/cf_dropdown_option_add.php @@ -49,5 +49,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.optionAddForm.name.focus()"'); $smarty->assign('title', $i18n->get('title.cf_add_dropdown_option')); -$smarty->assign('content_page_name', 'cf_dropdown_option_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'cf_dropdown_option_add.tpl'); +$smarty->display('index.tpl'); diff --git a/cf_dropdown_option_delete.php b/cf_dropdown_option_delete.php index e23288bd5..e6eeeeb75 100644 --- a/cf_dropdown_option_delete.php +++ b/cf_dropdown_option_delete.php @@ -53,5 +53,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.optionDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.cf_delete_dropdown_option')); -$smarty->assign('content_page_name', 'cf_dropdown_option_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'cf_dropdown_option_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/cf_dropdown_option_edit.php b/cf_dropdown_option_edit.php index c73200ffc..eee02f63c 100644 --- a/cf_dropdown_option_edit.php +++ b/cf_dropdown_option_edit.php @@ -51,5 +51,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.optionEditForm.name.focus()"'); $smarty->assign('title', $i18n->get('title.cf_edit_dropdown_option')); -$smarty->assign('content_page_name', 'cf_dropdown_option_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'cf_dropdown_option_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/cf_dropdown_options.php b/cf_dropdown_options.php index 2570f0ee0..06f53a7d8 100644 --- a/cf_dropdown_options.php +++ b/cf_dropdown_options.php @@ -28,5 +28,5 @@ $smarty->assign('field_id', $field_id); $smarty->assign('options', $options); $smarty->assign('title', $i18n->get('title.cf_dropdown_options')); -$smarty->assign('content_page_name', 'cf_dropdown_options2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'cf_dropdown_options.tpl'); +$smarty->display('index.tpl'); diff --git a/charts.php b/charts.php index 25e6695d4..1bf6d34fa 100644 --- a/charts.php +++ b/charts.php @@ -205,5 +205,5 @@ $smarty->assign('onload', 'onLoad="adjustTodayLinks()"'); $smarty->assign('forms', array($chart_form->getName() => $chart_form->toArray())); $smarty->assign('title', $i18n->get('title.charts')); -$smarty->assign('content_page_name', 'charts2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'charts.tpl'); +$smarty->display('index.tpl'); diff --git a/feature_disabled.php b/feature_disabled.php index 42f3e47ae..d15413541 100644 --- a/feature_disabled.php +++ b/feature_disabled.php @@ -9,4 +9,4 @@ $smarty->assign('title', $i18n->get('label.error')); $smarty->assign('content_page_name', 'access_denied.tpl'); -$smarty->display('index2.tpl'); +$smarty->display('index.tpl'); diff --git a/initialize.php b/initialize.php index 87083f8ed..378edcba6 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5540"); +define("APP_VERSION", "1.19.28.5541"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From edc7f366e8e45096e54bf15c46ea205fbf2867c3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 16:05:40 +0000 Subject: [PATCH 1556/1848] More template files renamed. --- WEB-INF/templates/{client_add2.tpl => client_add.tpl} | 0 WEB-INF/templates/{client_delete2.tpl => client_delete.tpl} | 0 WEB-INF/templates/{client_edit2.tpl => client_edit.tpl} | 0 WEB-INF/templates/{clients2.tpl => clients.tpl} | 0 .../templates/{display_options2.tpl => display_options.tpl} | 0 WEB-INF/templates/{entity_files2.tpl => entity_files.tpl} | 0 WEB-INF/templates/{expense_delete2.tpl => expense_delete.tpl} | 0 WEB-INF/templates/{expense_edit2.tpl => expense_edit.tpl} | 0 WEB-INF/templates/{expenses2.tpl => expenses.tpl} | 0 WEB-INF/templates/{export2.tpl => export.tpl} | 0 WEB-INF/templates/{file_delete2.tpl => file_delete.tpl} | 0 WEB-INF/templates/{file_download2.tpl => file_download.tpl} | 0 WEB-INF/templates/{file_edit2.tpl => file_edit.tpl} | 0 client_add.php | 4 ++-- client_delete.php | 4 ++-- client_edit.php | 4 ++-- clients.php | 4 ++-- display_options.php | 4 ++-- expense_delete.php | 4 ++-- expense_edit.php | 4 ++-- expense_files.php | 4 ++-- expenses.php | 4 ++-- export.php | 4 ++-- file_delete.php | 4 ++-- file_download.php | 4 ++-- file_edit.php | 4 ++-- initialize.php | 2 +- project_files.php | 4 ++-- time_files.php | 4 ++-- timesheet_files.php | 4 ++-- 30 files changed, 33 insertions(+), 33 deletions(-) rename WEB-INF/templates/{client_add2.tpl => client_add.tpl} (100%) rename WEB-INF/templates/{client_delete2.tpl => client_delete.tpl} (100%) rename WEB-INF/templates/{client_edit2.tpl => client_edit.tpl} (100%) rename WEB-INF/templates/{clients2.tpl => clients.tpl} (100%) rename WEB-INF/templates/{display_options2.tpl => display_options.tpl} (100%) rename WEB-INF/templates/{entity_files2.tpl => entity_files.tpl} (100%) rename WEB-INF/templates/{expense_delete2.tpl => expense_delete.tpl} (100%) rename WEB-INF/templates/{expense_edit2.tpl => expense_edit.tpl} (100%) rename WEB-INF/templates/{expenses2.tpl => expenses.tpl} (100%) rename WEB-INF/templates/{export2.tpl => export.tpl} (100%) rename WEB-INF/templates/{file_delete2.tpl => file_delete.tpl} (100%) rename WEB-INF/templates/{file_download2.tpl => file_download.tpl} (100%) rename WEB-INF/templates/{file_edit2.tpl => file_edit.tpl} (100%) diff --git a/WEB-INF/templates/client_add2.tpl b/WEB-INF/templates/client_add.tpl similarity index 100% rename from WEB-INF/templates/client_add2.tpl rename to WEB-INF/templates/client_add.tpl diff --git a/WEB-INF/templates/client_delete2.tpl b/WEB-INF/templates/client_delete.tpl similarity index 100% rename from WEB-INF/templates/client_delete2.tpl rename to WEB-INF/templates/client_delete.tpl diff --git a/WEB-INF/templates/client_edit2.tpl b/WEB-INF/templates/client_edit.tpl similarity index 100% rename from WEB-INF/templates/client_edit2.tpl rename to WEB-INF/templates/client_edit.tpl diff --git a/WEB-INF/templates/clients2.tpl b/WEB-INF/templates/clients.tpl similarity index 100% rename from WEB-INF/templates/clients2.tpl rename to WEB-INF/templates/clients.tpl diff --git a/WEB-INF/templates/display_options2.tpl b/WEB-INF/templates/display_options.tpl similarity index 100% rename from WEB-INF/templates/display_options2.tpl rename to WEB-INF/templates/display_options.tpl diff --git a/WEB-INF/templates/entity_files2.tpl b/WEB-INF/templates/entity_files.tpl similarity index 100% rename from WEB-INF/templates/entity_files2.tpl rename to WEB-INF/templates/entity_files.tpl diff --git a/WEB-INF/templates/expense_delete2.tpl b/WEB-INF/templates/expense_delete.tpl similarity index 100% rename from WEB-INF/templates/expense_delete2.tpl rename to WEB-INF/templates/expense_delete.tpl diff --git a/WEB-INF/templates/expense_edit2.tpl b/WEB-INF/templates/expense_edit.tpl similarity index 100% rename from WEB-INF/templates/expense_edit2.tpl rename to WEB-INF/templates/expense_edit.tpl diff --git a/WEB-INF/templates/expenses2.tpl b/WEB-INF/templates/expenses.tpl similarity index 100% rename from WEB-INF/templates/expenses2.tpl rename to WEB-INF/templates/expenses.tpl diff --git a/WEB-INF/templates/export2.tpl b/WEB-INF/templates/export.tpl similarity index 100% rename from WEB-INF/templates/export2.tpl rename to WEB-INF/templates/export.tpl diff --git a/WEB-INF/templates/file_delete2.tpl b/WEB-INF/templates/file_delete.tpl similarity index 100% rename from WEB-INF/templates/file_delete2.tpl rename to WEB-INF/templates/file_delete.tpl diff --git a/WEB-INF/templates/file_download2.tpl b/WEB-INF/templates/file_download.tpl similarity index 100% rename from WEB-INF/templates/file_download2.tpl rename to WEB-INF/templates/file_download.tpl diff --git a/WEB-INF/templates/file_edit2.tpl b/WEB-INF/templates/file_edit.tpl similarity index 100% rename from WEB-INF/templates/file_edit2.tpl rename to WEB-INF/templates/file_edit.tpl diff --git a/client_add.php b/client_add.php index 1b91a4080..f1f45333e 100644 --- a/client_add.php +++ b/client_add.php @@ -68,5 +68,5 @@ $smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"'); $smarty->assign('show_projects', $show_projects); $smarty->assign('title', $i18n->get('title.add_client')); -$smarty->assign('content_page_name', 'client_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'client_add.tpl'); +$smarty->display('index.tpl'); diff --git a/client_delete.php b/client_delete.php index 147f2db54..e832c6bcb 100644 --- a/client_delete.php +++ b/client_delete.php @@ -50,5 +50,5 @@ $smarty->assign('client_to_delete', $client_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.delete_client')); -$smarty->assign('content_page_name', 'client_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'client_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/client_edit.php b/client_edit.php index c7e0a92e3..349834181 100644 --- a/client_edit.php +++ b/client_edit.php @@ -104,5 +104,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_projects', $show_projects); $smarty->assign('title', $i18n->get('title.edit_client')); -$smarty->assign('content_page_name', 'client_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'client_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/clients.php b/clients.php index 77ade9c7b..309eb155a 100644 --- a/clients.php +++ b/clients.php @@ -27,5 +27,5 @@ $smarty->assign('active_clients', $active_clients); $smarty->assign('inactive_clients', $inactive_clients); $smarty->assign('title', $i18n->get('title.clients')); -$smarty->assign('content_page_name', 'clients2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'clients.tpl'); +$smarty->display('index.tpl'); diff --git a/display_options.php b/display_options.php index 53a86ca9e..21b488c64 100644 --- a/display_options.php +++ b/display_options.php @@ -74,5 +74,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.display_options')); -$smarty->assign('content_page_name', 'display_options2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'display_options.tpl'); +$smarty->display('index.tpl'); diff --git a/expense_delete.php b/expense_delete.php index 7ecd2c6d3..6c5cb791f 100644 --- a/expense_delete.php +++ b/expense_delete.php @@ -60,5 +60,5 @@ $smarty->assign('expense_item', $expense_item); $smarty->assign('show_project', $show_project); $smarty->assign('title', $i18n->get('title.delete_expense')); -$smarty->assign('content_page_name', 'expense_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'expense_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/expense_edit.php b/expense_edit.php index f4d3c2216..271a588ac 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -211,5 +211,5 @@ $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); $smarty->assign('title', $i18n->get('title.edit_expense')); -$smarty->assign('content_page_name', 'expense_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'expense_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/expense_files.php b/expense_files.php index 5642cb383..7fe2a5d1a 100644 --- a/expense_files.php +++ b/expense_files.php @@ -61,5 +61,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('files', $files); $smarty->assign('title', $i18n->get('title.expense_files')); -$smarty->assign('content_page_name', 'entity_files2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'entity_files.tpl'); +$smarty->display('index.tpl'); diff --git a/expenses.php b/expenses.php index d5978228e..1914a253e 100644 --- a/expenses.php +++ b/expenses.php @@ -230,5 +230,5 @@ $smarty->assign('project_list', $project_list); $smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); $smarty->assign('title', $i18n->get('title.expenses')); -$smarty->assign('content_page_name', 'expenses2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'expenses.tpl'); +$smarty->display('index.tpl'); diff --git a/export.php b/export.php index b5e1206dd..2bcba2dce 100644 --- a/export.php +++ b/export.php @@ -55,5 +55,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.export')); -$smarty->assign('content_page_name', 'export2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'export.tpl'); +$smarty->display('index.tpl'); diff --git a/file_delete.php b/file_delete.php index 1b415c19b..e6cb53378 100644 --- a/file_delete.php +++ b/file_delete.php @@ -98,5 +98,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fileDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_file')); -$smarty->assign('content_page_name', 'file_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'file_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/file_download.php b/file_download.php index ff7e1633a..2fb52f79b 100644 --- a/file_download.php +++ b/file_download.php @@ -59,5 +59,5 @@ } $smarty->assign('title', $i18n->get('title.download_file')); -$smarty->assign('content_page_name', 'file_download2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'file_download.tpl'); +$smarty->display('index.tpl'); diff --git a/file_edit.php b/file_edit.php index 745293c2e..aeb8f70c7 100644 --- a/file_edit.php +++ b/file_edit.php @@ -96,5 +96,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fileForm.description.focus()"'); $smarty->assign('title', $i18n->get('title.edit_file')); -$smarty->assign('content_page_name', 'file_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'file_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/initialize.php b/initialize.php index 378edcba6..658b5fb64 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5541"); +define("APP_VERSION", "1.19.28.5542"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/project_files.php b/project_files.php index 60fc4d9e3..8b38a8ce6 100644 --- a/project_files.php +++ b/project_files.php @@ -62,5 +62,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('files', $files); $smarty->assign('title', $i18n->get('title.project_files').': '.$project['name']); -$smarty->assign('content_page_name', 'entity_files2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'entity_files.tpl'); +$smarty->display('index.tpl'); diff --git a/time_files.php b/time_files.php index 210bd534c..c5dce5baa 100644 --- a/time_files.php +++ b/time_files.php @@ -62,5 +62,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('files', $files); $smarty->assign('title', $i18n->get('title.time_files')); -$smarty->assign('content_page_name', 'entity_files2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'entity_files.tpl'); +$smarty->display('index.tpl'); diff --git a/timesheet_files.php b/timesheet_files.php index d09ecd57d..bca00f28d 100644 --- a/timesheet_files.php +++ b/timesheet_files.php @@ -61,5 +61,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('files', $files); $smarty->assign('title', $i18n->get('title.timesheet_files').': '.$timesheet['name']); -$smarty->assign('content_page_name', 'entity_files2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'entity_files.tpl'); +$smarty->display('index.tpl'); From 9f25423fdd777837465ef62d0d8ba97853e725ed Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 16:39:30 +0000 Subject: [PATCH 1557/1848] More templates renamed. --- WEB-INF/templates/{footer2.tpl => footer.tpl} | 0 WEB-INF/templates/{group_add2.tpl => group_add.tpl} | 0 .../{group_advanced_edit2.tpl => group_advanced_edit.tpl} | 0 WEB-INF/templates/{group_delete2.tpl => group_delete.tpl} | 0 WEB-INF/templates/{group_edit2.tpl => group_edit.tpl} | 0 WEB-INF/templates/{groups2.tpl => groups.tpl} | 0 WEB-INF/templates/{header2.tpl => header.tpl} | 0 WEB-INF/templates/{import2.tpl => import.tpl} | 0 WEB-INF/templates/index.tpl | 4 ++-- WEB-INF/templates/index2.tpl | 4 ++-- WEB-INF/templates/{user_add2.tpl => user_add.tpl} | 0 WEB-INF/templates/{user_delete2.tpl => user_delete.tpl} | 0 WEB-INF/templates/{user_edit2.tpl => user_edit.tpl} | 0 WEB-INF/templates/{users2.tpl => users.tpl} | 0 WEB-INF/templates/{week2.tpl => week.tpl} | 0 WEB-INF/templates/{week_view2.tpl => week_view.tpl} | 0 WEB-INF/templates/{work_units2.tpl => work_units.tpl} | 0 group_add.php | 4 ++-- group_advanced_edit.php | 4 ++-- group_delete.php | 4 ++-- group_edit.php | 4 ++-- groups.php | 4 ++-- import.php | 4 ++-- initialize.php | 2 +- user_add.php | 4 ++-- user_delete.php | 4 ++-- user_edit.php | 4 ++-- users.php | 4 ++-- week.php | 4 ++-- week_view.php | 4 ++-- work_units.php | 4 ++-- 31 files changed, 31 insertions(+), 31 deletions(-) rename WEB-INF/templates/{footer2.tpl => footer.tpl} (100%) rename WEB-INF/templates/{group_add2.tpl => group_add.tpl} (100%) rename WEB-INF/templates/{group_advanced_edit2.tpl => group_advanced_edit.tpl} (100%) rename WEB-INF/templates/{group_delete2.tpl => group_delete.tpl} (100%) rename WEB-INF/templates/{group_edit2.tpl => group_edit.tpl} (100%) rename WEB-INF/templates/{groups2.tpl => groups.tpl} (100%) rename WEB-INF/templates/{header2.tpl => header.tpl} (100%) rename WEB-INF/templates/{import2.tpl => import.tpl} (100%) rename WEB-INF/templates/{user_add2.tpl => user_add.tpl} (100%) rename WEB-INF/templates/{user_delete2.tpl => user_delete.tpl} (100%) rename WEB-INF/templates/{user_edit2.tpl => user_edit.tpl} (100%) rename WEB-INF/templates/{users2.tpl => users.tpl} (100%) rename WEB-INF/templates/{week2.tpl => week.tpl} (100%) rename WEB-INF/templates/{week_view2.tpl => week_view.tpl} (100%) rename WEB-INF/templates/{work_units2.tpl => work_units.tpl} (100%) diff --git a/WEB-INF/templates/footer2.tpl b/WEB-INF/templates/footer.tpl similarity index 100% rename from WEB-INF/templates/footer2.tpl rename to WEB-INF/templates/footer.tpl diff --git a/WEB-INF/templates/group_add2.tpl b/WEB-INF/templates/group_add.tpl similarity index 100% rename from WEB-INF/templates/group_add2.tpl rename to WEB-INF/templates/group_add.tpl diff --git a/WEB-INF/templates/group_advanced_edit2.tpl b/WEB-INF/templates/group_advanced_edit.tpl similarity index 100% rename from WEB-INF/templates/group_advanced_edit2.tpl rename to WEB-INF/templates/group_advanced_edit.tpl diff --git a/WEB-INF/templates/group_delete2.tpl b/WEB-INF/templates/group_delete.tpl similarity index 100% rename from WEB-INF/templates/group_delete2.tpl rename to WEB-INF/templates/group_delete.tpl diff --git a/WEB-INF/templates/group_edit2.tpl b/WEB-INF/templates/group_edit.tpl similarity index 100% rename from WEB-INF/templates/group_edit2.tpl rename to WEB-INF/templates/group_edit.tpl diff --git a/WEB-INF/templates/groups2.tpl b/WEB-INF/templates/groups.tpl similarity index 100% rename from WEB-INF/templates/groups2.tpl rename to WEB-INF/templates/groups.tpl diff --git a/WEB-INF/templates/header2.tpl b/WEB-INF/templates/header.tpl similarity index 100% rename from WEB-INF/templates/header2.tpl rename to WEB-INF/templates/header.tpl diff --git a/WEB-INF/templates/import2.tpl b/WEB-INF/templates/import.tpl similarity index 100% rename from WEB-INF/templates/import2.tpl rename to WEB-INF/templates/import.tpl diff --git a/WEB-INF/templates/index.tpl b/WEB-INF/templates/index.tpl index 410a7616a..75a751e08 100644 --- a/WEB-INF/templates/index.tpl +++ b/WEB-INF/templates/index.tpl @@ -1,5 +1,5 @@ -{include file="header2.tpl"} +{include file="header.tpl"} {if $content_page_name}{include file="$content_page_name"}{/if} -{include file="footer2.tpl"} +{include file="footer.tpl"} diff --git a/WEB-INF/templates/index2.tpl b/WEB-INF/templates/index2.tpl index 410a7616a..75a751e08 100644 --- a/WEB-INF/templates/index2.tpl +++ b/WEB-INF/templates/index2.tpl @@ -1,5 +1,5 @@ -{include file="header2.tpl"} +{include file="header.tpl"} {if $content_page_name}{include file="$content_page_name"}{/if} -{include file="footer2.tpl"} +{include file="footer.tpl"} diff --git a/WEB-INF/templates/user_add2.tpl b/WEB-INF/templates/user_add.tpl similarity index 100% rename from WEB-INF/templates/user_add2.tpl rename to WEB-INF/templates/user_add.tpl diff --git a/WEB-INF/templates/user_delete2.tpl b/WEB-INF/templates/user_delete.tpl similarity index 100% rename from WEB-INF/templates/user_delete2.tpl rename to WEB-INF/templates/user_delete.tpl diff --git a/WEB-INF/templates/user_edit2.tpl b/WEB-INF/templates/user_edit.tpl similarity index 100% rename from WEB-INF/templates/user_edit2.tpl rename to WEB-INF/templates/user_edit.tpl diff --git a/WEB-INF/templates/users2.tpl b/WEB-INF/templates/users.tpl similarity index 100% rename from WEB-INF/templates/users2.tpl rename to WEB-INF/templates/users.tpl diff --git a/WEB-INF/templates/week2.tpl b/WEB-INF/templates/week.tpl similarity index 100% rename from WEB-INF/templates/week2.tpl rename to WEB-INF/templates/week.tpl diff --git a/WEB-INF/templates/week_view2.tpl b/WEB-INF/templates/week_view.tpl similarity index 100% rename from WEB-INF/templates/week_view2.tpl rename to WEB-INF/templates/week_view.tpl diff --git a/WEB-INF/templates/work_units2.tpl b/WEB-INF/templates/work_units.tpl similarity index 100% rename from WEB-INF/templates/work_units2.tpl rename to WEB-INF/templates/work_units.tpl diff --git a/group_add.php b/group_add.php index 8436acd80..6f88af205 100644 --- a/group_add.php +++ b/group_add.php @@ -46,5 +46,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.groupForm.group_name.focus()"'); $smarty->assign('title', $i18n->get('title.add_group')); -$smarty->assign('content_page_name', 'group_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'group_add.tpl'); +$smarty->display('index.tpl'); diff --git a/group_advanced_edit.php b/group_advanced_edit.php index efb7a49e7..d08017576 100644 --- a/group_advanced_edit.php +++ b/group_advanced_edit.php @@ -62,5 +62,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_group')); -$smarty->assign('content_page_name', 'group_advanced_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'group_advanced_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/group_delete.php b/group_delete.php index c1e47d02c..377bb80e9 100644 --- a/group_delete.php +++ b/group_delete.php @@ -64,5 +64,5 @@ $smarty->assign('group_to_delete', $group_name); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.delete_group')); -$smarty->assign('content_page_name', 'group_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'group_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/group_edit.php b/group_edit.php index 097c34054..ab3065d52 100644 --- a/group_edit.php +++ b/group_edit.php @@ -231,5 +231,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="handlePluginCheckboxes();"'); $smarty->assign('title', $i18n->get('title.edit_group')); -$smarty->assign('content_page_name', 'group_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'group_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/groups.php b/groups.php index 5773220a2..a7bf2dfe6 100644 --- a/groups.php +++ b/groups.php @@ -39,5 +39,5 @@ $smarty->assign('subgroups', $user->getSubgroups($group_id)); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('label.subgroups')); -$smarty->assign('content_page_name', 'groups2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'groups.tpl'); +$smarty->display('index.tpl'); diff --git a/import.php b/import.php index c4b59c240..b743b3f5a 100644 --- a/import.php +++ b/import.php @@ -25,5 +25,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray()) ); $smarty->assign('title', $i18n->get('title.import')); -$smarty->assign('content_page_name', 'import2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'import.tpl'); +$smarty->display('index.tpl'); diff --git a/initialize.php b/initialize.php index 658b5fb64..f69c77a18 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5542"); +define("APP_VERSION", "1.19.28.5543"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_add.php b/user_add.php index 7325682e5..8d584afb7 100644 --- a/user_add.php +++ b/user_add.php @@ -217,5 +217,5 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('show_quota', $show_quota); $smarty->assign('show_projects', $show_projects); $smarty->assign('title', $i18n->get('title.add_user')); -$smarty->assign('content_page_name', 'user_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'user_add.tpl'); +$smarty->display('index.tpl'); diff --git a/user_delete.php b/user_delete.php index 99378fda4..e6ec7365e 100644 --- a/user_delete.php +++ b/user_delete.php @@ -59,5 +59,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.delete_user')); -$smarty->assign('content_page_name', 'user_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'user_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/user_edit.php b/user_edit.php index bae837c43..10aaebbb0 100644 --- a/user_edit.php +++ b/user_edit.php @@ -279,5 +279,5 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('show_projects', $show_projects); $smarty->assign('user_id', $user_id); $smarty->assign('title', $i18n->get('title.edit_user')); -$smarty->assign('content_page_name', 'user_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'user_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/users.php b/users.php index a0ccdc3c1..16a422390 100644 --- a/users.php +++ b/users.php @@ -41,5 +41,5 @@ $smarty->assign('inactive_users', $inactive_users); $smarty->assign('show_quota', $user->isPluginEnabled('mq')); $smarty->assign('title', $i18n->get('title.users')); -$smarty->assign('content_page_name', 'users2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'users.tpl'); +$smarty->display('index.tpl'); diff --git a/week.php b/week.php index 63bd38235..6a2a25e26 100644 --- a/week.php +++ b/week.php @@ -559,5 +559,5 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('show_start', $showStart); $smarty->assign('show_files', $showFiles); $smarty->assign('title', $i18n->get('menu.week')); -$smarty->assign('content_page_name', 'week2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'week.tpl'); +$smarty->display('index.tpl'); diff --git a/week_view.php b/week_view.php index d612239b0..1718afd4b 100644 --- a/week_view.php +++ b/week_view.php @@ -45,5 +45,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.week_view')); -$smarty->assign('content_page_name', 'week_view2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'week_view.tpl'); +$smarty->display('index.tpl'); diff --git a/work_units.php b/work_units.php index ab2ac81af..b8a4a747e 100644 --- a/work_units.php +++ b/work_units.php @@ -53,5 +53,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.work_units')); -$smarty->assign('content_page_name', 'work_units2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'work_units.tpl'); +$smarty->display('index.tpl'); From 9358c20bf5a5ff35c17633c093fca9f8a0d84118 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 17:05:44 +0000 Subject: [PATCH 1558/1848] Some more templates renamed. --- WEB-INF/templates/{template_add2.tpl => template_add.tpl} | 0 .../templates/{template_delete2.tpl => template_delete.tpl} | 0 WEB-INF/templates/{template_edit2.tpl => template_edit.tpl} | 0 WEB-INF/templates/{templates2.tpl => templates.tpl} | 0 WEB-INF/templates/{time2.tpl => time.tpl} | 0 WEB-INF/templates/{time_delete2.tpl => time_delete.tpl} | 0 WEB-INF/templates/{time_edit2.tpl => time_edit.tpl} | 0 WEB-INF/templates/{timer2.tpl => timer.tpl} | 0 WEB-INF/templates/{timesheet_add2.tpl => timesheet_add.tpl} | 0 .../templates/{timesheet_delete2.tpl => timesheet_delete.tpl} | 0 WEB-INF/templates/{timesheet_edit2.tpl => timesheet_edit.tpl} | 0 WEB-INF/templates/{timesheet_view2.tpl => timesheet_view.tpl} | 0 WEB-INF/templates/{timesheets2.tpl => timesheets.tpl} | 0 initialize.php | 2 +- template_add.php | 4 ++-- template_delete.php | 4 ++-- template_edit.php | 4 ++-- templates.php | 4 ++-- time.php | 4 ++-- time_delete.php | 4 ++-- time_edit.php | 4 ++-- timer.php | 4 ++-- timesheet_add.php | 4 ++-- timesheet_delete.php | 4 ++-- timesheet_edit.php | 4 ++-- timesheet_view.php | 4 ++-- timesheets.php | 4 ++-- 27 files changed, 27 insertions(+), 27 deletions(-) rename WEB-INF/templates/{template_add2.tpl => template_add.tpl} (100%) rename WEB-INF/templates/{template_delete2.tpl => template_delete.tpl} (100%) rename WEB-INF/templates/{template_edit2.tpl => template_edit.tpl} (100%) rename WEB-INF/templates/{templates2.tpl => templates.tpl} (100%) rename WEB-INF/templates/{time2.tpl => time.tpl} (100%) rename WEB-INF/templates/{time_delete2.tpl => time_delete.tpl} (100%) rename WEB-INF/templates/{time_edit2.tpl => time_edit.tpl} (100%) rename WEB-INF/templates/{timer2.tpl => timer.tpl} (100%) rename WEB-INF/templates/{timesheet_add2.tpl => timesheet_add.tpl} (100%) rename WEB-INF/templates/{timesheet_delete2.tpl => timesheet_delete.tpl} (100%) rename WEB-INF/templates/{timesheet_edit2.tpl => timesheet_edit.tpl} (100%) rename WEB-INF/templates/{timesheet_view2.tpl => timesheet_view.tpl} (100%) rename WEB-INF/templates/{timesheets2.tpl => timesheets.tpl} (100%) diff --git a/WEB-INF/templates/template_add2.tpl b/WEB-INF/templates/template_add.tpl similarity index 100% rename from WEB-INF/templates/template_add2.tpl rename to WEB-INF/templates/template_add.tpl diff --git a/WEB-INF/templates/template_delete2.tpl b/WEB-INF/templates/template_delete.tpl similarity index 100% rename from WEB-INF/templates/template_delete2.tpl rename to WEB-INF/templates/template_delete.tpl diff --git a/WEB-INF/templates/template_edit2.tpl b/WEB-INF/templates/template_edit.tpl similarity index 100% rename from WEB-INF/templates/template_edit2.tpl rename to WEB-INF/templates/template_edit.tpl diff --git a/WEB-INF/templates/templates2.tpl b/WEB-INF/templates/templates.tpl similarity index 100% rename from WEB-INF/templates/templates2.tpl rename to WEB-INF/templates/templates.tpl diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time.tpl similarity index 100% rename from WEB-INF/templates/time2.tpl rename to WEB-INF/templates/time.tpl diff --git a/WEB-INF/templates/time_delete2.tpl b/WEB-INF/templates/time_delete.tpl similarity index 100% rename from WEB-INF/templates/time_delete2.tpl rename to WEB-INF/templates/time_delete.tpl diff --git a/WEB-INF/templates/time_edit2.tpl b/WEB-INF/templates/time_edit.tpl similarity index 100% rename from WEB-INF/templates/time_edit2.tpl rename to WEB-INF/templates/time_edit.tpl diff --git a/WEB-INF/templates/timer2.tpl b/WEB-INF/templates/timer.tpl similarity index 100% rename from WEB-INF/templates/timer2.tpl rename to WEB-INF/templates/timer.tpl diff --git a/WEB-INF/templates/timesheet_add2.tpl b/WEB-INF/templates/timesheet_add.tpl similarity index 100% rename from WEB-INF/templates/timesheet_add2.tpl rename to WEB-INF/templates/timesheet_add.tpl diff --git a/WEB-INF/templates/timesheet_delete2.tpl b/WEB-INF/templates/timesheet_delete.tpl similarity index 100% rename from WEB-INF/templates/timesheet_delete2.tpl rename to WEB-INF/templates/timesheet_delete.tpl diff --git a/WEB-INF/templates/timesheet_edit2.tpl b/WEB-INF/templates/timesheet_edit.tpl similarity index 100% rename from WEB-INF/templates/timesheet_edit2.tpl rename to WEB-INF/templates/timesheet_edit.tpl diff --git a/WEB-INF/templates/timesheet_view2.tpl b/WEB-INF/templates/timesheet_view.tpl similarity index 100% rename from WEB-INF/templates/timesheet_view2.tpl rename to WEB-INF/templates/timesheet_view.tpl diff --git a/WEB-INF/templates/timesheets2.tpl b/WEB-INF/templates/timesheets.tpl similarity index 100% rename from WEB-INF/templates/timesheets2.tpl rename to WEB-INF/templates/timesheets.tpl diff --git a/initialize.php b/initialize.php index f69c77a18..c57314c26 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5543"); +define("APP_VERSION", "1.19.28.5544"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/template_add.php b/template_add.php index 6347d22e3..cb84fb33b 100644 --- a/template_add.php +++ b/template_add.php @@ -65,5 +65,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_projects', $bindTemplatesWithProjects && count($projects) > 0); $smarty->assign('title', $i18n->get('title.add_template')); -$smarty->assign('content_page_name', 'template_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'template_add.tpl'); +$smarty->display('index.tpl'); diff --git a/template_delete.php b/template_delete.php index 792cadbd0..a4996e05b 100644 --- a/template_delete.php +++ b/template_delete.php @@ -47,5 +47,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.templateDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_template')); -$smarty->assign('content_page_name', 'template_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'template_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/template_edit.php b/template_edit.php index 3451ff646..814eff591 100644 --- a/template_edit.php +++ b/template_edit.php @@ -83,5 +83,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_projects', $bindTemplatesWithProjects && count($projects) > 0); $smarty->assign('title', $i18n->get('title.edit_template')); -$smarty->assign('content_page_name', 'template_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'template_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/templates.php b/templates.php index 53d57b86f..636d4bc10 100644 --- a/templates.php +++ b/templates.php @@ -59,5 +59,5 @@ $smarty->assign('inactive_templates', $inactiveTemplates); $smarty->assign('show_bind_with_projects_checkbox', $showBindWithProjectsCheckbox); $smarty->assign('title', $i18n->get('title.templates')); -$smarty->assign('content_page_name', 'templates2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'templates.tpl'); +$smarty->display('index.tpl'); diff --git a/time.php b/time.php index 9b366b543..9bd31127f 100644 --- a/time.php +++ b/time.php @@ -488,5 +488,5 @@ $smarty->assign('onload', 'onLoad="fillDropdowns();prepopulateNote();adjustTodayLinks()"'); $smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); $smarty->assign('title', $i18n->get('title.time')); -$smarty->assign('content_page_name', 'time2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'time.tpl'); +$smarty->display('index.tpl'); diff --git a/time_delete.php b/time_delete.php index 5b3849525..9c028dabb 100644 --- a/time_delete.php +++ b/time_delete.php @@ -69,5 +69,5 @@ $smarty->assign('show_duration', $showDuration); $smarty->assign('forms', array($form->getName() => $form->toArray())); $smarty->assign('title', $i18n->get('title.delete_time_record')); -$smarty->assign('content_page_name', 'time_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'time_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/time_edit.php b/time_edit.php index 8e9f31e56..d34ae1ca6 100644 --- a/time_edit.php +++ b/time_edit.php @@ -467,5 +467,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="fillDropdowns()"'); $smarty->assign('title', $i18n->get('title.edit_time_record')); -$smarty->assign('content_page_name', 'time_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'time_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/timer.php b/timer.php index aa51a4dc4..cd0081f3d 100644 --- a/timer.php +++ b/timer.php @@ -307,5 +307,5 @@ $smarty->assign('onload', 'onLoad="fillDropdowns()"'); $smarty->assign('timestring', $selected_date->toString($user->date_format)); $smarty->assign('title', $i18n->get('title.time')); -$smarty->assign('content_page_name', 'timer2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'timer.tpl'); +$smarty->display('index.tpl'); diff --git a/timesheet_add.php b/timesheet_add.php index 5fb15df6e..7361c4f28 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -80,5 +80,5 @@ $smarty->assign('show_client', $showClient); $smarty->assign('show_project', $showProject); $smarty->assign('title', $i18n->get('title.add_timesheet')); -$smarty->assign('content_page_name', 'timesheet_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'timesheet_add.tpl'); +$smarty->display('index.tpl'); diff --git a/timesheet_delete.php b/timesheet_delete.php index b0b847973..ff1e4e180 100644 --- a/timesheet_delete.php +++ b/timesheet_delete.php @@ -47,5 +47,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.invoiceDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_timesheet')); -$smarty->assign('content_page_name', 'timesheet_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'timesheet_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/timesheet_edit.php b/timesheet_edit.php index c9676ed5a..164cc61bb 100644 --- a/timesheet_edit.php +++ b/timesheet_edit.php @@ -81,5 +81,5 @@ $smarty->assign('onload', 'onLoad="document.timesheetForm.timesheet_name.focus()"'); $smarty->assign('can_delete', $canDelete); $smarty->assign('title', $i18n->get('title.edit_timesheet')); -$smarty->assign('content_page_name', 'timesheet_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'timesheet_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/timesheet_view.php b/timesheet_view.php index a74424a6b..905371768 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -126,5 +126,5 @@ $smarty->assign('show_approve', $showApprove); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.timesheet').": ".$timesheet['start_date']." - ".$timesheet['end_date']); -$smarty->assign('content_page_name', 'timesheet_view2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'timesheet_view.tpl'); +$smarty->display('index.tpl'); diff --git a/timesheets.php b/timesheets.php index 54bbc3396..7dbbb78df 100644 --- a/timesheets.php +++ b/timesheets.php @@ -78,5 +78,5 @@ $smarty->assign('show_files', $showFiles); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.timesheets')); -$smarty->assign('content_page_name', 'timesheets2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'timesheets.tpl'); +$smarty->display('index.tpl'); From eea705e1dcf06723cd7f1f334e4f716f8cfaae1a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 17:20:08 +0000 Subject: [PATCH 1559/1848] More work in progress on template renaming. --- WEB-INF/templates/{quotas2.tpl => quotas.tpl} | 0 WEB-INF/templates/{register2.tpl => register.tpl} | 0 WEB-INF/templates/{report2.tpl => report.tpl} | 0 WEB-INF/templates/{reports2.tpl => reports.tpl} | 2 +- WEB-INF/templates/{role_add2.tpl => role_add.tpl} | 0 WEB-INF/templates/{role_delete2.tpl => role_delete.tpl} | 0 WEB-INF/templates/{role_edit2.tpl => role_edit.tpl} | 0 WEB-INF/templates/{roles2.tpl => roles.tpl} | 0 WEB-INF/templates/{success2.tpl => success.tpl} | 0 WEB-INF/templates/{swap_roles2.tpl => swap_roles.tpl} | 0 WEB-INF/templates/{task_add2.tpl => task_add.tpl} | 0 WEB-INF/templates/{task_delete2.tpl => task_delete.tpl} | 0 WEB-INF/templates/{task_edit2.tpl => task_edit.tpl} | 0 WEB-INF/templates/{tasks2.tpl => tasks.tpl} | 0 initialize.php | 2 +- quotas.php | 4 ++-- register.php | 4 ++-- report.php | 4 ++-- reports.php | 4 ++-- role_add.php | 4 ++-- role_delete.php | 4 ++-- role_edit.php | 4 ++-- roles.php | 4 ++-- success.php | 4 ++-- swap_roles.php | 4 ++-- task_add.php | 4 ++-- task_delete.php | 4 ++-- task_edit.php | 4 ++-- tasks.php | 4 ++-- 29 files changed, 30 insertions(+), 30 deletions(-) rename WEB-INF/templates/{quotas2.tpl => quotas.tpl} (100%) rename WEB-INF/templates/{register2.tpl => register.tpl} (100%) rename WEB-INF/templates/{report2.tpl => report.tpl} (100%) rename WEB-INF/templates/{reports2.tpl => reports.tpl} (99%) rename WEB-INF/templates/{role_add2.tpl => role_add.tpl} (100%) rename WEB-INF/templates/{role_delete2.tpl => role_delete.tpl} (100%) rename WEB-INF/templates/{role_edit2.tpl => role_edit.tpl} (100%) rename WEB-INF/templates/{roles2.tpl => roles.tpl} (100%) rename WEB-INF/templates/{success2.tpl => success.tpl} (100%) rename WEB-INF/templates/{swap_roles2.tpl => swap_roles.tpl} (100%) rename WEB-INF/templates/{task_add2.tpl => task_add.tpl} (100%) rename WEB-INF/templates/{task_delete2.tpl => task_delete.tpl} (100%) rename WEB-INF/templates/{task_edit2.tpl => task_edit.tpl} (100%) rename WEB-INF/templates/{tasks2.tpl => tasks.tpl} (100%) diff --git a/WEB-INF/templates/quotas2.tpl b/WEB-INF/templates/quotas.tpl similarity index 100% rename from WEB-INF/templates/quotas2.tpl rename to WEB-INF/templates/quotas.tpl diff --git a/WEB-INF/templates/register2.tpl b/WEB-INF/templates/register.tpl similarity index 100% rename from WEB-INF/templates/register2.tpl rename to WEB-INF/templates/register.tpl diff --git a/WEB-INF/templates/report2.tpl b/WEB-INF/templates/report.tpl similarity index 100% rename from WEB-INF/templates/report2.tpl rename to WEB-INF/templates/report.tpl diff --git a/WEB-INF/templates/reports2.tpl b/WEB-INF/templates/reports.tpl similarity index 99% rename from WEB-INF/templates/reports2.tpl rename to WEB-INF/templates/reports.tpl index 294d5ea7c..aa8e9d633 100644 --- a/WEB-INF/templates/reports2.tpl +++ b/WEB-INF/templates/reports.tpl @@ -121,7 +121,7 @@ function fillProjectDropdown(id) { function fillTaskDropdown(project_id) { var str_task_ids; // Get a string of comma-separated task ids. - if (project_id) { + if (project_id) { var property = "p" + project_id; str_task_ids = obj_tasks[property]; } diff --git a/WEB-INF/templates/role_add2.tpl b/WEB-INF/templates/role_add.tpl similarity index 100% rename from WEB-INF/templates/role_add2.tpl rename to WEB-INF/templates/role_add.tpl diff --git a/WEB-INF/templates/role_delete2.tpl b/WEB-INF/templates/role_delete.tpl similarity index 100% rename from WEB-INF/templates/role_delete2.tpl rename to WEB-INF/templates/role_delete.tpl diff --git a/WEB-INF/templates/role_edit2.tpl b/WEB-INF/templates/role_edit.tpl similarity index 100% rename from WEB-INF/templates/role_edit2.tpl rename to WEB-INF/templates/role_edit.tpl diff --git a/WEB-INF/templates/roles2.tpl b/WEB-INF/templates/roles.tpl similarity index 100% rename from WEB-INF/templates/roles2.tpl rename to WEB-INF/templates/roles.tpl diff --git a/WEB-INF/templates/success2.tpl b/WEB-INF/templates/success.tpl similarity index 100% rename from WEB-INF/templates/success2.tpl rename to WEB-INF/templates/success.tpl diff --git a/WEB-INF/templates/swap_roles2.tpl b/WEB-INF/templates/swap_roles.tpl similarity index 100% rename from WEB-INF/templates/swap_roles2.tpl rename to WEB-INF/templates/swap_roles.tpl diff --git a/WEB-INF/templates/task_add2.tpl b/WEB-INF/templates/task_add.tpl similarity index 100% rename from WEB-INF/templates/task_add2.tpl rename to WEB-INF/templates/task_add.tpl diff --git a/WEB-INF/templates/task_delete2.tpl b/WEB-INF/templates/task_delete.tpl similarity index 100% rename from WEB-INF/templates/task_delete2.tpl rename to WEB-INF/templates/task_delete.tpl diff --git a/WEB-INF/templates/task_edit2.tpl b/WEB-INF/templates/task_edit.tpl similarity index 100% rename from WEB-INF/templates/task_edit2.tpl rename to WEB-INF/templates/task_edit.tpl diff --git a/WEB-INF/templates/tasks2.tpl b/WEB-INF/templates/tasks.tpl similarity index 100% rename from WEB-INF/templates/tasks2.tpl rename to WEB-INF/templates/tasks.tpl diff --git a/initialize.php b/initialize.php index c57314c26..b2857f6ed 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5544"); +define("APP_VERSION", "1.19.28.5545"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/quotas.php b/quotas.php index c49fbf1f7..55214093f 100644 --- a/quotas.php +++ b/quotas.php @@ -107,5 +107,5 @@ $smarty->assign('months', $months); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.monthly_quotas')); -$smarty->assign('content_page_name', 'quotas2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'quotas.tpl'); +$smarty->display('index.tpl'); diff --git a/register.php b/register.php index 220376138..35fbee9cc 100644 --- a/register.php +++ b/register.php @@ -96,5 +96,5 @@ $smarty->assign('title', $i18n->get('title.add_group')); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.groupForm.group_name.focus()"'); -$smarty->assign('content_page_name', 'register2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'register.tpl'); +$smarty->display('index.tpl'); diff --git a/report.php b/report.php index cb959d488..bd2576f14 100644 --- a/report.php +++ b/report.php @@ -320,5 +320,5 @@ $smarty->assign('colspan', $colspan); $smarty->assign('bean', $bean); $smarty->assign('title', $i18n->get('title.report').": ".$totals['start_date']." - ".$totals['end_date']); -$smarty->assign('content_page_name', 'report2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'report.tpl'); +$smarty->display('index.tpl'); diff --git a/reports.php b/reports.php index 71f455bea..059c7d903 100644 --- a/reports.php +++ b/reports.php @@ -492,5 +492,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="handleCheckboxes();fillDropdowns()"'); $smarty->assign('title', $i18n->get('title.reports')); -$smarty->assign('content_page_name', 'reports2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'reports.tpl'); +$smarty->display('index.tpl'); diff --git a/role_add.php b/role_add.php index 54fd9bdb5..b2879dd8f 100644 --- a/role_add.php +++ b/role_add.php @@ -55,5 +55,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.add_role')); -$smarty->assign('content_page_name', 'role_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'role_add.tpl'); +$smarty->display('index.tpl'); diff --git a/role_delete.php b/role_delete.php index 805c89dba..e2f0805eb 100644 --- a/role_delete.php +++ b/role_delete.php @@ -46,5 +46,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_role')); -$smarty->assign('content_page_name', 'role_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'role_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/role_edit.php b/role_edit.php index 03e1d2473..5192ee62d 100644 --- a/role_edit.php +++ b/role_edit.php @@ -115,5 +115,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_role')); -$smarty->assign('content_page_name', 'role_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'role_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/roles.php b/roles.php index f2795fb0f..569f2649a 100644 --- a/roles.php +++ b/roles.php @@ -17,5 +17,5 @@ $smarty->assign('active_roles', ttTeamHelper::getActiveRolesForUser()); $smarty->assign('inactive_roles', ttTeamHelper::getInactiveRolesForUser()); $smarty->assign('title', $i18n->get('title.roles')); -$smarty->assign('content_page_name', 'roles2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'roles.tpl'); +$smarty->display('index.tpl'); diff --git a/success.php b/success.php index eea4687a2..6fbf8ad2a 100644 --- a/success.php +++ b/success.php @@ -8,5 +8,5 @@ if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. $smarty->assign('title', $i18n->get('title.success')); -$smarty->assign('content_page_name', 'success2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'success.tpl'); +$smarty->display('index.tpl'); diff --git a/swap_roles.php b/swap_roles.php index e49bed75b..7a036a777 100644 --- a/swap_roles.php +++ b/swap_roles.php @@ -49,5 +49,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.swapForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.swap_roles')); -$smarty->assign('content_page_name', 'swap_roles2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'swap_roles.tpl'); +$smarty->display('index.tpl'); diff --git a/task_add.php b/task_add.php index 4888677f1..3d8dcc1c7 100644 --- a/task_add.php +++ b/task_add.php @@ -62,5 +62,5 @@ $smarty->assign('show_projects', count($projects) > 0); $smarty->assign('onload', 'onLoad="document.taskForm.name.focus()"'); $smarty->assign('title', $i18n->get('title.add_task')); -$smarty->assign('content_page_name', 'task_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'task_add.tpl'); +$smarty->display('index.tpl'); diff --git a/task_delete.php b/task_delete.php index 61f5e23ff..04008010f 100644 --- a/task_delete.php +++ b/task_delete.php @@ -50,5 +50,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_task')); -$smarty->assign('content_page_name', 'task_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'task_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/task_edit.php b/task_edit.php index 4b9a72aef..b2b61b80b 100644 --- a/task_edit.php +++ b/task_edit.php @@ -96,5 +96,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_projects', count($projects) > 0); $smarty->assign('title', $i18n->get('title.edit_task')); -$smarty->assign('content_page_name', 'task_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'task_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/tasks.php b/tasks.php index 464af6159..13787a8ab 100644 --- a/tasks.php +++ b/tasks.php @@ -49,5 +49,5 @@ $smarty->assign('active_tasks', $active_tasks); $smarty->assign('inactive_tasks', $inactive_tasks); $smarty->assign('title', $i18n->get('title.tasks')); -$smarty->assign('content_page_name', 'tasks2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'tasks.tpl'); +$smarty->display('index.tpl'); From 01dfa61fb9f34b4559d6be25e6efee210a2f046d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 18:00:57 +0000 Subject: [PATCH 1560/1848] More templates renamed. --- .../templates/{password_change2.tpl => password_change.tpl} | 0 WEB-INF/templates/{password_reset2.tpl => password_reset.tpl} | 0 WEB-INF/templates/{plugins2.tpl => plugins.tpl} | 0 ...predefined_expense_add2.tpl => predefined_expense_add.tpl} | 0 ...ined_expense_delete2.tpl => predefined_expense_delete.tpl} | 0 ...edefined_expense_edit2.tpl => predefined_expense_edit.tpl} | 0 .../{predefined_expenses2.tpl => predefined_expenses.tpl} | 0 WEB-INF/templates/{profile_edit2.tpl => profile_edit.tpl} | 0 WEB-INF/templates/{project_add2.tpl => project_add.tpl} | 0 WEB-INF/templates/{project_delete2.tpl => project_delete.tpl} | 0 WEB-INF/templates/{project_edit2.tpl => project_edit.tpl} | 0 WEB-INF/templates/{projects2.tpl => projects.tpl} | 0 initialize.php | 2 +- password_change.php | 4 ++-- password_reset.php | 4 ++-- plugins.php | 4 ++-- predefined_expense_add.php | 4 ++-- predefined_expense_delete.php | 4 ++-- predefined_expense_edit.php | 4 ++-- predefined_expenses.php | 4 ++-- profile_edit.php | 4 ++-- project_add.php | 4 ++-- project_delete.php | 4 ++-- project_edit.php | 4 ++-- projects.php | 4 ++-- 25 files changed, 25 insertions(+), 25 deletions(-) rename WEB-INF/templates/{password_change2.tpl => password_change.tpl} (100%) rename WEB-INF/templates/{password_reset2.tpl => password_reset.tpl} (100%) rename WEB-INF/templates/{plugins2.tpl => plugins.tpl} (100%) rename WEB-INF/templates/{predefined_expense_add2.tpl => predefined_expense_add.tpl} (100%) rename WEB-INF/templates/{predefined_expense_delete2.tpl => predefined_expense_delete.tpl} (100%) rename WEB-INF/templates/{predefined_expense_edit2.tpl => predefined_expense_edit.tpl} (100%) rename WEB-INF/templates/{predefined_expenses2.tpl => predefined_expenses.tpl} (100%) rename WEB-INF/templates/{profile_edit2.tpl => profile_edit.tpl} (100%) rename WEB-INF/templates/{project_add2.tpl => project_add.tpl} (100%) rename WEB-INF/templates/{project_delete2.tpl => project_delete.tpl} (100%) rename WEB-INF/templates/{project_edit2.tpl => project_edit.tpl} (100%) rename WEB-INF/templates/{projects2.tpl => projects.tpl} (100%) diff --git a/WEB-INF/templates/password_change2.tpl b/WEB-INF/templates/password_change.tpl similarity index 100% rename from WEB-INF/templates/password_change2.tpl rename to WEB-INF/templates/password_change.tpl diff --git a/WEB-INF/templates/password_reset2.tpl b/WEB-INF/templates/password_reset.tpl similarity index 100% rename from WEB-INF/templates/password_reset2.tpl rename to WEB-INF/templates/password_reset.tpl diff --git a/WEB-INF/templates/plugins2.tpl b/WEB-INF/templates/plugins.tpl similarity index 100% rename from WEB-INF/templates/plugins2.tpl rename to WEB-INF/templates/plugins.tpl diff --git a/WEB-INF/templates/predefined_expense_add2.tpl b/WEB-INF/templates/predefined_expense_add.tpl similarity index 100% rename from WEB-INF/templates/predefined_expense_add2.tpl rename to WEB-INF/templates/predefined_expense_add.tpl diff --git a/WEB-INF/templates/predefined_expense_delete2.tpl b/WEB-INF/templates/predefined_expense_delete.tpl similarity index 100% rename from WEB-INF/templates/predefined_expense_delete2.tpl rename to WEB-INF/templates/predefined_expense_delete.tpl diff --git a/WEB-INF/templates/predefined_expense_edit2.tpl b/WEB-INF/templates/predefined_expense_edit.tpl similarity index 100% rename from WEB-INF/templates/predefined_expense_edit2.tpl rename to WEB-INF/templates/predefined_expense_edit.tpl diff --git a/WEB-INF/templates/predefined_expenses2.tpl b/WEB-INF/templates/predefined_expenses.tpl similarity index 100% rename from WEB-INF/templates/predefined_expenses2.tpl rename to WEB-INF/templates/predefined_expenses.tpl diff --git a/WEB-INF/templates/profile_edit2.tpl b/WEB-INF/templates/profile_edit.tpl similarity index 100% rename from WEB-INF/templates/profile_edit2.tpl rename to WEB-INF/templates/profile_edit.tpl diff --git a/WEB-INF/templates/project_add2.tpl b/WEB-INF/templates/project_add.tpl similarity index 100% rename from WEB-INF/templates/project_add2.tpl rename to WEB-INF/templates/project_add.tpl diff --git a/WEB-INF/templates/project_delete2.tpl b/WEB-INF/templates/project_delete.tpl similarity index 100% rename from WEB-INF/templates/project_delete2.tpl rename to WEB-INF/templates/project_delete.tpl diff --git a/WEB-INF/templates/project_edit2.tpl b/WEB-INF/templates/project_edit.tpl similarity index 100% rename from WEB-INF/templates/project_edit2.tpl rename to WEB-INF/templates/project_edit.tpl diff --git a/WEB-INF/templates/projects2.tpl b/WEB-INF/templates/projects.tpl similarity index 100% rename from WEB-INF/templates/projects2.tpl rename to WEB-INF/templates/projects.tpl diff --git a/initialize.php b/initialize.php index b2857f6ed..691f66ed2 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5545"); +define("APP_VERSION", "1.19.28.5546"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/password_change.php b/password_change.php index f501a78e5..992bdd87b 100644 --- a/password_change.php +++ b/password_change.php @@ -77,5 +77,5 @@ $smarty->assign('forms', array($form->getName() => $form->toArray())); $smarty->assign('title', $i18n->get('title.change_password')); -$smarty->assign('content_page_name', 'password_change2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'password_change.tpl'); +$smarty->display('index.tpl'); diff --git a/password_reset.php b/password_reset.php index a9dfd1f0a..9645139e4 100644 --- a/password_reset.php +++ b/password_reset.php @@ -106,5 +106,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.resetPasswordForm.login.focus()"'); $smarty->assign('title', $i18n->get('title.reset_password')); -$smarty->assign('content_page_name', 'password_reset2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'password_reset.tpl'); +$smarty->display('index.tpl'); diff --git a/plugins.php b/plugins.php index 730889bc0..9b3bc1a27 100644 --- a/plugins.php +++ b/plugins.php @@ -141,5 +141,5 @@ $smarty->assign('onload', 'onLoad="handlePluginCheckboxes();"'); $smarty->assign('user_exists', $user->exists()); $smarty->assign('title', $i18n->get('title.plugins')); -$smarty->assign('content_page_name', 'plugins2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'plugins.tpl'); +$smarty->display('index.tpl'); diff --git a/predefined_expense_add.php b/predefined_expense_add.php index 8cac318f1..08e395ce2 100644 --- a/predefined_expense_add.php +++ b/predefined_expense_add.php @@ -45,5 +45,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.add_predefined_expense')); -$smarty->assign('content_page_name', 'predefined_expense_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'predefined_expense_add.tpl'); +$smarty->display('index.tpl'); diff --git a/predefined_expense_delete.php b/predefined_expense_delete.php index 26b726fc1..e965b0be2 100644 --- a/predefined_expense_delete.php +++ b/predefined_expense_delete.php @@ -48,5 +48,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.predefinedExpenseDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_predefined_expense')); -$smarty->assign('content_page_name', 'predefined_expense_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'predefined_expense_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/predefined_expense_edit.php b/predefined_expense_edit.php index d1b557553..8f4750245 100644 --- a/predefined_expense_edit.php +++ b/predefined_expense_edit.php @@ -55,5 +55,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_predefined_expense')); -$smarty->assign('content_page_name', 'predefined_expense_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'predefined_expense_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/predefined_expenses.php b/predefined_expenses.php index c44aee27b..9f94bd1cc 100644 --- a/predefined_expenses.php +++ b/predefined_expenses.php @@ -33,5 +33,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('predefined_expenses', $predefinedExpenses); $smarty->assign('title', $i18n->get('title.predefined_expenses')); -$smarty->assign('content_page_name', 'predefined_expenses2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'predefined_expenses.tpl'); +$smarty->display('index.tpl'); diff --git a/profile_edit.php b/profile_edit.php index f85473fe4..a9f11fc2d 100644 --- a/profile_edit.php +++ b/profile_edit.php @@ -87,5 +87,5 @@ $smarty->assign('auth_external', $auth->isPasswordExternal()); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.profile')); -$smarty->assign('content_page_name', 'profile_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'profile_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/project_add.php b/project_add.php index 16af7a8d1..35b45c97a 100644 --- a/project_add.php +++ b/project_add.php @@ -91,5 +91,5 @@ $smarty->assign('show_users', count($users) > 0); $smarty->assign('show_tasks', $show_tasks); $smarty->assign('title', $i18n->get('title.add_project')); -$smarty->assign('content_page_name', 'project_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'project_add.tpl'); +$smarty->display('index.tpl'); diff --git a/project_delete.php b/project_delete.php index 2d6ca2895..4f4353b87 100644 --- a/project_delete.php +++ b/project_delete.php @@ -47,5 +47,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.projectDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_project')); -$smarty->assign('content_page_name', 'project_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'project_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/project_edit.php b/project_edit.php index cbb2c1f9b..917b2e974 100644 --- a/project_edit.php +++ b/project_edit.php @@ -108,5 +108,5 @@ $smarty->assign('show_users', count($users) > 0); $smarty->assign('show_tasks', $show_tasks); $smarty->assign('title', $i18n->get('title.edit_project')); -$smarty->assign('content_page_name', 'project_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'project_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/projects.php b/projects.php index e9a0b5dcf..ed4d371df 100644 --- a/projects.php +++ b/projects.php @@ -30,5 +30,5 @@ $smarty->assign('inactive_projects', $inactive_projects); $smarty->assign('show_files', $showFiles); $smarty->assign('title', $i18n->get('title.projects')); -$smarty->assign('content_page_name', 'projects2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'projects.tpl'); +$smarty->display('index.tpl'); From 339fea0fc8c13ba9ad30064f9d255b10761184b3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 18:20:47 +0000 Subject: [PATCH 1561/1848] Finished renaming template files. --- WEB-INF/templates/index2.tpl | 5 ----- WEB-INF/templates/{invoice_add2.tpl => invoice_add.tpl} | 0 .../templates/{invoice_delete2.tpl => invoice_delete.tpl} | 0 WEB-INF/templates/{invoice_view2.tpl => invoice_view.tpl} | 0 WEB-INF/templates/{invoices2.tpl => invoices.tpl} | 0 WEB-INF/templates/{locking2.tpl => locking.tpl} | 0 WEB-INF/templates/{login.db2.tpl => login.db.tpl} | 0 WEB-INF/templates/{login.ldap2.tpl => login.ldap.tpl} | 0 WEB-INF/templates/{login2.tpl => login.tpl} | 2 +- WEB-INF/templates/{mail2.tpl => mail.tpl} | 0 .../{notification_add2.tpl => notification_add.tpl} | 0 .../{notification_delete2.tpl => notification_delete.tpl} | 0 .../{notification_edit2.tpl => notification_edit.tpl} | 0 WEB-INF/templates/{notifications2.tpl => notifications.tpl} | 0 initialize.php | 2 +- invoice_add.php | 4 ++-- invoice_delete.php | 4 ++-- invoice_send.php | 4 ++-- invoice_view.php | 4 ++-- invoices.php | 4 ++-- locking.php | 4 ++-- login.php | 6 +++--- notification_add.php | 4 ++-- notification_delete.php | 4 ++-- notification_edit.php | 4 ++-- notifications.php | 4 ++-- report_send.php | 4 ++-- site_map.php | 2 +- 28 files changed, 28 insertions(+), 33 deletions(-) delete mode 100644 WEB-INF/templates/index2.tpl rename WEB-INF/templates/{invoice_add2.tpl => invoice_add.tpl} (100%) rename WEB-INF/templates/{invoice_delete2.tpl => invoice_delete.tpl} (100%) rename WEB-INF/templates/{invoice_view2.tpl => invoice_view.tpl} (100%) rename WEB-INF/templates/{invoices2.tpl => invoices.tpl} (100%) rename WEB-INF/templates/{locking2.tpl => locking.tpl} (100%) rename WEB-INF/templates/{login.db2.tpl => login.db.tpl} (100%) rename WEB-INF/templates/{login.ldap2.tpl => login.ldap.tpl} (100%) rename WEB-INF/templates/{login2.tpl => login.tpl} (85%) rename WEB-INF/templates/{mail2.tpl => mail.tpl} (100%) rename WEB-INF/templates/{notification_add2.tpl => notification_add.tpl} (100%) rename WEB-INF/templates/{notification_delete2.tpl => notification_delete.tpl} (100%) rename WEB-INF/templates/{notification_edit2.tpl => notification_edit.tpl} (100%) rename WEB-INF/templates/{notifications2.tpl => notifications.tpl} (100%) diff --git a/WEB-INF/templates/index2.tpl b/WEB-INF/templates/index2.tpl deleted file mode 100644 index 75a751e08..000000000 --- a/WEB-INF/templates/index2.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{include file="header.tpl"} - -{if $content_page_name}{include file="$content_page_name"}{/if} - -{include file="footer.tpl"} diff --git a/WEB-INF/templates/invoice_add2.tpl b/WEB-INF/templates/invoice_add.tpl similarity index 100% rename from WEB-INF/templates/invoice_add2.tpl rename to WEB-INF/templates/invoice_add.tpl diff --git a/WEB-INF/templates/invoice_delete2.tpl b/WEB-INF/templates/invoice_delete.tpl similarity index 100% rename from WEB-INF/templates/invoice_delete2.tpl rename to WEB-INF/templates/invoice_delete.tpl diff --git a/WEB-INF/templates/invoice_view2.tpl b/WEB-INF/templates/invoice_view.tpl similarity index 100% rename from WEB-INF/templates/invoice_view2.tpl rename to WEB-INF/templates/invoice_view.tpl diff --git a/WEB-INF/templates/invoices2.tpl b/WEB-INF/templates/invoices.tpl similarity index 100% rename from WEB-INF/templates/invoices2.tpl rename to WEB-INF/templates/invoices.tpl diff --git a/WEB-INF/templates/locking2.tpl b/WEB-INF/templates/locking.tpl similarity index 100% rename from WEB-INF/templates/locking2.tpl rename to WEB-INF/templates/locking.tpl diff --git a/WEB-INF/templates/login.db2.tpl b/WEB-INF/templates/login.db.tpl similarity index 100% rename from WEB-INF/templates/login.db2.tpl rename to WEB-INF/templates/login.db.tpl diff --git a/WEB-INF/templates/login.ldap2.tpl b/WEB-INF/templates/login.ldap.tpl similarity index 100% rename from WEB-INF/templates/login.ldap2.tpl rename to WEB-INF/templates/login.ldap.tpl diff --git a/WEB-INF/templates/login2.tpl b/WEB-INF/templates/login.tpl similarity index 85% rename from WEB-INF/templates/login2.tpl rename to WEB-INF/templates/login.tpl index 755763c35..e6a8a4ed3 100644 --- a/WEB-INF/templates/login2.tpl +++ b/WEB-INF/templates/login.tpl @@ -9,7 +9,7 @@ function get_date() { {$forms.loginForm.open} -{include file="login.`$smarty.const.AUTH_MODULE`2.tpl"} +{include file="login.`$smarty.const.AUTH_MODULE`.tpl"} {$forms.loginForm.close} {if !empty($about_text)} diff --git a/WEB-INF/templates/mail2.tpl b/WEB-INF/templates/mail.tpl similarity index 100% rename from WEB-INF/templates/mail2.tpl rename to WEB-INF/templates/mail.tpl diff --git a/WEB-INF/templates/notification_add2.tpl b/WEB-INF/templates/notification_add.tpl similarity index 100% rename from WEB-INF/templates/notification_add2.tpl rename to WEB-INF/templates/notification_add.tpl diff --git a/WEB-INF/templates/notification_delete2.tpl b/WEB-INF/templates/notification_delete.tpl similarity index 100% rename from WEB-INF/templates/notification_delete2.tpl rename to WEB-INF/templates/notification_delete.tpl diff --git a/WEB-INF/templates/notification_edit2.tpl b/WEB-INF/templates/notification_edit.tpl similarity index 100% rename from WEB-INF/templates/notification_edit2.tpl rename to WEB-INF/templates/notification_edit.tpl diff --git a/WEB-INF/templates/notifications2.tpl b/WEB-INF/templates/notifications.tpl similarity index 100% rename from WEB-INF/templates/notifications2.tpl rename to WEB-INF/templates/notifications.tpl diff --git a/initialize.php b/initialize.php index 691f66ed2..0df7d7ecf 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5546"); +define("APP_VERSION", "1.19.28.5547"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/invoice_add.php b/invoice_add.php index bc337a000..e7018f009 100644 --- a/invoice_add.php +++ b/invoice_add.php @@ -80,5 +80,5 @@ $smarty->assign('onload', 'onLoad="document.invoiceForm.number.focus()"'); $smarty->assign('show_project', $show_project); $smarty->assign('title', $i18n->get('title.add_invoice')); -$smarty->assign('content_page_name', 'invoice_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'invoice_add.tpl'); +$smarty->display('index.tpl'); diff --git a/invoice_delete.php b/invoice_delete.php index 7e80b1265..5b473dfa0 100644 --- a/invoice_delete.php +++ b/invoice_delete.php @@ -51,5 +51,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.invoiceDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_invoice')); -$smarty->assign('content_page_name', 'invoice_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'invoice_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/invoice_send.php b/invoice_send.php index c3126eb9c..5483a09b1 100644 --- a/invoice_send.php +++ b/invoice_send.php @@ -80,5 +80,5 @@ $smarty->assign('title', $i18n->get('title.send_invoice')); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.mailForm.'.($cl_receiver?'comment':'receiver').'.focus()"'); -$smarty->assign('content_page_name', 'mail2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'mail.tpl'); +$smarty->display('index.tpl'); diff --git a/invoice_view.php b/invoice_view.php index 621ae4a0c..b03b719e4 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -107,5 +107,5 @@ $smarty->assign('invoice_items', $invoice_items); $smarty->assign('colspan', $colspan); $smarty->assign('title', $i18n->get('title.view_invoice')); -$smarty->assign('content_page_name', 'invoice_view2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'invoice_view.tpl'); +$smarty->display('index.tpl'); diff --git a/invoices.php b/invoices.php index bbca99cc7..3f6438b96 100644 --- a/invoices.php +++ b/invoices.php @@ -90,5 +90,5 @@ $smarty->assign('show_sorting_options', count($invoices) > 1); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.invoices')); -$smarty->assign('content_page_name', 'invoices2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'invoices.tpl'); +$smarty->display('index.tpl'); diff --git a/locking.php b/locking.php index 5277ec90d..04c8d9419 100644 --- a/locking.php +++ b/locking.php @@ -37,5 +37,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.locking')); -$smarty->assign('content_page_name', 'locking2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'locking.tpl'); +$smarty->display('index.tpl'); diff --git a/login.php b/login.php index 31d7f6d19..09c7af141 100644 --- a/login.php +++ b/login.php @@ -60,7 +60,7 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_hint', $show_hint); $smarty->assign('onload', 'onLoad="document.loginForm.'.(!$cl_login?'login':'password').'.focus()"'); -$smarty->assign('title', $i18n->get('title.login')); -$smarty->assign('content_page_name', 'login2.tpl'); $smarty->assign('about_text', $i18n->get('form.login.about')); -$smarty->display('index2.tpl'); +$smarty->assign('title', $i18n->get('title.login')); +$smarty->assign('content_page_name', 'login.tpl'); +$smarty->display('index.tpl'); diff --git a/notification_add.php b/notification_add.php index 1290bfa23..99602fe5d 100644 --- a/notification_add.php +++ b/notification_add.php @@ -95,5 +95,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.add_notification')); -$smarty->assign('content_page_name', 'notification_add2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'notification_add.tpl'); +$smarty->display('index.tpl'); diff --git a/notification_delete.php b/notification_delete.php index 741826c03..93820427c 100644 --- a/notification_delete.php +++ b/notification_delete.php @@ -51,5 +51,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.notificationDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_notification')); -$smarty->assign('content_page_name', 'notification_delete2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'notification_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/notification_edit.php b/notification_edit.php index 43dbabcff..164127e93 100644 --- a/notification_edit.php +++ b/notification_edit.php @@ -106,5 +106,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_notification')); -$smarty->assign('content_page_name', 'notification_edit2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'notification_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/notifications.php b/notifications.php index 23d1feb16..5945320ef 100644 --- a/notifications.php +++ b/notifications.php @@ -40,5 +40,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('notifications', $notifications); $smarty->assign('title', $i18n->get('title.notifications')); -$smarty->assign('content_page_name', 'notifications2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'notifications.tpl'); +$smarty->display('index.tpl'); diff --git a/report_send.php b/report_send.php index 67e7136c6..b20dd6dfe 100644 --- a/report_send.php +++ b/report_send.php @@ -74,5 +74,5 @@ $smarty->assign('title', $i18n->get('title.send_report')); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.mailForm.'.($cl_receiver?'comment':'receiver').'.focus()"'); -$smarty->assign('content_page_name', 'mail2.tpl'); -$smarty->display('index2.tpl'); +$smarty->assign('content_page_name', 'mail.tpl'); +$smarty->display('index.tpl'); diff --git a/site_map.php b/site_map.php index 56a79511b..11695f781 100644 --- a/site_map.php +++ b/site_map.php @@ -14,4 +14,4 @@ // $smarty->assign('title', $i18n->get('form.label.menu')); $smarty->assign('content_page_name', 'site_map.tpl'); -$smarty->display('index2.tpl'); +$smarty->display('index.tpl'); From dc81e09a376196a503bc9ce0c6a0540b3721985f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 10 May 2021 18:31:47 +0000 Subject: [PATCH 1562/1848] Addressed a php warning. --- initialize.php | 2 +- reports.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/initialize.php b/initialize.php index 0df7d7ecf..daa1667ab 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5547"); +define("APP_VERSION", "1.19.28.5548"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports.php b/reports.php index 059c7d903..b71706220 100644 --- a/reports.php +++ b/reports.php @@ -167,7 +167,7 @@ // Add user table. $showUsers = $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient(); -$user_list = array(); +$user_list = $user_list_active = $user_list_inactive = array(); if ($showUsers) { // Prepare user and assigned projects arrays. if ($user->can('view_reports') || $user->can('view_all_reports')) { @@ -206,7 +206,6 @@ 'layout'=>'V', 'groupin'=>$row_count)); - $user_list_inactive = array(); foreach ($inactive_users as $single_user) { $user_list_inactive[$single_user['id']] = $single_user['name']; $projects = ttProjectHelper::getAssignedProjects($single_user['id']); From 49e89ce143d21f13c22919bdd8a168db25ec12f8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 11 May 2021 13:02:46 +0000 Subject: [PATCH 1563/1848] Added a what is it link explaning delete invoice entries option. --- WEB-INF/templates/invoice_delete.tpl | 5 ++++- initialize.php | 2 +- site_map.php | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/invoice_delete.tpl b/WEB-INF/templates/invoice_delete.tpl index 6fb7cb6c4..951e5e816 100644 --- a/WEB-INF/templates/invoice_delete.tpl +++ b/WEB-INF/templates/invoice_delete.tpl @@ -23,7 +23,10 @@ License: See license.txt *}
{$forms.invoiceDeleteForm.delete_invoice_entries.control}{$forms.invoiceDeleteForm.delete_invoice_entries.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
diff --git a/initialize.php b/initialize.php index daa1667ab..90c7b3096 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5548"); +define("APP_VERSION", "1.19.28.5549"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/site_map.php b/site_map.php index 11695f781..f769edd76 100644 --- a/site_map.php +++ b/site_map.php @@ -12,6 +12,5 @@ global $auth; $authenticated = $auth->isAuthenticated(); // This call assigns 'authenticated' to smarty. -// $smarty->assign('title', $i18n->get('form.label.menu')); $smarty->assign('content_page_name', 'site_map.tpl'); $smarty->display('index.tpl'); From b141c562ab1802dc2a3c20a68d2d7254f4bc5def Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 14 May 2021 14:12:52 +0000 Subject: [PATCH 1564/1848] Fixed presentation issue on the login page. --- default.css | 2 -- initialize.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/default.css b/default.css index e04cab3d5..956c35ed5 100644 --- a/default.css +++ b/default.css @@ -799,8 +799,6 @@ input[type=checkbox], label { div.table-divider { height: 30px; } -div#LoginAboutText { width: 400px; } - .uncompleted-entry { display: inline-block; height: 8px; diff --git a/initialize.php b/initialize.php index 90c7b3096..9c2bae6f8 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5549"); +define("APP_VERSION", "1.19.28.5550"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 3a89ce9194bd0a38a4a9a854844455367390a72f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 14 May 2021 23:45:36 +0000 Subject: [PATCH 1565/1848] Removed no longer needed NOTE_INPUT_HEIGHT from config.php.dist. --- WEB-INF/config.php.dist | 2 -- initialize.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index bbf647cec..9d9d90dfd 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -176,8 +176,6 @@ define('AUTH_MODULE', 'db'); // define('MONTHLY_QUOTA_YEAR_START', 2010); // If nothing is specified, it falls back to 2015. // define('MONTHLY_QUOTA_YEAR_END', 2025); // If nothing is specified, it falls back to 2030. -// Height in pixels for the note input field in time.php. Defaults to 40. -// define('NOTE_INPUT_HEIGHT', 100); // A comma-separated list of default plugins for new group registrations. // Example below enables charts and attachments. diff --git a/initialize.php b/initialize.php index 9c2bae6f8..2942020c1 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5550"); +define("APP_VERSION", "1.19.28.5551"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From bc04705f7a876c73a68c49a4513acbf161e8741f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 15 May 2021 13:27:55 +0000 Subject: [PATCH 1566/1848] Introduced a what is it link explaining custom CSS in display options. --- WEB-INF/templates/display_options.tpl | 1 + initialize.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index e4da2cfac..8c9db8ea7 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -45,6 +45,7 @@ License: See license.txt *}
{$i18n.form.display_options.custom_css}
{$forms.displayOptionsForm.custom_css.control}
{$i18n.label.what_is_it}
{$forms.displayOptionsForm.btn_save.control}
diff --git a/initialize.php b/initialize.php index 2942020c1..dca1b42e7 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5551"); +define("APP_VERSION", "1.19.28.5552"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From beec12ef1f35549ab44b3f19a3ed5cf4785e0446 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 15 May 2021 14:54:33 +0000 Subject: [PATCH 1567/1848] Addressed a couple of php8 warnings. --- WEB-INF/lib/ttWeekViewHelper.class.php | 10 ++++++---- initialize.php | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index 55e40dc18..421676312 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -406,8 +406,9 @@ static function getLockedDaysForWeek($start_date) { static function makeRowIdentifier($record) { global $user; // Start with client. + $row_identifier = ''; if ($user->isPluginEnabled('cl')) - $row_identifier = $record['client_id'] ? 'cl:'.$record['client_id'] : ''; + $row_identifier .= $record['client_id'] ? 'cl:'.$record['client_id'] : ''; // Add billable flag. if (!empty($row_identifier)) $row_identifier .= ','; $row_identifier .= 'bl:'.$record['billable']; @@ -417,7 +418,7 @@ static function makeRowIdentifier($record) { $row_identifier .= $record['task_id'] ? ',ts:'.$record['task_id'] : ''; // Add custom field parts. global $custom_fields; - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) @@ -438,8 +439,9 @@ static function makeRowIdentifier($record) { static function makeRowLabel($record) { global $user; // Start with client. + $label = ''; if ($user->isPluginEnabled('cl')) - $label = $record['client']; + $label .= $record['client']; // Add project. if (!empty($label) && !empty($record['project'])) $label .= ' - '; @@ -451,7 +453,7 @@ static function makeRowLabel($record) { // Add custom field parts. global $custom_fields; - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; $field_value = $record[$field_name]; diff --git a/initialize.php b/initialize.php index dca1b42e7..d3b1ff263 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5552"); +define("APP_VERSION", "1.19.28.5553"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ecb2c17d8d2f482f0112915c82ed7fbd69460479 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 15 May 2021 17:16:41 +0000 Subject: [PATCH 1568/1848] Improved week view by remembering custom fields and also printing them when configured to do so. --- WEB-INF/templates/week.tpl | 12 ++++++++++++ initialize.php | 2 +- week.php | 24 +++++++++++++----------- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl index 99da5ef47..42fa0b34e 100644 --- a/WEB-INF/templates/week.tpl +++ b/WEB-INF/templates/week.tpl @@ -101,6 +101,11 @@ function fillDropdowns() { + {if $show_record_custom_fields && isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + + {/foreach} + {/if} {if $show_client} {/if} @@ -125,6 +130,13 @@ function fillDropdowns() { {foreach $time_records as $record} + {* record custom fileds *} + {if $show_record_custom_fields && isset($custom_fields) && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + {/foreach} + {/if} {if $show_client} {/if} diff --git a/initialize.php b/initialize.php index d3b1ff263..f1c0f038c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5553"); +define("APP_VERSION", "1.19.28.5554"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/week.php b/week.php index 6a2a25e26..7687f9598 100644 --- a/week.php +++ b/week.php @@ -62,6 +62,7 @@ $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showFiles = $user->isPluginEnabled('at'); +$showRecordCustomFields = $user->isOptionEnabled('record_custom_fields'); // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -127,17 +128,17 @@ $timeCustomFields = array(); // If we have time custom fields - collect input. -if ($request->isPost()) { - if (isset($custom_fields) && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($request->getParameter($control_name))); - } +if (isset($custom_fields) && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); + $_SESSION[$control_name] = $cl_control_name; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($cl_control_name)); } } @@ -548,6 +549,7 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('onload', 'onLoad="fillDropdowns()"'); $smarty->assign('timestring', $startDate->toString($user->date_format).' - '.$endDate->toString($user->date_format)); $smarty->assign('time_records', $records); +$smarty->assign('show_record_custom_fields', $showRecordCustomFields); $smarty->assign('show_navigation', !$user->isOptionEnabled('week_menu')); $smarty->assign('show_client', $showClient); $smarty->assign('show_billable', $showBillable); From bddfeb53d64046ea825477adf6d5a3dcaedac9d2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 15 May 2021 18:00:48 +0000 Subject: [PATCH 1569/1848] Renamed timer.php to puncher.php to implement it as a plugin. --- WEB-INF/templates/{timer.tpl => puncher.tpl} | 0 initialize.php | 2 +- timer.php => puncher.php | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename WEB-INF/templates/{timer.tpl => puncher.tpl} (100%) rename timer.php => puncher.php (99%) diff --git a/WEB-INF/templates/timer.tpl b/WEB-INF/templates/puncher.tpl similarity index 100% rename from WEB-INF/templates/timer.tpl rename to WEB-INF/templates/puncher.tpl diff --git a/initialize.php b/initialize.php index f1c0f038c..2ffd096f9 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5554"); +define("APP_VERSION", "1.19.28.5555"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/timer.php b/puncher.php similarity index 99% rename from timer.php rename to puncher.php index cd0081f3d..56292a574 100644 --- a/timer.php +++ b/puncher.php @@ -307,5 +307,5 @@ $smarty->assign('onload', 'onLoad="fillDropdowns()"'); $smarty->assign('timestring', $selected_date->toString($user->date_format)); $smarty->assign('title', $i18n->get('title.time')); -$smarty->assign('content_page_name', 'timer.tpl'); +$smarty->assign('content_page_name', 'puncher.tpl'); $smarty->display('index.tpl'); From 565b05d323a8983beda56447f82fc6586cd00a69 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 16 May 2021 14:35:08 +0000 Subject: [PATCH 1570/1848] Implemented puncher page as a plugin. --- WEB-INF/resources/ca.lang.php | 1 - WEB-INF/resources/cs.lang.php | 1 - WEB-INF/resources/da.lang.php | 1 - WEB-INF/resources/de.lang.php | 1 - WEB-INF/resources/en.lang.php | 4 +++- WEB-INF/resources/es.lang.php | 1 - WEB-INF/resources/et.lang.php | 2 -- WEB-INF/resources/fa.lang.php | 1 - WEB-INF/resources/fi.lang.php | 1 - WEB-INF/resources/fr.lang.php | 1 - WEB-INF/resources/gr.lang.php | 2 -- WEB-INF/resources/he.lang.php | 1 - WEB-INF/resources/hu.lang.php | 1 - WEB-INF/resources/it.lang.php | 2 -- WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 1 - WEB-INF/resources/no.lang.php | 1 - WEB-INF/resources/pl.lang.php | 1 - WEB-INF/resources/pt-br.lang.php | 1 - WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 1 - WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 1 - WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 1 - WEB-INF/resources/sv.lang.php | 1 - WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 1 - WEB-INF/resources/zh-tw.lang.php | 1 - WEB-INF/templates/header.tpl | 3 +++ WEB-INF/templates/plugins.tpl | 20 ++++++++++++++-- WEB-INF/templates/puncher_conf.tpl | 17 ++++++++++++++ WEB-INF/templates/time.tpl | 4 +++- WEB-INF/templates/week_view.tpl | 4 ++-- initialize.php | 2 +- plugins.php | 5 ++++ puncher.php | 6 ++--- puncher_conf.php | 37 ++++++++++++++++++++++++++++++ time.php | 4 +++- 40 files changed, 95 insertions(+), 43 deletions(-) create mode 100644 WEB-INF/templates/puncher_conf.tpl create mode 100644 puncher_conf.php diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 34421e73d..5d115f9c8 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -240,7 +240,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 199a96faf..99d24e05f 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -250,7 +250,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index efdacc370..567310f30 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -231,7 +231,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index e41d92b09..9c2a35c27 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -222,7 +222,6 @@ 'label.paid_status' => 'Bezahlstatus', 'label.paid' => 'Bezahlt', 'label.mark_paid' => 'Als bezahlt setzen', -'label.week_menu' => 'Wochenansicht im Menü', 'label.week_note' => 'Wochennotiz', 'label.week_list' => 'Wochenliste', 'label.work_units' => 'Arbeitseinheiten', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 37aae4cae..1733fe489 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -24,6 +24,7 @@ 'menu.subgroups' => 'Subgroups', 'menu.plugins' => 'Plugins', 'menu.time' => 'Time', +'menu.puncher' => 'Punch', 'menu.week' => 'Week', 'menu.expenses' => 'Expenses', 'menu.reports' => 'Reports', @@ -173,6 +174,7 @@ 'label.select_none' => 'Deselect all', 'label.day_view' => 'Day view', 'label.week_view' => 'Week view', +'label.puncher' => 'Puncher', 'label.id' => 'ID', 'label.language' => 'Language', 'label.decimal_mark' => 'Decimal mark', @@ -215,7 +217,6 @@ 'label.paid_status' => 'Paid status', 'label.paid' => 'Paid', 'label.mark_paid' => 'Mark paid', -'label.week_menu' => 'Week menu', 'label.week_note' => 'Week note', 'label.week_list' => 'Week list', 'label.work_units' => 'Work units', @@ -269,6 +270,7 @@ 'title.edit_time_record' => 'Editing Time Record', 'title.delete_time_record' => 'Deleting Time Record', 'title.time_files' => 'Time Record Files', +'title.puncher' => 'Puncher', 'title.expenses' => 'Expenses', 'title.edit_expense' => 'Editing Expense Item', 'title.delete_expense' => 'Deleting Expense Item', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 9df814845..e8757a7f1 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -243,7 +243,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 7638ade63..1bd5ff234 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -238,8 +238,6 @@ 'label.paid_status' => 'Makse olek', 'label.paid' => 'Makstud', 'label.mark_paid' => 'Märgi makstuks', -// TODO: translate the following. -// 'label.week_menu' => 'Week menu', 'label.week_note' => 'Nädala märge', 'label.week_list' => 'Nädala nimekiri', 'label.work_units' => 'Töö ühikud', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 0fca34586..96c461865 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -243,7 +243,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index eaad8a293..80220a610 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -235,7 +235,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 771ed18e3..5c11e4224 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -229,7 +229,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index e9003045c..a5490a59f 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -223,8 +223,6 @@ 'label.paid_status' => 'Κατάσταση πληρωμής', 'label.paid' => 'Πληρωμένο', 'label.mark_paid' => 'Σήμανση πληρωμένα', -// TODO: translate the following. -// 'label.week_menu' => 'Week menu', 'label.week_note' => 'Σημείωση εβδομάδας', 'label.week_list' => 'Λίστα εβδομάδων', // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 032e01bf0..6112f1f06 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -250,7 +250,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 1909682fb..7425cc9ac 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -247,7 +247,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 35035d3e9..3aeb88a81 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -227,8 +227,6 @@ 'label.paid_status' => 'Stato pagamento', 'label.paid' => 'Pagato', 'label.mark_paid' => 'Segna come pagato', -// TODO: translate the following. -// 'label.week_menu' => 'Week menu', 'label.week_note' => 'Nota settimanale', 'label.week_list' => 'Lista settimanale', // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 0ba848ba0..c98730d99 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -250,7 +250,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 975e42169..d7edcbf4b 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -250,7 +250,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 70750349d..4580c677a 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -206,7 +206,6 @@ 'label.paid_status' => 'Status van betaling', 'label.paid' => 'Betaald', 'label.mark_paid' => 'Markeer als betaald', -'label.week_menu' => 'Week menu', 'label.week_note' => 'Week aantekening', 'label.week_list' => 'Week overzicht', 'label.work_units' => 'Werk eenheid', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index cfaf305b5..f7e0240df 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -248,7 +248,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 24664d693..e2cb857e6 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -236,7 +236,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index e41cf26c3..bf89e0c20 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -233,7 +233,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 13912a44d..1ff1bf992 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -236,7 +236,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 0c531ad11..60d9b1a38 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -247,7 +247,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index db94bf685..82cbce9d4 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -206,7 +206,6 @@ 'label.paid_status' => 'Статус оплаты', 'label.paid' => 'Оплачено', 'label.mark_paid' => 'Отметить оплату', -'label.week_menu' => 'Меню недели', 'label.week_note' => 'Комментарий недели', 'label.week_list' => 'Список недели', 'label.work_units' => 'Единицы работы', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 57c14a7db..a24317b9b 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -240,7 +240,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 32e200f81..65a3d0a01 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -231,7 +231,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 38cf8565b..7be8bd4f4 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -235,7 +235,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index fe05e89a7..8bab1c086 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -231,7 +231,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 777440e88..61472bf9e 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -254,7 +254,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 01e639bdd..129e21151 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -241,7 +241,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 66dc7099f..19e8800dc 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -246,7 +246,6 @@ // 'label.paid_status' => 'Paid status', // 'label.paid' => 'Paid', // 'label.mark_paid' => 'Mark paid', -// 'label.week_menu' => 'Week menu', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', // 'label.work_units' => 'Work units', diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 1d8627a66..e7df23ea6 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -98,6 +98,9 @@ {if $user->exists() && ($user->can('track_own_time') || $user->can('track_time'))} + {if $user->isPluginEnabled('pu') && $user->isOptionEnabled('puncher_menu')} + + {/if} {if $user->isPluginEnabled('wv') && $user->isOptionEnabled('week_menu')} {/if} diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index 370c93c59..5c1e4c943 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -4,6 +4,17 @@ License: See license.txt *} +{$forms.timesheetsForm.open}
{$i18n.label.date}{$timeField['label']|escape}{$i18n.label.client}
{$record.date}{$record.$control_name|escape}{$record.client|escape}
{$i18n.menu.time}{$i18n.menu.puncher}{$i18n.menu.week}
{if $user_dropdown} - {$forms.timesheetsForm.open} - {$forms.timesheetsForm.close} {/if}
{$forms.timesheetsForm.user.control}
+{$forms.timesheetsForm.close}
{if $inactive_timesheets}
{$i18n.form.timesheets.active_timesheets}
@@ -27,8 +27,8 @@ License: See license.txt *} {if $show_client}
{$i18n.label.client}{$i18n.label.submitted} - {$i18n.label.approved} + {$i18n.label.submitted}{$i18n.label.approved}{$i18n.label.client}{$i18n.label.submitted} - {$i18n.label.approved} + {$i18n.label.submitted}{$i18n.label.approved}
+ {/if} diff --git a/WEB-INF/templates/work/footer.tpl b/WEB-INF/templates/work/footer_old.tpl similarity index 100% rename from WEB-INF/templates/work/footer.tpl rename to WEB-INF/templates/work/footer_old.tpl diff --git a/WEB-INF/templates/work/index.tpl b/WEB-INF/templates/work/index.tpl index 3c6500821..c4f193521 100644 --- a/WEB-INF/templates/work/index.tpl +++ b/WEB-INF/templates/work/index.tpl @@ -2,4 +2,4 @@ {if $content_page_name}{include file="$content_page_name"}{/if} -{include file="work/footer.tpl"} +{include file="work/footer_old.tpl"} diff --git a/initialize.php b/initialize.php index a1be5736b..666e412c0 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5570"); +define("APP_VERSION", "1.19.28.5571"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/template_add.php b/template_add.php index cb84fb33b..8eef424ef 100644 --- a/template_add.php +++ b/template_add.php @@ -19,9 +19,11 @@ $config = new ttConfigHelper($user->getConfig()); $bindTemplatesWithProjects = $config->getDefinedValue('bind_templates_with_projects'); +$projects = $cl_projects = array(); if ($bindTemplatesWithProjects) $projects = ttGroupHelper::getActiveProjects(); +$cl_name = $cl_description = $cl_content = null; if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_description = trim($request->getParameter('description')); diff --git a/template_edit.php b/template_edit.php index 814eff591..2f3c69727 100644 --- a/template_edit.php +++ b/template_edit.php @@ -25,9 +25,11 @@ $config = $user->getConfigHelper(); $bindTemplatesWithProjects = $config->getDefinedValue('bind_templates_with_projects'); +$projects = $cl_projects = array(); if ($bindTemplatesWithProjects) $projects = ttGroupHelper::getActiveProjects(); +$cl_name = $cl_description = $cl_content = $cl_status = null; if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_description = trim($request->getParameter('description')); diff --git a/timesheet_files.php b/timesheet_files.php index bca00f28d..bec4e29d8 100644 --- a/timesheet_files.php +++ b/timesheet_files.php @@ -24,6 +24,7 @@ } // End of access checks. +$cl_description = null; if ($request->isPost()) { $cl_description = trim($request->getParameter('description')); } From 8f576b10e996d468d28febf8767d0bc95b824421 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 18 May 2021 22:20:28 +0000 Subject: [PATCH 1587/1848] Addressed several more php8 warnings. --- WEB-INF/lib/ttFavReportHelper.class.php | 12 ++++----- WEB-INF/lib/ttRoleHelper.class.php | 33 ++++--------------------- initialize.php | 2 +- role_add.php | 1 + topdf.php | 21 ++++++++-------- 5 files changed, 24 insertions(+), 45 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index b4f917a4a..d1cce7240 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -399,7 +399,7 @@ static function loadReport(&$bean) { 'chtotalsonly' => null, 'new_fav_report' => null)); // Time custom fields. - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; $checkbox_field_name = 'show_'.$field_name; @@ -408,7 +408,7 @@ static function loadReport(&$bean) { } } // User custom fields. - if ($custom_fields && $custom_fields->userFields) { + if (isset($custom_fields) && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; $checkbox_field_name = 'show_'.$field_name; @@ -416,7 +416,7 @@ static function loadReport(&$bean) { $custom_field_attrs[$checkbox_field_name] = null; } } - if (is_array($custom_field_attrs)) + if (isset($custom_field_attrs)) $attrs = array_merge($attrs, $custom_field_attrs); $bean->setAttributes($attrs); } @@ -543,7 +543,7 @@ static function makeReportSpec($bean) { } // Add time custom field settings. - if ($custom_fields && $custom_fields->timeFields) { + if (isset($custom_fields) && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; $field_value = str_replace(',',',',$bean->getAttribute($field_name)); @@ -555,7 +555,7 @@ static function makeReportSpec($bean) { } // Add user custom field settings. - if ($custom_fields && $custom_fields->userFields) { + if (isset($custom_fields) && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; $field_value = str_replace(',',',',$bean->getAttribute($field_name)); @@ -567,7 +567,7 @@ static function makeReportSpec($bean) { } $reportSpec = null; - if (is_array($reportSpecArray)) + if (isset($reportSpecArray)) $reportSpec = implode(',', $reportSpecArray); return $reportSpec; } diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index a3753d238..683f7ebaf 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -1,30 +1,6 @@ fetchRow(); - if ($val['id']) + if (isset($val['id']) && $val['id']) return $val; } return false; @@ -115,7 +91,7 @@ static function getRoleByRank($rank) { if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - if ($val['id']) + if (isset($val['id']) && $val['id']) return $val['id']; } return false; @@ -130,6 +106,7 @@ static function update($fields) { $org_id = $user->org_id; $id = (int)$fields['id']; + $name_part = $rank_part = $descr_part = $status_part = $rights_part = ''; if (isset($fields['name'])) $name_part = 'name = '.$mdb2->quote($fields['name']); if (isset($fields['rank'])) $rank_part = ', `rank` = '.(int)$fields['rank']; if (isset($fields['description'])) $descr_part = ', description = '.$mdb2->quote($fields['description']); diff --git a/initialize.php b/initialize.php index 666e412c0..2493a2154 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5571"); +define("APP_VERSION", "1.19.28.5572"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/role_add.php b/role_add.php index b2879dd8f..b4e05f903 100644 --- a/role_add.php +++ b/role_add.php @@ -12,6 +12,7 @@ exit(); } +$cl_name = $cl_description = $cl_rank = null; if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_description = trim($request->getParameter('description')); diff --git a/topdf.php b/topdf.php index aa840e106..85ff8d84e 100644 --- a/topdf.php +++ b/topdf.php @@ -46,6 +46,7 @@ // Obtain items for report. $options = ttReportHelper::getReportOptions($bean); $grouping = ttReportHelper::grouping($options); +$items = null; if (!$totals_only) $items = ttReportHelper::getItems($options); // Individual entries. if ($totals_only || $grouping) @@ -128,7 +129,7 @@ $html .= '
'.$i18n->get('label.date').''.$i18n->get('label.user').''.$i18n->get('label.project').''.$i18n->get('label.task').''.$item['date'].''.htmlspecialchars($item['user']).''.htmlspecialchars($item['project']).''.htmlspecialchars($item['task']).''.$i18n->get('label.total').'
{$forms.displayOptionsForm.report_inactive_projects.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.form.display_options.custom_css}
-
Create database structure (v1.19.23) + Create database structure (v1.19.29)
(applies only to new installations, do not execute when updating)
@@ -1269,8 +1271,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.23)Update database structure (v1.19 to v1.19.29)
diff --git a/initialize.php b/initialize.php index d36445879..97dfbe2ac 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.28.5590"); +define("APP_VERSION", "1.19.29.5591"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mysql.sql b/mysql.sql index e9f4cc031..7a87b3766 100644 --- a/mysql.sql +++ b/mysql.sql @@ -45,6 +45,7 @@ CREATE TABLE `tt_groups` ( `modified` datetime default NULL, # modification timestamp `modified_ip` varchar(45) default NULL, # modifier ip `modified_by` int(11) default NULL, # modifier user_id + `entities_modified` datetime default NULL, # modification timestamp of group entities (clients, projects, etc.) `status` tinyint(4) default 1, # group status PRIMARY KEY (`id`) ); @@ -656,4 +657,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.23', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.29', now()); # TODO: change when structure changes. From 30ae56536c029705287b6a5c291624e5e4c5ed11 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 13 Aug 2021 14:21:56 +0000 Subject: [PATCH 1609/1848] Wrote ttGroupHelper::updateEntitiesModidied function and started to use it for group and project changes. --- WEB-INF/lib/ttGroupHelper.class.php | 13 +++++++++++++ WEB-INF/lib/ttProjectHelper.class.php | 21 +++++++++++++++++---- WEB-INF/lib/ttUser.class.php | 3 +++ initialize.php | 2 +- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 0dd3dd412..0fa0355ea 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -761,4 +761,17 @@ static function deleteGroupFiles($group_id) { // By design, we ignore such errors. return true; } + + // updateEntitiesModified updates the entities_modided field in tt_groups table + // with a current timestamp. + static function updateEntitiesModified() { + global $user; + $org_id = $user->org_id; + $group_id = $user->getGroup(); + $mdb2 = getConnection(); + + $sql = "update tt_groups set entities_modified = now() where id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } } diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index ebbd055fb..5e3321b92 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -216,9 +216,14 @@ static function delete($id) { if (is_a($affected, 'PEAR_Error')) return false; - // Finally, delete the project from the projects field in tt_clients table. - $result = ttClientHelper::deleteProject($id); - return $result; + // Delete the project from the projects field in tt_clients table. + if (!ttClientHelper::deleteProject($id)) + return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) return false; + + return true; } // insert function inserts a new project into database. @@ -269,6 +274,9 @@ static function insert($fields) } } + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) return false; + return $last_id; } @@ -354,7 +362,12 @@ static function update($fields) { ", tasks = ".$mdb2->quote($comma_separated).", status = ".$mdb2->quote($status). " where id = $project_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) return false; + + return true; } // getAssignedUsers - returns an array of user ids assigned to a project. diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 2086a3740..c6539db66 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -707,6 +707,9 @@ function updateGroup($fields) { $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) return false; + return true; } diff --git a/initialize.php b/initialize.php index 97dfbe2ac..5c37c7452 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.29.5591"); +define("APP_VERSION", "1.19.29.5592"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 25c08b9eab394193cddae071ca3d6cca652ef88d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 13 Aug 2021 15:47:54 +0000 Subject: [PATCH 1610/1848] Started to update entities_modified for client add, edit, and delete operations. --- WEB-INF/lib/ttClientHelper.class.php | 22 ++++++++++++++++++++-- WEB-INF/lib/ttGroupHelper.class.php | 2 +- WEB-INF/lib/ttProjectHelper.class.php | 12 ++++++++---- WEB-INF/lib/ttUser.class.php | 6 ++++-- initialize.php | 2 +- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index 3c5f0d646..ba62d0f33 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -150,7 +150,14 @@ static function delete($id, $delete_client_entries) { $sql = "update tt_clients set status = null". " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + + return true; } // The insert function inserts a new client record into the clients table. @@ -190,6 +197,10 @@ static function insert($fields) return false; } + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return $last_id; } @@ -232,7 +243,14 @@ static function update($fields) ", tax = $tax, projects = ".$mdb2->quote($comma_separated).", status = $status". " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + + return true; } // The fillBean function fills the ActionForm object with client data. diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 0fa0355ea..aa75a571e 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -762,7 +762,7 @@ static function deleteGroupFiles($group_id) { return true; } - // updateEntitiesModified updates the entities_modided field in tt_groups table + // updateEntitiesModified updates the entities_modified field in tt_groups table // with a current timestamp. static function updateEntitiesModified() { global $user; diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 5e3321b92..dd6e35cb8 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -221,7 +221,8 @@ static function delete($id) { return false; // Update entities_modified, too. - if (!ttGroupHelper::updateEntitiesModified()) return false; + if (!ttGroupHelper::updateEntitiesModified()) + return false; return true; } @@ -275,7 +276,8 @@ static function insert($fields) } // Update entities_modified, too. - if (!ttGroupHelper::updateEntitiesModified()) return false; + if (!ttGroupHelper::updateEntitiesModified()) + return false; return $last_id; } @@ -362,10 +364,12 @@ static function update($fields) { ", tasks = ".$mdb2->quote($comma_separated).", status = ".$mdb2->quote($status). " where id = $project_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; + if (is_a($affected, 'PEAR_Error')) + return false; // Update entities_modified, too. - if (!ttGroupHelper::updateEntitiesModified()) return false; + if (!ttGroupHelper::updateEntitiesModified()) + return false; return true; } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index c6539db66..6848a72df 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -705,10 +705,12 @@ function updateGroup($fields) { $sql = "update tt_groups set $parts where id = $group_id and org_id = $this->org_id"; $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) return false; + if (is_a($affected, 'PEAR_Error')) + return false; // Update entities_modified, too. - if (!ttGroupHelper::updateEntitiesModified()) return false; + if (!ttGroupHelper::updateEntitiesModified()) + return false; return true; } diff --git a/initialize.php b/initialize.php index 5c37c7452..d2b0a737d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.29.5592"); +define("APP_VERSION", "1.19.29.5593"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 9a99a01e54029b20a1f1ed6dcc2ae9062e300576 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 13 Aug 2021 16:33:58 +0000 Subject: [PATCH 1611/1848] Start to update entities_modified for task and user update operations. --- WEB-INF/lib/ttTaskHelper.class.php | 19 +++++++++++- WEB-INF/lib/ttUser.class.php | 4 ++- WEB-INF/lib/ttUserHelper.class.php | 47 +++++++++++++++++++----------- initialize.php | 2 +- 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/WEB-INF/lib/ttTaskHelper.class.php b/WEB-INF/lib/ttTaskHelper.class.php index 71a520025..e93d3d669 100644 --- a/WEB-INF/lib/ttTaskHelper.class.php +++ b/WEB-INF/lib/ttTaskHelper.class.php @@ -107,7 +107,14 @@ static function delete($task_id) { // Mark the task as deleted. $sql = "update tt_tasks set status = NULL where id = $task_id"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + + return true; } // insert function inserts a new task into database. @@ -161,6 +168,11 @@ static function insert($fields) return false; } } + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return $last_id; } @@ -242,6 +254,11 @@ static function update($fields) } } } + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return true; } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 6848a72df..320fa623d 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -760,7 +760,9 @@ function markUserDeleted($user_id) { if (is_a($affected, 'PEAR_Error')) return false; - + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; return true; } diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 95be4fbb5..122c7889c 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -95,27 +95,31 @@ static function insert($fields, $hash = true) { $mdb2->quote($fields['name']).", ".$mdb2->quote($fields['login']). ", $password, $group_id, $org_id, ".$mdb2->quote($fields['role_id']).", ".$mdb2->quote($fields['client_id']).", $rate, $quota_percent, ".$mdb2->quote($email).", now() $created_ip_v $created_by_v)"; $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; // Now deal with project assignment. - if (!is_a($affected, 'PEAR_Error')) { - $last_id = $mdb2->lastInsertID('tt_users', 'id'); - $projects = isset($fields['projects']) ? $fields['projects'] : array(); - if (count($projects) > 0) { - // We have at least one project assigned. Insert corresponding entries in tt_user_project_binds table. - foreach($projects as $p) { - if(!isset($p['rate'])) - $p['rate'] = 0; - else - $p['rate'] = str_replace(',', '.', $p['rate']); - - $sql = "insert into tt_user_project_binds (project_id, user_id, group_id, org_id, rate, status)". - " values(".$p['id'].", $last_id, $group_id, $org_id, ".$p['rate'].", 1)"; - $affected = $mdb2->exec($sql); - } + $last_id = $mdb2->lastInsertID('tt_users', 'id'); + $projects = isset($fields['projects']) ? $fields['projects'] : array(); + if (count($projects) > 0) { + // We have at least one project assigned. Insert corresponding entries in tt_user_project_binds table. + foreach($projects as $p) { + if(!isset($p['rate'])) + $p['rate'] = 0; + else + $p['rate'] = str_replace(',', '.', $p['rate']); + + $sql = "insert into tt_user_project_binds (project_id, user_id, group_id, org_id, rate, status)". + " values(".$p['id'].", $last_id, $group_id, $org_id, ".$p['rate'].", 1)"; + $affected = $mdb2->exec($sql); } - return $last_id; } - return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + + return $last_id; } // update - updates a user in database. @@ -232,6 +236,11 @@ static function update($user_id, $fields) { } } } + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return true; } @@ -282,6 +291,10 @@ static function delete($user_id) { if (is_a($affected, 'PEAR_Error')) return false; + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return true; } diff --git a/initialize.php b/initialize.php index d2b0a737d..984dc3718 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.29.5593"); +define("APP_VERSION", "1.19.29.5594"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 974a1cf40a424eca9594bc0d0dbf08e3b72c78f2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 14 Aug 2021 16:52:54 +0000 Subject: [PATCH 1612/1848] Started to update entities_modified on custom field and predefined expenses changes. --- .../lib/ttPredefinedExpenseHelper.class.php | 17 ++++++- initialize.php | 2 +- plugins/CustomFields.class.php | 50 +++++++++++++++++-- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php index 8ec8ccfee..c6bc3f356 100644 --- a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php +++ b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php @@ -66,6 +66,10 @@ static function delete($id) { if (is_a($affected, 'PEAR_Error')) return false; + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return true; } @@ -88,6 +92,10 @@ static function insert($fields) { if (is_a($affected, 'PEAR_Error')) return false; + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return true; } @@ -108,6 +116,13 @@ static function update($fields) { $sql = "update tt_predefined_expenses set name = ".$mdb2->quote($name).", cost = ".$mdb2->quote($cost). " where id = $predefined_expense_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + + return true; } } diff --git a/initialize.php b/initialize.php index 984dc3718..21f27ce82 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.29.5594"); +define("APP_VERSION", "1.19.29.5595"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index a11e40a32..6350a6784 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -156,6 +156,11 @@ static function insertOption($field_id, $option_name) { if (is_a($affected, 'PEAR_Error')) return false; } + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return true; } @@ -170,7 +175,14 @@ static function updateOption($id, $option_name) { $sql = "update tt_custom_field_options set value = " . $mdb2->quote($option_name) . " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + + return true; } // delete Option deletes an option and all custom field log entries that used it. @@ -196,7 +208,14 @@ static function deleteOption($id) { $sql = "update tt_custom_field_options set status = null" . " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + + return true; } // getOptions returns an array of options for a custom field. @@ -314,7 +333,14 @@ static function insertField($field_name, $entity_type, $field_type, $required) { $sql = "insert into tt_custom_fields (group_id, org_id, entity_type, type, label, required, status)" . " values($group_id, $org_id, $entity_type, $field_type, " . $mdb2->quote($field_name) . ", $required, 1)"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + + return true; } // The updateField updates custom field for group. @@ -328,7 +354,14 @@ static function updateField($id, $name, $type, $required) { $sql = "update tt_custom_fields set label = " . $mdb2->quote($name) . ", type = $type, required = $required" . " where id = $id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + + return true; } // The deleteField deletes a custom field, its options and log entries for group. @@ -357,7 +390,14 @@ static function deleteField($field_id) { $sql = "update tt_custom_fields set status = null" . " where id = $field_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + + return true; } // insertTimeFields - inserts time custom fields into tt_custom_field_log. From 865dd33879409b174a4eab42beecedf426f26602 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 14 Aug 2021 17:10:06 +0000 Subject: [PATCH 1613/1848] Started to update entities_modified on template changes. --- WEB-INF/lib/ttTemplateHelper.class.php | 13 +++++++++++++ initialize.php | 2 +- plugins/MonthlyQuota.class.php | 8 +++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttTemplateHelper.class.php b/WEB-INF/lib/ttTemplateHelper.class.php index 6e6ad0a02..0b9fcf92a 100644 --- a/WEB-INF/lib/ttTemplateHelper.class.php +++ b/WEB-INF/lib/ttTemplateHelper.class.php @@ -48,6 +48,10 @@ static function delete($id) { if (is_a($affected, 'PEAR_Error')) return false; + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return true; } @@ -87,6 +91,11 @@ static function insert($fields) { return false; } } + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return $last_id; } @@ -129,6 +138,10 @@ static function update($fields) { die($affected->getMessage()); } + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return true; } diff --git a/initialize.php b/initialize.php index 21f27ce82..b8f7a204f 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.29.5595"); +define("APP_VERSION", "1.19.29.5596"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins/MonthlyQuota.class.php b/plugins/MonthlyQuota.class.php index 0a8ee4e9b..f742fd918 100644 --- a/plugins/MonthlyQuota.class.php +++ b/plugins/MonthlyQuota.class.php @@ -51,8 +51,14 @@ public function update($year, $month, $minutes) { $insertSql = "insert into tt_monthly_quotas (group_id, org_id, year, month, minutes)". " values ($this->group_id, $this->org_id, $year, $month, $minutes)"; $affected = $this->db->exec($insertSql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; } + + // Update entities_modified, too. + if (!ttGroupHelper::updateEntitiesModified()) + return false; + return true; } From 72d595742225a383fa8b891cd19add6296b2c208 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 1 Sep 2021 14:27:58 +0000 Subject: [PATCH 1614/1848] Cosmetic fixes to typos in comments. --- WEB-INF/lib/ttTimeHelper.class.php | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 031ccfb61..75c911e04 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -119,13 +119,13 @@ static function isValidDuration($value) { } // postedDurationToMinutes - converts a value representing a duration - // (usually enetered in a form by a user) to an integer number of minutes. + // (usually entered in a form by a user) to an integer number of minutes. // // Parameters: // $duration - user entered duration string. Valid strings are: // 3 or 3h - means 3 hours. Note: h and m letters are not localized. // 0.25 or 0.25h or .25 or .25h - means a quarter of hour. - // 0,25 or 0,25h or ,25 or ,25h - same as above for users with comma ad decimal mark. + // 0,25 or 0,25h or ,25 or ,25h - same as above for users with comma as decimal mark. // 1:30 - means 1 hour 30 minutes. // 25m - means 25 minutes. // $max - maximum number of minutes that is valid. diff --git a/initialize.php b/initialize.php index b8f7a204f..934f9d4b4 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.29.5596"); +define("APP_VERSION", "1.19.29.5597"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 71796c69b7128ce6d49c6772ccfa8c0c14ff4ba0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 7 Oct 2021 17:39:30 +0000 Subject: [PATCH 1615/1848] Maintenance fixes. --- initialize.php | 2 +- plugins/CustomFields.class.php | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/initialize.php b/initialize.php index 934f9d4b4..105507363 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.29.5597"); +define("APP_VERSION", "1.19.29.5598"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 6350a6784..26e4532b3 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -373,18 +373,27 @@ static function deleteField($field_id) { $org_id = $user->org_id; // Mark log entries as deleted. TODO: why are we doing this? Research impact. + // The impact is quite severe: an accidental delete of a custom field makes manual recovery problematic. + // Therefore, not doing this anymore as of Oct 7, 2021. + /* $sql = "update tt_custom_field_log set status = null" . " where field_id = $field_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; + */ // Mark field options as deleted. + // Same comment as above applies. + // An accidental delete of a custom field makes manual recovery problematic. + // Therefore, not doing this anymore as of Oct 7, 2021. + /* $sql = "update tt_custom_field_options set status = null" . " where field_id = $field_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; + */ // Mark custom field as deleted. $sql = "update tt_custom_fields set status = null" . From 559906731f153c9b3a632c2839ed11669b76d593 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 12 Oct 2021 20:01:36 +0000 Subject: [PATCH 1616/1848] Added a check for passed in date to time.php. --- initialize.php | 2 +- time.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/initialize.php b/initialize.php index 105507363..e0b38f4d5 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.29.5598"); +define("APP_VERSION", "1.19.30.5599"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 1bee1129c..61e771f8b 100644 --- a/time.php +++ b/time.php @@ -32,6 +32,12 @@ exit(); } } +// If we are passed in a date, make sure it is in correct format. +$date = $request->getParameter('date'); +if ($date && !ttValidDate($date)) { + header('Location: access_denied.php'); + exit(); +} // End of access checks. // Determine user for whom we display this page. From d3f60bd3e3ea8ff8ec31a596baec6750af601b7c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 12 Oct 2021 20:31:02 +0000 Subject: [PATCH 1617/1848] A better fix to validate a passed-in date. --- WEB-INF/lib/common.lib.php | 20 +++++++++++++++++--- initialize.php | 2 +- time.php | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index d5b43f57f..db8d58ea3 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -226,15 +226,29 @@ function ttValidDate($val) if (strlen($val) == 0) return false; - // This should accept a string in format 'YYYY-MM-DD', 'MM/DD/YYYY', 'DD-MM-YYYY', 'DD.MM.YYYY', or 'DD.MM.YYYY whatever'. + // This should validate a string in format 'YYYY-MM-DD', 'MM/DD/YYYY', 'DD-MM-YYYY', 'DD.MM.YYYY', or 'DD.MM.YYYY whatever'. if (!preg_match('/^\d\d\d\d-\d\d-\d\d$/', $val) && !preg_match('/^\d\d\/\d\d\/\d\d\d\d$/', $val) && !preg_match('/^\d\d\-\d\d\-\d\d\d\d$/', $val) && !preg_match('/^\d\d\.\d\d\.\d\d\d\d$/', $val) && !preg_match('/^\d\d\.\d\d\.\d\d\d\d .+$/', $val)) return false; - - return true; + + return true; +} + +// ttValidDbDateFormatDate is used to check user input to validate a date in DB_DATEFORMAT. +function ttValidDbDateFormatDate($val) +{ + $val = trim($val); + if (strlen($val) == 0) + return false; + + // This should validate a string in format 'YYYY-MM-DD'. + if (!preg_match('/^\d\d\d\d-\d\d-\d\d$/', $val)) + return false; + + return true; } // ttValidInteger is used to check user input to validate an integer. diff --git a/initialize.php b/initialize.php index e0b38f4d5..3d6aeab4c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.30.5599"); +define("APP_VERSION", "1.19.30.5600"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 61e771f8b..e5e509c06 100644 --- a/time.php +++ b/time.php @@ -34,7 +34,7 @@ } // If we are passed in a date, make sure it is in correct format. $date = $request->getParameter('date'); -if ($date && !ttValidDate($date)) { +if ($date && !ttValidDbDateFormatDate($date)) { header('Location: access_denied.php'); exit(); } From 42ea5b1d1658ba5a0fa14069d8b31b9292249821 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 12 Oct 2021 21:00:47 +0000 Subject: [PATCH 1618/1848] Added validation of browser_today parameter in posts. --- expense_edit.php | 8 ++++++++ expenses.php | 8 ++++++++ initialize.php | 2 +- login.php | 11 +++++++++++ puncher.php | 8 ++++++++ time.php | 8 ++++++++ time_edit.php | 8 ++++++++ 7 files changed, 52 insertions(+), 1 deletion(-) diff --git a/expense_edit.php b/expense_edit.php index 271a588ac..258437b33 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -27,6 +27,14 @@ header('Location: access_denied.php'); exit(); } +if ($request->isPost()) { + // Validate that browser_today parameter is in correct format. + $browser_today = $request->getParameter('browser_today'); + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); diff --git a/expenses.php b/expenses.php index 1914a253e..1b5d99c1d 100644 --- a/expenses.php +++ b/expenses.php @@ -38,6 +38,14 @@ exit(); } } +if ($request->isPost()) { + // Validate that browser_today parameter is in correct format. + $browser_today = $request->getParameter('browser_today'); + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. // Determine user for which we display this page. diff --git a/initialize.php b/initialize.php index 3d6aeab4c..63ee048df 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.30.5600"); +define("APP_VERSION", "1.19.30.5601"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/login.php b/login.php index 09c7af141..9e2436206 100644 --- a/login.php +++ b/login.php @@ -7,6 +7,17 @@ import('ttOrgHelper'); import('ttUser'); +// Access checks. +if ($request->isPost()) { + // Validate that browser_today parameter is in correct format. + $browser_today = $request->getParameter('browser_today'); + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + header('Location: access_denied.php'); + exit(); + } +} +// End of access checks. + $cl_login = $request->getParameter('login'); if ($cl_login == null && $request->isGet()) $cl_login = @$_COOKIE[LOGIN_COOKIE_NAME]; $cl_password = $request->getParameter('password'); diff --git a/puncher.php b/puncher.php index 5d6bca7c0..787c6f34b 100644 --- a/puncher.php +++ b/puncher.php @@ -19,6 +19,14 @@ header('Location: feature_disabled.php'); exit(); } +if ($request->isPost()) { + // Validate that browser_today parameter is in correct format. + $browser_today = $request->getParameter('browser_today'); + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. $showClient = $user->isPluginEnabled('cl'); diff --git a/time.php b/time.php index e5e509c06..9202dc1d7 100644 --- a/time.php +++ b/time.php @@ -38,6 +38,14 @@ header('Location: access_denied.php'); exit(); } +if ($request->isPost()) { + // Validate that browser_today parameter is in correct format. + $browser_today = $request->getParameter('browser_today'); + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. // Determine user for whom we display this page. diff --git a/time_edit.php b/time_edit.php index d34ae1ca6..e82e21b88 100644 --- a/time_edit.php +++ b/time_edit.php @@ -24,6 +24,14 @@ header('Location: access_denied.php'); exit(); } +if ($request->isPost()) { + // Validate that browser_today parameter is in correct format. + $browser_today = $request->getParameter('browser_today'); + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. $user_id = $user->getUser(); From 8f78ea2bac49e937eedf5477dfcb9cf61c498069 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 12 Oct 2021 21:45:35 +0000 Subject: [PATCH 1619/1848] Forgot to check in one file. --- week.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/week.php b/week.php index 7687f9598..fbfbfee36 100644 --- a/week.php +++ b/week.php @@ -38,6 +38,14 @@ exit(); } } +if ($request->isPost()) { + // Validate that browser_today parameter is in correct format. + $browser_today = $request->getParameter('browser_today'); + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. // Determine user for whom we display this page. From 94fda0cc0c9c20ab98d38ccc75ff040d13dc7f1b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 20 Oct 2021 20:51:47 +0000 Subject: [PATCH 1620/1848] Fixed an sql injection vulnerability in groups.php. --- groups.php | 13 ++++++++++--- initialize.php | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/groups.php b/groups.php index a7bf2dfe6..ca01a5f7c 100644 --- a/groups.php +++ b/groups.php @@ -11,9 +11,16 @@ header('Location: access_denied.php'); exit(); } -if ($request->isPost() && !$user->isGroupValid($request->getParameter('group'))) { - header('Location: access_denied.php'); // Wrong group id in post. - exit(); +if ($request->isPost()) { + $group_id = $request->getParameter('group'); + if (!ttValidInteger($group_id)) { + header('Location: access_denied.php'); // Protection against sql injection. + exit(); + } + if (!$user->isGroupValid($group_id)) { + header('Location: access_denied.php'); // Wrong group id in post. + exit(); + } } // End of access checks. diff --git a/initialize.php b/initialize.php index 63ee048df..92c907f30 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.30.5601"); +define("APP_VERSION", "1.19.31.5602"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 0cf32f1046418aa2e5218b0b370064820c330c6a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 21 Oct 2021 12:29:00 +0000 Subject: [PATCH 1621/1848] Added additional protection against an sql injection fixed in previous commit. --- WEB-INF/lib/ttGroupHelper.class.php | 6 +++++- initialize.php | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index aa75a571e..81b0c7f34 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -27,9 +27,13 @@ static function getGroupName($group_id) { static function getParentGroup($group_id) { global $user; + // Checking parameters for sanity is normally done in access check blocks on pages. + // This cast below is just in case we forgot to check $group_id to be an integer. + $groupId = (int) $group_id; // Protection against sql injection. + $mdb2 = getConnection(); - $sql = "select parent_id from tt_groups where id = $group_id and org_id = $user->org_id and status = 1"; + $sql = "select parent_id from tt_groups where id = $groupId and org_id = $user->org_id and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { diff --git a/initialize.php b/initialize.php index 92c907f30..bc05d18d9 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.31.5602"); +define("APP_VERSION", "1.19.31.5603"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 571a69ca25e0c94af905d54b84dc06b3d9df22d8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 21 Oct 2021 15:27:59 +0000 Subject: [PATCH 1622/1848] A couple more fixes to address CVE-2021-41139. --- charts.php | 5 +++++ expenses.php | 6 ++++++ initialize.php | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/charts.php b/charts.php index 1bf6d34fa..88878f6b0 100644 --- a/charts.php +++ b/charts.php @@ -40,6 +40,11 @@ exit(); } } +$date = $request->getParameter('date'); +if ($date && !ttValidDbDateFormatDate($date)) { + header('Location: access_denied.php'); + exit(); +} // End of access checks. // Determine user for which we display this page. diff --git a/expenses.php b/expenses.php index 1b5d99c1d..578e2d1c6 100644 --- a/expenses.php +++ b/expenses.php @@ -38,6 +38,12 @@ exit(); } } +// If we are passed in a date, make sure it is in correct format. +$date = $request->getParameter('date'); +if ($date && !ttValidDbDateFormatDate($date)) { + header('Location: access_denied.php'); + exit(); +} if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); diff --git a/initialize.php b/initialize.php index bc05d18d9..6caaec770 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.31.5603"); +define("APP_VERSION", "1.19.32.5604"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 098706ef27d5fbc8dda87383d64a671b9dd5aa7c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 22 Oct 2021 19:54:28 +0000 Subject: [PATCH 1623/1848] Security fix, added checking status value for sanity. --- WEB-INF/lib/common.lib.php | 13 +++++++++++++ client_edit.php | 2 ++ initialize.php | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index db8d58ea3..5840f3684 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -219,6 +219,19 @@ function ttValidFloat($val, $emptyValid = false) return true; } +// ttValidStatus is used to check user input to validate a status value. +function ttValidStatus($val) +{ + if (!ttValidInteger($val)) + return false; + + $intVal = (int) $val; // Cast to int for comparisons below to work. + if ($intVal != ACTIVE && $intVal != INACTIVE) + return false; + + return true; +} + // ttValidDate is used to check user input to validate a date. function ttValidDate($val) { diff --git a/client_edit.php b/client_edit.php index 349834181..4489e2a75 100644 --- a/client_edit.php +++ b/client_edit.php @@ -33,6 +33,7 @@ $cl_address = trim($request->getParameter('address')); $cl_tax = trim($request->getParameter('tax')); $cl_status = $request->getParameter('status'); +$cl_status = "1" ; $cl_projects = $request->getParameter('projects'); } else { $cl_name = $client['name']; @@ -64,6 +65,7 @@ if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); + if (!ttValidStatus($cl_status)) $err->add($i18n->get('error.field'), $i18n->get('label.status')); if ($err->no()) { if ($request->getParameter('btn_save')) { diff --git a/initialize.php b/initialize.php index 6caaec770..4497264e5 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.32.5604"); +define("APP_VERSION", "1.19.33.5605"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 1e89145d4f841021ebe82049b58ce4e6840091d4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 22 Oct 2021 19:56:09 +0000 Subject: [PATCH 1624/1848] Proper security fix, added checking status value for sanity. --- client_edit.php | 1 - 1 file changed, 1 deletion(-) diff --git a/client_edit.php b/client_edit.php index 4489e2a75..665fda15e 100644 --- a/client_edit.php +++ b/client_edit.php @@ -33,7 +33,6 @@ $cl_address = trim($request->getParameter('address')); $cl_tax = trim($request->getParameter('tax')); $cl_status = $request->getParameter('status'); -$cl_status = "1" ; $cl_projects = $request->getParameter('projects'); } else { $cl_name = $client['name']; From c1db27ad9c9a4a1ebe0726977789bea52184f088 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 22 Oct 2021 20:15:50 +0000 Subject: [PATCH 1625/1848] Added checking status parameter for sanity in more files. --- initialize.php | 2 +- project_edit.php | 1 + role_edit.php | 1 + task_edit.php | 1 + template_edit.php | 1 + timesheet_edit.php | 1 + user_edit.php | 1 + 7 files changed, 7 insertions(+), 1 deletion(-) diff --git a/initialize.php b/initialize.php index 4497264e5..342d458a6 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.33.5605"); +define("APP_VERSION", "1.19.33.5606"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/project_edit.php b/project_edit.php index 917b2e974..7d8e113dd 100644 --- a/project_edit.php +++ b/project_edit.php @@ -63,6 +63,7 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidStatus($cl_status)) $err->add($i18n->get('error.field'), $i18n->get('label.status')); if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); diff --git a/role_edit.php b/role_edit.php index 5192ee62d..f2aecadee 100644 --- a/role_edit.php +++ b/role_edit.php @@ -58,6 +58,7 @@ if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if ($cl_rank >= $user->rank || $cl_rank < 0) $err->add($i18n->get('error.field'), $i18n->get('form.roles.rank')); + if (!ttValidStatus($cl_status)) $err->add($i18n->get('error.field'), $i18n->get('label.status')); if ($err->no()) { $existing_role = ttRoleHelper::getRoleByName($cl_name); diff --git a/task_edit.php b/task_edit.php index b2b61b80b..9761e31db 100644 --- a/task_edit.php +++ b/task_edit.php @@ -56,6 +56,7 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidStatus($cl_status)) $err->add($i18n->get('error.field'), $i18n->get('label.status')); if ($err->no()) { if ($request->getParameter('btn_save')) { diff --git a/template_edit.php b/template_edit.php index 2f3c69727..2ff87b721 100644 --- a/template_edit.php +++ b/template_edit.php @@ -64,6 +64,7 @@ if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidString($cl_content)) $err->add($i18n->get('error.field'), $i18n->get('label.template')); + if (!ttValidStatus($cl_status)) $err->add($i18n->get('error.field'), $i18n->get('label.status')); if (!ttGroupHelper::validateCheckboxGroupInput($cl_projects, 'tt_projects')) $err->add($i18n->get('error.field'), $i18n->get('label.projects')); // Finished validating user input. diff --git a/timesheet_edit.php b/timesheet_edit.php index 164cc61bb..3e46733ae 100644 --- a/timesheet_edit.php +++ b/timesheet_edit.php @@ -51,6 +51,7 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); + if (!ttValidStatus($cl_status)) $err->add($i18n->get('error.field'), $i18n->get('label.status')); if ($request->getParameter('btn_save')) { if ($err->no()) { diff --git a/user_edit.php b/user_edit.php index 10aaebbb0..57133eb39 100644 --- a/user_edit.php +++ b/user_edit.php @@ -194,6 +194,7 @@ function render(&$table, $value, $row, $column, $selected = false) { if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); // Require selection of a client for a client role. if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); + if (!ttValidStatus($cl_status)) $err->add($i18n->get('error.field'), $i18n->get('label.status')); if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); // Validate input in user custom fields. if (isset($custom_fields) && $custom_fields->userFields) { From 4546333e1869a99b28981e3049a83b6ee4d4fa1f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 24 Oct 2021 14:57:44 +0000 Subject: [PATCH 1626/1848] Fixed ttValidStatus function to accept null values. --- WEB-INF/lib/common.lib.php | 3 +++ initialize.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 5840f3684..05a06808f 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -222,6 +222,9 @@ function ttValidFloat($val, $emptyValid = false) // ttValidStatus is used to check user input to validate a status value. function ttValidStatus($val) { + if (null == $val) + return true; + if (!ttValidInteger($val)) return false; diff --git a/initialize.php b/initialize.php index 342d458a6..c778bc422 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.33.5606"); +define("APP_VERSION", "1.19.33.5607"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 50c7a625e0f8e86d3ffb8ea7c5664a995718f797 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 28 Oct 2021 14:45:37 +0000 Subject: [PATCH 1627/1848] Dutch translation improvement. --- WEB-INF/resources/nl.lang.php | 3 +-- initialize.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 921d50af8..91ff4c8bc 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -594,8 +594,7 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', // Translator (Henk) comment: "kolom is the right word in Dutch." 'form.display_options.not_complete_days' => 'Niet complete dagen', -// TODO: translate the following. -// 'form.display_options.inactive_projects' => 'Inactive projects', +'form.display_options.inactive_projects' => 'Niet actieve projecten', 'form.display_options.custom_css' => 'Aangepaste CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php diff --git a/initialize.php b/initialize.php index c778bc422..f02b0b0e3 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.33.5607"); +define("APP_VERSION", "1.19.33.5608"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ab0e714e047eac432316aca5eee38589215745d8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 22 Nov 2021 17:19:15 +0000 Subject: [PATCH 1628/1848] Fixed CustomFileds class for adding a previously deleted option. --- initialize.php | 2 +- plugins/CustomFields.class.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/initialize.php b/initialize.php index f02b0b0e3..b93c09ce2 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.33.5608"); +define("APP_VERSION", "1.19.34.5609"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 26e4532b3..1a7b94e9e 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -140,8 +140,9 @@ static function insertOption($field_id, $option_name) { // Check if the option exists. $id = 0; - $sql = "select id from tt_custom_field_options" . - " where field_id = $field_id and group_id = $group_id and org_id = $org_id and value = " . $mdb2->quote($option_name); + $sql = "select id from tt_custom_field_options". + " where field_id = $field_id and group_id = $group_id and org_id = $org_id and value = ".$mdb2->quote($option_name). + " and status is not null"; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; From 79b16664911af80dc0703ea8d8192242e7f32748 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 21 Dec 2021 21:16:50 +0000 Subject: [PATCH 1629/1848] Addressed CVE-2021-41139 situation in week.php. --- initialize.php | 2 +- week.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/initialize.php b/initialize.php index b93c09ce2..4be516486 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5609"); +define("APP_VERSION", "1.19.34.5610"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/week.php b/week.php index fbfbfee36..e6f7864bb 100644 --- a/week.php +++ b/week.php @@ -38,6 +38,12 @@ exit(); } } +// If we are passed in a date, make sure it is in correct format. +$date = $request->getParameter('date'); +if ($date && !ttValidDbDateFormatDate($date)) { + header('Location: access_denied.php'); + exit(); +} if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); From 52e8604e0ac0c33497c6e0de0db459a53b6627d7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 24 Jan 2022 17:25:34 +0000 Subject: [PATCH 1630/1848] Work in progress removing remote work plugin. --- WEB-INF/templates/plugins.tpl | 6 ------ initialize.php | 2 +- plugins.php | 5 ----- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index 5c1e4c943..e4402f62d 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -210,12 +210,6 @@ function handlePluginCheckboxes() {
{$forms.pluginsForm.attachments.control} {$i18n.label.what_is_it}
{$forms.pluginsForm.work.control} {$i18n.label.what_is_it}
{$forms.pluginsForm.btn_save.control}
{$forms.pluginsForm.close} diff --git a/initialize.php b/initialize.php index 4be516486..c4fccc0f4 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5610"); +define("APP_VERSION", "1.19.34.5611"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins.php b/plugins.php index 95b6d4b9b..1dfe6a073 100644 --- a/plugins.php +++ b/plugins.php @@ -32,7 +32,6 @@ $cl_timesheets = (bool)$request->getParameter('timesheets'); $cl_templates = (bool)$request->getParameter('templates'); $cl_attachments = (bool)$request->getParameter('attachments'); - $cl_work = (bool)$request->getParameter('work'); } else { // Note: we get here in get, and also in post when group changes. // Which plugins do we have enabled in currently selected group? @@ -55,7 +54,6 @@ $cl_timesheets = in_array('ts', $plugins); $cl_templates = in_array('tp', $plugins); $cl_attachments = in_array('at', $plugins); - $cl_work = in_array('wk', $plugins); } $form = new Form('pluginsForm'); @@ -79,7 +77,6 @@ $form->addInput(array('type'=>'checkbox','name'=>'timesheets','value'=>$cl_timesheets)); $form->addInput(array('type'=>'checkbox','name'=>'templates','value'=>$cl_templates,'onchange'=>'handlePluginCheckboxes()')); $form->addInput(array('type'=>'checkbox','name'=>'attachments','value'=>$cl_attachments,'onchange'=>'handlePluginCheckboxes()')); -$form->addInput(array('type'=>'checkbox','name'=>'work','value'=>$cl_work,'onchange'=>'handlePluginCheckboxes()')); // Submit button. $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); @@ -124,8 +121,6 @@ $plugins .= ',tp'; if ($cl_attachments) $plugins .= ',at'; - if ($cl_work) - $plugins .= ',wk'; $plugins = trim($plugins, ','); // Prepare a new config string. From 6ff1577e836c0f8134734f8a382be7b11c888fe1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 24 Jan 2022 17:35:24 +0000 Subject: [PATCH 1631/1848] Fixed headers to remove remote work plugin. --- WEB-INF/templates/header.tpl | 3 --- WEB-INF/templates/work/header.tpl | 3 --- initialize.php | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index e7df23ea6..372b18d46 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -134,9 +134,6 @@ {if $user->isPluginEnabled('cl') && ($user->can('view_own_clients') || $user->can('manage_clients'))}
{$i18n.menu.clients}{$i18n.title.work}{$i18n.menu.export}
{$i18n.menu.groups} {$i18n.menu.options}{$i18n.label.work}
diff --git a/WEB-INF/templates/site_map.tpl b/WEB-INF/templates/site_map.tpl index 6848fc52e..54ff8818d 100644 --- a/WEB-INF/templates/site_map.tpl +++ b/WEB-INF/templates/site_map.tpl @@ -4,9 +4,6 @@
- {if isTrue('WORK_SERVER_ADMINISTRATION')} - - {/if}
{* end of sub menu for admin *} {* main menu for admin *} diff --git a/WEB-INF/templates/work/admin_offer_edit.tpl b/WEB-INF/templates/work/admin_offer_edit.tpl deleted file mode 100644 index bd9a6542b..000000000 --- a/WEB-INF/templates/work/admin_offer_edit.tpl +++ /dev/null @@ -1,70 +0,0 @@ -{$forms.offerForm.open} - - - - -
- -{if $work_id} - - - - - - - - - -{/if} - - - - - - - - - - - - -{if $show_files} - - - - -{/if} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.work}:{$work_name}
{$forms.offerForm.work_description.control}
 
{$i18n.label.offer} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control}
{$i18n.label.status}:{$forms.offerForm.status.control}
{$i18n.label.moderator_comment}:{$forms.offerForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_approve.control} {$forms.offerForm.btn_save.control} {$forms.offerForm.btn_disapprove.control}
-
-{$forms.offerForm.close} diff --git a/WEB-INF/templates/work/admin_work.tpl b/WEB-INF/templates/work/admin_work.tpl deleted file mode 100644 index 13f37e911..000000000 --- a/WEB-INF/templates/work/admin_work.tpl +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - -
-{if $pending_work} - - - - - - - - - - - {foreach $pending_work as $work_item} - - - - - - - - - {/foreach} -
{$i18n.title.pending_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape} ({$work_item.site_id}.{$work_item.group_id}){$work_item.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
-{/if} - -
- -{if $pending_offers} - - - - - - - - - - - {foreach $pending_offers as $offer} - - - - - - - - - {/foreach} -
{$i18n.title.pending_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape} ({$offer.site_id}.{$offer.group_id}){$offer.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
-{/if} - -
- - - -{if $available_work} - - - - - - - {foreach $available_work as $work_item} - - - - - - - {/foreach} -{/if} -
{$i18n.title.available_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape}{$work_item.amount_with_currency}
- -
- - - -{if $available_offers} - - - - - - - {foreach $available_offers as $offer} - - - - - - - {/foreach} -{/if} -
{$i18n.title.available_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape}{$offer.amount_with_currency}
- -
diff --git a/WEB-INF/templates/work/admin_work_edit.tpl b/WEB-INF/templates/work/admin_work_edit.tpl deleted file mode 100644 index 1ae59a6fe..000000000 --- a/WEB-INF/templates/work/admin_work_edit.tpl +++ /dev/null @@ -1,67 +0,0 @@ -{$forms.workForm.open} - -{if $offer} - - - -{/if} - - - -
- - - - - -
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
-
- - - - - - - - - - - - - -{if $show_files} - - - - -{/if} - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.work} (*):{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control}
{$i18n.label.status}:{$forms.workForm.status.control}
{$i18n.label.moderator_comment}:{$forms.workForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_save.control}
-
-{$forms.workForm.close} diff --git a/WEB-INF/templates/work/footer_old.tpl b/WEB-INF/templates/work/footer_old.tpl deleted file mode 100644 index 611067550..000000000 --- a/WEB-INF/templates/work/footer_old.tpl +++ /dev/null @@ -1,29 +0,0 @@ -
-

 

- - - - - -
{$i18n.footer.contribute_msg}
-
- - - - -
Anuko Time Tracker {constant('APP_VERSION')} | Copyright © Anuko | - {$i18n.footer.credits} | - {$i18n.footer.license} | - {$i18n.footer.improve} -
-
- -
- - - diff --git a/WEB-INF/templates/work/header.tpl b/WEB-INF/templates/work/header.tpl deleted file mode 100644 index 6b767a16a..000000000 --- a/WEB-INF/templates/work/header.tpl +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - -{if $i18n.language.rtl} - -{/if} - Time Tracker{if $title} - {$title}{/if} - - - - - - - -{assign var="tab_width" value="700"} - - - - - - + +
- - - - -{if $user->custom_logo} - - -
-{else} - -{/if} - - - - -
- - - -{if $user->custom_logo} - -{else} - -{/if} - - -
-
- - -{if $authenticated} - {if $user->can('administer_site')} - - - - - -
  - {$i18n.menu.logout} - {$i18n.menu.forum} - {$i18n.menu.help} -
- - - - - - - - - - {else} - - - - - -
  - {$i18n.menu.logout} - {if $user->exists() && $user->can('manage_own_settings')} - {$i18n.menu.profile} - {/if} - {if $user->can('manage_basic_settings')} - {$i18n.menu.group} - {/if} - {if $user->can('manage_features')} - {$i18n.menu.plugins} - {/if} - {$i18n.menu.forum} - {$i18n.menu.help} -
- - - - - - - - - - {/if} -{else} - - - - - -
  - {$i18n.menu.login} - {if isTrue('MULTIORG_MODE') && constant('AUTH_MODULE') == 'db'} - {$i18n.menu.register} - {/if} - {$i18n.menu.forum} - {$i18n.menu.help} -
-{/if} -
- - -{if $title} - - - {* No need to escape as it is done in the class. *} -
{$title}{if $timestring}: {$timestring}{/if}
{$user->getUserPartForHeader()}
-{/if} - - - -{if $err->yes()} - - - - -
- {foreach $err->getErrors() as $error} - {$error.message}
{* No need to escape as they are not coming from user and may contain a link. *} - {/foreach} -
-{/if} - - - -{if $msg->yes()} - - - - -
- {foreach $msg->getErrors() as $message} - {$message.message}
{* No need to escape. *} - {/foreach} -
-{/if} - diff --git a/WEB-INF/templates/work/index.tpl b/WEB-INF/templates/work/index.tpl deleted file mode 100644 index c4f193521..000000000 --- a/WEB-INF/templates/work/index.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{include file="work/header.tpl"} - -{if $content_page_name}{include file="$content_page_name"}{/if} - -{include file="work/footer_old.tpl"} diff --git a/WEB-INF/templates/work/offer_add.tpl b/WEB-INF/templates/work/offer_add.tpl deleted file mode 100644 index 80e07d803..000000000 --- a/WEB-INF/templates/work/offer_add.tpl +++ /dev/null @@ -1,74 +0,0 @@ -{$forms.offerForm.open} - -{if $work_item} - - - -{/if} - - - - -
- - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- -{if $work_id} - - - - - - - - - -{/if} - - - - - - - - - - - - -{if $show_files} - - - - -{/if} - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.work}:{$work_name}
{$forms.offerForm.work_description.control}
 
{$i18n.label.offer} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_add.control}
-
-{$forms.offerForm.close} diff --git a/WEB-INF/templates/work/offer_delete.tpl b/WEB-INF/templates/work/offer_delete.tpl deleted file mode 100644 index 7d8954cfb..000000000 --- a/WEB-INF/templates/work/offer_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.offerDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$offer_to_delete|escape}
 
{$forms.offerDeleteForm.btn_delete.control}  {$forms.offerDeleteForm.btn_cancel.control}
-
-{$forms.offerDeleteForm.close} diff --git a/WEB-INF/templates/work/offer_edit.tpl b/WEB-INF/templates/work/offer_edit.tpl deleted file mode 100644 index 5c1e89a33..000000000 --- a/WEB-INF/templates/work/offer_edit.tpl +++ /dev/null @@ -1,67 +0,0 @@ -{$forms.offerForm.open} - -{if $work_item} - - - -{/if} - - - - -
- - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{if $show_moderator_comment} - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.offer} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control} {$i18n.label.what_is_it}
{$i18n.label.status}:{$forms.offerForm.status.control}
{$i18n.label.moderator_comment}:{$forms.offerForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_save.control}
-
-{$forms.offerForm.close} diff --git a/WEB-INF/templates/work/offer_message.tpl b/WEB-INF/templates/work/offer_message.tpl deleted file mode 100644 index c97a3db91..000000000 --- a/WEB-INF/templates/work/offer_message.tpl +++ /dev/null @@ -1,32 +0,0 @@ - - -{$forms.messageForm.open} - -{if $offer} - - - -{/if} - - - -
- - - - -
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
-
- - - - - - - - -
{$i18n.work.label.message}:{$forms.messageForm.message_body.control}
{$forms.messageForm.btn_send.control}
-
-{$forms.messageForm.close} diff --git a/WEB-INF/templates/work/offer_view.tpl b/WEB-INF/templates/work/offer_view.tpl deleted file mode 100644 index 3d9d7d0c5..000000000 --- a/WEB-INF/templates/work/offer_view.tpl +++ /dev/null @@ -1,47 +0,0 @@ - - -{$forms.offerForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.contractor}:{$forms.offerForm.contractor.control}
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
-
-{$forms.offerForm.close} - - - - - -
- - - - - -
-
diff --git a/WEB-INF/templates/work/offer_view_own.tpl b/WEB-INF/templates/work/offer_view_own.tpl deleted file mode 100644 index d00ae7ea1..000000000 --- a/WEB-INF/templates/work/offer_view_own.tpl +++ /dev/null @@ -1,42 +0,0 @@ - - -{$forms.offerForm.open} - -{if $work_item} - - - -{/if} - - - - -
- - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- - - - - - - - - - - - - - - - - -
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
-
-{$forms.offerForm.close} diff --git a/WEB-INF/templates/work/work.tpl b/WEB-INF/templates/work/work.tpl deleted file mode 100644 index 67235b64f..000000000 --- a/WEB-INF/templates/work/work.tpl +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - -
-{if $own_work_items} - - - - - - - - - - - - {foreach $own_work_items as $work_item} - - - - - - - {if $work_item.can_edit} - - {else} - - {/if} - {if $work_item.can_delete} - - {else} - - {/if} - - {/foreach} -
{$i18n.work.label.own_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.status}{$i18n.work.label.offers}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.status_label}{if $work_item.num_offers}{$work_item.num_offers}{/if}{$work_item.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
-{/if} - - - -{if $available_work_items} - - - - - - - {foreach $available_work_items as $work_item} - - - - - - - {/foreach} -{/if} -
{$i18n.title.available_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape}{$work_item.amount_with_currency}
- - - - - -

-
-
- -{if $own_offers} - - - - - - - - - - - {foreach $own_offers as $offer} - - - - - - - - - {/foreach} -
{$i18n.work.label.own_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.status}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.status_label}{$offer.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
-{/if} - - - -{if $available_offers} - - - - - - - {foreach $available_offers as $offer} - - - - - - - {/foreach} -{/if} -
{$i18n.title.available_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape}{$offer.amount_with_currency}
- - - - - -

-
-
- -
diff --git a/WEB-INF/templates/work/work_add.tpl b/WEB-INF/templates/work/work_add.tpl deleted file mode 100644 index eca0ba799..000000000 --- a/WEB-INF/templates/work/work_add.tpl +++ /dev/null @@ -1,62 +0,0 @@ -{$forms.workForm.open} - -{if $offer} - - - -{/if} - - - -
- - - - -
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
-
- - - - - - - - - - - - - - - - - -{if $show_files} - - - - -{/if} - - - - - - - - - - - - - - - - - - - -
{$i18n.label.work} (*):{$forms.workForm.work_name.control}
{$i18n.label.type}:{$forms.workForm.work_type.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_add.control}
-
-{$forms.workForm.close} diff --git a/WEB-INF/templates/work/work_delete.tpl b/WEB-INF/templates/work/work_delete.tpl deleted file mode 100644 index 2831b0f15..000000000 --- a/WEB-INF/templates/work/work_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.workDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$work_to_delete|escape}
 
{$forms.workDeleteForm.btn_delete.control}  {$forms.workDeleteForm.btn_cancel.control}
-
-{$forms.workDeleteForm.close} diff --git a/WEB-INF/templates/work/work_edit.tpl b/WEB-INF/templates/work/work_edit.tpl deleted file mode 100644 index 7165d5e19..000000000 --- a/WEB-INF/templates/work/work_edit.tpl +++ /dev/null @@ -1,73 +0,0 @@ -{$forms.workForm.open} - -{if $offer} - - - -{/if} - - - -
- - - - - -
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
-
- - - - - - - - - - - - - - - - - -{if $show_files} - - - - -{/if} - - - - - - - - - - - - -{if $show_moderator_comment} - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.work} (*):{$forms.workForm.work_name.control}
{$i18n.label.type}:{$forms.workForm.work_type.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.status}:{$forms.workForm.status.control}
{$i18n.label.moderator_comment}:{$forms.workForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_save.control}
-
-{$forms.workForm.close} diff --git a/WEB-INF/templates/work/work_message.tpl b/WEB-INF/templates/work/work_message.tpl deleted file mode 100644 index 3f237659c..000000000 --- a/WEB-INF/templates/work/work_message.tpl +++ /dev/null @@ -1,32 +0,0 @@ - - -{$forms.messageForm.open} - -{if $work_item} - - - -{/if} - - - -
- - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- - - - - - - - -
{$i18n.work.label.message}:{$forms.messageForm.message_body.control}
{$forms.messageForm.btn_send.control}
-
-{$forms.messageForm.close} diff --git a/WEB-INF/templates/work/work_offer_view.tpl b/WEB-INF/templates/work/work_offer_view.tpl deleted file mode 100644 index e2afe0003..000000000 --- a/WEB-INF/templates/work/work_offer_view.tpl +++ /dev/null @@ -1,57 +0,0 @@ -{$forms.offerForm.open} - -{if $work_item} - - - -{/if} - - - -
- - - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.client}: {$work_item.group_name}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.contractor}:{$forms.offerForm.contractor.control}
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
{$i18n.label.status}:{$forms.offerForm.status.control}
 
{$forms.offerForm.btn_accept.control} {$forms.offerForm.btn_decline.control}
{$i18n.label.comment}:{$forms.offerForm.client_comment.control}
-
-{$forms.offerForm.close} diff --git a/WEB-INF/templates/work/work_offers.tpl b/WEB-INF/templates/work/work_offers.tpl deleted file mode 100644 index ea0d8816f..000000000 --- a/WEB-INF/templates/work/work_offers.tpl +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - -
- - - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.client}: {$work_item.group_name}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- -{if $work_item_offers} - - - - - - - - {foreach $work_item_offers as $offer} - - - - - - - {/foreach} -
{$i18n.label.contractor}{$i18n.label.description}{$i18n.label.status}{$i18n.label.budget}
{$offer.group_name|escape}{$offer.description|escape}{$offer.status_label}{$offer.amount_with_currency}
-{/if} - -
diff --git a/WEB-INF/templates/work/work_view.tpl b/WEB-INF/templates/work/work_view.tpl deleted file mode 100644 index 468cb9ddd..000000000 --- a/WEB-INF/templates/work/work_view.tpl +++ /dev/null @@ -1,47 +0,0 @@ - - -{$forms.workForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.client}:{$forms.workForm.client.control}
{$i18n.label.work}:{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.budget}:{$forms.workForm.budget.control}
-
-{$forms.workForm.close} - - - - - -
- - - - - -
-
diff --git a/WEB-INF/templates/work/work_view_own.tpl b/WEB-INF/templates/work/work_view_own.tpl deleted file mode 100644 index 61e270b4b..000000000 --- a/WEB-INF/templates/work/work_view_own.tpl +++ /dev/null @@ -1,38 +0,0 @@ -{$forms.workForm.open} - -{if $offer} - - - -{/if} - - - -
- - - - - -
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
-
- - - - - - - - - - - - - - - - - -
{$i18n.label.work}:{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.budget}:{$forms.workForm.budget.control}
-
-{$forms.workForm.close} diff --git a/work/admin_offer_delete.php b/work/admin_offer_delete.php deleted file mode 100644 index a1bd5fac1..000000000 --- a/work/admin_offer_delete.php +++ /dev/null @@ -1,71 +0,0 @@ -getParameter('id'); -$adminWorkHelper = new ttAdminWorkHelper($err); -$offer = $adminWorkHelper->getOffer($cl_offer_id); -if (!$offer) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -$offer_to_delete = $offer['subject']; - -$form = new Form('offerDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if ($adminWorkHelper->deleteOffer($cl_offer_id)) { - header('Location: admin_work.php'); - exit(); - } - } elseif ($request->getParameter('btn_cancel')) { - header('Location: admin_work.php'); - exit(); - } -} // isPost - -$smarty->assign('offer_to_delete', $offer_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.offerDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_offer')); -$smarty->assign('content_page_name', 'work/offer_delete.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/admin_offer_edit.php b/work/admin_offer_edit.php deleted file mode 100644 index ab795c136..000000000 --- a/work/admin_offer_edit.php +++ /dev/null @@ -1,171 +0,0 @@ -getParameter('id'); -$adminWorkHelper = new ttAdminWorkHelper($err); -$offer = $adminWorkHelper->getOffer($cl_offer_id); -if (!$offer) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -// Is this offer associated with a work item? -$work_id = $offer['work_id']; -if ($work_id) { - $work_item = $adminWorkHelper->getWorkItem($work_id); - if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); -} - -$existingStatus = $offer['status']; -$currencies = ttWorkHelper::getCurrencies(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('offer_name')); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - $cl_budget = $request->getParameter('budget'); - $cl_payment_info = $request->getParameter('payment_info'); - // $cl_status = $request->getParameter('status'); - $cl_moderator_comment = $request->getParameter('moderator_comment'); -} else { - $cl_name = $offer['subject']; - $cl_description = $offer['descr_short']; - $cl_details = $offer['descr_long']; - $currency = $offer['currency']; - $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); - $cl_budget = $offer['amount']; - $cl_payment_info = $offer['payment_info']; - $status = $offer['status']; - $status_label = $offer['status_label']; - $cl_moderator_comment = $offer['moderator_comment']; -} - -$form = new Form('offerForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -if ($work_id) { - $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); - $form->getElement('work_description')->setEnabled(false); -} -$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); -if ($work_id) $form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -if ($work_id) $form->getElement('currency')->setEnabled(false); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); -$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$status_label)); -$form->getElement('status')->setEnabled(false); - -// Prepare status choices. -/* -$status_options = array(); -$status_options[STATUS_PENDING_APPROVAL] = $i18n->get('dropdown.pending_approval'); -$status_options[STATUS_DISAPPROVED] = $i18n->get('dropdown.not_approved'); -$status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); - -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); -*/ -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -if ($status == STATUS_PENDING_APPROVAL) { - $form->addInput(array('type'=>'submit','name'=>'btn_approve','value'=>$i18n->get('button.approve'))); - $form->addInput(array('type'=>'submit','name'=>'btn_disapprove','value'=>$i18n->get('button.disapprove'))); -} - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - if (!ttValidString($cl_payment_info)) $err->add($i18n->get('error.field'), $i18n->get('label.how_to_pay')); - if (!ttValidString($cl_moderator_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.moderator_comment')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - $fields = array('offer_id'=>$cl_offer_id, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget, - 'payment_info' => $cl_payment_info, - 'moderator_comment' => $cl_moderator_comment); - - if ($err->no()) { - if ($request->getParameter('btn_approve')) { - // Approve offer. - if ($adminWorkHelper->approveOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } - - if ($request->getParameter('btn_save')) { - // Update offer without changing its status. - if ($adminWorkHelper->updateOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } - - if ($request->getParameter('btn_disapprove')) { - // Dispprove offer. - if ($adminWorkHelper->disapproveOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } - } -} // isPost - -if ($work_id) { - $smarty->assign('work_id', $work_id); - $smarty->assign('work_name', $work_item['subject']); - $smarty->assign('work_description', $work_item['descr_short']); -} -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.edit_offer')); -$smarty->assign('content_page_name', 'work/admin_offer_edit.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/admin_work.php b/work/admin_work.php deleted file mode 100644 index 86a029a4a..000000000 --- a/work/admin_work.php +++ /dev/null @@ -1,53 +0,0 @@ -getItems(); -$pending_work = $adminItems['pending_work']; -$pending_offers = $adminItems['pending_offers']; -$available_work = $adminItems['available_work']; -$available_offers = $adminItems['available_offers']; - -$smarty->assign('pending_work', $pending_work); -$smarty->assign('pending_offers', $pending_offers); -$smarty->assign('available_work', $available_work); -$smarty->assign('available_offers', $available_offers); -$smarty->assign('title', $i18n->get('title.work')); -$smarty->assign('content_page_name', 'work/admin_work.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/admin_work_delete.php b/work/admin_work_delete.php deleted file mode 100644 index 11b599430..000000000 --- a/work/admin_work_delete.php +++ /dev/null @@ -1,71 +0,0 @@ -getParameter('id'); -$adminWorkHelper = new ttAdminWorkHelper($err); -$work_item = $adminWorkHelper->getWorkItem($cl_work_id); -if (!$work_item) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -$work_to_delete = $work_item['subject']; - -$form = new Form('workDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if ($adminWorkHelper->deleteWorkItem($cl_work_id)) { - header('Location: admin_work.php'); - exit(); - } - } elseif ($request->getParameter('btn_cancel')) { - header('Location: admin_work.php'); - exit(); - } -} // isPost - -$smarty->assign('work_to_delete', $work_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.workDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_work')); -$smarty->assign('content_page_name', 'work/work_delete.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/admin_work_edit.php b/work/admin_work_edit.php deleted file mode 100644 index 51169325c..000000000 --- a/work/admin_work_edit.php +++ /dev/null @@ -1,168 +0,0 @@ -getParameter('id'); -$adminWorkHelper = new ttAdminWorkHelper($err); -$work_item = $adminWorkHelper->getWorkItem($cl_work_id); -if (!$work_item) { - header('Location: ../access_denied.php'); - exit(); -} -// Do we have offer_id? -$offer_id = $work_item['offer_id']; -if ($offer_id) { - $offer = $adminWorkHelper->getOffer($offer_id); - if (!$offer) { - header('Location: ../access_denied.php'); - exit(); - } -} -// End of access checks. - -$existingStatus = $work_item['status']; -$currencies = ttWorkHelper::getCurrencies(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('work_name')); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - $cl_budget = $request->getParameter('budget'); - $cl_status = $request->getParameter('status'); - $cl_moderator_comment = $request->getParameter('moderator_comment'); -} else { - $cl_name = $work_item['subject']; - $cl_description = $work_item['descr_short']; - $cl_details = $work_item['descr_long']; - $currency = $work_item['currency']; - $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - $cl_budget = $work_item['amount']; - $cl_status = $work_item['status']; - $cl_moderator_comment = $work_item['moderator_comment']; -} - -$form = new Form('workForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -// Disable some controls for work on an available offer. -if ($offer) { - $form->getElement('work_name')->setEnabled(false); - // $form->getElement('work_type')->setEnabled(false); - $form->getElement('currency')->setEnabled(false); - $form->getElement('budget')->setEnabled(false); -} - -// Prepare status choices. -$status_options = array(); -$status_options[STATUS_PENDING_APPROVAL] = $i18n->get('dropdown.pending_approval'); -$status_options[STATUS_DISAPPROVED] = $i18n->get('dropdown.not_approved'); -$status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); - -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - if (!ttValidString($cl_moderator_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.moderator_comment')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $fields = array('work_id'=>$cl_work_id, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget, - 'moderator_comment' => $cl_moderator_comment); - - // Do things differently, depending on status control value. - if ($existingStatus == $cl_status) { - // Status not changed. Update work information. - if ($adminWorkHelper->updateWorkItem($fields)) { - header('Location: admin_work.php'); - exit(); - } - } else if ($cl_status == STATUS_DISAPPROVED) { - // Status changed to "not approved". Disapprove work. - if ($offer_id) { - if ($adminWorkHelper->disapproveWorkItemOnOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } else { - if ($adminWorkHelper->disapproveWorkItem($fields)) { - header('Location: admin_work.php'); - exit(); - } - } - } else if ($cl_status == STATUS_APPROVED) { - // Status changed to "approved". Approve work. - if ($offer_id) { - if ($adminWorkHelper->approveWorkItemOnOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } else { - if ($adminWorkHelper->approveWorkItem($fields)) { - header('Location: admin_work.php'); - exit(); - } - } - } - } - } -} // isPost - -$smarty->assign('offer', $offer); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.edit_work')); -$smarty->assign('content_page_name', 'work/admin_work_edit.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/offer_add.php b/work/offer_add.php deleted file mode 100644 index bafdae216..000000000 --- a/work/offer_add.php +++ /dev/null @@ -1,120 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -// Do we have work_id? -$cl_work_id = (int)$request->getParameter('work_id'); -if ($cl_work_id) { - $workHelper = new ttWorkHelper($err); - $work_item = $workHelper->getAvailableWorkItem($cl_work_id); - if (!$work_item) { - header('Location: ../access_denied.php'); - exit(); - } -} -// End of access checks. -if ($work_item) $cl_name = $work_item['subject']; - -if ($request->isPost()) { - if (!$work_item) - $cl_name = trim($request->getParameter('offer_name')); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - $cl_budget = $request->getParameter('budget'); - $cl_payment_info = $request->getParameter('payment_info'); -} else { - if ($work_item) { - $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - } -} - -$form = new Form('offerForm'); -if ($cl_work_id) { - $form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); - $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); - $form->getElement('work_description')->setEnabled(false); -} -$form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); -if ($work_item) $form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -// Add a dropdown for currency. -$currencies = ttWorkHelper::getCurrencies(); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -if ($work_item) $form->getElement('currency')->setEnabled(false); // Do not allow changing currency for offers on existing work items. -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.offer')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - if (!ttValidString($cl_payment_info)) $err->add($i18n->get('error.field'), $i18n->get('label.how_to_pay')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - $workHelper = new ttWorkHelper($err); - $fields = array('work_id'=>$cl_work_id, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget, - 'payment_info' => $cl_payment_info); - if ($workHelper->putOwnOffer($fields)) { - header('Location: work.php'); - exit(); - } - } -} // isPost - -$smarty->assign('work_item', $work_item); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); -$smarty->assign('title', $i18n->get('title.add_offer')); -$smarty->assign('content_page_name', 'work/offer_add.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/offer_delete.php b/work/offer_delete.php deleted file mode 100644 index fd3d2e7d1..000000000 --- a/work/offer_delete.php +++ /dev/null @@ -1,75 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -$cl_offer_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getOwnOffer($cl_offer_id); -if (!$offer) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -$offer_to_delete = $offer['subject']; - -$form = new Form('offerDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if ($workHelper->deleteOwnOffer($cl_offer_id)) { - header('Location: work.php'); - exit(); - } - } elseif ($request->getParameter('btn_cancel')) { - header('Location: work.php'); - exit(); - } -} // isPost - -$smarty->assign('offer_to_delete', $offer_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.offerDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_offer')); -$smarty->assign('content_page_name', 'work/offer_delete.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/offer_edit.php b/work/offer_edit.php deleted file mode 100644 index bd2172210..000000000 --- a/work/offer_edit.php +++ /dev/null @@ -1,135 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -$cl_offer_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getOwnOffer($cl_offer_id); -if (!$offer) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -// Is this offer associated with a work item? -$work_id = $offer['work_id']; -if ($work_id) { - $work_item = $workHelper->getAvailableWorkItem($work_id); - if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); -} - -$currencies = ttWorkHelper::getCurrencies(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('offer_name')); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - $cl_budget = $request->getParameter('budget'); - $cl_payment_info = $request->getParameter('payment_info'); -} else { - $cl_name = $offer['subject']; - $cl_description = $offer['descr_short']; - $cl_details = $offer['descr_long']; - $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); - $cl_budget = $offer['amount']; - $cl_payment_info = $offer['payment_info']; - $cl_status = $offer['status_label']; - $cl_moderator_comment = $offer['moderator_comment']; -} - -$show_moderator_comment = $cl_moderator_comment != null; - -$form = new Form('offerForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -if ($work_id) { - $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); - $form->getElement('work_description')->setEnabled(false); -} -$form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); -if ($work_id) $form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -if ($work_id) $form->getElement('currency')->setEnabled(false); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px; vertical-align: middle','value'=>$cl_payment_info)); -$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); -$form->getElement('status')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); -$form->getElement('moderator_comment')->setEnabled(false); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.offer')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - if (!ttValidString($cl_payment_info)) $err->add($i18n->get('error.field'), $i18n->get('label.how_to_pay')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - // Update offer information. - $fields = array('offer_id'=>$cl_offer_id, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget, - 'payment_info' => $cl_payment_info); - if ($workHelper->updateOwnOffer($fields)) { - header('Location: work.php'); - exit(); - } - } - } -} // isPost - -$smarty->assign('work_item', $work_item); -$smarty->assign('show_moderator_comment', $show_moderator_comment); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.edit_offer')); -$smarty->assign('content_page_name', 'work/offer_edit.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/offer_message.php b/work/offer_message.php deleted file mode 100644 index ff324808e..000000000 --- a/work/offer_message.php +++ /dev/null @@ -1,90 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -$cl_offer_id = (int)$request->getParameter('offer_id'); -if (!$cl_offer_id) { - header('Location: ../access_denied.php'); - exit(); -} -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getAvailableOffer($cl_offer_id); -if (!$offer) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -$cl_name = $offer['subject']; - -if ($request->isPost()) { - $cl_message_body = trim($request->getParameter('message_body')); -} - -$form = new Form('messageForm'); -$form->addInput(array('type'=>'hidden','name'=>'offer_id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'textarea','name'=>'message_body','style'=>'width: 400px; height: 80px;vertical-align: middle','value'=>$cl_message_body)); -$form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('work.button.send_message'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_message_body)) $err->add($i18n->get('error.field'), $i18n->get('work.label.message')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - $workHelper = new ttWorkHelper($err); - $fields = array('offer_id'=>$cl_offer_id, - 'message_body' => $cl_message_body); - if ($workHelper->sendMessageToOfferOwner($fields)) { - $msg->add($i18n->get('work.msg.message_sent')); - // header('Location: work.php'); // TODO: where to redirect? - // exit(); - } - } -} // isPost - -$smarty->assign('offer', $offer); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); -$smarty->assign('title', $i18n->get('work.title.send_message')); -$smarty->assign('content_page_name', 'work/offer_message.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/offer_view.php b/work/offer_view.php deleted file mode 100644 index 1e045bf20..000000000 --- a/work/offer_view.php +++ /dev/null @@ -1,81 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -if (!ttAccessAllowed('manage_work')) { - header('Location: ../access_denied.php'); - exit(); -} -$offer_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getAvailableOffer($offer_id); -if (!$offer) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -// Is this offer associated with a work item? -$work_id = $offer['work_id']; -if ($work_id) { - $work_item = $workHelper->getAvailableWorkItem($work_id); - if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); -} - -$cl_contractor = $offer['group_name']; -$cl_name = $offer['subject']; -$cl_description = $offer['descr_short']; -$cl_details = $offer['descr_long']; -$cl_budget = $offer['amount_with_currency']; - -$form = new Form('offerForm'); -$form->addInput(array('type'=>'text','name'=>'contractor','value'=>$cl_contractor)); -$form->getElement('contractor')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->getElement('details')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); -$form->getElement('budget')->setEnabled(false); - - -$smarty->assign('offer_id', $offer_id); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.offer')); -$smarty->assign('content_page_name', 'work/offer_view.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/offer_view_own.php b/work/offer_view_own.php deleted file mode 100644 index 57b1b95b3..000000000 --- a/work/offer_view_own.php +++ /dev/null @@ -1,77 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -if (!ttAccessAllowed('manage_work')) { - header('Location: ../access_denied.php'); - exit(); -} -$offer_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getOwnOffer($offer_id); -if (!$offer) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -// Is this offer associated with a work item? -$work_id = $offer['work_id']; -if ($work_id) { - $work_item = $workHelper->getAvailableWorkItem($work_id); - if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); -} - -$cl_name = $offer['subject']; -$cl_description = $offer['descr_short']; -$cl_details = $offer['descr_long']; -$cl_budget = $offer['amount_with_currency']; - -$form = new Form('offerForm'); -$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->getElement('details')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); -$form->getElement('budget')->setEnabled(false); - -$smarty->assign('work_item', $work_item); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.offer')); -$smarty->assign('content_page_name', 'work/offer_view_own.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/work.php b/work/work.php deleted file mode 100644 index b043690b4..000000000 --- a/work/work.php +++ /dev/null @@ -1,65 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -// End of access checks. - -$workHelper = new ttWorkHelper($err); -$groupItems = $workHelper->getGroupItems(); // All group items. -if($user->can('manage_work')) { - $own_work_items = $groupItems['own_work_items']; // Own work items this group is outsourcing. - $available_offers = $groupItems['available_offers']; // Available offers from other organizations. -} -if($user->can('bid_on_work')) { - $available_work_items = $groupItems['available_work_items']; // Currently available work items from other orgs. - $own_offers = $groupItems['own_offers']; // Own offers this group makes available to other groups. -} -if($user->can('update_work')) { - // $in_progress_work = ttWorkHelper::getInProgressWork(); // Work items in progress for other groups. - // $completed_work = ttWorkHelper::getCompletedWork(); // Completed work items for other groups. -} -// TODO: review access rights for the code above. - -$smarty->assign('own_work_items', $own_work_items); -$smarty->assign('available_work_items', $available_work_items); -$smarty->assign('own_offers', $own_offers); -$smarty->assign('available_offers', $available_offers); -$smarty->assign('title', $i18n->get('title.work')); -$smarty->assign('content_page_name', 'work/work.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/work_add.php b/work/work_add.php deleted file mode 100644 index df12c9155..000000000 --- a/work/work_add.php +++ /dev/null @@ -1,122 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -// Do we have offer_id? -$cl_offer_id = (int)$request->getParameter('offer_id'); -if ($cl_offer_id) { - $workHelper = new ttWorkHelper($err); - $offer = $workHelper->getAvailableOffer($cl_offer_id); - if (!$offer) { - header('Location: ../access_denied.php'); - exit(); - } -} -// End of access checks. - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('work_name')); - $cl_work_type = $request->getParameter('work_type'); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - $cl_budget = $request->getParameter('budget'); -} -// Override some fields for work being created on an available offer. -if ($offer) { - $cl_name = $offer['subject']; - $cl_work_type = 0; // one-time work - $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); - $cl_budget = $offer['amount']; -} - -$form = new Form('workForm'); -if ($offer) - $form->addInput(array('type'=>'hidden','name'=>'offer_id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); -$WORK_TYPE_OPTIONS = array('0'=>$i18n->get('work.type.one_time'),'1'=>$i18n->get('work.type.ongoing')); -$form->addInput(array('type'=>'combobox','name'=>'work_type','data'=>$WORK_TYPE_OPTIONS,'value'=>$cl_work_type)); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -// Add a dropdown for currency. -$currencies = ttWorkHelper::getCurrencies(); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); -// Disable some controls for work being created on an available offer. -if ($offer) { - $form->getElement('work_name')->setEnabled(false); - $form->getElement('work_type')->setEnabled(false); - $form->getElement('currency')->setEnabled(false); - $form->getElement('budget')->setEnabled(false); -} - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - $workHelper = new ttWorkHelper($err); - $fields = array('offer_id' => $cl_offer_id, - 'subject' => $cl_name, - 'type' => $cl_work_type, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget); - if ($workHelper->putOwnWorkItem($fields)) { - header('Location: work.php'); - exit(); - } - } -} // isPost - -$smarty->assign('offer', $offer); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.workForm.work_name.focus()"'); -$smarty->assign('title', $i18n->get('title.add_work')); -$smarty->assign('content_page_name', 'work/work_add.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/work_delete.php b/work/work_delete.php deleted file mode 100644 index 1d94603ab..000000000 --- a/work/work_delete.php +++ /dev/null @@ -1,75 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -$cl_work_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getOwnWorkItem($cl_work_id); -if (!$work_item) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -$work_to_delete = $work_item['subject']; - -$form = new Form('workDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if ($workHelper->deleteOwnWorkItem($cl_work_id)) { - header('Location: work.php'); - exit(); - } - } elseif ($request->getParameter('btn_cancel')) { - header('Location: work.php'); - exit(); - } -} // isPost - -$smarty->assign('work_to_delete', $work_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.workDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_work')); -$smarty->assign('content_page_name', 'work/work_delete.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/work_edit.php b/work/work_edit.php deleted file mode 100644 index 7e27106b8..000000000 --- a/work/work_edit.php +++ /dev/null @@ -1,151 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -$cl_work_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getOwnWorkItem($cl_work_id); -if (!$work_item) { - header('Location: ../access_denied.php'); - exit(); -} -// Do we have offer_id? -$offer_id = $work_item['offer_id']; -if ($offer_id) { - $offer = $workHelper->getAvailableOffer($offer_id); - if (!$offer) { - header('Location: ../access_denied.php'); - exit(); - } -} -// End of access checks. - -$currencies = ttWorkHelper::getCurrencies(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('work_name')); - $cl_work_type = $request->getParameter('work_type'); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - $cl_budget = $request->getParameter('budget'); -} else { - $cl_name = $work_item['subject']; - $cl_work_type = $work_item['type']; - $cl_description = $work_item['descr_short']; - $cl_details = $work_item['descr_long']; - $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - $cl_budget = $work_item['amount']; - $cl_status = $work_item['status_label']; - $cl_moderator_comment = $work_item['moderator_comment']; -} -// Override some fields for work on an available offer. -if ($offer) { - $cl_name = $offer['subject']; - $cl_work_type = 0; // one-time work - $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); - $cl_budget = $offer['amount']; -} - -$show_moderator_comment = $cl_moderator_comment != null; - -$form = new Form('workForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); -$WORK_TYPE_OPTIONS = array('0'=>$i18n->get('work.type.one_time'),'1'=>$i18n->get('work.type.ongoing')); -$form->addInput(array('type'=>'combobox','name'=>'work_type','data'=>$WORK_TYPE_OPTIONS,'value'=>$cl_work_type)); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); -$form->getElement('status')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); -$form->getElement('moderator_comment')->setEnabled(false); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -// Disable some controls for work on an available offer. -if ($offer) { - $form->getElement('work_name')->setEnabled(false); - $form->getElement('work_type')->setEnabled(false); - $form->getElement('currency')->setEnabled(false); - $form->getElement('budget')->setEnabled(false); -} - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - // Update work information. - $fields = array('work_id'=>$cl_work_id, - 'type'=>$cl_work_type, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget); - if ($offer_id > 0) { - if ($workHelper->updateOwnWorkItemOnOffer($fields)) { - header('Location: work.php'); - exit(); - } - } else { - if ($workHelper->updateOwnWorkItem($fields)) { - header('Location: work.php'); - exit(); - } - } - } - } -} // isPost - -$smarty->assign('offer', $offer); -$smarty->assign('show_moderator_comment', $show_moderator_comment); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.edit_work')); -$smarty->assign('content_page_name', 'work/work_edit.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/work_message.php b/work/work_message.php deleted file mode 100644 index 91d02b5cb..000000000 --- a/work/work_message.php +++ /dev/null @@ -1,90 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -$cl_work_id = (int)$request->getParameter('work_id'); -if (!$cl_work_id) { - header('Location: ../access_denied.php'); - exit(); -} -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getAvailableWorkItem($cl_work_id); -if (!$work_item) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -$cl_name = $work_item['subject']; - -if ($request->isPost()) { - $cl_message_body = trim($request->getParameter('message_body')); -} - -$form = new Form('messageForm'); -$form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'textarea','name'=>'message_body','style'=>'width: 400px; height: 80px;vertical-align: middle','value'=>$cl_message_body)); -$form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('work.button.send_message'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_message_body)) $err->add($i18n->get('error.field'), $i18n->get('work.label.message')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - $workHelper = new ttWorkHelper($err); - $fields = array('work_id'=>$cl_work_id, - 'message_body' => $cl_message_body); - if ($workHelper->sendMessageToWorkOwner($fields)) { - $msg->add($i18n->get('work.msg.message_sent')); - // header('Location: work.php'); // TODO: where to redirect? - // exit(); - } - } -} // isPost - -$smarty->assign('work_item', $work_item); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); -$smarty->assign('title', $i18n->get('work.title.send_message')); -$smarty->assign('content_page_name', 'work/work_message.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/work_offer_view.php b/work/work_offer_view.php deleted file mode 100644 index c0dd5ee1a..000000000 --- a/work/work_offer_view.php +++ /dev/null @@ -1,123 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -if (!ttAccessAllowed('manage_work')) { - header('Location: ../access_denied.php'); - exit(); -} -$cl_offer_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getOwnWorkItemOffer($cl_offer_id); -if (!$offer) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -// Get an associated work item. -$work_item = $workHelper->getOwnWorkItem($offer['work_id']); -if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); - -if ($request->isPost()) { - $cl_client_comment = $request->getParameter('client_comment'); -} else { - $cl_client_comment = $offer['client_comment']; -} - -$cl_contractor = $offer['group_name']; -$cl_name = $offer['subject']; -$cl_description = $offer['descr_short']; -$cl_details = $offer['descr_long']; -$cl_budget = $offer['amount_with_currency']; -$cl_status = $offer['status_label']; - -$form = new Form('offerForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','name'=>'contractor','value'=>$cl_contractor)); -$form->getElement('contractor')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->getElement('details')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); -$form->getElement('budget')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); -$form->getElement('status')->setEnabled(false); -if ($offer['status'] == STATUS_APPROVED) { - $form->addInput(array('type'=>'submit','name'=>'btn_accept','value'=>$i18n->get('work.button.accept'))); - $form->addInput(array('type'=>'submit','name'=>'btn_decline','value'=>$i18n->get('work.button.decline'))); -} -$form->addInput(array('type'=>'textarea','name'=>'client_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_client_comment)); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_client_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - $workHelper = new ttWorkHelper($err); - $fields = array('offer_id'=>$cl_offer_id, - 'client_comment'=>$cl_client_comment); - - if ($request->getParameter('btn_accept')) { - // Accept offer. - if ($workHelper->acceptOwnWorkItemOffer($fields)) { - header('Location: work_offer_view.php?id='.$cl_offer_id); - exit(); - } - } - - if ($request->getParameter('btn_decline')) { - // Decline offer. - if ($workHelper->declineOwnWorkItemOffer($fields)) { - header('Location: work_offer_view.php?id='.$cl_offer_id); - exit(); - } - } - } -} // isPost - -$smarty->assign('work_item', $work_item); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.offer')); -$smarty->assign('content_page_name', 'work/work_offer_view.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/work_offers.php b/work/work_offers.php deleted file mode 100644 index eae9841bb..000000000 --- a/work/work_offers.php +++ /dev/null @@ -1,56 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -$work_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getOwnWorkItem($work_id); -if (!$work_item) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -$work_item_offers = $workHelper->getOwnWorkItemOffers($work_id); - -$smarty->assign('work_item', $work_item); -$smarty->assign('work_item_offers', $work_item_offers); -$smarty->assign('title', $i18n->get('work.label.offers')); -$smarty->assign('content_page_name', 'work/work_offers.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/work_view.php b/work/work_view.php deleted file mode 100644 index cb73f2eed..000000000 --- a/work/work_view.php +++ /dev/null @@ -1,74 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -if (!ttAccessAllowed('bid_on_work')) { - header('Location: ../access_denied.php'); - exit(); -} -$cl_work_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getAvailableWorkItem($cl_work_id); -if (!$work_item) { - header('Location: ../access_denied.php'); - exit(); -} -// End of access checks. - -$cl_client = $work_item['group_name']; -$cl_name = $work_item['subject']; -$cl_description = $work_item['descr_short']; -$cl_details = $work_item['descr_long']; -$cl_budget = $work_item['amount_with_currency']; - -$form = new Form('workForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','name'=>'client','value'=>$cl_client)); -$form->getElement('client')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->getElement('work_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->getElement('details')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); -$form->getElement('budget')->setEnabled(false); - -$smarty->assign('work_id', $cl_work_id); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.work')); -$smarty->assign('content_page_name', 'work/work_view.tpl'); -$smarty->display('work/index.tpl'); diff --git a/work/work_view_own.php b/work/work_view_own.php deleted file mode 100644 index c4b887e7e..000000000 --- a/work/work_view_own.php +++ /dev/null @@ -1,79 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: ../feature_disabled.php'); - exit(); -} -if (!ttAccessAllowed('manage_work')) { - header('Location: ../access_denied.php'); - exit(); -} -$work_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getOwnWorkItem($work_id); -if (!$work_item) { - header('Location: ../access_denied.php'); - exit(); -} -// Do we have offer_id? -$offer_id = $work_item['offer_id']; -if ($offer_id) { - $offer = $workHelper->getAvailableOffer($offer_id); - if (!$offer) { - header('Location: ../access_denied.php'); - exit(); - } -} -// End of access checks. - -$cl_name = $work_item['subject']; -$cl_description = $work_item['descr_short']; -$cl_details = $work_item['descr_long']; -$cl_budget = $work_item['amount_with_currency']; - -$form = new Form('workForm'); -$form->addInput(array('type'=>'textarea','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->getElement('work_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->getElement('details')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); -$form->getElement('budget')->setEnabled(false); - -$smarty->assign('offer', $offer); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.work')); -$smarty->assign('content_page_name', 'work/work_view_own.tpl'); -$smarty->display('work/index.tpl'); From 0db69425bcc8bbdc20091e20d2b7437f7b53071d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 25 Jan 2022 15:08:53 +0000 Subject: [PATCH 1633/1848] Some cleanup in translation files. --- WEB-INF/resources/ca.lang.php | 8 -------- WEB-INF/resources/cs.lang.php | 8 -------- WEB-INF/resources/da.lang.php | 8 -------- WEB-INF/resources/de.lang.php | 9 --------- WEB-INF/resources/en.lang.php | 8 -------- WEB-INF/resources/es.lang.php | 8 -------- WEB-INF/resources/et.lang.php | 8 -------- WEB-INF/resources/fa.lang.php | 8 -------- WEB-INF/resources/fi.lang.php | 8 -------- WEB-INF/resources/fr.lang.php | 8 -------- WEB-INF/resources/gr.lang.php | 8 -------- WEB-INF/resources/he.lang.php | 8 -------- WEB-INF/resources/hu.lang.php | 8 -------- WEB-INF/resources/it.lang.php | 8 -------- WEB-INF/resources/ja.lang.php | 8 -------- WEB-INF/resources/ko.lang.php | 8 -------- WEB-INF/resources/nl.lang.php | 5 ----- WEB-INF/resources/no.lang.php | 8 -------- WEB-INF/resources/pl.lang.php | 8 -------- WEB-INF/resources/pt-br.lang.php | 5 ----- WEB-INF/resources/pt.lang.php | 8 -------- WEB-INF/resources/ro.lang.php | 8 -------- WEB-INF/resources/ru.lang.php | 5 ----- WEB-INF/resources/sk.lang.php | 8 -------- WEB-INF/resources/sl.lang.php | 8 -------- WEB-INF/resources/sr.lang.php | 8 -------- WEB-INF/resources/sv.lang.php | 8 -------- WEB-INF/resources/tr.lang.php | 8 -------- WEB-INF/resources/zh-cn.lang.php | 8 -------- WEB-INF/resources/zh-tw.lang.php | 8 -------- initialize.php | 2 +- 31 files changed, 1 insertion(+), 233 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index f9d9952db..a2e130835 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -265,14 +265,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 453a51000..be62bf261 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -275,14 +275,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index a33224168..48a37886c 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -258,14 +258,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 47eb84a16..916861d1b 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -253,15 +253,6 @@ // Another use is with offers with Remote Work plugin, where details hold a long, precise, and complete description of the offer. // 'label.details' => 'Details', 'label.budget' => 'Budget', -// TODO: translate the following. -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index c1c00af9d..2a78286a6 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -239,14 +239,6 @@ 'label.inactive_users' => 'Inactive Users', 'label.details' => 'Details', 'label.budget' => 'Budget', -'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 8a8902f7d..83b5a6c0b 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -268,14 +268,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 3299e8ada..727da041d 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -266,14 +266,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 019c4ca31..4ec8ef170 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -269,14 +269,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 0940dc597..d01becc4d 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -262,14 +262,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 88a96690e..f690a4dc8 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -256,14 +256,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 489185a8c..3d0ac2a74 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -251,14 +251,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 918b5f7dc..bf17c6155 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -277,14 +277,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 407c22cd4..f67aadf87 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -270,14 +270,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 165afe880..ca7eec157 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -255,14 +255,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index dbac8f190..9519dd4c3 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -275,14 +275,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 896f1939f..0d190764b 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -275,14 +275,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 91ff4c8bc..fe5f4653e 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -230,11 +230,6 @@ 'label.inactive_users' => 'Inactieve medewerkers', 'label.details' => 'Details', 'label.budget' => 'Budget', -'label.work' => 'Werk', -'label.offer' => 'Aanbod', -'label.contractor' => 'Aanbieder', -'label.how_to_pay' => 'Betaalwijze', -'label.moderator_comment' => 'Commentaar', // Entity names. 'entity.time' => 'tijd', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 5cb39137d..73a640b99 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -272,14 +272,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index d77f11c3d..ea5013148 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -263,14 +263,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 15e3ef91f..a46208163 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -231,11 +231,6 @@ 'label.inactive_users' => 'Usuários inativos', 'label.details' => 'Detalhes', 'label.budget' => 'Orçamento', -'label.work' => 'Trabalho', -'label.offer' => 'Oferta', -'label.contractor' => 'Contratante', -'label.how_to_pay' => 'Como pagar', -'label.moderator_comment' => 'Comentário do moderador', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 6a1598cc7..fff0ad651 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -260,14 +260,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index f93f12085..736c934e4 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -272,14 +272,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 71bc709bf..3450227db 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -230,11 +230,6 @@ 'label.inactive_users' => 'Неактивные пользователи', 'label.details' => 'Детали', 'label.budget' => 'Бюджет', -'label.work' => 'Работа', -'label.offer' => 'Предложение', -'label.contractor' => 'Подрядчик', -'label.how_to_pay' => 'Как оплатить', -'label.moderator_comment' => 'Комментарий модератора', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index da24d8caf..8c386d1a8 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -266,14 +266,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 40abaabea..44be6053d 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -255,14 +255,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 8e9fe4e8f..45dbb1004 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -261,14 +261,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index bd025f84b..cb30b5e41 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -257,14 +257,6 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 5ac60a72d..56c309432 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -279,14 +279,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 6c6451214..6f492d491 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -265,14 +265,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index d16bf4cb7..f9496eb21 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -270,14 +270,6 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', -// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). - // Technically, it is either an org name or a combination of org and group names - // because both work items and offers are owned by Time Tracker groups of users. -// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc. -// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/initialize.php b/initialize.php index 16f3a5b1e..db645a9d5 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5612"); +define("APP_VERSION", "1.19.34.5613"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 91294bc2d33e9415d104670928b2ecd83ce68c36 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 25 Jan 2022 15:26:22 +0000 Subject: [PATCH 1634/1848] A bit more cleanup in translation files. --- WEB-INF/resources/ca.lang.php | 2 -- WEB-INF/resources/cs.lang.php | 2 -- WEB-INF/resources/da.lang.php | 3 --- WEB-INF/resources/de.lang.php | 6 ------ WEB-INF/resources/en.lang.php | 2 -- WEB-INF/resources/es.lang.php | 2 -- WEB-INF/resources/et.lang.php | 3 --- WEB-INF/resources/fa.lang.php | 3 --- WEB-INF/resources/fi.lang.php | 3 --- WEB-INF/resources/fr.lang.php | 3 --- WEB-INF/resources/gr.lang.php | 3 --- WEB-INF/resources/he.lang.php | 3 --- WEB-INF/resources/hu.lang.php | 2 -- WEB-INF/resources/it.lang.php | 3 --- WEB-INF/resources/ja.lang.php | 2 -- WEB-INF/resources/ko.lang.php | 2 -- WEB-INF/resources/nl.lang.php | 2 -- WEB-INF/resources/no.lang.php | 2 -- WEB-INF/resources/pl.lang.php | 3 --- WEB-INF/resources/pt-br.lang.php | 2 -- WEB-INF/resources/pt.lang.php | 2 -- WEB-INF/resources/ro.lang.php | 2 -- WEB-INF/resources/ru.lang.php | 2 -- WEB-INF/resources/sk.lang.php | 3 --- WEB-INF/resources/sl.lang.php | 2 -- WEB-INF/resources/sr.lang.php | 3 --- WEB-INF/resources/sv.lang.php | 3 --- WEB-INF/resources/tr.lang.php | 2 -- WEB-INF/resources/zh-cn.lang.php | 2 -- WEB-INF/resources/zh-tw.lang.php | 2 -- initialize.php | 2 +- 31 files changed, 1 insertion(+), 77 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index a2e130835..fefaad825 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -263,8 +263,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index be62bf261..ff237c005 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -273,8 +273,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 48a37886c..9a9c532d5 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -255,9 +255,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Aktive Brugere', 'label.inactive_users' => 'Inaktive Brugere', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 916861d1b..3fea57b73 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -247,12 +247,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Aktive Nutzer', 'label.inactive_users' => 'Inaktive Nutzer', -// TODO: translate the following or confirm that "Details" is also correct for German (exactly as the English string). -// label.details is used to identify a field for LONG DESCRIPTION of a work item used in Remote Work plugin. -// For example, a work item could be "Design a logo", and the Details hold EXACT anfd PRECISE specs of what a customer needs. -// Another use is with offers with Remote Work plugin, where details hold a long, precise, and complete description of the offer. -// 'label.details' => 'Details', -'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 2a78286a6..d82bb75b1 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -237,8 +237,6 @@ 'label.file' => 'File', 'label.active_users' => 'Active Users', 'label.inactive_users' => 'Inactive Users', -'label.details' => 'Details', -'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 83b5a6c0b..0f2b8a319 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -266,8 +266,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 727da041d..7137357e7 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -263,9 +263,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Aktiivsed kasutajad', 'label.inactive_users' => 'Mitteaktiivsed kasutajad', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 4ec8ef170..085f80ca4 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -266,9 +266,6 @@ // 'label.file' => 'File', 'label.active_users' => 'کاربران فعال', 'label.inactive_users' => 'کاربران غیرفعال', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index d01becc4d..f3237ff0c 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -259,9 +259,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Aktiiviset käyttäjät', 'label.inactive_users' => 'Ei-aktiiviset käyttäjät', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index f690a4dc8..5c971ea9b 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -253,9 +253,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Utilisateurs actifs', 'label.inactive_users' => 'Utilisateurs inactifs', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 3d0ac2a74..dbbd85dbb 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -248,9 +248,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Ενεργοί χρήστες', 'label.inactive_users' => 'Ανενεργοί χρήστες', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index bf17c6155..f3cee584a 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -274,9 +274,6 @@ // 'label.file' => 'File', 'label.active_users' => 'משתמשים פעילים', 'label.inactive_users' => 'משתמשים לא פעילים', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index f67aadf87..08e52d402 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -268,8 +268,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index ca7eec157..d9cca113c 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -252,9 +252,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Utenti attivi', 'label.inactive_users' => 'Utenti inattivi', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 9519dd4c3..7437648bc 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -273,8 +273,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 0d190764b..3454a362c 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -273,8 +273,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index fe5f4653e..2c1b7b71b 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -228,8 +228,6 @@ 'label.file' => 'Bestand', 'label.active_users' => 'Actieve medewerkers', 'label.inactive_users' => 'Inactieve medewerkers', -'label.details' => 'Details', -'label.budget' => 'Budget', // Entity names. 'entity.time' => 'tijd', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 73a640b99..20f50546d 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -270,8 +270,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index ea5013148..84cd8241e 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -260,9 +260,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Aktywni użytkownicy', 'label.inactive_users' => 'Nieaktywni użytkownicy', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index a46208163..fbdff5ace 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -229,8 +229,6 @@ 'label.file' => 'Arquivo', 'label.active_users' => 'Usuários ativos', 'label.inactive_users' => 'Usuários inativos', -'label.details' => 'Detalhes', -'label.budget' => 'Orçamento', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index fff0ad651..728c4ba62 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -258,8 +258,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 736c934e4..d89e335b3 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -270,8 +270,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3450227db..d16bd99df 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -228,8 +228,6 @@ 'label.file' => 'Файл', 'label.active_users' => 'Активные пользователи', 'label.inactive_users' => 'Неактивные пользователи', -'label.details' => 'Детали', -'label.budget' => 'Бюджет', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 8c386d1a8..37303bdf7 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -263,9 +263,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Aktívny používatelia', 'label.inactive_users' => 'Neaktívny používatelia', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 44be6053d..91e6dea08 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -253,8 +253,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 45dbb1004..5eddee167 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -258,9 +258,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Aktivni korisnik', 'label.inactive_users' => 'Neaktivni korisnik', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index cb30b5e41..fddf70abb 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -254,9 +254,6 @@ // 'label.file' => 'File', 'label.active_users' => 'Aktiva användare', 'label.inactive_users' => 'Inaktiva användare', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 56c309432..e5c4e5c23 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -277,8 +277,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 6f492d491..157a95727 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -263,8 +263,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index f9496eb21..a2c2705ec 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -268,8 +268,6 @@ // 'label.file' => 'File', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/initialize.php b/initialize.php index db645a9d5..ddbfe2444 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5613"); +define("APP_VERSION", "1.19.34.5614"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From efef96ec94f019afbad9af8cf8b6b0f9e4cefbcf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 25 Jan 2022 15:38:24 +0000 Subject: [PATCH 1635/1848] More cleanup in translation files. --- WEB-INF/resources/ca.lang.php | 16 ---------------- WEB-INF/resources/cs.lang.php | 16 ---------------- WEB-INF/resources/da.lang.php | 16 ---------------- WEB-INF/resources/de.lang.php | 16 ---------------- WEB-INF/resources/en.lang.php | 16 ---------------- WEB-INF/resources/es.lang.php | 16 ---------------- WEB-INF/resources/et.lang.php | 16 ---------------- WEB-INF/resources/fa.lang.php | 16 ---------------- WEB-INF/resources/fi.lang.php | 16 ---------------- WEB-INF/resources/fr.lang.php | 16 ---------------- WEB-INF/resources/gr.lang.php | 16 ---------------- WEB-INF/resources/he.lang.php | 16 ---------------- WEB-INF/resources/hu.lang.php | 16 ---------------- WEB-INF/resources/it.lang.php | 16 ---------------- WEB-INF/resources/ja.lang.php | 16 ---------------- WEB-INF/resources/ko.lang.php | 16 ---------------- WEB-INF/resources/nl.lang.php | 15 --------------- WEB-INF/resources/no.lang.php | 16 ---------------- WEB-INF/resources/pl.lang.php | 16 ---------------- WEB-INF/resources/pt-br.lang.php | 15 --------------- WEB-INF/resources/pt.lang.php | 16 ---------------- WEB-INF/resources/ro.lang.php | 16 ---------------- WEB-INF/resources/ru.lang.php | 15 --------------- WEB-INF/resources/sk.lang.php | 16 ---------------- WEB-INF/resources/sl.lang.php | 16 ---------------- WEB-INF/resources/sr.lang.php | 16 ---------------- WEB-INF/resources/sv.lang.php | 16 ---------------- WEB-INF/resources/tr.lang.php | 16 ---------------- WEB-INF/resources/zh-cn.lang.php | 16 ---------------- WEB-INF/resources/zh-tw.lang.php | 16 ---------------- initialize.php | 2 +- 31 files changed, 1 insertion(+), 478 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index fefaad825..0f05c8d73 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -675,20 +675,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index ff237c005..d42f51935 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -688,20 +688,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 9a9c532d5..af755d4ae 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -651,20 +651,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 3fea57b73..46cdcb473 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -624,20 +624,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index d82bb75b1..897faa592 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -607,20 +607,4 @@ 'form.display_options.not_complete_days' => 'Not complete days', 'form.display_options.inactive_projects' => 'Inactive projects', 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -'work.error.work_not_available' => 'Work item is not available.', -'work.error.offer_not_available' => 'Offer is not available.', -'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -'work.label.own_work' => 'Own work', -'work.label.own_offers' => 'Own offers', -'work.label.offers' => 'Offers', -'work.label.message' => 'Message', -'work.button.send_message' => 'Send message', -'work.button.make_offer' => 'Make offer', -'work.button.accept' => 'Accept', -'work.button.decline' => 'Decline', -'work.title.send_message' => 'Sending Message', -'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 0f2b8a319..f9a300370 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -690,20 +690,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 7137357e7..ad93af7d9 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -659,20 +659,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 085f80ca4..7bf3a9637 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -675,20 +675,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index f3237ff0c..71f401fb0 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -659,20 +659,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 5c971ea9b..e56425f58 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -647,20 +647,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index dbbd85dbb..fe89a425d 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -639,20 +639,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index f3cee584a..9c4718bf2 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -680,20 +680,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 08e52d402..d20ff3524 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -679,20 +679,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index d9cca113c..253c08545 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -653,20 +653,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 7437648bc..06d452108 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -683,20 +683,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 3454a362c..07603b634 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -681,20 +681,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 2c1b7b71b..ac41ea720 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -589,19 +589,4 @@ 'form.display_options.not_complete_days' => 'Niet complete dagen', 'form.display_options.inactive_projects' => 'Niet actieve projecten', 'form.display_options.custom_css' => 'Aangepaste CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -'work.error.work_not_available' => 'Werk onderdeel is niet beschikbaar.', -'work.error.offer_not_available' => 'Aanbod is niet beschikbaar.', -'work.type.one_time' => 'eenmalig', -'work.type.ongoing' => 'doorlopend', -'work.label.own_work' => 'Eigen werk', -'work.label.own_offers' => 'Eigen aanbod', -'work.label.offers' => 'Aanbiedingen', -'work.button.send_message' => 'Verstuur bericht', -'work.button.make_offer' => 'maak aanbieding', -'work.button.accept' => 'Accepteer', -'work.button.decline' => 'Weiger', -'work.title.send_message' => 'Bericht wordt verstuurd', -'work.msg.message_sent' => 'Bericht is verstuurd.', ); diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 20f50546d..05b4f16c3 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -682,20 +682,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 84cd8241e..114465b50 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -660,20 +660,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index fbdff5ace..9bdede0da 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -588,20 +588,5 @@ // TODO: translate the following. // 'form.display_options.inactive_projects' => 'Inactive projects', 'form.display_options.custom_css' => 'CSS customizado', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php. -'work.error.work_not_available' => 'Item de trabalho não está disponível.', -'work.error.offer_not_available' => 'Oferta não disponível', -'work.type.one_time' => 'Uma interação', -'work.type.ongoing' => 'Em progresso', -'work.label.own_work' => 'Trabalho próprio', -'work.label.own_offers' => 'Ofertas próprias', -'work.label.offers' => 'Ofertas', -'work.button.send_message' => 'Enviar mensagem', -'work.button.make_offer' => 'Fazer oferta', -'work.button.accept' => 'Aceitar', -'work.button.decline' => 'Recusar', -'work.title.send_message' => 'Enviando mensagem', -'work.msg.message_sent' => 'Mensagem enviada.', ); diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 728c4ba62..25a65270a 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -662,20 +662,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index d89e335b3..74f898568 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -683,20 +683,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index d16bd99df..a59d7e413 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -590,19 +590,4 @@ 'form.display_options.not_complete_days' => 'Незавершенные дни', 'form.display_options.inactive_projects' => 'Неактивные проекты', 'form.display_options.custom_css' => 'Пользовательская CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -'work.error.work_not_available' => 'Работа отсутствует.', -'work.error.offer_not_available' => 'Предложение отсутствует.', -'work.type.one_time' => 'одноразовая', -'work.type.ongoing' => 'постоянная', -'work.label.own_work' => 'Своя работа', -'work.label.own_offers' => 'Свои предложения', -'work.label.offers' => 'Предложения', -'work.button.send_message' => 'Отправить сообщение', -'work.button.make_offer' => 'Сделать предложение', -'work.button.accept' => 'Принять', -'work.button.decline' => 'Отклонить', -'work.title.send_message' => 'Отсылка сообщения', -'work.msg.message_sent' => 'Сообщение отослано.', ); diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 37303bdf7..d09cd1063 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -664,20 +664,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 91e6dea08..98621f355 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -656,20 +656,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 5eddee167..1dc547f16 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -662,20 +662,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index fddf70abb..2fa40ce33 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -659,20 +659,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index e5c4e5c23..10b582dc2 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -696,20 +696,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 157a95727..6722da048 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -670,20 +670,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index a2c2705ec..24bc7b817 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -673,20 +673,4 @@ // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.custom_css' => 'Custom CSS', - -// Work plugin strings. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'work.error.work_not_available' => 'Work item is not available.', -// 'work.error.offer_not_available' => 'Offer is not available.', -// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). -// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.own_work' => 'Own work', -// 'work.label.own_offers' => 'Own offers', -// 'work.label.offers' => 'Offers', -// 'work.button.send_message' => 'Send message', -// 'work.button.make_offer' => 'Make offer', -// 'work.button.accept' => 'Accept', -// 'work.button.decline' => 'Decline', -// 'work.title.send_message' => 'Sending Message', -// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/initialize.php b/initialize.php index ddbfe2444..0ec782c6d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5614"); +define("APP_VERSION", "1.19.34.5615"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 2a6379743ea1ff38a24062c39610749e9581c9dc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 25 Jan 2022 16:09:52 +0000 Subject: [PATCH 1636/1848] Removed no longer used string from translation files. --- WEB-INF/resources/ca.lang.php | 1 - WEB-INF/resources/cs.lang.php | 1 - WEB-INF/resources/da.lang.php | 1 - WEB-INF/resources/de.lang.php | 1 - WEB-INF/resources/en.lang.php | 5 ----- WEB-INF/resources/es.lang.php | 1 - WEB-INF/resources/et.lang.php | 1 - WEB-INF/resources/fa.lang.php | 1 - WEB-INF/resources/fi.lang.php | 1 - WEB-INF/resources/fr.lang.php | 1 - WEB-INF/resources/gr.lang.php | 1 - WEB-INF/resources/he.lang.php | 1 - WEB-INF/resources/hu.lang.php | 1 - WEB-INF/resources/it.lang.php | 1 - WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 1 - WEB-INF/resources/no.lang.php | 1 - WEB-INF/resources/pl.lang.php | 1 - WEB-INF/resources/pt-br.lang.php | 1 - WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 1 - WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 1 - WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 1 - WEB-INF/resources/sv.lang.php | 1 - WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 1 - WEB-INF/resources/zh-tw.lang.php | 1 - initialize.php | 2 +- 31 files changed, 1 insertion(+), 35 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 0f05c8d73..0202a4be0 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -97,7 +97,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d42f51935..6ace11812 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -99,7 +99,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index af755d4ae..b76c65c24 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -94,7 +94,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 46cdcb473..6a11c4054 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -90,7 +90,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. 'warn.sure' => 'Sind Sie sicher?', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 897faa592..44a1c2a69 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -86,11 +86,6 @@ // "something went wrong" when trying to do some operation with attachments. // For example, File Storage server could be offline, or Time Tracker config option is wrong, etc. 'error.file_storage' => 'File storage server error.', -// Meaning of error.remote_work: an (unspecified) error occurred when trying to communicate with -// "Remote Work" server, the one that supports the "Work" plugin, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm -// It is a generic message telling us that "something went wrong" when trying to do some operation with Work plugin. -// For example, Remote Work server could be offline, among other things. -'error.remote_work' => 'Remote work server error.', // Warning messages. 'warn.sure' => 'Are you sure?', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index f9a300370..09fe1d9e6 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -95,7 +95,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index ad93af7d9..9cbcf13b5 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -107,7 +107,6 @@ 'error.expired' => 'Kehtivusaeg on lõppenud.', // TODO: translate the following. // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. 'warn.sure' => 'Oled kindel?', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 7bf3a9637..16fb3e5ad 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -102,7 +102,6 @@ // 'error.expired' => 'Expiration date reached.', // TODO: translate the following. // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 71f401fb0..9c76d646b 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -96,7 +96,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index e56425f58..5a3017365 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -94,7 +94,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index fe89a425d..e2bd54181 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -89,7 +89,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 9c4718bf2..5fd42b36c 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -110,7 +110,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index d20ff3524..e03a684cb 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -98,7 +98,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 253c08545..2e3fd91f5 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -93,7 +93,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 06d452108..c2b509f3e 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -101,7 +101,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 07603b634..dc2172408 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -100,7 +100,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index ac41ea720..247a3652c 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -81,7 +81,6 @@ 'error.user_count' => 'Limiet op aantal gebruikers.', 'error.expired' => 'Verloop datum is bereikt.', 'error.file_storage' => 'Bestand server probleem.', -'error.remote_work' => 'Werk op afstand server probleem.', // Warning messages. 'warn.sure' => 'Ben je er zeker van?', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 05b4f16c3..094d6b0a2 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -101,7 +101,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 114465b50..0cb9f69f5 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -98,7 +98,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 9bdede0da..ae860cf1c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -81,7 +81,6 @@ 'error.user_count' => 'Limite na contagem de usuários.', 'error.expired' => 'Data de expiração atingida.', 'error.file_storage' => 'Erro relacionado ao servidor de armazenamento de arquivos.', -'error.remote_work' => 'Erro relacionado ao servidor responsável pelo plugin work.', // Warning messages. 'warn.sure' => 'Tem certeza?', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 25a65270a..538dd52f0 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -94,7 +94,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 74f898568..cde5a27d7 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -101,7 +101,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index a59d7e413..c62142727 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -81,7 +81,6 @@ 'error.user_count' => 'Ограничение на количество пользователей.', 'error.expired' => 'Достигнута дата экспирации.', 'error.file_storage' => 'Ошибка сервера для хранения файлов.', -'error.remote_work' => 'Ошибка сервера удаленной работы.', // Warning messages. 'warn.sure' => 'Вы уверены?', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d09cd1063..d74bb3183 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -99,7 +99,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 98621f355..f615e431f 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -91,7 +91,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 1dc547f16..7bb9edbe8 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -95,7 +95,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 2fa40ce33..dce2488b3 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -93,7 +93,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 10b582dc2..c154a3a41 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -104,7 +104,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 6722da048..a2e6bf285 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -94,7 +94,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 24bc7b817..69121475b 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -98,7 +98,6 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage server error.', // See comment in English file. -// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/initialize.php b/initialize.php index 0ec782c6d..7825bbe59 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5615"); +define("APP_VERSION", "1.19.34.5616"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 46fa236d1a379935b89bd218af2190a1691d3e10 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 25 Jan 2022 16:45:01 +0000 Subject: [PATCH 1637/1848] Removed no longer used titles from translation files. --- WEB-INF/resources/ca.lang.php | 16 ---------------- WEB-INF/resources/cs.lang.php | 16 ---------------- WEB-INF/resources/da.lang.php | 16 ---------------- WEB-INF/resources/de.lang.php | 16 ---------------- WEB-INF/resources/en.lang.php | 16 ---------------- WEB-INF/resources/es.lang.php | 16 ---------------- WEB-INF/resources/et.lang.php | 16 ---------------- WEB-INF/resources/fa.lang.php | 16 ---------------- WEB-INF/resources/fi.lang.php | 16 ---------------- WEB-INF/resources/fr.lang.php | 16 ---------------- WEB-INF/resources/gr.lang.php | 16 ---------------- WEB-INF/resources/he.lang.php | 16 ---------------- WEB-INF/resources/hu.lang.php | 16 ---------------- WEB-INF/resources/it.lang.php | 16 ---------------- WEB-INF/resources/ja.lang.php | 16 ---------------- WEB-INF/resources/ko.lang.php | 16 ---------------- WEB-INF/resources/nl.lang.php | 16 ---------------- WEB-INF/resources/no.lang.php | 16 ---------------- WEB-INF/resources/pl.lang.php | 16 ---------------- WEB-INF/resources/pt-br.lang.php | 16 ---------------- WEB-INF/resources/pt.lang.php | 16 ---------------- WEB-INF/resources/ro.lang.php | 16 ---------------- WEB-INF/resources/ru.lang.php | 16 ---------------- WEB-INF/resources/sk.lang.php | 16 ---------------- WEB-INF/resources/sl.lang.php | 16 ---------------- WEB-INF/resources/sr.lang.php | 16 ---------------- WEB-INF/resources/sv.lang.php | 16 ---------------- WEB-INF/resources/tr.lang.php | 16 ---------------- WEB-INF/resources/zh-cn.lang.php | 16 ---------------- WEB-INF/resources/zh-tw.lang.php | 16 ---------------- initialize.php | 2 +- 31 files changed, 1 insertion(+), 481 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 0202a4be0..6a9290041 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -378,22 +378,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 6ace11812..15da342d5 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -388,22 +388,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index b76c65c24..d357a3b3e 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -362,22 +362,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 6a11c4054..259f6c55c 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -345,22 +345,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 44a1c2a69..8867e8c29 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -331,22 +331,6 @@ 'title.edit_file' => 'Editing File', 'title.delete_file' => 'Deleting File', 'title.download_file' => 'Downloading File', -'title.work' => 'Work', -'title.add_work' => 'Adding Work', -'title.edit_work' => 'Editing Work', -'title.delete_work' => 'Deleting Work', -'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -'title.available_work' => 'Available Work', // Available work items from other organizations. -'title.inactive_work' => 'Inactive Work', // Inactive work items for group. -'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -'title.offer' => 'Offer', -'title.add_offer' => 'Adding Offer', -'title.edit_offer' => 'Editing Offer', -'title.delete_offer' => 'Deleting Offer', -'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -'title.available_offers' => 'Available Offers', // Available offers from other organizations. -'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 09fe1d9e6..25c94b896 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -377,22 +377,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 9cbcf13b5..0f0d1448c 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -371,22 +371,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 16fb3e5ad..831e9228b 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -371,22 +371,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 9c76d646b..bbb33f37b 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -362,22 +362,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 5a3017365..443ace913 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -356,22 +356,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index e2bd54181..229d94eb2 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -354,22 +354,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 5fd42b36c..5431e0513 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -378,22 +378,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index e03a684cb..d1a093baa 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -377,22 +377,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 2e3fd91f5..1afc09eb6 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -364,22 +364,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index c2b509f3e..93ab30e43 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -384,22 +384,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index dc2172408..6ca74cf65 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -385,22 +385,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 247a3652c..ae1df70d6 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -323,22 +323,6 @@ 'title.edit_file' => 'Bestand bewerken', 'title.delete_file' => 'Bestand verwijderen', 'title.download_file' => ' Bestand downloaden', -'title.work' => 'Werk', -'title.add_work' => 'Werk toevoegen', -'title.edit_work' => 'Werk bewerken', -'title.delete_work' => 'Werk verwijderen', -'title.active_work' => 'Actief werk', -'title.available_work' => 'Beschikbaar werk', -'title.inactive_work' => 'Inactief werk', -'title.pending_work' => 'Werk in afwachting van goedkeuring', -'title.offer' => 'Aanbod', -'title.add_offer' => 'Aanbieding toevoegen', -'title.edit_offer' => 'Aanbieding bewerken', -'title.delete_offer' => 'Aanbieding verwijderen', -'title.active_offers' => 'Actieve aanbiedingen', -'title.available_offers' => 'Beschikbare aanbiedingen', -'title.inactive_offers' => 'Inactieve aanbiedingen', -'title.pending_offers' => 'Aangeboden werk in afwachting van goedkeuring', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 094d6b0a2..5b6780779 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -381,22 +381,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 0cb9f69f5..970acaf1e 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -365,22 +365,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index ae860cf1c..b46a54a89 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -321,22 +321,6 @@ 'title.edit_file' => 'Editando arquivo', 'title.delete_file' => 'Apagando arquivo', 'title.download_file' => 'Baixando arquivo', -'title.work' => 'Trabalho', -'title.add_work' => 'Adicionando trabalho', -'title.edit_work' => 'Editando trabalho', -'title.delete_work' => 'Apagando trabalho', -'title.active_work' => 'Trabalho ativo', -'title.available_work' => 'Trabalho disponível', -'title.inactive_work' => 'Trabalho inativo', -'title.pending_work' => 'Trabalho pendente', -'title.offer' => 'Oferta', -'title.add_offer' => 'Adicionando oferta', -'title.edit_offer' => 'Editando oferta', -'title.delete_offer' => 'Apagando oferta', -'title.active_offers' => 'Ofertas ativas', -'title.available_offers' => 'Ofertas disponíveis', -'title.inactive_offers' => 'Ofertas inativas', -'title.pending_offers' => 'Ofertas pendentes', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 538dd52f0..1fb18ea17 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -365,22 +365,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index cde5a27d7..f5bdba763 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -383,22 +383,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.add_offer' => 'Adding Offer', -// 'title.offer' => 'Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index c62142727..8171ba517 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -324,22 +324,6 @@ 'title.edit_file' => 'Редактирование файла', 'title.delete_file' => 'Удаление файла', 'title.download_file' => 'Скачивание файла', -'title.work' => 'Работа', -'title.add_work' => 'Добавление работы', -'title.edit_work' => 'Редактирование работы', -'title.delete_work' => 'Удаление работы', -'title.active_work' => 'Активная работа', -'title.available_work' => 'Имеющаяся работа', -'title.inactive_work' => 'Неактивная работа', -'title.pending_work' => 'Работа в ожидании', -'title.offer' => 'Предложение', -'title.add_offer' => 'Добавление предложения', -'title.edit_offer' => 'Редактирование предложения', -'title.delete_offer' => 'Удаление предложения', -'title.active_offers' => 'Активные предложения', -'title.available_offers' => 'Имеющиеся предложения', -'title.inactive_offers' => 'Неактивные предложения', -'title.pending_offers' => 'Предложения в ожидании', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d74bb3183..ab601e945 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -367,22 +367,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index f615e431f..b8f7e9407 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -358,22 +358,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 7bb9edbe8..bc98a1d33 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -363,22 +363,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index dce2488b3..d977a9a2e 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -363,22 +363,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index c154a3a41..dc8bd0736 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -392,22 +392,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index a2e6bf285..50cff7bcc 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -374,22 +374,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 69121475b..8bc481b9e 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -378,22 +378,6 @@ // 'title.edit_file' => 'Editing File', // 'title.delete_file' => 'Deleting File', // 'title.download_file' => 'Downloading File', -// 'title.work' => 'Work', -// 'title.add_work' => 'Adding Work', -// 'title.edit_work' => 'Editing Work', -// 'title.delete_work' => 'Deleting Work', -// 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. -// 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. -// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. -// 'title.offer' => 'Offer', -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. -// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/initialize.php b/initialize.php index 7825bbe59..07344a419 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5616"); +define("APP_VERSION", "1.19.34.5617"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From cb7c7934259f96399c6fc14c25311c9430fd75a7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 25 Jan 2022 17:59:14 +0000 Subject: [PATCH 1638/1848] Removed 3 unused strings from translation files. --- WEB-INF/resources/ca.lang.php | 3 --- WEB-INF/resources/cs.lang.php | 4 ---- WEB-INF/resources/da.lang.php | 3 --- WEB-INF/resources/de.lang.php | 3 --- WEB-INF/resources/en.lang.php | 3 --- WEB-INF/resources/es.lang.php | 3 --- WEB-INF/resources/et.lang.php | 3 --- WEB-INF/resources/fa.lang.php | 3 --- WEB-INF/resources/fi.lang.php | 3 --- WEB-INF/resources/fr.lang.php | 3 --- WEB-INF/resources/gr.lang.php | 3 --- WEB-INF/resources/he.lang.php | 3 --- WEB-INF/resources/hu.lang.php | 3 --- WEB-INF/resources/it.lang.php | 3 --- WEB-INF/resources/ja.lang.php | 5 ----- WEB-INF/resources/ko.lang.php | 5 ----- WEB-INF/resources/nl.lang.php | 3 --- WEB-INF/resources/no.lang.php | 3 --- WEB-INF/resources/pl.lang.php | 3 --- WEB-INF/resources/pt-br.lang.php | 3 --- WEB-INF/resources/pt.lang.php | 4 ---- WEB-INF/resources/ro.lang.php | 3 --- WEB-INF/resources/ru.lang.php | 3 --- WEB-INF/resources/sk.lang.php | 3 --- WEB-INF/resources/sl.lang.php | 3 --- WEB-INF/resources/sr.lang.php | 3 --- WEB-INF/resources/sv.lang.php | 3 --- WEB-INF/resources/tr.lang.php | 3 --- WEB-INF/resources/zh-cn.lang.php | 3 --- WEB-INF/resources/zh-tw.lang.php | 3 --- initialize.php | 2 +- 31 files changed, 1 insertion(+), 97 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 6a9290041..196a4441d 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -214,9 +214,6 @@ // 'label.ldap_hint' => 'Type your Windows login and password in the fields below.', 'label.required_fields' => '* camps requerits', 'label.on_behalf' => 'a nom de', -'label.role_manager' => '(manejador)', -'label.role_comanager' => '(auxiliar del manejador)', -'label.role_admin' => '(administrador)', // TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 15da342d5..a30d83c89 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -224,10 +224,6 @@ 'label.required_fields' => '* nutno vyplnit', // TODO: translate the following. // 'label.on_behalf' => 'on behalf of', -'label.role_manager' => '(manažer)', -'label.role_comanager' => '(spolumanažer)', -'label.role_admin' => '(administrator)', -// TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', // 'label.yes' => 'yes', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index d357a3b3e..369c965f4 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -207,9 +207,6 @@ 'label.ldap_hint' => 'Skriv dit Windows brugernavn eller adgangskode i felterne her under.', 'label.required_fields' => '* - obligatorisk felt', 'label.on_behalf' => 'på vegne af', -'label.role_manager' => '(Manager)', -'label.role_comanager' => '(Co-Manager)', -'label.role_admin' => '(Administrator)', 'label.page' => 'Side', 'label.condition' => 'Betingelse', // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 259f6c55c..87f40c849 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -201,9 +201,6 @@ 'label.ldap_hint' => 'Geben Sie unten Ihren Windows Benutzernamen und Ihr Passwort ein.', 'label.required_fields' => '* - Pflichtfelder', 'label.on_behalf' => 'für', -'label.role_manager' => '(Manager)', -'label.role_comanager' => '(Co-Manager)', -'label.role_admin' => '(Administrator)', 'label.page' => 'Seite', 'label.condition' => 'Bedingung', 'label.yes' => 'Ja', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 8867e8c29..0d82650c8 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -189,9 +189,6 @@ 'label.ldap_hint' => 'Type your Windows login and password in the fields below.', 'label.required_fields' => '* - required fields', 'label.on_behalf' => 'on behalf of', -'label.role_manager' => '(manager)', -'label.role_comanager' => '(co-manager)', -'label.role_admin' => '(administrator)', 'label.page' => 'Page', 'label.condition' => 'Condition', 'label.yes' => 'yes', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 25c94b896..68dcc8c31 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -218,9 +218,6 @@ // 'label.ldap_hint' => 'Type your Windows login and password in the fields below.', 'label.required_fields' => '* - campos requeridos', 'label.on_behalf' => 'a nombre de', -'label.role_manager' => '(manejador)', -'label.role_comanager' => '(auxiliar del manejador)', -'label.role_admin' => '(administrador)', // TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 0f0d1448c..431f29563 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -216,9 +216,6 @@ 'label.required_fields' => '* nõutud väljad', // TODO: Translate label.on_behalf, perhaps trying as "instead of". // 'label.on_behalf' => 'on behalf of', -'label.role_manager' => '(haldur)', -'label.role_comanager' => '(kaashaldur)', -'label.role_admin' => '(administraator)', 'label.page' => 'Lehekülg', 'label.condition' => 'Tingimus', 'label.yes' => 'jah', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 831e9228b..9ae24d016 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -218,9 +218,6 @@ 'label.ldap_hint' => 'نام کاربری ویندوزو رمزعبورخود را در فیلدهای زیر وارد کنید', 'label.required_fields' => '* - فیلد های اجباری', 'label.on_behalf' => 'از دیدگاه', -'label.role_manager' => '(مدیر)', -'label.role_comanager' => '(دستیار مدیر)', -'label.role_admin' => '(مدیر ارشد)', // Translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index bbb33f37b..a9396eba9 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -210,9 +210,6 @@ 'label.ldap_hint' => 'Syötä Windows-käyttäjätunnuksesi ja salasanasi ao. kenttiin.', 'label.required_fields' => '* - pakolliset kentät', 'label.on_behalf' => 'puolesta', -'label.role_manager' => '(esimies)', -'label.role_comanager' => '(apu-esimies)', -'label.role_admin' => '(ylläpitäjä)', 'label.page' => 'Sivu', // TODO: translate the following. // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 443ace913..91e04d793 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -206,9 +206,6 @@ 'label.ldap_hint' => 'Entrer votre Identifiant Windows et votre mot de passe dans les champs suivants.', 'label.required_fields' => '* - champs obligatoires', 'label.on_behalf' => 'de la part de', -'label.role_manager' => '(responsable)', -'label.role_comanager' => '(coresponsable)', -'label.role_admin' => '(administrateur)', 'label.page' => 'Page', 'label.condition' => 'Condition', // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 229d94eb2..1fd83890f 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -200,9 +200,6 @@ 'label.ldap_hint' => 'Εισάγετε το όνομα σύνδεσης των Windows και κωδικό πρόσβασης στα παρακάτω πεδία.', 'label.required_fields' => '* - υποχρεωτικά πεδία', 'label.on_behalf' => 'εκ μέρους του', -'label.role_manager' => '(Διευθυντής)', -'label.role_comanager' => '(Υποδιευθυντής)', -'label.role_admin' => '(Διαχειριστής)', 'label.page' => 'Σελίδα', 'label.condition' => 'Κατάσταση', 'label.yes' => 'ναι', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 5431e0513..ef7597cd3 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -226,9 +226,6 @@ 'label.ldap_hint' => 'הכנס את שם המשתמש ואת הסיסמה של ווינדוז בשדות.', 'label.required_fields' => '* - שדות חובה', 'label.on_behalf' => 'מטעם', -'label.role_manager' => '(מנהל)', -'label.role_comanager' => '(מנהל משנה)', -'label.role_admin' => '(מנהל המערכת)', // Translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index d1a093baa..1c446ac53 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -221,9 +221,6 @@ // 'label.ldap_hint' => 'Type your Windows login and password in the fields below.', 'label.required_fields' => '* kötelezően kitöltendő mezők', 'label.on_behalf' => 'helyett', -'label.role_manager' => '(vezető)', -'label.role_comanager' => '(helyettes)', -'label.role_admin' => '(adminisztrátor)', // TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 1afc09eb6..e3d19aa5f 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -204,9 +204,6 @@ 'label.ldap_hint' => 'Digita il tuo Login Windows e la tua password nei campi qui sotto.', 'label.required_fields' => '* campi obbligatori', 'label.on_behalf' => 'a favore di', -'label.role_manager' => '(manager)', -'label.role_comanager' => '(co-manager)', -'label.role_admin' => '(amministratore)', 'label.page' => 'Pagina', 'label.condition' => 'Condizione', 'label.yes' => 'si', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 93ab30e43..aa2389788 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -223,11 +223,6 @@ 'label.ldap_hint' => '下記のフィールドにあなたのWindowsのログインIDパスワードを入力してください。', 'label.required_fields' => '* 必須のフィールド', 'label.on_behalf' => 'を代表して', -// TODO: translate all 3 roles properly, see https://www.anuko.com/time_tracker/user_guide/user_accounts.htm -// This may require different terms for role_manager and role_comanager. -'label.role_manager' => '(管理者)', -'label.role_comanager' => '(共同管理者)', -// 'label.role_admin' => '(administrator)', // TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 6ca74cf65..cc52c1108 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -222,11 +222,6 @@ 'label.ldap_hint' => '아래의 필드들에서 Windows 로그인암호 를 입력하십시오.', 'label.required_fields' => '* 필수 필드', 'label.on_behalf' => '을 대표하여', -// TODO: translate all 3 roles properly, see https://www.anuko.com/time_tracker/user_guide/user_accounts.htm -// This may require different terms for role_manager and role_comanager. -'label.role_manager' => '(관리자)', -'label.role_comanager' => '(공동관리자)', -// 'label.role_admin' => '(administrator)', // TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index ae1df70d6..360ddd802 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -184,9 +184,6 @@ 'label.ldap_hint' => 'Type uw Windows login en wachtwoord in de onderstaande velden.', 'label.required_fields' => '* - verplichte velden', 'label.on_behalf' => 'namens', -'label.role_manager' => '(manager)', -'label.role_comanager' => '(co-manager)', -'label.role_admin' => '(beheerder)', 'label.page' => 'Pagina', 'label.condition' => 'Voorwaarde', 'label.yes' => 'ja', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 5b6780779..8202b4e9f 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -224,9 +224,6 @@ 'label.required_fields' => '* obligatoriske felt', 'label.on_behalf' => 'på vegne av', // TODO: translate the following. -// 'label.role_manager' => '(manager)', -// 'label.role_comanager' => '(co-manager)', -// 'label.role_admin' => '(administrator)', // 'label.page' => 'Page', // 'label.condition' => 'Condition', // 'label.yes' => 'yes', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 970acaf1e..ad4ec2c3d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -212,9 +212,6 @@ 'label.ldap_hint' => 'Wpisz swoją nazwę użytkownika Windows i hasło w polach poniżej.', 'label.required_fields' => '* - pola wymagane', 'label.on_behalf' => 'w imieniu', -'label.role_manager' => '(Manager)', -'label.role_comanager' => '(Co-manager)', -'label.role_admin' => '(Administrator)', // TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index b46a54a89..3b8ceccf3 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -185,9 +185,6 @@ 'label.ldap_hint' => 'Entre com o seu login do Windows e senha nos campos abaixo.', 'label.required_fields' => '* - campos obrigatórios', 'label.on_behalf' => 'em nome de', -'label.role_manager' => '(gerente)', -'label.role_comanager' => '(coordenador)', -'label.role_admin' => '(administrador)', 'label.page' => 'Página', 'label.condition' => 'Condição', 'label.yes' => 'sim', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 1fb18ea17..4b6db659e 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -212,10 +212,6 @@ 'label.required_fields' => '* campos obrigatórios', // TODO: translate the following. // 'label.on_behalf' => 'on behalf of', -'label.role_manager' => '(gerente)', -// TODO: translate the following. -// 'label.role_comanager' => '(co-manager)', -// 'label.role_admin' => '(administrator)', // 'label.page' => 'Page', // 'label.condition' => 'Condition', // 'label.yes' => 'yes', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index f5bdba763..fc8c9a8f8 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -222,9 +222,6 @@ // 'label.ldap_hint' => 'Type your Windows login and password in the fields below.', 'label.required_fields' => '* date obligatorii', 'label.on_behalf' => 'in numele', -'label.role_manager' => '(manager)', -'label.role_comanager' => '(co-manager)', -'label.role_admin' => '(administrator)', // TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 8171ba517..e052ba818 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -184,9 +184,6 @@ 'label.ldap_hint' => 'Введите свои Windows логин и пароль в поля ниже.', 'label.required_fields' => '* - обязательные для заполнения поля', 'label.on_behalf' => 'от имени', -'label.role_manager' => '(менеджер)', -'label.role_comanager' => '(ассистент менеджера)', -'label.role_admin' => '(администратор)', 'label.page' => 'Стр', 'label.condition' => 'Условие', 'label.yes' => 'да', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index ab601e945..6eb804d20 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -214,9 +214,6 @@ 'label.ldap_hint' => 'Zadajte prihlasovacie meno do Windowsu a heslo do polí nižšie.', 'label.required_fields' => '* - povinné polia', 'label.on_behalf' => 'v zastúpení', -'label.role_manager' => '(manažér)', -'label.role_comanager' => '(spolu-manažér)', -'label.role_admin' => '(administrátor)', // TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index b8f7e9407..1703ba75d 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -208,9 +208,6 @@ // 'label.ldap_hint' => 'Type your Windows login and password in the fields below.', // 'label.required_fields' => '* - required fields', // 'label.on_behalf' => 'on behalf of', -// 'label.role_manager' => '(manager)', -// 'label.role_comanager' => '(co-manager)', -// 'label.role_admin' => '(administrator)', // 'label.page' => 'Page', // 'label.condition' => 'Condition', // 'label.yes' => 'yes', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index bc98a1d33..fac94f100 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -209,9 +209,6 @@ 'label.ldap_hint' => 'Unesi tvoju Windows prijavu i lozinku u polje ispod.', 'label.required_fields' => '* - obavezna polja', 'label.on_behalf' => 'ispred', -'label.role_manager' => '(menadžer)', -'label.role_comanager' => '(saradnik)', -'label.role_admin' => '(administrator)', 'label.page' => 'Strana', // TODO: translate the following. // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index d977a9a2e..64311d4ad 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -205,9 +205,6 @@ 'label.ldap_hint' => 'Fyll i ditt användarnamn och lösenord för Windows i fälten nedan.', 'label.required_fields' => '* - Obligatoriska fält', 'label.on_behalf' => 'agerar som', -'label.role_manager' => '(Ansvarig)', -'label.role_comanager' => '(Delansvarig)', -'label.role_admin' => '(Administratör)', 'label.page' => 'Sida', 'label.condition' => 'Villkor', // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index dc8bd0736..a41fda46c 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -229,9 +229,6 @@ // 'label.ldap_hint' => 'Type your Windows login and password in the fields below.', 'label.required_fields' => '* zorunlu bilgi', 'label.on_behalf' => 'adına', -'label.role_manager' => '(yönetici)', -'label.role_comanager' => '(yardımcı yönetici)', -'label.role_admin' => '(sistem yönetici)', // TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 50cff7bcc..e6df6346f 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -216,9 +216,6 @@ 'label.ldap_hint' => '在下面的栏目输入您的Windows用户名密码。', 'label.required_fields' => '* 必填栏目', 'label.on_behalf' => '代表', -'label.role_manager' => '(经理)', -'label.role_comanager' => '(合作经理人)', -'label.role_admin' => '(管理员)', 'label.page' => '页码', // TODO: translate the following. // 'label.condition' => 'Condition', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 8bc481b9e..353ca1fdf 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -221,9 +221,6 @@ 'label.ldap_hint' => '在下麵的欄目輸入您的Windows用戶名密碼。', 'label.required_fields' => '* 必填欄目', 'label.on_behalf' => '代表', -'label.role_manager' => '(經理)', -'label.role_comanager' => '(合作經理人)', -'label.role_admin' => '(管理員)', // TODO: translate the following. // 'label.page' => 'Page', // 'label.condition' => 'Condition', diff --git a/initialize.php b/initialize.php index 07344a419..d2596211c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5617"); +define("APP_VERSION", "1.19.34.5618"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 63fbf04bc85853a1c8a43edfb710009b6531bcce Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 25 Jan 2022 18:08:42 +0000 Subject: [PATCH 1639/1848] Removed no longer used string from translation files. --- WEB-INF/resources/ca.lang.php | 1 - WEB-INF/resources/cs.lang.php | 1 - WEB-INF/resources/da.lang.php | 1 - WEB-INF/resources/de.lang.php | 1 - WEB-INF/resources/en.lang.php | 1 - WEB-INF/resources/es.lang.php | 1 - WEB-INF/resources/et.lang.php | 1 - WEB-INF/resources/fa.lang.php | 1 - WEB-INF/resources/fi.lang.php | 1 - WEB-INF/resources/fr.lang.php | 1 - WEB-INF/resources/gr.lang.php | 1 - WEB-INF/resources/he.lang.php | 1 - WEB-INF/resources/hu.lang.php | 1 - WEB-INF/resources/it.lang.php | 1 - WEB-INF/resources/ja.lang.php | 1 - WEB-INF/resources/ko.lang.php | 1 - WEB-INF/resources/nl.lang.php | 1 - WEB-INF/resources/no.lang.php | 1 - WEB-INF/resources/pl.lang.php | 1 - WEB-INF/resources/pt-br.lang.php | 1 - WEB-INF/resources/pt.lang.php | 1 - WEB-INF/resources/ro.lang.php | 1 - WEB-INF/resources/ru.lang.php | 1 - WEB-INF/resources/sk.lang.php | 1 - WEB-INF/resources/sl.lang.php | 1 - WEB-INF/resources/sr.lang.php | 1 - WEB-INF/resources/sv.lang.php | 1 - WEB-INF/resources/tr.lang.php | 1 - WEB-INF/resources/zh-cn.lang.php | 1 - WEB-INF/resources/zh-tw.lang.php | 1 - initialize.php | 2 +- 31 files changed, 1 insertion(+), 31 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 196a4441d..6b74dced4 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -407,7 +407,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index a30d83c89..836ef4f28 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -414,7 +414,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 369c965f4..bc042b6e5 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -391,7 +391,6 @@ 'dropdown.delete' => 'Slet', 'dropdown.do_not_delete' => 'Slet ikke', // TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 87f40c849..dae614fbc 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -372,7 +372,6 @@ 'dropdown.delete' => 'löschen', 'dropdown.do_not_delete' => 'nicht löschen', // TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'bezahlt', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 0d82650c8..652c3e484 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -356,7 +356,6 @@ 'dropdown.status_inactive' => 'inactive', 'dropdown.delete' => 'delete', 'dropdown.do_not_delete' => 'do not delete', -'dropdown.pending_approval' => 'pending approval', 'dropdown.approved' => 'approved', 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 68dcc8c31..f2bb893ba 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -406,7 +406,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 431f29563..67210ee66 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -398,7 +398,6 @@ 'dropdown.delete' => 'kustuta', 'dropdown.do_not_delete' => 'ära kustuta', // TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'makstud', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 9ae24d016..31c1506fe 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -403,7 +403,6 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index a9396eba9..c0d712667 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -391,7 +391,6 @@ 'dropdown.delete' => 'poista', 'dropdown.do_not_delete' => 'älä poista', // TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 91e04d793..61570ee8c 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -383,7 +383,6 @@ 'dropdown.delete' => 'supprimer', 'dropdown.do_not_delete' => 'ne pas supprimer', // TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 1fd83890f..c795c5073 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -381,7 +381,6 @@ 'dropdown.delete' => 'διαγραφή', 'dropdown.do_not_delete' => 'μη το διαγράψετε', // TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'εξοφλημένο', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index ef7597cd3..72a48ba5d 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -408,7 +408,6 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 1c446ac53..8b1e0b348 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -408,7 +408,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index e3d19aa5f..90167eb26 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -391,7 +391,6 @@ 'dropdown.delete' => 'elimina', 'dropdown.do_not_delete' => 'non eliminare', // TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'pagato', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index aa2389788..d0bad574e 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -408,7 +408,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index cc52c1108..3e62d9d2d 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -412,7 +412,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 360ddd802..dc86183ac 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -348,7 +348,6 @@ 'dropdown.status_inactive' => 'inactief', 'dropdown.delete' => 'verwijderen', 'dropdown.do_not_delete' => 'niet verwijderen', -'dropdown.pending_approval' => 'in afwachting van goedkeuring', 'dropdown.approved' => 'goedgekeurd', 'dropdown.not_approved' => 'afgekeurd', 'dropdown.paid' => 'betaald', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 8202b4e9f..598950581 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -410,7 +410,6 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index ad4ec2c3d..c826441f3 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -394,7 +394,6 @@ 'dropdown.delete' => 'usuń', 'dropdown.do_not_delete' => 'nie usuwaj', // TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 3b8ceccf3..ba2ed1d73 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -346,7 +346,6 @@ 'dropdown.status_inactive' => 'inativo', 'dropdown.delete' => 'apagar', 'dropdown.do_not_delete' => 'não apagar', -'dropdown.pending_approval' => 'aprovação pendente', 'dropdown.approved' => 'aprovado', 'dropdown.not_approved' => 'não aprovado', 'dropdown.paid' => 'pago', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 4b6db659e..cac4c68e8 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -392,7 +392,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index fc8c9a8f8..1d97b1fed 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -413,7 +413,6 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index e052ba818..20d7d7e60 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -349,7 +349,6 @@ 'dropdown.status_inactive' => 'неактивный', 'dropdown.delete' => 'удалить', 'dropdown.do_not_delete' => 'не удалять', -'dropdown.pending_approval' => 'в ожидании одобрения', 'dropdown.approved' => 'одобрено', 'dropdown.not_approved' => 'не одобрено', 'dropdown.paid' => 'оплачено', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 6eb804d20..89f26abde 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -397,7 +397,6 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 1703ba75d..56eeb2050 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -385,7 +385,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index fac94f100..c88e9d07c 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -392,7 +392,6 @@ 'dropdown.delete' => 'obriši', 'dropdown.do_not_delete' => 'nemoj obrisati', // TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 64311d4ad..36c0a325c 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -390,7 +390,6 @@ 'dropdown.delete' => 'Ta bort', 'dropdown.do_not_delete' => 'Ta inte bort', // TODO: translate the following. -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index a41fda46c..2e5bed2bb 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -421,7 +421,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index e6df6346f..b1c0667b3 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -402,7 +402,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 353ca1fdf..5212a3f80 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -406,7 +406,6 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', -// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/initialize.php b/initialize.php index d2596211c..8b24ed417 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5618"); +define("APP_VERSION", "1.19.34.5619"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From e0201c7924628b3727cb63b7e4b43d5f284f4326 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 26 Jan 2022 14:33:39 +0000 Subject: [PATCH 1640/1848] Updated database structure after removing remote work plugin. --- WEB-INF/lib/ttRoleHelper.class.php | 4 +-- dbinstall.php | 13 +++++++--- initialize.php | 2 +- mysql.sql | 40 ++---------------------------- 4 files changed, 14 insertions(+), 45 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 683f7ebaf..1ddc839cc 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -168,8 +168,8 @@ static function createPredefinedRoles($group_id, $lang) $rights_client = 'view_client_reports,view_client_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; - $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,update_work'; - $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_work,bid_on_work'; + $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; + $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; $rights_manager = $rights_comanager.',manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_own_timesheets,manage_subgroups'; // Active roles. diff --git a/dbinstall.php b/dbinstall.php index 2dfe30d66..c966bdbaa 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1137,7 +1137,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11929"]) { + if ($_POST["convert11900to12000"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1172,6 +1172,11 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.23', modified = now() where param_name = 'version_db' and param_value = '1.19.22'"); ttExecute("ALTER TABLE `tt_groups` ADD `entities_modified` datetime default NULL AFTER `modified_by`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.29', modified = now() where param_name = 'version_db' and param_value = '1.19.23'"); + ttExecute("DROP TABLE `tt_work_currencies`"); + ttExecute("DROP TABLE `tt_work_categories`"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.19.29') set rights = replace(rights, 'swap_roles,update_work', 'swap_roles') where `rank` >= 12"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.19.29') set rights = replace(rights, 'view_all_reports,manage_work,bid_on_work', 'view_all_reports') where `rank` >= 68"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.20.0', modified = now() where param_name = 'version_db' and param_value = '1.19.29'"); } if ($_POST["cleanup"]) { @@ -1222,7 +1227,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.19.29) + Create database structure (v1.20.0)
(applies only to new installations, do not execute when updating)
@@ -1271,8 +1276,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.29)Update database structure (v1.19 to v1.20)
diff --git a/initialize.php b/initialize.php index 8b24ed417..e0a6999eb 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.19.34.5619"); +define("APP_VERSION", "1.20.0.5620"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mysql.sql b/mysql.sql index 7a87b3766..55d8e8b5c 100644 --- a/mysql.sql +++ b/mysql.sql @@ -78,7 +78,7 @@ create unique index role_idx on tt_roles(group_id, `rank`, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,update_work,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_work,bid_on_work,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_own_timesheets,manage_subgroups,view_client_unapproved,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_own_timesheets,manage_subgroups,view_client_unapproved,delete_group'); # @@ -608,42 +608,6 @@ CREATE TABLE `tt_files` ( ); -# -# Structure for table tt_work_currencies. -# This table keeps currencies supported by remote work plugin. -# -CREATE TABLE `tt_work_currencies` ( - `id` int(10) unsigned NOT NULL, # currency id - `name` varchar(10) NOT NULL, # currency name (USD, CAD, etc.) - PRIMARY KEY (`id`) -); - -# Create an index that guarantees unique work currencies. -create unique index currency_idx on tt_work_currencies(`name`); - -INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD'); - - -# -# Structure for table tt_work_categories. -# This table keeps work categories supported by remote work plugin. -# -CREATE TABLE `tt_work_categories` ( - `id` int(10) unsigned NOT NULL, # Category id. - `parents` text default NULL, # Comma-separated list of parent ids associated with this category. - `name` varchar(64) NOT NULL, # English category name. - `name_localized` text default NULL, # Comma-separated list of localized category names in other languages. - # Example: es:Codificación,ru:Кодирование. - PRIMARY KEY (`id`) -); - -# Insert some default categories. Table content to be updated at run time, though. -INSERT INTO `tt_work_categories` (`id`, `parents`, `name`, `name_localized`) VALUES ('1', NULL, 'Coding', 'es:Codificación,ru:Кодирование'); -INSERT INTO `tt_work_categories` (`id`, `parents`, `name`, `name_localized`) VALUES ('2', NULL, 'Other', 'es:Otra,ru:Другое'); -INSERT INTO `tt_work_categories` (`id`, `parents`, `name`, `name_localized`) VALUES ('3', '1', 'PHP', NULL); -INSERT INTO `tt_work_categories` (`id`, `parents`, `name`, `name_localized`) VALUES ('4', '1', 'C/C++', NULL); - - # # Structure for table tt_site_config. This table stores configuration data # for Time Tracker site as a whole. @@ -657,4 +621,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.29', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.20.0', now()); # TODO: change when structure changes. From beb0be399e413bc1ade1d5da86f259154c9782e1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 4 Feb 2022 22:54:34 +0000 Subject: [PATCH 1641/1848] Remove no longer needed file. --- initialize.php | 3 ++- plugins/work_constants.php | 36 ------------------------------------ 2 files changed, 2 insertions(+), 37 deletions(-) delete mode 100644 plugins/work_constants.php diff --git a/initialize.php b/initialize.php index e0a6999eb..73f4e7581 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,8 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5620"); +define("APP_VERSION", "1.20.0.5621" + . ""); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins/work_constants.php b/plugins/work_constants.php deleted file mode 100644 index 207ca5d35..000000000 --- a/plugins/work_constants.php +++ /dev/null @@ -1,36 +0,0 @@ - Date: Fri, 4 Feb 2022 23:13:49 +0000 Subject: [PATCH 1642/1848] Fixed a typo problem in previous commit. --- initialize.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/initialize.php b/initialize.php index 73f4e7581..c417c1c4e 100644 --- a/initialize.php +++ b/initialize.php @@ -12,8 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5621" - . ""); +define("APP_VERSION", "1.20.0.5621"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From fb8b436cabe05c119156de56c24f0b74a042a218 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 7 Feb 2022 19:28:04 +0000 Subject: [PATCH 1643/1848] Cosmetic maintenance. --- expenses.php | 5 ++++- initialize.php | 2 +- time.php | 6 +++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/expenses.php b/expenses.php index 578e2d1c6..897d64d91 100644 --- a/expenses.php +++ b/expenses.php @@ -189,6 +189,10 @@ // Submit. if ($request->isPost()) { if ($request->getParameter('btn_submit')) { + // Use the "limit" plugin if we have one. Ignore include errors. + // The "limit" plugin is not required for normal operation of Time Tracker. + @include('plugins/limit/access_check.php'); + // Validate user input. if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); @@ -203,7 +207,6 @@ if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); // Finished validating input data. // Prohibit creating entries in locked range. diff --git a/initialize.php b/initialize.php index c417c1c4e..ac607dd98 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5621"); +define("APP_VERSION", "1.20.0.5622"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 9202dc1d7..6bc95e930 100644 --- a/time.php +++ b/time.php @@ -342,6 +342,11 @@ if ($request->isPost()) { if ($request->getParameter('btn_submit')) { // Submit button clicked. + + // Use the "limit" plugin if we have one. Ignore include errors. + // The "limit" plugin is not required for normal operation of Time Tracker. + @include('plugins/limit/access_check.php'); + // Validate user input. if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); @@ -384,7 +389,6 @@ if ($user->isPluginEnabled('tp') && !ttValidTemplateText($cl_note)) { $err->add($i18n->get('error.field'), $i18n->get('label.note')); } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); // Finished validating user input. // Prohibit creating entries in future. From 58fb0f456312711d175495e8ea6f6116d131a068 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Feb 2022 16:25:10 +0000 Subject: [PATCH 1644/1848] Addressed several php8 warnings. --- WEB-INF/lib/ttReportHelper.class.php | 8 +++++--- initialize.php | 2 +- login.php | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 68fc85b2d..ffef6e773 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -109,7 +109,7 @@ static function getWhere($options) { } // Prepare sql query part for user list. - $userlist = $options['users'] ? $options['users'] : '-1'; + $userlist = isset($options['users']) ? $options['users'] : '-1'; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and l.user_id in ($userlist)"; else @@ -191,7 +191,7 @@ static function getExpenseWhere($options) { } // Prepare sql query part for user list. - $userlist = $options['users'] ? $options['users'] : '-1'; + $userlist = isset($options['users']) ? $options['users'] : '-1'; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $user_list_part = " and ei.user_id in ($userlist)"; else @@ -571,7 +571,7 @@ static function getItems($options) { } else { $sort_part .= 'date'; } - if (($canViewReports || $isClient) && $options['users'] && !$grouping_by_user) + if (($canViewReports || $isClient) && isset($options['users']) && !$grouping_by_user) $sort_part .= ', user, type'; if ($options['show_start']) $sort_part .= ', unformatted_start'; @@ -584,6 +584,7 @@ static function getItems($options) { $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die($res->getMessage()); + $report_items = array(); while ($val = $res->fetchRow()) { if ($convertTo12Hour) { if($val['start'] != '') @@ -1526,6 +1527,7 @@ static function getReportOptions($bean) { $options['timesheet'] = $bean->getAttribute('timesheet'); $active_users_in_bean = $bean->getAttribute('users_active'); + $users = ''; if ($active_users_in_bean && is_array($active_users_in_bean)) { $users = join(',', $active_users_in_bean); } diff --git a/initialize.php b/initialize.php index ac607dd98..6e3baf991 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5622"); +define("APP_VERSION", "1.20.0.5623"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/login.php b/login.php index 9e2436206..93b1cd084 100644 --- a/login.php +++ b/login.php @@ -66,7 +66,7 @@ $err->add($i18n->get('error.no_groups')); // Determine whether to show login hint. It is currently used only for Windows LDAP authentication. -$show_hint = ('ad' == $GLOBALS['AUTH_MODULE_PARAMS']['type']); +$show_hint = ('ad' == isset($GLOBALS['AUTH_MODULE_PARAMS']['type']) ? $GLOBALS['AUTH_MODULE_PARAMS']['type'] : null); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_hint', $show_hint); From 8f06d7527e7e7311b3ac289177ecc1fc77aeebd9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Feb 2022 17:15:05 +0000 Subject: [PATCH 1645/1848] Updated dbinstall.php for php8.1 breaking change. --- dbinstall.php | 30 ++++++++++++++++++++---------- initialize.php | 2 +- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/dbinstall.php b/dbinstall.php index c966bdbaa..12a1e6232 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -94,10 +94,16 @@ function ttGenerateKeys() { // $required_version = '5.2.1'; // Something in TCPDF library does not work below this one. $required_version = '5.4.0'; // Week view (week.php) requires 5.4 because of []-way of referencing arrays. // This needs further investigation as we use [] elsewhere without obvious problems. - if (version_compare(phpversion(), $required_version, '>=')) { - echo('PHP version: '.phpversion().', good enough.
'); + // Print a warning about php >= 8.1 because of a breaking change + // with mysqli default error mode, see https://php.watch/versions/8.1/mysqli-error-mode + if (version_compare(phpversion(), '8.1', '>=')) { + echo('Error: This app was not tested with PHP version: '.phpversion().'
'); } else { - echo('Error: PHP version is not high enough: '.phpversion().'. Required: '.$required_version.'.
'); + if (version_compare(phpversion(), $required_version, '>=')) { + echo('PHP version: '.phpversion().', good enough.
'); + } else { + echo('Error: PHP version is not high enough: '.phpversion().'. Required: '.$required_version.'.
'); + } } // Depending on DSN, require either mysqli or mysql extensions. @@ -171,13 +177,17 @@ function ttGenerateKeys() { echo('There are no tables in database. Execute step 1 - Create database structure.
'); } - $sql = "select param_value from tt_site_config where param_name = 'version_db'"; - $res = $conn->query($sql); - if (is_a($res, 'MDB2_Error')) { - echo('Error: database schema version query failed. '.$res->getMessage().'
'); - } else { - $val = $res->fetchRow(); - echo('Database version is: '.$val['param_value'].'.'); + try { + $sql = "select param_value from tt_site_config where param_name = 'version_db'"; + $res = $conn->query($sql); + if (is_a($res, 'MDB2_Error')) { + echo('Error: database schema version query failed. '.$res->getMessage().'
'); + } else { + $val = $res->fetchRow(); + echo('Database version is: '.$val['param_value'].'.'); + } + } catch (Exception $e) { + echo('Caught exception: '.$e->getMessage().'
'); } $conn->disconnect(); diff --git a/initialize.php b/initialize.php index 6e3baf991..27f6705fe 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5623"); +define("APP_VERSION", "1.20.0.5624"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From d04650cf53ea378f9bd8c7b81104f63c34713936 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Feb 2022 19:28:48 +0000 Subject: [PATCH 1646/1848] Starting to address numerous php8.1 issues. --- WEB-INF/lib/ttConfigHelper.class.php | 33 +++++----------------------- initialize.php | 2 +- time.php | 10 ++++----- 3 files changed, 11 insertions(+), 34 deletions(-) diff --git a/WEB-INF/lib/ttConfigHelper.class.php b/WEB-INF/lib/ttConfigHelper.class.php index 33e94e513..95bc1e0f1 100644 --- a/WEB-INF/lib/ttConfigHelper.class.php +++ b/WEB-INF/lib/ttConfigHelper.class.php @@ -1,30 +1,6 @@ config = trim($config, ' ,'); + if (!is_null($config)) + $this->config = trim($config, ' ,'); if ($this->config) $this->config_array = explode(',', $this->config); } @@ -120,6 +97,6 @@ function setIntValue($name, $value) { // The getConfig returns the config string. function getConfig() { - return trim($this->config, ' ,'); + return (is_null($this->config) ? null : trim($this->config, ' ,')); } } diff --git a/initialize.php b/initialize.php index 27f6705fe..7a7f06efe 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5624"); +define("APP_VERSION", "1.20.0.5625"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 6bc95e930..f5f84deb3 100644 --- a/time.php +++ b/time.php @@ -129,10 +129,10 @@ } // Initialize variables. -$cl_start = trim($request->getParameter('start')); -$cl_finish = trim($request->getParameter('finish')); -$cl_duration = trim($request->getParameter('duration')); -$cl_note = trim($request->getParameter('note')); +$cl_start = is_null($request->getParameter('start')) ? null : trim($request->getParameter('start')); +$cl_finish = is_null($request->getParameter('finish')) ? null : trim($request->getParameter('finish')); +$cl_duration = is_null($request->getParameter('duration')) ? null : trim($request->getParameter('duration')); +$cl_note = is_null($request->getParameter('note')) ? null : trim($request->getParameter('note')); $cl_billable = 1; if ($showBillable) { if ($request->isPost()) { @@ -161,7 +161,7 @@ 'label' => $timeField['label'], 'type' => $timeField['type'], 'required' => $timeField['required'], - 'value' => trim($cl_control_name)); + 'value' => is_null($cl_control_name) ? null : trim($cl_control_name)); } } From 15c3ecc308bb027469926644af84e4cd49bb8904 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Feb 2022 15:49:30 +0000 Subject: [PATCH 1647/1848] Started making a replacement for DateAndTime class for php8.1 support. --- WEB-INF/lib/ttDate.class.php | 75 ++++++++++++++++++++++++++++++++++++ initialize.php | 2 +- time.php | 11 ++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/lib/ttDate.class.php diff --git a/WEB-INF/lib/ttDate.class.php b/WEB-INF/lib/ttDate.class.php new file mode 100644 index 000000000..519a76623 --- /dev/null +++ b/WEB-INF/lib/ttDate.class.php @@ -0,0 +1,75 @@ +$dateInDbDateFormat = $dateString; + $this->isValid = true; + } else { + $today = date_create(); + $this->dateInDbDateFormat = date_format($today, 'Y-m-d'); + $this->isValid = true; + } + + $this->unixTimestamp = strtotime($this->dateInDbDateFormat); + $this->year = date('Y', $this->unixTimestamp); + $this->month = date('m', $this->unixTimestamp); + $this->day = date('d', $this->unixTimestamp); + $this->dayOfWeek = date('w', $this->unixTimestamp); + } + + + // isValid determines if we have a properly initialized ttDate object. + function isValid() { + return $this->isValid; + } + + + // toString returns a date in specified format. + function toString($format = null) { + if (!$this->isValid) return null; + + if ($format == null || $format == DB_DATEFORMAT) + return $this->dateInDbDateFormat; + else { + return $this->formatDate($format); + } + } + + + // formatDate returns a date string in specified format. + function formatDate($format) { + global $i18n; + + $formattedDate = $format; // Start with unmodified format string. + + // Replace all found elements with data. + $formattedDate = str_replace('%Y', $this->year, $formattedDate); + $formattedDate = str_replace('%m', $this->month, $formattedDate); + $formattedDate = str_replace('%d', $this->day, $formattedDate); + // Replace locale-dependent days of week. + $formattedDate = str_replace('%a', mb_substr($i18n->getWeekDayName($this->dayOfWeek), 0, 3, 'utf-8'), $formattedDate); + return $formattedDate; + } +} diff --git a/initialize.php b/initialize.php index 7a7f06efe..28d4a8d1d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5625"); +define("APP_VERSION", "1.20.0.5626"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index f5f84deb3..9ee63d91c 100644 --- a/time.php +++ b/time.php @@ -11,6 +11,7 @@ import('ttTimeHelper'); import('ttFileHelper'); import('DateAndTime'); +import('ttDate'); // Access checks. if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { @@ -81,6 +82,16 @@ $cl_date = $selected_date->toString(DB_DATEFORMAT); $_SESSION['date'] = $cl_date; +// Refactoring in progress for php8.1. +// TODO: remove the above block when done. +$selected_date2 = new ttDate(); +if (!$selected_date2->isValid()) + $selected_date2 = new ttDate(); +if(!$cl_date) + $cl_date = $selected_date2->toString(DB_DATEFORMAT); +$_SESSION['date'] = $cl_date; +// End of TODO. + // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); From 496e3ed494343bbd328af0f7a5f288d47a584778 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Feb 2022 16:09:55 +0000 Subject: [PATCH 1648/1848] Some more refactoring for php8.1. --- initialize.php | 2 +- plugins/MonthlyQuota.class.php | 8 ++++---- time.php | 6 ++++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/initialize.php b/initialize.php index 28d4a8d1d..237566d18 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5626"); +define("APP_VERSION", "1.20.0.5627"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins/MonthlyQuota.class.php b/plugins/MonthlyQuota.class.php index f742fd918..76a7c5100 100644 --- a/plugins/MonthlyQuota.class.php +++ b/plugins/MonthlyQuota.class.php @@ -104,13 +104,13 @@ public function getUserQuota($year, $month) { // from 1st of the month up to and inclusive of $selected_date. public function getUserQuotaFrom1st($selected_date) { // TODO: we may need a better algorithm here. Review. - $monthQuotaMinutes = $this->getUserQuota($selected_date->mYear, $selected_date->mMonth); - $workdaysInMonth = $this->getNumWorkdays($selected_date->mMonth, $selected_date->mYear); + $monthQuotaMinutes = $this->getUserQuota($selected_date->year, $selected_date->month); + $workdaysInMonth = $this->getNumWorkdays($selected_date->month, $selected_date->year); // Iterate from 1st up to selected date. $workdaysFrom1st = 0; - for ($i = 1; $i <= $selected_date->mDate; $i++) { - $date = ttTimeHelper::dateInDatabaseFormat($selected_date->mYear, $selected_date->mMonth, $i); + for ($i = 1; $i <= $selected_date->day; $i++) { + $date = ttTimeHelper::dateInDatabaseFormat($selected_date->year, $selected_date->month, $i); if (!ttTimeHelper::isWeekend($date) && !ttTimeHelper::isHoliday($date)) { $workdaysFrom1st++; } diff --git a/time.php b/time.php index 9ee63d91c..6e9dd610d 100644 --- a/time.php +++ b/time.php @@ -84,6 +84,7 @@ // Refactoring in progress for php8.1. // TODO: remove the above block when done. +// Also replace all occurrences of $selected_date2 with $selected_date. $selected_date2 = new ttDate(); if (!$selected_date2->isValid()) $selected_date2 = new ttDate(); @@ -124,8 +125,9 @@ if ($user->isPluginEnabled('mq')){ require_once('plugins/MonthlyQuota.class.php'); $quota = new MonthlyQuota(); - $month_quota_minutes = $quota->getUserQuota($selected_date->mYear, $selected_date->mMonth); - $quota_minutes_from_1st = $quota->getUserQuotaFrom1st($selected_date); + $month_quota_minutes = $quota->getUserQuota($selected_date2->year, $selected_date2->month); + $quota_minutes_from_1st = $quota->getUserQuotaFrom1st($selected_date2); + // TODO: refactor ttTimeHelper::getTimeForMonth to use a new ttPeriod class. $month_total = ttTimeHelper::getTimeForMonth($selected_date); $month_total_minutes = ttTimeHelper::toMinutes($month_total); $balance_left = $quota_minutes_from_1st - $month_total_minutes; From 6dd18388f02edf24238aea848cd651380ccbe02a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 17 Feb 2022 12:15:20 +0000 Subject: [PATCH 1649/1848] Some refactoring for php8.1 support. --- WEB-INF/lib/ttDate.class.php | 34 ++++++++++++++++++++++-- WEB-INF/lib/ttPeriod.class.php | 42 ++++++++++++++++++++++++++++++ WEB-INF/lib/ttTimeHelper.class.php | 27 +++++++++++++++++++ initialize.php | 2 +- time.php | 9 +++---- 5 files changed, 106 insertions(+), 8 deletions(-) create mode 100644 WEB-INF/lib/ttPeriod.class.php diff --git a/WEB-INF/lib/ttDate.class.php b/WEB-INF/lib/ttDate.class.php index 519a76623..791a1e942 100644 --- a/WEB-INF/lib/ttDate.class.php +++ b/WEB-INF/lib/ttDate.class.php @@ -22,9 +22,8 @@ class ttDate { // Constructor. function __construct($dateString = null) { - // TODO: redo the constructor and initialize year. month, day, and dayOfWeek properly. if (ttValidDbDateFormatDate($dateString)) { - $this->$dateInDbDateFormat = $dateString; + $this->dateInDbDateFormat = $dateString; $this->isValid = true; } else { $today = date_create(); @@ -46,6 +45,25 @@ function isValid() { } + // Returns unix timestamp. + function getTimestamp() { + return $this->unixTimestamp; + } + + + // Resets the object properties from a passed in unix timestamp. + function setFromUnixTimestamp($unixTimestamp) { + $this->unixTimestamp = $unixTimestamp; + + $this->year = date('Y', $this->unixTimestamp); + $this->month = date('m', $this->unixTimestamp); + $this->day = date('d', $this->unixTimestamp); + $this->dayOfWeek = date('w', $this->unixTimestamp); + + $this->dateInDbDateFormat = $this->year.'-'.$this->month.'-'.$this->day; + } + + // toString returns a date in specified format. function toString($format = null) { if (!$this->isValid) return null; @@ -72,4 +90,16 @@ function formatDate($format) { $formattedDate = str_replace('%a', mb_substr($i18n->getWeekDayName($this->dayOfWeek), 0, 3, 'utf-8'), $formattedDate); return $formattedDate; } + + + function before(/*ttDate*/ $obj) { + if ($this->getTimestamp() < $obj->getTimestamp()) return true; + return false; + } + + + function after(/*ttDate*/ $obj) { + if ($this->getTimestamp() > $obj->getTimestamp()) return true; + return false; + } } diff --git a/WEB-INF/lib/ttPeriod.class.php b/WEB-INF/lib/ttPeriod.class.php new file mode 100644 index 000000000..a541663fe --- /dev/null +++ b/WEB-INF/lib/ttPeriod.class.php @@ -0,0 +1,42 @@ +getWeekStart(); + + $t_arr = localtime($ttDateInstance->getTimestamp()); + $t_arr[5] = $t_arr[5] + 1900; + + $this->startDate = new ttDate(); + $this->endDate = new ttDate(); + + switch ($period_type) { + case INTERVAL_THIS_MONTH: + $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,1,$t_arr[5])); + $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+2,0,$t_arr[5])); + break; + } + } + + + // Returns start date in specified format. + function getStartDate($format = null) { + return $this->startDate->toString($format); + } + + + // Returns end date in specified format. + function getEndDate($format = null) { + return $this->endDate->toString($format); + } +} \ No newline at end of file diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 75c911e04..917ceb571 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -605,6 +605,7 @@ static function getTimeForWeek($date) { static function getTimeForMonth($date) { global $user; import('Period'); + import('ttPeriod'); $mdb2 = getConnection(); $user_id = $user->getUser(); @@ -612,6 +613,8 @@ static function getTimeForMonth($date) { $org_id = $user->org_id; $period = new Period(INTERVAL_THIS_MONTH, $date); + // TODO: refactoring in progress... + $period2 = new ttPeriod(INTERVAL_THIS_MONTH, $date); $sql = "select sum(time_to_sec(duration)) as sm from tt_log". " where user_id = $user_id and group_id = $group_id and org_id = $org_id". " and date >= '".$period->getStartDate(DB_DATEFORMAT)."' and date <= '".$period->getEndDate(DB_DATEFORMAT)."' and status = 1"; @@ -623,6 +626,30 @@ static function getTimeForMonth($date) { return false; } + // getTimeForMonth2 - gets total time for a user for a given month. + // Refactoring - this is a replacement function for getTimeForMonth above. + // TODO: remove getTimeForMonth after refactoring week view. + static function getTimeForMonth2($date) { + global $user; + import('ttPeriod'); + $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $period = new ttPeriod(INTERVAL_THIS_MONTH, $date); + $sql = "select sum(time_to_sec(duration)) as sm from tt_log". + " where user_id = $user_id and group_id = $group_id and org_id = $org_id". + " and date >= '".$period->getStartDate()."' and date <= '".$period->getEndDate()."' and status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + return ttTimeHelper::minutesToDuration($val['sm'] / 60); + } + return false; + } + // getUncompleted - retrieves an uncompleted record for user, if one exists. static function getUncompleted($user_id) { $mdb2 = getConnection(); diff --git a/initialize.php b/initialize.php index 237566d18..e6223498a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5627"); +define("APP_VERSION", "1.20.0.5628"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 6e9dd610d..b20308974 100644 --- a/time.php +++ b/time.php @@ -85,7 +85,7 @@ // Refactoring in progress for php8.1. // TODO: remove the above block when done. // Also replace all occurrences of $selected_date2 with $selected_date. -$selected_date2 = new ttDate(); +$selected_date2 = new ttDate($cl_date); if (!$selected_date2->isValid()) $selected_date2 = new ttDate(); if(!$cl_date) @@ -127,8 +127,7 @@ $quota = new MonthlyQuota(); $month_quota_minutes = $quota->getUserQuota($selected_date2->year, $selected_date2->month); $quota_minutes_from_1st = $quota->getUserQuotaFrom1st($selected_date2); - // TODO: refactor ttTimeHelper::getTimeForMonth to use a new ttPeriod class. - $month_total = ttTimeHelper::getTimeForMonth($selected_date); + $month_total = ttTimeHelper::getTimeForMonth2($selected_date2); $month_total_minutes = ttTimeHelper::toMinutes($month_total); $balance_left = $quota_minutes_from_1st - $month_total_minutes; $minutes_left = $month_quota_minutes - $month_total_minutes; @@ -406,8 +405,8 @@ // Prohibit creating entries in future. if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) + $browser_today = new ttDate($request->getParameter('browser_today', null)); + if ($selected_date2->after($browser_today)) $err->add($i18n->get('error.future_date')); } From 82ff14f082c8e03098292b9c9bdf79c22227aa21 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 17 Feb 2022 13:07:48 +0000 Subject: [PATCH 1650/1848] More refactoring for php8.1. --- WEB-INF/lib/ttPeriod.class.php | 11 +++++++++-- WEB-INF/lib/ttTimeHelper.class.php | 27 ++++++++++++++++++++++++--- WEB-INF/lib/ttUser.class.php | 2 +- initialize.php | 2 +- time.php | 29 +++++++++-------------------- 5 files changed, 44 insertions(+), 27 deletions(-) diff --git a/WEB-INF/lib/ttPeriod.class.php b/WEB-INF/lib/ttPeriod.class.php index a541663fe..1d4b2c4d6 100644 --- a/WEB-INF/lib/ttPeriod.class.php +++ b/WEB-INF/lib/ttPeriod.class.php @@ -2,6 +2,7 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ +define('INTERVAL_THIS_WEEK', 2); define('INTERVAL_THIS_MONTH', 3); class ttPeriod { @@ -11,16 +12,22 @@ class ttPeriod { function __construct($period_type = INTERVAL_THIS_MONTH, $ttDateInstance) { - // global $user; - // $weekStartDay = $user->getWeekStart(); + global $user; + $weekStartDay = $user->getWeekStart(); $t_arr = localtime($ttDateInstance->getTimestamp()); $t_arr[5] = $t_arr[5] + 1900; + $startWeekBias = ($t_arr[6] < $weekStartDay) ? $weekStartDay - 7 : $weekStartDay; $this->startDate = new ttDate(); $this->endDate = new ttDate(); switch ($period_type) { + case INTERVAL_THIS_WEEK: + $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+$startWeekBias,$t_arr[5])); + $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+6+$startWeekBias,$t_arr[5])); + break; + case INTERVAL_THIS_MONTH: $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,1,$t_arr[5])); $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+2,0,$t_arr[5])); diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 917ceb571..604724160 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -600,12 +600,35 @@ static function getTimeForWeek($date) { } return false; } + + // getTimeForWeek2 - gets total time for a user for a given week. + // Refactoring - this is a replacement function for getTimeForWeek above. + // TODO: remove getTimeForWeek after refactoring week view and puncher. + static function getTimeForWeek2($date) { + global $user; + import('ttPeriod'); + $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $period = new ttPeriod(INTERVAL_THIS_WEEK, $date); + $sql = "select sum(time_to_sec(duration)) as sm from tt_log". + " where user_id = $user_id and group_id = $group_id and org_id = $org_id". + " and date >= '".$period->getStartDate()."' and date <= '".$period->getEndDate()."' and status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + return ttTimeHelper::minutesToDuration($val['sm'] / 60); + } + return false; + } // getTimeForMonth - gets total time for a user for a given month. static function getTimeForMonth($date) { global $user; import('Period'); - import('ttPeriod'); $mdb2 = getConnection(); $user_id = $user->getUser(); @@ -613,8 +636,6 @@ static function getTimeForMonth($date) { $org_id = $user->org_id; $period = new Period(INTERVAL_THIS_MONTH, $date); - // TODO: refactoring in progress... - $period2 = new ttPeriod(INTERVAL_THIS_MONTH, $date); $sql = "select sum(time_to_sec(duration)) as sm from tt_log". " where user_id = $user_id and group_id = $group_id and org_id = $org_id". " and date >= '".$period->getStartDate(DB_DATEFORMAT)."' and date <= '".$period->getEndDate(DB_DATEFORMAT)."' and status = 1"; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 320fa623d..e6ed7ed71 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -436,7 +436,7 @@ function isDateLocked($date) // Calculate the last occurrence of a lock. $last = tdCron::getLastOccurrence($this->getLockSpec(), time()); - $lockdate = new DateAndTime(DB_DATEFORMAT, strftime('%Y-%m-%d', $last)); + $lockdate = new ttDate(strftime('%Y-%m-%d', $last)); if ($date->before($lockdate)) return true; diff --git a/initialize.php b/initialize.php index e6223498a..588dbac7c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5628"); +define("APP_VERSION", "1.20.0.5629"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index b20308974..b4dcd84e7 100644 --- a/time.php +++ b/time.php @@ -75,24 +75,13 @@ // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); +$selected_date = new ttDate($cl_date); +if (!$selected_date->isValid()) + $selected_date = new ttDate(); if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); + $cl_date = $selected_date->toString(); $_SESSION['date'] = $cl_date; -// Refactoring in progress for php8.1. -// TODO: remove the above block when done. -// Also replace all occurrences of $selected_date2 with $selected_date. -$selected_date2 = new ttDate($cl_date); -if (!$selected_date2->isValid()) - $selected_date2 = new ttDate(); -if(!$cl_date) - $cl_date = $selected_date2->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; -// End of TODO. - // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); @@ -125,9 +114,9 @@ if ($user->isPluginEnabled('mq')){ require_once('plugins/MonthlyQuota.class.php'); $quota = new MonthlyQuota(); - $month_quota_minutes = $quota->getUserQuota($selected_date2->year, $selected_date2->month); - $quota_minutes_from_1st = $quota->getUserQuotaFrom1st($selected_date2); - $month_total = ttTimeHelper::getTimeForMonth2($selected_date2); + $month_quota_minutes = $quota->getUserQuota($selected_date->year, $selected_date->month); + $quota_minutes_from_1st = $quota->getUserQuotaFrom1st($selected_date); + $month_total = ttTimeHelper::getTimeForMonth2($selected_date); $month_total_minutes = ttTimeHelper::toMinutes($month_total); $balance_left = $quota_minutes_from_1st - $month_total_minutes; $minutes_left = $month_quota_minutes - $month_total_minutes; @@ -406,7 +395,7 @@ // Prohibit creating entries in future. if (!$user->isOptionEnabled('future_entries')) { $browser_today = new ttDate($request->getParameter('browser_today', null)); - if ($selected_date2->after($browser_today)) + if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); } @@ -491,7 +480,7 @@ } } // isPost -$week_total = ttTimeHelper::getTimeForWeek($selected_date); +$week_total = ttTimeHelper::getTimeForWeek2($selected_date); $timeRecords = ttTimeHelper::getRecords($cl_date, $showFiles); $showNavigation = ($user->isPluginEnabled('wv') && !$user->isOptionEnabled('week_menu')) || ($user->isPluginEnabled('pu') && !$user->isOptionEnabled('puncher_menu')); From 98534ea6d695fb4fe5f606d9352d0e259f7733d6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 17 Feb 2022 14:14:33 +0000 Subject: [PATCH 1651/1848] Refactoring for php8.1. --- WEB-INF/lib/common.lib.php | 3 +-- WEB-INF/lib/ttPeriod.class.php | 6 +++--- WEB-INF/lib/ttUser.class.php | 2 +- initialize.php | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 05a06808f..fcc36ed40 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -256,8 +256,7 @@ function ttValidDate($val) // ttValidDbDateFormatDate is used to check user input to validate a date in DB_DATEFORMAT. function ttValidDbDateFormatDate($val) { - $val = trim($val); - if (strlen($val) == 0) + if (is_null($val) || strlen($val) == 0) return false; // This should validate a string in format 'YYYY-MM-DD'. diff --git a/WEB-INF/lib/ttPeriod.class.php b/WEB-INF/lib/ttPeriod.class.php index 1d4b2c4d6..077aff278 100644 --- a/WEB-INF/lib/ttPeriod.class.php +++ b/WEB-INF/lib/ttPeriod.class.php @@ -24,9 +24,9 @@ function __construct($period_type = INTERVAL_THIS_MONTH, $ttDateInstance) { switch ($period_type) { case INTERVAL_THIS_WEEK: - $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+$startWeekBias,$t_arr[5])); - $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+6+$startWeekBias,$t_arr[5])); - break; + $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+$startWeekBias,$t_arr[5])); + $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+6+$startWeekBias,$t_arr[5])); + break; case INTERVAL_THIS_MONTH: $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,1,$t_arr[5])); diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index e6ed7ed71..93e71116a 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -297,7 +297,7 @@ function isClient() { // isPluginEnabled checks whether a plugin is enabled for user. function isPluginEnabled($plugin) { - return in_array($plugin, explode(',', $this->getPlugins())); + return in_array($plugin, explode(',', $this->getPlugins() ? $this->getPlugins() : '')); } // isOptionEnabled checks whether a config option is enabled for user. diff --git a/initialize.php b/initialize.php index 588dbac7c..9514cc4a1 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5629"); +define("APP_VERSION", "1.20.0.5630"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 6c9cddd745b7aa9a985d596633762320a5586d8b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 17 Feb 2022 14:54:42 +0000 Subject: [PATCH 1652/1848] Started refactoring Calendar.class.php for php8.1. --- WEB-INF/lib/form/Calendar.class.php | 10 ++++++---- WEB-INF/lib/ttDate.class.php | 7 +++++++ initialize.php | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index 337737f1c..02a6d0845 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -64,20 +64,22 @@ function getHtml() { global $user; $selectedDate = $this->value; - if (!$selectedDate) $selectedDate = strftime(DB_DATEFORMAT); // Determine month and year for selected date. - $selectedDateObject = new DateAndTime(DB_DATEFORMAT, $selectedDate); + $selectedDateObject = new ttDate($selectedDate); $selectedMonth = $selectedDateObject->getMonth(); $selectedYear = $selectedDateObject->getYear(); // Determine date for the 1st of next month for calendar navigation. $firstOfNextMonth2AM = mktime(2, 0, 0, $selectedMonth + 1, 1, $selectedYear); // 2 am on the 1st of next month. - $firstOfNextMonth = strftime(DB_DATEFORMAT, $firstOfNextMonth2AM); + $ttDateObject = new ttDate(); + $ttDateObject->setFromUnixTimestamp($firstOfNextMonth2AM); + $firstOfNextMonth = $ttDateObject->toString(); // Determine date for the 1st of previous month. $firstOfPreviousMonth2AM = mktime(2, 0, 0, $selectedMonth - 1, 1, $selectedYear); // 2 am on the 1st of previous month. - $firstOfPreviousMonth = strftime(DB_DATEFORMAT, $firstOfPreviousMonth2AM); + $ttDateObject->setFromUnixTimestamp($firstOfPreviousMonth2AM); + $firstOfPreviousMonth = $ttDateObject->toString(); // Print calendar header. $html = "\n\n\n"; diff --git a/WEB-INF/lib/ttDate.class.php b/WEB-INF/lib/ttDate.class.php index 791a1e942..f2ae46226 100644 --- a/WEB-INF/lib/ttDate.class.php +++ b/WEB-INF/lib/ttDate.class.php @@ -102,4 +102,11 @@ function after(/*ttDate*/ $obj) { if ($this->getTimestamp() > $obj->getTimestamp()) return true; return false; } + + + // Geters. + function getYear() { return $this->year; } + function getMonth() { return $this->month; } + function getDay() { return $this->day; } + function getDayOfWeek() { return $this->dayOfWeek; } } diff --git a/initialize.php b/initialize.php index 9514cc4a1..f98d2cb39 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5630"); +define("APP_VERSION", "1.20.0.5631"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 22d3a95aee4e07b29f9b8bd282faa0c595c2a7c5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 17 Feb 2022 21:44:54 +0000 Subject: [PATCH 1653/1848] More refactoring for php8.1 support. --- WEB-INF/lib/common.lib.php | 4 +++- WEB-INF/lib/form/Calendar.class.php | 8 ++++---- WEB-INF/lib/ttDate.class.php | 15 +++++++++++++++ WEB-INF/lib/ttPeriod.class.php | 2 +- WEB-INF/lib/ttTimeHelper.class.php | 4 ++-- initialize.php | 2 +- 6 files changed, 26 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index fcc36ed40..cabf62621 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -128,7 +128,9 @@ function isTrue($val) // ttValidString is used to check user input to validate a string. function ttValidString($val, $emptyValid = false) { - $val = trim($val); + if(!is_null($val)) + $val = trim($val); + if (strlen($val) == 0 && !$emptyValid) return false; diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index 02a6d0845..af32eea1d 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -157,14 +157,14 @@ function getHtml() { } // Handle selected day. - if ($selectedDate == strftime(DB_DATEFORMAT, $cellDate0am)) + if ($selectedDate == ttDate::dateFromUnixTimestamp($cellDate0am)) $cell_style = ' class="calendarDaySelected"'; $html .= ''; // Handle days with existing entries. if ($active_dates) { // Entries exist. - if (in_array(strftime(DB_DATEFORMAT, $cellDate0am), $active_dates)) { + if (in_array(ttDate::dateFromUnixTimestamp($cellDate0am), $active_dates)) { if ($handleNotCompleteDays && $this->highlight == 'time') { $day_total_minutes = ttTimeHelper::toMinutes(ttTimeHelper::getTimeForDay($date_to_check)); if ($day_total_minutes >= $workday_minutes) @@ -176,7 +176,7 @@ function getHtml() { $link_style = ' class="calendarLinkRecordsExist"'; } } - $html .= "name."=".strftime(DB_DATEFORMAT, $cellDate0am)."\" tabindex=\"-1\">".date("d",$cellDate0am).""; + $html .= "name."=".ttDate::dateFromUnixTimestamp($cellDate0am)."\" tabindex=\"-1\">".date("d",$cellDate0am).""; $html .= "
 
name."=".strftime(DB_DATEFORMAT)."\" tabindex=\"-1\">".$i18n->get('label.today')."
name."=".ttDate::dateFromUnixTimestamp()."\" tabindex=\"-1\">".$i18n->get('label.today')."
\n"; // Add a hidden control for selected date. diff --git a/WEB-INF/lib/ttDate.class.php b/WEB-INF/lib/ttDate.class.php index f2ae46226..fcf58e60c 100644 --- a/WEB-INF/lib/ttDate.class.php +++ b/WEB-INF/lib/ttDate.class.php @@ -109,4 +109,19 @@ function getYear() { return $this->year; } function getMonth() { return $this->month; } function getDay() { return $this->day; } function getDayOfWeek() { return $this->dayOfWeek; } + + + // A static function to obtain a date in DB_DATEFORMAT from a Unix timestamp. + static function dateFromUnixTimestamp($unixTimestamp = null) { + if ($unixTimestamp == null) { + $today = date_create(); + return date_format($today, 'Y-m-d'); + } + + $year = date('Y', $unixTimestamp); + $month = date('m', $unixTimestamp); + $day = date('d', $unixTimestamp); + $dateInDbFormat = $year.'-'.$month.'-'.$day; + return $dateInDbFormat; + } } diff --git a/WEB-INF/lib/ttPeriod.class.php b/WEB-INF/lib/ttPeriod.class.php index 077aff278..3eb431cc4 100644 --- a/WEB-INF/lib/ttPeriod.class.php +++ b/WEB-INF/lib/ttPeriod.class.php @@ -10,7 +10,7 @@ class ttPeriod { var $endDate; // ttDate object. - function __construct($period_type = INTERVAL_THIS_MONTH, $ttDateInstance) { + function __construct($ttDateInstance, $period_type = INTERVAL_THIS_MONTH) { global $user; $weekStartDay = $user->getWeekStart(); diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 604724160..b45c6d17f 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -613,7 +613,7 @@ static function getTimeForWeek2($date) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $period = new ttPeriod(INTERVAL_THIS_WEEK, $date); + $period = new ttPeriod($date, INTERVAL_THIS_WEEK); $sql = "select sum(time_to_sec(duration)) as sm from tt_log". " where user_id = $user_id and group_id = $group_id and org_id = $org_id". " and date >= '".$period->getStartDate()."' and date <= '".$period->getEndDate()."' and status = 1"; @@ -659,7 +659,7 @@ static function getTimeForMonth2($date) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $period = new ttPeriod(INTERVAL_THIS_MONTH, $date); + $period = new ttPeriod($date, INTERVAL_THIS_MONTH); $sql = "select sum(time_to_sec(duration)) as sm from tt_log". " where user_id = $user_id and group_id = $group_id and org_id = $org_id". " and date >= '".$period->getStartDate()."' and date <= '".$period->getEndDate()."' and status = 1"; diff --git a/initialize.php b/initialize.php index f98d2cb39..5874ba026 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5631"); +define("APP_VERSION", "1.20.0.5632"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From b33a06c5f0eb6ef32b0840f3219dfba1f8bcf426 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 19 Feb 2022 17:29:53 +0000 Subject: [PATCH 1654/1848] Fixed Calendar.class.php with a forgotten import. --- WEB-INF/lib/form/Calendar.class.php | 1 + WEB-INF/lib/ttDate.class.php | 2 +- initialize.php | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index af32eea1d..3f16ed597 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -28,6 +28,7 @@ import('form.FormElement'); import('DateAndTime'); +import('ttDate'); import('ttTimeHelper'); class Calendar extends FormElement { diff --git a/WEB-INF/lib/ttDate.class.php b/WEB-INF/lib/ttDate.class.php index fcf58e60c..1b5bad9c4 100644 --- a/WEB-INF/lib/ttDate.class.php +++ b/WEB-INF/lib/ttDate.class.php @@ -104,7 +104,7 @@ function after(/*ttDate*/ $obj) { } - // Geters. + // Getters. function getYear() { return $this->year; } function getMonth() { return $this->month; } function getDay() { return $this->day; } diff --git a/initialize.php b/initialize.php index 5874ba026..29789ed1a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5632"); +define("APP_VERSION", "1.20.0.5633"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From eb3210f9fdd97c1a220b874ab2bf73efdc280029 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 19 Feb 2022 19:51:24 +0000 Subject: [PATCH 1655/1848] Added a missing import to ttUser.class.php. --- WEB-INF/lib/ttUser.class.php | 1 + initialize.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 93e71116a..592b5d9c8 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -9,6 +9,7 @@ import('form.Form'); import('form.ActionForm'); import('ttTemplateHelper'); +import('ttDate'); class ttUser { var $login = null; // User login. diff --git a/initialize.php b/initialize.php index 29789ed1a..03294184b 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5633"); +define("APP_VERSION", "1.20.0.5634"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 042398a7f8f0322eb2caa002360172b31c2d2f78 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 19 Feb 2022 21:23:00 +0000 Subject: [PATCH 1656/1848] Fixed adjusting fav report options for changed user role. --- WEB-INF/lib/ttFavReportHelper.class.php | 11 ++++++++++- initialize.php | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index be23f6a39..303750d63 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -473,6 +473,7 @@ static function adjustOptions($options) { } } else { $users_to_adjust = explode(',', $options['users']); // Users to adjust. + // Adjust user list for a client. if ($user->isClient()) { $users = ttGroupHelper::getUsersForClient(); // Active and inactive users for clients. foreach ($users as $single_user) { @@ -485,7 +486,15 @@ static function adjustOptions($options) { } $options['users'] = implode(',', $adjusted_user_ids); } - // TODO: add checking the existing user list for potentially changed access rights for user. + // Reset user list for a role that no longer has view_reports or view_all_reports rights. + if (!($user->can('view_reports') || $user->can('view_all_reports'))) { + $options['users'] = null; + // Also remove grouping by user if we can't do it. + if (isset($options['group_by1']) && $options['group_by1'] == 'user') unset($options['group_by1']); + if (isset($options['group_by2']) && $options['group_by2'] == 'user') unset($options['group_by2']); + if (isset($options['group_by3']) && $options['group_by3'] == 'user') unset($options['group_by3']); + } + // TODO: improve checking the existing user list for potentially changed access rights for user. } if ($user->isPluginEnabled('ap') && $user->isClient() && !$user->can('view_client_unapproved')) diff --git a/initialize.php b/initialize.php index 03294184b..09344a542 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5634"); +define("APP_VERSION", "1.20.0.5635"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 8e8321a78d7dd9c341f7253a18d324a74b039cfc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 20 Feb 2022 12:54:19 +0000 Subject: [PATCH 1657/1848] Addressed a php warning. --- WEB-INF/lib/ttReportHelper.class.php | 5 +++-- initialize.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index ffef6e773..20e6d7a46 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -693,6 +693,8 @@ static function getSubtotals($options) { // Execute query. $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die($res->getMessage()); + + $subtotals = array(); while ($val = $res->fetchRow()) { $time = ttTimeHelper::minutesToDuration($val['time'] / 60); $rowLabel = ttReportHelper::makeGroupByLabel($val['group_field'], $options); @@ -1014,8 +1016,7 @@ static function prepareReportBody($options, $comment = null) $items = ttReportHelper::getItems($options); $grouping = ttReportHelper::grouping($options); - if ($grouping) - $subtotals = ttReportHelper::getSubtotals($options); + $subtotals = $grouping ? ttReportHelper::getSubtotals($options) : array(); $totals = ttReportHelper::getTotals($options); // Use custom fields plugin if it is enabled. diff --git a/initialize.php b/initialize.php index 09344a542..e06256f06 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5635"); +define("APP_VERSION", "1.20.0.5636"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 4f95a311ebc6ec1092ad572a4dc2b59ad58a3a79 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 20 Feb 2022 15:20:18 +0000 Subject: [PATCH 1658/1848] Some refactoring in Calendar class. --- WEB-INF/lib/form/Calendar.class.php | 8 ++------ initialize.php | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index 3f16ed597..072b48281 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -27,7 +27,6 @@ // +----------------------------------------------------------------------+ import('form.FormElement'); -import('DateAndTime'); import('ttDate'); import('ttTimeHelper'); @@ -73,14 +72,11 @@ function getHtml() { // Determine date for the 1st of next month for calendar navigation. $firstOfNextMonth2AM = mktime(2, 0, 0, $selectedMonth + 1, 1, $selectedYear); // 2 am on the 1st of next month. - $ttDateObject = new ttDate(); - $ttDateObject->setFromUnixTimestamp($firstOfNextMonth2AM); - $firstOfNextMonth = $ttDateObject->toString(); + $firstOfNextMonth = ttDate::dateFromUnixTimestamp($firstOfNextMonth2AM); // Determine date for the 1st of previous month. $firstOfPreviousMonth2AM = mktime(2, 0, 0, $selectedMonth - 1, 1, $selectedYear); // 2 am on the 1st of previous month. - $ttDateObject->setFromUnixTimestamp($firstOfPreviousMonth2AM); - $firstOfPreviousMonth = $ttDateObject->toString(); + $firstOfPreviousMonth = ttDate::dateFromUnixTimestamp($firstOfPreviousMonth2AM); // Print calendar header. $html = "\n\n\n"; diff --git a/initialize.php b/initialize.php index e06256f06..aa92c01e2 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5636"); +define("APP_VERSION", "1.20.0.5637"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 28c91182fc500cd9c4a77ada70a24151c6afd7b2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 20 Feb 2022 15:46:25 +0000 Subject: [PATCH 1659/1848] Resumed refactoring for php8.1. --- WEB-INF/lib/common.lib.php | 10 ++++++---- initialize.php | 2 +- time.php | 1 - 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index cabf62621..d8ed3c8d5 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -128,16 +128,18 @@ function isTrue($val) // ttValidString is used to check user input to validate a string. function ttValidString($val, $emptyValid = false) { - if(!is_null($val)) - $val = trim($val); + if (is_null($val)) { + return $emptyValid ? true : false; + } + $val = trim($val); if (strlen($val) == 0 && !$emptyValid) return false; - + // String must not be XSS evil (to insert JavaScript). if (stristr($val, ''; + return ''; } elseif ($encode === 'javascript_charcode') { $string = '' . $text . ''; - for ($x = 0, $y = strlen($string); $x < $y; $x++) { + for ($x = 0, $_length = strlen($string); $x < $_length; $x++) { $ord[] = ord($string[ $x ]); } - $_ret = "\n"; - return $_ret; + return ''; } elseif ($encode === 'hex') { preg_match('!^(.*)(\?.*)$!', $address, $match); if (!empty($match[ 2 ])) { diff --git a/WEB-INF/lib/smarty/plugins/function.math.php b/WEB-INF/lib/smarty/plugins/function.math.php index 7348d9649..fd5b3d166 100644 --- a/WEB-INF/lib/smarty/plugins/function.math.php +++ b/WEB-INF/lib/smarty/plugins/function.math.php @@ -12,7 +12,7 @@ * Name: math * Purpose: handle math computations in template * - * @link http://www.smarty.net/manual/en/language.function.math.php {math} + * @link https://www.smarty.net/manual/en/language.function.math.php {math} * (Smarty online manual) * @author Monte Ohrt * @@ -28,7 +28,12 @@ function smarty_function_math($params, $template) 'int' => true, 'abs' => true, 'ceil' => true, + 'acos' => true, + 'acosh' => true, 'cos' => true, + 'cosh' => true, + 'deg2rad' => true, + 'rad2deg' => true, 'exp' => true, 'floor' => true, 'log' => true, @@ -39,27 +44,51 @@ function smarty_function_math($params, $template) 'pow' => true, 'rand' => true, 'round' => true, + 'asin' => true, + 'asinh' => true, 'sin' => true, + 'sinh' => true, 'sqrt' => true, 'srand' => true, - 'tan' => true + 'atan' => true, + 'atanh' => true, + 'tan' => true, + 'tanh' => true ); + // be sure equation parameter is present if (empty($params[ 'equation' ])) { trigger_error("math: missing equation parameter", E_USER_WARNING); return; } $equation = $params[ 'equation' ]; + + // Remove whitespaces + $equation = preg_replace('/\s+/', '', $equation); + + // Adapted from https://www.php.net/manual/en/function.eval.php#107377 + $number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number + $functionsOrVars = '((?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))'; + $operators = '[+\/*\^%-]'; // Allowed math operators + $regexp = '/^(('.$number.'|'.$functionsOrVars.'|('.$functionsOrVars.'\s*\((?1)+\)|\((?1)+\)))(?:'.$operators.'(?1))?)+$/'; + + if (!preg_match($regexp, $equation)) { + trigger_error("math: illegal characters", E_USER_WARNING); + return; + } + // make sure parenthesis are balanced if (substr_count($equation, '(') !== substr_count($equation, ')')) { trigger_error("math: unbalanced parenthesis", E_USER_WARNING); return; } + // disallow backticks if (strpos($equation, '`') !== false) { trigger_error("math: backtick character not allowed in equation", E_USER_WARNING); return; } + // also disallow dollar signs if (strpos($equation, '$') !== false) { trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING); @@ -96,6 +125,7 @@ function smarty_function_math($params, $template) } $smarty_math_result = null; eval("\$smarty_math_result = " . $equation . ";"); + if (empty($params[ 'format' ])) { if (empty($params[ 'assign' ])) { return $smarty_math_result; diff --git a/WEB-INF/lib/smarty/plugins/modifier.date_format.php b/WEB-INF/lib/smarty/plugins/modifier.date_format.php index c8e88c5c9..8e7e0b6e1 100644 --- a/WEB-INF/lib/smarty/plugins/modifier.date_format.php +++ b/WEB-INF/lib/smarty/plugins/modifier.date_format.php @@ -15,7 +15,7 @@ * - format: strftime format for output * - default_date: default date if $string is empty * - * @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual) + * @link https://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual) * @author Monte Ohrt * * @param string $string input date string diff --git a/WEB-INF/lib/smarty/plugins/modifier.escape.php b/WEB-INF/lib/smarty/plugins/modifier.escape.php index 150901c7c..47489aa98 100644 --- a/WEB-INF/lib/smarty/plugins/modifier.escape.php +++ b/WEB-INF/lib/smarty/plugins/modifier.escape.php @@ -11,7 +11,7 @@ * Name: escape * Purpose: escape string for output * - * @link http://www.smarty.net/docs/en/language.modifier.escape + * @link https://www.smarty.net/docs/en/language.modifier.escape * @author Monte Ohrt * * @param string $string input string @@ -23,12 +23,9 @@ */ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) { - static $_double_encode = null; + static $_double_encode = true; static $is_loaded_1 = false; static $is_loaded_2 = false; - if ($_double_encode === null) { - $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>='); - } if (!$char_set) { $char_set = Smarty::$_CHARSET; } @@ -184,7 +181,11 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $ '"' => '\\"', "\r" => '\\r', "\n" => '\\n', - ' '<\/' + ' '<\/', + // see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements + '#ms', '', $source); // capture html elements not to be messed with $_offset = 0; diff --git a/WEB-INF/lib/smarty/plugins/shared.escape_special_chars.php b/WEB-INF/lib/smarty/plugins/shared.escape_special_chars.php index 6b18d3eec..a204b092c 100644 --- a/WEB-INF/lib/smarty/plugins/shared.escape_special_chars.php +++ b/WEB-INF/lib/smarty/plugins/shared.escape_special_chars.php @@ -20,13 +20,7 @@ function smarty_function_escape_special_chars($string) { if (!is_array($string)) { - if (version_compare(PHP_VERSION, '5.2.3', '>=')) { - $string = htmlspecialchars($string, ENT_COMPAT, Smarty::$_CHARSET, false); - } else { - $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); - $string = htmlspecialchars($string); - $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); - } + $string = htmlspecialchars($string, ENT_COMPAT, Smarty::$_CHARSET, false); } return $string; } diff --git a/WEB-INF/lib/smarty/plugins/shared.mb_str_replace.php b/WEB-INF/lib/smarty/plugins/shared.mb_str_replace.php index 206cf9ea6..226d9035d 100644 --- a/WEB-INF/lib/smarty/plugins/shared.mb_str_replace.php +++ b/WEB-INF/lib/smarty/plugins/shared.mb_str_replace.php @@ -44,7 +44,7 @@ function smarty_mb_str_replace($search, $replace, $subject, &$count = 0) } } } else { - $parts = mb_split(preg_quote($search), $subject); + $parts = mb_split(preg_quote($search), $subject) ?: array(); $count = count($parts) - 1; $subject = implode($replace, $parts); } diff --git a/WEB-INF/lib/smarty/readme b/WEB-INF/lib/smarty/readme new file mode 100644 index 000000000..91eff4784 --- /dev/null +++ b/WEB-INF/lib/smarty/readme @@ -0,0 +1,8 @@ +These are files from Smarty-4.1.0 with 2 modifications in: + +Smarty.class.php +sysplugins/smarty_internal_cacheresource_file.php + +Nik edited these files for php5.4 support, as they use php7.0 features. + + diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_cacheresource_file.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_cacheresource_file.php index 61618449d..f6879bc76 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_cacheresource_file.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_cacheresource_file.php @@ -196,12 +196,8 @@ public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $e */ public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) { - if (version_compare(PHP_VERSION, '5.3.0', '>=')) { - clearstatcache(true, $cached->lock_id); - } else { - clearstatcache(); - } - if (is_file($cached->lock_id)) { + clearstatcache(true, $cached->lock_id ?: ''); + if (null !== $cached->lock_id && is_file($cached->lock_id)) { $t = filemtime($cached->lock_id); return $t && (time() - $t < $smarty->locking_timeout); } else { diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_for.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_for.php index 3f113e56d..969e22c1a 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_for.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_for.php @@ -18,7 +18,7 @@ class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase { /** * Compiles code for the {for} tag - * Smarty 3 does implement two different syntax's: + * Smarty supports two different syntax's: * - {for $var in $array} * For looping over arrays or iterators * - {for $x=0; $x<$y; $x++} diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_foreach.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_foreach.php index a68da5409..edfe358be 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_foreach.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_foreach.php @@ -219,9 +219,9 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler) if (isset($itemAttr[ 'index' ])) { $output .= "{$itemVar}->index = -1;\n"; } - $output .= "{$itemVar}->do_else = true;\n"; + $output .= "{$itemVar}->do_else = true;\n"; $output .= "if (\$_from !== null) foreach (\$_from as {$keyTerm}{$itemVar}->value) {\n"; - $output .= "{$itemVar}->do_else = false;\n"; + $output .= "{$itemVar}->do_else = false;\n"; if (isset($attributes[ 'key' ]) && isset($itemAttr[ 'key' ])) { $output .= "\$_smarty_tpl->tpl_vars['{$key}']->value = {$itemVar}->key;\n"; } diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php index d0f2b0f4a..84e9584d9 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php @@ -157,7 +157,7 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler) $output = "template->compiled->nocache_hash}%%*/smarty->ext->_tplFunction->restoreTemplateVariables(\\\$_smarty_tpl, '{$_name}');?>\n"; $output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\";\n?>"; - $output .= "template->compiled->nocache_hash}', \$_smarty_tpl->compiled->nocache_hash, ob_get_clean());\n"; + $output .= "template->compiled->nocache_hash}', \$_smarty_tpl->compiled->nocache_hash ?? '', ob_get_clean());\n"; $output .= "}\n}\n"; $output .= "/*/ {$_funcName}_nocache */\n\n"; $output .= "?>\n"; diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_include_php.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_include_php.php deleted file mode 100644 index 1b0fdaad3..000000000 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_include_php.php +++ /dev/null @@ -1,110 +0,0 @@ -smarty instanceof SmartyBC)) { - throw new SmartyException("{include_php} is deprecated, use SmartyBC class to enable"); - } - // check and get attributes - $_attr = $this->getAttributes($compiler, $args); - /** - * - * - * @var Smarty_Internal_Template $_smarty_tpl - * used in evaluated code - */ - $_smarty_tpl = $compiler->template; - $_filepath = false; - $_file = null; - eval('$_file = @' . $_attr[ 'file' ] . ';'); - if (!isset($compiler->smarty->security_policy) && file_exists($_file)) { - $_filepath = $compiler->smarty->_realpath($_file, true); - } else { - if (isset($compiler->smarty->security_policy)) { - $_dir = $compiler->smarty->security_policy->trusted_dir; - } else { - $_dir = $compiler->smarty->trusted_dir; - } - if (!empty($_dir)) { - foreach ((array)$_dir as $_script_dir) { - $_path = $compiler->smarty->_realpath($_script_dir . DIRECTORY_SEPARATOR . $_file, true); - if (file_exists($_path)) { - $_filepath = $_path; - break; - } - } - } - } - if ($_filepath === false) { - $compiler->trigger_template_error("{include_php} file '{$_file}' is not readable", null, true); - } - if (isset($compiler->smarty->security_policy)) { - $compiler->smarty->security_policy->isTrustedPHPDir($_filepath); - } - if (isset($_attr[ 'assign' ])) { - // output will be stored in a smarty variable instead of being displayed - $_assign = $_attr[ 'assign' ]; - } - $_once = '_once'; - if (isset($_attr[ 'once' ])) { - if ($_attr[ 'once' ] === 'false') { - $_once = ''; - } - } - if (isset($_assign)) { - return "assign({$_assign},ob_get_clean());\n?>"; - } else { - return "\n"; - } - } -} diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_insert.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_insert.php index 4bdc3952e..c91ff62cb 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_insert.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_insert.php @@ -89,7 +89,7 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler) if (isset($compiler->smarty->security_policy)) { $_dir = $compiler->smarty->security_policy->trusted_dir; } else { - $_dir = $compiler->smarty instanceof SmartyBC ? $compiler->smarty->trusted_dir : null; + $_dir = null; } if (!empty($_dir)) { foreach ((array)$_dir as $_script_dir) { diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_php.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_php.php deleted file mode 100644 index ff48c6fbc..000000000 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_php.php +++ /dev/null @@ -1,253 +0,0 @@ -getAttributes($compiler, $args); - $compiler->has_code = false; - if ($_attr[ 'type' ] === 'xml') { - $compiler->tag_nocache = true; - $output = addcslashes($_attr[ 'code' ], "'\\"); - $compiler->parser->current_buffer->append_subtree( - $compiler->parser, - new Smarty_Internal_ParseTree_Tag( - $compiler->parser, - $compiler->processNocacheCode( - "\n", - true - ) - ) - ); - return ''; - } - if ($_attr[ 'type' ] !== 'tag') { - if ($compiler->php_handling === Smarty::PHP_REMOVE) { - return ''; - } elseif ($compiler->php_handling === Smarty::PHP_QUOTE) { - $output = - preg_replace_callback( - '#(<\?(?:php|=)?)|(<%)|()|(\?>)|(%>)|(<\/script>)#i', - array($this, 'quote'), - $_attr[ 'code' ] - ); - $compiler->parser->current_buffer->append_subtree( - $compiler->parser, - new Smarty_Internal_ParseTree_Text($output) - ); - return ''; - } elseif ($compiler->php_handling === Smarty::PHP_PASSTHRU || $_attr[ 'type' ] === 'unmatched') { - $compiler->tag_nocache = true; - $output = addcslashes($_attr[ 'code' ], "'\\"); - $compiler->parser->current_buffer->append_subtree( - $compiler->parser, - new Smarty_Internal_ParseTree_Tag( - $compiler->parser, - $compiler->processNocacheCode( - "\n", - true - ) - ) - ); - return ''; - } elseif ($compiler->php_handling === Smarty::PHP_ALLOW) { - if (!($compiler->smarty instanceof SmartyBC)) { - $compiler->trigger_template_error( - '$smarty->php_handling PHP_ALLOW not allowed. Use SmartyBC to enable it', - null, - true - ); - } - $compiler->has_code = true; - return $_attr[ 'code' ]; - } else { - $compiler->trigger_template_error('Illegal $smarty->php_handling value', null, true); - } - } else { - $compiler->has_code = true; - if (!($compiler->smarty instanceof SmartyBC)) { - $compiler->trigger_template_error( - '{php}{/php} tags not allowed. Use SmartyBC to enable them', - null, - true - ); - } - $ldel = preg_quote($compiler->smarty->left_delimiter, '#'); - $rdel = preg_quote($compiler->smarty->right_delimiter, '#'); - preg_match("#^({$ldel}php\\s*)((.)*?)({$rdel})#", $_attr[ 'code' ], $match); - if (!empty($match[ 2 ])) { - if ('nocache' === trim($match[ 2 ])) { - $compiler->tag_nocache = true; - } else { - $compiler->trigger_template_error("illegal value of option flag '{$match[2]}'", null, true); - } - } - return preg_replace( - array("#^{$ldel}\\s*php\\s*(.)*?{$rdel}#", "#{$ldel}\\s*/\\s*php\\s*{$rdel}$#"), - array(''), - $_attr[ 'code' ] - ); - } - } - - /** - * Lexer code for PHP tags - * - * This code has been moved from lexer here fo easier debugging and maintenance - * - * @param Smarty_Internal_Templatelexer $lex - * - * @throws \SmartyCompilerException - */ - public function parsePhp(Smarty_Internal_Templatelexer $lex) - { - $lex->token = Smarty_Internal_Templateparser::TP_PHP; - $close = 0; - $lex->taglineno = $lex->line; - $closeTag = '?>'; - if (strpos($lex->value, 'is_xml = true; - $lex->phpType = 'xml'; - return; - } elseif (strpos($lex->value, 'phpType = 'php'; - } elseif (strpos($lex->value, '<%') === 0) { - $lex->phpType = 'asp'; - $closeTag = '%>'; - } elseif (strpos($lex->value, '%>') === 0) { - $lex->phpType = 'unmatched'; - } elseif (strpos($lex->value, '?>') === 0) { - if ($lex->is_xml) { - $lex->is_xml = false; - $lex->phpType = 'xml'; - return; - } - $lex->phpType = 'unmatched'; - } elseif (strpos($lex->value, 'phpType = 'script'; - $closeTag = ''; - } elseif (strpos($lex->value, $lex->smarty->left_delimiter) === 0) { - if ($lex->isAutoLiteral()) { - $lex->token = Smarty_Internal_Templateparser::TP_TEXT; - return; - } - $closeTag = "{$lex->smarty->left_delimiter}/php{$lex->smarty->right_delimiter}"; - if ($lex->value === $closeTag) { - $lex->compiler->trigger_template_error("unexpected closing tag '{$closeTag}'"); - } - $lex->phpType = 'tag'; - } - if ($lex->phpType === 'unmatched') { - return; - } - if (($lex->phpType === 'php' || $lex->phpType === 'asp') - && - ($lex->compiler->php_handling === Smarty::PHP_PASSTHRU || - $lex->compiler->php_handling === Smarty::PHP_QUOTE) - ) { - return; - } - $start = $lex->counter + strlen($lex->value); - $body = true; - if (preg_match('~' . preg_quote($closeTag, '~') . '~i', $lex->data, $match, PREG_OFFSET_CAPTURE, $start)) { - $close = $match[ 0 ][ 1 ]; - } else { - $lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'"); - } - while ($body) { - if (preg_match( - '~([/][*])|([/][/][^\n]*)|(\'[^\'\\\\]*(?:\\.[^\'\\\\]*)*\')|("[^"\\\\]*(?:\\.[^"\\\\]*)*")~', - $lex->data, - $match, - PREG_OFFSET_CAPTURE, - $start - ) - ) { - $value = $match[ 0 ][ 0 ]; - $from = $pos = $match[ 0 ][ 1 ]; - if ($pos > $close) { - $body = false; - } else { - $start = $pos + strlen($value); - $phpCommentStart = $value === '/*'; - if ($phpCommentStart) { - $phpCommentEnd = preg_match('~([*][/])~', $lex->data, $match, PREG_OFFSET_CAPTURE, $start); - if ($phpCommentEnd) { - $pos2 = $match[ 0 ][ 1 ]; - $start = $pos2 + strlen($match[ 0 ][ 0 ]); - } - } - while ($close > $pos && $close < $start) { - if (preg_match( - '~' . preg_quote($closeTag, '~') . '~i', - $lex->data, - $match, - PREG_OFFSET_CAPTURE, - $from - ) - ) { - $close = $match[ 0 ][ 1 ]; - $from = $close + strlen($match[ 0 ][ 0 ]); - } else { - $lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'"); - } - } - if ($phpCommentStart && (!$phpCommentEnd || $pos2 > $close)) { - $lex->taglineno = $lex->line + substr_count(substr($lex->data, $lex->counter, $start), "\n"); - $lex->compiler->trigger_template_error("missing PHP comment closing tag '*/'"); - } - } - } else { - $body = false; - } - } - $lex->value = substr($lex->data, $lex->counter, $close + strlen($closeTag) - $lex->counter); - } - - /* - * Call back function for $php_handling = PHP_QUOTE - * - */ - /** - * @param $match - * - * @return string - */ - private function quote($match) - { - return htmlspecialchars($match[ 0 ], ENT_QUOTES); - } -} diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php index 90c5dcefa..a9b940e5a 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php @@ -158,7 +158,7 @@ public function compileTemplate(Smarty_Internal_Template $template) } // template header code $template_header = - "template->source->filepath}' */ ?>\n"; $code = 'smarty->ext->configLoad->_loadConfigVars($_smarty_tpl, ' . diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_data.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_data.php index 98e3e57b3..1b64185b8 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_data.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_data.php @@ -121,7 +121,7 @@ public function assign($tpl_var, $value = null, $nocache = false) * appends values to template variables * * @api Smarty::append() - * @link http://www.smarty.net/docs/en/api.append.tpl + * @link https://www.smarty.net/docs/en/api.append.tpl * * @param array|string $tpl_var the template variable name(s) * @param mixed $value the value to append @@ -182,7 +182,7 @@ public function assignByRef($tpl_var, &$value, $nocache = false) * Returns a single or all template variables * * @api Smarty::getTemplateVars() - * @link http://www.smarty.net/docs/en/api.get.template.vars.tpl + * @link https://www.smarty.net/docs/en/api.get.template.vars.tpl * * @param string $varName variable name or null * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $_ptr optional pointer to data object @@ -195,26 +195,6 @@ public function getTemplateVars($varName = null, Smarty_Internal_Data $_ptr = nu return $this->ext->getTemplateVars->getTemplateVars($this, $varName, $_ptr, $searchParents); } - /** - * gets the object of a Smarty variable - * - * @param string $variable the name of the Smarty variable - * @param Smarty_Internal_Data $_ptr optional pointer to data object - * @param boolean $searchParents search also in parent data - * @param bool $error_enable - * - * @return Smarty_Variable|Smarty_Undefined_Variable the object of the variable - * @deprecated since 3.1.28 please use Smarty_Internal_Data::getTemplateVars() instead. - */ - public function getVariable( - $variable = null, - Smarty_Internal_Data $_ptr = null, - $searchParents = true, - $error_enable = true - ) { - return $this->ext->getTemplateVars->_getVariable($this, $variable, $_ptr, $searchParents, $error_enable); - } - /** * Follow the parent chain an merge template and config variables * diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php index 56dca18fa..c2b653ef4 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php @@ -1,61 +1,60 @@ previousErrorHandler = set_error_handler([$this, 'handleError']); + } + + /** + * Disable error handler + */ + public function deactivate() { + restore_error_handler(); + $this->previousErrorHandler = null; } /** * Error Handler to mute expected messages * - * @link http://php.net/set_error_handler + * @link https://php.net/set_error_handler * * @param integer $errno Error level * @param $errstr @@ -65,49 +64,21 @@ public static function muteExpectedErrors() * * @return bool */ - public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext = array()) + public function handleError($errno, $errstr, $errfile, $errline, $errcontext = []) { - $_is_muted_directory = false; - // add the SMARTY_DIR to the list of muted directories - if (!isset(self::$mutedDirectories[ SMARTY_DIR ])) { - $smarty_dir = realpath(SMARTY_DIR); - if ($smarty_dir !== false) { - self::$mutedDirectories[ SMARTY_DIR ] = - array('file' => $smarty_dir, 'length' => strlen($smarty_dir),); - } + if ($this->allowUndefinedVars && $errstr == 'Attempt to read property "value" on null') { + return; // suppresses this error } - // walk the muted directories and test against $errfile - foreach (self::$mutedDirectories as $key => &$dir) { - if (!$dir) { - // resolve directory and length for speedy comparisons - $file = realpath($key); - if ($file === false) { - // this directory does not exist, remove and skip it - unset(self::$mutedDirectories[ $key ]); - continue; - } - $dir = array('file' => $file, 'length' => strlen($file),); - } - if (!strncmp($errfile, $dir[ 'file' ], $dir[ 'length' ])) { - $_is_muted_directory = true; - break; - } - } - // pass to next error handler if this error did not occur inside SMARTY_DIR - // or the error was within smarty but masked to be ignored - if (!$_is_muted_directory || ($errno && $errno & error_reporting())) { - if (self::$previousErrorHandler) { - return call_user_func( - self::$previousErrorHandler, - $errno, - $errstr, - $errfile, - $errline, - $errcontext - ); - } else { - return false; - } + + if ($this->allowUndefinedArrayKeys && preg_match( + '/^(Undefined array key|Trying to access array offset on value of type null)/', + $errstr + )) { + return; // suppresses this error } + + // pass all other errors through to the previous error handler or to the default PHP error handler + return $this->previousErrorHandler ? + call_user_func($this->previousErrorHandler, $errno, $errstr, $errfile, $errline, $errcontext) : false; } } diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_append.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_append.php index 881375efe..e207734e8 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_append.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_append.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_Append * appends values to template variables * * @api Smarty::append() - * @link http://www.smarty.net/docs/en/api.append.tpl + * @link https://www.smarty.net/docs/en/api.append.tpl * * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data * @param array|string $tpl_var the template variable name(s) diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_appendbyref.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_appendbyref.php index c95904460..b5be69b54 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_appendbyref.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_appendbyref.php @@ -15,7 +15,7 @@ class Smarty_Internal_Method_AppendByRef * appends values to template variables by reference * * @api Smarty::appendByRef() - * @link http://www.smarty.net/docs/en/api.append.by.ref.tpl + * @link https://www.smarty.net/docs/en/api.append.by.ref.tpl * * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data * @param string $tpl_var the template variable name diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearallassign.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearallassign.php index 29ff2ffb0..6fb0c8f3d 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearallassign.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearallassign.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearAllAssign * clear all the assigned template variables. * * @api Smarty::clearAllAssign() - * @link http://www.smarty.net/docs/en/api.clear.all.assign.tpl + * @link https://www.smarty.net/docs/en/api.clear.all.assign.tpl * * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data * diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearallcache.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearallcache.php index 30d55f7d2..b74d30580 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearallcache.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearallcache.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearAllCache * Empty cache folder * * @api Smarty::clearAllCache() - * @link http://www.smarty.net/docs/en/api.clear.all.cache.tpl + * @link https://www.smarty.net/docs/en/api.clear.all.cache.tpl * * @param \Smarty $smarty * @param integer $exp_time expiration time diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearassign.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearassign.php index 22bfa2d31..12b755c06 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearassign.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearassign.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearAssign * clear the given assigned template variable(s). * * @api Smarty::clearAssign() - * @link http://www.smarty.net/docs/en/api.clear.assign.tpl + * @link https://www.smarty.net/docs/en/api.clear.assign.tpl * * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data * @param string|array $tpl_var the template variable(s) to clear diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearcache.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearcache.php index a5dd4e26e..df766eee8 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearcache.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearcache.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearCache * Empty cache for a specific template * * @api Smarty::clearCache() - * @link http://www.smarty.net/docs/en/api.clear.cache.tpl + * @link https://www.smarty.net/docs/en/api.clear.cache.tpl * * @param \Smarty $smarty * @param string $template_name template name diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearcompiledtemplate.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearcompiledtemplate.php index bf4929807..db0a49b00 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearcompiledtemplate.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearcompiledtemplate.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearCompiledTemplate * Delete compiled template file * * @api Smarty::clearCompiledTemplate() - * @link http://www.smarty.net/docs/en/api.clear.compiled.template.tpl + * @link https://www.smarty.net/docs/en/api.clear.compiled.template.tpl * * @param \Smarty $smarty * @param string $resource_name template name diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearconfig.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearconfig.php index 15bf492a1..d1b730322 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearconfig.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_clearconfig.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_ClearConfig * clear a single or all config variables * * @api Smarty::clearConfig() - * @link http://www.smarty.net/docs/en/api.clear.config.tpl + * @link https://www.smarty.net/docs/en/api.clear.config.tpl * * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data * @param string|null $name variable name or null diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_configload.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_configload.php index 2e6254880..c3174d2d0 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_configload.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_configload.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_ConfigLoad * load a config file, optionally load just selected sections * * @api Smarty::configLoad() - * @link http://www.smarty.net/docs/en/api.config.load.tpl + * @link https://www.smarty.net/docs/en/api.config.load.tpl * * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data * @param string $config_file filename @@ -42,7 +42,7 @@ public function configLoad(Smarty_Internal_Data $data, $config_file, $sections = * load a config file, optionally load just selected sections * * @api Smarty::configLoad() - * @link http://www.smarty.net/docs/en/api.config.load.tpl + * @link https://www.smarty.net/docs/en/api.config.load.tpl * * @param \Smarty|\Smarty_Internal_Data|\Smarty_Internal_Template $data * @param string $config_file filename diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_createdata.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_createdata.php index f95097519..c684c0870 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_createdata.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_createdata.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_CreateData * creates a data object * * @api Smarty::createData() - * @link http://www.smarty.net/docs/en/api.create.data.tpl + * @link https://www.smarty.net/docs/en/api.create.data.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param \Smarty_Internal_Template|\Smarty_Internal_Data|\Smarty_Data|\Smarty $parent next higher level of Smarty diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_getconfigvars.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_getconfigvars.php index 1d11e44c1..763bdf989 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_getconfigvars.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_getconfigvars.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_GetConfigVars * Returns a single or all config variables * * @api Smarty::getConfigVars() - * @link http://www.smarty.net/docs/en/api.get.config.vars.tpl + * @link https://www.smarty.net/docs/en/api.get.config.vars.tpl * * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data * @param string $varname variable name or null diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_getregisteredobject.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_getregisteredobject.php index df6ede130..0b3a071d3 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_getregisteredobject.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_getregisteredobject.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_GetRegisteredObject * return a reference to a registered object * * @api Smarty::getRegisteredObject() - * @link http://www.smarty.net/docs/en/api.get.registered.object.tpl + * @link https://www.smarty.net/docs/en/api.get.registered.object.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $object_name object name diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_gettags.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_gettags.php index c07ae07ec..0d1335a8d 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_gettags.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_gettags.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_GetTags * Return array of tag/attributes of all tags used by an template * * @api Smarty::getTags() - * @link http://www.smarty.net/docs/en/api.get.tags.tpl + * @link https://www.smarty.net/docs/en/api.get.tags.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param null|string|Smarty_Internal_Template $template diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_gettemplatevars.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_gettemplatevars.php index 9ef7d46bb..0470785b1 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_gettemplatevars.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_gettemplatevars.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_GetTemplateVars * Returns a single or all template variables * * @api Smarty::getTemplateVars() - * @link http://www.smarty.net/docs/en/api.get.template.vars.tpl + * @link https://www.smarty.net/docs/en/api.get.template.vars.tpl * * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data * @param string $varName variable name or null diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_loadfilter.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_loadfilter.php index 66d80d474..af788a24e 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_loadfilter.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_loadfilter.php @@ -30,7 +30,7 @@ class Smarty_Internal_Method_LoadFilter * * @api Smarty::loadFilter() * - * @link http://www.smarty.net/docs/en/api.load.filter.tpl + * @link https://www.smarty.net/docs/en/api.load.filter.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $type filter type diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registercacheresource.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registercacheresource.php index 648365619..5608b3fd0 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registercacheresource.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registercacheresource.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_RegisterCacheResource * Registers a resource to fetch a template * * @api Smarty::registerCacheResource() - * @link http://www.smarty.net/docs/en/api.register.cacheresource.tpl + * @link https://www.smarty.net/docs/en/api.register.cacheresource.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $name name of resource type diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerclass.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerclass.php index 8d18547e2..76a69c6e5 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerclass.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerclass.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_RegisterClass * Registers static classes to be used in templates * * @api Smarty::registerClass() - * @link http://www.smarty.net/docs/en/api.register.class.tpl + * @link https://www.smarty.net/docs/en/api.register.class.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $class_name diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerdefaultpluginhandler.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerdefaultpluginhandler.php index a9fb78dc6..4cda5b056 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerdefaultpluginhandler.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerdefaultpluginhandler.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_RegisterDefaultPluginHandler * Registers a default plugin handler * * @api Smarty::registerDefaultPluginHandler() - * @link http://www.smarty.net/docs/en/api.register.default.plugin.handler.tpl + * @link https://www.smarty.net/docs/en/api.register.default.plugin.handler.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param callable $callback class/method name diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerfilter.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerfilter.php index c0f9fff10..9719eb2b6 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerfilter.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerfilter.php @@ -30,7 +30,7 @@ class Smarty_Internal_Method_RegisterFilter * * @api Smarty::registerFilter() * - * @link http://www.smarty.net/docs/en/api.register.filter.tpl + * @link https://www.smarty.net/docs/en/api.register.filter.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $type filter type diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerobject.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerobject.php index 4646e4f22..8e6fe0521 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerobject.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerobject.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_RegisterObject * Registers object to be used in templates * * @api Smarty::registerObject() - * @link http://www.smarty.net/docs/en/api.register.object.tpl + * @link https://www.smarty.net/docs/en/api.register.object.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $object_name diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerplugin.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerplugin.php index ed18d84bb..74c0ae908 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerplugin.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerplugin.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_RegisterPlugin * Registers plugin to be used in templates * * @api Smarty::registerPlugin() - * @link http://www.smarty.net/docs/en/api.register.plugin.tpl + * @link https://www.smarty.net/docs/en/api.register.plugin.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $type plugin type diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerresource.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerresource.php index 7c7d0f78a..302657ae0 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerresource.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_registerresource.php @@ -22,25 +22,18 @@ class Smarty_Internal_Method_RegisterResource * Registers a resource to fetch a template * * @api Smarty::registerResource() - * @link http://www.smarty.net/docs/en/api.register.resource.tpl + * @link https://www.smarty.net/docs/en/api.register.resource.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $name name of resource type - * @param Smarty_Resource|array $resource_handler or instance of - * Smarty_Resource, - * or array of - * callbacks to - * handle - * resource - * (deprecated) + * @param Smarty_Resource $resource_handler instance of Smarty_Resource * * @return \Smarty|\Smarty_Internal_Template */ - public function registerResource(Smarty_Internal_TemplateBase $obj, $name, $resource_handler) + public function registerResource(Smarty_Internal_TemplateBase $obj, $name, Smarty_Resource $resource_handler) { $smarty = $obj->_getSmartyObj(); - $smarty->registered_resources[ $name ] = - $resource_handler instanceof Smarty_Resource ? $resource_handler : array($resource_handler, false); + $smarty->registered_resources[ $name ] = $resource_handler; return $obj; } } diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unloadfilter.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unloadfilter.php index 55e1596be..e41e8dffc 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unloadfilter.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unloadfilter.php @@ -16,7 +16,7 @@ class Smarty_Internal_Method_UnloadFilter extends Smarty_Internal_Method_LoadFil * * @api Smarty::unloadFilter() * - * @link http://www.smarty.net/docs/en/api.unload.filter.tpl + * @link https://www.smarty.net/docs/en/api.unload.filter.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $type filter type diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregistercacheresource.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregistercacheresource.php index b99903867..377397e97 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregistercacheresource.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregistercacheresource.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_UnregisterCacheResource * Registers a resource to fetch a template * * @api Smarty::unregisterCacheResource() - * @link http://www.smarty.net/docs/en/api.unregister.cacheresource.tpl + * @link https://www.smarty.net/docs/en/api.unregister.cacheresource.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param $name diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterfilter.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterfilter.php index 9cb494a52..ebc9337d0 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterfilter.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterfilter.php @@ -16,7 +16,7 @@ class Smarty_Internal_Method_UnregisterFilter extends Smarty_Internal_Method_Reg * * @api Smarty::unregisterFilter() * - * @link http://www.smarty.net/docs/en/api.unregister.filter.tpl + * @link https://www.smarty.net/docs/en/api.unregister.filter.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $type filter type diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterobject.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterobject.php index 1e592b339..77d619637 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterobject.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterobject.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_UnregisterObject * Registers plugin to be used in templates * * @api Smarty::unregisterObject() - * @link http://www.smarty.net/docs/en/api.unregister.object.tpl + * @link https://www.smarty.net/docs/en/api.unregister.object.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $object_name name of object diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterplugin.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterplugin.php index f39e31678..2431d5c23 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterplugin.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterplugin.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_UnregisterPlugin * Registers plugin to be used in templates * * @api Smarty::unregisterPlugin() - * @link http://www.smarty.net/docs/en/api.unregister.plugin.tpl + * @link https://www.smarty.net/docs/en/api.unregister.plugin.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $type plugin type diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterresource.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterresource.php index a79db4299..bbb6a861d 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterresource.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_method_unregisterresource.php @@ -22,7 +22,7 @@ class Smarty_Internal_Method_UnregisterResource * Registers a resource to fetch a template * * @api Smarty::unregisterResource() - * @link http://www.smarty.net/docs/en/api.unregister.resource.tpl + * @link https://www.smarty.net/docs/en/api.unregister.resource.tpl * * @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj * @param string $type name of resource type diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php index ab4c3ec3b..829c420fe 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php @@ -87,83 +87,83 @@ public function to_smarty_php(Smarty_Internal_Templateparser $parser) $code = ''; foreach ($this->getChunkedSubtrees() as $chunk) { - $text = ''; - switch ($chunk['mode']) { - case 'textstripped': - foreach ($chunk['subtrees'] as $subtree) { - $text .= $subtree->to_smarty_php($parser); - } - $code .= preg_replace( - '/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/', - "\n", - $parser->compiler->processText($text) - ); - break; - case 'text': - foreach ($chunk['subtrees'] as $subtree) { - $text .= $subtree->to_smarty_php($parser); - } - $code .= preg_replace( - '/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/', - "\n", - $text - ); - break; - case 'tag': - foreach ($chunk['subtrees'] as $subtree) { - $text = $parser->compiler->appendCode($text, $subtree->to_smarty_php($parser)); - } - $code .= $text; - break; - default: - foreach ($chunk['subtrees'] as $subtree) { - $text = $subtree->to_smarty_php($parser); - } - $code .= $text; + $text = ''; + switch ($chunk['mode']) { + case 'textstripped': + foreach ($chunk['subtrees'] as $subtree) { + $text .= $subtree->to_smarty_php($parser); + } + $code .= preg_replace( + '/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/', + "\n", + $parser->compiler->processText($text) + ); + break; + case 'text': + foreach ($chunk['subtrees'] as $subtree) { + $text .= $subtree->to_smarty_php($parser); + } + $code .= preg_replace( + '/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/', + "\n", + $text + ); + break; + case 'tag': + foreach ($chunk['subtrees'] as $subtree) { + $text = $parser->compiler->appendCode($text, $subtree->to_smarty_php($parser)); + } + $code .= $text; + break; + default: + foreach ($chunk['subtrees'] as $subtree) { + $text = $subtree->to_smarty_php($parser); + } + $code .= $text; - } + } } return $code; } private function getChunkedSubtrees() { - $chunks = array(); - $currentMode = null; - $currentChunk = array(); - for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) { + $chunks = array(); + $currentMode = null; + $currentChunk = array(); + for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) { - if ($this->subtrees[ $key ]->data === '' && in_array($currentMode, array('textstripped', 'text', 'tag'))) { - continue; - } + if ($this->subtrees[ $key ]->data === '' && in_array($currentMode, array('textstripped', 'text', 'tag'))) { + continue; + } - if ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text - && $this->subtrees[ $key ]->isToBeStripped()) { - $newMode = 'textstripped'; - } elseif ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text) { - $newMode = 'text'; - } elseif ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Tag) { - $newMode = 'tag'; - } else { - $newMode = 'other'; - } + if ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text + && $this->subtrees[ $key ]->isToBeStripped()) { + $newMode = 'textstripped'; + } elseif ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text) { + $newMode = 'text'; + } elseif ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Tag) { + $newMode = 'tag'; + } else { + $newMode = 'other'; + } - if ($newMode == $currentMode) { - $currentChunk[] = $this->subtrees[ $key ]; - } else { - $chunks[] = array( - 'mode' => $currentMode, - 'subtrees' => $currentChunk - ); - $currentMode = $newMode; - $currentChunk = array($this->subtrees[ $key ]); - } - } - if ($currentMode && $currentChunk) { - $chunks[] = array( - 'mode' => $currentMode, - 'subtrees' => $currentChunk - ); - } - return $chunks; + if ($newMode == $currentMode) { + $currentChunk[] = $this->subtrees[ $key ]; + } else { + $chunks[] = array( + 'mode' => $currentMode, + 'subtrees' => $currentChunk + ); + $currentMode = $newMode; + $currentChunk = array($this->subtrees[ $key ]); + } + } + if ($currentMode && $currentChunk) { + $chunks[] = array( + 'mode' => $currentMode, + 'subtrees' => $currentChunk + ); + } + return $chunks; } } diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_text.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_text.php index 399e84941..58116c811 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_text.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_text.php @@ -17,30 +17,30 @@ class Smarty_Internal_ParseTree_Text extends Smarty_Internal_ParseTree { - /** - * Wether this section should be stripped on output to smarty php - * @var bool - */ - private $toBeStripped = false; + /** + * Wether this section should be stripped on output to smarty php + * @var bool + */ + private $toBeStripped = false; - /** - * Create template text buffer - * - * @param string $data text - * @param bool $toBeStripped wether this section should be stripped on output to smarty php - */ + /** + * Create template text buffer + * + * @param string $data text + * @param bool $toBeStripped wether this section should be stripped on output to smarty php + */ public function __construct($data, $toBeStripped = false) { $this->data = $data; $this->toBeStripped = $toBeStripped; } - /** - * Wether this section should be stripped on output to smarty php - * @return bool - */ - public function isToBeStripped() { - return $this->toBeStripped; + /** + * Wether this section should be stripped on output to smarty php + * @return bool + */ + public function isToBeStripped() { + return $this->toBeStripped; } /** diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_resource_registered.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_resource_registered.php deleted file mode 100644 index df526101f..000000000 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_resource_registered.php +++ /dev/null @@ -1,101 +0,0 @@ -filepath = $source->type . ':' . $source->name; - $source->uid = sha1($source->filepath . $source->smarty->_joined_template_dir); - $source->timestamp = $this->getTemplateTimestamp($source); - $source->exists = !!$source->timestamp; - } - - /** - * populate Source Object with timestamp and exists from Resource - * - * @param Smarty_Template_Source $source source object - * - * @return void - */ - public function populateTimestamp(Smarty_Template_Source $source) - { - $source->timestamp = $this->getTemplateTimestamp($source); - $source->exists = !!$source->timestamp; - } - - /** - * Get timestamp (epoch) the template source was modified - * - * @param Smarty_Template_Source $source source object - * - * @return integer|boolean timestamp (epoch) the template was modified, false if resources has no timestamp - */ - public function getTemplateTimestamp(Smarty_Template_Source $source) - { - // return timestamp - $time_stamp = false; - call_user_func_array( - $source->smarty->registered_resources[ $source->type ][ 0 ][ 1 ], - array($source->name, &$time_stamp, $source->smarty) - ); - return is_numeric($time_stamp) ? (int)$time_stamp : $time_stamp; - } - - /** - * Load template's source by invoking the registered callback into current template object - * - * @param Smarty_Template_Source $source source object - * - * @return string template source - * @throws SmartyException if source cannot be loaded - */ - public function getContent(Smarty_Template_Source $source) - { - // return template string - $content = null; - $t = call_user_func_array( - $source->smarty->registered_resources[ $source->type ][ 0 ][ 0 ], - array($source->name, &$content, $source->smarty) - ); - if (is_bool($t) && !$t) { - throw new SmartyException("Unable to read template {$source->type} '{$source->name}'"); - } - return $content; - } - - /** - * Determine basename for compiled filename - * - * @param Smarty_Template_Source $source source object - * - * @return string resource's basename - */ - public function getBasename(Smarty_Template_Source $source) - { - return basename($source->name); - } -} diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_resource_stream.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_resource_stream.php index 9956bd073..5f0203498 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_resource_stream.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_resource_stream.php @@ -13,7 +13,7 @@ * Smarty Internal Plugin Resource Stream * Implements the streams as resource for Smarty template * - * @link http://php.net/streams + * @link https://php.net/streams * @package Smarty * @subpackage TemplateResources */ diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_runtime_codeframe.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_runtime_codeframe.php index 983ca6180..b5361c9bb 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_runtime_codeframe.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_runtime_codeframe.php @@ -45,7 +45,7 @@ public function create( $properties[ 'cache_lifetime' ] = $_template->cache_lifetime; } $output = "source->filepath) . "' */\n\n"; $output .= "/* @var Smarty_Internal_Template \$_smarty_tpl */\n"; $dec = "\$_smarty_tpl->_decodeProperties(\$_smarty_tpl, " . var_export($properties, true) . ',' . diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatebase.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatebase.php index 200c11bb5..2ffb896fa 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatebase.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatebase.php @@ -138,7 +138,7 @@ public function display($template = null, $cache_id = null, $compile_id = null, * test if cache is valid * * @api Smarty::isCached() - * @link http://www.smarty.net/docs/en/api.is.cached.tpl + * @link https://www.smarty.net/docs/en/api.is.cached.tpl * * @param null|string|\Smarty_Internal_Template $template the resource handle of the template file or template * object @@ -199,6 +199,12 @@ private function _execute($template, $cache_id, $compile_id, $parent, $function) try { $_smarty_old_error_level = isset($smarty->error_reporting) ? error_reporting($smarty->error_reporting) : null; + + if ($smarty->isMutingUndefinedOrNullWarnings()) { + $errorHandler = new Smarty_Internal_ErrorHandler(); + $errorHandler->activate(); + } + if ($this->_objType === 2) { /* @var Smarty_Internal_Template $this */ $template->tplFunctions = $this->tplFunctions; @@ -242,6 +248,11 @@ private function _execute($template, $cache_id, $compile_id, $parent, $function) } } } + + if (isset($errorHandler)) { + $errorHandler->deactivate(); + } + if (isset($_smarty_old_error_level)) { error_reporting($_smarty_old_error_level); } @@ -250,6 +261,10 @@ private function _execute($template, $cache_id, $compile_id, $parent, $function) while (ob_get_level() > $level) { ob_end_clean(); } + if (isset($errorHandler)) { + $errorHandler->deactivate(); + } + if (isset($_smarty_old_error_level)) { error_reporting($_smarty_old_error_level); } @@ -261,7 +276,7 @@ private function _execute($template, $cache_id, $compile_id, $parent, $function) * Registers plugin to be used in templates * * @api Smarty::registerPlugin() - * @link http://www.smarty.net/docs/en/api.register.plugin.tpl + * @link https://www.smarty.net/docs/en/api.register.plugin.tpl * * @param string $type plugin type * @param string $name name of template tag @@ -281,7 +296,7 @@ public function registerPlugin($type, $name, $callback, $cacheable = true, $cach * load a filter of specified type and name * * @api Smarty::loadFilter() - * @link http://www.smarty.net/docs/en/api.load.filter.tpl + * @link https://www.smarty.net/docs/en/api.load.filter.tpl * * @param string $type filter type * @param string $name filter name @@ -298,7 +313,7 @@ public function loadFilter($type, $name) * Registers a filter function * * @api Smarty::registerFilter() - * @link http://www.smarty.net/docs/en/api.register.filter.tpl + * @link https://www.smarty.net/docs/en/api.register.filter.tpl * * @param string $type filter type * @param callable $callback @@ -316,7 +331,7 @@ public function registerFilter($type, $callback, $name = null) * Registers object to be used in templates * * @api Smarty::registerObject() - * @link http://www.smarty.net/docs/en/api.register.object.tpl + * @link https://www.smarty.net/docs/en/api.register.object.tpl * * @param string $object_name * @param object $object the referenced PHP object to register diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatecompilerbase.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatecompilerbase.php index 3cc957dec..272616148 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatecompilerbase.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatecompilerbase.php @@ -203,13 +203,6 @@ abstract class Smarty_Internal_TemplateCompilerBase */ public $blockOrFunctionCode = ''; - /** - * php_handling setting either from Smarty or security - * - * @var int - */ - public $php_handling = 0; - /** * flags for used modifier plugins * @@ -438,11 +431,6 @@ public function compileTemplateSource( } $this->smarty->_debug->start_compile($this->template); } - if (isset($this->template->smarty->security_policy)) { - $this->php_handling = $this->template->smarty->security_policy->php_handling; - } else { - $this->php_handling = $this->template->smarty->php_handling; - } $this->parent_compiler = $parent_compiler ? $parent_compiler : $this; $nocache = isset($nocache) ? $nocache : false; if (empty($template->compiled->nocache_hash)) { @@ -627,11 +615,11 @@ public function compilePHPFunctionCall($name, $parameter) $this->trigger_template_error('Illegal number of parameter in "isset()"'); } - $pa = array(); - foreach ($parameter as $p) { - $pa[] = $this->syntaxMatchesVariable($p) ? 'isset(' . $p . ')' : '(' . $p . ' !== null )'; - } - return '(' . implode(' && ', $pa) . ')'; + $pa = array(); + foreach ($parameter as $p) { + $pa[] = $this->syntaxMatchesVariable($p) ? 'isset(' . $p . ')' : '(' . $p . ' !== null )'; + } + return '(' . implode(' && ', $pa) . ')'; } elseif (in_array( $func_name, @@ -649,12 +637,8 @@ public function compilePHPFunctionCall($name, $parameter) $this->trigger_template_error("Illegal number of parameter in '{$func_name()}'"); } if ($func_name === 'empty') { - if (!$this->syntaxMatchesVariable($parameter[0]) && version_compare(PHP_VERSION, '5.5.0', '<')) { - return '(' . $parameter[ 0 ] . ' === false )'; - } else { - return $func_name . '(' . - str_replace("')->value", "',null,true,false)->value", $parameter[ 0 ]) . ')'; - } + return $func_name . '(' . + str_replace("')->value", "',null,true,false)->value", $parameter[ 0 ]) . ')'; } else { return $func_name . '(' . $parameter[ 0 ] . ')'; } @@ -667,16 +651,16 @@ public function compilePHPFunctionCall($name, $parameter) } } - /** - * Determines whether the passed string represents a valid (PHP) variable. - * This is important, because `isset()` only works on variables and `empty()` can only be passed - * a variable prior to php5.5 - * @param $string - * @return bool - */ - private function syntaxMatchesVariable($string) { - static $regex_pattern = '/^\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*((->)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\[.*]*\])*$/'; - return 1 === preg_match($regex_pattern, trim($string)); + /** + * Determines whether the passed string represents a valid (PHP) variable. + * This is important, because `isset()` only works on variables and `empty()` can only be passed + * a variable prior to php5.5 + * @param $string + * @return bool + */ + private function syntaxMatchesVariable($string) { + static $regex_pattern = '/^\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*((->)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\[.*]*\])*$/'; + return 1 === preg_match($regex_pattern, trim($string)); } /** @@ -691,11 +675,11 @@ public function processText($text) { if (strpos($text, '<') === false) { - return preg_replace($this->stripRegEx, '', $text); + return preg_replace($this->stripRegEx, '', $text); } - $store = array(); - $_store = 0; + $store = array(); + $_store = 0; // capture html elements not to be messed with $_offset = 0; @@ -1151,7 +1135,7 @@ public function trigger_template_error($args = null, $line = null, $tagline = nu flush(); } $e = new SmartyCompilerException($error_text); - $e->line = $line; + $e->setLine($line); $e->source = trim(preg_replace('![\t\r\n]+!', ' ', $match[ $line - 1 ])); $e->desc = $args; $e->template = $this->template->source->filepath; diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatelexer.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatelexer.php index 867a31d26..5ca482058 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatelexer.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_templatelexer.php @@ -18,12 +18,6 @@ */ class Smarty_Internal_Templatelexer { - const TEXT = 1; - const TAG = 2; - const TAGBODY = 3; - const LITERAL = 4; - const DOUBLEQUOTEDSTRING = 5; - /** * Source * @@ -80,7 +74,7 @@ class Smarty_Internal_Templatelexer */ public $phpType = ''; - /** + /** * state number * * @var int @@ -229,10 +223,6 @@ class Smarty_Internal_Templatelexer */ private $yy_global_literal = null; - private $_yy_state = 1; - - private $_yy_stack = array(); - /** * constructor * @@ -245,14 +235,14 @@ public function __construct($source, Smarty_Internal_TemplateCompilerBase $compi $this->dataLength = strlen($this->data); $this->counter = 0; if (preg_match('/^\xEF\xBB\xBF/i', $this->data, $match)) { - $this->counter += strlen($match[ 0 ]); + $this->counter += strlen($match[0]); } $this->line = 1; $this->smarty = $compiler->template->smarty; $this->compiler = $compiler; $this->compiler->initDelimiterPreg(); - $this->smarty_token_names[ 'LDEL' ] = $this->smarty->getLeftDelimiter(); - $this->smarty_token_names[ 'RDEL' ] = $this->smarty->getRightDelimiter(); + $this->smarty_token_names['LDEL'] = $this->smarty->getLeftDelimiter(); + $this->smarty_token_names['RDEL'] = $this->smarty->getRightDelimiter(); } /** @@ -265,17 +255,17 @@ public function PrintTrace() $this->yyTracePrompt = '
'; } - /** + /** * replace placeholders with runtime preg code * * @param string $preg * * @return string */ - public function replace($preg) - { + public function replace($preg) + { return $this->compiler->replaceDelimiter($preg); - } + } /** * check if current value is an autoliteral left delimiter @@ -286,7 +276,11 @@ public function isAutoLiteral() { return $this->smarty->getAutoLiteral() && isset($this->value[ $this->compiler->getLdelLength() ]) ? strpos(" \n\t\r", $this->value[ $this->compiler->getLdelLength() ]) !== false : false; - } // end function + } + + + private $_yy_state = 1; + private $_yy_stack = array(); public function yylex() { @@ -296,62 +290,60 @@ public function yylex() public function yypushstate($state) { if ($this->yyTraceFILE) { - fprintf($this->yyTraceFILE, "%sState push %s\n", $this->yyTracePrompt, - isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state); + fprintf($this->yyTraceFILE, "%sState push %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state); } array_push($this->_yy_stack, $this->_yy_state); $this->_yy_state = $state; if ($this->yyTraceFILE) { - fprintf($this->yyTraceFILE, "%snew State %s\n", $this->yyTracePrompt, - isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state); + fprintf($this->yyTraceFILE, "%snew State %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state); } } public function yypopstate() { - if ($this->yyTraceFILE) { - fprintf($this->yyTraceFILE, "%sState pop %s\n", $this->yyTracePrompt, - isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state); + if ($this->yyTraceFILE) { + fprintf($this->yyTraceFILE, "%sState pop %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state); } - $this->_yy_state = array_pop($this->_yy_stack); + $this->_yy_state = array_pop($this->_yy_stack); if ($this->yyTraceFILE) { - fprintf($this->yyTraceFILE, "%snew State %s\n", $this->yyTracePrompt, - isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state); + fprintf($this->yyTraceFILE, "%snew State %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state); } + } public function yybegin($state) { - $this->_yy_state = $state; + $this->_yy_state = $state; if ($this->yyTraceFILE) { - fprintf($this->yyTraceFILE, "%sState set %s\n", $this->yyTracePrompt, - isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state); + fprintf($this->yyTraceFILE, "%sState set %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state); } } + + public function yylex1() { if (!isset($this->yy_global_pattern1)) { - $this->yy_global_pattern1 = - $this->replace("/\G([{][}])|\G((SMARTYldel)SMARTYal[*])|\G((SMARTYldel)SMARTYalphp([ ].*?)?SMARTYrdel|(SMARTYldel)SMARTYal[\/]phpSMARTYrdel)|\G((SMARTYldel)SMARTYautoliteral\\s+SMARTYliteral)|\G((SMARTYldel)SMARTYalliteral\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/]literal\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal)|\G([<][?]((php\\s+|=)|\\s+)|[<][%]|[<][?]xml\\s+|[<]script\\s+language\\s*=\\s*[\"']?\\s*php\\s*[\"']?\\s*[>]|[?][>]|[%][>])|\G([\S\s])/isS"); + $this->yy_global_pattern1 = $this->replace("/\G([{][}])|\G((SMARTYldel)SMARTYal[*])|\G((SMARTYldel)SMARTYautoliteral\\s+SMARTYliteral)|\G((SMARTYldel)SMARTYalliteral\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/]literal\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal)|\G([\S\s])/isS"); } if (!isset($this->dataLength)) { $this->dataLength = strlen($this->data); } - if ($this->counter >= $this->dataLength) { + if ($this->counter >= $this->dataLength) { return false; // end of input } + do { - if (preg_match($this->yy_global_pattern1, $this->data, $yymatches, 0, $this->counter)) { - if (!isset($yymatches[ 0 ][ 1 ])) { - $yymatches = preg_grep("/(.|\s)+/", $yymatches); + if (preg_match($this->yy_global_pattern1,$this->data, $yymatches, 0, $this->counter)) { + if (!isset($yymatches[ 0 ][1])) { + $yymatches = preg_grep("/(.|\s)+/", $yymatches); } else { $yymatches = array_filter($yymatches); } if (empty($yymatches)) { throw new Exception('Error: lexing failed because a rule matched' . - ' an empty string. Input "' . substr($this->data, - $this->counter, 5) . '... state TEXT'); + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state TEXT'); } next($yymatches); // skip global match $this->token = key($yymatches); // token number @@ -369,110 +361,102 @@ public function yylex1() } elseif ($r === false) { $this->counter += strlen($this->value); $this->line += substr_count($this->value, "\n"); - if ($this->counter >= $this->dataLength) { + if ($this->counter >= $this->dataLength) { return false; // end of input } // skip this token continue; - } - } else { - throw new Exception('Unexpected input at line ' . $this->line . - ': ' . $this->data[ $this->counter ]); + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); } break; } while (true); - } + } // end function + + + const TEXT = 1; public function yy_r1_1() { - $this->token = Smarty_Internal_Templateparser::TP_TEXT; - } + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } public function yy_r1_2() { - $to = $this->dataLength; - preg_match("/[*]{$this->compiler->getRdelPreg()}[\n]?/", $this->data, $match, PREG_OFFSET_CAPTURE, - $this->counter); - if (isset($match[ 0 ][ 1 ])) { - $to = $match[ 0 ][ 1 ] + strlen($match[ 0 ][ 0 ]); + + $to = $this->dataLength; + preg_match("/[*]{$this->compiler->getRdelPreg()}[\n]?/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1] + strlen($match[0][0]); } else { - $this->compiler->trigger_template_error("missing or misspelled comment closing tag '{$this->smarty->getRightDelimiter()}'"); + $this->compiler->trigger_template_error ("missing or misspelled comment closing tag '{$this->smarty->getRightDelimiter()}'"); } - $this->value = substr($this->data, $this->counter, $to - $this->counter); + $this->value = substr($this->data,$this->counter,$to-$this->counter); return false; - } - + } public function yy_r1_4() { - $this->compiler->getTagCompiler('private_php')->parsePhp($this); - } - public function yy_r1_8() - { $this->token = Smarty_Internal_Templateparser::TP_TEXT; - } - - public function yy_r1_10() + } + public function yy_r1_6() { + $this->token = Smarty_Internal_Templateparser::TP_LITERALSTART; $this->yypushstate(self::LITERAL); - } - - public function yy_r1_12() + } + public function yy_r1_8() { + $this->token = Smarty_Internal_Templateparser::TP_LITERALEND; $this->yypushstate(self::LITERAL); - } // end function - - public function yy_r1_14() + } + public function yy_r1_10() { + $this->yypushstate(self::TAG); return true; - } - - public function yy_r1_16() + } + public function yy_r1_12() { - $this->compiler->getTagCompiler('private_php')->parsePhp($this); - } - public function yy_r1_19() - { - if (!isset($this->yy_global_text)) { - $this->yy_global_text = - $this->replace('/(SMARTYldel)SMARTYal|[<][?]((php\s+|=)|\s+)|[<][%]|[<][?]xml\s+|[<]script\s+language\s*=\s*["\']?\s*php\s*["\']?\s*[>]|[?][>]|[%][>]SMARTYliteral/isS'); - } - $to = $this->dataLength; - preg_match($this->yy_global_text, $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter); - if (isset($match[ 0 ][ 1 ])) { - $to = $match[ 0 ][ 1 ]; - } - $this->value = substr($this->data, $this->counter, $to - $this->counter); - $this->token = Smarty_Internal_Templateparser::TP_TEXT; - } + if (!isset($this->yy_global_text)) { + $this->yy_global_text = $this->replace('/(SMARTYldel)SMARTYal/isS'); + } + $to = $this->dataLength; + preg_match($this->yy_global_text, $this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } + $this->value = substr($this->data,$this->counter,$to-$this->counter); + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + public function yylex2() { if (!isset($this->yy_global_pattern2)) { - $this->yy_global_pattern2 = - $this->replace("/\G((SMARTYldel)SMARTYal(if|elseif|else if|while)\\s+)|\G((SMARTYldel)SMARTYalfor\\s+)|\G((SMARTYldel)SMARTYalforeach(?![^\s]))|\G((SMARTYldel)SMARTYalsetfilter\\s+)|\G((SMARTYldel)SMARTYalmake_nocache\\s+)|\G((SMARTYldel)SMARTYal[0-9]*[a-zA-Z_]\\w*(\\s+nocache)?\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[$]smarty\\.block\\.(child|parent)\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/][0-9]*[a-zA-Z_]\\w*\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[$][0-9]*[a-zA-Z_]\\w*(\\s+nocache)?\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/])|\G((SMARTYldel)SMARTYal)/isS"); + $this->yy_global_pattern2 = $this->replace("/\G((SMARTYldel)SMARTYal(if|elseif|else if|while)\\s+)|\G((SMARTYldel)SMARTYalfor\\s+)|\G((SMARTYldel)SMARTYalforeach(?![^\s]))|\G((SMARTYldel)SMARTYalsetfilter\\s+)|\G((SMARTYldel)SMARTYalmake_nocache\\s+)|\G((SMARTYldel)SMARTYal[0-9]*[a-zA-Z_]\\w*(\\s+nocache)?\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[$]smarty\\.block\\.(child|parent)\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/][0-9]*[a-zA-Z_]\\w*\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[$][0-9]*[a-zA-Z_]\\w*(\\s+nocache)?\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/])|\G((SMARTYldel)SMARTYal)/isS"); } if (!isset($this->dataLength)) { $this->dataLength = strlen($this->data); } - if ($this->counter >= $this->dataLength) { + if ($this->counter >= $this->dataLength) { return false; // end of input } + do { - if (preg_match($this->yy_global_pattern2, $this->data, $yymatches, 0, $this->counter)) { - if (!isset($yymatches[ 0 ][ 1 ])) { - $yymatches = preg_grep("/(.|\s)+/", $yymatches); + if (preg_match($this->yy_global_pattern2,$this->data, $yymatches, 0, $this->counter)) { + if (!isset($yymatches[ 0 ][1])) { + $yymatches = preg_grep("/(.|\s)+/", $yymatches); } else { $yymatches = array_filter($yymatches); } if (empty($yymatches)) { throw new Exception('Error: lexing failed because a rule matched' . - ' an empty string. Input "' . substr($this->data, - $this->counter, 5) . '... state TAG'); + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state TAG'); } next($yymatches); // skip global match $this->token = key($yymatches); // token number @@ -490,79 +474,82 @@ public function yylex2() } elseif ($r === false) { $this->counter += strlen($this->value); $this->line += substr_count($this->value, "\n"); - if ($this->counter >= $this->dataLength) { + if ($this->counter >= $this->dataLength) { return false; // end of input } // skip this token continue; - } - } else { - throw new Exception('Unexpected input at line ' . $this->line . - ': ' . $this->data[ $this->counter ]); + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); } break; } while (true); - } + } // end function + + + const TAG = 2; public function yy_r2_1() { + $this->token = Smarty_Internal_Templateparser::TP_LDELIF; $this->yybegin(self::TAGBODY); $this->taglineno = $this->line; - } - + } public function yy_r2_4() { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOR; $this->yybegin(self::TAGBODY); $this->taglineno = $this->line; - } - + } public function yy_r2_6() { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH; $this->yybegin(self::TAGBODY); $this->taglineno = $this->line; - } - + } public function yy_r2_8() { + $this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER; $this->yybegin(self::TAGBODY); $this->taglineno = $this->line; - } - + } public function yy_r2_10() { + $this->token = Smarty_Internal_Templateparser::TP_LDELMAKENOCACHE; $this->yybegin(self::TAGBODY); $this->taglineno = $this->line; - } - + } public function yy_r2_12() { + $this->yypopstate(); $this->token = Smarty_Internal_Templateparser::TP_SIMPLETAG; $this->taglineno = $this->line; - } - + } public function yy_r2_15() { - $this->yypopstate(); - $this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILDPARENT; - $this->taglineno = $this->line; - } + $this->yypopstate(); + $this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILDPARENT; + $this->taglineno = $this->line; + } public function yy_r2_18() { + $this->yypopstate(); $this->token = Smarty_Internal_Templateparser::TP_CLOSETAG; $this->taglineno = $this->line; - } - + } public function yy_r2_20() { - if ($this->_yy_stack[ count($this->_yy_stack) - 1 ] === self::TEXT) { + + if ($this->_yy_stack[count($this->_yy_stack)-1] === self::TEXT) { $this->yypopstate(); $this->token = Smarty_Internal_Templateparser::TP_SIMPELOUTPUT; $this->taglineno = $this->line; @@ -572,45 +559,46 @@ public function yy_r2_20() $this->yybegin(self::TAGBODY); $this->taglineno = $this->line; } - } // end function - + } public function yy_r2_23() { + $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH; $this->yybegin(self::TAGBODY); $this->taglineno = $this->line; - } - + } public function yy_r2_25() { + $this->token = Smarty_Internal_Templateparser::TP_LDEL; $this->yybegin(self::TAGBODY); $this->taglineno = $this->line; - } + } + public function yylex3() { if (!isset($this->yy_global_pattern3)) { - $this->yy_global_pattern3 = - $this->replace("/\G(\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal)|\G([\"])|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')|\G([$][0-9]*[a-zA-Z_]\\w*)|\G([$])|\G(\\s+is\\s+in\\s+)|\G(\\s+as\\s+)|\G(\\s+to\\s+)|\G(\\s+step\\s+)|\G(\\s+instanceof\\s+)|\G(\\s*([!=][=]{1,2}|[<][=>]?|[>][=]?|[&|]{2})\\s*)|\G(\\s+(eq|ne|neq|gt|ge|gte|lt|le|lte|mod|and|or|xor)\\s+)|\G(\\s+is\\s+(not\\s+)?(odd|even|div)\\s+by\\s+)|\G(\\s+is\\s+(not\\s+)?(odd|even))|\G([!]\\s*|not\\s+)|\G([(](int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)[)]\\s*)|\G(\\s*[(]\\s*)|\G(\\s*[)])|\G(\\[\\s*)|\G(\\s*\\])|\G(\\s*[-][>]\\s*)|\G(\\s*[=][>]\\s*)|\G(\\s*[=]\\s*)|\G(([+]|[-]){2})|\G(\\s*([+]|[-])\\s*)|\G(\\s*([*]{1,2}|[%\/^&]|[<>]{2})\\s*)|\G([@])|\G(array\\s*[(]\\s*)|\G([#])|\G(\\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\\s*[=]\\s*)|\G(([0-9]*[a-zA-Z_]\\w*)?(\\\\[0-9]*[a-zA-Z_]\\w*)+)|\G([0-9]*[a-zA-Z_]\\w*)|\G(\\d+)|\G([`])|\G([|][@]?)|\G([.])|\G(\\s*[,]\\s*)|\G(\\s*[;]\\s*)|\G([:]{2})|\G(\\s*[:]\\s*)|\G(\\s*[?]\\s*)|\G(0[xX][0-9a-fA-F]+)|\G(\\s+)|\G([\S\s])/isS"); + $this->yy_global_pattern3 = $this->replace("/\G(\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal)|\G([\"])|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')|\G([$][0-9]*[a-zA-Z_]\\w*)|\G([$])|\G(\\s+is\\s+in\\s+)|\G(\\s+as\\s+)|\G(\\s+to\\s+)|\G(\\s+step\\s+)|\G(\\s+instanceof\\s+)|\G(\\s*([!=][=]{1,2}|[<][=>]?|[>][=]?|[&|]{2})\\s*)|\G(\\s+(eq|ne|neq|gt|ge|gte|lt|le|lte|mod|and|or|xor)\\s+)|\G(\\s+is\\s+(not\\s+)?(odd|even|div)\\s+by\\s+)|\G(\\s+is\\s+(not\\s+)?(odd|even))|\G([!]\\s*|not\\s+)|\G([(](int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)[)]\\s*)|\G(\\s*[(]\\s*)|\G(\\s*[)])|\G(\\[\\s*)|\G(\\s*\\])|\G(\\s*[-][>]\\s*)|\G(\\s*[=][>]\\s*)|\G(\\s*[=]\\s*)|\G(([+]|[-]){2})|\G(\\s*([+]|[-])\\s*)|\G(\\s*([*]{1,2}|[%\/^&]|[<>]{2})\\s*)|\G([@])|\G(array\\s*[(]\\s*)|\G([#])|\G(\\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\\s*[=]\\s*)|\G(([0-9]*[a-zA-Z_]\\w*)?(\\\\[0-9]*[a-zA-Z_]\\w*)+)|\G([0-9]*[a-zA-Z_]\\w*)|\G(\\d+)|\G([`])|\G([|][@]?)|\G([.])|\G(\\s*[,]\\s*)|\G(\\s*[;]\\s*)|\G([:]{2})|\G(\\s*[:]\\s*)|\G(\\s*[?]\\s*)|\G(0[xX][0-9a-fA-F]+)|\G(\\s+)|\G([\S\s])/isS"); } if (!isset($this->dataLength)) { $this->dataLength = strlen($this->data); } - if ($this->counter >= $this->dataLength) { + if ($this->counter >= $this->dataLength) { return false; // end of input } + do { - if (preg_match($this->yy_global_pattern3, $this->data, $yymatches, 0, $this->counter)) { - if (!isset($yymatches[ 0 ][ 1 ])) { - $yymatches = preg_grep("/(.|\s)+/", $yymatches); + if (preg_match($this->yy_global_pattern3,$this->data, $yymatches, 0, $this->counter)) { + if (!isset($yymatches[ 0 ][1])) { + $yymatches = preg_grep("/(.|\s)+/", $yymatches); } else { $yymatches = array_filter($yymatches); } if (empty($yymatches)) { throw new Exception('Error: lexing failed because a rule matched' . - ' an empty string. Input "' . substr($this->data, - $this->counter, 5) . '... state TAGBODY'); + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state TAGBODY'); } next($yymatches); // skip global match $this->token = key($yymatches); // token number @@ -628,281 +616,285 @@ public function yylex3() } elseif ($r === false) { $this->counter += strlen($this->value); $this->line += substr_count($this->value, "\n"); - if ($this->counter >= $this->dataLength) { + if ($this->counter >= $this->dataLength) { return false; // end of input } // skip this token continue; - } - } else { - throw new Exception('Unexpected input at line ' . $this->line . - ': ' . $this->data[ $this->counter ]); + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); } break; } while (true); - } + } // end function + + + const TAGBODY = 3; public function yy_r3_1() { + $this->token = Smarty_Internal_Templateparser::TP_RDEL; $this->yypopstate(); - } - + } public function yy_r3_2() { + $this->yypushstate(self::TAG); return true; - } - + } public function yy_r3_4() { + $this->token = Smarty_Internal_Templateparser::TP_QUOTE; $this->yypushstate(self::DOUBLEQUOTEDSTRING); $this->compiler->enterDoubleQuote(); - } - + } public function yy_r3_5() { - $this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING; - } + $this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING; + } public function yy_r3_6() { - $this->token = Smarty_Internal_Templateparser::TP_DOLLARID; - } + $this->token = Smarty_Internal_Templateparser::TP_DOLLARID; + } public function yy_r3_7() { - $this->token = Smarty_Internal_Templateparser::TP_DOLLAR; - } + $this->token = Smarty_Internal_Templateparser::TP_DOLLAR; + } public function yy_r3_8() { - $this->token = Smarty_Internal_Templateparser::TP_ISIN; - } + $this->token = Smarty_Internal_Templateparser::TP_ISIN; + } public function yy_r3_9() { - $this->token = Smarty_Internal_Templateparser::TP_AS; - } + $this->token = Smarty_Internal_Templateparser::TP_AS; + } public function yy_r3_10() { - $this->token = Smarty_Internal_Templateparser::TP_TO; - } + $this->token = Smarty_Internal_Templateparser::TP_TO; + } public function yy_r3_11() { - $this->token = Smarty_Internal_Templateparser::TP_STEP; - } + $this->token = Smarty_Internal_Templateparser::TP_STEP; + } public function yy_r3_12() { - $this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF; - } + $this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF; + } public function yy_r3_13() { - $this->token = Smarty_Internal_Templateparser::TP_LOGOP; - } + $this->token = Smarty_Internal_Templateparser::TP_LOGOP; + } public function yy_r3_15() { - $this->token = Smarty_Internal_Templateparser::TP_SLOGOP; - } + $this->token = Smarty_Internal_Templateparser::TP_SLOGOP; + } public function yy_r3_17() { - $this->token = Smarty_Internal_Templateparser::TP_TLOGOP; - } + $this->token = Smarty_Internal_Templateparser::TP_TLOGOP; + } public function yy_r3_20() { - $this->token = Smarty_Internal_Templateparser::TP_SINGLECOND; - } + $this->token = Smarty_Internal_Templateparser::TP_SINGLECOND; + } public function yy_r3_23() { - $this->token = Smarty_Internal_Templateparser::TP_NOT; - } + $this->token = Smarty_Internal_Templateparser::TP_NOT; + } public function yy_r3_24() { - $this->token = Smarty_Internal_Templateparser::TP_TYPECAST; - } + $this->token = Smarty_Internal_Templateparser::TP_TYPECAST; + } public function yy_r3_28() { - $this->token = Smarty_Internal_Templateparser::TP_OPENP; - } + $this->token = Smarty_Internal_Templateparser::TP_OPENP; + } public function yy_r3_29() { - $this->token = Smarty_Internal_Templateparser::TP_CLOSEP; - } + $this->token = Smarty_Internal_Templateparser::TP_CLOSEP; + } public function yy_r3_30() { - $this->token = Smarty_Internal_Templateparser::TP_OPENB; - } + $this->token = Smarty_Internal_Templateparser::TP_OPENB; + } public function yy_r3_31() { - $this->token = Smarty_Internal_Templateparser::TP_CLOSEB; - } + $this->token = Smarty_Internal_Templateparser::TP_CLOSEB; + } public function yy_r3_32() { - $this->token = Smarty_Internal_Templateparser::TP_PTR; - } + $this->token = Smarty_Internal_Templateparser::TP_PTR; + } public function yy_r3_33() { - $this->token = Smarty_Internal_Templateparser::TP_APTR; - } + $this->token = Smarty_Internal_Templateparser::TP_APTR; + } public function yy_r3_34() { - $this->token = Smarty_Internal_Templateparser::TP_EQUAL; - } + $this->token = Smarty_Internal_Templateparser::TP_EQUAL; + } public function yy_r3_35() { - $this->token = Smarty_Internal_Templateparser::TP_INCDEC; - } + $this->token = Smarty_Internal_Templateparser::TP_INCDEC; + } public function yy_r3_37() { - $this->token = Smarty_Internal_Templateparser::TP_UNIMATH; - } + $this->token = Smarty_Internal_Templateparser::TP_UNIMATH; + } public function yy_r3_39() { - $this->token = Smarty_Internal_Templateparser::TP_MATH; - } + $this->token = Smarty_Internal_Templateparser::TP_MATH; + } public function yy_r3_41() { - $this->token = Smarty_Internal_Templateparser::TP_AT; - } + $this->token = Smarty_Internal_Templateparser::TP_AT; + } public function yy_r3_42() { - $this->token = Smarty_Internal_Templateparser::TP_ARRAYOPEN; - } + $this->token = Smarty_Internal_Templateparser::TP_ARRAYOPEN; + } public function yy_r3_43() { - $this->token = Smarty_Internal_Templateparser::TP_HATCH; - } + $this->token = Smarty_Internal_Templateparser::TP_HATCH; + } public function yy_r3_44() { + // resolve conflicts with shorttag and right_delimiter starting with '=' - if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->compiler->getRdelLength()) === - $this->smarty->getRightDelimiter()) { - preg_match('/\s+/', $this->value, $match); - $this->value = $match[ 0 ]; + if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->compiler->getRdelLength()) === $this->smarty->getRightDelimiter()) { + preg_match('/\s+/',$this->value,$match); + $this->value = $match[0]; $this->token = Smarty_Internal_Templateparser::TP_SPACE; } else { $this->token = Smarty_Internal_Templateparser::TP_ATTR; } - } - + } public function yy_r3_45() { - $this->token = Smarty_Internal_Templateparser::TP_NAMESPACE; - } + $this->token = Smarty_Internal_Templateparser::TP_NAMESPACE; + } public function yy_r3_48() { - $this->token = Smarty_Internal_Templateparser::TP_ID; - } + $this->token = Smarty_Internal_Templateparser::TP_ID; + } public function yy_r3_49() { - $this->token = Smarty_Internal_Templateparser::TP_INTEGER; - } + $this->token = Smarty_Internal_Templateparser::TP_INTEGER; + } public function yy_r3_50() { + $this->token = Smarty_Internal_Templateparser::TP_BACKTICK; $this->yypopstate(); - } - + } public function yy_r3_51() { - $this->token = Smarty_Internal_Templateparser::TP_VERT; - } + $this->token = Smarty_Internal_Templateparser::TP_VERT; + } public function yy_r3_52() { - $this->token = Smarty_Internal_Templateparser::TP_DOT; - } + $this->token = Smarty_Internal_Templateparser::TP_DOT; + } public function yy_r3_53() { - $this->token = Smarty_Internal_Templateparser::TP_COMMA; - } + $this->token = Smarty_Internal_Templateparser::TP_COMMA; + } public function yy_r3_54() { - $this->token = Smarty_Internal_Templateparser::TP_SEMICOLON; - } + $this->token = Smarty_Internal_Templateparser::TP_SEMICOLON; + } public function yy_r3_55() { - $this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON; - } + $this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON; + } public function yy_r3_56() { - $this->token = Smarty_Internal_Templateparser::TP_COLON; - } + $this->token = Smarty_Internal_Templateparser::TP_COLON; + } public function yy_r3_57() { - $this->token = Smarty_Internal_Templateparser::TP_QMARK; - } + $this->token = Smarty_Internal_Templateparser::TP_QMARK; + } public function yy_r3_58() { - $this->token = Smarty_Internal_Templateparser::TP_HEX; - } + $this->token = Smarty_Internal_Templateparser::TP_HEX; + } public function yy_r3_59() { - $this->token = Smarty_Internal_Templateparser::TP_SPACE; - } // end function + $this->token = Smarty_Internal_Templateparser::TP_SPACE; + } public function yy_r3_60() { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; - } + } + + public function yylex4() { if (!isset($this->yy_global_pattern4)) { - $this->yy_global_pattern4 = - $this->replace("/\G((SMARTYldel)SMARTYalliteral\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/]literal\\s*SMARTYrdel)|\G([\S\s])/isS"); + $this->yy_global_pattern4 = $this->replace("/\G((SMARTYldel)SMARTYalliteral\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/]literal\\s*SMARTYrdel)|\G([\S\s])/isS"); } if (!isset($this->dataLength)) { $this->dataLength = strlen($this->data); } - if ($this->counter >= $this->dataLength) { + if ($this->counter >= $this->dataLength) { return false; // end of input } + do { - if (preg_match($this->yy_global_pattern4, $this->data, $yymatches, 0, $this->counter)) { - if (!isset($yymatches[ 0 ][ 1 ])) { - $yymatches = preg_grep("/(.|\s)+/", $yymatches); + if (preg_match($this->yy_global_pattern4,$this->data, $yymatches, 0, $this->counter)) { + if (!isset($yymatches[ 0 ][1])) { + $yymatches = preg_grep("/(.|\s)+/", $yymatches); } else { $yymatches = array_filter($yymatches); } if (empty($yymatches)) { throw new Exception('Error: lexing failed because a rule matched' . - ' an empty string. Input "' . substr($this->data, - $this->counter, 5) . '... state LITERAL'); + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state LITERAL'); } next($yymatches); // skip global match $this->token = key($yymatches); // token number @@ -920,76 +912,80 @@ public function yylex4() } elseif ($r === false) { $this->counter += strlen($this->value); $this->line += substr_count($this->value, "\n"); - if ($this->counter >= $this->dataLength) { + if ($this->counter >= $this->dataLength) { return false; // end of input } // skip this token continue; - } - } else { - throw new Exception('Unexpected input at line ' . $this->line . - ': ' . $this->data[ $this->counter ]); + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); } break; } while (true); - } + } // end function + + + const LITERAL = 4; public function yy_r4_1() { + $this->literal_cnt++; $this->token = Smarty_Internal_Templateparser::TP_LITERAL; - } - + } public function yy_r4_3() { + if ($this->literal_cnt) { - $this->literal_cnt--; + $this->literal_cnt--; $this->token = Smarty_Internal_Templateparser::TP_LITERAL; } else { $this->token = Smarty_Internal_Templateparser::TP_LITERALEND; $this->yypopstate(); } - } - + } public function yy_r4_5() { - if (!isset($this->yy_global_literal)) { - $this->yy_global_literal = $this->replace('/(SMARTYldel)SMARTYal[\/]?literalSMARTYrdel/isS'); - } - $to = $this->dataLength; - preg_match($this->yy_global_literal, $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter); - if (isset($match[ 0 ][ 1 ])) { - $to = $match[ 0 ][ 1 ]; - } else { - $this->compiler->trigger_template_error("missing or misspelled literal closing tag"); - } - $this->value = substr($this->data, $this->counter, $to - $this->counter); - $this->token = Smarty_Internal_Templateparser::TP_LITERAL; - } // end function + if (!isset($this->yy_global_literal)) { + $this->yy_global_literal = $this->replace('/(SMARTYldel)SMARTYal[\/]?literalSMARTYrdel/isS'); + } + $to = $this->dataLength; + preg_match($this->yy_global_literal, $this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } else { + $this->compiler->trigger_template_error ("missing or misspelled literal closing tag"); + } + $this->value = substr($this->data,$this->counter,$to-$this->counter); + $this->token = Smarty_Internal_Templateparser::TP_LITERAL; + } + + public function yylex5() { if (!isset($this->yy_global_pattern5)) { - $this->yy_global_pattern5 = - $this->replace("/\G((SMARTYldel)SMARTYautoliteral\\s+SMARTYliteral)|\G((SMARTYldel)SMARTYalliteral\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/]literal\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/])|\G((SMARTYldel)SMARTYal[0-9]*[a-zA-Z_]\\w*)|\G((SMARTYldel)SMARTYal)|\G([\"])|\G([`][$])|\G([$][0-9]*[a-zA-Z_]\\w*)|\G([$])|\G(([^\"\\\\]*?)((?:\\\\.[^\"\\\\]*?)*?)(?=((SMARTYldel)SMARTYal|\\$|`\\$|\"SMARTYliteral)))|\G([\S\s])/isS"); + $this->yy_global_pattern5 = $this->replace("/\G((SMARTYldel)SMARTYautoliteral\\s+SMARTYliteral)|\G((SMARTYldel)SMARTYalliteral\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/]literal\\s*SMARTYrdel)|\G((SMARTYldel)SMARTYal[\/])|\G((SMARTYldel)SMARTYal[0-9]*[a-zA-Z_]\\w*)|\G((SMARTYldel)SMARTYal)|\G([\"])|\G([`][$])|\G([$][0-9]*[a-zA-Z_]\\w*)|\G([$])|\G(([^\"\\\\]*?)((?:\\\\.[^\"\\\\]*?)*?)(?=((SMARTYldel)SMARTYal|\\$|`\\$|\"SMARTYliteral)))|\G([\S\s])/isS"); } if (!isset($this->dataLength)) { $this->dataLength = strlen($this->data); } - if ($this->counter >= $this->dataLength) { + if ($this->counter >= $this->dataLength) { return false; // end of input } + do { - if (preg_match($this->yy_global_pattern5, $this->data, $yymatches, 0, $this->counter)) { - if (!isset($yymatches[ 0 ][ 1 ])) { - $yymatches = preg_grep("/(.|\s)+/", $yymatches); + if (preg_match($this->yy_global_pattern5,$this->data, $yymatches, 0, $this->counter)) { + if (!isset($yymatches[ 0 ][1])) { + $yymatches = preg_grep("/(.|\s)+/", $yymatches); } else { $yymatches = array_filter($yymatches); } if (empty($yymatches)) { throw new Exception('Error: lexing failed because a rule matched' . - ' an empty string. Input "' . substr($this->data, - $this->counter, 5) . '... state DOUBLEQUOTEDSTRING'); + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state DOUBLEQUOTEDSTRING'); } next($yymatches); // skip global match $this->token = key($yymatches); // token number @@ -1007,89 +1003,93 @@ public function yylex5() } elseif ($r === false) { $this->counter += strlen($this->value); $this->line += substr_count($this->value, "\n"); - if ($this->counter >= $this->dataLength) { + if ($this->counter >= $this->dataLength) { return false; // end of input } // skip this token continue; - } - } else { - throw new Exception('Unexpected input at line ' . $this->line . - ': ' . $this->data[ $this->counter ]); + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); } break; } while (true); - } + } // end function + + + const DOUBLEQUOTEDSTRING = 5; public function yy_r5_1() { - $this->token = Smarty_Internal_Templateparser::TP_TEXT; - } + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } public function yy_r5_3() { - $this->token = Smarty_Internal_Templateparser::TP_TEXT; - } + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } public function yy_r5_5() { - $this->token = Smarty_Internal_Templateparser::TP_TEXT; - } + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } public function yy_r5_7() { + $this->yypushstate(self::TAG); return true; - } - + } public function yy_r5_9() { + $this->yypushstate(self::TAG); return true; - } - + } public function yy_r5_11() { + $this->token = Smarty_Internal_Templateparser::TP_LDEL; $this->taglineno = $this->line; $this->yypushstate(self::TAGBODY); - } - + } public function yy_r5_13() { + $this->token = Smarty_Internal_Templateparser::TP_QUOTE; $this->yypopstate(); - } - + } public function yy_r5_14() { + $this->token = Smarty_Internal_Templateparser::TP_BACKTICK; - $this->value = substr($this->value, 0, -1); + $this->value = substr($this->value,0,-1); $this->yypushstate(self::TAGBODY); $this->taglineno = $this->line; - } - + } public function yy_r5_15() { - $this->token = Smarty_Internal_Templateparser::TP_DOLLARID; - } + $this->token = Smarty_Internal_Templateparser::TP_DOLLARID; + } public function yy_r5_16() { - $this->token = Smarty_Internal_Templateparser::TP_TEXT; - } + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } public function yy_r5_17() { - $this->token = Smarty_Internal_Templateparser::TP_TEXT; - } + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } public function yy_r5_22() { + $to = $this->dataLength; - $this->value = substr($this->data, $this->counter, $to - $this->counter); + $this->value = substr($this->data,$this->counter,$to-$this->counter); $this->token = Smarty_Internal_Templateparser::TP_TEXT; - } -} + } - + } + + \ No newline at end of file diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_templateparser.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_templateparser.php index aaeae63b7..a2dd0d6fb 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_templateparser.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_templateparser.php @@ -7,1598 +7,25 @@ class TP_yyStackEntry ** number for the token at this stack level */ public $minor; /* The user-supplied minor token value. This ** is the value of the token */ -} +}; + // line 11 "../smarty/lexer/smarty_internal_templateparser.y" /** - * Smarty Template Parser Class - * - * This is the template parser. - * It is generated from the smarty_internal_templateparser.y file - * - * @author Uwe Tews - */ +* Smarty Template Parser Class +* +* This is the template parser. +* It is generated from the smarty_internal_templateparser.y file +* +* @author Uwe Tews +*/ class Smarty_Internal_Templateparser { - // line 23 "../smarty/lexer/smarty_internal_templateparser.y" - const ERR1 = 'Security error: Call to private object member not allowed'; - const ERR2 = 'Security error: Call to dynamic object member not allowed'; - const ERR3 = 'PHP in template not allowed. Use SmartyBC to enable it'; - const TP_VERT = 1; - const TP_COLON = 2; - const TP_PHP = 3; - const TP_TEXT = 4; - const TP_STRIPON = 5; - const TP_STRIPOFF = 6; - const TP_LITERALSTART = 7; - const TP_LITERALEND = 8; - const TP_LITERAL = 9; - const TP_SIMPELOUTPUT = 10; - const TP_SIMPLETAG = 11; - const TP_SMARTYBLOCKCHILDPARENT = 12; - const TP_LDEL = 13; - const TP_RDEL = 14; - const TP_DOLLARID = 15; - const TP_EQUAL = 16; - const TP_ID = 17; - const TP_PTR = 18; - const TP_LDELMAKENOCACHE = 19; - const TP_LDELIF = 20; - const TP_LDELFOR = 21; - const TP_SEMICOLON = 22; - const TP_INCDEC = 23; - const TP_TO = 24; - const TP_STEP = 25; - const TP_LDELFOREACH = 26; - const TP_SPACE = 27; - const TP_AS = 28; - const TP_APTR = 29; - const TP_LDELSETFILTER = 30; - const TP_CLOSETAG = 31; - const TP_LDELSLASH = 32; - const TP_ATTR = 33; - const TP_INTEGER = 34; - const TP_COMMA = 35; - const TP_OPENP = 36; - const TP_CLOSEP = 37; - const TP_MATH = 38; - const TP_UNIMATH = 39; - const TP_ISIN = 40; - const TP_QMARK = 41; - const TP_NOT = 42; - const TP_TYPECAST = 43; - const TP_HEX = 44; - const TP_DOT = 45; - const TP_INSTANCEOF = 46; - const TP_SINGLEQUOTESTRING = 47; - const TP_DOUBLECOLON = 48; - const TP_NAMESPACE = 49; - const TP_AT = 50; - const TP_HATCH = 51; - const TP_OPENB = 52; - const TP_CLOSEB = 53; - const TP_DOLLAR = 54; - const TP_LOGOP = 55; - const TP_SLOGOP = 56; - const TP_TLOGOP = 57; - const TP_SINGLECOND = 58; - const TP_ARRAYOPEN = 59; - const TP_QUOTE = 60; - const TP_BACKTICK = 61; - const YY_NO_ACTION = 516; - const YY_ACCEPT_ACTION = 515; - const YY_ERROR_ACTION = 514; - const YY_SZ_ACTTAB = 2071; - const YY_SHIFT_USE_DFLT = -31; - const YY_SHIFT_MAX = 230; - const YY_REDUCE_USE_DFLT = -91; - const YY_REDUCE_MAX = 178; - const YYNOCODE = 110; - const YYSTACKDEPTH = 500; - const YYNSTATE = 327; - const YYNRULE = 187; - const YYERRORSYMBOL = 62; - const YYERRSYMDT = 'yy0'; - const YYFALLBACK = 0; - - public static $yy_action = array( - 251, 234, 237, 1, 144, 127, 428, 184, 199, 212, - 10, 54, 19, 175, 282, 215, 109, 389, 428, 428, - 224, 321, 223, 303, 203, 389, 13, 389, 281, 43, - 389, 428, 41, 40, 266, 225, 389, 213, 389, 194, - 389, 52, 4, 308, 301, 383, 34, 209, 222, 3, - 50, 153, 251, 234, 237, 1, 199, 131, 383, 198, - 305, 212, 10, 54, 383, 16, 199, 428, 109, 385, - 132, 18, 224, 321, 223, 222, 221, 12, 32, 428, - 116, 43, 385, 262, 41, 40, 266, 225, 385, 233, - 95, 194, 16, 52, 4, 131, 301, 252, 18, 265, - 164, 3, 50, 324, 251, 234, 237, 1, 23, 130, - 229, 198, 150, 212, 10, 54, 326, 11, 170, 284, - 109, 42, 22, 239, 224, 321, 223, 193, 221, 261, - 13, 52, 157, 43, 301, 286, 41, 40, 266, 225, - 205, 233, 5, 194, 96, 52, 4, 263, 301, 301, - 99, 349, 96, 3, 50, 199, 251, 234, 237, 1, - 238, 130, 241, 181, 349, 212, 10, 54, 382, 240, - 349, 36, 109, 185, 104, 256, 224, 321, 223, 132, - 191, 382, 13, 49, 91, 43, 12, 382, 41, 40, - 266, 225, 257, 233, 152, 194, 457, 52, 4, 457, - 301, 301, 228, 457, 282, 3, 50, 285, 251, 234, - 237, 1, 301, 131, 441, 198, 238, 212, 10, 54, - 349, 441, 325, 175, 109, 30, 349, 273, 224, 321, - 223, 20, 221, 295, 32, 211, 457, 39, 166, 49, - 41, 40, 266, 225, 87, 233, 205, 194, 279, 52, - 4, 24, 301, 204, 200, 280, 99, 3, 50, 199, - 251, 234, 237, 1, 31, 130, 96, 198, 205, 212, - 10, 54, 350, 55, 293, 207, 109, 283, 99, 96, - 224, 321, 223, 199, 180, 350, 13, 134, 230, 43, - 222, 350, 41, 40, 266, 225, 104, 233, 316, 194, - 279, 52, 4, 24, 301, 165, 284, 280, 85, 3, - 50, 25, 251, 234, 237, 1, 131, 129, 210, 198, - 14, 212, 10, 54, 269, 270, 301, 116, 109, 295, - 216, 211, 224, 321, 223, 171, 221, 95, 13, 28, - 219, 43, 323, 9, 41, 40, 266, 225, 151, 233, - 324, 194, 52, 52, 4, 301, 301, 30, 282, 302, - 178, 3, 50, 7, 251, 234, 237, 1, 136, 130, - 304, 179, 238, 212, 10, 54, 279, 175, 282, 24, - 109, 238, 429, 280, 224, 321, 223, 177, 221, 270, - 13, 255, 281, 43, 429, 49, 41, 40, 266, 225, - 275, 233, 318, 194, 49, 52, 4, 276, 301, 163, - 26, 199, 8, 3, 50, 119, 251, 234, 237, 1, - 11, 93, 291, 51, 107, 212, 10, 54, 226, 428, - 206, 201, 109, 148, 178, 322, 224, 321, 223, 441, - 221, 428, 13, 282, 9, 43, 441, 115, 41, 40, - 266, 225, 167, 233, 227, 194, 457, 52, 4, 457, - 301, 96, 158, 457, 101, 3, 50, 271, 251, 234, - 237, 1, 282, 130, 235, 186, 135, 212, 10, 54, - 199, 37, 119, 315, 109, 165, 284, 176, 224, 321, - 223, 104, 221, 149, 13, 281, 146, 43, 281, 300, - 41, 40, 266, 225, 30, 233, 289, 194, 21, 52, - 4, 272, 301, 211, 18, 301, 161, 3, 50, 110, - 251, 234, 237, 1, 137, 128, 282, 198, 268, 212, - 10, 54, 222, 169, 515, 92, 109, 172, 284, 31, - 224, 321, 223, 29, 221, 238, 6, 260, 53, 43, - 232, 139, 41, 40, 266, 225, 154, 233, 178, 194, - 168, 52, 4, 214, 301, 145, 99, 33, 49, 3, - 50, 245, 208, 211, 320, 282, 90, 111, 311, 183, - 98, 70, 309, 297, 236, 178, 95, 319, 142, 258, - 247, 267, 249, 264, 250, 195, 231, 199, 246, 324, - 317, 253, 254, 259, 126, 137, 133, 251, 234, 237, - 1, 326, 290, 105, 143, 156, 212, 10, 54, 88, - 84, 83, 484, 109, 322, 282, 37, 224, 321, 223, - 245, 208, 211, 320, 281, 90, 111, 298, 182, 98, - 56, 245, 298, 211, 178, 95, 103, 147, 258, 197, - 102, 75, 141, 250, 195, 231, 95, 246, 324, 258, - 279, 242, 89, 24, 250, 195, 231, 280, 246, 324, - 298, 298, 298, 298, 298, 298, 298, 16, 298, 192, - 277, 298, 298, 18, 294, 44, 45, 38, 298, 298, - 251, 234, 237, 2, 298, 296, 298, 298, 298, 212, - 10, 54, 310, 312, 313, 314, 109, 162, 298, 298, - 224, 321, 223, 298, 298, 298, 294, 282, 298, 42, - 22, 239, 251, 234, 237, 2, 298, 296, 298, 298, - 298, 212, 10, 54, 298, 159, 298, 298, 109, 298, - 298, 17, 224, 321, 223, 282, 298, 42, 22, 239, - 298, 298, 245, 298, 211, 278, 298, 103, 111, 298, - 183, 98, 70, 298, 298, 298, 298, 95, 298, 298, - 258, 298, 292, 17, 298, 250, 195, 231, 279, 246, - 324, 24, 298, 395, 245, 280, 211, 298, 298, 103, - 298, 298, 197, 102, 75, 16, 298, 140, 298, 95, - 298, 18, 258, 298, 298, 298, 298, 250, 195, 231, - 298, 246, 324, 298, 298, 298, 298, 428, 298, 395, - 395, 395, 202, 277, 298, 245, 298, 211, 298, 428, - 103, 298, 298, 197, 120, 69, 395, 395, 395, 395, - 95, 298, 298, 258, 298, 298, 298, 160, 250, 195, - 231, 86, 246, 324, 245, 16, 211, 282, 298, 103, - 196, 18, 197, 120, 69, 298, 44, 45, 38, 95, - 298, 298, 258, 298, 298, 298, 178, 250, 195, 231, - 298, 246, 324, 310, 312, 313, 314, 298, 298, 190, - 245, 298, 211, 298, 298, 103, 298, 298, 197, 102, - 75, 298, 298, 298, 298, 95, 298, 298, 258, 298, - 298, 298, 298, 250, 195, 231, 298, 246, 324, 298, - 298, 298, 245, 298, 211, 298, 199, 100, 298, 288, - 197, 120, 47, 298, 106, 298, 298, 95, 298, 353, - 258, 155, 298, 218, 298, 250, 195, 231, 298, 246, - 324, 282, 16, 42, 22, 239, 298, 245, 18, 211, - 298, 428, 103, 298, 298, 197, 120, 69, 298, 298, - 298, 298, 95, 428, 298, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 100, 189, 298, 197, 120, 59, 245, 207, 211, - 298, 95, 103, 298, 258, 197, 120, 81, 298, 250, - 195, 231, 95, 246, 324, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 197, 120, 80, 298, 298, - 298, 298, 95, 298, 298, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 197, 120, 67, 245, 298, 211, - 298, 95, 103, 298, 258, 197, 120, 57, 298, 250, - 195, 231, 95, 246, 324, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 197, 120, 58, 298, 298, - 298, 298, 95, 298, 298, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 197, 120, 82, 245, 298, 211, - 298, 95, 103, 298, 258, 197, 97, 76, 298, 250, - 195, 231, 95, 246, 324, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 197, 120, 71, 298, 298, - 298, 298, 95, 298, 298, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 187, 120, 61, 245, 298, 211, - 298, 95, 103, 298, 258, 197, 120, 63, 298, 250, - 195, 231, 95, 246, 324, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 197, 94, 79, 298, 298, - 298, 298, 95, 298, 298, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 197, 120, 59, 245, 298, 211, - 298, 95, 103, 298, 258, 197, 120, 77, 298, 250, - 195, 231, 95, 246, 324, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 188, 108, 64, 298, 298, - 298, 298, 95, 298, 298, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 197, 120, 65, 245, 298, 211, - 298, 95, 103, 298, 258, 197, 97, 66, 298, 250, - 195, 231, 95, 246, 324, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 197, 120, 68, 298, 298, - 298, 298, 95, 298, 298, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 197, 120, 62, 245, 298, 211, - 298, 95, 103, 298, 258, 197, 120, 60, 298, 250, - 195, 231, 95, 246, 324, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 197, 120, 74, 298, 298, - 298, 298, 95, 298, 298, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 197, 120, 72, 245, 298, 211, - 298, 95, 103, 298, 258, 197, 120, 48, 298, 250, - 195, 231, 95, 246, 324, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 197, 120, 46, 298, 298, - 298, 298, 95, 298, 298, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 197, 120, 78, 245, 298, 211, - 298, 95, 103, 298, 258, 197, 120, 73, 298, 250, - 195, 231, 95, 246, 324, 258, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 197, 125, 298, 298, 298, - 298, 298, 95, 298, 298, 298, 298, 298, 298, 244, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 197, 114, 298, 245, 298, 211, - 298, 95, 103, 298, 298, 197, 122, 298, 243, 250, - 195, 231, 95, 246, 324, 298, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 197, 117, 298, 298, 298, - 298, 298, 95, 298, 298, 298, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 197, 121, 298, 245, 298, 211, - 298, 95, 103, 298, 298, 197, 124, 298, 298, 250, - 195, 231, 95, 246, 324, 298, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 298, 245, 298, 211, - 298, 298, 103, 298, 298, 197, 118, 298, 298, 298, - 298, 298, 95, 298, 298, 298, 298, 298, 298, 298, - 250, 195, 231, 298, 246, 324, 245, 298, 211, 298, - 298, 103, 298, 298, 197, 123, 298, 245, 298, 211, - 298, 95, 103, 298, 298, 197, 113, 298, 298, 250, - 195, 231, 95, 246, 324, 298, 298, 298, 298, 298, - 250, 195, 231, 220, 246, 324, 298, 27, 298, 16, - 298, 457, 298, 298, 457, 18, 298, 26, 457, 441, - 44, 45, 38, 217, 44, 45, 38, 298, 298, 298, - 298, 298, 298, 298, 298, 298, 298, 310, 312, 313, - 314, 310, 312, 313, 314, 298, 441, 298, 298, 441, - 298, 457, 220, 441, 457, 298, 298, 457, 298, 298, - 457, 457, 441, 457, 298, 298, 220, 457, 441, 298, - 298, 298, 298, 298, 457, 298, 298, 457, 298, 298, - 5, 457, 441, 298, 298, 298, 298, 298, 298, 441, - 298, 298, 441, 298, 457, 441, 441, 298, 441, 298, - 457, 298, 441, 306, 298, 298, 298, 298, 298, 441, - 298, 298, 441, 298, 457, 220, 441, 298, 298, 298, - 298, 298, 298, 457, 298, 298, 457, 298, 298, 15, - 457, 441, 35, 274, 44, 45, 38, 457, 298, 298, - 457, 298, 298, 298, 457, 441, 298, 298, 298, 298, - 298, 310, 312, 313, 314, 298, 298, 298, 441, 298, - 298, 441, 298, 457, 298, 441, 287, 298, 44, 45, - 38, 298, 441, 298, 298, 441, 298, 457, 298, 441, - 248, 298, 298, 298, 298, 310, 312, 313, 314, 298, - 44, 45, 38, 298, 298, 112, 298, 44, 45, 38, - 298, 173, 298, 298, 44, 45, 38, 310, 312, 313, - 314, 44, 45, 38, 310, 312, 313, 314, 298, 298, - 299, 310, 312, 313, 314, 44, 45, 38, 310, 312, - 313, 314, 174, 298, 298, 298, 138, 298, 298, 298, - 298, 298, 310, 312, 313, 314, 44, 45, 38, 298, - 298, 298, 44, 45, 38, 298, 44, 45, 38, 298, - 44, 45, 38, 310, 312, 313, 314, 307, 298, 310, - 312, 313, 314, 310, 312, 313, 314, 310, 312, 313, - 314, - ); - - public static $yy_lookahead = array( - 10, 11, 12, 13, 74, 15, 36, 17, 1, 19, - 20, 21, 29, 103, 84, 45, 26, 14, 48, 36, - 30, 31, 32, 53, 34, 22, 36, 24, 98, 39, - 27, 48, 42, 43, 44, 45, 33, 47, 35, 49, - 37, 51, 52, 53, 54, 14, 16, 16, 45, 59, - 60, 96, 10, 11, 12, 13, 1, 15, 27, 17, - 53, 19, 20, 21, 33, 27, 1, 36, 26, 14, - 45, 33, 30, 31, 32, 45, 34, 52, 36, 48, - 72, 39, 27, 75, 42, 43, 44, 45, 33, 47, - 82, 49, 27, 51, 52, 15, 54, 17, 33, 91, - 83, 59, 60, 95, 10, 11, 12, 13, 13, 15, - 15, 17, 17, 19, 20, 21, 97, 35, 99, 100, - 26, 86, 87, 88, 30, 31, 32, 66, 34, 49, - 36, 51, 96, 39, 54, 53, 42, 43, 44, 45, - 72, 47, 16, 49, 18, 51, 52, 79, 54, 54, - 82, 14, 18, 59, 60, 1, 10, 11, 12, 13, - 23, 15, 15, 17, 27, 19, 20, 21, 14, 17, - 33, 13, 26, 15, 48, 17, 30, 31, 32, 45, - 34, 27, 36, 46, 83, 39, 52, 33, 42, 43, - 44, 45, 34, 47, 74, 49, 10, 51, 52, 13, - 54, 54, 50, 17, 84, 59, 60, 14, 10, 11, - 12, 13, 54, 15, 45, 17, 23, 19, 20, 21, - 27, 52, 100, 103, 26, 35, 33, 37, 30, 31, - 32, 22, 34, 67, 36, 69, 50, 39, 83, 46, - 42, 43, 44, 45, 35, 47, 72, 49, 10, 51, - 52, 13, 54, 79, 80, 17, 82, 59, 60, 1, - 10, 11, 12, 13, 16, 15, 18, 17, 72, 19, - 20, 21, 14, 107, 108, 79, 26, 71, 82, 18, - 30, 31, 32, 1, 34, 27, 36, 15, 50, 39, - 45, 33, 42, 43, 44, 45, 48, 47, 53, 49, - 10, 51, 52, 13, 54, 99, 100, 17, 36, 59, - 60, 29, 10, 11, 12, 13, 15, 15, 17, 17, - 13, 19, 20, 21, 8, 9, 54, 72, 26, 67, - 75, 69, 30, 31, 32, 78, 34, 82, 36, 24, - 50, 39, 17, 36, 42, 43, 44, 45, 74, 47, - 95, 49, 51, 51, 52, 54, 54, 35, 84, 37, - 103, 59, 60, 36, 10, 11, 12, 13, 74, 15, - 108, 17, 23, 19, 20, 21, 10, 103, 84, 13, - 26, 23, 36, 17, 30, 31, 32, 7, 34, 9, - 36, 17, 98, 39, 48, 46, 42, 43, 44, 45, - 17, 47, 53, 49, 46, 51, 52, 93, 54, 78, - 16, 1, 36, 59, 60, 101, 10, 11, 12, 13, - 35, 15, 37, 17, 48, 19, 20, 21, 18, 36, - 65, 66, 26, 74, 103, 104, 30, 31, 32, 45, - 34, 48, 36, 84, 36, 39, 52, 17, 42, 43, - 44, 45, 15, 47, 17, 49, 10, 51, 52, 13, - 54, 18, 74, 17, 82, 59, 60, 34, 10, 11, - 12, 13, 84, 15, 93, 17, 15, 19, 20, 21, - 1, 2, 101, 101, 26, 99, 100, 17, 30, 31, - 32, 48, 34, 96, 36, 98, 96, 39, 98, 71, - 42, 43, 44, 45, 35, 47, 37, 49, 27, 51, - 52, 67, 54, 69, 33, 54, 74, 59, 60, 17, - 10, 11, 12, 13, 96, 15, 84, 17, 34, 19, - 20, 21, 45, 78, 63, 64, 26, 99, 100, 16, - 30, 31, 32, 16, 34, 23, 36, 17, 17, 39, - 23, 51, 42, 43, 44, 45, 72, 47, 103, 49, - 78, 51, 52, 17, 54, 74, 82, 41, 46, 59, - 60, 67, 68, 69, 70, 84, 72, 73, 53, 75, - 76, 77, 53, 61, 15, 103, 82, 14, 51, 85, - 14, 37, 17, 8, 90, 91, 92, 1, 94, 95, - 3, 4, 5, 6, 7, 96, 82, 10, 11, 12, - 13, 97, 84, 81, 96, 74, 19, 20, 21, 78, - 82, 82, 1, 26, 104, 84, 2, 30, 31, 32, - 67, 68, 69, 70, 98, 72, 73, 109, 75, 76, - 77, 67, 109, 69, 103, 82, 72, 96, 85, 75, - 76, 77, 96, 90, 91, 92, 82, 94, 95, 85, - 10, 14, 96, 13, 90, 91, 92, 17, 94, 95, - 109, 109, 109, 109, 109, 109, 109, 27, 109, 105, - 106, 109, 109, 33, 4, 38, 39, 40, 109, 109, - 10, 11, 12, 13, 109, 15, 109, 109, 109, 19, - 20, 21, 55, 56, 57, 58, 26, 74, 109, 109, - 30, 31, 32, 109, 109, 109, 4, 84, 109, 86, - 87, 88, 10, 11, 12, 13, 109, 15, 109, 109, - 109, 19, 20, 21, 109, 74, 109, 109, 26, 109, - 60, 61, 30, 31, 32, 84, 109, 86, 87, 88, - 109, 109, 67, 109, 69, 70, 109, 72, 73, 109, - 75, 76, 77, 109, 109, 109, 109, 82, 109, 109, - 85, 109, 60, 61, 109, 90, 91, 92, 10, 94, - 95, 13, 109, 2, 67, 17, 69, 109, 109, 72, - 109, 109, 75, 76, 77, 27, 109, 29, 109, 82, - 109, 33, 85, 109, 109, 109, 109, 90, 91, 92, - 109, 94, 95, 109, 109, 109, 109, 36, 109, 38, - 39, 40, 105, 106, 109, 67, 109, 69, 109, 48, - 72, 109, 109, 75, 76, 77, 55, 56, 57, 58, - 82, 109, 109, 85, 109, 109, 109, 74, 90, 91, - 92, 78, 94, 95, 67, 27, 69, 84, 109, 72, - 102, 33, 75, 76, 77, 109, 38, 39, 40, 82, - 109, 109, 85, 109, 109, 109, 103, 90, 91, 92, - 109, 94, 95, 55, 56, 57, 58, 109, 109, 102, - 67, 109, 69, 109, 109, 72, 109, 109, 75, 76, - 77, 109, 109, 109, 109, 82, 109, 109, 85, 109, - 109, 109, 109, 90, 91, 92, 109, 94, 95, 109, - 109, 109, 67, 109, 69, 109, 1, 72, 109, 106, - 75, 76, 77, 109, 79, 109, 109, 82, 109, 14, - 85, 74, 109, 18, 109, 90, 91, 92, 109, 94, - 95, 84, 27, 86, 87, 88, 109, 67, 33, 69, - 109, 36, 72, 109, 109, 75, 76, 77, 109, 109, - 109, 109, 82, 48, 109, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 102, 109, 75, 76, 77, 67, 79, 69, - 109, 82, 72, 109, 85, 75, 76, 77, 109, 90, - 91, 92, 82, 94, 95, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 77, 109, 109, - 109, 109, 82, 109, 109, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 77, 67, 109, 69, - 109, 82, 72, 109, 85, 75, 76, 77, 109, 90, - 91, 92, 82, 94, 95, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 77, 109, 109, - 109, 109, 82, 109, 109, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 77, 67, 109, 69, - 109, 82, 72, 109, 85, 75, 76, 77, 109, 90, - 91, 92, 82, 94, 95, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 77, 109, 109, - 109, 109, 82, 109, 109, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 77, 67, 109, 69, - 109, 82, 72, 109, 85, 75, 76, 77, 109, 90, - 91, 92, 82, 94, 95, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 77, 109, 109, - 109, 109, 82, 109, 109, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 77, 67, 109, 69, - 109, 82, 72, 109, 85, 75, 76, 77, 109, 90, - 91, 92, 82, 94, 95, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 77, 109, 109, - 109, 109, 82, 109, 109, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 77, 67, 109, 69, - 109, 82, 72, 109, 85, 75, 76, 77, 109, 90, - 91, 92, 82, 94, 95, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 77, 109, 109, - 109, 109, 82, 109, 109, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 77, 67, 109, 69, - 109, 82, 72, 109, 85, 75, 76, 77, 109, 90, - 91, 92, 82, 94, 95, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 77, 109, 109, - 109, 109, 82, 109, 109, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 77, 67, 109, 69, - 109, 82, 72, 109, 85, 75, 76, 77, 109, 90, - 91, 92, 82, 94, 95, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 77, 109, 109, - 109, 109, 82, 109, 109, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 77, 67, 109, 69, - 109, 82, 72, 109, 85, 75, 76, 77, 109, 90, - 91, 92, 82, 94, 95, 85, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 109, 109, 109, - 109, 109, 82, 109, 109, 109, 109, 109, 109, 89, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 109, 67, 109, 69, - 109, 82, 72, 109, 109, 75, 76, 109, 89, 90, - 91, 92, 82, 94, 95, 109, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 109, 109, 109, - 109, 109, 82, 109, 109, 109, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 109, 67, 109, 69, - 109, 82, 72, 109, 109, 75, 76, 109, 109, 90, - 91, 92, 82, 94, 95, 109, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 109, 67, 109, 69, - 109, 109, 72, 109, 109, 75, 76, 109, 109, 109, - 109, 109, 82, 109, 109, 109, 109, 109, 109, 109, - 90, 91, 92, 109, 94, 95, 67, 109, 69, 109, - 109, 72, 109, 109, 75, 76, 109, 67, 109, 69, - 109, 82, 72, 109, 109, 75, 76, 109, 109, 90, - 91, 92, 82, 94, 95, 109, 109, 109, 109, 109, - 90, 91, 92, 2, 94, 95, 109, 25, 109, 27, - 109, 10, 109, 109, 13, 33, 109, 16, 17, 18, - 38, 39, 40, 37, 38, 39, 40, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 55, 56, 57, - 58, 55, 56, 57, 58, 109, 45, 109, 109, 48, - 109, 50, 2, 52, 10, 109, 109, 13, 109, 109, - 10, 17, 18, 13, 109, 109, 2, 17, 18, 109, - 109, 109, 109, 109, 10, 109, 109, 13, 109, 109, - 16, 17, 18, 109, 109, 109, 109, 109, 109, 45, - 109, 109, 48, 109, 50, 45, 52, 109, 48, 109, - 50, 109, 52, 53, 109, 109, 109, 109, 109, 45, - 109, 109, 48, 109, 50, 2, 52, 109, 109, 109, - 109, 109, 109, 10, 109, 109, 13, 109, 109, 2, - 17, 18, 2, 37, 38, 39, 40, 10, 109, 109, - 13, 109, 109, 109, 17, 18, 109, 109, 109, 109, - 109, 55, 56, 57, 58, 109, 109, 109, 45, 109, - 109, 48, 109, 50, 109, 52, 14, 109, 38, 39, - 40, 109, 45, 109, 109, 48, 109, 50, 109, 52, - 14, 109, 109, 109, 109, 55, 56, 57, 58, 109, - 38, 39, 40, 109, 109, 22, 109, 38, 39, 40, - 109, 14, 109, 109, 38, 39, 40, 55, 56, 57, - 58, 38, 39, 40, 55, 56, 57, 58, 109, 109, - 61, 55, 56, 57, 58, 38, 39, 40, 55, 56, - 57, 58, 14, 109, 109, 109, 28, 109, 109, 109, - 109, 109, 55, 56, 57, 58, 38, 39, 40, 109, - 109, 109, 38, 39, 40, 109, 38, 39, 40, 109, - 38, 39, 40, 55, 56, 57, 58, 53, 109, 55, - 56, 57, 58, 55, 56, 57, 58, 55, 56, 57, - 58, - ); - - public static $yy_shift_ofst = array( - -31, 406, 406, 458, 458, 94, 510, 94, 94, 94, - 510, 458, -10, 94, 94, 354, 146, 94, 94, 94, - 94, 146, 94, 94, 94, 94, 250, 94, 94, 94, - 94, 94, 94, 302, 94, 94, 94, 198, 42, 42, - 42, 42, 42, 42, 42, 42, 1772, 828, 828, 80, - 712, 925, 301, 65, 272, 680, 1942, 1920, 1886, 1776, - 647, 1949, 1977, 2008, 2004, 1963, 1998, 1956, 2012, 2012, - 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, - 2012, 2012, 2012, 768, 650, 272, 65, 272, 65, 134, - 126, 479, 597, 1854, 154, 290, 95, 55, 258, 366, - 248, 366, 282, 443, 437, 38, 38, 437, 7, 481, - 410, 38, 461, 621, 596, 596, 261, 596, 596, 261, - 596, 596, 596, 596, 596, -31, -31, 1840, 1791, 1917, - 1903, 1834, 158, 238, 394, 446, 38, 25, 147, 169, - 147, 25, 169, 25, 38, 38, 25, 25, 38, 25, - 307, 38, 38, 25, 527, 38, 38, 25, 38, 38, - 38, 38, 38, 596, 624, 261, 624, 327, 596, 596, - 261, 596, 261, -31, -31, -31, -31, -31, -31, 781, - 3, 31, 193, 137, -30, 186, -17, 522, 349, 469, - 322, 30, 82, 316, 346, 376, 190, 358, 393, 152, - 209, 380, 385, 245, 315, 523, 585, 554, 576, 575, - 537, 573, 569, 529, 525, 546, 500, 526, 531, 325, - 530, 487, 494, 502, 470, 433, 430, 408, 383, 327, - 374, - ); - - public static $yy_reduce_ofst = array( - 471, 504, 563, 717, 574, 685, 919, 890, 787, 758, - 855, 823, 1240, 1199, 1140, 1100, 1070, 1129, 1170, 1210, - 1269, 1280, 1310, 1339, 1350, 1380, 1409, 1420, 1450, 1479, - 1490, 1059, 1030, 1000, 930, 960, 989, 1520, 1549, 1700, - 1619, 1689, 1660, 1630, 1590, 1560, 633, 661, 867, 8, - 166, 773, 255, 541, 174, 262, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 294, -70, 196, 120, 68, 274, 19, - 206, 331, 444, 428, 257, 400, 382, 257, 257, 400, - 386, 397, 257, 386, 381, 388, 359, 314, 257, 442, - 482, 491, 484, 257, 257, 455, 386, 257, 257, 438, - 257, 257, 257, 257, 257, 257, 365, 509, 509, 509, - 509, 509, 524, 536, 509, 509, 528, 514, 539, 551, - 538, 514, 556, 514, 528, 528, 514, 514, 528, 514, - 518, 528, 528, 514, 532, 528, 528, 514, 528, 528, - 528, 528, 528, -90, 520, 122, 520, 566, -90, -90, - 122, -90, 122, -45, 36, 155, 101, 61, 17, - ); - - public static $yyExpectedTokens = array( - array(), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 53, 54, 59, - 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array( - 10, 11, 12, 13, 15, 17, 19, 20, 21, 26, 30, 31, 32, 34, 36, 39, 42, 43, 44, 45, 47, 49, 51, 52, 54, 59, 60, - ), - array(25, 27, 33, 38, 39, 40, 55, 56, 57, 58,), - array(27, 33, 38, 39, 40, 55, 56, 57, 58,), - array(27, 33, 38, 39, 40, 55, 56, 57, 58,), - array(15, 17, 49, 51, 54,), - array(4, 10, 11, 12, 13, 15, 19, 20, 21, 26, 30, 31, 32, 60, 61,), - array(1, 14, 18, 27, 33, 36, 48,), - array(15, 17, 51, 54,), - array(1, 27, 33,), - array(15, 36, 54,), - array(4, 10, 11, 12, 13, 15, 19, 20, 21, 26, 30, 31, 32, 60, 61,), - array(14, 38, 39, 40, 55, 56, 57, 58,), - array(2, 38, 39, 40, 55, 56, 57, 58,), - array(37, 38, 39, 40, 55, 56, 57, 58,), - array(37, 38, 39, 40, 55, 56, 57, 58,), - array(14, 38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58, 61,), - array(14, 38, 39, 40, 55, 56, 57, 58,), - array(14, 38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 53, 55, 56, 57, 58,), - array(22, 38, 39, 40, 55, 56, 57, 58,), - array(28, 38, 39, 40, 55, 56, 57, 58,), - array(14, 38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(38, 39, 40, 55, 56, 57, 58,), - array(10, 13, 17, 27, 29, 33,), - array(10, 13, 17, 27, 33,), - array(15, 36, 54,), - array(1, 27, 33,), - array(15, 36, 54,), - array(1, 27, 33,), - array(18, 45, 52,), - array(16, 18, 48,), - array(1, 2,), - array(3, 4, 5, 6, 7, 10, 11, 12, 13, 19, 20, 21, 26, 30, 31, 32,), - array(2, 10, 13, 16, 17, 18, 45, 48, 50, 52,), - array(1, 14, 27, 33,), - array(10, 13, 17, 50,), - array(13, 15, 17, 54,), - array(1, 14, 27, 33,), - array(1, 14, 27, 33,), - array(10, 13, 17,), - array(16, 18, 48,), - array(10, 13, 17,), - array(1, 29,), - array(18, 48,), - array(15, 17,), - array(27, 33,), - array(27, 33,), - array(15, 17,), - array(1, 53,), - array(27, 33,), - array(1, 18,), - array(27, 33,), - array(15, 54,), - array(1,), - array(1,), - array(1,), - array(18,), - array(1,), - array(1,), - array(18,), - array(1,), - array(1,), - array(1,), - array(1,), - array(1,), - array(), - array(), - array(2, 10, 13, 17, 18, 45, 48, 50, 52, 53,), - array(2, 10, 13, 16, 17, 18, 45, 48, 50, 52,), - array(2, 10, 13, 17, 18, 45, 48, 50, 52,), - array(2, 10, 13, 17, 18, 45, 48, 50, 52,), - array(10, 13, 17, 18, 45, 48, 50, 52,), - array(13, 15, 17, 34, 54,), - array(10, 13, 17, 50,), - array(16, 45, 52,), - array(10, 13, 17,), - array(27, 33,), - array(45, 52,), - array(15, 54,), - array(45, 52,), - array(15, 54,), - array(45, 52,), - array(45, 52,), - array(45, 52,), - array(27, 33,), - array(27, 33,), - array(45, 52,), - array(45, 52,), - array(27, 33,), - array(45, 52,), - array(13, 36,), - array(27, 33,), - array(27, 33,), - array(45, 52,), - array(16, 23,), - array(27, 33,), - array(27, 33,), - array(45, 52,), - array(27, 33,), - array(27, 33,), - array(27, 33,), - array(27, 33,), - array(27, 33,), - array(1,), - array(2,), - array(18,), - array(2,), - array(36,), - array(1,), - array(1,), - array(18,), - array(1,), - array(18,), - array(), - array(), - array(), - array(), - array(), - array(), - array(2, 36, 38, 39, 40, 48, 55, 56, 57, 58,), - array(14, 22, 24, 27, 33, 35, 37, 45,), - array(14, 16, 27, 33, 36, 48,), - array(14, 23, 27, 33, 46,), - array(14, 23, 27, 33, 46,), - array(36, 45, 48, 53,), - array(10, 13, 17, 50,), - array(29, 36, 48,), - array(23, 46, 61,), - array(23, 46, 53,), - array(35, 37,), - array(35, 37,), - array(16, 45,), - array(35, 53,), - array(8, 9,), - array(36, 48,), - array(36, 48,), - array(35, 37,), - array(23, 46,), - array(36, 48,), - array(17, 50,), - array(22, 35,), - array(7, 9,), - array(35, 37,), - array(45, 53,), - array(24,), - array(16,), - array(8,), - array(37,), - array(14,), - array(17,), - array(51,), - array(14,), - array(15,), - array(53,), - array(53,), - array(17,), - array(51,), - array(41,), - array(17,), - array(17,), - array(17,), - array(45,), - array(34,), - array(17,), - array(17,), - array(34,), - array(17,), - array(36,), - array(17,), - array(36,), - array(17,), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - array(), - ); - - public static $yy_default = array( - 338, 514, 514, 499, 499, 514, 514, 476, 476, 476, - 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, - 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, - 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, - 514, 514, 514, 514, 514, 514, 379, 358, 379, 514, - 514, 415, 514, 379, 514, 514, 351, 514, 514, 514, - 514, 514, 514, 514, 514, 514, 384, 514, 399, 475, - 351, 403, 390, 474, 500, 502, 384, 501, 363, 381, - 404, 386, 391, 379, 379, 514, 379, 514, 379, 489, - 431, 370, 327, 430, 393, 441, 514, 393, 393, 441, - 431, 441, 393, 431, 514, 379, 360, 514, 393, 379, - 373, 379, 514, 406, 402, 375, 431, 396, 398, 486, - 393, 408, 397, 407, 406, 483, 336, 430, 430, 430, - 430, 430, 514, 443, 457, 441, 367, 438, 514, 436, - 514, 435, 434, 466, 368, 348, 439, 437, 361, 467, - 441, 356, 354, 468, 514, 366, 355, 469, 362, 359, - 352, 369, 365, 371, 478, 463, 477, 441, 374, 376, - 490, 424, 487, 441, 441, 482, 482, 336, 482, 415, - 411, 415, 405, 405, 415, 442, 415, 405, 405, 514, - 514, 411, 514, 514, 425, 514, 514, 405, 415, 514, - 514, 334, 514, 411, 387, 514, 514, 514, 514, 514, - 514, 514, 514, 420, 514, 514, 514, 417, 514, 514, - 514, 411, 413, 514, 514, 514, 514, 488, 514, 457, - 514, 421, 364, 420, 340, 422, 357, 341, 409, 400, - 480, 457, 462, 401, 485, 423, 426, 342, 447, 380, - 416, 339, 428, 329, 330, 444, 445, 446, 394, 331, - 395, 429, 419, 388, 332, 418, 410, 392, 412, 333, - 335, 414, 337, 472, 417, 479, 427, 497, 347, 461, - 460, 459, 378, 346, 464, 510, 495, 511, 498, 473, - 377, 496, 503, 506, 513, 512, 509, 507, 504, 508, - 345, 458, 471, 448, 505, 454, 452, 455, 456, 450, - 491, 449, 492, 493, 494, 470, 451, 328, 453, 343, - 344, 372, 481, 432, 433, 465, 440, - ); - - public static $yyFallback = array(); - - public static $yyRuleName = array( - 'start ::= template', - 'template ::= template PHP', - 'template ::= template TEXT', - 'template ::= template STRIPON', - 'template ::= template STRIPOFF', - 'template ::= template LITERALSTART literal_e2 LITERALEND', - 'literal_e2 ::= literal_e1 LITERALSTART literal_e1 LITERALEND', - 'literal_e2 ::= literal_e1', - 'literal_e1 ::= literal_e1 LITERAL', - 'literal_e1 ::=', - 'template ::= template smartytag', - 'template ::=', - 'smartytag ::= SIMPELOUTPUT', - 'smartytag ::= SIMPLETAG', - 'smartytag ::= SMARTYBLOCKCHILDPARENT', - 'smartytag ::= LDEL tagbody RDEL', - 'smartytag ::= tag RDEL', - 'tagbody ::= outattr', - 'tagbody ::= DOLLARID eqoutattr', - 'tagbody ::= varindexed eqoutattr', - 'eqoutattr ::= EQUAL outattr', - 'outattr ::= output attributes', - 'output ::= variable', - 'output ::= value', - 'output ::= expr', - 'tag ::= LDEL ID attributes', - 'tag ::= LDEL ID', - 'tag ::= LDEL ID modifierlist attributes', - 'tag ::= LDEL ID PTR ID attributes', - 'tag ::= LDEL ID PTR ID modifierlist attributes', - 'tag ::= LDELMAKENOCACHE DOLLARID', - 'tag ::= LDELIF expr', - 'tag ::= LDELIF expr attributes', - 'tag ::= LDELIF statement', - 'tag ::= LDELIF statement attributes', - 'tag ::= LDELFOR statements SEMICOLON expr SEMICOLON varindexed foraction attributes', - 'foraction ::= EQUAL expr', - 'foraction ::= INCDEC', - 'tag ::= LDELFOR statement TO expr attributes', - 'tag ::= LDELFOR statement TO expr STEP expr attributes', - 'tag ::= LDELFOREACH SPACE expr AS varvar attributes', - 'tag ::= LDELFOREACH SPACE expr AS varvar APTR varvar attributes', - 'tag ::= LDELFOREACH attributes', - 'tag ::= LDELSETFILTER ID modparameters', - 'tag ::= LDELSETFILTER ID modparameters modifierlist', - 'smartytag ::= CLOSETAG', - 'tag ::= LDELSLASH ID', - 'tag ::= LDELSLASH ID modifierlist', - 'tag ::= LDELSLASH ID PTR ID', - 'tag ::= LDELSLASH ID PTR ID modifierlist', - 'attributes ::= attributes attribute', - 'attributes ::= attribute', - 'attributes ::=', - 'attribute ::= SPACE ID EQUAL ID', - 'attribute ::= ATTR expr', - 'attribute ::= ATTR value', - 'attribute ::= SPACE ID', - 'attribute ::= SPACE expr', - 'attribute ::= SPACE value', - 'attribute ::= SPACE INTEGER EQUAL expr', - 'statements ::= statement', - 'statements ::= statements COMMA statement', - 'statement ::= DOLLARID EQUAL INTEGER', - 'statement ::= DOLLARID EQUAL expr', - 'statement ::= varindexed EQUAL expr', - 'statement ::= OPENP statement CLOSEP', - 'expr ::= value', - 'expr ::= ternary', - 'expr ::= DOLLARID COLON ID', - 'expr ::= expr MATH value', - 'expr ::= expr UNIMATH value', - 'expr ::= expr tlop value', - 'expr ::= expr lop expr', - 'expr ::= expr scond', - 'expr ::= expr ISIN array', - 'expr ::= expr ISIN value', - 'ternary ::= OPENP expr CLOSEP QMARK DOLLARID COLON expr', - 'ternary ::= OPENP expr CLOSEP QMARK expr COLON expr', - 'value ::= variable', - 'value ::= UNIMATH value', - 'value ::= NOT value', - 'value ::= TYPECAST value', - 'value ::= variable INCDEC', - 'value ::= HEX', - 'value ::= INTEGER', - 'value ::= INTEGER DOT INTEGER', - 'value ::= INTEGER DOT', - 'value ::= DOT INTEGER', - 'value ::= ID', - 'value ::= function', - 'value ::= OPENP expr CLOSEP', - 'value ::= variable INSTANCEOF ns1', - 'value ::= variable INSTANCEOF variable', - 'value ::= SINGLEQUOTESTRING', - 'value ::= doublequoted_with_quotes', - 'value ::= varindexed DOUBLECOLON static_class_access', - 'value ::= smartytag', - 'value ::= value modifierlist', - 'value ::= NAMESPACE', - 'value ::= arraydef', - 'value ::= ns1 DOUBLECOLON static_class_access', - 'ns1 ::= ID', - 'ns1 ::= NAMESPACE', - 'variable ::= DOLLARID', - 'variable ::= varindexed', - 'variable ::= varvar AT ID', - 'variable ::= object', - 'variable ::= HATCH ID HATCH', - 'variable ::= HATCH ID HATCH arrayindex', - 'variable ::= HATCH variable HATCH', - 'variable ::= HATCH variable HATCH arrayindex', - 'varindexed ::= DOLLARID arrayindex', - 'varindexed ::= varvar arrayindex', - 'arrayindex ::= arrayindex indexdef', - 'arrayindex ::=', - 'indexdef ::= DOT DOLLARID', - 'indexdef ::= DOT varvar', - 'indexdef ::= DOT varvar AT ID', - 'indexdef ::= DOT ID', - 'indexdef ::= DOT INTEGER', - 'indexdef ::= DOT LDEL expr RDEL', - 'indexdef ::= OPENB ID CLOSEB', - 'indexdef ::= OPENB ID DOT ID CLOSEB', - 'indexdef ::= OPENB SINGLEQUOTESTRING CLOSEB', - 'indexdef ::= OPENB INTEGER CLOSEB', - 'indexdef ::= OPENB DOLLARID CLOSEB', - 'indexdef ::= OPENB variable CLOSEB', - 'indexdef ::= OPENB value CLOSEB', - 'indexdef ::= OPENB expr CLOSEB', - 'indexdef ::= OPENB CLOSEB', - 'varvar ::= DOLLARID', - 'varvar ::= DOLLAR', - 'varvar ::= varvar varvarele', - 'varvarele ::= ID', - 'varvarele ::= SIMPELOUTPUT', - 'varvarele ::= LDEL expr RDEL', - 'object ::= varindexed objectchain', - 'objectchain ::= objectelement', - 'objectchain ::= objectchain objectelement', - 'objectelement ::= PTR ID arrayindex', - 'objectelement ::= PTR varvar arrayindex', - 'objectelement ::= PTR LDEL expr RDEL arrayindex', - 'objectelement ::= PTR ID LDEL expr RDEL arrayindex', - 'objectelement ::= PTR method', - 'function ::= ns1 OPENP params CLOSEP', - 'method ::= ID OPENP params CLOSEP', - 'method ::= DOLLARID OPENP params CLOSEP', - 'params ::= params COMMA expr', - 'params ::= expr', - 'params ::=', - 'modifierlist ::= modifierlist modifier modparameters', - 'modifierlist ::= modifier modparameters', - 'modifier ::= VERT AT ID', - 'modifier ::= VERT ID', - 'modparameters ::= modparameters modparameter', - 'modparameters ::=', - 'modparameter ::= COLON value', - 'modparameter ::= COLON UNIMATH value', - 'modparameter ::= COLON array', - 'static_class_access ::= method', - 'static_class_access ::= method objectchain', - 'static_class_access ::= ID', - 'static_class_access ::= DOLLARID arrayindex', - 'static_class_access ::= DOLLARID arrayindex objectchain', - 'lop ::= LOGOP', - 'lop ::= SLOGOP', - 'tlop ::= TLOGOP', - 'scond ::= SINGLECOND', - 'arraydef ::= OPENB arrayelements CLOSEB', - 'arraydef ::= ARRAYOPEN arrayelements CLOSEP', - 'arrayelements ::= arrayelement', - 'arrayelements ::= arrayelements COMMA arrayelement', - 'arrayelements ::=', - 'arrayelement ::= value APTR expr', - 'arrayelement ::= ID APTR expr', - 'arrayelement ::= expr', - 'doublequoted_with_quotes ::= QUOTE QUOTE', - 'doublequoted_with_quotes ::= QUOTE doublequoted QUOTE', - 'doublequoted ::= doublequoted doublequotedcontent', - 'doublequoted ::= doublequotedcontent', - 'doublequotedcontent ::= BACKTICK variable BACKTICK', - 'doublequotedcontent ::= BACKTICK expr BACKTICK', - 'doublequotedcontent ::= DOLLARID', - 'doublequotedcontent ::= LDEL variable RDEL', - 'doublequotedcontent ::= LDEL expr RDEL', - 'doublequotedcontent ::= smartytag', - 'doublequotedcontent ::= TEXT', - ); +// line 23 "../smarty/lexer/smarty_internal_templateparser.y" - public static $yyRuleInfo = array( - array(0 => 63, 1 => 1), - array(0 => 64, 1 => 2), - array(0 => 64, 1 => 2), - array(0 => 64, 1 => 2), - array(0 => 64, 1 => 2), - array(0 => 64, 1 => 4), - array(0 => 65, 1 => 4), - array(0 => 65, 1 => 1), - array(0 => 66, 1 => 2), - array(0 => 66, 1 => 0), - array(0 => 64, 1 => 2), - array(0 => 64, 1 => 0), - array(0 => 67, 1 => 1), - array(0 => 67, 1 => 1), - array(0 => 67, 1 => 1), - array(0 => 67, 1 => 3), - array(0 => 67, 1 => 2), - array(0 => 68, 1 => 1), - array(0 => 68, 1 => 2), - array(0 => 68, 1 => 2), - array(0 => 71, 1 => 2), - array(0 => 70, 1 => 2), - array(0 => 73, 1 => 1), - array(0 => 73, 1 => 1), - array(0 => 73, 1 => 1), - array(0 => 69, 1 => 3), - array(0 => 69, 1 => 2), - array(0 => 69, 1 => 4), - array(0 => 69, 1 => 5), - array(0 => 69, 1 => 6), - array(0 => 69, 1 => 2), - array(0 => 69, 1 => 2), - array(0 => 69, 1 => 3), - array(0 => 69, 1 => 2), - array(0 => 69, 1 => 3), - array(0 => 69, 1 => 8), - array(0 => 81, 1 => 2), - array(0 => 81, 1 => 1), - array(0 => 69, 1 => 5), - array(0 => 69, 1 => 7), - array(0 => 69, 1 => 6), - array(0 => 69, 1 => 8), - array(0 => 69, 1 => 2), - array(0 => 69, 1 => 3), - array(0 => 69, 1 => 4), - array(0 => 67, 1 => 1), - array(0 => 69, 1 => 2), - array(0 => 69, 1 => 3), - array(0 => 69, 1 => 4), - array(0 => 69, 1 => 5), - array(0 => 74, 1 => 2), - array(0 => 74, 1 => 1), - array(0 => 74, 1 => 0), - array(0 => 84, 1 => 4), - array(0 => 84, 1 => 2), - array(0 => 84, 1 => 2), - array(0 => 84, 1 => 2), - array(0 => 84, 1 => 2), - array(0 => 84, 1 => 2), - array(0 => 84, 1 => 4), - array(0 => 80, 1 => 1), - array(0 => 80, 1 => 3), - array(0 => 79, 1 => 3), - array(0 => 79, 1 => 3), - array(0 => 79, 1 => 3), - array(0 => 79, 1 => 3), - array(0 => 77, 1 => 1), - array(0 => 77, 1 => 1), - array(0 => 77, 1 => 3), - array(0 => 77, 1 => 3), - array(0 => 77, 1 => 3), - array(0 => 77, 1 => 3), - array(0 => 77, 1 => 3), - array(0 => 77, 1 => 2), - array(0 => 77, 1 => 3), - array(0 => 77, 1 => 3), - array(0 => 85, 1 => 7), - array(0 => 85, 1 => 7), - array(0 => 76, 1 => 1), - array(0 => 76, 1 => 2), - array(0 => 76, 1 => 2), - array(0 => 76, 1 => 2), - array(0 => 76, 1 => 2), - array(0 => 76, 1 => 1), - array(0 => 76, 1 => 1), - array(0 => 76, 1 => 3), - array(0 => 76, 1 => 2), - array(0 => 76, 1 => 2), - array(0 => 76, 1 => 1), - array(0 => 76, 1 => 1), - array(0 => 76, 1 => 3), - array(0 => 76, 1 => 3), - array(0 => 76, 1 => 3), - array(0 => 76, 1 => 1), - array(0 => 76, 1 => 1), - array(0 => 76, 1 => 3), - array(0 => 76, 1 => 1), - array(0 => 76, 1 => 2), - array(0 => 76, 1 => 1), - array(0 => 76, 1 => 1), - array(0 => 76, 1 => 3), - array(0 => 91, 1 => 1), - array(0 => 91, 1 => 1), - array(0 => 75, 1 => 1), - array(0 => 75, 1 => 1), - array(0 => 75, 1 => 3), - array(0 => 75, 1 => 1), - array(0 => 75, 1 => 3), - array(0 => 75, 1 => 4), - array(0 => 75, 1 => 3), - array(0 => 75, 1 => 4), - array(0 => 72, 1 => 2), - array(0 => 72, 1 => 2), - array(0 => 96, 1 => 2), - array(0 => 96, 1 => 0), - array(0 => 97, 1 => 2), - array(0 => 97, 1 => 2), - array(0 => 97, 1 => 4), - array(0 => 97, 1 => 2), - array(0 => 97, 1 => 2), - array(0 => 97, 1 => 4), - array(0 => 97, 1 => 3), - array(0 => 97, 1 => 5), - array(0 => 97, 1 => 3), - array(0 => 97, 1 => 3), - array(0 => 97, 1 => 3), - array(0 => 97, 1 => 3), - array(0 => 97, 1 => 3), - array(0 => 97, 1 => 3), - array(0 => 97, 1 => 2), - array(0 => 82, 1 => 1), - array(0 => 82, 1 => 1), - array(0 => 82, 1 => 2), - array(0 => 98, 1 => 1), - array(0 => 98, 1 => 1), - array(0 => 98, 1 => 3), - array(0 => 95, 1 => 2), - array(0 => 99, 1 => 1), - array(0 => 99, 1 => 2), - array(0 => 100, 1 => 3), - array(0 => 100, 1 => 3), - array(0 => 100, 1 => 5), - array(0 => 100, 1 => 6), - array(0 => 100, 1 => 2), - array(0 => 90, 1 => 4), - array(0 => 101, 1 => 4), - array(0 => 101, 1 => 4), - array(0 => 102, 1 => 3), - array(0 => 102, 1 => 1), - array(0 => 102, 1 => 0), - array(0 => 78, 1 => 3), - array(0 => 78, 1 => 2), - array(0 => 103, 1 => 3), - array(0 => 103, 1 => 2), - array(0 => 83, 1 => 2), - array(0 => 83, 1 => 0), - array(0 => 104, 1 => 2), - array(0 => 104, 1 => 3), - array(0 => 104, 1 => 2), - array(0 => 93, 1 => 1), - array(0 => 93, 1 => 2), - array(0 => 93, 1 => 1), - array(0 => 93, 1 => 2), - array(0 => 93, 1 => 3), - array(0 => 87, 1 => 1), - array(0 => 87, 1 => 1), - array(0 => 86, 1 => 1), - array(0 => 88, 1 => 1), - array(0 => 94, 1 => 3), - array(0 => 94, 1 => 3), - array(0 => 105, 1 => 1), - array(0 => 105, 1 => 3), - array(0 => 105, 1 => 0), - array(0 => 106, 1 => 3), - array(0 => 106, 1 => 3), - array(0 => 106, 1 => 1), - array(0 => 92, 1 => 2), - array(0 => 92, 1 => 3), - array(0 => 107, 1 => 2), - array(0 => 107, 1 => 1), - array(0 => 108, 1 => 3), - array(0 => 108, 1 => 3), - array(0 => 108, 1 => 1), - array(0 => 108, 1 => 3), - array(0 => 108, 1 => 3), - array(0 => 108, 1 => 1), - array(0 => 108, 1 => 1), - ); - - public static $yyReduceMap = array( - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 22 => 7, - 23 => 7, - 24 => 7, - 37 => 7, - 57 => 7, - 58 => 7, - 66 => 7, - 67 => 7, - 78 => 7, - 83 => 7, - 84 => 7, - 89 => 7, - 93 => 7, - 94 => 7, - 98 => 7, - 99 => 7, - 101 => 7, - 106 => 7, - 170 => 7, - 175 => 7, - 8 => 8, - 9 => 9, - 10 => 10, - 12 => 12, - 13 => 13, - 14 => 14, - 15 => 15, - 16 => 16, - 17 => 17, - 18 => 18, - 19 => 19, - 20 => 20, - 21 => 21, - 25 => 25, - 26 => 26, - 27 => 27, - 28 => 28, - 29 => 29, - 30 => 30, - 31 => 31, - 32 => 32, - 34 => 32, - 33 => 33, - 35 => 35, - 36 => 36, - 38 => 38, - 39 => 39, - 40 => 40, - 41 => 41, - 42 => 42, - 43 => 43, - 44 => 44, - 45 => 45, - 46 => 46, - 47 => 47, - 48 => 48, - 49 => 49, - 50 => 50, - 51 => 51, - 60 => 51, - 148 => 51, - 152 => 51, - 156 => 51, - 158 => 51, - 52 => 52, - 149 => 52, - 155 => 52, - 53 => 53, - 54 => 54, - 55 => 54, - 56 => 56, - 133 => 56, - 59 => 59, - 61 => 61, - 62 => 62, - 63 => 62, - 64 => 64, - 65 => 65, - 68 => 68, - 69 => 69, - 70 => 69, - 71 => 71, - 72 => 72, - 73 => 73, - 74 => 74, - 75 => 75, - 76 => 76, - 77 => 77, - 79 => 79, - 81 => 79, - 82 => 79, - 113 => 79, - 80 => 80, - 85 => 85, - 86 => 86, - 87 => 87, - 88 => 88, - 90 => 90, - 91 => 91, - 92 => 91, - 95 => 95, - 96 => 96, - 97 => 97, - 100 => 100, - 102 => 102, - 103 => 103, - 104 => 104, - 105 => 105, - 107 => 107, - 108 => 108, - 109 => 109, - 110 => 110, - 111 => 111, - 112 => 112, - 114 => 114, - 172 => 114, - 115 => 115, - 116 => 116, - 117 => 117, - 118 => 118, - 119 => 119, - 120 => 120, - 128 => 120, - 121 => 121, - 122 => 122, - 123 => 123, - 124 => 123, - 126 => 123, - 127 => 123, - 125 => 125, - 129 => 129, - 130 => 130, - 131 => 131, - 176 => 131, - 132 => 132, - 134 => 134, - 135 => 135, - 136 => 136, - 137 => 137, - 138 => 138, - 139 => 139, - 140 => 140, - 141 => 141, - 142 => 142, - 143 => 143, - 144 => 144, - 145 => 145, - 146 => 146, - 147 => 147, - 150 => 150, - 151 => 151, - 153 => 153, - 154 => 154, - 157 => 157, - 159 => 159, - 160 => 160, - 161 => 161, - 162 => 162, - 163 => 163, - 164 => 164, - 165 => 165, - 166 => 166, - 167 => 167, - 168 => 168, - 169 => 168, - 171 => 171, - 173 => 173, - 174 => 174, - 177 => 177, - 178 => 178, - 179 => 179, - 180 => 180, - 183 => 180, - 181 => 181, - 184 => 181, - 182 => 182, - 185 => 185, - 186 => 186, - ); + const ERR1 = 'Security error: Call to private object member not allowed'; + const ERR2 = 'Security error: Call to dynamic object member not allowed'; /** * result status @@ -1654,13 +81,19 @@ class Smarty_Internal_Templateparser */ public $lex; + /** + * internal error flag + * + * @var bool + */ + private $internalError = false; + /** * {strip} status * * @var bool */ public $strip = false; - /** * compiler object * @@ -1710,54 +143,6 @@ class Smarty_Internal_Templateparser */ public $template_postfix = array(); - public $yyTraceFILE; - - public $yyTracePrompt; - - public $yyidx; - - public $yyerrcnt; - - public $yystack = array(); - - public $yyTokenName = array( - '$', 'VERT', 'COLON', 'PHP', - 'TEXT', 'STRIPON', 'STRIPOFF', 'LITERALSTART', - 'LITERALEND', 'LITERAL', 'SIMPELOUTPUT', 'SIMPLETAG', - 'SMARTYBLOCKCHILDPARENT', 'LDEL', 'RDEL', 'DOLLARID', - 'EQUAL', 'ID', 'PTR', 'LDELMAKENOCACHE', - 'LDELIF', 'LDELFOR', 'SEMICOLON', 'INCDEC', - 'TO', 'STEP', 'LDELFOREACH', 'SPACE', - 'AS', 'APTR', 'LDELSETFILTER', 'CLOSETAG', - 'LDELSLASH', 'ATTR', 'INTEGER', 'COMMA', - 'OPENP', 'CLOSEP', 'MATH', 'UNIMATH', - 'ISIN', 'QMARK', 'NOT', 'TYPECAST', - 'HEX', 'DOT', 'INSTANCEOF', 'SINGLEQUOTESTRING', - 'DOUBLECOLON', 'NAMESPACE', 'AT', 'HATCH', - 'OPENB', 'CLOSEB', 'DOLLAR', 'LOGOP', - 'SLOGOP', 'TLOGOP', 'SINGLECOND', 'ARRAYOPEN', - 'QUOTE', 'BACKTICK', 'error', 'start', - 'template', 'literal_e2', 'literal_e1', 'smartytag', - 'tagbody', 'tag', 'outattr', 'eqoutattr', - 'varindexed', 'output', 'attributes', 'variable', - 'value', 'expr', 'modifierlist', 'statement', - 'statements', 'foraction', 'varvar', 'modparameters', - 'attribute', 'ternary', 'tlop', 'lop', - 'scond', 'array', 'function', 'ns1', - 'doublequoted_with_quotes', 'static_class_access', 'arraydef', 'object', - 'arrayindex', 'indexdef', 'varvarele', 'objectchain', - 'objectelement', 'method', 'params', 'modifier', - 'modparameter', 'arrayelements', 'arrayelement', 'doublequoted', - 'doublequotedcontent', - ); - - /** - * internal error flag - * - * @var bool - */ - private $internalError = false; /* Index of top element in stack */ - private $_retvalue; /* Shifts left before out of the error */ /** * constructor * @@ -1772,16 +157,9 @@ public function __construct(Smarty_Internal_Templatelexer $lex, Smarty_Internal_ $this->smarty = $this->template->smarty; $this->security = isset($this->smarty->security_policy) ? $this->smarty->security_policy : false; $this->current_buffer = $this->root_buffer = new Smarty_Internal_ParseTree_Template(); - } /* The parser's stack */ - public static function yy_destructor($yymajor, $yypminor) - { - switch ($yymajor) { - default: - break; /* If no destructor action specified: do nothing */ - } } - /** + /** * insert PHP code in current buffer * * @param string $code @@ -1823,6 +201,898 @@ public function mergePrefixCode($code) return new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode($tmp, true)); } + + const TP_VERT = 1; + const TP_COLON = 2; + const TP_TEXT = 3; + const TP_STRIPON = 4; + const TP_STRIPOFF = 5; + const TP_LITERALSTART = 6; + const TP_LITERALEND = 7; + const TP_LITERAL = 8; + const TP_SIMPELOUTPUT = 9; + const TP_SIMPLETAG = 10; + const TP_SMARTYBLOCKCHILDPARENT = 11; + const TP_LDEL = 12; + const TP_RDEL = 13; + const TP_DOLLARID = 14; + const TP_EQUAL = 15; + const TP_ID = 16; + const TP_PTR = 17; + const TP_LDELMAKENOCACHE = 18; + const TP_LDELIF = 19; + const TP_LDELFOR = 20; + const TP_SEMICOLON = 21; + const TP_INCDEC = 22; + const TP_TO = 23; + const TP_STEP = 24; + const TP_LDELFOREACH = 25; + const TP_SPACE = 26; + const TP_AS = 27; + const TP_APTR = 28; + const TP_LDELSETFILTER = 29; + const TP_CLOSETAG = 30; + const TP_LDELSLASH = 31; + const TP_ATTR = 32; + const TP_INTEGER = 33; + const TP_COMMA = 34; + const TP_OPENP = 35; + const TP_CLOSEP = 36; + const TP_MATH = 37; + const TP_UNIMATH = 38; + const TP_ISIN = 39; + const TP_QMARK = 40; + const TP_NOT = 41; + const TP_TYPECAST = 42; + const TP_HEX = 43; + const TP_DOT = 44; + const TP_INSTANCEOF = 45; + const TP_SINGLEQUOTESTRING = 46; + const TP_DOUBLECOLON = 47; + const TP_NAMESPACE = 48; + const TP_AT = 49; + const TP_HATCH = 50; + const TP_OPENB = 51; + const TP_CLOSEB = 52; + const TP_DOLLAR = 53; + const TP_LOGOP = 54; + const TP_SLOGOP = 55; + const TP_TLOGOP = 56; + const TP_SINGLECOND = 57; + const TP_ARRAYOPEN = 58; + const TP_QUOTE = 59; + const TP_BACKTICK = 60; + const YY_NO_ACTION = 514; + const YY_ACCEPT_ACTION = 513; + const YY_ERROR_ACTION = 512; + + const YY_SZ_ACTTAB = 1997; +public static $yy_action = array( + 249, 250, 239, 1, 27, 127, 220, 184, 160, 213, + 11, 54, 278, 10, 173, 34, 108, 387, 282, 279, + 223, 321, 221, 8, 194, 387, 18, 387, 85, 41, + 387, 285, 42, 44, 264, 222, 387, 209, 387, 198, + 387, 52, 5, 307, 288, 288, 164, 283, 224, 4, + 50, 249, 250, 239, 1, 232, 131, 381, 189, 205, + 213, 11, 54, 39, 35, 243, 31, 108, 94, 17, + 381, 223, 321, 221, 439, 226, 381, 33, 49, 426, + 41, 439, 89, 42, 44, 264, 222, 9, 235, 163, + 198, 426, 52, 5, 131, 288, 212, 284, 102, 106, + 4, 50, 249, 250, 239, 1, 232, 129, 426, 189, + 347, 213, 11, 54, 175, 324, 347, 208, 108, 22, + 426, 301, 223, 321, 221, 302, 226, 135, 18, 49, + 52, 41, 26, 288, 42, 44, 264, 222, 16, 235, + 294, 198, 204, 52, 5, 170, 288, 32, 90, 267, + 268, 4, 50, 249, 250, 239, 1, 20, 129, 185, + 179, 255, 213, 11, 54, 455, 288, 192, 455, 108, + 175, 167, 455, 223, 321, 221, 439, 226, 256, 18, + 55, 292, 41, 439, 132, 42, 44, 264, 222, 427, + 235, 12, 198, 165, 52, 5, 232, 288, 288, 347, + 153, 427, 4, 50, 249, 250, 239, 1, 232, 129, + 286, 181, 347, 213, 11, 54, 24, 13, 347, 49, + 108, 232, 320, 426, 223, 321, 221, 195, 201, 173, + 18, 49, 139, 41, 296, 426, 42, 44, 264, 222, + 7, 235, 286, 198, 49, 52, 5, 147, 288, 117, + 150, 317, 263, 4, 50, 249, 250, 239, 1, 95, + 130, 173, 189, 155, 213, 11, 54, 22, 244, 271, + 192, 108, 323, 286, 101, 223, 321, 221, 294, 226, + 204, 18, 348, 257, 41, 166, 283, 42, 44, 264, + 222, 28, 235, 300, 198, 348, 52, 5, 247, 288, + 117, 348, 94, 206, 4, 50, 249, 250, 239, 1, + 95, 129, 22, 189, 277, 213, 11, 54, 91, 274, + 224, 426, 108, 323, 216, 156, 223, 321, 221, 132, + 180, 262, 18, 426, 100, 41, 12, 288, 42, 44, + 264, 222, 15, 235, 216, 198, 254, 52, 5, 233, + 288, 210, 190, 192, 100, 4, 50, 249, 250, 239, + 1, 3, 131, 94, 189, 192, 213, 11, 54, 269, + 10, 204, 290, 108, 325, 216, 224, 223, 321, 221, + 23, 226, 211, 33, 315, 100, 45, 513, 92, 42, + 44, 264, 222, 102, 235, 178, 198, 268, 52, 5, + 275, 288, 161, 192, 37, 25, 4, 50, 249, 250, + 239, 1, 286, 129, 172, 187, 305, 213, 11, 54, + 164, 283, 310, 141, 108, 281, 281, 236, 223, 321, + 221, 169, 226, 230, 18, 122, 171, 41, 225, 175, + 42, 44, 264, 222, 144, 235, 303, 198, 134, 52, + 5, 265, 288, 151, 286, 192, 175, 4, 50, 249, + 250, 239, 1, 286, 128, 94, 189, 143, 213, 11, + 54, 219, 152, 207, 193, 108, 149, 281, 31, 223, + 321, 221, 100, 226, 21, 6, 286, 288, 41, 158, + 16, 42, 44, 264, 222, 102, 235, 238, 198, 286, + 52, 5, 157, 288, 281, 122, 168, 283, 4, 50, + 249, 250, 239, 1, 30, 93, 308, 51, 215, 213, + 11, 54, 53, 251, 140, 248, 108, 245, 304, 116, + 223, 321, 221, 111, 226, 176, 18, 270, 266, 41, + 224, 322, 42, 44, 264, 222, 7, 235, 259, 198, + 147, 52, 5, 257, 288, 43, 40, 38, 83, 4, + 50, 241, 214, 204, 319, 280, 88, 107, 138, 182, + 97, 64, 311, 312, 313, 316, 95, 281, 298, 258, + 142, 234, 94, 105, 272, 197, 231, 482, 237, 323, + 37, 133, 324, 241, 214, 204, 319, 314, 88, 107, + 296, 183, 97, 82, 84, 43, 40, 38, 95, 296, + 296, 258, 296, 296, 296, 159, 272, 197, 231, 296, + 237, 323, 311, 312, 313, 316, 241, 296, 204, 296, + 296, 103, 296, 296, 199, 104, 77, 296, 296, 110, + 296, 95, 296, 296, 258, 278, 296, 296, 34, 272, + 197, 231, 279, 237, 323, 43, 40, 38, 296, 296, + 296, 241, 26, 204, 196, 276, 103, 296, 16, 199, + 104, 77, 311, 312, 313, 316, 95, 192, 296, 258, + 146, 296, 296, 296, 272, 197, 231, 296, 237, 323, + 286, 393, 39, 35, 243, 296, 296, 296, 296, 191, + 276, 296, 26, 318, 252, 253, 126, 296, 16, 249, + 250, 239, 1, 296, 296, 131, 296, 261, 213, 11, + 54, 296, 296, 296, 426, 108, 393, 393, 393, 223, + 321, 221, 241, 296, 204, 299, 426, 103, 107, 296, + 183, 97, 82, 393, 393, 393, 393, 95, 296, 260, + 258, 52, 296, 296, 288, 272, 197, 231, 296, 237, + 323, 293, 296, 296, 296, 296, 296, 249, 250, 239, + 2, 296, 295, 296, 296, 296, 213, 11, 54, 296, + 296, 177, 296, 108, 136, 296, 296, 223, 321, 221, + 296, 296, 296, 293, 43, 40, 38, 296, 296, 249, + 250, 239, 2, 296, 295, 43, 40, 38, 213, 11, + 54, 311, 312, 313, 316, 108, 296, 291, 14, 223, + 321, 221, 311, 312, 313, 316, 296, 296, 241, 296, + 204, 296, 192, 103, 296, 296, 199, 104, 77, 296, + 296, 296, 296, 95, 383, 296, 258, 296, 296, 297, + 14, 272, 197, 231, 296, 237, 323, 383, 296, 296, + 241, 296, 204, 383, 296, 99, 296, 287, 199, 120, + 48, 241, 112, 204, 296, 95, 103, 296, 258, 199, + 120, 74, 296, 272, 197, 231, 95, 237, 323, 258, + 455, 296, 296, 455, 272, 197, 231, 455, 237, 323, + 241, 296, 204, 296, 296, 103, 200, 296, 199, 120, + 74, 296, 296, 296, 296, 95, 296, 296, 258, 278, + 296, 296, 34, 272, 197, 231, 279, 237, 323, 241, + 455, 204, 296, 296, 99, 202, 296, 199, 120, 56, + 241, 211, 204, 296, 95, 103, 296, 258, 199, 120, + 74, 296, 272, 197, 231, 95, 237, 323, 258, 227, + 296, 296, 296, 272, 197, 231, 296, 237, 323, 241, + 296, 204, 148, 296, 103, 203, 86, 199, 120, 73, + 296, 296, 286, 296, 95, 296, 296, 258, 278, 296, + 296, 34, 272, 197, 231, 279, 237, 323, 241, 296, + 204, 175, 296, 103, 296, 296, 199, 120, 75, 241, + 296, 204, 296, 95, 103, 296, 258, 199, 120, 63, + 296, 272, 197, 231, 95, 237, 323, 258, 229, 192, + 296, 296, 272, 197, 231, 296, 237, 323, 241, 296, + 204, 380, 296, 103, 296, 296, 199, 120, 58, 296, + 296, 296, 296, 95, 380, 296, 258, 296, 296, 296, + 380, 272, 197, 231, 296, 237, 323, 241, 296, 204, + 296, 296, 103, 296, 296, 199, 120, 71, 241, 296, + 204, 296, 95, 103, 296, 258, 199, 120, 79, 296, + 272, 197, 231, 95, 237, 323, 258, 296, 296, 296, + 154, 272, 197, 231, 87, 237, 323, 241, 296, 204, + 286, 296, 103, 296, 296, 199, 120, 70, 296, 296, + 296, 296, 95, 296, 296, 258, 296, 296, 296, 175, + 272, 197, 231, 296, 237, 323, 241, 296, 204, 296, + 296, 103, 296, 296, 199, 120, 56, 241, 296, 204, + 296, 95, 103, 296, 258, 199, 120, 46, 296, 272, + 197, 231, 95, 237, 323, 258, 296, 296, 296, 296, + 272, 197, 231, 296, 237, 323, 241, 296, 204, 296, + 296, 103, 296, 296, 199, 120, 78, 296, 296, 296, + 296, 95, 296, 296, 258, 296, 296, 296, 296, 272, + 197, 231, 296, 237, 323, 241, 296, 204, 296, 296, + 103, 296, 296, 199, 120, 66, 241, 296, 204, 296, + 95, 103, 296, 258, 199, 120, 59, 296, 272, 197, + 231, 95, 237, 323, 258, 296, 296, 296, 296, 272, + 197, 231, 296, 237, 323, 241, 296, 204, 296, 296, + 103, 296, 296, 186, 109, 57, 296, 296, 296, 296, + 95, 296, 296, 258, 296, 296, 296, 296, 272, 197, + 231, 296, 237, 323, 241, 296, 204, 296, 296, 103, + 296, 296, 188, 120, 67, 241, 296, 204, 296, 95, + 103, 296, 258, 199, 96, 62, 296, 272, 197, 231, + 95, 237, 323, 258, 296, 296, 296, 296, 272, 197, + 231, 296, 237, 323, 241, 296, 204, 296, 296, 103, + 296, 296, 199, 120, 80, 296, 296, 296, 296, 95, + 296, 296, 258, 296, 296, 296, 296, 272, 197, 231, + 296, 237, 323, 241, 296, 204, 296, 296, 103, 296, + 296, 199, 120, 76, 241, 296, 204, 296, 95, 103, + 296, 258, 199, 120, 81, 296, 272, 197, 231, 95, + 237, 323, 258, 296, 296, 296, 296, 272, 197, 231, + 296, 237, 323, 241, 296, 204, 296, 296, 103, 296, + 296, 199, 120, 65, 296, 296, 296, 296, 95, 296, + 296, 258, 296, 296, 296, 296, 272, 197, 231, 296, + 237, 323, 241, 296, 204, 296, 296, 103, 296, 296, + 199, 96, 68, 241, 296, 204, 296, 95, 103, 296, + 258, 199, 120, 61, 296, 272, 197, 231, 95, 237, + 323, 258, 296, 296, 296, 296, 272, 197, 231, 296, + 237, 323, 241, 296, 204, 296, 296, 103, 296, 296, + 199, 98, 69, 296, 296, 296, 296, 95, 296, 296, + 258, 296, 296, 296, 296, 272, 197, 231, 296, 237, + 323, 241, 296, 204, 296, 296, 103, 296, 296, 199, + 120, 72, 241, 296, 204, 296, 95, 103, 296, 258, + 199, 120, 47, 296, 272, 197, 231, 95, 237, 323, + 258, 296, 296, 296, 296, 272, 197, 231, 296, 237, + 323, 241, 192, 204, 296, 296, 103, 296, 296, 199, + 120, 60, 296, 296, 351, 296, 95, 296, 217, 258, + 296, 296, 296, 296, 272, 197, 231, 26, 237, 323, + 241, 296, 204, 16, 296, 103, 426, 296, 199, 125, + 296, 241, 296, 204, 296, 95, 103, 296, 426, 199, + 118, 296, 242, 272, 197, 231, 95, 237, 323, 296, + 296, 296, 296, 246, 272, 197, 231, 296, 237, 323, + 241, 296, 204, 278, 296, 103, 34, 296, 199, 121, + 279, 296, 296, 296, 296, 95, 296, 296, 296, 296, + 26, 296, 162, 272, 197, 231, 16, 237, 323, 241, + 296, 204, 296, 296, 103, 296, 296, 199, 123, 296, + 241, 296, 204, 296, 95, 103, 296, 296, 199, 114, + 296, 296, 272, 197, 231, 95, 237, 323, 296, 296, + 296, 296, 296, 272, 197, 231, 296, 237, 323, 241, + 296, 204, 296, 145, 103, 296, 296, 199, 124, 296, + 296, 296, 296, 286, 95, 39, 35, 243, 296, 296, + 296, 296, 272, 197, 231, 296, 237, 323, 241, 296, + 204, 296, 296, 103, 296, 296, 199, 115, 296, 241, + 296, 204, 296, 95, 103, 296, 296, 199, 113, 296, + 296, 272, 197, 231, 95, 237, 323, 296, 296, 296, + 296, 296, 272, 197, 231, 228, 237, 323, 241, 296, + 204, 296, 455, 103, 296, 455, 199, 119, 3, 455, + 439, 296, 296, 95, 296, 296, 296, 296, 296, 296, + 296, 272, 197, 231, 228, 237, 323, 296, 296, 296, + 296, 455, 296, 296, 455, 296, 296, 439, 455, 439, + 439, 228, 455, 296, 439, 296, 296, 137, 455, 296, + 296, 455, 296, 296, 32, 455, 439, 286, 296, 39, + 35, 243, 29, 296, 26, 296, 439, 296, 296, 439, + 16, 455, 296, 439, 306, 43, 40, 38, 296, 296, + 296, 296, 296, 439, 296, 296, 439, 296, 455, 296, + 439, 26, 311, 312, 313, 316, 296, 16, 228, 296, + 296, 296, 43, 40, 38, 455, 296, 296, 455, 296, + 296, 296, 455, 439, 296, 296, 19, 296, 296, 311, + 312, 313, 316, 455, 296, 296, 455, 296, 296, 296, + 455, 439, 296, 296, 296, 43, 40, 38, 296, 296, + 439, 296, 296, 439, 174, 455, 296, 439, 296, 240, + 309, 296, 311, 312, 313, 316, 296, 289, 439, 296, + 36, 439, 296, 455, 296, 439, 296, 296, 43, 40, + 38, 296, 296, 43, 40, 38, 296, 296, 296, 296, + 296, 43, 40, 38, 296, 311, 312, 313, 316, 296, + 311, 312, 313, 316, 296, 43, 40, 38, 311, 312, + 313, 316, 273, 43, 40, 38, 296, 296, 296, 296, + 296, 296, 311, 312, 313, 316, 296, 296, 296, 296, + 311, 312, 313, 316, 455, 296, 296, 455, 43, 40, + 38, 455, 439, 218, 43, 40, 38, 296, 296, 296, + 296, 296, 296, 296, 296, 311, 312, 313, 316, 296, + 296, 311, 312, 313, 316, 296, 296, 296, 296, 439, + 296, 296, 439, 296, 455, 296, 439, + ); + public static $yy_lookahead = array( + 9, 10, 11, 12, 12, 14, 14, 16, 16, 18, + 19, 20, 9, 34, 102, 12, 25, 13, 70, 16, + 29, 30, 31, 35, 33, 21, 35, 23, 95, 38, + 26, 52, 41, 42, 43, 44, 32, 46, 34, 48, + 36, 50, 51, 52, 53, 53, 98, 99, 44, 58, + 59, 9, 10, 11, 12, 22, 14, 13, 16, 15, + 18, 19, 20, 85, 86, 87, 15, 25, 17, 21, + 26, 29, 30, 31, 44, 33, 32, 35, 45, 35, + 38, 51, 34, 41, 42, 43, 44, 35, 46, 77, + 48, 47, 50, 51, 14, 53, 16, 13, 47, 47, + 58, 59, 9, 10, 11, 12, 22, 14, 35, 16, + 26, 18, 19, 20, 102, 103, 32, 44, 25, 34, + 47, 36, 29, 30, 31, 52, 33, 14, 35, 45, + 50, 38, 26, 53, 41, 42, 43, 44, 32, 46, + 66, 48, 68, 50, 51, 77, 53, 15, 35, 7, + 8, 58, 59, 9, 10, 11, 12, 12, 14, 14, + 16, 16, 18, 19, 20, 9, 53, 1, 12, 25, + 102, 82, 16, 29, 30, 31, 44, 33, 33, 35, + 106, 107, 38, 51, 44, 41, 42, 43, 44, 35, + 46, 51, 48, 82, 50, 51, 22, 53, 53, 13, + 73, 47, 58, 59, 9, 10, 11, 12, 22, 14, + 83, 16, 26, 18, 19, 20, 28, 12, 32, 45, + 25, 22, 70, 35, 29, 30, 31, 65, 33, 102, + 35, 45, 73, 38, 60, 47, 41, 42, 43, 44, + 35, 46, 83, 48, 45, 50, 51, 95, 53, 71, + 95, 52, 74, 58, 59, 9, 10, 11, 12, 81, + 14, 102, 16, 73, 18, 19, 20, 34, 90, 36, + 1, 25, 94, 83, 81, 29, 30, 31, 66, 33, + 68, 35, 13, 96, 38, 98, 99, 41, 42, 43, + 44, 15, 46, 100, 48, 26, 50, 51, 14, 53, + 71, 32, 17, 74, 58, 59, 9, 10, 11, 12, + 81, 14, 34, 16, 36, 18, 19, 20, 82, 107, + 44, 35, 25, 94, 71, 95, 29, 30, 31, 44, + 33, 78, 35, 47, 81, 38, 51, 53, 41, 42, + 43, 44, 15, 46, 71, 48, 16, 50, 51, 22, + 53, 78, 79, 1, 81, 58, 59, 9, 10, 11, + 12, 15, 14, 17, 16, 1, 18, 19, 20, 66, + 34, 68, 36, 25, 16, 71, 44, 29, 30, 31, + 28, 33, 78, 35, 52, 81, 38, 62, 63, 41, + 42, 43, 44, 47, 46, 6, 48, 8, 50, 51, + 16, 53, 73, 1, 2, 40, 58, 59, 9, 10, + 11, 12, 83, 14, 77, 16, 52, 18, 19, 20, + 98, 99, 52, 95, 25, 97, 97, 92, 29, 30, + 31, 77, 33, 49, 35, 100, 14, 38, 16, 102, + 41, 42, 43, 44, 73, 46, 14, 48, 14, 50, + 51, 36, 53, 73, 83, 1, 102, 58, 59, 9, + 10, 11, 12, 83, 14, 17, 16, 50, 18, 19, + 20, 17, 71, 64, 65, 25, 73, 97, 15, 29, + 30, 31, 81, 33, 26, 35, 83, 53, 38, 73, + 32, 41, 42, 43, 44, 47, 46, 92, 48, 83, + 50, 51, 95, 53, 97, 100, 98, 99, 58, 59, + 9, 10, 11, 12, 23, 14, 52, 16, 16, 18, + 19, 20, 16, 7, 50, 16, 25, 13, 13, 16, + 29, 30, 31, 16, 33, 16, 35, 33, 33, 38, + 44, 16, 41, 42, 43, 44, 35, 46, 16, 48, + 95, 50, 51, 96, 53, 37, 38, 39, 81, 58, + 59, 66, 67, 68, 69, 83, 71, 72, 95, 74, + 75, 76, 54, 55, 56, 57, 81, 97, 60, 84, + 95, 13, 17, 80, 89, 90, 91, 1, 93, 94, + 2, 81, 103, 66, 67, 68, 69, 99, 71, 72, + 108, 74, 75, 76, 81, 37, 38, 39, 81, 108, + 108, 84, 108, 108, 108, 95, 89, 90, 91, 108, + 93, 94, 54, 55, 56, 57, 66, 108, 68, 108, + 108, 71, 108, 108, 74, 75, 76, 108, 108, 21, + 108, 81, 108, 108, 84, 9, 108, 108, 12, 89, + 90, 91, 16, 93, 94, 37, 38, 39, 108, 108, + 108, 66, 26, 68, 104, 105, 71, 108, 32, 74, + 75, 76, 54, 55, 56, 57, 81, 1, 108, 84, + 73, 108, 108, 108, 89, 90, 91, 108, 93, 94, + 83, 2, 85, 86, 87, 108, 108, 108, 108, 104, + 105, 108, 26, 3, 4, 5, 6, 108, 32, 9, + 10, 11, 12, 108, 108, 14, 108, 16, 18, 19, + 20, 108, 108, 108, 35, 25, 37, 38, 39, 29, + 30, 31, 66, 108, 68, 69, 47, 71, 72, 108, + 74, 75, 76, 54, 55, 56, 57, 81, 108, 48, + 84, 50, 108, 108, 53, 89, 90, 91, 108, 93, + 94, 3, 108, 108, 108, 108, 108, 9, 10, 11, + 12, 108, 14, 108, 108, 108, 18, 19, 20, 108, + 108, 13, 108, 25, 27, 108, 108, 29, 30, 31, + 108, 108, 108, 3, 37, 38, 39, 108, 108, 9, + 10, 11, 12, 108, 14, 37, 38, 39, 18, 19, + 20, 54, 55, 56, 57, 25, 108, 59, 60, 29, + 30, 31, 54, 55, 56, 57, 108, 108, 66, 108, + 68, 108, 1, 71, 108, 108, 74, 75, 76, 108, + 108, 108, 108, 81, 13, 108, 84, 108, 108, 59, + 60, 89, 90, 91, 108, 93, 94, 26, 108, 108, + 66, 108, 68, 32, 108, 71, 108, 105, 74, 75, + 76, 66, 78, 68, 108, 81, 71, 108, 84, 74, + 75, 76, 108, 89, 90, 91, 81, 93, 94, 84, + 9, 108, 108, 12, 89, 90, 91, 16, 93, 94, + 66, 108, 68, 108, 108, 71, 101, 108, 74, 75, + 76, 108, 108, 108, 108, 81, 108, 108, 84, 9, + 108, 108, 12, 89, 90, 91, 16, 93, 94, 66, + 49, 68, 108, 108, 71, 101, 108, 74, 75, 76, + 66, 78, 68, 108, 81, 71, 108, 84, 74, 75, + 76, 108, 89, 90, 91, 81, 93, 94, 84, 49, + 108, 108, 108, 89, 90, 91, 108, 93, 94, 66, + 108, 68, 73, 108, 71, 101, 77, 74, 75, 76, + 108, 108, 83, 108, 81, 108, 108, 84, 9, 108, + 108, 12, 89, 90, 91, 16, 93, 94, 66, 108, + 68, 102, 108, 71, 108, 108, 74, 75, 76, 66, + 108, 68, 108, 81, 71, 108, 84, 74, 75, 76, + 108, 89, 90, 91, 81, 93, 94, 84, 49, 1, + 108, 108, 89, 90, 91, 108, 93, 94, 66, 108, + 68, 13, 108, 71, 108, 108, 74, 75, 76, 108, + 108, 108, 108, 81, 26, 108, 84, 108, 108, 108, + 32, 89, 90, 91, 108, 93, 94, 66, 108, 68, + 108, 108, 71, 108, 108, 74, 75, 76, 66, 108, + 68, 108, 81, 71, 108, 84, 74, 75, 76, 108, + 89, 90, 91, 81, 93, 94, 84, 108, 108, 108, + 73, 89, 90, 91, 77, 93, 94, 66, 108, 68, + 83, 108, 71, 108, 108, 74, 75, 76, 108, 108, + 108, 108, 81, 108, 108, 84, 108, 108, 108, 102, + 89, 90, 91, 108, 93, 94, 66, 108, 68, 108, + 108, 71, 108, 108, 74, 75, 76, 66, 108, 68, + 108, 81, 71, 108, 84, 74, 75, 76, 108, 89, + 90, 91, 81, 93, 94, 84, 108, 108, 108, 108, + 89, 90, 91, 108, 93, 94, 66, 108, 68, 108, + 108, 71, 108, 108, 74, 75, 76, 108, 108, 108, + 108, 81, 108, 108, 84, 108, 108, 108, 108, 89, + 90, 91, 108, 93, 94, 66, 108, 68, 108, 108, + 71, 108, 108, 74, 75, 76, 66, 108, 68, 108, + 81, 71, 108, 84, 74, 75, 76, 108, 89, 90, + 91, 81, 93, 94, 84, 108, 108, 108, 108, 89, + 90, 91, 108, 93, 94, 66, 108, 68, 108, 108, + 71, 108, 108, 74, 75, 76, 108, 108, 108, 108, + 81, 108, 108, 84, 108, 108, 108, 108, 89, 90, + 91, 108, 93, 94, 66, 108, 68, 108, 108, 71, + 108, 108, 74, 75, 76, 66, 108, 68, 108, 81, + 71, 108, 84, 74, 75, 76, 108, 89, 90, 91, + 81, 93, 94, 84, 108, 108, 108, 108, 89, 90, + 91, 108, 93, 94, 66, 108, 68, 108, 108, 71, + 108, 108, 74, 75, 76, 108, 108, 108, 108, 81, + 108, 108, 84, 108, 108, 108, 108, 89, 90, 91, + 108, 93, 94, 66, 108, 68, 108, 108, 71, 108, + 108, 74, 75, 76, 66, 108, 68, 108, 81, 71, + 108, 84, 74, 75, 76, 108, 89, 90, 91, 81, + 93, 94, 84, 108, 108, 108, 108, 89, 90, 91, + 108, 93, 94, 66, 108, 68, 108, 108, 71, 108, + 108, 74, 75, 76, 108, 108, 108, 108, 81, 108, + 108, 84, 108, 108, 108, 108, 89, 90, 91, 108, + 93, 94, 66, 108, 68, 108, 108, 71, 108, 108, + 74, 75, 76, 66, 108, 68, 108, 81, 71, 108, + 84, 74, 75, 76, 108, 89, 90, 91, 81, 93, + 94, 84, 108, 108, 108, 108, 89, 90, 91, 108, + 93, 94, 66, 108, 68, 108, 108, 71, 108, 108, + 74, 75, 76, 108, 108, 108, 108, 81, 108, 108, + 84, 108, 108, 108, 108, 89, 90, 91, 108, 93, + 94, 66, 108, 68, 108, 108, 71, 108, 108, 74, + 75, 76, 66, 108, 68, 108, 81, 71, 108, 84, + 74, 75, 76, 108, 89, 90, 91, 81, 93, 94, + 84, 108, 108, 108, 108, 89, 90, 91, 108, 93, + 94, 66, 1, 68, 108, 108, 71, 108, 108, 74, + 75, 76, 108, 108, 13, 108, 81, 108, 17, 84, + 108, 108, 108, 108, 89, 90, 91, 26, 93, 94, + 66, 108, 68, 32, 108, 71, 35, 108, 74, 75, + 108, 66, 108, 68, 108, 81, 71, 108, 47, 74, + 75, 108, 88, 89, 90, 91, 81, 93, 94, 108, + 108, 108, 108, 88, 89, 90, 91, 108, 93, 94, + 66, 108, 68, 9, 108, 71, 12, 108, 74, 75, + 16, 108, 108, 108, 108, 81, 108, 108, 108, 108, + 26, 108, 28, 89, 90, 91, 32, 93, 94, 66, + 108, 68, 108, 108, 71, 108, 108, 74, 75, 108, + 66, 108, 68, 108, 81, 71, 108, 108, 74, 75, + 108, 108, 89, 90, 91, 81, 93, 94, 108, 108, + 108, 108, 108, 89, 90, 91, 108, 93, 94, 66, + 108, 68, 108, 73, 71, 108, 108, 74, 75, 108, + 108, 108, 108, 83, 81, 85, 86, 87, 108, 108, + 108, 108, 89, 90, 91, 108, 93, 94, 66, 108, + 68, 108, 108, 71, 108, 108, 74, 75, 108, 66, + 108, 68, 108, 81, 71, 108, 108, 74, 75, 108, + 108, 89, 90, 91, 81, 93, 94, 108, 108, 108, + 108, 108, 89, 90, 91, 2, 93, 94, 66, 108, + 68, 108, 9, 71, 108, 12, 74, 75, 15, 16, + 17, 108, 108, 81, 108, 108, 108, 108, 108, 108, + 108, 89, 90, 91, 2, 93, 94, 108, 108, 108, + 108, 9, 108, 108, 12, 108, 108, 44, 16, 17, + 47, 2, 49, 108, 51, 108, 108, 73, 9, 108, + 108, 12, 108, 108, 15, 16, 17, 83, 108, 85, + 86, 87, 24, 108, 26, 108, 44, 108, 108, 47, + 32, 49, 108, 51, 52, 37, 38, 39, 108, 108, + 108, 108, 108, 44, 108, 108, 47, 108, 49, 108, + 51, 26, 54, 55, 56, 57, 108, 32, 2, 108, + 108, 108, 37, 38, 39, 9, 108, 108, 12, 108, + 108, 108, 16, 17, 108, 108, 2, 108, 108, 54, + 55, 56, 57, 9, 108, 108, 12, 108, 108, 108, + 16, 17, 108, 108, 108, 37, 38, 39, 108, 108, + 44, 108, 108, 47, 13, 49, 108, 51, 108, 13, + 52, 108, 54, 55, 56, 57, 108, 13, 44, 108, + 2, 47, 108, 49, 108, 51, 108, 108, 37, 38, + 39, 108, 108, 37, 38, 39, 108, 108, 108, 108, + 108, 37, 38, 39, 108, 54, 55, 56, 57, 108, + 54, 55, 56, 57, 108, 37, 38, 39, 54, 55, + 56, 57, 36, 37, 38, 39, 108, 108, 108, 108, + 108, 108, 54, 55, 56, 57, 108, 108, 108, 108, + 54, 55, 56, 57, 9, 108, 108, 12, 37, 38, + 39, 16, 17, 36, 37, 38, 39, 108, 108, 108, + 108, 108, 108, 108, 108, 54, 55, 56, 57, 108, + 108, 54, 55, 56, 57, 108, 108, 108, 108, 44, + 108, 108, 47, 108, 49, 108, 51, +); + const YY_SHIFT_USE_DFLT = -22; + const YY_SHIFT_MAX = 230; + public static $yy_shift_ofst = array( + -22, 501, 501, 93, 399, 399, 450, 93, 93, 93, + 399, 450, -9, 93, 93, 93, 93, 93, 93, 144, + 93, 195, 93, 93, 93, 246, 195, 93, 93, 93, + 93, 93, 297, 93, 93, 93, 93, 348, 42, 42, + 42, 42, 42, 42, 42, 42, 1768, 1795, 1795, 701, + 758, 1521, 80, 676, 113, 790, 1927, 1828, 1896, 568, + 768, 1861, 757, 1866, 1874, 1888, 618, 518, 1921, 1921, + 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921, + 1921, 1921, 1921, 1584, 636, 285, 676, 676, 346, 113, + 113, 402, 700, 1723, -8, 910, 831, 269, 1028, 51, + 3, 3, 422, 448, 352, 106, 422, 106, 458, 364, + 434, 454, 106, 166, 166, 166, 166, 565, 166, 166, + 166, 586, 565, 166, 166, -22, -22, 1752, 1769, 1826, + 1844, 1945, 145, 979, 156, 132, 284, 106, 140, 106, + 30, 140, 140, 30, 106, 106, 106, 140, 106, 106, + 140, 106, 327, 106, 106, 106, 140, 140, 106, 140, + 205, 106, 284, 166, 565, 588, 565, 588, 565, 166, + 166, -12, 166, -22, -22, -22, -22, -22, -22, 689, + 4, 44, 84, 186, 73, 881, 199, 188, 174, 286, + 48, 336, 384, 389, 332, 142, -21, 52, 154, 33, + 85, 276, 278, 233, 515, 509, 474, 516, 502, 464, + 491, 415, 417, 432, 514, 370, 463, 506, 365, 513, + -12, 517, 504, 519, 505, 511, 496, 525, 532, 330, + 358, +); + const YY_REDUCE_USE_DFLT = -89; + const YY_REDUCE_MAX = 178; + public static $yy_reduce_ofst = array( + 325, 527, 495, 666, 595, 560, 863, 874, 834, 805, + 762, 794, 1179, 1455, 1208, 1012, 1386, 1139, 1070, 1110, + 1150, 1219, 1248, 1277, 1288, 1317, 1346, 1357, 1415, 1426, + 1081, 1041, 1001, 972, 943, 932, 903, 1484, 1495, 1622, + 1633, 1662, 1593, 1564, 1553, 1524, 1704, 607, 1590, 178, + 74, 1027, 229, 899, 273, 212, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, 380, 329, 187, 159, 127, -52, 253, + 304, 12, 303, 152, 193, 328, 68, 68, 68, 322, + 328, 407, 405, 322, 68, 190, 335, 416, 403, 68, + 401, 354, 371, 68, 68, 68, 337, 322, 68, 68, + 68, 68, 408, 68, 68, 68, 409, 455, 455, 455, + 455, 455, 510, 480, 455, 455, 477, 482, 457, 482, + 473, 457, 457, 485, 482, 482, 482, 457, 482, 482, + 457, 482, 503, 482, 482, 482, 457, 457, 482, 457, + 520, 482, 523, -88, 498, 489, 498, 489, 498, -88, + -88, -67, -88, 111, 155, 89, 236, 230, 162, +); + public static $yyExpectedTokens = array( + array(), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 52, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(9, 10, 11, 12, 14, 16, 18, 19, 20, 25, 29, 30, 31, 33, 35, 38, 41, 42, 43, 44, 46, 48, 50, 51, 53, 58, 59, ), + array(24, 26, 32, 37, 38, 39, 54, 55, 56, 57, ), + array(26, 32, 37, 38, 39, 54, 55, 56, 57, ), + array(26, 32, 37, 38, 39, 54, 55, 56, 57, ), + array(14, 16, 48, 50, 53, ), + array(3, 9, 10, 11, 12, 14, 18, 19, 20, 25, 29, 30, 31, 59, 60, ), + array(1, 13, 17, 26, 32, 35, 47, ), + array(14, 16, 50, 53, ), + array(1, 26, 32, ), + array(14, 35, 53, ), + array(3, 9, 10, 11, 12, 14, 18, 19, 20, 25, 29, 30, 31, 59, 60, ), + array(36, 37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 52, 54, 55, 56, 57, ), + array(36, 37, 38, 39, 54, 55, 56, 57, ), + array(13, 37, 38, 39, 54, 55, 56, 57, ), + array(13, 37, 38, 39, 54, 55, 56, 57, ), + array(13, 37, 38, 39, 54, 55, 56, 57, ), + array(27, 37, 38, 39, 54, 55, 56, 57, ), + array(13, 37, 38, 39, 54, 55, 56, 57, ), + array(13, 37, 38, 39, 54, 55, 56, 57, ), + array(2, 37, 38, 39, 54, 55, 56, 57, ), + array(21, 37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, 60, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(37, 38, 39, 54, 55, 56, 57, ), + array(9, 12, 16, 26, 28, 32, ), + array(9, 12, 16, 26, 32, ), + array(17, 44, 51, ), + array(1, 26, 32, ), + array(1, 26, 32, ), + array(15, 17, 47, ), + array(14, 35, 53, ), + array(14, 35, 53, ), + array(1, 2, ), + array(3, 4, 5, 6, 9, 10, 11, 12, 18, 19, 20, 25, 29, 30, 31, ), + array(2, 9, 12, 15, 16, 17, 44, 47, 49, 51, ), + array(12, 14, 16, 53, ), + array(9, 12, 16, 49, ), + array(1, 13, 26, 32, ), + array(1, 13, 26, 32, ), + array(1, 13, 26, 32, ), + array(15, 17, 47, ), + array(9, 12, 16, ), + array(9, 12, 16, ), + array(14, 16, ), + array(17, 47, ), + array(1, 28, ), + array(26, 32, ), + array(14, 16, ), + array(26, 32, ), + array(26, 32, ), + array(1, 52, ), + array(14, 53, ), + array(1, 17, ), + array(26, 32, ), + array(1, ), + array(1, ), + array(1, ), + array(1, ), + array(17, ), + array(1, ), + array(1, ), + array(1, ), + array(1, ), + array(17, ), + array(1, ), + array(1, ), + array(), + array(), + array(2, 9, 12, 16, 17, 44, 47, 49, 51, 52, ), + array(2, 9, 12, 15, 16, 17, 44, 47, 49, 51, ), + array(2, 9, 12, 16, 17, 44, 47, 49, 51, ), + array(2, 9, 12, 16, 17, 44, 47, 49, 51, ), + array(9, 12, 16, 17, 44, 47, 49, 51, ), + array(12, 14, 16, 33, 53, ), + array(9, 12, 16, 49, ), + array(9, 12, 16, ), + array(15, 44, 51, ), + array(14, 53, ), + array(26, 32, ), + array(44, 51, ), + array(26, 32, ), + array(44, 51, ), + array(44, 51, ), + array(44, 51, ), + array(44, 51, ), + array(26, 32, ), + array(26, 32, ), + array(26, 32, ), + array(44, 51, ), + array(26, 32, ), + array(26, 32, ), + array(44, 51, ), + array(26, 32, ), + array(15, 22, ), + array(26, 32, ), + array(26, 32, ), + array(26, 32, ), + array(44, 51, ), + array(44, 51, ), + array(26, 32, ), + array(44, 51, ), + array(12, 35, ), + array(26, 32, ), + array(14, 53, ), + array(1, ), + array(17, ), + array(2, ), + array(17, ), + array(2, ), + array(17, ), + array(1, ), + array(1, ), + array(35, ), + array(1, ), + array(), + array(), + array(), + array(), + array(), + array(), + array(2, 35, 37, 38, 39, 47, 54, 55, 56, 57, ), + array(13, 21, 23, 26, 32, 34, 36, 44, ), + array(13, 15, 26, 32, 35, 47, ), + array(13, 22, 26, 32, 45, ), + array(13, 22, 26, 32, 45, ), + array(35, 44, 47, 52, ), + array(9, 12, 16, 49, ), + array(22, 45, 52, ), + array(28, 35, 47, ), + array(22, 45, 60, ), + array(35, 47, ), + array(21, 34, ), + array(34, 36, ), + array(16, 49, ), + array(6, 8, ), + array(44, 52, ), + array(7, 8, ), + array(34, 52, ), + array(35, 47, ), + array(35, 47, ), + array(22, 45, ), + array(34, 36, ), + array(15, 44, ), + array(34, 36, ), + array(34, 36, ), + array(13, ), + array(16, ), + array(50, ), + array(7, ), + array(16, ), + array(52, ), + array(23, ), + array(36, ), + array(50, ), + array(14, ), + array(13, ), + array(52, ), + array(15, ), + array(16, ), + array(40, ), + array(16, ), + array(35, ), + array(16, ), + array(33, ), + array(16, ), + array(33, ), + array(35, ), + array(44, ), + array(16, ), + array(16, ), + array(16, ), + array(16, ), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), + array(), +); + public static $yy_default = array( + 336, 512, 512, 512, 497, 497, 512, 474, 474, 474, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 377, 377, 356, 512, + 512, 413, 512, 377, 512, 512, 512, 512, 512, 512, + 512, 512, 382, 512, 349, 512, 512, 512, 382, 379, + 389, 388, 384, 402, 473, 397, 498, 500, 401, 361, + 472, 499, 349, 377, 377, 487, 377, 377, 429, 512, + 512, 368, 326, 428, 512, 439, 391, 391, 391, 429, + 439, 439, 512, 429, 391, 377, 512, 377, 377, 391, + 512, 371, 358, 395, 394, 396, 373, 429, 400, 404, + 391, 404, 484, 406, 405, 481, 334, 428, 428, 428, + 428, 428, 512, 441, 439, 455, 512, 363, 435, 354, + 434, 437, 433, 432, 359, 357, 364, 436, 353, 367, + 466, 365, 512, 352, 350, 360, 467, 465, 346, 464, + 439, 366, 512, 369, 461, 475, 488, 476, 485, 372, + 422, 439, 374, 480, 439, 480, 480, 439, 334, 413, + 409, 413, 403, 403, 413, 440, 403, 413, 403, 413, + 512, 512, 512, 332, 409, 512, 512, 512, 423, 403, + 512, 409, 512, 512, 512, 512, 512, 512, 512, 418, + 385, 512, 512, 512, 512, 512, 512, 512, 415, 512, + 455, 512, 512, 512, 411, 486, 409, 512, 512, 512, + 512, 419, 407, 362, 445, 418, 425, 424, 420, 339, + 460, 421, 483, 398, 416, 340, 399, 455, 378, 337, + 338, 330, 328, 329, 442, 443, 444, 438, 392, 393, + 427, 426, 386, 417, 408, 390, 410, 331, 333, 335, + 412, 470, 414, 415, 503, 478, 495, 471, 459, 458, + 375, 457, 344, 462, 508, 493, 376, 496, 456, 509, + 494, 501, 504, 511, 510, 507, 505, 502, 506, 345, + 468, 469, 446, 355, 341, 452, 450, 454, 448, 453, + 447, 489, 490, 491, 463, 449, 492, 451, 327, 342, + 343, 370, 430, 431, 479, 477, +); + const YYNOCODE = 109; + const YYSTACKDEPTH = 500; + const YYNSTATE = 326; + const YYNRULE = 186; + const YYERRORSYMBOL = 61; + const YYERRSYMDT = 'yy0'; + const YYFALLBACK = 0; + public static $yyFallback = array( + ); public function Trace($TraceFILE, $zTracePrompt) { if (!$TraceFILE) { @@ -1840,18 +1110,250 @@ public function PrintTrace() $this->yyTracePrompt = '
'; } + public $yyTraceFILE; + public $yyTracePrompt; + public $yyidx; /* Index of top element in stack */ + public $yyerrcnt; /* Shifts left before out of the error */ + public $yystack = array(); /* The parser's stack */ + + public $yyTokenName = array( + '$', 'VERT', 'COLON', 'TEXT', + 'STRIPON', 'STRIPOFF', 'LITERALSTART', 'LITERALEND', + 'LITERAL', 'SIMPELOUTPUT', 'SIMPLETAG', 'SMARTYBLOCKCHILDPARENT', + 'LDEL', 'RDEL', 'DOLLARID', 'EQUAL', + 'ID', 'PTR', 'LDELMAKENOCACHE', 'LDELIF', + 'LDELFOR', 'SEMICOLON', 'INCDEC', 'TO', + 'STEP', 'LDELFOREACH', 'SPACE', 'AS', + 'APTR', 'LDELSETFILTER', 'CLOSETAG', 'LDELSLASH', + 'ATTR', 'INTEGER', 'COMMA', 'OPENP', + 'CLOSEP', 'MATH', 'UNIMATH', 'ISIN', + 'QMARK', 'NOT', 'TYPECAST', 'HEX', + 'DOT', 'INSTANCEOF', 'SINGLEQUOTESTRING', 'DOUBLECOLON', + 'NAMESPACE', 'AT', 'HATCH', 'OPENB', + 'CLOSEB', 'DOLLAR', 'LOGOP', 'SLOGOP', + 'TLOGOP', 'SINGLECOND', 'ARRAYOPEN', 'QUOTE', + 'BACKTICK', 'error', 'start', 'template', + 'literal_e2', 'literal_e1', 'smartytag', 'tagbody', + 'tag', 'outattr', 'eqoutattr', 'varindexed', + 'output', 'attributes', 'variable', 'value', + 'expr', 'modifierlist', 'statement', 'statements', + 'foraction', 'varvar', 'modparameters', 'attribute', + 'ternary', 'tlop', 'lop', 'scond', + 'array', 'function', 'ns1', 'doublequoted_with_quotes', + 'static_class_access', 'arraydef', 'object', 'arrayindex', + 'indexdef', 'varvarele', 'objectchain', 'objectelement', + 'method', 'params', 'modifier', 'modparameter', + 'arrayelements', 'arrayelement', 'doublequoted', 'doublequotedcontent', + ); + + public static $yyRuleName = array( + 'start ::= template', + 'template ::= template TEXT', + 'template ::= template STRIPON', + 'template ::= template STRIPOFF', + 'template ::= template LITERALSTART literal_e2 LITERALEND', + 'literal_e2 ::= literal_e1 LITERALSTART literal_e1 LITERALEND', + 'literal_e2 ::= literal_e1', + 'literal_e1 ::= literal_e1 LITERAL', + 'literal_e1 ::=', + 'template ::= template smartytag', + 'template ::=', + 'smartytag ::= SIMPELOUTPUT', + 'smartytag ::= SIMPLETAG', + 'smartytag ::= SMARTYBLOCKCHILDPARENT', + 'smartytag ::= LDEL tagbody RDEL', + 'smartytag ::= tag RDEL', + 'tagbody ::= outattr', + 'tagbody ::= DOLLARID eqoutattr', + 'tagbody ::= varindexed eqoutattr', + 'eqoutattr ::= EQUAL outattr', + 'outattr ::= output attributes', + 'output ::= variable', + 'output ::= value', + 'output ::= expr', + 'tag ::= LDEL ID attributes', + 'tag ::= LDEL ID', + 'tag ::= LDEL ID modifierlist attributes', + 'tag ::= LDEL ID PTR ID attributes', + 'tag ::= LDEL ID PTR ID modifierlist attributes', + 'tag ::= LDELMAKENOCACHE DOLLARID', + 'tag ::= LDELIF expr', + 'tag ::= LDELIF expr attributes', + 'tag ::= LDELIF statement', + 'tag ::= LDELIF statement attributes', + 'tag ::= LDELFOR statements SEMICOLON expr SEMICOLON varindexed foraction attributes', + 'foraction ::= EQUAL expr', + 'foraction ::= INCDEC', + 'tag ::= LDELFOR statement TO expr attributes', + 'tag ::= LDELFOR statement TO expr STEP expr attributes', + 'tag ::= LDELFOREACH SPACE expr AS varvar attributes', + 'tag ::= LDELFOREACH SPACE expr AS varvar APTR varvar attributes', + 'tag ::= LDELFOREACH attributes', + 'tag ::= LDELSETFILTER ID modparameters', + 'tag ::= LDELSETFILTER ID modparameters modifierlist', + 'smartytag ::= CLOSETAG', + 'tag ::= LDELSLASH ID', + 'tag ::= LDELSLASH ID modifierlist', + 'tag ::= LDELSLASH ID PTR ID', + 'tag ::= LDELSLASH ID PTR ID modifierlist', + 'attributes ::= attributes attribute', + 'attributes ::= attribute', + 'attributes ::=', + 'attribute ::= SPACE ID EQUAL ID', + 'attribute ::= ATTR expr', + 'attribute ::= ATTR value', + 'attribute ::= SPACE ID', + 'attribute ::= SPACE expr', + 'attribute ::= SPACE value', + 'attribute ::= SPACE INTEGER EQUAL expr', + 'statements ::= statement', + 'statements ::= statements COMMA statement', + 'statement ::= DOLLARID EQUAL INTEGER', + 'statement ::= DOLLARID EQUAL expr', + 'statement ::= varindexed EQUAL expr', + 'statement ::= OPENP statement CLOSEP', + 'expr ::= value', + 'expr ::= ternary', + 'expr ::= DOLLARID COLON ID', + 'expr ::= expr MATH value', + 'expr ::= expr UNIMATH value', + 'expr ::= expr tlop value', + 'expr ::= expr lop expr', + 'expr ::= expr scond', + 'expr ::= expr ISIN array', + 'expr ::= expr ISIN value', + 'ternary ::= OPENP expr CLOSEP QMARK DOLLARID COLON expr', + 'ternary ::= OPENP expr CLOSEP QMARK expr COLON expr', + 'value ::= variable', + 'value ::= UNIMATH value', + 'value ::= NOT value', + 'value ::= TYPECAST value', + 'value ::= variable INCDEC', + 'value ::= HEX', + 'value ::= INTEGER', + 'value ::= INTEGER DOT INTEGER', + 'value ::= INTEGER DOT', + 'value ::= DOT INTEGER', + 'value ::= ID', + 'value ::= function', + 'value ::= OPENP expr CLOSEP', + 'value ::= variable INSTANCEOF ns1', + 'value ::= variable INSTANCEOF variable', + 'value ::= SINGLEQUOTESTRING', + 'value ::= doublequoted_with_quotes', + 'value ::= varindexed DOUBLECOLON static_class_access', + 'value ::= smartytag', + 'value ::= value modifierlist', + 'value ::= NAMESPACE', + 'value ::= arraydef', + 'value ::= ns1 DOUBLECOLON static_class_access', + 'ns1 ::= ID', + 'ns1 ::= NAMESPACE', + 'variable ::= DOLLARID', + 'variable ::= varindexed', + 'variable ::= varvar AT ID', + 'variable ::= object', + 'variable ::= HATCH ID HATCH', + 'variable ::= HATCH ID HATCH arrayindex', + 'variable ::= HATCH variable HATCH', + 'variable ::= HATCH variable HATCH arrayindex', + 'varindexed ::= DOLLARID arrayindex', + 'varindexed ::= varvar arrayindex', + 'arrayindex ::= arrayindex indexdef', + 'arrayindex ::=', + 'indexdef ::= DOT DOLLARID', + 'indexdef ::= DOT varvar', + 'indexdef ::= DOT varvar AT ID', + 'indexdef ::= DOT ID', + 'indexdef ::= DOT INTEGER', + 'indexdef ::= DOT LDEL expr RDEL', + 'indexdef ::= OPENB ID CLOSEB', + 'indexdef ::= OPENB ID DOT ID CLOSEB', + 'indexdef ::= OPENB SINGLEQUOTESTRING CLOSEB', + 'indexdef ::= OPENB INTEGER CLOSEB', + 'indexdef ::= OPENB DOLLARID CLOSEB', + 'indexdef ::= OPENB variable CLOSEB', + 'indexdef ::= OPENB value CLOSEB', + 'indexdef ::= OPENB expr CLOSEB', + 'indexdef ::= OPENB CLOSEB', + 'varvar ::= DOLLARID', + 'varvar ::= DOLLAR', + 'varvar ::= varvar varvarele', + 'varvarele ::= ID', + 'varvarele ::= SIMPELOUTPUT', + 'varvarele ::= LDEL expr RDEL', + 'object ::= varindexed objectchain', + 'objectchain ::= objectelement', + 'objectchain ::= objectchain objectelement', + 'objectelement ::= PTR ID arrayindex', + 'objectelement ::= PTR varvar arrayindex', + 'objectelement ::= PTR LDEL expr RDEL arrayindex', + 'objectelement ::= PTR ID LDEL expr RDEL arrayindex', + 'objectelement ::= PTR method', + 'function ::= ns1 OPENP params CLOSEP', + 'method ::= ID OPENP params CLOSEP', + 'method ::= DOLLARID OPENP params CLOSEP', + 'params ::= params COMMA expr', + 'params ::= expr', + 'params ::=', + 'modifierlist ::= modifierlist modifier modparameters', + 'modifierlist ::= modifier modparameters', + 'modifier ::= VERT AT ID', + 'modifier ::= VERT ID', + 'modparameters ::= modparameters modparameter', + 'modparameters ::=', + 'modparameter ::= COLON value', + 'modparameter ::= COLON UNIMATH value', + 'modparameter ::= COLON array', + 'static_class_access ::= method', + 'static_class_access ::= method objectchain', + 'static_class_access ::= ID', + 'static_class_access ::= DOLLARID arrayindex', + 'static_class_access ::= DOLLARID arrayindex objectchain', + 'lop ::= LOGOP', + 'lop ::= SLOGOP', + 'tlop ::= TLOGOP', + 'scond ::= SINGLECOND', + 'arraydef ::= OPENB arrayelements CLOSEB', + 'arraydef ::= ARRAYOPEN arrayelements CLOSEP', + 'arrayelements ::= arrayelement', + 'arrayelements ::= arrayelements COMMA arrayelement', + 'arrayelements ::=', + 'arrayelement ::= value APTR expr', + 'arrayelement ::= ID APTR expr', + 'arrayelement ::= expr', + 'doublequoted_with_quotes ::= QUOTE QUOTE', + 'doublequoted_with_quotes ::= QUOTE doublequoted QUOTE', + 'doublequoted ::= doublequoted doublequotedcontent', + 'doublequoted ::= doublequotedcontent', + 'doublequotedcontent ::= BACKTICK variable BACKTICK', + 'doublequotedcontent ::= BACKTICK expr BACKTICK', + 'doublequotedcontent ::= DOLLARID', + 'doublequotedcontent ::= LDEL variable RDEL', + 'doublequotedcontent ::= LDEL expr RDEL', + 'doublequotedcontent ::= smartytag', + 'doublequotedcontent ::= TEXT', + ); + public function tokenName($tokenType) { if ($tokenType === 0) { return 'End of Input'; } if ($tokenType > 0 && $tokenType < count($this->yyTokenName)) { - return $this->yyTokenName[ $tokenType ]; + return $this->yyTokenName[$tokenType]; } else { return 'Unknown'; } } + public static function yy_destructor($yymajor, $yypminor) + { + switch ($yymajor) { + default: break; /* If no destructor action specified: do nothing */ + } + } + public function yy_pop_parser_stack() { if (empty($this->yystack)) { @@ -1860,18 +1362,19 @@ public function yy_pop_parser_stack() $yytos = array_pop($this->yystack); if ($this->yyTraceFILE && $this->yyidx >= 0) { fwrite($this->yyTraceFILE, - $this->yyTracePrompt . 'Popping ' . $this->yyTokenName[ $yytos->major ] . - "\n"); + $this->yyTracePrompt . 'Popping ' . $this->yyTokenName[$yytos->major] . + "\n"); } $yymajor = $yytos->major; self::yy_destructor($yymajor, $yytos->minor); $this->yyidx--; + return $yymajor; } public function __destruct() { - while ($this->yystack !== array()) { + while ($this->yystack !== Array()) { $this->yy_pop_parser_stack(); } if (is_resource($this->yyTraceFILE)) { @@ -1883,14 +1386,14 @@ public function yy_get_expected_tokens($token) { static $res3 = array(); static $res4 = array(); - $state = $this->yystack[ $this->yyidx ]->stateno; - $expected = self::$yyExpectedTokens[ $state ]; - if (isset($res3[ $state ][ $token ])) { - if ($res3[ $state ][ $token ]) { + $state = $this->yystack[$this->yyidx]->stateno; + $expected = self::$yyExpectedTokens[$state]; + if (isset($res3[$state][$token])) { + if ($res3[$state][$token]) { return $expected; } } else { - if ($res3[ $state ][ $token ] = in_array($token, self::$yyExpectedTokens[ $state ], true)) { + if ($res3[$state][$token] = in_array($token, self::$yyExpectedTokens[$state], true)) { return $expected; } } @@ -1910,21 +1413,20 @@ public function yy_get_expected_tokens($token) return array_unique($expected); } $yyruleno = $yyact - self::YYNSTATE; - $this->yyidx -= self::$yyRuleInfo[ $yyruleno ][ 1 ]; + $this->yyidx -= self::$yyRuleInfo[$yyruleno][1]; $nextstate = $this->yy_find_reduce_action( - $this->yystack[ $this->yyidx ]->stateno, - self::$yyRuleInfo[ $yyruleno ][ 0 ]); - if (isset(self::$yyExpectedTokens[ $nextstate ])) { - $expected = array_merge($expected, self::$yyExpectedTokens[ $nextstate ]); - if (isset($res4[ $nextstate ][ $token ])) { - if ($res4[ $nextstate ][ $token ]) { + $this->yystack[$this->yyidx]->stateno, + self::$yyRuleInfo[$yyruleno][0]); + if (isset(self::$yyExpectedTokens[$nextstate])) { + $expected = array_merge($expected, self::$yyExpectedTokens[$nextstate]); + if (isset($res4[$nextstate][$token])) { + if ($res4[$nextstate][$token]) { $this->yyidx = $yyidx; $this->yystack = $stack; return array_unique($expected); } } else { - if ($res4[ $nextstate ][ $token ] = - in_array($token, self::$yyExpectedTokens[ $nextstate ], true)) { + if ($res4[$nextstate][$token] = in_array($token, self::$yyExpectedTokens[$nextstate], true)) { $this->yyidx = $yyidx; $this->yystack = $stack; return array_unique($expected); @@ -1936,8 +1438,8 @@ public function yy_get_expected_tokens($token) $this->yyidx++; $x = new TP_yyStackEntry; $x->stateno = $nextstate; - $x->major = self::$yyRuleInfo[ $yyruleno ][ 0 ]; - $this->yystack[ $this->yyidx ] = $x; + $x->major = self::$yyRuleInfo[$yyruleno][0]; + $this->yystack[$this->yyidx] = $x; continue 2; } elseif ($nextstate === self::YYNSTATE + self::YYNRULE + 1) { $this->yyidx = $yyidx; @@ -1958,8 +1460,9 @@ public function yy_get_expected_tokens($token) } break; } while (true); - $this->yyidx = $yyidx; - $this->yystack = $stack; + $this->yyidx = $yyidx; + $this->yystack = $stack; + return array_unique($expected); } @@ -1970,16 +1473,16 @@ public function yy_is_expected_token($token) if ($token === 0) { return true; // 0 is not part of this } - $state = $this->yystack[ $this->yyidx ]->stateno; - if (isset($res[ $state ][ $token ])) { - if ($res[ $state ][ $token ]) { + $state = $this->yystack[$this->yyidx]->stateno; + if (isset($res[$state][$token])) { + if ($res[$state][$token]) { return true; } } else { - if ($res[ $state ][ $token ] = in_array($token, self::$yyExpectedTokens[ $state ], true)) { + if ($res[$state][$token] = in_array($token, self::$yyExpectedTokens[$state], true)) { return true; } - } + } $stack = $this->yystack; $yyidx = $this->yyidx; do { @@ -1996,20 +1499,18 @@ public function yy_is_expected_token($token) return true; } $yyruleno = $yyact - self::YYNSTATE; - $this->yyidx -= self::$yyRuleInfo[ $yyruleno ][ 1 ]; + $this->yyidx -= self::$yyRuleInfo[$yyruleno][1]; $nextstate = $this->yy_find_reduce_action( - $this->yystack[ $this->yyidx ]->stateno, - self::$yyRuleInfo[ $yyruleno ][ 0 ]); - if (isset($res2[ $nextstate ][ $token ])) { - if ($res2[ $nextstate ][ $token ]) { + $this->yystack[$this->yyidx]->stateno, + self::$yyRuleInfo[$yyruleno][0]); + if (isset($res2[$nextstate][$token])) { + if ($res2[$nextstate][$token]) { $this->yyidx = $yyidx; $this->yystack = $stack; return true; } } else { - if ($res2[ $nextstate ][ $token ] = - (isset(self::$yyExpectedTokens[ $nextstate ]) && - in_array($token, self::$yyExpectedTokens[ $nextstate ], true))) { + if ($res2[$nextstate][$token] = (isset(self::$yyExpectedTokens[$nextstate]) && in_array($token, self::$yyExpectedTokens[$nextstate], true))) { $this->yyidx = $yyidx; $this->yystack = $stack; return true; @@ -2020,8 +1521,8 @@ public function yy_is_expected_token($token) $this->yyidx++; $x = new TP_yyStackEntry; $x->stateno = $nextstate; - $x->major = self::$yyRuleInfo[ $yyruleno ][ 0 ]; - $this->yystack[ $this->yyidx ] = $x; + $x->major = self::$yyRuleInfo[$yyruleno][0]; + $this->yystack[$this->yyidx] = $x; continue 2; } elseif ($nextstate === self::YYNSTATE + self::YYNRULE + 1) { $this->yyidx = $yyidx; @@ -2048,65 +1549,69 @@ public function yy_is_expected_token($token) } while (true); $this->yyidx = $yyidx; $this->yystack = $stack; + return true; } - public function yy_find_shift_action($iLookAhead) + public function yy_find_shift_action($iLookAhead) { - $stateno = $this->yystack[ $this->yyidx ]->stateno; + $stateno = $this->yystack[$this->yyidx]->stateno; + /* if ($this->yyidx < 0) return self::YY_NO_ACTION; */ - if (!isset(self::$yy_shift_ofst[ $stateno ])) { + if (!isset(self::$yy_shift_ofst[$stateno])) { // no shift actions - return self::$yy_default[ $stateno ]; + return self::$yy_default[$stateno]; } - $i = self::$yy_shift_ofst[ $stateno ]; + $i = self::$yy_shift_ofst[$stateno]; if ($i === self::YY_SHIFT_USE_DFLT) { - return self::$yy_default[ $stateno ]; + return self::$yy_default[$stateno]; } if ($iLookAhead === self::YYNOCODE) { return self::YY_NO_ACTION; } $i += $iLookAhead; if ($i < 0 || $i >= self::YY_SZ_ACTTAB || - self::$yy_lookahead[ $i ] != $iLookAhead) { + self::$yy_lookahead[$i] != $iLookAhead) { if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback) - && ($iFallback = self::$yyFallback[ $iLookAhead ]) != 0) { + && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) { if ($this->yyTraceFILE) { fwrite($this->yyTraceFILE, $this->yyTracePrompt . 'FALLBACK ' . - $this->yyTokenName[ $iLookAhead ] . ' => ' . - $this->yyTokenName[ $iFallback ] . "\n"); + $this->yyTokenName[$iLookAhead] . ' => ' . + $this->yyTokenName[$iFallback] . "\n"); } + return $this->yy_find_shift_action($iFallback); } - return self::$yy_default[ $stateno ]; + + return self::$yy_default[$stateno]; } else { - return self::$yy_action[ $i ]; + return self::$yy_action[$i]; } } public function yy_find_reduce_action($stateno, $iLookAhead) { /* $stateno = $this->yystack[$this->yyidx]->stateno; */ - if (!isset(self::$yy_reduce_ofst[ $stateno ])) { - return self::$yy_default[ $stateno ]; + + if (!isset(self::$yy_reduce_ofst[$stateno])) { + return self::$yy_default[$stateno]; } - $i = self::$yy_reduce_ofst[ $stateno ]; + $i = self::$yy_reduce_ofst[$stateno]; if ($i === self::YY_REDUCE_USE_DFLT) { - return self::$yy_default[ $stateno ]; + return self::$yy_default[$stateno]; } if ($iLookAhead === self::YYNOCODE) { return self::YY_NO_ACTION; } $i += $iLookAhead; if ($i < 0 || $i >= self::YY_SZ_ACTTAB || - self::$yy_lookahead[ $i ] != $iLookAhead) { - return self::$yy_default[ $stateno ]; + self::$yy_lookahead[$i] != $iLookAhead) { + return self::$yy_default[$stateno]; } else { - return self::$yy_action[ $i ]; + return self::$yy_action[$i]; } } - // line 234 "../smarty/lexer/smarty_internal_templateparser.y" public function yy_shift($yyNewState, $yyMajor, $yypMinor) { $this->yyidx++; @@ -2118,9 +1623,11 @@ public function yy_shift($yyNewState, $yyMajor, $yypMinor) while ($this->yyidx >= 0) { $this->yy_pop_parser_stack(); } - // line 221 "../smarty/lexer/smarty_internal_templateparser.y" - $this->internalError = true; - $this->compiler->trigger_template_error('Stack overflow in template parser'); +// line 220 "../smarty/lexer/smarty_internal_templateparser.y" + + $this->internalError = true; + $this->compiler->trigger_template_error('Stack overflow in template parser'); + return; } $yytos = new TP_yyStackEntry; @@ -2134,1357 +1641,1150 @@ public function yy_shift($yyNewState, $yyMajor, $yypMinor) fprintf($this->yyTraceFILE, "%sStack:", $this->yyTracePrompt); for ($i = 1; $i <= $this->yyidx; $i++) { fprintf($this->yyTraceFILE, " %s", - $this->yyTokenName[ $this->yystack[ $i ]->major ]); + $this->yyTokenName[$this->yystack[$i]->major]); } - fwrite($this->yyTraceFILE, "\n"); + fwrite($this->yyTraceFILE,"\n"); } } - // line 242 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r0() - { - $this->root_buffer->prepend_array($this, $this->template_prefix); - $this->root_buffer->append_array($this, $this->template_postfix); - $this->_retvalue = $this->root_buffer->to_smarty_php($this); - } + public static $yyRuleInfo = array( + array( 0 => 62, 1 => 1 ), + array( 0 => 63, 1 => 2 ), + array( 0 => 63, 1 => 2 ), + array( 0 => 63, 1 => 2 ), + array( 0 => 63, 1 => 4 ), + array( 0 => 64, 1 => 4 ), + array( 0 => 64, 1 => 1 ), + array( 0 => 65, 1 => 2 ), + array( 0 => 65, 1 => 0 ), + array( 0 => 63, 1 => 2 ), + array( 0 => 63, 1 => 0 ), + array( 0 => 66, 1 => 1 ), + array( 0 => 66, 1 => 1 ), + array( 0 => 66, 1 => 1 ), + array( 0 => 66, 1 => 3 ), + array( 0 => 66, 1 => 2 ), + array( 0 => 67, 1 => 1 ), + array( 0 => 67, 1 => 2 ), + array( 0 => 67, 1 => 2 ), + array( 0 => 70, 1 => 2 ), + array( 0 => 69, 1 => 2 ), + array( 0 => 72, 1 => 1 ), + array( 0 => 72, 1 => 1 ), + array( 0 => 72, 1 => 1 ), + array( 0 => 68, 1 => 3 ), + array( 0 => 68, 1 => 2 ), + array( 0 => 68, 1 => 4 ), + array( 0 => 68, 1 => 5 ), + array( 0 => 68, 1 => 6 ), + array( 0 => 68, 1 => 2 ), + array( 0 => 68, 1 => 2 ), + array( 0 => 68, 1 => 3 ), + array( 0 => 68, 1 => 2 ), + array( 0 => 68, 1 => 3 ), + array( 0 => 68, 1 => 8 ), + array( 0 => 80, 1 => 2 ), + array( 0 => 80, 1 => 1 ), + array( 0 => 68, 1 => 5 ), + array( 0 => 68, 1 => 7 ), + array( 0 => 68, 1 => 6 ), + array( 0 => 68, 1 => 8 ), + array( 0 => 68, 1 => 2 ), + array( 0 => 68, 1 => 3 ), + array( 0 => 68, 1 => 4 ), + array( 0 => 66, 1 => 1 ), + array( 0 => 68, 1 => 2 ), + array( 0 => 68, 1 => 3 ), + array( 0 => 68, 1 => 4 ), + array( 0 => 68, 1 => 5 ), + array( 0 => 73, 1 => 2 ), + array( 0 => 73, 1 => 1 ), + array( 0 => 73, 1 => 0 ), + array( 0 => 83, 1 => 4 ), + array( 0 => 83, 1 => 2 ), + array( 0 => 83, 1 => 2 ), + array( 0 => 83, 1 => 2 ), + array( 0 => 83, 1 => 2 ), + array( 0 => 83, 1 => 2 ), + array( 0 => 83, 1 => 4 ), + array( 0 => 79, 1 => 1 ), + array( 0 => 79, 1 => 3 ), + array( 0 => 78, 1 => 3 ), + array( 0 => 78, 1 => 3 ), + array( 0 => 78, 1 => 3 ), + array( 0 => 78, 1 => 3 ), + array( 0 => 76, 1 => 1 ), + array( 0 => 76, 1 => 1 ), + array( 0 => 76, 1 => 3 ), + array( 0 => 76, 1 => 3 ), + array( 0 => 76, 1 => 3 ), + array( 0 => 76, 1 => 3 ), + array( 0 => 76, 1 => 3 ), + array( 0 => 76, 1 => 2 ), + array( 0 => 76, 1 => 3 ), + array( 0 => 76, 1 => 3 ), + array( 0 => 84, 1 => 7 ), + array( 0 => 84, 1 => 7 ), + array( 0 => 75, 1 => 1 ), + array( 0 => 75, 1 => 2 ), + array( 0 => 75, 1 => 2 ), + array( 0 => 75, 1 => 2 ), + array( 0 => 75, 1 => 2 ), + array( 0 => 75, 1 => 1 ), + array( 0 => 75, 1 => 1 ), + array( 0 => 75, 1 => 3 ), + array( 0 => 75, 1 => 2 ), + array( 0 => 75, 1 => 2 ), + array( 0 => 75, 1 => 1 ), + array( 0 => 75, 1 => 1 ), + array( 0 => 75, 1 => 3 ), + array( 0 => 75, 1 => 3 ), + array( 0 => 75, 1 => 3 ), + array( 0 => 75, 1 => 1 ), + array( 0 => 75, 1 => 1 ), + array( 0 => 75, 1 => 3 ), + array( 0 => 75, 1 => 1 ), + array( 0 => 75, 1 => 2 ), + array( 0 => 75, 1 => 1 ), + array( 0 => 75, 1 => 1 ), + array( 0 => 75, 1 => 3 ), + array( 0 => 90, 1 => 1 ), + array( 0 => 90, 1 => 1 ), + array( 0 => 74, 1 => 1 ), + array( 0 => 74, 1 => 1 ), + array( 0 => 74, 1 => 3 ), + array( 0 => 74, 1 => 1 ), + array( 0 => 74, 1 => 3 ), + array( 0 => 74, 1 => 4 ), + array( 0 => 74, 1 => 3 ), + array( 0 => 74, 1 => 4 ), + array( 0 => 71, 1 => 2 ), + array( 0 => 71, 1 => 2 ), + array( 0 => 95, 1 => 2 ), + array( 0 => 95, 1 => 0 ), + array( 0 => 96, 1 => 2 ), + array( 0 => 96, 1 => 2 ), + array( 0 => 96, 1 => 4 ), + array( 0 => 96, 1 => 2 ), + array( 0 => 96, 1 => 2 ), + array( 0 => 96, 1 => 4 ), + array( 0 => 96, 1 => 3 ), + array( 0 => 96, 1 => 5 ), + array( 0 => 96, 1 => 3 ), + array( 0 => 96, 1 => 3 ), + array( 0 => 96, 1 => 3 ), + array( 0 => 96, 1 => 3 ), + array( 0 => 96, 1 => 3 ), + array( 0 => 96, 1 => 3 ), + array( 0 => 96, 1 => 2 ), + array( 0 => 81, 1 => 1 ), + array( 0 => 81, 1 => 1 ), + array( 0 => 81, 1 => 2 ), + array( 0 => 97, 1 => 1 ), + array( 0 => 97, 1 => 1 ), + array( 0 => 97, 1 => 3 ), + array( 0 => 94, 1 => 2 ), + array( 0 => 98, 1 => 1 ), + array( 0 => 98, 1 => 2 ), + array( 0 => 99, 1 => 3 ), + array( 0 => 99, 1 => 3 ), + array( 0 => 99, 1 => 5 ), + array( 0 => 99, 1 => 6 ), + array( 0 => 99, 1 => 2 ), + array( 0 => 89, 1 => 4 ), + array( 0 => 100, 1 => 4 ), + array( 0 => 100, 1 => 4 ), + array( 0 => 101, 1 => 3 ), + array( 0 => 101, 1 => 1 ), + array( 0 => 101, 1 => 0 ), + array( 0 => 77, 1 => 3 ), + array( 0 => 77, 1 => 2 ), + array( 0 => 102, 1 => 3 ), + array( 0 => 102, 1 => 2 ), + array( 0 => 82, 1 => 2 ), + array( 0 => 82, 1 => 0 ), + array( 0 => 103, 1 => 2 ), + array( 0 => 103, 1 => 3 ), + array( 0 => 103, 1 => 2 ), + array( 0 => 92, 1 => 1 ), + array( 0 => 92, 1 => 2 ), + array( 0 => 92, 1 => 1 ), + array( 0 => 92, 1 => 2 ), + array( 0 => 92, 1 => 3 ), + array( 0 => 86, 1 => 1 ), + array( 0 => 86, 1 => 1 ), + array( 0 => 85, 1 => 1 ), + array( 0 => 87, 1 => 1 ), + array( 0 => 93, 1 => 3 ), + array( 0 => 93, 1 => 3 ), + array( 0 => 104, 1 => 1 ), + array( 0 => 104, 1 => 3 ), + array( 0 => 104, 1 => 0 ), + array( 0 => 105, 1 => 3 ), + array( 0 => 105, 1 => 3 ), + array( 0 => 105, 1 => 1 ), + array( 0 => 91, 1 => 2 ), + array( 0 => 91, 1 => 3 ), + array( 0 => 106, 1 => 2 ), + array( 0 => 106, 1 => 1 ), + array( 0 => 107, 1 => 3 ), + array( 0 => 107, 1 => 3 ), + array( 0 => 107, 1 => 1 ), + array( 0 => 107, 1 => 3 ), + array( 0 => 107, 1 => 3 ), + array( 0 => 107, 1 => 1 ), + array( 0 => 107, 1 => 1 ), + ); - // line 251 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r1() - { - $code = - $this->compiler->compileTag('private_php', - array(array('code' => $this->yystack[ $this->yyidx + 0 ]->minor), array('type' => $this->lex->phpType)), - array()); - if ($this->compiler->has_code && !empty($code)) { - $tmp = ''; - foreach ($this->compiler->prefix_code as $code) { - $tmp .= $code; + public static $yyReduceMap = array( + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + 6 => 6, + 21 => 6, + 22 => 6, + 23 => 6, + 36 => 6, + 56 => 6, + 57 => 6, + 65 => 6, + 66 => 6, + 77 => 6, + 82 => 6, + 83 => 6, + 88 => 6, + 92 => 6, + 93 => 6, + 97 => 6, + 98 => 6, + 100 => 6, + 105 => 6, + 169 => 6, + 174 => 6, + 7 => 7, + 8 => 8, + 9 => 9, + 11 => 11, + 12 => 12, + 13 => 13, + 14 => 14, + 15 => 15, + 16 => 16, + 17 => 17, + 18 => 18, + 19 => 19, + 20 => 20, + 24 => 24, + 25 => 25, + 26 => 26, + 27 => 27, + 28 => 28, + 29 => 29, + 30 => 30, + 31 => 31, + 33 => 31, + 32 => 32, + 34 => 34, + 35 => 35, + 37 => 37, + 38 => 38, + 39 => 39, + 40 => 40, + 41 => 41, + 42 => 42, + 43 => 43, + 44 => 44, + 45 => 45, + 46 => 46, + 47 => 47, + 48 => 48, + 49 => 49, + 50 => 50, + 59 => 50, + 147 => 50, + 151 => 50, + 155 => 50, + 157 => 50, + 51 => 51, + 148 => 51, + 154 => 51, + 52 => 52, + 53 => 53, + 54 => 53, + 55 => 55, + 132 => 55, + 58 => 58, + 60 => 60, + 61 => 61, + 62 => 61, + 63 => 63, + 64 => 64, + 67 => 67, + 68 => 68, + 69 => 68, + 70 => 70, + 71 => 71, + 72 => 72, + 73 => 73, + 74 => 74, + 75 => 75, + 76 => 76, + 78 => 78, + 80 => 78, + 81 => 78, + 112 => 78, + 79 => 79, + 84 => 84, + 85 => 85, + 86 => 86, + 87 => 87, + 89 => 89, + 90 => 90, + 91 => 90, + 94 => 94, + 95 => 95, + 96 => 96, + 99 => 99, + 101 => 101, + 102 => 102, + 103 => 103, + 104 => 104, + 106 => 106, + 107 => 107, + 108 => 108, + 109 => 109, + 110 => 110, + 111 => 111, + 113 => 113, + 171 => 113, + 114 => 114, + 115 => 115, + 116 => 116, + 117 => 117, + 118 => 118, + 119 => 119, + 127 => 119, + 120 => 120, + 121 => 121, + 122 => 122, + 123 => 122, + 125 => 122, + 126 => 122, + 124 => 124, + 128 => 128, + 129 => 129, + 130 => 130, + 175 => 130, + 131 => 131, + 133 => 133, + 134 => 134, + 135 => 135, + 136 => 136, + 137 => 137, + 138 => 138, + 139 => 139, + 140 => 140, + 141 => 141, + 142 => 142, + 143 => 143, + 144 => 144, + 145 => 145, + 146 => 146, + 149 => 149, + 150 => 150, + 152 => 152, + 153 => 153, + 156 => 156, + 158 => 158, + 159 => 159, + 160 => 160, + 161 => 161, + 162 => 162, + 163 => 163, + 164 => 164, + 165 => 165, + 166 => 166, + 167 => 167, + 168 => 167, + 170 => 170, + 172 => 172, + 173 => 173, + 176 => 176, + 177 => 177, + 178 => 178, + 179 => 179, + 182 => 179, + 180 => 180, + 183 => 180, + 181 => 181, + 184 => 184, + 185 => 185, + ); +// line 233 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r0(){ + $this->root_buffer->prepend_array($this, $this->template_prefix); + $this->root_buffer->append_array($this, $this->template_postfix); + $this->_retvalue = $this->root_buffer->to_smarty_php($this); + } +// line 240 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r1(){ + $text = $this->yystack[ $this->yyidx + 0 ]->minor; + + if ((string)$text == '') { + $this->current_buffer->append_subtree($this, null); + } + + $this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text($text, $this->strip)); + } +// line 250 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r2(){ + $this->strip = true; + } +// line 254 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r3(){ + $this->strip = false; + } +// line 259 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r4(){ + $this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text($this->yystack[$this->yyidx + -1]->minor)); + } +// line 264 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r5(){ + $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor.$this->yystack[$this->yyidx + -1]->minor; + } +// line 267 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r6(){ + $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; + } +// line 271 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r7(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; + + } +// line 276 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r8(){ + $this->_retvalue = ''; + } +// line 280 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r9(){ + if ($this->compiler->has_code) { + $this->current_buffer->append_subtree($this, $this->mergePrefixCode($this->yystack[$this->yyidx + 0]->minor)); + } + $this->compiler->has_variable_string = false; + $this->block_nesting_level = count($this->compiler->_tag_stack); + } +// line 292 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r11(){ + $var = trim(substr($this->yystack[$this->yyidx + 0]->minor, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' $'); + if (preg_match('/^(.*)(\s+nocache)$/', $var, $match)) { + $this->_retvalue = $this->compiler->compileTag('private_print_expression',array('nocache'),array('value'=>$this->compiler->compileVariable('\''.$match[1].'\''))); + } else { + $this->_retvalue = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$this->compiler->compileVariable('\''.$var.'\''))); + } + } +// line 302 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r12(){ + $tag = trim(substr($this->yystack[$this->yyidx + 0]->minor, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength())); + if ($tag == 'strip') { + $this->strip = true; + $this->_retvalue = null; + } else { + if (defined($tag)) { + if ($this->security) { + $this->security->isTrustedConstant($tag, $this->compiler); + } + $this->_retvalue = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$tag)); + } else { + if (preg_match('/^(.*)(\s+nocache)$/', $tag, $match)) { + $this->_retvalue = $this->compiler->compileTag($match[1],array('\'nocache\'')); + } else { + $this->_retvalue = $this->compiler->compileTag($tag,array()); } - $this->compiler->prefix_code = array(); - $this->current_buffer->append_subtree($this, - new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode($tmp . $code, true))); } } - - // line 255 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r2() - { - $text = $this->yystack[ $this->yyidx + 0 ]->minor; - - if ((string)$text == '') { - $this->current_buffer->append_subtree($this, null); - } - - $this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text($text, $this->strip)); } - - // line 259 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r3() - { - $this->strip = true; +// line 323 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r13(){ + $j = strrpos($this->yystack[$this->yyidx + 0]->minor,'.'); + if ($this->yystack[$this->yyidx + 0]->minor[$j+1] == 'c') { + // {$smarty.block.child} + $this->_retvalue = $this->compiler->compileTag('child',array(),array($this->yystack[$this->yyidx + 0]->minor)); + } else { + // {$smarty.block.parent} + $this->_retvalue = $this->compiler->compileTag('parent',array(),array($this->yystack[$this->yyidx + 0]->minor)); + } + } +// line 334 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r14(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; + } +// line 338 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r15(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; + } +// line 342 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r16(){ + $this->_retvalue = $this->compiler->compileTag('private_print_expression',$this->yystack[$this->yyidx + 0]->minor[1],array('value'=>$this->yystack[$this->yyidx + 0]->minor[0])); + } +// line 351 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r17(){ + $this->_retvalue = $this->compiler->compileTag('assign',array_merge(array(array('value'=>$this->yystack[$this->yyidx + 0]->minor[0]),array('var'=>'\''.substr($this->yystack[$this->yyidx + -1]->minor,1).'\'')),$this->yystack[$this->yyidx + 0]->minor[1])); + } +// line 355 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r18(){ + $this->_retvalue = $this->compiler->compileTag('assign',array_merge(array(array('value'=>$this->yystack[$this->yyidx + 0]->minor[0]),array('var'=>$this->yystack[$this->yyidx + -1]->minor['var'])),$this->yystack[$this->yyidx + 0]->minor[1]),array('smarty_internal_index'=>$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index'])); + } +// line 359 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r19(){ + $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; + } +// line 363 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r20(){ + $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor); + } +// line 378 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r24(){ + if (defined($this->yystack[$this->yyidx + -1]->minor)) { + if ($this->security) { + $this->security->isTrustedConstant($this->yystack[$this->yyidx + -1]->minor, $this->compiler); + } + $this->_retvalue = $this->compiler->compileTag('private_print_expression',$this->yystack[$this->yyidx + 0]->minor,array('value'=>$this->yystack[$this->yyidx + -1]->minor)); + } else { + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor); + } } - - // line 264 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r4() - { +// line 388 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r25(){ + if (defined($this->yystack[$this->yyidx + 0]->minor)) { + if ($this->security) { + $this->security->isTrustedConstant($this->yystack[$this->yyidx + 0]->minor, $this->compiler); + } + $this->_retvalue = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$this->yystack[$this->yyidx + 0]->minor)); + } else { + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + 0]->minor,array()); + } + } +// line 401 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r26(){ + if (defined($this->yystack[$this->yyidx + -2]->minor)) { + if ($this->security) { + $this->security->isTrustedConstant($this->yystack[$this->yyidx + -2]->minor, $this->compiler); + } + $this->_retvalue = $this->compiler->compileTag('private_print_expression',$this->yystack[$this->yyidx + 0]->minor,array('value'=>$this->yystack[$this->yyidx + -2]->minor, 'modifierlist'=>$this->yystack[$this->yyidx + -1]->minor)); + } else { + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor,$this->yystack[$this->yyidx + 0]->minor, array('modifierlist'=>$this->yystack[$this->yyidx + -1]->minor)); + } + } +// line 413 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r27(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -3]->minor,$this->yystack[$this->yyidx + 0]->minor,array('object_method'=>$this->yystack[$this->yyidx + -1]->minor)); + } +// line 418 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r28(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -4]->minor,$this->yystack[$this->yyidx + 0]->minor,array('modifierlist'=>$this->yystack[$this->yyidx + -1]->minor, 'object_method'=>$this->yystack[$this->yyidx + -2]->minor)); + } +// line 423 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r29(){ + $this->_retvalue = $this->compiler->compileTag('make_nocache',array(array('var'=>'\''.substr($this->yystack[$this->yyidx + 0]->minor,1).'\''))); + } +// line 428 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r30(){ + $tag = trim(substr($this->yystack[$this->yyidx + -1]->minor,$this->compiler->getLdelLength())); + $this->_retvalue = $this->compiler->compileTag(($tag === 'else if')? 'elseif' : $tag,array(),array('if condition'=>$this->yystack[$this->yyidx + 0]->minor)); + } +// line 433 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r31(){ + $tag = trim(substr($this->yystack[$this->yyidx + -2]->minor,$this->compiler->getLdelLength())); + $this->_retvalue = $this->compiler->compileTag(($tag === 'else if')? 'elseif' : $tag,$this->yystack[$this->yyidx + 0]->minor,array('if condition'=>$this->yystack[$this->yyidx + -1]->minor)); + } +// line 438 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r32(){ + $tag = trim(substr($this->yystack[$this->yyidx + -1]->minor,$this->compiler->getLdelLength())); + $this->_retvalue = $this->compiler->compileTag(($tag === 'else if')? 'elseif' : $tag,array(),array('if condition'=>$this->yystack[$this->yyidx + 0]->minor)); + } +// line 449 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r34(){ + $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + 0]->minor,array(array('start'=>$this->yystack[$this->yyidx + -6]->minor),array('ifexp'=>$this->yystack[$this->yyidx + -4]->minor),array('var'=>$this->yystack[$this->yyidx + -2]->minor),array('step'=>$this->yystack[$this->yyidx + -1]->minor))),1); + } +// line 453 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r35(){ + $this->_retvalue = '='.$this->yystack[$this->yyidx + 0]->minor; + } +// line 461 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r37(){ + $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + 0]->minor,array(array('start'=>$this->yystack[$this->yyidx + -3]->minor),array('to'=>$this->yystack[$this->yyidx + -1]->minor))),0); + } +// line 465 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r38(){ + $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + 0]->minor,array(array('start'=>$this->yystack[$this->yyidx + -5]->minor),array('to'=>$this->yystack[$this->yyidx + -3]->minor),array('step'=>$this->yystack[$this->yyidx + -1]->minor))),0); + } +// line 470 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r39(){ + $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + 0]->minor,array(array('from'=>$this->yystack[$this->yyidx + -3]->minor),array('item'=>$this->yystack[$this->yyidx + -1]->minor)))); + } +// line 474 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r40(){ + $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + 0]->minor,array(array('from'=>$this->yystack[$this->yyidx + -5]->minor),array('item'=>$this->yystack[$this->yyidx + -1]->minor),array('key'=>$this->yystack[$this->yyidx + -3]->minor)))); + } +// line 477 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r41(){ + $this->_retvalue = $this->compiler->compileTag('foreach',$this->yystack[$this->yyidx + 0]->minor); + } +// line 482 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r42(){ + $this->_retvalue = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array(array_merge(array($this->yystack[$this->yyidx + -1]->minor),$this->yystack[$this->yyidx + 0]->minor)))); + } +// line 486 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r43(){ + $this->_retvalue = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array_merge(array(array_merge(array($this->yystack[$this->yyidx + -2]->minor),$this->yystack[$this->yyidx + -1]->minor)),$this->yystack[$this->yyidx + 0]->minor))); + } +// line 492 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r44(){ + $tag = trim(substr($this->yystack[$this->yyidx + 0]->minor, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' /'); + if ($tag === 'strip') { $this->strip = false; + $this->_retvalue = null; + } else { + $this->_retvalue = $this->compiler->compileTag($tag.'close',array()); + } + } +// line 501 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r45(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + 0]->minor.'close',array()); + } +// line 505 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r46(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -1]->minor.'close',array(),array('modifier_list'=>$this->yystack[$this->yyidx + 0]->minor)); + } +// line 510 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r47(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor.'close',array(),array('object_method'=>$this->yystack[$this->yyidx + 0]->minor)); + } +// line 514 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r48(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -3]->minor.'close',array(),array('object_method'=>$this->yystack[$this->yyidx + -1]->minor, 'modifier_list'=>$this->yystack[$this->yyidx + 0]->minor)); + } +// line 522 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r49(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; + $this->_retvalue[] = $this->yystack[$this->yyidx + 0]->minor; + } +// line 528 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r50(){ + $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor); + } +// line 533 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r51(){ + $this->_retvalue = array(); + } +// line 538 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r52(){ + if (defined($this->yystack[$this->yyidx + 0]->minor)) { + if ($this->security) { + $this->security->isTrustedConstant($this->yystack[$this->yyidx + 0]->minor, $this->compiler); + } + $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>$this->yystack[$this->yyidx + 0]->minor); + } else { + $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>'\''.$this->yystack[$this->yyidx + 0]->minor.'\''); } - - // line 269 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r5() - { - $this->current_buffer->append_subtree($this, - new Smarty_Internal_ParseTree_Text($this->yystack[ $this->yyidx + -1 ]->minor)); } - - // line 272 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r6() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -3 ]->minor . $this->yystack[ $this->yyidx + -1 ]->minor; +// line 549 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r53(){ + $this->_retvalue = array(trim($this->yystack[$this->yyidx + -1]->minor," =\n\r\t")=>$this->yystack[$this->yyidx + 0]->minor); } - - // line 276 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r7() - { - $this->_retvalue = $this->yystack[ $this->yyidx + 0 ]->minor; +// line 557 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r55(){ + $this->_retvalue = '\''.$this->yystack[$this->yyidx + 0]->minor.'\''; } - - // line 281 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r8() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor . $this->yystack[ $this->yyidx + 0 ]->minor; +// line 569 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r58(){ + $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>$this->yystack[$this->yyidx + 0]->minor); } - - // line 285 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r9() - { - $this->_retvalue = ''; +// line 582 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r60(){ + $this->yystack[$this->yyidx + -2]->minor[]=$this->yystack[$this->yyidx + 0]->minor; + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor; } - - // line 297 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r10() - { - if ($this->compiler->has_code) { - $this->current_buffer->append_subtree($this, - $this->mergePrefixCode($this->yystack[ $this->yyidx + 0 ]->minor)); - } - $this->compiler->has_variable_string = false; - $this->block_nesting_level = count($this->compiler->_tag_stack); +// line 587 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r61(){ + $this->_retvalue = array('var' => '\''.substr($this->yystack[$this->yyidx + -2]->minor,1).'\'', 'value'=>$this->yystack[$this->yyidx + 0]->minor); } - - // line 307 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r12() - { - $var = - trim(substr($this->yystack[ $this->yyidx + 0 ]->minor, $this->compiler->getLdelLength(), - -$this->compiler->getRdelLength()), ' $'); - if (preg_match('/^(.*)(\s+nocache)$/', $var, $match)) { - $this->_retvalue = - $this->compiler->compileTag('private_print_expression', array('nocache'), - array('value' => $this->compiler->compileVariable('\'' . $match[ 1 ] . '\''))); - } else { - $this->_retvalue = - $this->compiler->compileTag('private_print_expression', array(), - array('value' => $this->compiler->compileVariable('\'' . $var . '\''))); - } +// line 594 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r63(){ + $this->_retvalue = array('var' => $this->yystack[$this->yyidx + -2]->minor, 'value'=>$this->yystack[$this->yyidx + 0]->minor); } - - // line 328 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r13() - { - $tag = - trim(substr($this->yystack[ $this->yyidx + 0 ]->minor, $this->compiler->getLdelLength(), - -$this->compiler->getRdelLength())); - if ($tag == 'strip') { - $this->strip = true; - $this->_retvalue = null; - } else { - if (defined($tag)) { - if ($this->security) { - $this->security->isTrustedConstant($tag, $this->compiler); - } - $this->_retvalue = - $this->compiler->compileTag('private_print_expression', array(), array('value' => $tag)); - } else { - if (preg_match('/^(.*)(\s+nocache)$/', $tag, $match)) { - $this->_retvalue = $this->compiler->compileTag($match[ 1 ], array('\'nocache\'')); - } else { - $this->_retvalue = $this->compiler->compileTag($tag, array()); - } - } - } +// line 598 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r64(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; } - - // line 339 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r14() - { - $j = strrpos($this->yystack[ $this->yyidx + 0 ]->minor, '.'); - if ($this->yystack[ $this->yyidx + 0 ]->minor[ $j + 1 ] == 'c') { - // {$smarty.block.child} - $this->_retvalue = - $this->compiler->compileTag('child', array(), array($this->yystack[ $this->yyidx + 0 ]->minor)); - } else { - // {$smarty.block.parent} - $this->_retvalue = - $this->compiler->compileTag('parent', array(), array($this->yystack[ $this->yyidx + 0 ]->minor)); - } +// line 618 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r67(){ + $this->_retvalue = '$_smarty_tpl->getStreamVariable(\''.substr($this->yystack[$this->yyidx + -2]->minor,1).'://' . $this->yystack[$this->yyidx + 0]->minor . '\')'; } - - // line 343 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r15() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor; +// line 623 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r68(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor . trim($this->yystack[$this->yyidx + -1]->minor) . $this->yystack[$this->yyidx + 0]->minor; } - - // line 347 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r16() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor; +// line 633 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r70(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor['pre']. $this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor['op'].$this->yystack[$this->yyidx + 0]->minor .')'; } - - // line 356 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r17() - { - $this->_retvalue = - $this->compiler->compileTag('private_print_expression', $this->yystack[ $this->yyidx + 0 ]->minor[ 1 ], - array('value' => $this->yystack[ $this->yyidx + 0 ]->minor[ 0 ])); +// line 637 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r71(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; } - - // line 360 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r18() - { - $this->_retvalue = - $this->compiler->compileTag('assign', array_merge(array( - array('value' => $this->yystack[ $this->yyidx + 0 ]->minor[ 0 ]), - array('var' => '\'' . substr($this->yystack[ $this->yyidx + -1 ]->minor, 1) . '\'') - ), $this->yystack[ $this->yyidx + 0 ]->minor[ 1 ])); +// line 641 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r72(){ + $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor . $this->yystack[$this->yyidx + -1]->minor . ')'; } - - // line 364 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r19() - { - $this->_retvalue = - $this->compiler->compileTag('assign', array_merge(array( - array('value' => $this->yystack[ $this->yyidx + 0 ]->minor[ 0 ]), - array('var' => $this->yystack[ $this->yyidx + -1 ]->minor[ 'var' ]) - ), $this->yystack[ $this->yyidx + 0 ]->minor[ 1 ]), array( - 'smarty_internal_index' => $this->yystack[ $this->yyidx + - -1 ]->minor[ 'smarty_internal_index' ] - )); - } - - // line 368 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r20() - { - $this->_retvalue = $this->yystack[ $this->yyidx + 0 ]->minor; +// line 645 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r73(){ + $this->_retvalue = 'in_array('.$this->yystack[$this->yyidx + -2]->minor.','.$this->yystack[$this->yyidx + 0]->minor.')'; } - - // line 383 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r21() - { - $this->_retvalue = array($this->yystack[ $this->yyidx + -1 ]->minor, $this->yystack[ $this->yyidx + 0 ]->minor); - } - - // line 393 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r25() - { - if (defined($this->yystack[ $this->yyidx + -1 ]->minor)) { - if ($this->security) { - $this->security->isTrustedConstant($this->yystack[ $this->yyidx + -1 ]->minor, $this->compiler); - } - $this->_retvalue = - $this->compiler->compileTag('private_print_expression', $this->yystack[ $this->yyidx + 0 ]->minor, - array('value' => $this->yystack[ $this->yyidx + -1 ]->minor)); - } else { - $this->_retvalue = - $this->compiler->compileTag($this->yystack[ $this->yyidx + -1 ]->minor, - $this->yystack[ $this->yyidx + 0 ]->minor); - } - } - - // line 406 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r26() - { - if (defined($this->yystack[ $this->yyidx + 0 ]->minor)) { - if ($this->security) { - $this->security->isTrustedConstant($this->yystack[ $this->yyidx + 0 ]->minor, $this->compiler); - } - $this->_retvalue = - $this->compiler->compileTag('private_print_expression', array(), - array('value' => $this->yystack[ $this->yyidx + 0 ]->minor)); - } else { - $this->_retvalue = $this->compiler->compileTag($this->yystack[ $this->yyidx + 0 ]->minor, array()); - } - } - - // line 418 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r27() - { - if (defined($this->yystack[ $this->yyidx + -2 ]->minor)) { - if ($this->security) { - $this->security->isTrustedConstant($this->yystack[ $this->yyidx + -2 ]->minor, $this->compiler); - } - $this->_retvalue = - $this->compiler->compileTag('private_print_expression', $this->yystack[ $this->yyidx + 0 ]->minor, - array( - 'value' => $this->yystack[ $this->yyidx + -2 ]->minor, - 'modifierlist' => $this->yystack[ $this->yyidx + -1 ]->minor - )); - } else { - $this->_retvalue = - $this->compiler->compileTag($this->yystack[ $this->yyidx + -2 ]->minor, - $this->yystack[ $this->yyidx + 0 ]->minor, - array('modifierlist' => $this->yystack[ $this->yyidx + -1 ]->minor)); - } - } - - // line 423 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r28() - { - $this->_retvalue = - $this->compiler->compileTag($this->yystack[ $this->yyidx + -3 ]->minor, - $this->yystack[ $this->yyidx + 0 ]->minor, - array('object_method' => $this->yystack[ $this->yyidx + -1 ]->minor)); - } - - // line 428 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r29() - { - $this->_retvalue = - $this->compiler->compileTag($this->yystack[ $this->yyidx + -4 ]->minor, - $this->yystack[ $this->yyidx + 0 ]->minor, array( - 'modifierlist' => $this->yystack[ $this->yyidx + -1 ]->minor, - 'object_method' => $this->yystack[ $this->yyidx + -2 ]->minor - )); - } - - // line 433 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r30() - { - $this->_retvalue = - $this->compiler->compileTag('make_nocache', - array(array('var' => '\'' . substr($this->yystack[ $this->yyidx + 0 ]->minor, 1) . '\''))); - } - - // line 438 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r31() - { - $tag = trim(substr($this->yystack[ $this->yyidx + -1 ]->minor, $this->compiler->getLdelLength())); - $this->_retvalue = - $this->compiler->compileTag(($tag === 'else if') ? 'elseif' : $tag, array(), - array('if condition' => $this->yystack[ $this->yyidx + 0 ]->minor)); - } - - // line 443 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r32() - { - $tag = trim(substr($this->yystack[ $this->yyidx + -2 ]->minor, $this->compiler->getLdelLength())); - $this->_retvalue = - $this->compiler->compileTag(($tag === 'else if') ? 'elseif' : $tag, - $this->yystack[ $this->yyidx + 0 ]->minor, - array('if condition' => $this->yystack[ $this->yyidx + -1 ]->minor)); - } - - // line 454 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r33() - { - $tag = trim(substr($this->yystack[ $this->yyidx + -1 ]->minor, $this->compiler->getLdelLength())); - $this->_retvalue = - $this->compiler->compileTag(($tag === 'else if') ? 'elseif' : $tag, array(), - array('if condition' => $this->yystack[ $this->yyidx + 0 ]->minor)); - } - - // line 458 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r35() - { - $this->_retvalue = - $this->compiler->compileTag('for', array_merge($this->yystack[ $this->yyidx + 0 ]->minor, array( - array('start' => $this->yystack[ $this->yyidx + -6 ]->minor), - array('ifexp' => $this->yystack[ $this->yyidx + -4 ]->minor), - array('var' => $this->yystack[ $this->yyidx + -2 ]->minor), - array('step' => $this->yystack[ $this->yyidx + -1 ]->minor) - )), 1); - } - - // line 466 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r36() - { - $this->_retvalue = '=' . $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 470 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r38() - { - $this->_retvalue = - $this->compiler->compileTag('for', array_merge($this->yystack[ $this->yyidx + 0 ]->minor, array( - array('start' => $this->yystack[ $this->yyidx + -3 ]->minor), - array('to' => $this->yystack[ $this->yyidx + -1 ]->minor) - )), 0); - } - - // line 475 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r39() - { - $this->_retvalue = - $this->compiler->compileTag('for', array_merge($this->yystack[ $this->yyidx + 0 ]->minor, array( - array('start' => $this->yystack[ $this->yyidx + -5 ]->minor), - array('to' => $this->yystack[ $this->yyidx + -3 ]->minor), - array('step' => $this->yystack[ $this->yyidx + -1 ]->minor) - )), 0); - } - - // line 479 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r40() - { - $this->_retvalue = - $this->compiler->compileTag('foreach', array_merge($this->yystack[ $this->yyidx + 0 ]->minor, array( - array('from' => $this->yystack[ $this->yyidx + -3 ]->minor), - array('item' => $this->yystack[ $this->yyidx + -1 ]->minor) - ))); - } - - // line 482 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r41() - { - $this->_retvalue = - $this->compiler->compileTag('foreach', array_merge($this->yystack[ $this->yyidx + 0 ]->minor, array( - array('from' => $this->yystack[ $this->yyidx + -5 ]->minor), - array('item' => $this->yystack[ $this->yyidx + -1 ]->minor), - array('key' => $this->yystack[ $this->yyidx + -3 ]->minor) - ))); - } - - // line 487 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r42() - { - $this->_retvalue = $this->compiler->compileTag('foreach', $this->yystack[ $this->yyidx + 0 ]->minor); - } - - // line 491 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r43() - { - $this->_retvalue = - $this->compiler->compileTag('setfilter', array(), array( - 'modifier_list' => array( - array_merge(array($this->yystack[ $this->yyidx + -1 ]->minor), - $this->yystack[ $this->yyidx + 0 ]->minor) - ) - )); - } - - // line 497 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r44() - { - $this->_retvalue = - $this->compiler->compileTag('setfilter', array(), array( - 'modifier_list' => array_merge(array( - array_merge(array( - $this->yystack[ $this->yyidx + - -2 ]->minor - ), $this->yystack[ $this->yyidx + -1 ]->minor) - ), $this->yystack[ $this->yyidx + 0 ]->minor) - )); - } - - // line 506 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r45() - { - $tag = - trim(substr($this->yystack[ $this->yyidx + 0 ]->minor, $this->compiler->getLdelLength(), - -$this->compiler->getRdelLength()), ' /'); - if ($tag === 'strip') { - $this->strip = false; - $this->_retvalue = null; - } else { - $this->_retvalue = $this->compiler->compileTag($tag . 'close', array()); - } - } - - // line 510 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r46() - { - $this->_retvalue = $this->compiler->compileTag($this->yystack[ $this->yyidx + 0 ]->minor . 'close', array()); - } - - // line 515 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r47() - { - $this->_retvalue = - $this->compiler->compileTag($this->yystack[ $this->yyidx + -1 ]->minor . 'close', array(), - array('modifier_list' => $this->yystack[ $this->yyidx + 0 ]->minor)); - } - - // line 519 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r48() - { - $this->_retvalue = - $this->compiler->compileTag($this->yystack[ $this->yyidx + -2 ]->minor . 'close', array(), - array('object_method' => $this->yystack[ $this->yyidx + 0 ]->minor)); - } - - // line 527 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r49() - { - $this->_retvalue = - $this->compiler->compileTag($this->yystack[ $this->yyidx + -3 ]->minor . 'close', array(), array( - 'object_method' => $this->yystack[ $this->yyidx + -1 ]->minor, - 'modifier_list' => $this->yystack[ $this->yyidx + 0 ]->minor - )); - } - - // line 533 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r50() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor; - $this->_retvalue[] = $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 538 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r51() - { - $this->_retvalue = array($this->yystack[ $this->yyidx + 0 ]->minor); - } - - // line 543 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r52() - { - $this->_retvalue = array(); - } - - // line 554 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r53() - { - if (defined($this->yystack[ $this->yyidx + 0 ]->minor)) { - if ($this->security) { - $this->security->isTrustedConstant($this->yystack[ $this->yyidx + 0 ]->minor, $this->compiler); - } - $this->_retvalue = - array($this->yystack[ $this->yyidx + -2 ]->minor => $this->yystack[ $this->yyidx + 0 ]->minor); - } else { - $this->_retvalue = - array( - $this->yystack[ $this->yyidx + -2 ]->minor => '\'' . - $this->yystack[ $this->yyidx + 0 ]->minor . - '\'' - ); - } - } - - // line 562 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r54() - { - $this->_retvalue = - array( - trim($this->yystack[ $this->yyidx + -1 ]->minor, " =\n\r\t") => $this->yystack[ $this->yyidx + - 0 ]->minor - ); - } - - // line 574 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r56() - { - $this->_retvalue = '\'' . $this->yystack[ $this->yyidx + 0 ]->minor . '\''; - } - - // line 587 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r59() - { - $this->_retvalue = - array($this->yystack[ $this->yyidx + -2 ]->minor => $this->yystack[ $this->yyidx + 0 ]->minor); - } - - // line 592 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r61() - { - $this->yystack[ $this->yyidx + -2 ]->minor[] = $this->yystack[ $this->yyidx + 0 ]->minor; - $this->_retvalue = $this->yystack[ $this->yyidx + -2 ]->minor; - } - - // line 599 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r62() - { - $this->_retvalue = - array( - 'var' => '\'' . substr($this->yystack[ $this->yyidx + -2 ]->minor, 1) . '\'', - 'value' => $this->yystack[ $this->yyidx + 0 ]->minor - ); - } - - // line 603 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r64() - { - $this->_retvalue = - array( - 'var' => $this->yystack[ $this->yyidx + -2 ]->minor, - 'value' => $this->yystack[ $this->yyidx + 0 ]->minor - ); - } - - // line 623 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r65() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor; - } - - // line 628 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r68() - { - $this->_retvalue = - '$_smarty_tpl->getStreamVariable(\'' . - substr($this->yystack[ $this->yyidx + -2 ]->minor, 1) . - '://' . - $this->yystack[ $this->yyidx + 0 ]->minor . - '\')'; - } - - // line 638 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r69() - { - $this->_retvalue = - $this->yystack[ $this->yyidx + -2 ]->minor . - trim($this->yystack[ $this->yyidx + -1 ]->minor) . - $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 642 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r71() - { - $this->_retvalue = - $this->yystack[ $this->yyidx + -1 ]->minor[ 'pre' ] . - $this->yystack[ $this->yyidx + -2 ]->minor . - $this->yystack[ $this->yyidx + -1 ]->minor[ 'op' ] . - $this->yystack[ $this->yyidx + 0 ]->minor . - ')'; - } - - // line 646 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r72() - { - $this->_retvalue = - $this->yystack[ $this->yyidx + -2 ]->minor . - $this->yystack[ $this->yyidx + -1 ]->minor . - $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 650 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r73() - { - $this->_retvalue = $this->yystack[ $this->yyidx + 0 ]->minor . $this->yystack[ $this->yyidx + -1 ]->minor . ')'; - } - - // line 654 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r74() - { - $this->_retvalue = - 'in_array(' . - $this->yystack[ $this->yyidx + -2 ]->minor . - ',' . - $this->yystack[ $this->yyidx + 0 ]->minor . - ')'; - } - - // line 662 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r75() - { - $this->_retvalue = - 'in_array(' . - $this->yystack[ $this->yyidx + -2 ]->minor . - ',(array)' . - $this->yystack[ $this->yyidx + 0 ]->minor . - ')'; - } - - // line 666 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r76() - { - $this->_retvalue = - $this->yystack[ $this->yyidx + -5 ]->minor . - ' ? ' . - $this->compiler->compileVariable('\'' . substr($this->yystack[ $this->yyidx + -2 ]->minor, 1) . '\'') . - ' : ' . - $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 676 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r77() - { - $this->_retvalue = - $this->yystack[ $this->yyidx + -5 ]->minor . - ' ? ' . - $this->yystack[ $this->yyidx + -2 ]->minor . - ' : ' . - $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 681 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r79() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor . $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 702 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r80() - { - $this->_retvalue = '!' . $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 706 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r85() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -2 ]->minor . '.' . $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 710 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r86() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor . '.'; - } - - // line 715 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r87() - { - $this->_retvalue = '.' . $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 732 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r88() - { - if (defined($this->yystack[ $this->yyidx + 0 ]->minor)) { - if ($this->security) { - $this->security->isTrustedConstant($this->yystack[ $this->yyidx + 0 ]->minor, $this->compiler); - } - $this->_retvalue = $this->yystack[ $this->yyidx + 0 ]->minor; - } else { - $this->_retvalue = '\'' . $this->yystack[ $this->yyidx + 0 ]->minor . '\''; - } - } - - // line 736 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r90() - { - $this->_retvalue = '(' . $this->yystack[ $this->yyidx + -1 ]->minor . ')'; - } - - // line 754 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r91() - { - $this->_retvalue = - $this->yystack[ $this->yyidx + -2 ]->minor . - $this->yystack[ $this->yyidx + -1 ]->minor . - $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 765 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r95() - { - $prefixVar = $this->compiler->getNewPrefixVariable(); - if ($this->yystack[ $this->yyidx + -2 ]->minor[ 'var' ] === '\'smarty\'') { - $this->compiler->appendPrefixCode("compiler->compileTag('private_special_variable', array(), - $this->yystack[ $this->yyidx + - -2 ]->minor[ 'smarty_internal_index' ]) . - ';?>'); - } else { - $this->compiler->appendPrefixCode("compiler->compileVariable($this->yystack[ $this->yyidx + - -2 ]->minor[ 'var' ]) . - $this->yystack[ $this->yyidx + -2 ]->minor[ 'smarty_internal_index' ] . - ';?>'); - } - $this->_retvalue = - $prefixVar . - '::' . - $this->yystack[ $this->yyidx + 0 ]->minor[ 0 ] . - $this->yystack[ $this->yyidx + 0 ]->minor[ 1 ]; - } - - // line 772 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r96() - { - $prefixVar = $this->compiler->getNewPrefixVariable(); - $tmp = $this->compiler->appendCode('', $this->yystack[ $this->yyidx + 0 ]->minor); - $this->compiler->appendPrefixCode($this->compiler->appendCode($tmp, "")); - $this->_retvalue = $prefixVar; - } - - // line 785 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r97() - { - $this->_retvalue = - $this->compiler->compileTag('private_modifier', array(), array( - 'value' => $this->yystack[ $this->yyidx + -1 ]->minor, - 'modifierlist' => $this->yystack[ $this->yyidx + 0 ]->minor - )); +// line 649 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r74(){ + $this->_retvalue = 'in_array('.$this->yystack[$this->yyidx + -2]->minor.',(array)'.$this->yystack[$this->yyidx + 0]->minor.')'; } - - // line 804 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r100() - { - if (!in_array(strtolower($this->yystack[ $this->yyidx + -2 ]->minor), array('self', 'parent')) && - (!$this->security || - $this->security->isTrustedStaticClassAccess($this->yystack[ $this->yyidx + -2 ]->minor, - $this->yystack[ $this->yyidx + 0 ]->minor, $this->compiler))) { - if (isset($this->smarty->registered_classes[ $this->yystack[ $this->yyidx + -2 ]->minor ])) { - $this->_retvalue = - $this->smarty->registered_classes[ $this->yystack[ $this->yyidx + -2 ]->minor ] . - '::' . - $this->yystack[ $this->yyidx + 0 ]->minor[ 0 ] . - $this->yystack[ $this->yyidx + 0 ]->minor[ 1 ]; - } else { - $this->_retvalue = - $this->yystack[ $this->yyidx + -2 ]->minor . - '::' . - $this->yystack[ $this->yyidx + 0 ]->minor[ 0 ] . - $this->yystack[ $this->yyidx + 0 ]->minor[ 1 ]; - } - } else { - $this->compiler->trigger_template_error('static class \'' . - $this->yystack[ $this->yyidx + -2 ]->minor . - '\' is undefined or not allowed by security setting'); - } - } - - // line 815 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r102() - { - $this->_retvalue = $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 818 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r103() - { - $this->_retvalue = - $this->compiler->compileVariable('\'' . substr($this->yystack[ $this->yyidx + 0 ]->minor, 1) . '\''); +// line 657 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r75(){ + $this->_retvalue = $this->yystack[$this->yyidx + -5]->minor.' ? '. $this->compiler->compileVariable('\''.substr($this->yystack[$this->yyidx + -2]->minor,1).'\'') . ' : '.$this->yystack[$this->yyidx + 0]->minor; } - - // line 831 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r104() - { - if ($this->yystack[ $this->yyidx + 0 ]->minor[ 'var' ] === '\'smarty\'') { - $smarty_var = - $this->compiler->compileTag('private_special_variable', array(), - $this->yystack[ $this->yyidx + 0 ]->minor[ 'smarty_internal_index' ]); - $this->_retvalue = $smarty_var; - } else { - // used for array reset,next,prev,end,current - $this->last_variable = $this->yystack[ $this->yyidx + 0 ]->minor[ 'var' ]; - $this->last_index = $this->yystack[ $this->yyidx + 0 ]->minor[ 'smarty_internal_index' ]; - $this->_retvalue = - $this->compiler->compileVariable($this->yystack[ $this->yyidx + 0 ]->minor[ 'var' ]) . - $this->yystack[ $this->yyidx + 0 ]->minor[ 'smarty_internal_index' ]; - } +// line 661 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r76(){ + $this->_retvalue = $this->yystack[$this->yyidx + -5]->minor.' ? '.$this->yystack[$this->yyidx + -2]->minor.' : '.$this->yystack[$this->yyidx + 0]->minor; } - - // line 841 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r105() - { - $this->_retvalue = - '$_smarty_tpl->tpl_vars[' . - $this->yystack[ $this->yyidx + -2 ]->minor . - ']->' . - $this->yystack[ $this->yyidx + 0 ]->minor; +// line 671 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r78(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; } - - // line 845 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r107() - { - $this->_retvalue = - $this->compiler->compileConfigVariable('\'' . $this->yystack[ $this->yyidx + -1 ]->minor . '\''); +// line 676 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r79(){ + $this->_retvalue = '!'.$this->yystack[$this->yyidx + 0]->minor; } - - // line 849 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r108() - { - $this->_retvalue = - '(is_array($tmp = ' . - $this->compiler->compileConfigVariable('\'' . $this->yystack[ $this->yyidx + -2 ]->minor . '\'') . - ') ? $tmp' . - $this->yystack[ $this->yyidx + 0 ]->minor . - ' :null)'; +// line 697 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r84(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'.'.$this->yystack[$this->yyidx + 0]->minor; } - - // line 853 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r109() - { - $this->_retvalue = $this->compiler->compileConfigVariable($this->yystack[ $this->yyidx + -1 ]->minor); - } - - // line 857 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r110() - { - $this->_retvalue = - '(is_array($tmp = ' . - $this->compiler->compileConfigVariable($this->yystack[ $this->yyidx + -2 ]->minor) . - ') ? $tmp' . - $this->yystack[ $this->yyidx + 0 ]->minor . - ' : null)'; - } - - // line 860 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r111() - { - $this->_retvalue = - array( - 'var' => '\'' . substr($this->yystack[ $this->yyidx + -1 ]->minor, 1) . '\'', - 'smarty_internal_index' => $this->yystack[ $this->yyidx + 0 ]->minor - ); - } - - // line 873 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r112() - { - $this->_retvalue = - array( - 'var' => $this->yystack[ $this->yyidx + -1 ]->minor, - 'smarty_internal_index' => $this->yystack[ $this->yyidx + 0 ]->minor - ); - } - - // line 879 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r114() - { - return; - } - - // line 882 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r115() - { - $this->_retvalue = - '[' . - $this->compiler->compileVariable('\'' . substr($this->yystack[ $this->yyidx + 0 ]->minor, 1) . '\'') . - ']'; - } - - // line 886 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r116() - { - $this->_retvalue = '[' . $this->compiler->compileVariable($this->yystack[ $this->yyidx + 0 ]->minor) . ']'; - } - - // line 890 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r117() - { - $this->_retvalue = - '[' . - $this->compiler->compileVariable($this->yystack[ $this->yyidx + -2 ]->minor) . - '->' . - $this->yystack[ $this->yyidx + 0 ]->minor . - ']'; - } - - // line 894 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r118() - { - $this->_retvalue = '[\'' . $this->yystack[ $this->yyidx + 0 ]->minor . '\']'; - } - - // line 899 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r119() - { - $this->_retvalue = '[' . $this->yystack[ $this->yyidx + 0 ]->minor . ']'; - } - - // line 904 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r120() - { - $this->_retvalue = '[' . $this->yystack[ $this->yyidx + -1 ]->minor . ']'; - } - - // line 908 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r121() - { - $this->_retvalue = - '[' . - $this->compiler->compileTag('private_special_variable', array(), - '[\'section\'][\'' . $this->yystack[ $this->yyidx + -1 ]->minor . '\'][\'index\']') . - ']'; - } - - // line 911 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r122() - { - $this->_retvalue = - '[' . - $this->compiler->compileTag('private_special_variable', array(), '[\'section\'][\'' . - $this->yystack[ $this->yyidx + - -3 ]->minor . - '\'][\'' . - $this->yystack[ $this->yyidx + - -1 ]->minor . - '\']') . - ']'; - } - - // line 917 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r123() - { - $this->_retvalue = '[' . $this->yystack[ $this->yyidx + -1 ]->minor . ']'; - } - - // line 933 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r125() - { - $this->_retvalue = - '[' . - $this->compiler->compileVariable('\'' . substr($this->yystack[ $this->yyidx + -1 ]->minor, 1) . '\'') . - ']'; - } - - // line 943 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r129() - { - $this->_retvalue = '[]'; - } - - // line 947 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r130() - { - $this->_retvalue = '\'' . substr($this->yystack[ $this->yyidx + 0 ]->minor, 1) . '\''; - } - - // line 952 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r131() - { - $this->_retvalue = '\'\''; - } - - // line 960 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r132() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor . '.' . $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 966 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r134() - { - $var = - trim(substr($this->yystack[ $this->yyidx + 0 ]->minor, $this->compiler->getLdelLength(), - -$this->compiler->getRdelLength()), ' $'); - $this->_retvalue = $this->compiler->compileVariable('\'' . $var . '\''); - } - - // line 973 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r135() - { - $this->_retvalue = '(' . $this->yystack[ $this->yyidx + -1 ]->minor . ')'; - } - - // line 982 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r136() - { - if ($this->yystack[ $this->yyidx + -1 ]->minor[ 'var' ] === '\'smarty\'') { - $this->_retvalue = - $this->compiler->compileTag('private_special_variable', array(), - $this->yystack[ $this->yyidx + -1 ]->minor[ 'smarty_internal_index' ]) . - $this->yystack[ $this->yyidx + 0 ]->minor; - } else { - $this->_retvalue = - $this->compiler->compileVariable($this->yystack[ $this->yyidx + -1 ]->minor[ 'var' ]) . - $this->yystack[ $this->yyidx + -1 ]->minor[ 'smarty_internal_index' ] . - $this->yystack[ $this->yyidx + 0 ]->minor; - } - } - - // line 987 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r137() - { - $this->_retvalue = $this->yystack[ $this->yyidx + 0 ]->minor; - } - - // line 992 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r138() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor . $this->yystack[ $this->yyidx + 0 ]->minor; +// line 701 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r85(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.'.'; } - - // line 999 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r139() - { - if ($this->security && substr($this->yystack[ $this->yyidx + -1 ]->minor, 0, 1) === '_') { - $this->compiler->trigger_template_error(self::ERR1); - } - $this->_retvalue = - '->' . $this->yystack[ $this->yyidx + -1 ]->minor . $this->yystack[ $this->yyidx + 0 ]->minor; +// line 705 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r86(){ + $this->_retvalue = '.'.$this->yystack[$this->yyidx + 0]->minor; } - - // line 1006 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r140() - { +// line 710 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r87(){ + if (defined($this->yystack[$this->yyidx + 0]->minor)) { if ($this->security) { - $this->compiler->trigger_template_error(self::ERR2); + $this->security->isTrustedConstant($this->yystack[$this->yyidx + 0]->minor, $this->compiler); } - $this->_retvalue = - '->{' . - $this->compiler->compileVariable($this->yystack[ $this->yyidx + -1 ]->minor) . - $this->yystack[ $this->yyidx + 0 ]->minor . - '}'; + $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; + } else { + $this->_retvalue = '\''.$this->yystack[$this->yyidx + 0]->minor.'\''; } - - // line 1013 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r141() - { - if ($this->security) { - $this->compiler->trigger_template_error(self::ERR2); - } - $this->_retvalue = - '->{' . $this->yystack[ $this->yyidx + -2 ]->minor . $this->yystack[ $this->yyidx + 0 ]->minor . '}'; } - - // line 1021 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r142() - { - if ($this->security) { - $this->compiler->trigger_template_error(self::ERR2); - } - $this->_retvalue = - '->{\'' . - $this->yystack[ $this->yyidx + -4 ]->minor . - '\'.' . - $this->yystack[ $this->yyidx + -2 ]->minor . - $this->yystack[ $this->yyidx + 0 ]->minor . - '}'; +// line 727 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r89(){ + $this->_retvalue = '('. $this->yystack[$this->yyidx + -1]->minor .')'; } - - // line 1029 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r143() - { - $this->_retvalue = '->' . $this->yystack[ $this->yyidx + 0 ]->minor; +// line 731 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r90(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; } - - // line 1037 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r144() - { - $this->_retvalue = - $this->compiler->compilePHPFunctionCall($this->yystack[ $this->yyidx + -3 ]->minor, - $this->yystack[ $this->yyidx + -1 ]->minor); +// line 749 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r94(){ + if ($this->security && $this->security->static_classes !== array()) { + $this->compiler->trigger_template_error('dynamic static class not allowed by security setting'); + } + $prefixVar = $this->compiler->getNewPrefixVariable(); + if ($this->yystack[$this->yyidx + -2]->minor['var'] === '\'smarty\'') { + $this->compiler->appendPrefixCode("compiler->compileTag('private_special_variable',array(),$this->yystack[$this->yyidx + -2]->minor['smarty_internal_index']).';?>'); + } else { + $this->compiler->appendPrefixCode("compiler->compileVariable($this->yystack[$this->yyidx + -2]->minor['var']).$this->yystack[$this->yyidx + -2]->minor['smarty_internal_index'].';?>'); + } + $this->_retvalue = $prefixVar .'::'.$this->yystack[$this->yyidx + 0]->minor[0].$this->yystack[$this->yyidx + 0]->minor[1]; + } +// line 760 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r95(){ + $prefixVar = $this->compiler->getNewPrefixVariable(); + $tmp = $this->compiler->appendCode('', $this->yystack[$this->yyidx + 0]->minor); + $this->compiler->appendPrefixCode($this->compiler->appendCode($tmp, "")); + $this->_retvalue = $prefixVar; + } +// line 767 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r96(){ + $this->_retvalue = $this->compiler->compileTag('private_modifier',array(),array('value'=>$this->yystack[$this->yyidx + -1]->minor,'modifierlist'=>$this->yystack[$this->yyidx + 0]->minor)); + } +// line 780 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r99(){ + if (!in_array(strtolower($this->yystack[$this->yyidx + -2]->minor), array('self', 'parent')) && (!$this->security || $this->security->isTrustedStaticClassAccess($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->compiler))) { + if (isset($this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor])) { + $this->_retvalue = $this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor].'::'.$this->yystack[$this->yyidx + 0]->minor[0].$this->yystack[$this->yyidx + 0]->minor[1]; + } else { + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'::'.$this->yystack[$this->yyidx + 0]->minor[0].$this->yystack[$this->yyidx + 0]->minor[1]; + } + } else { + $this->compiler->trigger_template_error ('static class \''.$this->yystack[$this->yyidx + -2]->minor.'\' is undefined or not allowed by security setting'); } - - // line 1044 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r145() - { - if ($this->security && substr($this->yystack[ $this->yyidx + -3 ]->minor, 0, 1) === '_') { - $this->compiler->trigger_template_error(self::ERR1); - } - $this->_retvalue = - $this->yystack[ $this->yyidx + -3 ]->minor . - '(' . - implode(',', $this->yystack[ $this->yyidx + -1 ]->minor) . - ')'; } - - // line 1055 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r146() - { - if ($this->security) { - $this->compiler->trigger_template_error(self::ERR2); +// line 799 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r101(){ + $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; } - $prefixVar = $this->compiler->getNewPrefixVariable(); - $this->compiler->appendPrefixCode("compiler->compileVariable('\'' . - substr($this->yystack[ $this->yyidx + - -3 ]->minor, 1) . - '\'') . - ';?>'); - $this->_retvalue = $prefixVar . '(' . implode(',', $this->yystack[ $this->yyidx + -1 ]->minor) . ')'; - } - - // line 1072 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r147() - { - $this->_retvalue = - array_merge($this->yystack[ $this->yyidx + -2 ]->minor, array($this->yystack[ $this->yyidx + 0 ]->minor)); +// line 810 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r102(){ + $this->_retvalue = $this->compiler->compileVariable('\''.substr($this->yystack[$this->yyidx + 0]->minor,1).'\''); + } +// line 813 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r103(){ + if ($this->yystack[$this->yyidx + 0]->minor['var'] === '\'smarty\'') { + $smarty_var = $this->compiler->compileTag('private_special_variable',array(),$this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']); + $this->_retvalue = $smarty_var; + } else { + // used for array reset,next,prev,end,current + $this->last_variable = $this->yystack[$this->yyidx + 0]->minor['var']; + $this->last_index = $this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']; + $this->_retvalue = $this->compiler->compileVariable($this->yystack[$this->yyidx + 0]->minor['var']).$this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']; + } + } +// line 826 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r104(){ + $this->_retvalue = '$_smarty_tpl->tpl_vars['. $this->yystack[$this->yyidx + -2]->minor .']->'.$this->yystack[$this->yyidx + 0]->minor; + } +// line 836 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r106(){ + $this->_retvalue = $this->compiler->compileConfigVariable('\'' . $this->yystack[$this->yyidx + -1]->minor . '\''); + } +// line 840 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r107(){ + $this->_retvalue = '(is_array($tmp = ' . $this->compiler->compileConfigVariable('\'' . $this->yystack[$this->yyidx + -2]->minor . '\'') . ') ? $tmp'.$this->yystack[$this->yyidx + 0]->minor.' :null)'; + } +// line 844 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r108(){ + $this->_retvalue = $this->compiler->compileConfigVariable($this->yystack[$this->yyidx + -1]->minor); + } +// line 848 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r109(){ + $this->_retvalue = '(is_array($tmp = ' . $this->compiler->compileConfigVariable($this->yystack[$this->yyidx + -2]->minor) . ') ? $tmp'.$this->yystack[$this->yyidx + 0]->minor.' : null)'; + } +// line 852 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r110(){ + $this->_retvalue = array('var'=>'\''.substr($this->yystack[$this->yyidx + -1]->minor,1).'\'', 'smarty_internal_index'=>$this->yystack[$this->yyidx + 0]->minor); + } +// line 855 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r111(){ + $this->_retvalue = array('var'=>$this->yystack[$this->yyidx + -1]->minor, 'smarty_internal_index'=>$this->yystack[$this->yyidx + 0]->minor); + } +// line 868 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r113(){ + return; + } +// line 874 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r114(){ + $this->_retvalue = '['.$this->compiler->compileVariable('\''.substr($this->yystack[$this->yyidx + 0]->minor,1).'\'').']'; + } +// line 877 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r115(){ + $this->_retvalue = '['.$this->compiler->compileVariable($this->yystack[$this->yyidx + 0]->minor).']'; + } +// line 881 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r116(){ + $this->_retvalue = '['.$this->compiler->compileVariable($this->yystack[$this->yyidx + -2]->minor).'->'.$this->yystack[$this->yyidx + 0]->minor.']'; + } +// line 885 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r117(){ + $this->_retvalue = '[\''. $this->yystack[$this->yyidx + 0]->minor .'\']'; + } +// line 889 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r118(){ + $this->_retvalue = '['. $this->yystack[$this->yyidx + 0]->minor .']'; + } +// line 894 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r119(){ + $this->_retvalue = '['. $this->yystack[$this->yyidx + -1]->minor .']'; } - - // line 1076 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r150() - { - $this->_retvalue = - array_merge($this->yystack[ $this->yyidx + -2 ]->minor, array( - array_merge($this->yystack[ $this->yyidx + -1 ]->minor, $this->yystack[ $this->yyidx + 0 ]->minor) - )); +// line 899 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r120(){ + $this->_retvalue = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.$this->yystack[$this->yyidx + -1]->minor.'\'][\'index\']').']'; + } +// line 903 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r121(){ + $this->_retvalue = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.$this->yystack[$this->yyidx + -3]->minor.'\'][\''.$this->yystack[$this->yyidx + -1]->minor.'\']').']'; + } +// line 906 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r122(){ + $this->_retvalue = '['.$this->yystack[$this->yyidx + -1]->minor.']'; + } +// line 912 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r124(){ + $this->_retvalue = '['.$this->compiler->compileVariable('\''.substr($this->yystack[$this->yyidx + -1]->minor,1).'\'').']'; + } +// line 928 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r128(){ + $this->_retvalue = '[]'; + } +// line 938 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r129(){ + $this->_retvalue = '\''.substr($this->yystack[$this->yyidx + 0]->minor,1).'\''; + } +// line 942 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r130(){ + $this->_retvalue = '\'\''; + } +// line 947 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r131(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.'.'.$this->yystack[$this->yyidx + 0]->minor; } - - // line 1084 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r151() - { - $this->_retvalue = - array(array_merge($this->yystack[ $this->yyidx + -1 ]->minor, $this->yystack[ $this->yyidx + 0 ]->minor)); +// line 955 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r133(){ + $var = trim(substr($this->yystack[$this->yyidx + 0]->minor, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' $'); + $this->_retvalue = $this->compiler->compileVariable('\''.$var.'\''); } - - // line 1092 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r153() - { - $this->_retvalue = array($this->yystack[ $this->yyidx + 0 ]->minor); +// line 961 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r134(){ + $this->_retvalue = '('.$this->yystack[$this->yyidx + -1]->minor.')'; } - - // line 1105 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r154() - { - $this->_retvalue = - array_merge($this->yystack[ $this->yyidx + -1 ]->minor, $this->yystack[ $this->yyidx + 0 ]->minor); +// line 968 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r135(){ + if ($this->yystack[$this->yyidx + -1]->minor['var'] === '\'smarty\'') { + $this->_retvalue = $this->compiler->compileTag('private_special_variable',array(),$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index']).$this->yystack[$this->yyidx + 0]->minor; + } else { + $this->_retvalue = $this->compiler->compileVariable($this->yystack[$this->yyidx + -1]->minor['var']).$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index'].$this->yystack[$this->yyidx + 0]->minor; } - - // line 1114 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r157() - { - $this->_retvalue = - array(trim($this->yystack[ $this->yyidx + -1 ]->minor) . $this->yystack[ $this->yyidx + 0 ]->minor); } - - // line 1119 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r159() - { - $this->_retvalue = array($this->yystack[ $this->yyidx + 0 ]->minor, '', 'method'); +// line 977 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r136(){ + $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; } - - // line 1124 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r160() - { - $this->_retvalue = - array($this->yystack[ $this->yyidx + -1 ]->minor, $this->yystack[ $this->yyidx + 0 ]->minor, 'method'); +// line 982 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r137(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; } - - // line 1129 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r161() - { - $this->_retvalue = array($this->yystack[ $this->yyidx + 0 ]->minor, ''); +// line 987 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r138(){ + if ($this->security && substr($this->yystack[$this->yyidx + -1]->minor,0,1) === '_') { + $this->compiler->trigger_template_error (self::ERR1); } - - // line 1134 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r162() - { - $this->_retvalue = - array($this->yystack[ $this->yyidx + -1 ]->minor, $this->yystack[ $this->yyidx + 0 ]->minor, 'property'); - } - - // line 1140 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r163() - { - $this->_retvalue = - array( - $this->yystack[ $this->yyidx + -2 ]->minor, - $this->yystack[ $this->yyidx + -1 ]->minor . $this->yystack[ $this->yyidx + 0 ]->minor, 'property' - ); + $this->_retvalue = '->'.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; } - - // line 1144 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r164() - { - $this->_retvalue = ' ' . trim($this->yystack[ $this->yyidx + 0 ]->minor) . ' '; - } - - // line 1163 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r165() - { - static $lops = array( - 'eq' => ' == ', - 'ne' => ' != ', - 'neq' => ' != ', - 'gt' => ' > ', - 'ge' => ' >= ', - 'gte' => ' >= ', - 'lt' => ' < ', - 'le' => ' <= ', - 'lte' => ' <= ', - 'mod' => ' % ', - 'and' => ' && ', - 'or' => ' || ', - 'xor' => ' xor ', - ); - $op = strtolower(preg_replace('/\s*/', '', $this->yystack[ $this->yyidx + 0 ]->minor)); - $this->_retvalue = $lops[ $op ]; - } - - // line 1176 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r166() - { - static $tlops = array( - 'isdivby' => array('op' => ' % ', 'pre' => '!('), - 'isnotdivby' => array('op' => ' % ', 'pre' => '('), - 'isevenby' => array('op' => ' / ', 'pre' => '!(1 & '), - 'isnotevenby' => array('op' => ' / ', 'pre' => '(1 & '), - 'isoddby' => array('op' => ' / ', 'pre' => '(1 & '), - 'isnotoddby' => array('op' => ' / ', 'pre' => '!(1 & '), - ); - $op = strtolower(preg_replace('/\s*/', '', $this->yystack[ $this->yyidx + 0 ]->minor)); - $this->_retvalue = $tlops[ $op ]; - } - - // line 1190 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r167() - { - static $scond = array( - 'iseven' => '!(1 & ', +// line 994 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r139(){ + if ($this->security) { + $this->compiler->trigger_template_error (self::ERR2); + } + $this->_retvalue = '->{'.$this->compiler->compileVariable($this->yystack[$this->yyidx + -1]->minor).$this->yystack[$this->yyidx + 0]->minor.'}'; + } +// line 1001 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r140(){ + if ($this->security) { + $this->compiler->trigger_template_error (self::ERR2); + } + $this->_retvalue = '->{'.$this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + 0]->minor.'}'; + } +// line 1008 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r141(){ + if ($this->security) { + $this->compiler->trigger_template_error (self::ERR2); + } + $this->_retvalue = '->{\''.$this->yystack[$this->yyidx + -4]->minor.'\'.'.$this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + 0]->minor.'}'; + } +// line 1016 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r142(){ + $this->_retvalue = '->'.$this->yystack[$this->yyidx + 0]->minor; + } +// line 1024 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r143(){ + $this->_retvalue = $this->compiler->compilePHPFunctionCall($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + -1]->minor); + } +// line 1032 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r144(){ + if ($this->security && substr($this->yystack[$this->yyidx + -3]->minor,0,1) === '_') { + $this->compiler->trigger_template_error (self::ERR1); + } + $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . '('. implode(',',$this->yystack[$this->yyidx + -1]->minor) .')'; + } +// line 1039 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r145(){ + if ($this->security) { + $this->compiler->trigger_template_error (self::ERR2); + } + $prefixVar = $this->compiler->getNewPrefixVariable(); + $this->compiler->appendPrefixCode("compiler->compileVariable('\''.substr($this->yystack[$this->yyidx + -3]->minor,1).'\'').';?>'); + $this->_retvalue = $prefixVar .'('. implode(',',$this->yystack[$this->yyidx + -1]->minor) .')'; + } +// line 1050 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r146(){ + $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor,array($this->yystack[$this->yyidx + 0]->minor)); + } +// line 1067 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r149(){ + $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor,array(array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor))); + } +// line 1071 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r150(){ + $this->_retvalue = array(array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor)); + } +// line 1079 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r152(){ + $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor); + } +// line 1087 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r153(){ + $this->_retvalue = array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor); + } +// line 1100 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r156(){ + $this->_retvalue = array(trim($this->yystack[$this->yyidx + -1]->minor).$this->yystack[$this->yyidx + 0]->minor); + } +// line 1109 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r158(){ + $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor, '', 'method'); + } +// line 1114 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r159(){ + $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor, 'method'); + } +// line 1119 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r160(){ + $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor, ''); + } +// line 1124 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r161(){ + $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor, 'property'); + } +// line 1129 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r162(){ + $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor, 'property'); + } +// line 1135 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r163(){ + $this->_retvalue = ' '. trim($this->yystack[$this->yyidx + 0]->minor) . ' '; + } +// line 1139 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r164(){ + static $lops = array( + 'eq' => ' == ', + 'ne' => ' != ', + 'neq' => ' != ', + 'gt' => ' > ', + 'ge' => ' >= ', + 'gte' => ' >= ', + 'lt' => ' < ', + 'le' => ' <= ', + 'lte' => ' <= ', + 'mod' => ' % ', + 'and' => ' && ', + 'or' => ' || ', + 'xor' => ' xor ', + ); + $op = strtolower(preg_replace('/\s*/', '', $this->yystack[$this->yyidx + 0]->minor)); + $this->_retvalue = $lops[$op]; + } +// line 1158 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r165(){ + static $tlops = array( + 'isdivby' => array('op' => ' % ', 'pre' => '!('), + 'isnotdivby' => array('op' => ' % ', 'pre' => '('), + 'isevenby' => array('op' => ' / ', 'pre' => '!(1 & '), + 'isnotevenby' => array('op' => ' / ', 'pre' => '(1 & '), + 'isoddby' => array('op' => ' / ', 'pre' => '(1 & '), + 'isnotoddby' => array('op' => ' / ', 'pre' => '!(1 & '), + ); + $op = strtolower(preg_replace('/\s*/', '', $this->yystack[$this->yyidx + 0]->minor)); + $this->_retvalue = $tlops[$op]; + } +// line 1171 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r166(){ + static $scond = array ( + 'iseven' => '!(1 & ', 'isnoteven' => '(1 & ', - 'isodd' => '(1 & ', - 'isnotodd' => '!(1 & ', + 'isodd' => '(1 & ', + 'isnotodd' => '!(1 & ', ); - $op = strtolower(str_replace(' ', '', $this->yystack[ $this->yyidx + 0 ]->minor)); - $this->_retvalue = $scond[ $op ]; + $op = strtolower(str_replace(' ', '', $this->yystack[$this->yyidx + 0]->minor)); + $this->_retvalue = $scond[$op]; } - - // line 1201 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r168() - { - $this->_retvalue = 'array(' . $this->yystack[ $this->yyidx + -1 ]->minor . ')'; +// line 1185 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r167(){ + $this->_retvalue = 'array('.$this->yystack[$this->yyidx + -1]->minor.')'; } - - // line 1209 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r171() - { - $this->_retvalue = $this->yystack[ $this->yyidx + -2 ]->minor . ',' . $this->yystack[ $this->yyidx + 0 ]->minor; +// line 1196 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r170(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.','.$this->yystack[$this->yyidx + 0]->minor; } - - // line 1213 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r173() - { - $this->_retvalue = - $this->yystack[ $this->yyidx + -2 ]->minor . '=>' . $this->yystack[ $this->yyidx + 0 ]->minor; +// line 1204 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r172(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'=>'.$this->yystack[$this->yyidx + 0]->minor; } - - // line 1229 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r174() - { - $this->_retvalue = - '\'' . $this->yystack[ $this->yyidx + -2 ]->minor . '\'=>' . $this->yystack[ $this->yyidx + 0 ]->minor; +// line 1208 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r173(){ + $this->_retvalue = '\''.$this->yystack[$this->yyidx + -2]->minor.'\'=>'.$this->yystack[$this->yyidx + 0]->minor; } - - // line 1235 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r177() - { - $this->compiler->leaveDoubleQuote(); - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor->to_smarty_php($this); +// line 1224 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r176(){ + $this->compiler->leaveDoubleQuote(); + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor->to_smarty_php($this); } - - // line 1240 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r178() - { - $this->yystack[ $this->yyidx + -1 ]->minor->append_subtree($this, $this->yystack[ $this->yyidx + 0 ]->minor); - $this->_retvalue = $this->yystack[ $this->yyidx + -1 ]->minor; +// line 1230 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r177(){ + $this->yystack[$this->yyidx + -1]->minor->append_subtree($this, $this->yystack[$this->yyidx + 0]->minor); + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; } - - // line 1244 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r179() - { - $this->_retvalue = new Smarty_Internal_ParseTree_Dq($this, $this->yystack[ $this->yyidx + 0 ]->minor); +// line 1235 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r178(){ + $this->_retvalue = new Smarty_Internal_ParseTree_Dq($this, $this->yystack[$this->yyidx + 0]->minor); } - - // line 1248 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r180() - { - $this->_retvalue = new Smarty_Internal_ParseTree_Code('(string)' . $this->yystack[ $this->yyidx + -1 ]->minor); +// line 1239 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r179(){ + $this->_retvalue = new Smarty_Internal_ParseTree_Code('(string)'.$this->yystack[$this->yyidx + -1]->minor); } - - // line 1252 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r181() - { - $this->_retvalue = - new Smarty_Internal_ParseTree_Code('(string)(' . $this->yystack[ $this->yyidx + -1 ]->minor . ')'); +// line 1243 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r180(){ + $this->_retvalue = new Smarty_Internal_ParseTree_Code('(string)('.$this->yystack[$this->yyidx + -1]->minor.')'); } - - // line 1264 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r182() - { - $this->_retvalue = - new Smarty_Internal_ParseTree_Code('(string)$_smarty_tpl->tpl_vars[\'' . - substr($this->yystack[ $this->yyidx + 0 ]->minor, 1) . - '\']->value'); +// line 1247 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r181(){ + $this->_retvalue = new Smarty_Internal_ParseTree_Code('(string)$_smarty_tpl->tpl_vars[\''. substr($this->yystack[$this->yyidx + 0]->minor,1) .'\']->value'); } - - // line 1268 "../smarty/lexer/smarty_internal_templateparser.y" - public function yy_r185() - { - $this->_retvalue = new Smarty_Internal_ParseTree_Tag($this, $this->yystack[ $this->yyidx + 0 ]->minor); +// line 1259 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r184(){ + $this->_retvalue = new Smarty_Internal_ParseTree_Tag($this, $this->yystack[$this->yyidx + 0]->minor); } - - public function yy_r186() - { - $this->_retvalue = new Smarty_Internal_ParseTree_DqContent($this->yystack[ $this->yyidx + 0 ]->minor); +// line 1263 "../smarty/lexer/smarty_internal_templateparser.y" + public function yy_r185(){ + $this->_retvalue = new Smarty_Internal_ParseTree_DqContent($this->yystack[$this->yyidx + 0]->minor); } + private $_retvalue; + public function yy_reduce($yyruleno) { if ($this->yyTraceFILE && $yyruleno >= 0 - && $yyruleno < count(self::$yyRuleName)) { + && $yyruleno < count(self::$yyRuleName)) { fprintf($this->yyTraceFILE, "%sReduce (%d) [%s].\n", $this->yyTracePrompt, $yyruleno, - self::$yyRuleName[ $yyruleno ]); + self::$yyRuleName[$yyruleno]); } + $this->_retvalue = $yy_lefthand_side = null; - if (isset(self::$yyReduceMap[ $yyruleno ])) { + if (isset(self::$yyReduceMap[$yyruleno])) { // call the action $this->_retvalue = null; - $this->{'yy_r' . self::$yyReduceMap[ $yyruleno ]}(); + $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}(); $yy_lefthand_side = $this->_retvalue; } - $yygoto = self::$yyRuleInfo[ $yyruleno ][ 0 ]; - $yysize = self::$yyRuleInfo[ $yyruleno ][ 1 ]; + $yygoto = self::$yyRuleInfo[$yyruleno][0]; + $yysize = self::$yyRuleInfo[$yyruleno][1]; $this->yyidx -= $yysize; for ($i = $yysize; $i; $i--) { // pop all of the right-hand side parameters array_pop($this->yystack); } - $yyact = $this->yy_find_reduce_action($this->yystack[ $this->yyidx ]->stateno, $yygoto); + $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto); if ($yyact < self::YYNSTATE) { if (!$this->yyTraceFILE && $yysize) { $this->yyidx++; @@ -3492,7 +2792,7 @@ public function yy_reduce($yyruleno) $x->stateno = $yyact; $x->major = $yygoto; $x->minor = $yy_lefthand_side; - $this->yystack[ $this->yyidx ] = $x; + $this->yystack[$this->yyidx] = $x; } else { $this->yy_shift($yyact, $yygoto, $yy_lefthand_side); } @@ -3505,37 +2805,38 @@ public function yy_parse_failed() { if ($this->yyTraceFILE) { fprintf($this->yyTraceFILE, "%sFail!\n", $this->yyTracePrompt); - } - while ($this->yyidx >= 0) { + } while ($this->yyidx >= 0) { $this->yy_pop_parser_stack(); } } public function yy_syntax_error($yymajor, $TOKEN) { - // line 214 "../smarty/lexer/smarty_internal_templateparser.y" - $this->internalError = true; - $this->yymajor = $yymajor; - $this->compiler->trigger_template_error(); +// line 213 "../smarty/lexer/smarty_internal_templateparser.y" + + $this->internalError = true; + $this->yymajor = $yymajor; + $this->compiler->trigger_template_error(); } public function yy_accept() { if ($this->yyTraceFILE) { fprintf($this->yyTraceFILE, "%sAccept!\n", $this->yyTracePrompt); - } - while ($this->yyidx >= 0) { + } while ($this->yyidx >= 0) { $this->yy_pop_parser_stack(); } - // line 207 "../smarty/lexer/smarty_internal_templateparser.y" - $this->successful = !$this->internalError; - $this->internalError = false; - $this->retvalue = $this->_retvalue; +// line 206 "../smarty/lexer/smarty_internal_templateparser.y" + + $this->successful = !$this->internalError; + $this->internalError = false; + $this->retvalue = $this->_retvalue; } public function doParse($yymajor, $yytokenvalue) { $yyerrorhit = 0; /* True if yymajor has invoked an error */ + if ($this->yyidx === null || $this->yyidx < 0) { $this->yyidx = 0; $this->yyerrcnt = -1; @@ -3545,15 +2846,17 @@ public function doParse($yymajor, $yytokenvalue) $this->yystack = array(); $this->yystack[] = $x; } - $yyendofinput = ($yymajor == 0); + $yyendofinput = ($yymajor==0); + if ($this->yyTraceFILE) { fprintf($this->yyTraceFILE, "%sInput %s\n", - $this->yyTracePrompt, $this->yyTokenName[ $yymajor ]); + $this->yyTracePrompt, $this->yyTokenName[$yymajor]); } + do { $yyact = $this->yy_find_shift_action($yymajor); if ($yymajor < self::YYERRORSYMBOL && - !$this->yy_is_expected_token($yymajor)) { + !$this->yy_is_expected_token($yymajor)) { // force a syntax error $yyact = self::YY_ERROR_ACTION; } @@ -3576,22 +2879,22 @@ public function doParse($yymajor, $yytokenvalue) if ($this->yyerrcnt < 0) { $this->yy_syntax_error($yymajor, $yytokenvalue); } - $yymx = $this->yystack[ $this->yyidx ]->major; + $yymx = $this->yystack[$this->yyidx]->major; if ($yymx === self::YYERRORSYMBOL || $yyerrorhit) { if ($this->yyTraceFILE) { fprintf($this->yyTraceFILE, "%sDiscard input token %s\n", - $this->yyTracePrompt, $this->yyTokenName[ $yymajor ]); + $this->yyTracePrompt, $this->yyTokenName[$yymajor]); } $this->yy_destructor($yymajor, $yytokenvalue); $yymajor = self::YYNOCODE; } else { while ($this->yyidx >= 0 && - $yymx !== self::YYERRORSYMBOL && - ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE - ) { + $yymx !== self::YYERRORSYMBOL && + ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE + ){ $this->yy_pop_parser_stack(); } - if ($this->yyidx < 0 || $yymajor == 0) { + if ($this->yyidx < 0 || $yymajor==0) { $this->yy_destructor($yymajor, $yytokenvalue); $this->yy_parse_failed(); $yymajor = self::YYNOCODE; diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_testinstall.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_testinstall.php index 504a4582c..1fac79b74 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_testinstall.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_testinstall.php @@ -362,7 +362,6 @@ public static function testInstall(Smarty $smarty, &$errors = null) 'smarty_internal_compile_function.php' => true, 'smarty_internal_compile_if.php' => true, 'smarty_internal_compile_include.php' => true, - 'smarty_internal_compile_include_php.php' => true, 'smarty_internal_compile_insert.php' => true, 'smarty_internal_compile_ldelim.php' => true, 'smarty_internal_compile_make_nocache.php' => true, @@ -373,7 +372,6 @@ public static function testInstall(Smarty $smarty, &$errors = null) 'smarty_internal_compile_private_modifier.php' => true, 'smarty_internal_compile_private_object_block_function.php' => true, 'smarty_internal_compile_private_object_function.php' => true, - 'smarty_internal_compile_private_php.php' => true, 'smarty_internal_compile_private_print_expression.php' => true, 'smarty_internal_compile_private_registered_block.php' => true, 'smarty_internal_compile_private_registered_function.php' => true, @@ -388,7 +386,6 @@ public static function testInstall(Smarty $smarty, &$errors = null) 'smarty_internal_config_file_compiler.php' => true, 'smarty_internal_data.php' => true, 'smarty_internal_debug.php' => true, - 'smarty_internal_errorhandler.php' => true, 'smarty_internal_extension_handler.php' => true, 'smarty_internal_method_addautoloadfilters.php' => true, 'smarty_internal_method_adddefaultmodifiers.php' => true, @@ -450,7 +447,6 @@ public static function testInstall(Smarty $smarty, &$errors = null) 'smarty_internal_resource_extends.php' => true, 'smarty_internal_resource_file.php' => true, 'smarty_internal_resource_php.php' => true, - 'smarty_internal_resource_registered.php' => true, 'smarty_internal_resource_stream.php' => true, 'smarty_internal_resource_string.php' => true, 'smarty_internal_runtime_cachemodify.php' => true, diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_resource.php b/WEB-INF/lib/smarty/sysplugins/smarty_resource.php index aae7e42f7..7fe84536f 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_resource.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_resource.php @@ -72,9 +72,7 @@ public static function load(Smarty $smarty, $type) } // try registered resource if (isset($smarty->registered_resources[ $type ])) { - return $smarty->_cache[ 'resource_handlers' ][ $type ] = - $smarty->registered_resources[ $type ] instanceof Smarty_Resource ? - $smarty->registered_resources[ $type ] : new Smarty_Internal_Resource_Registered(); + return $smarty->_cache[ 'resource_handlers' ][ $type ] = $smarty->registered_resources[ $type ]; } // try sysplugins dir if (isset(self::$sysplugins[ $type ])) { diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_security.php b/WEB-INF/lib/smarty/sysplugins/smarty_security.php index 441a7e284..3c29c8132 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_security.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_security.php @@ -21,19 +21,6 @@ */ class Smarty_Security { - /** - * This determines how Smarty handles "" tags in templates. - * possible values: - *
    - *
  • Smarty::PHP_PASSTHRU -> echo PHP tags as they are
  • - *
  • Smarty::PHP_QUOTE -> escape tags as entities
  • - *
  • Smarty::PHP_REMOVE -> remove php tags
  • - *
  • Smarty::PHP_ALLOW -> execute php tags
  • - *
- * - * @var integer - */ - public $php_handling = Smarty::PHP_PASSTHRU; /** * This is the list of template directories that are considered secure. diff --git a/WEB-INF/lib/smarty/sysplugins/smartycompilerexception.php b/WEB-INF/lib/smarty/sysplugins/smartycompilerexception.php index f7ad39b93..8833aa52c 100644 --- a/WEB-INF/lib/smarty/sysplugins/smartycompilerexception.php +++ b/WEB-INF/lib/smarty/sysplugins/smartycompilerexception.php @@ -16,12 +16,12 @@ public function __toString() } /** - * The line number of the template error - * - * @type int|null + * @param int $line */ - public $line = null; - + public function setLine($line) + { + $this->line = $line; + } /** * The template source snippet relating to the error * diff --git a/initialize.php b/initialize.php index 911c1f71d..f8d3cf7db 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5638"); +define("APP_VERSION", "1.20.0.5639"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 0924ef499c2b0833a20c2d180b04fa70c6484b6d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 20 Feb 2022 20:46:15 +0000 Subject: [PATCH 1661/1848] Fixed Smarty.class.php so that it is possible to use it with php5.4. --- WEB-INF/lib/smarty/Smarty.class.php | 16 +++++++++++++++- WEB-INF/lib/smarty/readme | 7 +++---- initialize.php | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/smarty/Smarty.class.php b/WEB-INF/lib/smarty/Smarty.class.php index 05325a230..85a3d9a6e 100644 --- a/WEB-INF/lib/smarty/Smarty.class.php +++ b/WEB-INF/lib/smarty/Smarty.class.php @@ -60,6 +60,18 @@ */ define('SMARTY_MBSTRING', function_exists('mb_get_info')); } + +// Note: Nik put this back in from smarty3 for php5.4 that we still support. +// See also comment around Smarty::$_CHARSET. +if (!defined('SMARTY_RESOURCE_CHAR_SET')) { + // UTF-8 can only be done properly when mbstring is available! + /** + * @deprecated in favor of Smarty::$_CHARSET + */ + define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'); +} +// End of inserted fragment by Nik. + /** * Load Smarty_Autoloader */ @@ -160,7 +172,9 @@ class Smarty extends Smarty_Internal_TemplateBase /** * The character set to adhere to (e.g. "UTF-8") */ - public static $_CHARSET = SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'; + // public static $_CHARSET = SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'; + // Note by Nik: the above assignment only works with php >= 5.6, rolling back to SMARTY_RESOURCE_CHAR_SET as in smarty3. + public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET; /** * The date format to be used internally diff --git a/WEB-INF/lib/smarty/readme b/WEB-INF/lib/smarty/readme index 91eff4784..0a894518a 100644 --- a/WEB-INF/lib/smarty/readme +++ b/WEB-INF/lib/smarty/readme @@ -1,8 +1,7 @@ -These are files from Smarty-4.1.0 with 2 modifications in: +The files in this directory are from Smarty-4.1.0. +There are 2 modified files though to support older versions of php such as 5.4. Smarty.class.php sysplugins/smarty_internal_cacheresource_file.php -Nik edited these files for php5.4 support, as they use php7.0 features. - - +Nik edited these files in a few places for php5.4 support, as they use php7.0 and php5.6 features. diff --git a/initialize.php b/initialize.php index f8d3cf7db..221f3f6cd 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5639"); +define("APP_VERSION", "1.20.0.5640"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 992bcdd2f13da3ffa7161bbb9ed7c7d118e9297a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 21 Feb 2022 13:12:10 +0000 Subject: [PATCH 1662/1848] Added a comment about required php version. Dutch file improved. --- WEB-INF/resources/nl.lang.php | 2 +- dbinstall.php | 4 ++++ initialize.php | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index dc86183ac..79baaa97d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -110,7 +110,7 @@ 'button.stop' => 'Stop', 'button.approve' => 'Goedkeuren', 'button.disapprove' => 'Afkeuren', -// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. +'button.sync' => 'Sychroniseer', // Labels for controls on forms. Labels in this section are used on multiple forms. 'label.menu' => 'Menu', diff --git a/dbinstall.php b/dbinstall.php index 12a1e6232..a3168bbfa 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -94,6 +94,10 @@ function ttGenerateKeys() { // $required_version = '5.2.1'; // Something in TCPDF library does not work below this one. $required_version = '5.4.0'; // Week view (week.php) requires 5.4 because of []-way of referencing arrays. // This needs further investigation as we use [] elsewhere without obvious problems. + // Note: unmodified smarty 4.1.0 that we needed for php 8.1 support uses plp 5.6 and 7.0 features. + // Currently, embedded smarty in this product is adjusted to still support php 5.4. + // Next time we update smarty we may need to increase $required_version. + // Print a warning about php >= 8.1 because of a breaking change // with mysqli default error mode, see https://php.watch/versions/8.1/mysqli-error-mode if (version_compare(phpversion(), '8.1', '>=')) { diff --git a/initialize.php b/initialize.php index 221f3f6cd..295d77ca0 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5640"); +define("APP_VERSION", "1.20.0.5641"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 0e2d6563e2d969209c502a1eae4ddd8e87b73299 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 21 Feb 2022 14:56:48 +0000 Subject: [PATCH 1663/1848] Addressed an sql injection vulnerability in puncher.php. --- initialize.php | 2 +- puncher.php | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/initialize.php b/initialize.php index 295d77ca0..039438f08 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5641"); +define("APP_VERSION", "1.20.0.5642"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/puncher.php b/puncher.php index 787c6f34b..0cfd37f20 100644 --- a/puncher.php +++ b/puncher.php @@ -19,6 +19,13 @@ header('Location: feature_disabled.php'); exit(); } +// If we are passed in a date, make sure it is in correct format. +// TODO: redo this temporary sql injection fix as we are not supposed to pass a date. +$date = $request->getParameter('date'); +if ($date && !ttValidDbDateFormatDate($date)) { + header('Location: access_denied.php'); + exit(); +} if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); From 1804ff3d538651464545e1fac8fefcf10442ad7b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 22 Feb 2022 17:25:34 +0000 Subject: [PATCH 1664/1848] Improved puncher plugin. --- WEB-INF/lib/common.lib.php | 13 +++++++++ WEB-INF/lib/ttDate.class.php | 6 ++++ initialize.php | 2 +- puncher.php | 55 ++++++++++++++++++------------------ 4 files changed, 48 insertions(+), 28 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index d8ed3c8d5..f5baa1a12 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -270,6 +270,19 @@ function ttValidDbDateFormatDate($val) return true; } +// ttValidTime is used to check user input for time post. +function ttValidTime($val) +{ + if (is_null($val) || strlen($val) == 0) + return false; + + // This should validate a yime string in 24 hour format hh:mm. + if (!preg_match('/^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$/', $val)) + return false; + + return true; +} + // ttValidInteger is used to check user input to validate an integer. function ttValidInteger($val, $emptyValid = false) { diff --git a/WEB-INF/lib/ttDate.class.php b/WEB-INF/lib/ttDate.class.php index 1b5bad9c4..176692f84 100644 --- a/WEB-INF/lib/ttDate.class.php +++ b/WEB-INF/lib/ttDate.class.php @@ -111,6 +111,12 @@ function getDay() { return $this->day; } function getDayOfWeek() { return $this->dayOfWeek; } + // incrementDay increments our date by a number of days. + function incrementDay(/*int*/ $days = 1) { + $this->setFromUnixTimestamp(@mktime(0, 0, 0, $this->month, $this->day + $days, $this->year)); + } + + // A static function to obtain a date in DB_DATEFORMAT from a Unix timestamp. static function dateFromUnixTimestamp($unixTimestamp = null) { if ($unixTimestamp == null) { diff --git a/initialize.php b/initialize.php index 039438f08..9328d3c0f 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5642"); +define("APP_VERSION", "1.20.0.5643"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/puncher.php b/puncher.php index 0cfd37f20..55c42e368 100644 --- a/puncher.php +++ b/puncher.php @@ -8,7 +8,7 @@ import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); -import('DateAndTime'); +import('ttDate'); // Access check. if (!ttAccessAllowed('track_own_time')) { @@ -19,13 +19,8 @@ header('Location: feature_disabled.php'); exit(); } -// If we are passed in a date, make sure it is in correct format. -// TODO: redo this temporary sql injection fix as we are not supposed to pass a date. -$date = $request->getParameter('date'); -if ($date && !ttValidDbDateFormatDate($date)) { - header('Location: access_denied.php'); - exit(); -} +// If we are passed in browser_today, make sure it is in correct format. +$browser_today = null; // Reused below beyond access checks. if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); @@ -34,6 +29,16 @@ exit(); } } +// If we are passed in browser_ttime, make sure it is in correct format. +$browser_time = null; // Reused below beyond access checks. +if ($request->isPost()) { + // Validate that browser_today parameter is in correct format. + $browser_time = $request->getParameter('browser_time'); + if ($browser_time && !ttValidTime($browser_time)) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. $showClient = $user->isPluginEnabled('cl'); @@ -44,15 +49,9 @@ $taskRequired = false; if ($showTask) $taskRequired = $user->getConfigOption('task_required'); -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; -// TODO: for timer page we may limit the day to today only. +// Initialize $cl_date. +$date_today = new ttDate($browser_today); // Initialize to browser today if we are passed it in, otherwise server today. +$cl_date = $date_today->toString(); // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { @@ -66,8 +65,8 @@ $enable_controls = ($uncompleted == null); // Initialize variables. -$cl_start = trim($request->getParameter('browser_time')); -$cl_finish = trim($request->getParameter('browser_time')); +$cl_start = $browser_time; +$cl_finish = $browser_time; $cl_duration = $cl_note = null; // Disabled controls are not posted. Therefore, && $enable_controls condition in several places below. // This allows us to get values from session when controls are disabled and reset to null when not. @@ -204,9 +203,9 @@ // Start and stop buttons. $enable_start = $uncompleted ? false : true; if (!$uncompleted) - $form->addInput(array('type'=>'submit','name'=>'btn_start','onclick'=>'browser_time.value=get_time()','value'=>$i18n->get('button.start'),'enable'=>$enable_start)); + $form->addInput(array('type'=>'submit','name'=>'btn_start','onclick'=>'browser_today.value=get_date();browser_time.value=get_time()','value'=>$i18n->get('button.start'),'enable'=>$enable_start)); else - $form->addInput(array('type'=>'submit','name'=>'btn_stop','onclick'=>'browser_time.value=get_time()','value'=>$i18n->get('button.stop'),'enable'=>!$enable_start)); + $form->addInput(array('type'=>'submit','name'=>'btn_stop','onclick'=>'browser_today.value=get_date();browser_time.value=get_time()','value'=>$i18n->get('button.stop'),'enable'=>!$enable_start)); // Submit. if ($request->isPost()) { @@ -232,15 +231,17 @@ } // Finished validating user input. - // Prohibit creating entries in future. + // Prohibit creating entries in future. Tricky with a bogus browser_today data in post. if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) + // Just check if the date we are using is after server tomorrow. + $server_tomorrow = new ttDate(); + $server_tomorrow->incrementDay(); + if ($date_today->after($server_tomorrow)) $err->add($i18n->get('error.future_date')); } // Prohibit creating time entries in locked interval. - if ($user->isDateLocked($selected_date)) + if ($user->isDateLocked($date_today)) $err->add($i18n->get('error.range_locked')); // Prohibit creating another uncompleted record. @@ -309,7 +310,7 @@ } } // isPost -$week_total = ttTimeHelper::getTimeForWeek($cl_date); +$week_total = ttTimeHelper::getTimeForWeek2($date_today); $timeRecords = ttTimeHelper::getRecords($cl_date); $smarty->assign('week_total', $week_total); @@ -329,7 +330,7 @@ $smarty->assign('task_list', $task_list); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="fillDropdowns()"'); -$smarty->assign('timestring', $selected_date->toString($user->date_format)); +$smarty->assign('timestring', $date_today->toString($user->getDateFormat())); $smarty->assign('title', $i18n->get('title.puncher')); $smarty->assign('content_page_name', 'puncher.tpl'); $smarty->display('index.tpl'); From c6e71668ca55e91c8d0f039949656a0994b3be81 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 23 Feb 2022 13:55:58 +0000 Subject: [PATCH 1665/1848] Improved a check for valid date. --- WEB-INF/lib/common.lib.php | 5 +++-- initialize.php | 2 +- puncher.php | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index f5baa1a12..6702919b7 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -267,7 +267,8 @@ function ttValidDbDateFormatDate($val) if (!preg_match('/^\d\d\d\d-\d\d-\d\d$/', $val)) return false; - return true; + $date_parts = explode('-', $val); + return checkdate($date_parts[1], $date_parts[2], $date_parts[0]); } // ttValidTime is used to check user input for time post. @@ -276,7 +277,7 @@ function ttValidTime($val) if (is_null($val) || strlen($val) == 0) return false; - // This should validate a yime string in 24 hour format hh:mm. + // This should validate a time string in 24 hour format hh:mm. if (!preg_match('/^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$/', $val)) return false; diff --git a/initialize.php b/initialize.php index 9328d3c0f..827e9ce29 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5643"); +define("APP_VERSION", "1.20.0.5644"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/puncher.php b/puncher.php index 55c42e368..d23fbd1f0 100644 --- a/puncher.php +++ b/puncher.php @@ -29,7 +29,7 @@ exit(); } } -// If we are passed in browser_ttime, make sure it is in correct format. +// If we are passed in browser_time, make sure it is in correct format. $browser_time = null; // Reused below beyond access checks. if ($request->isPost()) { // Validate that browser_today parameter is in correct format. From bb7d08fa61a40369e8eeb07e476ec0a674e2f092 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 23 Feb 2022 14:31:36 +0000 Subject: [PATCH 1666/1848] Replaced emoji with an asterisk for subgroups dropdown because it does not display properly in Chrome 98. --- WEB-INF/lib/ttUser.class.php | 5 +++-- initialize.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 592b5d9c8..19e689b58 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -555,9 +555,10 @@ function getGroupsForDropdown() { // addGroupToDropdown is a recursive function to populate a tree of groups, used with getGroupsForDropdown(). function addGroupToDropdown(&$groups, $group_id, $subgroup_level) { $name = ''; - // Add indentation markup to indicate subdirectory level. + // Add indentation markup to indicate a subdirectory level. for ($i = 0; $i < $subgroup_level; $i++) { - $name .= '🛑'; // Unicode stop sign. + $name .= '*'; + // $name .= '🛑'; // Unicode stop sign. Does not display properly in Chrome 98. } if ($subgroup_level) $name .= ' '; // Add an extra space. $name .= ttGroupHelper::getGroupName($group_id); diff --git a/initialize.php b/initialize.php index 827e9ce29..62c2c0f8f 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5644"); +define("APP_VERSION", "1.20.0.5645"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 6aaad31630500d13b6c8459daa9f406fd5eb4330 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 23 Feb 2022 15:43:34 +0000 Subject: [PATCH 1667/1848] Addressed stored XSS vulnerability when displaying primary group name. --- WEB-INF/lib/ttUser.class.php | 2 +- initialize.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 19e689b58..f1eb3e094 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -834,7 +834,7 @@ function getUserPartForHeader() { $user_part .= ', '.htmlspecialchars($this->behalf_group_name).''; } else { if ($this->group_name) // Note: we did not require group names in the past. - $user_part .= ', '.$this->group_name; + $user_part .= ', '.htmlspecialchars($this->group_name); } return $user_part; } diff --git a/initialize.php b/initialize.php index 62c2c0f8f..b4ad492fa 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5645"); +define("APP_VERSION", "1.20.0.5646"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 48a36e432dbd8789b032499eb2a8ef5549b0c5f1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 2 Mar 2022 17:24:06 +0000 Subject: [PATCH 1668/1848] A fix for issue #118. --- WEB-INF/lib/ttClientHelper.class.php | 45 +++++++++++++++++++++++++++ WEB-INF/lib/ttProjectHelper.class.php | 7 ++++- initialize.php | 2 +- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttClientHelper.class.php b/WEB-INF/lib/ttClientHelper.class.php index ba62d0f33..5c9dff349 100644 --- a/WEB-INF/lib/ttClientHelper.class.php +++ b/WEB-INF/lib/ttClientHelper.class.php @@ -358,4 +358,49 @@ static function deleteProjectFromClient($project_id, $client_id) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // unassignProjectFromAllClients - removes a project reference from all clients in tt_clients table + // and also from tt_client_project_binds. + static function unassignProjectFromAllClients($project_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $project_id = (int) $project_id; // Cast for sql injection protection, just in case. + + // Start with cleaning up tt_client_project_binds table. + $sql = "delete from tt_client_project_binds". + " where project_id = $project_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Continue with tt_clients table. + $sql = "select id, projects from tt_clients where projects like '%$project_id%' and group_id = $group_id and org_id = $org_id"; + $res = $mdb2->query($sql); + while ($val = $res->fetchRow()) { + + $client_id = (int) $val['id']; + $projectListed = false; + + $projects = explode(',', $val['projects']); + if (($key = array_search($project_id, $projects)) !== false) { + unset($projects[$key]); + $projectListed = true; + } + if (!$projectListed) + continue; // Project not listed, continue iterating. + + // If we are here, project is listed and we need to remove it. + $comma_separated = implode(',', $projects); + $sql = "update tt_clients set projects = ".$mdb2->quote($comma_separated). + " where id = $client_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + } + return true; + } } diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index dd6e35cb8..97a9dbc29 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -357,7 +357,12 @@ static function update($fields) { return false; } // End of updating tt_project_task_binds table. - + + // If we are making the project inactive, remove references to it in tt_client_project_binds table. + if (constant('INACTIVE') == $status) { + ttClientHelper::unassignProjectFromAllClients($project_id); + } + // Update project name, description, tasks and status in tt_projects table. $comma_separated = implode(",", $tasks_to_bind); // This is a comma-separated list of associated task ids. $sql = "update tt_projects set name = ".$mdb2->quote($name).", description = ".$mdb2->quote($description). diff --git a/initialize.php b/initialize.php index b4ad492fa..5d433ef69 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.0.5646"); +define("APP_VERSION", "1.20.1.5647"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From bcb15ae43e46f2ae8a326374286f95a7436647de Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 2 Mar 2022 17:27:20 +0000 Subject: [PATCH 1669/1848] Cosmetic. Comment changed for clarity. --- WEB-INF/lib/ttProjectHelper.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 97a9dbc29..4a827189b 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -358,7 +358,7 @@ static function update($fields) { } // End of updating tt_project_task_binds table. - // If we are making the project inactive, remove references to it in tt_client_project_binds table. + // If we are making the project inactive, unassign it from all clients. if (constant('INACTIVE') == $status) { ttClientHelper::unassignProjectFromAllClients($project_id); } From 407e6c65271d30c058377ece5a885ecfc852aaea Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 3 Mar 2022 18:56:25 +0000 Subject: [PATCH 1670/1848] Improved a check for overlap. Existing code was not working when finish is start as in uncompleted records. --- WEB-INF/lib/ttTimeHelper.class.php | 2 +- initialize.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index b45c6d17f..70b98458f 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -718,7 +718,7 @@ static function overlaps($user_id, $date, $start, $finish, $record_id = null) { and start is not null and duration is not null and status = 1 and ( (cast(".$mdb2->quote($start)." as time) >= start and cast(".$mdb2->quote($start)." as time) < addtime(start, duration))"; if ($finish) { - $sql .= " or (cast(".$mdb2->quote($finish)." as time) <= addtime(start, duration) and cast(".$mdb2->quote($finish)." as time) > start) + $sql .= " or (cast(".$mdb2->quote($finish)." as time) < addtime(start, duration) and cast(".$mdb2->quote($finish)." as time) >= start) or (cast(".$mdb2->quote($start)." as time) < start and cast(".$mdb2->quote($finish)." as time) > addtime(start, duration))"; } $sql .= ")"; diff --git a/initialize.php b/initialize.php index 5d433ef69..61208f771 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.1.5647"); +define("APP_VERSION", "1.20.1.5648"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From d3fcdf90b38f68f7ce1bed7f05ee74fa70fdeb7b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 4 Mar 2022 15:08:48 +0000 Subject: [PATCH 1671/1848] Rolling back a change from previous commit. --- WEB-INF/lib/ttTimeHelper.class.php | 2 +- initialize.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 70b98458f..b45c6d17f 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -718,7 +718,7 @@ static function overlaps($user_id, $date, $start, $finish, $record_id = null) { and start is not null and duration is not null and status = 1 and ( (cast(".$mdb2->quote($start)." as time) >= start and cast(".$mdb2->quote($start)." as time) < addtime(start, duration))"; if ($finish) { - $sql .= " or (cast(".$mdb2->quote($finish)." as time) < addtime(start, duration) and cast(".$mdb2->quote($finish)." as time) >= start) + $sql .= " or (cast(".$mdb2->quote($finish)." as time) <= addtime(start, duration) and cast(".$mdb2->quote($finish)." as time) > start) or (cast(".$mdb2->quote($start)." as time) < start and cast(".$mdb2->quote($finish)." as time) > addtime(start, duration))"; } $sql .= ")"; diff --git a/initialize.php b/initialize.php index 61208f771..27e302483 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.1.5648"); +define("APP_VERSION", "1.20.1.5649"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 4bf1cc9e8a50d630db7571a2894cb6d87670ea3f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 10 Mar 2022 16:57:53 +0000 Subject: [PATCH 1672/1848] Added all users option to charts. --- WEB-INF/lib/ttChartHelper.class.php | 20 +++++++++--- WEB-INF/lib/ttRoleHelper.class.php | 2 +- WEB-INF/templates/header.tpl | 2 +- WEB-INF/templates/site_map.tpl | 2 +- charts.php | 48 +++++++++++++++++++++-------- dbinstall.php | 10 +++--- initialize.php | 2 +- mysql.sql | 4 +-- 8 files changed, 63 insertions(+), 27 deletions(-) diff --git a/WEB-INF/lib/ttChartHelper.class.php b/WEB-INF/lib/ttChartHelper.class.php index 60c9897cb..faf18263b 100644 --- a/WEB-INF/lib/ttChartHelper.class.php +++ b/WEB-INF/lib/ttChartHelper.class.php @@ -40,6 +40,11 @@ class ttChartHelper { // getTotals - returns total times by project or task for a given user in a specified period. static function getTotals($user_id, $chart_type, $selected_date, $interval_type) { + global $user; + $user_id = (int) $user_id; // Cast to int just in case for sql injections. + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $period = null; switch ($interval_type) { case INTERVAL_THIS_DAY: @@ -62,25 +67,32 @@ static function getTotals($user_id, $chart_type, $selected_date, $interval_type) $result = array(); $mdb2 = getConnection(); + $userIdPart = ''; + if ($user_id > 0) { + // -1 here means "all users in group" both active and inactive. + // Therefore, we will not be using user id. + $userIdPart = "and l.user_id = $user_id"; + } + $q_period = ''; if ($period != null) { - $q_period = " and date >= '".$period->getStartDate(DB_DATEFORMAT)."' and date <= '".$period->getEndDate(DB_DATEFORMAT)."'"; + $q_period = "and date >= '".$period->getStartDate(DB_DATEFORMAT)."' and date <= '".$period->getEndDate(DB_DATEFORMAT)."'"; } if (CHART_PROJECTS == $chart_type) { // Data for projects. $sql = "select p.name as name, sum(time_to_sec(l.duration)) as time from tt_log l left join tt_projects p on (p.id = l.project_id) - where l.status = 1 and l.user_id = $user_id $q_period group by l.project_id"; + where l.status = 1 $userIdPart and l.group_id = $group_id and l.org_id = $org_id $q_period group by l.project_id"; } elseif (CHART_TASKS == $chart_type) { // Data for tasks. $sql = "select t.name as name, sum(time_to_sec(l.duration)) as time from tt_log l left join tt_tasks t on (t.id = l.task_id) - where l.status = 1 and l.user_id = $user_id $q_period group by l.task_id"; + where l.status = 1 $userIdPart and l.group_id = $group_id and l.org_id = $org_id $q_period group by l.task_id"; } elseif (CHART_CLIENTS == $chart_type) { // Data for clients. $sql = "select c.name as name, sum(time_to_sec(l.duration)) as time from tt_log l left join tt_clients c on (c.id = l.client_id) - where l.status = 1 and l.user_id = $user_id $q_period group by l.client_id"; + where l.status = 1 $userIdPart and l.group_id = $group_id and l.org_id = $org_id $q_period group by l.client_id"; } $res = $mdb2->query($sql); diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 1ddc839cc..fa6739a5b 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -169,7 +169,7 @@ static function createPredefinedRoles($group_id, $lang) $rights_client = 'view_client_reports,view_client_invoices,manage_own_settings'; $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users'; $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles'; - $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports'; + $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_charts,view_all_reports'; $rights_manager = $rights_comanager.',manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_own_timesheets,manage_subgroups'; // Active roles. diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index a189e50e5..af6151acb 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -114,7 +114,7 @@ {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->can('view_client_invoices'))}
{$i18n.title.invoices}{$i18n.menu.charts}
-
Create database structure (v1.20.0) + Create database structure (v1.21.0)
(applies only to new installations, do not execute when updating)
@@ -1290,8 +1292,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.20)Update database structure (v1.19 to v1.21)
diff --git a/initialize.php b/initialize.php index 27e302483..48af9888e 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.20.1.5649"); +define("APP_VERSION", "1.21.0.5650"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mysql.sql b/mysql.sql index 55d8e8b5c..05743ee54 100644 --- a/mysql.sql +++ b/mysql.sql @@ -78,7 +78,7 @@ create unique index role_idx on tt_roles(group_id, `rank`, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_own_timesheets,manage_subgroups,view_client_unapproved,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_charts,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_own_timesheets,manage_subgroups,view_client_unapproved,delete_group'); # @@ -621,4 +621,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.20.0', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.21.0', now()); # TODO: change when structure changes. From d6ee66fa1e218b13c093e7c7d0b34f34cb15bd06 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Mar 2022 16:12:19 +0000 Subject: [PATCH 1673/1848] Updated links. --- .htaccess | 2 +- CONTRIBUTING.md | 4 ++-- WEB-INF/config.php.dist | 4 ++-- WEB-INF/lib/Auth.class.php | 2 +- WEB-INF/lib/DateAndTime.class.php | 2 +- WEB-INF/lib/I18n.class.php | 2 +- WEB-INF/lib/Period.class.php | 2 +- WEB-INF/lib/form/ActionErrors.class.php | 2 +- WEB-INF/lib/form/ActionForm.class.php | 2 +- WEB-INF/lib/form/Calendar.class.php | 2 +- WEB-INF/lib/form/Checkbox.class.php | 2 +- WEB-INF/lib/form/CheckboxCellRenderer.class.php | 2 +- WEB-INF/lib/form/CheckboxGroup.class.php | 2 +- WEB-INF/lib/form/DefaultCellRenderer.class.php | 2 +- WEB-INF/lib/form/FloatField.class.php | 2 +- WEB-INF/lib/form/Hidden.class.php | 2 +- WEB-INF/lib/form/Submit.class.php | 2 +- WEB-INF/lib/form/Table.class.php | 2 +- WEB-INF/lib/form/TableColumn.class.php | 2 +- WEB-INF/lib/form/TextArea.class.php | 2 +- WEB-INF/lib/form/TextField.class.php | 2 +- WEB-INF/lib/form/UploadFile.class.php | 2 +- WEB-INF/lib/html/HttpRequest.class.php | 2 +- WEB-INF/lib/mail/Mailer.class.php | 2 +- WEB-INF/lib/ttBehalfUser.class.php | 2 +- WEB-INF/lib/ttChartHelper.class.php | 2 +- WEB-INF/lib/ttCronJobHelper.class.php | 2 +- WEB-INF/lib/ttDebugTracer.class.php | 2 +- WEB-INF/lib/ttNotificationHelper.class.php | 2 +- WEB-INF/lib/ttOrgExportHelper.class.php | 2 +- WEB-INF/lib/ttOrgHelper.class.php | 2 +- WEB-INF/lib/ttPredefinedExpenseHelper.class.php | 2 +- WEB-INF/lib/ttProjectHelper.class.php | 2 +- WEB-INF/lib/ttTeamHelper.class.php | 2 +- initialize.php | 2 +- plugins/CustomFields.class.php | 2 +- plugins/MonthlyQuota.class.php | 2 +- readme.txt | 10 +++++----- 38 files changed, 44 insertions(+), 44 deletions(-) diff --git a/.htaccess b/.htaccess index 189e6b4b8..3b6168c75 100644 --- a/.htaccess +++ b/.htaccess @@ -2,7 +2,7 @@ AddDefaultCharset utf-8 # Restrict access to Time Tracker only from certain IPs. # -# See https://www.anuko.com/time_tracker/faq/restrict_access_by_ip.htm for help. +# See https://www.anuko.com/time-tracker/faq/restrict-access-by-ip.htm for help. # For this to work make sure AllowOverride is set to All in web server config file. # Uncomment 3 lines below and set your IP accordingly. # diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b7311238a..58c971801 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Resources -* [docs](https://www.anuko.com/time_tracker/features.htm) - detailed documentation about this project (needs updating). +* [docs](https://www.anuko.com/time-tracker/features.htm) - detailed documentation about this project (needs updating). * [forum](https://www.anuko.com/forum/viewforum.php?f=4) - general discussion. @@ -29,4 +29,4 @@ usr: admin psw: secret ``` -Without docker, perform a manual install of a web server, php, database server, and Time Tracker. Full installation and setup guide can be found [here](https://www.anuko.com/time_tracker/install_guide/index.htm). +Without docker, perform a manual install of a web server, php, database server, and Time Tracker. Full installation and setup guide can be found [here](https://www.anuko.com/time-tracker/install-guide/index.htm). diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 9d9d90dfd..6b6a68d84 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -88,7 +88,7 @@ define('SENDER', 'Anuko Time Tracker '); // MAIL_MODE - mail sending mode. Can be 'mail' or 'smtp'. // 'mail' - sending through php mail() function. // 'smtp' - sending directly through SMTP server. -// See https://www.anuko.com/time_tracker/install_guide/mail.htm +// See https://www.anuko.com/time-tracker/install-guide/mail.htm // define('MAIL_MODE', 'smtp'); define('MAIL_SMTP_HOST', 'localhost'); // For gmail use 'ssl://smtp.gmail.com' instead of 'localhost' and port 465. @@ -133,7 +133,7 @@ define('REPORT_FOOTER', true); define('AUTH_MODULE', 'db'); // LDAP authentication examples. -// Go to https://www.anuko.com/time_tracker/install_guide/ldap_auth/index.htm for detailed configuration instructions. +// Go to https://www.anuko.com/time-tracker/install-guide/ldap-auth/index.htm for detailed configuration instructions. // Configuration example for OpenLDAP server: // define('AUTH_MODULE', 'ldap'); diff --git a/WEB-INF/lib/Auth.class.php b/WEB-INF/lib/Auth.class.php index ccf2d915d..783721090 100644 --- a/WEB-INF/lib/Auth.class.php +++ b/WEB-INF/lib/Auth.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ class Auth { diff --git a/WEB-INF/lib/DateAndTime.class.php b/WEB-INF/lib/DateAndTime.class.php index 1184bd853..e72245985 100644 --- a/WEB-INF/lib/DateAndTime.class.php +++ b/WEB-INF/lib/DateAndTime.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ /** diff --git a/WEB-INF/lib/I18n.class.php b/WEB-INF/lib/I18n.class.php index ed8380815..1760da48a 100644 --- a/WEB-INF/lib/I18n.class.php +++ b/WEB-INF/lib/I18n.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ class I18n { diff --git a/WEB-INF/lib/Period.class.php b/WEB-INF/lib/Period.class.php index 2d2269e52..57ea0e44c 100644 --- a/WEB-INF/lib/Period.class.php +++ b/WEB-INF/lib/Period.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ define('INTERVAL_THIS_DAY', 1); diff --git a/WEB-INF/lib/form/ActionErrors.class.php b/WEB-INF/lib/form/ActionErrors.class.php index 3eaf68729..ba35ea639 100644 --- a/WEB-INF/lib/form/ActionErrors.class.php +++ b/WEB-INF/lib/form/ActionErrors.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ class ActionErrors { diff --git a/WEB-INF/lib/form/ActionForm.class.php b/WEB-INF/lib/form/ActionForm.class.php index 8e2ad8af4..abc5e006b 100644 --- a/WEB-INF/lib/form/ActionForm.class.php +++ b/WEB-INF/lib/form/ActionForm.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import("DateAndTime"); diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index 072b48281..7de81d876 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.FormElement'); diff --git a/WEB-INF/lib/form/Checkbox.class.php b/WEB-INF/lib/form/Checkbox.class.php index c4acbc5f5..619d39fb3 100644 --- a/WEB-INF/lib/form/Checkbox.class.php +++ b/WEB-INF/lib/form/Checkbox.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.FormElement'); diff --git a/WEB-INF/lib/form/CheckboxCellRenderer.class.php b/WEB-INF/lib/form/CheckboxCellRenderer.class.php index d117c12ef..cd9682703 100644 --- a/WEB-INF/lib/form/CheckboxCellRenderer.class.php +++ b/WEB-INF/lib/form/CheckboxCellRenderer.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.DefaultCellRenderer'); diff --git a/WEB-INF/lib/form/CheckboxGroup.class.php b/WEB-INF/lib/form/CheckboxGroup.class.php index 9488b5cce..68b24853b 100644 --- a/WEB-INF/lib/form/CheckboxGroup.class.php +++ b/WEB-INF/lib/form/CheckboxGroup.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.FormElement'); diff --git a/WEB-INF/lib/form/DefaultCellRenderer.class.php b/WEB-INF/lib/form/DefaultCellRenderer.class.php index 1e36f79b5..55f4bbca5 100644 --- a/WEB-INF/lib/form/DefaultCellRenderer.class.php +++ b/WEB-INF/lib/form/DefaultCellRenderer.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ class DefaultCellRenderer { diff --git a/WEB-INF/lib/form/FloatField.class.php b/WEB-INF/lib/form/FloatField.class.php index 5b939754e..e6cbf1068 100644 --- a/WEB-INF/lib/form/FloatField.class.php +++ b/WEB-INF/lib/form/FloatField.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.TextField'); diff --git a/WEB-INF/lib/form/Hidden.class.php b/WEB-INF/lib/form/Hidden.class.php index 6e59bc8e1..89e90c7eb 100644 --- a/WEB-INF/lib/form/Hidden.class.php +++ b/WEB-INF/lib/form/Hidden.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.FormElement'); diff --git a/WEB-INF/lib/form/Submit.class.php b/WEB-INF/lib/form/Submit.class.php index 5f8da37e5..151600b32 100644 --- a/WEB-INF/lib/form/Submit.class.php +++ b/WEB-INF/lib/form/Submit.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.FormElement'); diff --git a/WEB-INF/lib/form/Table.class.php b/WEB-INF/lib/form/Table.class.php index d617f8b39..acdf4813a 100644 --- a/WEB-INF/lib/form/Table.class.php +++ b/WEB-INF/lib/form/Table.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.FormElement'); diff --git a/WEB-INF/lib/form/TableColumn.class.php b/WEB-INF/lib/form/TableColumn.class.php index cb4bebf1b..87538eaa8 100644 --- a/WEB-INF/lib/form/TableColumn.class.php +++ b/WEB-INF/lib/form/TableColumn.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.DefaultCellRenderer'); diff --git a/WEB-INF/lib/form/TextArea.class.php b/WEB-INF/lib/form/TextArea.class.php index 715a6ea95..4faac1447 100644 --- a/WEB-INF/lib/form/TextArea.class.php +++ b/WEB-INF/lib/form/TextArea.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.FormElement'); diff --git a/WEB-INF/lib/form/TextField.class.php b/WEB-INF/lib/form/TextField.class.php index bb05c6738..bfc0e551f 100644 --- a/WEB-INF/lib/form/TextField.class.php +++ b/WEB-INF/lib/form/TextField.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.FormElement'); diff --git a/WEB-INF/lib/form/UploadFile.class.php b/WEB-INF/lib/form/UploadFile.class.php index 50e8aad56..36d0d92a7 100644 --- a/WEB-INF/lib/form/UploadFile.class.php +++ b/WEB-INF/lib/form/UploadFile.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('form.FormElement'); diff --git a/WEB-INF/lib/html/HttpRequest.class.php b/WEB-INF/lib/html/HttpRequest.class.php index 2eb26f0a7..bc32debcf 100644 --- a/WEB-INF/lib/html/HttpRequest.class.php +++ b/WEB-INF/lib/html/HttpRequest.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ class ttHttpRequest { diff --git a/WEB-INF/lib/mail/Mailer.class.php b/WEB-INF/lib/mail/Mailer.class.php index 30f0ffb64..4c7eb0134 100644 --- a/WEB-INF/lib/mail/Mailer.class.php +++ b/WEB-INF/lib/mail/Mailer.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ class Mailer { diff --git a/WEB-INF/lib/ttBehalfUser.class.php b/WEB-INF/lib/ttBehalfUser.class.php index 408602a10..e85770c1b 100644 --- a/WEB-INF/lib/ttBehalfUser.class.php +++ b/WEB-INF/lib/ttBehalfUser.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('ttConfigHelper'); diff --git a/WEB-INF/lib/ttChartHelper.class.php b/WEB-INF/lib/ttChartHelper.class.php index faf18263b..4e4f9c832 100644 --- a/WEB-INF/lib/ttChartHelper.class.php +++ b/WEB-INF/lib/ttChartHelper.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('Period'); diff --git a/WEB-INF/lib/ttCronJobHelper.class.php b/WEB-INF/lib/ttCronJobHelper.class.php index 8c44756c7..153938951 100644 --- a/WEB-INF/lib/ttCronJobHelper.class.php +++ b/WEB-INF/lib/ttCronJobHelper.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('ttRoleHelper'); diff --git a/WEB-INF/lib/ttDebugTracer.class.php b/WEB-INF/lib/ttDebugTracer.class.php index 46469a908..33921e9dd 100644 --- a/WEB-INF/lib/ttDebugTracer.class.php +++ b/WEB-INF/lib/ttDebugTracer.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('ttConfigHelper'); diff --git a/WEB-INF/lib/ttNotificationHelper.class.php b/WEB-INF/lib/ttNotificationHelper.class.php index 35c309040..8189e5a9b 100644 --- a/WEB-INF/lib/ttNotificationHelper.class.php +++ b/WEB-INF/lib/ttNotificationHelper.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ // Class ttNotificationHelper is used to help with notification related tasks. diff --git a/WEB-INF/lib/ttOrgExportHelper.class.php b/WEB-INF/lib/ttOrgExportHelper.class.php index 2dd54f1b3..277eac3ab 100644 --- a/WEB-INF/lib/ttOrgExportHelper.class.php +++ b/WEB-INF/lib/ttOrgExportHelper.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('ttTeamHelper'); diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index 81169032a..656450f0e 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ // Class ttOrgHelper contains helper functions that operate with organizations. diff --git a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php index c6bc3f356..6d60d533e 100644 --- a/WEB-INF/lib/ttPredefinedExpenseHelper.class.php +++ b/WEB-INF/lib/ttPredefinedExpenseHelper.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 4a827189b..e1d5754c5 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('ttUserHelper'); diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 9bb538912..981f01b50 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('ttUserHelper'); diff --git a/initialize.php b/initialize.php index 48af9888e..d9e800df7 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.0.5650"); +define("APP_VERSION", "1.21.0.5651"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 1a7b94e9e..4e2f13195 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -24,7 +24,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ class CustomFields { diff --git a/plugins/MonthlyQuota.class.php b/plugins/MonthlyQuota.class.php index 76a7c5100..b291d3730 100644 --- a/plugins/MonthlyQuota.class.php +++ b/plugins/MonthlyQuota.class.php @@ -23,7 +23,7 @@ // | // +----------------------------------------------------------------------+ // | Contributors: -// | https://www.anuko.com/time_tracker/credits.htm +// | https://www.anuko.com/time-tracker/credits.htm // +----------------------------------------------------------------------+ import('ttTimeHelper'); diff --git a/readme.txt b/readme.txt index 421a18cdb..90cdc970d 100644 --- a/readme.txt +++ b/readme.txt @@ -1,9 +1,9 @@ Anuko Time Tracker Copyright (c) Anuko (https://www.anuko.com) -Project home page: https://www.anuko.com/time_tracker/index.htm +Project home page: https://www.anuko.com/time-tracker/index.htm Forum: https://www.anuko.com/forum/viewforum.php?f=4 -Info for developers: https://www.anuko.com/time_tracker/info_for_developers.htm +Info for developers: https://www.anuko.com/time-tracker/info-for-developers.htm Free hosting of Time Tracker for individuals and small groups is available at https://timetracker.anuko.com Unless otherwise noted, files in this archive are protected by the LIBERAL FREEWARE LICENSE. @@ -12,7 +12,7 @@ Read the file license.txt for details. INSTALLATION INSTRUCTIONS -Documentation is available at https://www.anuko.com/time_tracker/install_guide/index.htm +Documentation is available at https://www.anuko.com/time-tracker/install-guide/index.htm The general installation procedure looks like this: @@ -40,7 +40,7 @@ The general installation procedure looks like this: UPGRADE FROM EARLIER VERSIONS -See https://www.anuko.com/time_tracker/upgrade.htm +See https://www.anuko.com/time-tracker/install-guide/upgrade.htm BLANK PAGES IN TIME TRACKER @@ -62,4 +62,4 @@ Support is available on per-incident basis - see https://www.anuko.com/support.h CHANGE LOG -Change log is available at https://www.anuko.com/time_tracker/change_log/index.htm \ No newline at end of file +Change log is available at https://www.anuko.com/time-tracker/change-log/index.htm \ No newline at end of file From 84638df3b637f376deb70ed060cb4a4b6d015295 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 13 Mar 2022 14:56:32 +0000 Subject: [PATCH 1674/1848] Starting working on password complexity. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/group_advanced_edit.tpl | 11 +++++++++++ group_advanced_edit.php | 7 ++++++- 32 files changed, 49 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 6b74dced4..a9937cea6 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -584,6 +584,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 836ef4f28..9d5331736 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -596,6 +596,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index bc042b6e5..22aba0ded 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -562,6 +562,7 @@ // TODO: translate the following. // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index dae614fbc..9a845d1f0 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -537,6 +537,7 @@ 'form.group_edit.confirm_save' => 'Speichern bestätigen', 'form.group_edit.allow_ip' => 'Erlaube IP', // TODO: translate the following. +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 652c3e484..ab7769558 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -520,6 +520,7 @@ 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', 'form.group_edit.confirm_save' => 'Confirm saving', 'form.group_edit.allow_ip' => 'Allow IP', +'form.group_edit.password_complexity' => 'Password complexity', 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index f2bb893ba..b7942fbeb 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -598,6 +598,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 67210ee66..e14416bc1 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -571,6 +571,7 @@ 'form.group_edit.confirm_save' => 'Kinnita salvestamine', 'form.group_edit.allow_ip' => 'Luba IP', // TODO: translate the following. +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 31c1506fe..8ccc29f08 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -584,6 +584,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index c0d712667..26c150880 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -568,6 +568,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 61570ee8c..892b0291f 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -558,6 +558,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index c795c5073..f1dbbc3c5 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -549,6 +549,7 @@ // TODO: translate the following. // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 72a48ba5d..4f2a49236 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -588,6 +588,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 8b1e0b348..924b4acc9 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -588,6 +588,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 90167eb26..383b1ab13 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -564,6 +564,7 @@ // TODO: translate the following. // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index d0bad574e..b3fd57f48 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -590,6 +590,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 3e62d9d2d..d182519a3 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -588,6 +588,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 79baaa97d..8c1afa7fb 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -506,6 +506,8 @@ 'form.group_edit.uncompleted_indicators' => 'Onvolledige indicatoren', 'form.group_edit.confirm_save' => 'Bevestigen dat je wilt opslaan', 'form.group_edit.allow_ip' => 'Toegestane IP adressen', +// TODO: translate the following. +// 'form.group_edit.password_complexity' => 'Password complexity', 'form.group_edit.advanced_settings' => 'Geavanceerde instellingen', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 598950581..8b5e13f0f 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -591,6 +591,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index c826441f3..97ac1e0da 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -570,6 +570,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index ba2ed1d73..b01e94d32 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -504,6 +504,8 @@ 'form.group_edit.uncompleted_indicators' => 'Indicadores incompletos', 'form.group_edit.confirm_save' => 'Confirme o salvamento', 'form.group_edit.allow_ip' => 'Permitir IP', +// TODO: translate the following. +// 'form.group_edit.password_complexity' => 'Password complexity', 'form.group_edit.advanced_settings' => 'Configurações avançadas', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index cac4c68e8..7c724cd29 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -570,6 +570,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 1d97b1fed..33c4547dc 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -592,6 +592,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 20d7d7e60..3707ce74a 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -507,6 +507,7 @@ 'form.group_edit.uncompleted_indicators' => 'Индикаторы незавершения', 'form.group_edit.confirm_save' => 'Предупреждать при сохранении', 'form.group_edit.allow_ip' => 'Разрешить доступ с IP', +'form.group_edit.password_complexity' => 'Сложность пароля', 'form.group_edit.advanced_settings' => 'Продвинутые настройки', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 89f26abde..345666d8f 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -574,6 +574,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 56eeb2050..d5b56f4a0 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -565,6 +565,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index c88e9d07c..652eaa893 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -570,6 +570,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 36c0a325c..b39366bc1 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -568,6 +568,7 @@ // TODO: translate the following. // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 2e5bed2bb..2aae8ed9c 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -605,6 +605,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index b1c0667b3..f423fab84 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -579,6 +579,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 5212a3f80..92f5dbf52 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -582,6 +582,7 @@ // 'form.group_edit.uncompleted_indicators' => 'Uncompleted indicators', // 'form.group_edit.confirm_save' => 'Confirm saving', // 'form.group_edit.allow_ip' => 'Allow IP', +// 'form.group_edit.password_complexity' => 'Password complexity', // 'form.group_edit.advanced_settings' => 'Advanced settings', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php diff --git a/WEB-INF/templates/group_advanced_edit.tpl b/WEB-INF/templates/group_advanced_edit.tpl index 1f55adf77..66fa41035 100644 --- a/WEB-INF/templates/group_advanced_edit.tpl +++ b/WEB-INF/templates/group_advanced_edit.tpl @@ -32,6 +32,17 @@ License: See license.txt *} {$i18n.label.what_is_it}
{$forms.groupAdvancedForm.password_complexity.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.label.required_fields}
{$i18n.label.required_fields}
{$forms.groupAdvancedForm.allow_ip.control} {$i18n.label.what_is_it} {$i18n.label.what_is_it}
{$forms.groupAdvancedForm.password_complexity.control} {$i18n.label.what_is_it} {$i18n.label.what_is_it} diff --git a/group_advanced_edit.php b/group_advanced_edit.php index 7683d879c..a4cf540e3 100644 --- a/group_advanced_edit.php +++ b/group_advanced_edit.php @@ -46,8 +46,8 @@ if (!ttValidString($cl_group)) $err->add($i18n->get('error.field'), $i18n->get('label.group_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.bcc')); - if (!ttValidIP($cl_allow_ip, true)) $err->add($i18n->get('error.field'), $i18n->get('form.group_edit.allow_ip')); - if (!ttValidPasswordComplexity($cl_password_complexity, true)) $err->add($i18n->get('error.field'), $i18n->get('form.group_edit.password_complexity')); + if (!ttValidIP($cl_allow_ip, true)) $err->add($i18n->get('error.field'), $i18n->get('form.group_advanced_edit.allow_ip')); + if (!ttValidPasswordComplexity($cl_password_complexity, true)) $err->add($i18n->get('error.field'), $i18n->get('form.group_advanced_edit.password_complexity')); // Finished validating user input. if ($err->no()) { diff --git a/initialize.php b/initialize.php index 3389203ce..74d3da0ad 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5659"); +define("APP_VERSION", "1.21.1.5660"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 81b2e03236fd74fe773105841b0f26fdcaa5ab59 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Mar 2022 17:45:26 +0000 Subject: [PATCH 1684/1848] Implmeneted handling of 2fa setting on advanced group settings page. --- WEB-INF/templates/group_advanced_edit.tpl | 11 +++++++++++ group_advanced_edit.php | 11 ++++++++++- initialize.php | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/group_advanced_edit.tpl b/WEB-INF/templates/group_advanced_edit.tpl index 4bcaedf49..d4bd55a1e 100644 --- a/WEB-INF/templates/group_advanced_edit.tpl +++ b/WEB-INF/templates/group_advanced_edit.tpl @@ -41,6 +41,17 @@ License: See license.txt *} {$i18n.label.what_is_it}
{$forms.groupAdvancedForm.2fa.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.label.required_fields}
+ + + + + + + + + +
{$forms.2faForm.2fa_code.control}
{$forms.2faForm.btn_login.control}
+{$forms.2faForm.close} + From 3c7cba88f69edd54f694f34f0907990977673b79 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 16 Mar 2022 15:40:39 +0000 Subject: [PATCH 1687/1848] Added title.2fa string to translation files. --- 2fa.php | 7 ++----- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 3 ++- WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 3 ++- WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 4 +++- WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ initialize.php | 2 +- 32 files changed, 62 insertions(+), 9 deletions(-) diff --git a/2fa.php b/2fa.php index 7c1728d28..15d1a2628 100644 --- a/2fa.php +++ b/2fa.php @@ -28,12 +28,9 @@ if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_2fa_code)) $err->add($i18n->get('error.field'), $i18n->get('fprm.2fa.2fa_code')); + if (!ttValidString($cl_2fa_code)) $err->add($i18n->get('error.field'), $i18n->get('form.2fa.2fa_code')); if ($err->no()) { - // Use the "limit" plugin if we have one. Ignore include errors. - // The "limit" plugin is not required for normal operation of Time Tracker. - @include('plugins/limit/access_check.php'); if ($auth->doLogin($cl_login, $cl_password)) { // Set current user date (as determined by user browser) into session. @@ -82,6 +79,6 @@ $smarty->assign('show_hint', $show_hint); $smarty->assign('onload', 'onLoad="document.loginForm.'.(!$cl_login?'login':'password').'.focus()"'); $smarty->assign('about_text', $i18n->get('form.login.about')); -$smarty->assign('title', $i18n->get('title.login')); +$smarty->assign('title', $i18n->get('title.2fa')); $smarty->assign('content_page_name', '2fa.tpl'); $smarty->display('index.tpl'); diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 3bd936dd1..8be97f9b4 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -277,6 +277,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Sessió iniciada', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Grups', // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index a4f116022..a9cc11823 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -286,6 +286,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Přihlásit', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Týmy', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index d1b991f41..74a239ca9 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -266,6 +266,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'Login', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Teams', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 75c2c0a72..e55d05641 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -257,6 +257,8 @@ 'title.error' => 'Fehler', 'title.success' => 'Erfol', 'title.login' => 'Anmelden', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Gruppen', 'title.add_group' => 'Gruppe anlegen', 'title.edit_group' => 'Gruppe bearbeiten', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 7adaceadc..f48c96eb7 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -241,6 +241,7 @@ 'title.error' => 'Error', 'title.success' => 'Success', 'title.login' => 'Login', +'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Groups', 'title.add_group' => 'Adding Group', 'title.edit_group' => 'Editing Group', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index a78f1e6f2..b7fbecd17 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -276,6 +276,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Sesión iniciada', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Grupos', // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 854a52e00..a81b9021d 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -277,6 +277,8 @@ 'title.error' => 'Viga', 'title.success' => 'Õnnestumine', 'title.login' => 'Sisene', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Grupid', 'title.add_group' => 'Lisa grupp', 'title.edit_group' => 'Muuda gruppi', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index bda4a4758..af722d6e7 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -277,6 +277,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'ورود', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'تیم ها', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 1d90ef233..86ee80d86 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -270,6 +270,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'Kirjautuminen', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Tiimit', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index ccb429359..9debf4673 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -264,6 +264,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'Connexion', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Équipes', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 4cf1f64f9..587e719a0 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -259,6 +259,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'Σύνδεση', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Ομάδες', // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 4342ea846..bde356c99 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -285,6 +285,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'כניסה', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'צוותים', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index b105d2483..a8fc41ef3 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -278,6 +278,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Bejelentkezés', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Csoportok', // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 16727cfe7..af53176eb 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -267,6 +267,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'Login', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Gruppi', // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 46c705532..f4cfc5651 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -282,6 +282,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'ログイン', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'チーム', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index a82356937..1c677aa96 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -282,6 +282,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => '로그인', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => '팀', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 9a7c1707d..dd89e3562 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -235,6 +235,8 @@ 'title.error' => 'Fout', 'title.success' => 'Succes', 'title.login' => 'Aanmelden', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Groepen', 'title.add_group' => 'Groep toevoegen', 'title.edit_group' => 'Groep bewerken', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index b7500bbaa..55cd54d45 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -281,7 +281,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Innlogging', -// TODO: translate the following. +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', // 'title.groups' => 'Groups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 0e482eebe..021e30cd6 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -271,6 +271,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'Logowanie', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Zespoły', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index f0b564de9..b2b71608f 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -238,6 +238,8 @@ 'title.error' => 'Erro', 'title.success' => 'Sucesso', 'title.login' => 'Login', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Grupos', 'title.add_group' => 'Adicionando grupo', 'title.edit_group' => 'Editando grupo', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index dcb0d0357..ebbc50b37 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -267,7 +267,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Login', -// TODO: translate the following. +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', // 'title.groups' => 'Groups', // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 7a5b41a3d..670d00dcd 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -283,6 +283,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Autentificare', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Echipe', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index da8d8b0f9..9ef4dc027 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -236,6 +236,7 @@ 'title.error' => 'Ошибка', 'title.success' => 'Успех', 'title.login' => 'Вход в систему', +'title.2fa' => 'Двухфакторная аутентификация', 'title.groups' => 'Группы', 'title.add_group' => 'Добавление группы', 'title.edit_group' => 'Редактирование группы', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 3bdc0e4bd..e75e0f2e4 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -274,6 +274,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'Prihlásenie', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Tímy', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index d7406f37a..150269293 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -263,6 +263,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Prijava', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Timi', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index b26d4f04a..44ad24e31 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -269,6 +269,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'Prijava', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Timovi', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 1c139a0e4..2098b705f 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -265,6 +265,8 @@ // TODO: Translate the following. // 'title.success' => 'Success', 'title.login' => 'Logga in', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => 'Grupper', // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 9f57fa3e0..4df3f5bdc 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -292,7 +292,9 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => 'Giriş', -'title.groups' => 'Ekipler', // TODO: change "teams" to "groups". +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', + 'title.groups' => 'Ekipler', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', // 'title.edit_group' => 'Editing Group', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 400529f60..7fc1e3a15 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -274,6 +274,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => '登录', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => '团队', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 3ece1f0fc..0d3885b21 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -279,6 +279,8 @@ // 'title.error' => 'Error', // 'title.success' => 'Success', 'title.login' => '登錄', +// TODO: translate the follolwing. +// 'title.2fa' => 'Two Factor Authentication', 'title.groups' => '團隊', // TODO: change "teams" to "groups". // TODO: translate the following. // 'title.add_group' => 'Adding Group', diff --git a/initialize.php b/initialize.php index 2f537eb6b..3fb0921fa 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5662"); +define("APP_VERSION", "1.21.1.5663"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 3ce1ed036de850af767d163d322dad93907a9df6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 16 Mar 2022 19:03:50 +0000 Subject: [PATCH 1688/1848] Smoe more work in progress on 2fa. --- WEB-INF/resources/ca.lang.php | 5 ++ WEB-INF/resources/cs.lang.php | 5 ++ WEB-INF/resources/da.lang.php | 5 ++ WEB-INF/resources/de.lang.php | 5 ++ WEB-INF/resources/en.lang.php | 5 +- WEB-INF/resources/es.lang.php | 5 ++ WEB-INF/resources/et.lang.php | 5 ++ WEB-INF/resources/fa.lang.php | 5 ++ WEB-INF/resources/fi.lang.php | 5 ++ WEB-INF/resources/fr.lang.php | 5 ++ WEB-INF/resources/gr.lang.php | 5 ++ WEB-INF/resources/he.lang.php | 5 ++ WEB-INF/resources/hu.lang.php | 5 ++ WEB-INF/resources/it.lang.php | 5 ++ WEB-INF/resources/ja.lang.php | 5 ++ WEB-INF/resources/ko.lang.php | 5 ++ WEB-INF/resources/nl.lang.php | 5 ++ WEB-INF/resources/no.lang.php | 5 ++ WEB-INF/resources/pl.lang.php | 5 ++ WEB-INF/resources/pt-br.lang.php | 5 ++ WEB-INF/resources/pt.lang.php | 5 ++ WEB-INF/resources/ro.lang.php | 5 ++ WEB-INF/resources/ru.lang.php | 4 + WEB-INF/resources/sk.lang.php | 5 ++ WEB-INF/resources/sl.lang.php | 5 ++ WEB-INF/resources/sr.lang.php | 5 ++ WEB-INF/resources/sv.lang.php | 5 ++ WEB-INF/resources/tr.lang.php | 5 ++ WEB-INF/resources/zh-cn.lang.php | 5 ++ WEB-INF/resources/zh-tw.lang.php | 5 ++ initialize.php | 2 +- login.php | 121 ++++++++++++++++++++++--------- 32 files changed, 236 insertions(+), 36 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 8be97f9b4..cdf0c7eda 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -422,6 +422,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index a9cc11823..2c64a8598 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -429,6 +429,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 74a239ca9..53644ed99 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -406,6 +406,11 @@ 'form.login.forgot_password' => 'Har du glemt din adgangskode?', 'form.login.about' => 'Anuko Time Tracker er et open source tidsregistrerings system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index e55d05641..006d7b89b 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -393,6 +393,11 @@ 'form.login.forgot_password' => 'Passwort vergessen?', 'form.login.about' => 'Anuko Time Tracker ist ein Open-Source Zeiterfassungssystem.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index f48c96eb7..3d5e59a86 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -372,9 +372,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Forgot password?', -'form.login.2fa_code' => '2FA code', 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index b7fbecd17..9ce3cb252 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -426,6 +426,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index a81b9021d..884d0e327 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -414,6 +414,11 @@ 'form.login.forgot_password' => 'Unustasid salasõna?', 'form.login.about' => 'Anuko Time Tracker on avatud lähtekoodiga ajaarvestussüsteem.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index af722d6e7..2eb5e5328 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -424,6 +424,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 86ee80d86..5b85ba637 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -412,6 +412,11 @@ // TODO: check translation of form.login.about - is open source "vapaan koodin"? 'form.login.about' => 'Anuko Time Tracker on vapaan koodin tuntiseurantaohjelmisto.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 9debf4673..19c3fbaa4 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -403,6 +403,11 @@ 'form.login.forgot_password' => 'Mot de passe oublié?', 'form.login.about' => 'Anuko Time Tracker est un système de gestion du temps, open source.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 587e719a0..9c07dd523 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -402,6 +402,11 @@ 'form.login.forgot_password' => 'Ξεχάσατε τον κωδικό πρόσβασης;', 'form.login.about' => 'Anuko Time Tracker είναι ένα ανοικτού κώδικα σύστημα παρακολούθησης χρόνου.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index bde356c99..3cb53daf0 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -430,6 +430,11 @@ // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker הינה מערכת פשוטה, קלה לשימוש וחינמית לניהול זמן.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index a8fc41ef3..61438d08a 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -423,6 +423,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index af53176eb..373587f5c 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -412,6 +412,11 @@ 'form.login.forgot_password' => 'Password dimenticata?', 'form.login.about' => 'Anuko Time Tracker è un sistema open source per registrare i tempi di lavoro.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index f4cfc5651..b86ed26e1 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -424,6 +424,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 1c677aa96..1a8106383 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -428,6 +428,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index dd89e3562..b2a7fd842 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -367,6 +367,11 @@ 'form.login.forgot_password' => 'Wachtwoord vergeten?', 'form.login.about' => 'Anuko Time Tracker is een open source tijdregistratiesysteem.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 55cd54d45..6cabab827 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -426,6 +426,11 @@ // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker er et enkelt, brukervennlig tidsregistreringssystem basert på åpen kildekode.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 021e30cd6..0aac60b48 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -414,6 +414,11 @@ 'form.login.forgot_password' => 'Nie pamiętasz hasła?', 'form.login.about' => 'Anuko Time Tracker jest otwartoźródłowym systemem śledzenia czasu.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index b2b71608f..d311c7a80 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -366,6 +366,11 @@ 'form.login.forgot_password' => 'Esqueceu a senha?', 'form.login.about' => 'Anuko Time Tracker é um sistema de código aberto de rastreamento do tempo.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index ebbc50b37..942ce2091 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -406,6 +406,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 670d00dcd..39e507f78 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -428,6 +428,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 9ef4dc027..98b6694ad 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -367,6 +367,10 @@ 'form.login.forgot_password' => 'Забыли пароль?', 'form.login.about' => 'Anuko Time Tracker - это открытая (open source) система трекинга рабочего времени.', +// Email subject and body for two-factor authentication. +'email.2fa_code.subject' => 'Anuko Time Tracker код для двухфакторной аутентификации', +'email.2fa_code.body' => "Уважаемый пользователь,\n\nВаш код для двухфакторной аутентификации:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. 'form.2fa.2fa_code' => '2FA код', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index e75e0f2e4..08bda8581 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -417,6 +417,11 @@ 'form.login.forgot_password' => 'Zabudnuté heslo?', 'form.login.about' => 'Anuko Time Tracker je systém na sledovanie času s otvoreným zdrojovým kódom.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 150269293..804b7fc8e 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -400,6 +400,11 @@ // 'form.login.forgot_password' => 'Forgot password?', // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 44ad24e31..6f3495502 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -414,6 +414,11 @@ // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker je jednostavan i lak za korišćenje za praćenje radnog vremena.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 2098b705f..4cb93fa00 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -412,6 +412,11 @@ // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker är en lättanvänd applikation byggd med öppen källkod som enkelt låter dig spåra och hålla koll på arbetstider.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 4df3f5bdc..12bdebf38 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -436,6 +436,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7fc1e3a15..c37b56616 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -419,6 +419,11 @@ // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker 是一种简单、易用、开放源代码的实时跟踪系统。', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 0d3885b21..fd78f3e35 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -422,6 +422,11 @@ // TODO: translate the following. // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', +// Email subject and body for two-factor authentication. +// TODO: translate the following. +// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', +// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", + // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. // 'form.2fa.2fa_code' => '2FA code', diff --git a/initialize.php b/initialize.php index 3fb0921fa..c8b41c6d4 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5663"); +define("APP_VERSION", "1.21.1.5664"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/login.php b/login.php index 5ea77d185..da59757bb 100644 --- a/login.php +++ b/login.php @@ -4,8 +4,9 @@ require_once('initialize.php'); import('form.Form'); -import('ttOrgHelper'); +//import('ttOrgHelper'); import('ttUser'); +import('ttUserHelper'); // Access checks. if ($request->isPost()) { @@ -33,46 +34,98 @@ if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); if (!ttValidString($cl_password)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); + $loginSucceeded = $use2FA = false; if ($err->no()) { // Use the "limit" plugin if we have one. Ignore include errors. // The "limit" plugin is not required for normal operation of Time Tracker. @include('plugins/limit/access_check.php'); - if ($auth->doLogin($cl_login, $cl_password)) { - // Set current user date (as determined by user browser) into session. - $current_user_date = $request->getParameter('browser_today', null); - if ($current_user_date) - $_SESSION['date'] = $current_user_date; - - // Remember user login in a cookie. - setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); - - $user = new ttUser(null, $auth->getUserId()); - - // Determine if we have to additionally use two-factor authentication. - $config = $user->getConfigHelper(); - $use2FA = $config->getDefinedValue('2fa'); - if ($use2FA) { - - // TODO: send 2fa code to user. - $auth->doLogout(); - - header('Location: 2fa.php'); - exit(); - } - - // Redirect, depending on user role. - if ($user->can('administer_site')) { - header('Location: admin_groups.php'); - } elseif ($user->isClient()) { - header('Location: reports.php'); - } else { - header('Location: time.php'); - } - exit(); + // Check user login. + $loginSucceeded = $auth->doLogin($cl_login, $cl_password); + } + + // Do we have to use 2FA? + if ($err->no() && $loginSucceeded) { + $user = new ttUser(null, $auth->getUserId()); + + // Determine if we have to additionally use two-factor authentication. + $config = $user->getConfigHelper(); + $use2FA = $config->getDefinedValue('2fa'); + } + + // If we have to use 2FA, create and email auith code to user. + if ($use2FA) { + // To keep things simple, we use the same code as for password resets. + $cryptographically_strong = true; + $random_bytes = openssl_random_pseudo_bytes(16, $cryptographically_strong); + if ($random_bytes === false) die ("openssl_random_pseudo_bytes function call failed..."); + $temp_ref = bin2hex($random_bytes); + ttUserHelper::saveTmpRef($temp_ref, $user->id); + + // For user languague in email. + $user_i18n = null; + if ($user->lang != $i18n->lang) { + $user_i18n = new I18n(); + $user_i18n->load($user->lang); } else - $err->add($i18n->get('error.auth')); + $user_i18n = &$i18n; + + // Where do we email to? + $receiver = null; + if ($user->email) + $receiver = $user->email; + else { + if (ttValidEmail($user->login)) + $receiver = $user->login; + } + if (!$receiver) $err->add($user_i18n->get('error.no_email')); + + // Send 2FA_code email to user. + if ($receiver) { + import('mail.Mailer'); + $mailer = new Mailer(); + $mailer->setCharSet(CHARSET); + $mailer->setSender(SENDER); + $mailer->setReceiver("$receiver"); + + $subject = $user_i18n->get('email.2fa_code.subject'); + $body = sprintf($user_i18n->get('email.2fa_code.body'), $temp_ref); + + $mailer->setMailMode(MAIL_MODE); + if (!$mailer->send($subject, $body)) + $err->add($i18n->get('error.mail_send')); + } + + $auth->doLogout(); + + // Redirect to 2fa.php if we have no errors. + if ($err->no()) { + header('Location: 2fa.php'); + exit(); + } } + + if ($err->no() && $loginSucceeded) { + + // Set current user date (as determined by user browser) into session. + $current_user_date = $request->getParameter('browser_today', null); + if ($current_user_date) + $_SESSION['date'] = $current_user_date; + + // Remember user login in a cookie. + setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); + + // Redirect, depending on user role. + if ($user->can('administer_site')) { + header('Location: admin_groups.php'); + } elseif ($user->isClient()) { + header('Location: reports.php'); + } else { + header('Location: time.php'); + } + exit(); + } else + $err->add($i18n->get('error.auth')); } // isPost if(!isTrue('MULTIORG_MODE') && !ttOrgHelper::getOrgs()) From 3d74117cda7abf4b2ae2634eb1a623d0a04794e0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 16 Mar 2022 22:19:44 +0000 Subject: [PATCH 1689/1848] A bit more progress on 2fa. --- 2fa.php | 74 ++++++++------------------------ WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/2fa.tpl | 11 +---- login.php | 9 ++-- 33 files changed, 56 insertions(+), 69 deletions(-) diff --git a/2fa.php b/2fa.php index 15d1a2628..005b4ea42 100644 --- a/2fa.php +++ b/2fa.php @@ -4,81 +4,43 @@ require_once('initialize.php'); import('form.Form'); -import('ttOrgHelper'); import('ttUser'); +import('ttUserHelper'); // Access checks. -if ($request->isPost()) { - // Validate that browser_today parameter is in correct format. - $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { - header('Location: access_denied.php'); - exit(); - } -} +// ... anything to check? // End of access checks. $cl_2fa_code = $request->getParameter('2fa_code'); -$cl_password = $request->getParameter('password'); $form = new Form('2faForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'2fa_code','value'=>$cl_2fa_code)); -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_login click. -$form->addInput(array('type'=>'submit','name'=>'btn_login','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.login'))); +$form->addInput(array('type'=>'submit','name'=>'btn_login','value'=>$i18n->get('button.login'))); if ($request->isPost()) { // Validate user input. if (!ttValidString($cl_2fa_code)) $err->add($i18n->get('error.field'), $i18n->get('form.2fa.2fa_code')); - if ($err->no()) { - - if ($auth->doLogin($cl_login, $cl_password)) { - // Set current user date (as determined by user browser) into session. - $current_user_date = $request->getParameter('browser_today', null); - if ($current_user_date) - $_SESSION['date'] = $current_user_date; - - // Remember user login in a cookie. - setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); - - $user = new ttUser(null, $auth->getUserId()); + // Get user id. + $user_id = ttUserHelper::getUserIdByTmpRef($cl_2fa_code); + if (!$user_id) $err->add($i18n->get('error.2fa_code')); - // Determine if we have to additionally use two-factor authentication. - $config = $user->getConfigHelper(); - $use2FA = $config->getDefinedValue('2fa'); - if ($use2FA) { - - // TODO: send 2fa code to user. - $auth->doLogout(); - - header('Location: 2fa.php'); - exit(); - } - - // Redirect, depending on user role. - if ($user->can('administer_site')) { - header('Location: admin_groups.php'); - } elseif ($user->isClient()) { - header('Location: reports.php'); - } else { - header('Location: time.php'); - } - exit(); - } else - $err->add($i18n->get('error.auth')); + if ($err->no()) { + $user = new ttUser(null, $user_id); // Note: reusing $user from initialize.php. + $auth->setAuth($user_id, $user->login); + + // Redirect, depending on user role. + if ($user->isClient()) { + header('Location: reports.php'); + } else { + header('Location: time.php'); + } + exit(); } } // isPost -if(!isTrue('MULTIORG_MODE') && !ttOrgHelper::getOrgs()) - $err->add($i18n->get('error.no_groups')); - -// Determine whether to show login hint. It is currently used only for Windows LDAP authentication. -$show_hint = ('ad' == isset($GLOBALS['AUTH_MODULE_PARAMS']['type']) ? $GLOBALS['AUTH_MODULE_PARAMS']['type'] : null); - $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_hint', $show_hint); -$smarty->assign('onload', 'onLoad="document.loginForm.'.(!$cl_login?'login':'password').'.focus()"'); -$smarty->assign('about_text', $i18n->get('form.login.about')); +$smarty->assign('onload', 'onLoad="document.2faForm.2fa_code.focus()"'); $smarty->assign('title', $i18n->get('title.2fa')); $smarty->assign('content_page_name', '2fa.tpl'); $smarty->display('index.tpl'); diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index cdf0c7eda..ef2d2ea6c 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -74,6 +74,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Usuari o parula de pas incorrecta.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 2c64a8598..0f44c1cc5 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -76,6 +76,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Nesprávné jméno nebo heslo.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 53644ed99..a159edfa2 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -67,6 +67,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Forkert brugernavn eller adgangskode.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Brugernavn eksistere allerede.', // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 006d7b89b..5e2c19d5b 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -65,6 +65,7 @@ 'error.record' => 'Eintrag auswählen.', 'error.auth' => 'Benutzername oder Passwort ungültig.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Benutzer mit diesem Konto ist bereits vorhanden.', 'error.object_exists' => 'Objekt mit diesem Namen ist bereits vorhanden.', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 3d5e59a86..89cfcd264 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -60,6 +60,7 @@ 'error.report' => 'Select report.', 'error.record' => 'Select record.', 'error.auth' => 'Incorrect login or password.', +'error.2fa_code' => 'Invalid 2FA code.', 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'User with this login already exists.', 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 9ce3cb252..96988bdcd 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -72,6 +72,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Usuario o contraseña incorrecta.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 884d0e327..035fb644d 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -66,6 +66,7 @@ 'error.record' => 'Vali kirje.', 'error.auth' => 'Autentimine ebaõnnestus.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Selle nimega kasutaja on juba kasutusel.', 'error.object_exists' => 'Sellise nimega objekt on juba olemas.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 2eb5e5328..e040921c0 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -72,6 +72,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'نام کاربری یا رمز عبور اشتباه است.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'کاربری با این نام کاربری موجود است.', // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 5b85ba637..3dfa94431 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -69,6 +69,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Virheellinen käyttäjänimi tai salasana.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Tämä käyttäjänimi on jo olemassa.', // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 19c3fbaa4..a7ef4f23e 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -67,6 +67,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Nom d\\\'utilisateur ou mot de passe incorrect.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Un utilisateur avec cet identifiant existe déjà.', // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 9c07dd523..72037b0ec 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -64,6 +64,7 @@ 'error.record' => 'Επιλογή εγγραφής.', 'error.auth' => 'Λανθασμένο όνομα εισόδου ή κωδικός.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Ο χρήστης με αυτήν τη σύνδεση υπάρχει ήδη.', 'error.object_exists' => 'Το αντικείμενο με αυτό το όνομα υπάρχει ήδη.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 3cb53daf0..1e03b4f75 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -82,6 +82,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'שם משתמש או סיסמה שגויים', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'שם משתמש כבר קיים', // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 61438d08a..1b4cf6d24 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -74,6 +74,7 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', // 'error.auth' => 'Incorrect login or password.', +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 373587f5c..8c12f14c7 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -66,6 +66,7 @@ 'error.record' => 'Seleziona record.', 'error.auth' => 'Login o password errati.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Esiste già un utente con questo username.', // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index b86ed26e1..30156d526 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -74,6 +74,7 @@ // 'error.record' => 'Select record.', 'error.auth' => '不正確なログインあるいはパスワードが不正確です。', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'このログインと関連されたユーザーは既に存在します。', // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 1a8106383..49e904b04 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -74,6 +74,7 @@ // 'error.record' => 'Select record.', 'error.auth' => '부정확한 로그인 혹은 암호가 틀립니다.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => '본 로그인과 연계된 사용자가 이미 있습니다.', // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index b2a7fd842..85899c8ac 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -59,6 +59,8 @@ 'error.report' => 'Kies rapport.', 'error.record' => 'Kies record.', 'error.auth' => 'Onjuiste inlognaam of wachtwoord.', +// TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', 'error.weak_password' => 'Zwak wachtwoord.', 'error.user_exists' => 'Een gebruiker met deze inlognaam bestaat al.', 'error.object_exists' => 'Een object met deze naam bestaat al.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 6cabab827..75910ddcf 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -75,6 +75,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Feil brukernavn eller passord.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Bruker med et slikt brukernavn eksisterer allerede.', // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 0aac60b48..4a4f9e72a 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -70,6 +70,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Błędny login lub hasło.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Użytkownik o takiej nazwie już istnieje.', // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index d311c7a80..ef122e23e 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -60,6 +60,7 @@ 'error.record' => 'Selecione o registro.', 'error.auth' => 'Usuário ou senha incorretos.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Já existe usuário com este login.', 'error.object_exists' => 'Já existe um objeto com este nome.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 942ce2091..d6ded6515 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -72,6 +72,7 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', // 'error.auth' => 'Incorrect login or password.', +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 39e507f78..39e2f379b 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -78,6 +78,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Nume de utilizator sau parola incorecta.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 98b6694ad..e4474b2f2 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -59,6 +59,7 @@ 'error.report' => 'Выберите отчёт.', 'error.record' => 'Выберите запись.', 'error.auth' => 'Неправильно введен логин или пароль.', +'error.2fa_code' => 'Неверный код 2FA.', 'error.weak_password' => 'Слабый пароль.', 'error.user_exists' => 'Пользователь с таким логином уже существует.', 'error.object_exists' => 'Объект с таким именем уже есть.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 08bda8581..76337a615 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -71,6 +71,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Nesprávne prihlasovacie meno alebo heslo.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Používateľ s týmto prihlasovacím menom už existuje.', // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 804b7fc8e..9730c474c 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -69,6 +69,7 @@ // 'error.report' => 'Select report.', // 'error.record' => 'Select record.', // 'error.auth' => 'Incorrect login or password.', +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 6f3495502..3c490d20d 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -67,6 +67,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Pogrešno korisničko ime ili lozinka.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Korisnik pod ovim imenom već postoji.', // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 4cb93fa00..30ed6da05 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -66,6 +66,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Ogiltigt användarnamn eller lösenord.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => 'Det finns redan en användare med det här användarnamnet.', // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 12bdebf38..5251ee8f6 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -81,6 +81,7 @@ // 'error.record' => 'Select record.', 'error.auth' => 'Hatalı kullanıcı adı veya parola.', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', // 'error.user_exists' => 'User with this login already exists.', // 'error.object_exists' => 'Object with this name already exists.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index c37b56616..fa7f78a37 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -69,6 +69,7 @@ // 'error.record' => 'Select record.', 'error.auth' => '不正确的用户名或密码。', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => '该用户登录信息已经存在。', // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index fd78f3e35..71587399f 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -72,6 +72,7 @@ // 'error.record' => 'Select record.', 'error.auth' => '不正確的用戶名或密碼。', // TODO: translate the following. +// 'error.2fa_code' => 'Invalid 2FA code.', // 'error.weak_password' => 'Weak password.', 'error.user_exists' => '該使用者登錄資訊已經存在。', // TODO: translate the following. diff --git a/WEB-INF/templates/2fa.tpl b/WEB-INF/templates/2fa.tpl index e634b624b..1754f0357 100644 --- a/WEB-INF/templates/2fa.tpl +++ b/WEB-INF/templates/2fa.tpl @@ -1,18 +1,11 @@ {* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt *} - - {$forms.2faForm.open} - + - + diff --git a/login.php b/login.php index da59757bb..dbf5d0c39 100644 --- a/login.php +++ b/login.php @@ -35,6 +35,7 @@ if (!ttValidString($cl_password)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); $loginSucceeded = $use2FA = false; + if ($err->no()) { // Use the "limit" plugin if we have one. Ignore include errors. // The "limit" plugin is not required for normal operation of Time Tracker. @@ -42,6 +43,8 @@ // Check user login. $loginSucceeded = $auth->doLogin($cl_login, $cl_password); + if (!$loginSucceeded) + $err->add($i18n->get('error.auth')); } // Do we have to use 2FA? @@ -53,7 +56,7 @@ $use2FA = $config->getDefinedValue('2fa'); } - // If we have to use 2FA, create and email auith code to user. + // If we have to use 2FA, create and email auth code to user. if ($use2FA) { // To keep things simple, we use the same code as for password resets. $cryptographically_strong = true; @@ -106,7 +109,6 @@ } if ($err->no() && $loginSucceeded) { - // Set current user date (as determined by user browser) into session. $current_user_date = $request->getParameter('browser_today', null); if ($current_user_date) @@ -124,8 +126,7 @@ header('Location: time.php'); } exit(); - } else - $err->add($i18n->get('error.auth')); + } } // isPost if(!isTrue('MULTIORG_MODE') && !ttOrgHelper::getOrgs()) From 274906af2c15cda962c21c8d8d7addc42482b7fd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 17 Mar 2022 00:32:38 +0000 Subject: [PATCH 1690/1848] Added a hint for 2fa.php page to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/2fa.tpl | 1 + initialize.php | 2 +- 32 files changed, 32 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index ef2d2ea6c..5db492323 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -430,6 +430,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 0f44c1cc5..c689bafbc 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -437,6 +437,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index a159edfa2..e2a0da44e 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -414,6 +414,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 5e2c19d5b..10c6cba46 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -401,6 +401,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 89cfcd264..fb31f0f85 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -380,6 +380,7 @@ 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 96988bdcd..bbb923fd3 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -434,6 +434,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 035fb644d..e698f9391 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -422,6 +422,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index e040921c0..7a2e8fbca 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -432,6 +432,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 3dfa94431..4b6a1832d 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -420,6 +420,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a7ef4f23e..b6d170271 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -411,6 +411,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 72037b0ec..a7eec7329 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -410,6 +410,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 1e03b4f75..e4ebe5198 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -438,6 +438,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 1b4cf6d24..7c761eec5 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -431,6 +431,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 8c12f14c7..a873bb477 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -420,6 +420,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 30156d526..9d5807078 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -432,6 +432,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 49e904b04..59222f086 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -436,6 +436,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 85899c8ac..6503da028 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -376,6 +376,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 75910ddcf..255495601 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -434,6 +434,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 4a4f9e72a..3a91e417d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -422,6 +422,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index ef122e23e..af1c6e943 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -374,6 +374,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d6ded6515..8b915d4db 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -414,6 +414,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 39e2f379b..5f267efa1 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -436,6 +436,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index e4474b2f2..c64c8e9c4 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -373,6 +373,7 @@ 'email.2fa_code.body' => "Уважаемый пользователь,\n\nВаш код для двухфакторной аутентификации:\n\n%s\n\n", // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. +'form.2fa.hint' => 'Проверьте электронную почту и введите высланный вам 2FA код здесь.', 'form.2fa.2fa_code' => '2FA код', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 76337a615..98d429610 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -425,6 +425,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 9730c474c..0f757c7d2 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -408,6 +408,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 3c490d20d..60c504ca0 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -422,6 +422,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Izmena forme za lozinku. Pogledajte primer na https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 30ed6da05..06e7f46af 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -420,6 +420,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 5251ee8f6..9d8ef4111 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -444,6 +444,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index fa7f78a37..1a91e596f 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -427,6 +427,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 71587399f..0a2f8510c 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -430,6 +430,7 @@ // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. // TODO: translate the following. +// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', // 'form.2fa.2fa_code' => '2FA code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/templates/2fa.tpl b/WEB-INF/templates/2fa.tpl index 1754f0357..bd7e2f01b 100644 --- a/WEB-INF/templates/2fa.tpl +++ b/WEB-INF/templates/2fa.tpl @@ -1,6 +1,7 @@ {* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt *} +
{$i18n.form.2fa.hint}
{$forms.2faForm.open}
{$forms.2faForm.2fa_code.control}
diff --git a/initialize.php b/initialize.php index c8b41c6d4..31f4096b6 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5664"); +define("APP_VERSION", "1.21.1.5665"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 09c609f8f08d9d1f9a5d5daf9d53462c495a4d08 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 17 Mar 2022 13:39:56 +0000 Subject: [PATCH 1691/1848] Introduced override_2fa access right for top managers. --- dbinstall.php | 12 ++++++++---- initialize.php | 2 +- mysql.sql | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/dbinstall.php b/dbinstall.php index 182910ada..f8e1b9362 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1151,7 +1151,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to12100"]) { + if ($_POST["convert11900to12102"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1193,6 +1193,10 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.20.0', modified = now() where param_name = 'version_db' and param_value = '1.19.29'"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.20.0') set rights = replace(rights, 'manage_basic_settings,view_all_reports', 'manage_basic_settings,view_all_charts,view_all_reports') where `rank` >= 68"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.21.0', modified = now() where param_name = 'version_db' and param_value = '1.20.0'"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.21.0') set rights = replace(rights, 'view_client_unapproved,delete_group', 'view_client_unapproved,override_2fa,delete_group') where `rank` = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.21.0') set rights = replace(rights, ',manage_work', '')"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.21.0') set rights = replace(rights, ',update_work', '')"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.21.2', modified = now() where param_name = 'version_db' and param_value = '1.21.0'"); } if ($_POST["cleanup"]) { @@ -1243,7 +1247,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.21.0) + Create database structure (v1.21.2)
(applies only to new installations, do not execute when updating)
@@ -1292,8 +1296,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.21)Update database structure (v1.19 to v1.21.2)
diff --git a/initialize.php b/initialize.php index 31f4096b6..8ed35c5cc 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.1.5665"); +define("APP_VERSION", "1.21.2.5666"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mysql.sql b/mysql.sql index 05743ee54..0856f94a0 100644 --- a/mysql.sql +++ b/mysql.sql @@ -78,7 +78,7 @@ create unique index role_idx on tt_roles(group_id, `rank`, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); -INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_charts,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_own_timesheets,manage_subgroups,view_client_unapproved,delete_group'); +INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_charts,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_own_timesheets,manage_subgroups,view_client_unapproved,override_2fa,delete_group'); # @@ -621,4 +621,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.21.0', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.21.2', now()); # TODO: change when structure changes. From a201018610d9d9f82c886104a7af879a28e1325a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 17 Mar 2022 13:56:41 +0000 Subject: [PATCH 1692/1848] Started to use override_2fa access right. --- initialize.php | 2 +- login.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/initialize.php b/initialize.php index 8ed35c5cc..d56c43b36 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.2.5666"); +define("APP_VERSION", "1.21.2.5667"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/login.php b/login.php index dbf5d0c39..a097c8883 100644 --- a/login.php +++ b/login.php @@ -56,8 +56,8 @@ $use2FA = $config->getDefinedValue('2fa'); } - // If we have to use 2FA, create and email auth code to user. - if ($use2FA) { + // If we have to use 2FA, email auth code to user and redirect to 2fa.php. + if ($use2FA && !$user->can('override_2fa')) { // To keep things simple, we use the same code as for password resets. $cryptographically_strong = true; $random_bytes = openssl_random_pseudo_bytes(16, $cryptographically_strong); From f2358bfc5e20cd3b741166379779505e8b149be8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 17 Mar 2022 15:26:17 +0000 Subject: [PATCH 1693/1848] Initial implementation of two factor authentication. --- 2fa.php | 54 +++++++++++++++-------- WEB-INF/templates/2fa.tpl | 24 +++++++--- WEB-INF/templates/group_advanced_edit.tpl | 2 - initialize.php | 2 +- login.php | 9 ++-- 5 files changed, 60 insertions(+), 31 deletions(-) diff --git a/2fa.php b/2fa.php index 005b4ea42..a7e3dbb29 100644 --- a/2fa.php +++ b/2fa.php @@ -11,36 +11,54 @@ // ... anything to check? // End of access checks. -$cl_2fa_code = $request->getParameter('2fa_code'); -$form = new Form('2faForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'2fa_code','value'=>$cl_2fa_code)); +$cl_login = $request->getParameter('login'); +if ($cl_login == null && $request->isGet()) $cl_login = @$_COOKIE[LOGIN_COOKIE_NAME]; +$cl_password = $request->getParameter('password'); +$cl_auth_code = $request->getParameter('auth_code'); + +$form = new Form('twoFactorAuthForm'); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','value'=>$cl_login)); +$form->getElement('login')->setEnabled(false); +$form->addInput(array('type'=>'password','maxlength'=>'50','name'=>'password','value'=>$cl_password)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'auth_code','value'=>$cl_auth_code)); $form->addInput(array('type'=>'submit','name'=>'btn_login','value'=>$i18n->get('button.login'))); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_2fa_code)) $err->add($i18n->get('error.field'), $i18n->get('form.2fa.2fa_code')); - - // Get user id. - $user_id = ttUserHelper::getUserIdByTmpRef($cl_2fa_code); - if (!$user_id) $err->add($i18n->get('error.2fa_code')); + if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); + if (!ttValidString($cl_password)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); + if (!ttValidString($cl_auth_code)) $err->add($i18n->get('error.field'), $i18n->get('form.2fa.2fa_code')); if ($err->no()) { - $user = new ttUser(null, $user_id); // Note: reusing $user from initialize.php. - $auth->setAuth($user_id, $user->login); - - // Redirect, depending on user role. - if ($user->isClient()) { - header('Location: reports.php'); - } else { - header('Location: time.php'); + // Get user id. + $user_id = ttUserHelper::getUserIdByTmpRef($cl_auth_code); + if (!$user_id) + $err->add($i18n->get('error.2fa_code')); + + if ($err->no()) { + // Additionally check user password for better protection + // against brute force attacks guessing 2FA codes. + $user = new ttUser(null, $user_id); // Note: reusing $user from initialize.php. + // Check user password. + if (!$auth->doLogin($user->login, $cl_password)) + $err->add($i18n->get('error.auth')); + } + + if ($err->no()) { + // Redirect, depending on user role. + if ($user->isClient()) { + header('Location: reports.php'); + } else { + header('Location: time.php'); + } + exit(); } - exit(); } } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.2faForm.2fa_code.focus()"'); +$smarty->assign('onload', 'onLoad="document.twoFactorAuthForm.auth_code.focus()"'); $smarty->assign('title', $i18n->get('title.2fa')); $smarty->assign('content_page_name', '2fa.tpl'); $smarty->display('index.tpl'); diff --git a/WEB-INF/templates/2fa.tpl b/WEB-INF/templates/2fa.tpl index bd7e2f01b..d425cbc11 100644 --- a/WEB-INF/templates/2fa.tpl +++ b/WEB-INF/templates/2fa.tpl @@ -2,17 +2,29 @@ License: See license.txt *}
{$i18n.form.2fa.hint}
-{$forms.2faForm.open} +{$forms.twoFactorAuthForm.open} - + - - + + + - + + + + + + + + + + + +
{$forms.2faForm.2fa_code.control}{$forms.twoFactorAuthForm.login.control}
{$forms.2faForm.btn_login.control}{$forms.twoFactorAuthForm.password.control}
{$forms.twoFactorAuthForm.auth_code.control}
{$forms.twoFactorAuthForm.btn_login.control}
-{$forms.2faForm.close} +{$forms.twoFactorAuthForm.close} diff --git a/WEB-INF/templates/group_advanced_edit.tpl b/WEB-INF/templates/group_advanced_edit.tpl index d4bd55a1e..82eac702c 100644 --- a/WEB-INF/templates/group_advanced_edit.tpl +++ b/WEB-INF/templates/group_advanced_edit.tpl @@ -41,7 +41,6 @@ License: See license.txt *} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
{$forms.groupForm.one_uncompleted.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{if $time_records} + + +
@@ -177,10 +188,13 @@ License: See license.txt *} {/if} {/if} - diff --git a/initialize.php b/initialize.php index 84470d543..2f7224b8a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5691"); +define("APP_VERSION", "1.21.4.5692"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/puncher.php b/puncher.php index 92f500d87..2b25462d3 100644 --- a/puncher.php +++ b/puncher.php @@ -32,7 +32,7 @@ // If we are passed in browser_time, make sure it is in correct format. $browser_time = null; // Reused below beyond access checks. if ($request->isPost()) { - // Validate that browser_today parameter is in correct format. + // Validate that browser_time parameter is in correct format. $browser_time = $request->getParameter('browser_time'); if ($browser_time && !ttValidTime($browser_time)) { header('Location: access_denied.php'); diff --git a/time.php b/time.php index 4f08cfe2a..faf064a4a 100644 --- a/time.php +++ b/time.php @@ -46,6 +46,30 @@ exit(); } } +// Additional checks for hidden controls used for completion of uncompleted records. +// browser_date, browser_time, record_id. +if ($request->isPost() && $request->getParameter('btn_stop')) { + $recordId = (int) $request->getParameter('record_id'); + $time_rec = ttTimeHelper::getRecord($recordId); + if (!$time_rec) { + // We are passed a bogus record id. + header('Location: access_denied.php'); + exit(); + } + + // Validate that browser_date parameter is in correct format. + $browser_date = $request->getParameter('browser_date'); + if ($browser_date && !ttValidDbDateFormatDate($browser_date)) { + header('Location: access_denied.php'); + exit(); + } + // Validate that browser_time parameter is in correct format. + $browser_time = $request->getParameter('browser_time'); + if ($browser_time && !ttValidTime($browser_time)) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. // Determine user for whom we display this page. From c88dfcd6d32eea8818f266e39144732f9c263184 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 9 Apr 2022 15:18:33 +0000 Subject: [PATCH 1718/1848] Resuming refactoring. --- WEB-INF/lib/common.lib.php | 2 +- initialize.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index fc27d2945..2d8e287d5 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -577,7 +577,7 @@ function ttEndsWith($string, $endString) function ttDateToUserFormat($date) { global $user; - $o_date = new DateAndTime(DB_DATEFORMAT, $date); + $o_date = new ttDate($date); return $o_date->toString($user->date_format); } diff --git a/initialize.php b/initialize.php index 2f7224b8a..e787e27b0 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5692"); +define("APP_VERSION", "1.21.4.5693"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ba5e71ff40894946290f51979dc07f4ab00e21d0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 9 Apr 2022 16:52:18 +0000 Subject: [PATCH 1719/1848] Incremental refactoring. --- WEB-INF/lib/form/ActionForm.class.php | 43 +++++++-------------------- initialize.php | 2 +- time_edit.php | 1 - week.php | 1 - 4 files changed, 12 insertions(+), 35 deletions(-) diff --git a/WEB-INF/lib/form/ActionForm.class.php b/WEB-INF/lib/form/ActionForm.class.php index abc5e006b..5b88292c4 100644 --- a/WEB-INF/lib/form/ActionForm.class.php +++ b/WEB-INF/lib/form/ActionForm.class.php @@ -1,32 +1,9 @@ mValues[$name] = $value; if ($this->mForm) { if (isset($this->mForm->elements[$name])) { if ($this->mForm->elements[$name]->class=="DateField") { - $dt = new DateAndTime($user->date_format, $value); - $value = $dt->toString(DB_DATEFORMAT); + // TODO: It appears that we never get here. Refactor this entire class. + $dt = new ttDate($user->date_format, $value); + $value = $dt->toString(); } $this->mForm->elements[$name]->setValueSafe($value); } @@ -140,8 +118,9 @@ function setAttributes($value) { if ($this->mForm) { if (isset($this->mForm->elements[$name])) { if ($this->mForm->elements[$name]->class=="DateField") { - $dt = new DateAndTime($user->date_format, $value); - $value = $dt->toString(DB_DATEFORMAT); + // TODO: It appears that we never get here. Refactor this entire class. + $dt = new ttDate($user->date_format, $value); + $value = $dt->toString(); } $this->mForm->elements[$name]->setValueSafe($value); } diff --git a/initialize.php b/initialize.php index e787e27b0..a8b14bca9 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5693"); +define("APP_VERSION", "1.21.4.5694"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time_edit.php b/time_edit.php index a00f66051..03c721193 100644 --- a/time_edit.php +++ b/time_edit.php @@ -9,7 +9,6 @@ import('ttClientHelper'); import('ttTimeHelper'); import('ttConfigHelper'); -import('DateAndTime'); import('ttDate'); // Access checks. diff --git a/week.php b/week.php index 1e0ec1b41..92eb95ee3 100644 --- a/week.php +++ b/week.php @@ -13,7 +13,6 @@ import('ttClientHelper'); import('ttTimeHelper'); import('ttDate'); -import('DateAndTime'); // Access checks. if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time'))) { From 43b0cadb33efc2bb97b3a62a95d6a7da5d93874b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 9 Apr 2022 18:40:23 +0000 Subject: [PATCH 1720/1848] More refactoring. --- expense_edit.php | 16 ++++++++-------- initialize.php | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/expense_edit.php b/expense_edit.php index 258437b33..e57db88d9 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -5,9 +5,9 @@ require_once('initialize.php'); import('form.Form'); import('ttGroupHelper'); -import('DateAndTime'); import('ttTimeHelper'); import('ttExpenseHelper'); +import('ttDate'); // Access checks. if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses'))) { @@ -37,7 +37,7 @@ } // End of access checks. -$item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); +$item_date = new ttDate($expense_item['date']); $confirm_save = $user->getConfigOption('confirm_save'); $trackingMode = $user->getTrackingMode(); $show_project = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; @@ -150,11 +150,11 @@ if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); // This is a new date for the expense item. - $new_date = new DateAndTime($user->getDateFormat(), $cl_date); + $new_date = new ttDate($cl_date, $user->getDateFormat()); // Prohibit creating entries in future. if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); + $browser_today = new ttDate($request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); } @@ -178,9 +178,9 @@ // Now, an update. if ($err->no()) { - if (ttExpenseHelper::update(array('id'=>$cl_id,'date'=>$new_date->toString(DB_DATEFORMAT), + if (ttExpenseHelper::update(array('id'=>$cl_id,'date'=>$new_date->toString(), 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'paid'=>$cl_paid))) { - header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); + header('Location: expenses.php?date='.$new_date->toString()); exit(); } } @@ -194,9 +194,9 @@ // Now, a new insert. if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'client_id'=>$cl_client, + if (ttExpenseHelper::insert(array('date'=>$new_date->toString(),'client_id'=>$cl_client, 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { - header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); + header('Location: expenses.php?date='.$new_date->toString()); exit(); } else $err->add($i18n->get('error.db')); diff --git a/initialize.php b/initialize.php index a8b14bca9..45fa67787 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5694"); +define("APP_VERSION", "1.21.4.5695"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 49ef4b11da9b456e26d5e1592fa79a3194a49b7e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 10 Apr 2022 16:04:20 +0000 Subject: [PATCH 1721/1848] Resuming refactoring. --- WEB-INF/lib/ttDate.class.php | 9 +++++++++ initialize.php | 2 +- reports.php | 33 +++++++++++++++++---------------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttDate.class.php b/WEB-INF/lib/ttDate.class.php index 1f1dfeaaf..3b798214a 100644 --- a/WEB-INF/lib/ttDate.class.php +++ b/WEB-INF/lib/ttDate.class.php @@ -153,6 +153,15 @@ function after(/*ttDate*/ $obj) { } + function compare(/*ttDate*/ $obj) { + $ts1 = $this->getTimestamp(); + $ts2 = $obj->getTimestamp(); + if ($ts1 < $ts2) return -1; + if ($ts1 == $ts2) return 0; + if ($ts1 > $ts2) return 1; + } + + // Getters. function getYear() { return $this->year; } function getMonth() { return $this->month; } diff --git a/initialize.php b/initialize.php index 45fa67787..201e96f4e 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5695"); +define("APP_VERSION", "1.21.4.5696"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports.php b/reports.php index c1df04387..858ca61cb 100644 --- a/reports.php +++ b/reports.php @@ -5,13 +5,13 @@ require_once('initialize.php'); import('form.Form'); import('form.ActionForm'); -import('DateAndTime'); import('ttGroupHelper'); -import('Period'); import('ttProjectHelper'); import('ttFavReportHelper'); import('ttClientHelper'); import('ttReportHelper'); +import('ttDate'); +import('ttPeriod'); // Access check. if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports') || ttAccessAllowed('view_client_reports'))) { @@ -357,9 +357,9 @@ if ($request->isGet() && !$bean->isSaved()) { // No previous form data were found in session. Use the following default values. $form->setValueByElement('users_active', array_keys((array)$user_list_active)); - $period = new Period(INTERVAL_THIS_MONTH, new DateAndTime($user->getDateFormat())); - $form->setValueByElement('start_date', $period->getStartDate()); - $form->setValueByElement('end_date', $period->getEndDate()); + $period = new ttPeriod(new ttDate(), INTERVAL_THIS_MONTH); + $form->setValueByElement('start_date', $period->getStartDate($user->getDateFormat())); + $form->setValueByElement('end_date', $period->getEndDate($user->getDateFormat())); $form->setValueByElement('chclient', '1'); $form->setValueByElement('chstart', '1'); @@ -438,17 +438,18 @@ } else { // Generate button pressed. Check some values. if (!$bean->getAttribute('period')) { - $start_date = new DateAndTime($user->getDateFormat(), $bean->getAttribute('start_date')); - - if ($start_date->isError() || !$bean->getAttribute('start_date')) - $err->add($i18n->get('error.field'), $i18n->get('label.start_date')); - - $end_date = new DateAndTime($user->getDateFormat(), $bean->getAttribute('end_date')); - if ($end_date->isError() || !$bean->getAttribute('end_date')) - $err->add($i18n->get('error.field'), $i18n->get('label.end_date')); - - if ($start_date->compare($end_date) > 0) - $err->add($i18n->get('error.interval'), $i18n->get('label.end_date'), $i18n->get('label.start_date')); + // Validate start date. + if (!ttValidDate($bean->getAttribute('start_date'))) $err->add($i18n->get('error.field'), $i18n->get('label.start_date')); + // Validate end date. + if (!ttValidDate($bean->getAttribute('end_date'))) $err->add($i18n->get('error.field'), $i18n->get('label.end_date')); + // Make sure that the end date is equal or after the start date. + if ($err->no()) { + $startDate = new ttDate($bean->getAttribute('start_date'), $user->getDateFormat()); + $endDate = new ttDate($bean->getAttribute('end_date'), $user->getDateFormat()); + if ($startDate->compare($endDate) > 0) { + $err->add($i18n->get('error.interval'), $i18n->get('label.end_date'), $i18n->get('label.start_date')); + } + } } $group_by1 = $bean->getAttribute('group_by1'); $group_by2 = $bean->getAttribute('group_by2'); From 66ee957d754819df5f672746af4d62aad44771a7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 10 Apr 2022 16:15:10 +0000 Subject: [PATCH 1722/1848] A bit more refactoring. --- initialize.php | 2 +- invoice_view.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/initialize.php b/initialize.php index 201e96f4e..5703b55be 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5696"); +define("APP_VERSION", "1.21.4.5697"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/invoice_view.php b/invoice_view.php index b03b719e4..b1fcf91f9 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -3,7 +3,7 @@ License: See license.txt */ require_once('initialize.php'); -import('DateAndTime'); +import('ttDate'); import('ttInvoiceHelper'); import('ttClientHelper'); import('form.Form'); @@ -25,7 +25,7 @@ } // End of access checks. -$invoice_date = new DateAndTime(DB_DATEFORMAT, $invoice['date']); +$invoice_date = new ttDate($invoice['date']); $client = ttClientHelper::getClient($invoice['client_id'], true); if (!$client) // In case client was deleted. $client = ttClientHelper::getDeletedClient($invoice['client_id']); From a44ba11b58ef6f76c7570a3092bb94c0088b2008 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 10 Apr 2022 16:39:55 +0000 Subject: [PATCH 1723/1848] More refactoring. --- expenses.php | 11 +++++------ initialize.php | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/expenses.php b/expenses.php index 897d64d91..34169b7dc 100644 --- a/expenses.php +++ b/expenses.php @@ -6,7 +6,7 @@ import('form.Form'); import('ttUserHelper'); import('ttGroupHelper'); -import('DateAndTime'); +import('ttDate'); import('ttTimeHelper'); import('ttExpenseHelper'); import('ttFileHelper'); @@ -65,13 +65,12 @@ // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); +$selected_date = new ttDate($cl_date); if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); + $cl_date = $selected_date->toString(); $_SESSION['date'] = $cl_date; + $tracking_mode = $user->getTrackingMode(); $show_project = MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode; $showFiles = $user->isPluginEnabled('at'); @@ -203,7 +202,7 @@ // Prohibit creating entries in future. if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); + $browser_today = new ttDate($request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); } diff --git a/initialize.php b/initialize.php index 5703b55be..e1a5ffd06 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5697"); +define("APP_VERSION", "1.21.4.5698"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 8b66de3dd6a21fc65fa26a3a6fcbf940d8d2b05f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 10 Apr 2022 16:53:05 +0000 Subject: [PATCH 1724/1848] A bit more refactoring. --- charts.php | 6 +++--- expense_delete.php | 4 ++-- initialize.php | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/charts.php b/charts.php index cfd01c5fe..1ad1c88d9 100644 --- a/charts.php +++ b/charts.php @@ -6,7 +6,7 @@ require_once('initialize.php'); import('form.Form'); -import('DateAndTime'); +import('ttDate'); import('ttChartHelper'); import('ttUserConfig'); import('PieChartEx'); @@ -72,8 +72,8 @@ // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); if(!$cl_date) { - $now = new DateAndTime(DB_DATEFORMAT); - $cl_date = $now->toString(DB_DATEFORMAT); + $now = new ttDate(); + $cl_date = $now->toString(); } $_SESSION['date'] = $cl_date; diff --git a/expense_delete.php b/expense_delete.php index 6c5cb791f..6dbf421a9 100644 --- a/expense_delete.php +++ b/expense_delete.php @@ -4,7 +4,7 @@ require_once('initialize.php'); import('form.Form'); -import('DateAndTime'); +import('ttDate'); import('ttExpenseHelper'); // Access checks. @@ -30,7 +30,7 @@ if ($request->getParameter('delete_button')) { // Delete button pressed. // Determine if it is okay to delete the record. - $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); + $item_date = new ttDate($expense_item['date']); if ($user->isDateLocked($item_date)) $err->add($i18n->get('error.range_locked')); diff --git a/initialize.php b/initialize.php index e1a5ffd06..6be6126dd 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5698"); +define("APP_VERSION", "1.21.4.5699"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 0a61c1b2469f7c519419b35712223838a37f40b9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 10 Apr 2022 17:28:27 +0000 Subject: [PATCH 1725/1848] Cleanup. --- WEB-INF/lib/ttTeamHelper.class.php | 30 ++---------------------------- WEB-INF/lib/ttTimeHelper.class.php | 2 -- initialize.php | 2 +- 3 files changed, 3 insertions(+), 31 deletions(-) diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 981f01b50..e12c2575b 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -1,33 +1,8 @@ query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { - $dt = new DateAndTime(DB_DATEFORMAT); while ($val = $res->fetchRow()) { $result[] = $val; } diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index dd0977476..2e9eddbb1 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -2,8 +2,6 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -import('DateAndTime'); - // The ttTimeHelper is a class to help with time-related values. class ttTimeHelper { diff --git a/initialize.php b/initialize.php index 6be6126dd..9ae6dcdb6 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5699"); +define("APP_VERSION", "1.21.4.5700"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 2cf98d9ab1e736794ff0131a41cb642374198fe5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 10 Apr 2022 17:45:17 +0000 Subject: [PATCH 1726/1848] A bit more cleanup and refactoring. --- WEB-INF/lib/ttGroupHelper.class.php | 4 +--- initialize.php | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 81b0c7f34..81d1af696 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -431,10 +431,9 @@ static function getActiveInvoices($sort_options = false) $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { - $dt = new DateAndTime(DB_DATEFORMAT); while ($val = $res->fetchRow()) { // Localize date. - $dt->parseVal($val['date']); + $dt = new ttDate($val['date']); $val['date'] = $dt->toString($user->getDateFormat()); if ($addPaidStatus) $val['paid'] = ttInvoiceHelper::isPaid($val['id']); @@ -679,7 +678,6 @@ static function getRecentInvoices($client_id) { $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { - $dt = new DateAndTime(DB_DATEFORMAT); while ($val = $res->fetchRow()) { $result[] = $val; } diff --git a/initialize.php b/initialize.php index 9ae6dcdb6..6b4471a20 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5700"); +define("APP_VERSION", "1.21.4.5701"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 912ffe1bfcbb21a8e87e6a162b57148321109a22 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 10 Apr 2022 20:01:41 +0000 Subject: [PATCH 1727/1848] Refactoring in progress. --- WEB-INF/lib/ttChartHelper.class.php | 40 ++++++----------------------- WEB-INF/lib/ttPeriod.class.php | 12 +++++++++ initialize.php | 2 +- 3 files changed, 21 insertions(+), 33 deletions(-) diff --git a/WEB-INF/lib/ttChartHelper.class.php b/WEB-INF/lib/ttChartHelper.class.php index 4e4f9c832..f0523036d 100644 --- a/WEB-INF/lib/ttChartHelper.class.php +++ b/WEB-INF/lib/ttChartHelper.class.php @@ -1,32 +1,8 @@ endDate = new ttDate(); switch ($period_type) { + case INTERVAL_THIS_DAY: + $this->startDate->setFromUnixTimestamp($ttDateInstance->getTimestamp()); + $this->endDate->setFromUnixTimestamp($ttDateInstance->getTimestamp()); + break; + case INTERVAL_THIS_WEEK: $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+$startWeekBias,$t_arr[5])); $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+6+$startWeekBias,$t_arr[5])); @@ -32,6 +39,11 @@ function __construct($ttDateInstance, $period_type = INTERVAL_THIS_MONTH) { $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,1,$t_arr[5])); $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+2,0,$t_arr[5])); break; + + case INTERVAL_THIS_YEAR: + $this->startDate->setFromUnixTimestamp(mktime(0,0,0,1,1,$t_arr[5])); + $this->endDate->setFromUnixTimestamp(mktime(0,0,0,12,31,$t_arr[5])); + break; } } diff --git a/initialize.php b/initialize.php index 6b4471a20..a078f888c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5701"); +define("APP_VERSION", "1.21.4.5702"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 50e2643ca231372b72c42d4094cd195903efe31d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 10 Apr 2022 20:36:34 +0000 Subject: [PATCH 1728/1848] Refactoring in progress. --- WEB-INF/lib/ttPeriod.class.php | 24 ++++++++++++++++++++++++ WEB-INF/lib/ttReportHelper.class.php | 10 ++++++---- initialize.php | 2 +- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttPeriod.class.php b/WEB-INF/lib/ttPeriod.class.php index 85022a85b..1d63ad9d1 100644 --- a/WEB-INF/lib/ttPeriod.class.php +++ b/WEB-INF/lib/ttPeriod.class.php @@ -6,6 +6,10 @@ define('INTERVAL_THIS_WEEK', 2); define('INTERVAL_THIS_MONTH', 3); define('INTERVAL_THIS_YEAR', 4); +define('INTERVAL_ALL_TIME', 5); +define('INTERVAL_LAST_WEEK', 6); +define('INTERVAL_LAST_MONTH', 7); +define('INTERVAL_LAST_DAY', 8); class ttPeriod { var $startDate; // ttDate object. @@ -30,16 +34,31 @@ function __construct($ttDateInstance, $period_type = INTERVAL_THIS_MONTH) { $this->endDate->setFromUnixTimestamp($ttDateInstance->getTimestamp()); break; + case INTERVAL_LAST_DAY: + $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-1,$t_arr[5])); + $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-1,$t_arr[5])); + break; + case INTERVAL_THIS_WEEK: $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+$startWeekBias,$t_arr[5])); $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+6+$startWeekBias,$t_arr[5])); break; + case INTERVAL_LAST_WEEK: + $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]-7+$startWeekBias,$t_arr[5])); + $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]-1+$startWeekBias,$t_arr[5])); + break; + case INTERVAL_THIS_MONTH: $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,1,$t_arr[5])); $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+2,0,$t_arr[5])); break; + case INTERVAL_LAST_MONTH: + $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4],1,$t_arr[5])); + $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,0,$t_arr[5])); + break; + case INTERVAL_THIS_YEAR: $this->startDate->setFromUnixTimestamp(mktime(0,0,0,1,1,$t_arr[5])); $this->endDate->setFromUnixTimestamp(mktime(0,0,0,12,31,$t_arr[5])); @@ -47,6 +66,11 @@ function __construct($ttDateInstance, $period_type = INTERVAL_THIS_MONTH) { } } + // Sets period to designated start and and dates. + function setPeriod($start_date, $end_date) { + $this->startDate = $start_date; + $this->endDate = $end_date; + } // Returns start date in specified format. function getStartDate($format = null) { diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 20e6d7a46..bafa40221 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -4,7 +4,9 @@ import('ttClientHelper'); import('DateAndTime'); +import('ttDate'); import('Period'); +import('ttPeriod'); import('ttTimeHelper'); import('ttConfigHelper'); @@ -119,12 +121,12 @@ static function getWhere($options) { // Prepare sql query part for where. $dateFormat = $user->getDateFormat(); if ($options['period']) - $period = new Period($options['period'], new DateAndTime($dateFormat)); + $period = new ttPeriod(new ttDate(), $options['period']); else { - $period = new Period(); + $period = new ttPeriod(new ttDate()); $period->setPeriod( - new DateAndTime($dateFormat, $options['period_start']), - new DateAndTime($dateFormat, $options['period_end'])); + new ttDate($options['period_start'], $dateFormat), + new ttDate($options['period_end'], $dateFormat)); } $where = " where l.status = 1 and l.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". " $user_list_part $dropdown_parts $cf_text_parts"; diff --git a/initialize.php b/initialize.php index a078f888c..7fbdc50ff 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5702"); +define("APP_VERSION", "1.21.4.5703"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 094e353b2f55375aedd70f14f495c23f179e1f24 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 11 Apr 2022 15:43:46 +0000 Subject: [PATCH 1729/1848] Resuming refactoring. --- WEB-INF/lib/ttReportHelper.class.php | 29 +++++++++++++--------------- initialize.php | 2 +- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index bafa40221..995cfa2b4 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -3,9 +3,7 @@ License: See license.txt */ import('ttClientHelper'); -import('DateAndTime'); import('ttDate'); -import('Period'); import('ttPeriod'); import('ttTimeHelper'); import('ttConfigHelper'); @@ -128,7 +126,7 @@ static function getWhere($options) { new ttDate($options['period_start'], $dateFormat), new ttDate($options['period_end'], $dateFormat)); } - $where = " where l.status = 1 and l.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". + $where = " where l.status = 1 and l.date >= '".$period->getStartDate()."' and l.date <= '".$period->getEndDate()."'". " $user_list_part $dropdown_parts $cf_text_parts"; return $where; } @@ -203,14 +201,14 @@ static function getExpenseWhere($options) { // Prepare sql query part for where. $dateFormat = $user->getDateFormat(); if ($options['period']) - $period = new Period($options['period'], new DateAndTime($dateFormat)); + $period = new ttPeriod(new ttDate(), $options['period']); else { - $period = new Period(); + $period = new ttPeriod(new ttDate()); $period->setPeriod( - new DateAndTime($dateFormat, $options['period_start']), - new DateAndTime($dateFormat, $options['period_end'])); + new ttDate($options['period_start'], $dateFormat), + new ttDate($options['period_end'], $dateFormat)); } - $where = " where ei.status = 1 and ei.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and ei.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". + $where = " where ei.status = 1 and ei.date >= '".$period->getStartDate()."' and ei.date <= '".$period->getEndDate()."'". " $user_list_part $dropdown_parts $cf_text_parts"; return $where; } @@ -883,17 +881,16 @@ static function getTotals($options) $dateFormat = $user->getDateFormat(); if (isset($options['period']) && $options['period']) - $period = new Period($options['period'], new DateAndTime($dateFormat)); + $period = new ttPeriod(new ttDate(), $options['period']); else { - $period = new Period(); - if (isset($options['period_start']) && isset($options['period_end'])) - $period->setPeriod( - new DateAndTime($dateFormat, $options['period_start']), - new DateAndTime($dateFormat, $options['period_end'])); + $period = new ttPeriod(new ttDate()); + $period->setPeriod( + new ttDate($options['period_start'], $dateFormat), + new ttDate($options['period_end'], $dateFormat)); } - $totals['start_date'] = $period->getStartDate(); - $totals['end_date'] = $period->getEndDate(); + $totals['start_date'] = $period->getStartDate($user->getDateFormat()); + $totals['end_date'] = $period->getEndDate($user->getDateFormat()); $totals['time'] = $total_time; $totals['minutes'] = $val['time'] / 60; $totals['units'] = isset($val['units']) ? $val['units'] : null; diff --git a/initialize.php b/initialize.php index 7fbdc50ff..88849a738 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5703"); +define("APP_VERSION", "1.21.4.5705"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 83b155b827c5ec9923b6aadd74ad462f7d8e3b61 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 11 Apr 2022 16:31:38 +0000 Subject: [PATCH 1730/1848] Refactoring. Fully replaced older Period class usage with newer ttPeriod. --- WEB-INF/lib/Period.class.php | 136 ------------------------ WEB-INF/lib/ttTimesheetHelper.class.php | 14 +-- initialize.php | 2 +- 3 files changed, 9 insertions(+), 143 deletions(-) delete mode 100644 WEB-INF/lib/Period.class.php diff --git a/WEB-INF/lib/Period.class.php b/WEB-INF/lib/Period.class.php deleted file mode 100644 index 57ea0e44c..000000000 --- a/WEB-INF/lib/Period.class.php +++ /dev/null @@ -1,136 +0,0 @@ -getWeekStart(); - - $this->startDate = new DateAndTime(); - $this->startDate->setFormat($date_point->getFormat()); - $this->endDate = new DateAndTime(); - $this->endDate->setFormat($date_point->getFormat()); - $t_arr = localtime($date_point->getTimestamp()); - $t_arr[5] = $t_arr[5] + 1900; - - if ($t_arr[6] < $weekStartDay) { - $startWeekBias = $weekStartDay - 7; - } else { - $startWeekBias = $weekStartDay; - } - - switch ($period_type) { - case INTERVAL_THIS_DAY: - $this->startDate->setTimestamp($date_point->getTimestamp()); - $this->endDate->setTimestamp($date_point->getTimestamp()); - break; - - case INTERVAL_LAST_DAY: - $this->startDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-1,$t_arr[5])); - $this->endDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-1,$t_arr[5])); - break; - - case INTERVAL_THIS_WEEK: - $this->startDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+$startWeekBias,$t_arr[5])); - $this->endDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+6+$startWeekBias,$t_arr[5])); - break; - case INTERVAL_LAST_WEEK: - $this->startDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]-7+$startWeekBias,$t_arr[5])); - $this->endDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]-1+$startWeekBias,$t_arr[5])); - break; - case INTERVAL_THIS_MONTH: - $this->startDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,1,$t_arr[5])); - $this->endDate->setTimestamp(mktime(0,0,0,$t_arr[4]+2,0,$t_arr[5])); - break; - case INTERVAL_LAST_MONTH: - $this->startDate->setTimestamp(mktime(0,0,0,$t_arr[4],1,$t_arr[5])); - $this->endDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,0,$t_arr[5])); - break; - - case INTERVAL_THIS_YEAR: - $this->startDate->setTimestamp(mktime(0, 0, 0, 1, 1, $t_arr[5])); - $this->endDate->setTimestamp(mktime(0, 0, 0, 12, 31, $t_arr[5])); - break; - } - } - - function setPeriod($b_date, $e_date) { - $this->startDate = $b_date; - $this->endDate = $e_date; - } - - // return date string - function getStartDate($format="") { - return $this->startDate->toString($format); - } - - // return date string - function getEndDate($format="") { - return $this->endDate->toString($format); - } -} diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 5ca3abe66..ec2032efb 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -4,6 +4,8 @@ import('ttUserHelper'); import('ttFileHelper'); +import('ttPeriod'); +import('ttDate'); // Class ttTimesheetHelper is used to help with project related tasks. class ttTimesheetHelper { @@ -545,15 +547,15 @@ static function getMatchingTimesheets($options) { // Determine start and end dates. $dateFormat = $user->getDateFormat(); if ($options['period']) - $period = new Period($options['period'], new DateAndTime($dateFormat)); + $period = new ttPeriod(new ttDate(), $options['period']); else { - $period = new Period(); + $period = new ttPeriod(new ttDate()); $period->setPeriod( - new DateAndTime($dateFormat, $options['period_start']), - new DateAndTime($dateFormat, $options['period_end'])); + new ttDate($options['period_start'], $dateFormat), + new ttDate($options['period_end'], $dateFormat)); } - $start = $period->getStartDate(DB_DATEFORMAT); - $end = $period->getEndDate(DB_DATEFORMAT); + $start = $period->getStartDate(); + $end = $period->getEndDate(); $result = false; $sql = "select id, name from tt_timesheets". diff --git a/initialize.php b/initialize.php index 88849a738..242fa0ab4 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5705"); +define("APP_VERSION", "1.21.4.5706"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 87386884d31673d31421cfb331f0957dc28ae971 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 11 Apr 2022 16:45:51 +0000 Subject: [PATCH 1731/1848] Incremental refactoring. --- WEB-INF/lib/ttInvoiceHelper.class.php | 8 ++++---- WEB-INF/lib/ttReportHelper.class.php | 4 ++-- WEB-INF/lib/ttTimesheetHelper.class.php | 2 +- initialize.php | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 9a20730ae..3fa4f2ce1 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -226,11 +226,11 @@ static function invoiceableItemsExist($fields) { $client_id = (int) $fields['client_id']; - $start_date = new DateAndTime($user->date_format, $fields['start_date']); - $start = $start_date->toString(DB_DATEFORMAT); + $start_date = new ttDate($fields['start_date'], $user->getDateFormat()); + $start = $start_date->toString(); - $end_date = new DateAndTime($user->date_format, $fields['end_date']); - $end = $end_date->toString(DB_DATEFORMAT); + $end_date = new ttDate($fields['end_date'], $user->getDateFormat()); + $end = $end_date->toString(); $project_id = null; $project_part = ''; diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 995cfa2b4..693fe6521 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -118,7 +118,7 @@ static function getWhere($options) { // Prepare sql query part for where. $dateFormat = $user->getDateFormat(); - if ($options['period']) + if (isset($options['period']) && $options['period']) $period = new ttPeriod(new ttDate(), $options['period']); else { $period = new ttPeriod(new ttDate()); @@ -200,7 +200,7 @@ static function getExpenseWhere($options) { // Prepare sql query part for where. $dateFormat = $user->getDateFormat(); - if ($options['period']) + if (isset($options['period']) && $options['period']) $period = new ttPeriod(new ttDate(), $options['period']); else { $period = new ttPeriod(new ttDate()); diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index ec2032efb..070d31d7b 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -546,7 +546,7 @@ static function getMatchingTimesheets($options) { // Determine start and end dates. $dateFormat = $user->getDateFormat(); - if ($options['period']) + if (isset($options['period']) && $options['period']) $period = new ttPeriod(new ttDate(), $options['period']); else { $period = new ttPeriod(new ttDate()); diff --git a/initialize.php b/initialize.php index 242fa0ab4..ee6c46922 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5706"); +define("APP_VERSION", "1.21.4.5707"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From a299407343dd43cb46a90ac3063fa9bcc5b7d700 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 11 Apr 2022 17:01:00 +0000 Subject: [PATCH 1732/1848] A bit more refactoring. --- WEB-INF/lib/ttInvoiceHelper.class.php | 17 ++++++++--------- initialize.php | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 3fa4f2ce1..2ac63db44 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -3,7 +3,7 @@ License: See license.txt */ import('ttClientHelper'); -import('DateAndTime'); +import('ttDate'); // Class ttInvoiceHelper is used for help with invoices. class ttInvoiceHelper { @@ -159,9 +159,8 @@ static function getInvoiceItems($invoice_id) { $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { - $dt = new DateAndTime(DB_DATEFORMAT); while ($val = $res->fetchRow()) { - $dt->parseVal($val['date']); + $dt = new ttDate($val['date']); $val['date'] = $dt->toString($user->getDateFormat()); $result[] = $val; } @@ -304,14 +303,14 @@ static function createInvoice($fields) { $client_id = (int) $fields['client_id']; - $invoice_date = new DateAndTime($user->date_format, $fields['date']); - $date = $invoice_date->toString(DB_DATEFORMAT); + $invoice_date = new ttDate($fields['date'], $user->getDateFormat()); + $date = $invoice_date->toString(); - $start_date = new DateAndTime($user->date_format, $fields['start_date']); - $start = $start_date->toString(DB_DATEFORMAT); + $start_date = new ttDate($fields['start_date'], $user->getDateFormat()); + $start = $start_date->toString(); - $end_date = new DateAndTime($user->date_format, $fields['end_date']); - $end = $end_date->toString(DB_DATEFORMAT); + $end_date = new ttDate($fields['end_date'], $user->getDateFormat()); + $end = $end_date->toString(); $project_id = null; $project_part = ''; diff --git a/initialize.php b/initialize.php index ee6c46922..97e7b7701 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5707"); +define("APP_VERSION", "1.21.4.5708"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From d17164a8ecd5880d4b16a5eff98bd130566bc5ce Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 11 Apr 2022 17:54:04 +0000 Subject: [PATCH 1733/1848] More progress with refactoring. --- WEB-INF/lib/ttTimesheetHelper.class.php | 24 ++++++++++++------------ initialize.php | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 070d31d7b..16d740291 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -47,11 +47,11 @@ static function createTimesheet($fields) $name = $fields['name']; $comment = $fields['comment']; - $start_date = new DateAndTime($user->date_format, $fields['start_date']); - $start = $start_date->toString(DB_DATEFORMAT); + $start_date = new ttDate($fields['start_date'], $user->getDateFormat()); + $start = $start_date->toString(); - $end_date = new DateAndTime($user->date_format, $fields['end_date']); - $end = $end_date->toString(DB_DATEFORMAT); + $end_date = new ttDate($fields['end_date'], $user->getDateFormat()); + $end = $end_date->toString(); $created_part = ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$user->id; @@ -448,11 +448,11 @@ static function timesheetItemsExist($fields) { if (isset($fields['client_id'])) $client_id = (int) $fields['client_id']; if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; - $start_date = new DateAndTime($user->date_format, $fields['start_date']); - $start = $start_date->toString(DB_DATEFORMAT); + $start_date = new ttDate($fields['start_date'], $user->getDateFormat()); + $start = $start_date->toString(); - $end_date = new DateAndTime($user->date_format, $fields['end_date']); - $end = $end_date->toString(DB_DATEFORMAT); + $end_date = new ttDate($fields['end_date'], $user->getDateFormat()); + $end = $end_date->toString(); // sql parts. $client_part = $project_part = ''; @@ -488,12 +488,12 @@ static function overlaps($fields) { if (isset($fields['client_id'])) $client_id = (int) $fields['client_id']; if (isset($fields['project_id'])) $project_id = (int) $fields['project_id']; - $start_date = new DateAndTime($user->date_format, $fields['start_date']); - $start = $start_date->toString(DB_DATEFORMAT); + $start_date = new ttDate($fields['start_date'], $user->getDateFormat()); + $start = $start_date->toString(); $quoted_start = $mdb2->quote($start); - $end_date = new DateAndTime($user->date_format, $fields['end_date']); - $end = $end_date->toString(DB_DATEFORMAT); + $end_date = new ttDate($fields['end_date'], $user->getDateFormat()); + $end = $end_date->toString(); $quoted_end = $mdb2->quote($end); // sql parts. diff --git a/initialize.php b/initialize.php index 97e7b7701..b567181c4 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5708"); +define("APP_VERSION", "1.21.4.5709"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 24d68b74cec8556cb594366e59a75d2107ff1e3c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 11 Apr 2022 19:29:44 +0000 Subject: [PATCH 1734/1848] Fixed loading fav reports. --- WEB-INF/lib/form/ActionForm.class.php | 8 ++++---- WEB-INF/lib/ttFavReportHelper.class.php | 9 +++++---- initialize.php | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/WEB-INF/lib/form/ActionForm.class.php b/WEB-INF/lib/form/ActionForm.class.php index 5b88292c4..253091b48 100644 --- a/WEB-INF/lib/form/ActionForm.class.php +++ b/WEB-INF/lib/form/ActionForm.class.php @@ -88,8 +88,8 @@ function setAttribute($name,$value) { if ($this->mForm) { if (isset($this->mForm->elements[$name])) { if ($this->mForm->elements[$name]->class=="DateField") { - // TODO: It appears that we never get here. Refactor this entire class. - $dt = new ttDate($user->date_format, $value); + // We get here when loading a fav report. Refactor this entire class. + $dt = new ttDate($value, $user->getDateFormat()); $value = $dt->toString(); } $this->mForm->elements[$name]->setValueSafe($value); @@ -118,8 +118,8 @@ function setAttributes($value) { if ($this->mForm) { if (isset($this->mForm->elements[$name])) { if ($this->mForm->elements[$name]->class=="DateField") { - // TODO: It appears that we never get here. Refactor this entire class. - $dt = new ttDate($user->date_format, $value); + // We get here when changing to --- no --- fav report. Refactor this entire class. + $dt = new ttDate($value, $user->getDateFormat()); $value = $dt->toString(); } $this->mForm->elements[$name]->setValueSafe($value); diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 303750d63..9e1827e09 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -3,6 +3,7 @@ License: See license.txt */ import('ttGroupHelper'); +import('ttDate'); // Class ttFavReportHelper is used to help with favorite report related tasks. class ttFavReportHelper { @@ -212,12 +213,12 @@ static function saveReport($bean) { } if ($bean->getAttribute('start_date')) { - $dt = new DateAndTime($user->getDateFormat(), $bean->getAttribute('start_date')); - $from = $dt->toString(DB_DATEFORMAT); + $dt = new ttDate($bean->getAttribute('start_date'), $user->getDateFormat()); + $from = $dt->toString(); } if ($bean->getAttribute('end_date')) { - $dt = new DateAndTime($user->getDateFormat(), $bean->getAttribute('end_date')); - $to = $dt->toString(DB_DATEFORMAT); + $dt = new ttDate($bean->getAttribute('end_date'), $user->getDateFormat()); + $to = $dt->toString(); } $fields = array( diff --git a/initialize.php b/initialize.php index b567181c4..17750f01b 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.4.5709"); +define("APP_VERSION", "1.21.5.5710"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 7478a60d4496328cf020a94c6e8b5b02aece11ab Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 11 Apr 2022 20:41:55 +0000 Subject: [PATCH 1735/1848] Refactoring. Finished replacing older DateAndTime class with newer ttDate class. --- WEB-INF/lib/DateAndTime.class.php | 348 ------------------------ WEB-INF/lib/form/DateField.class.php | 14 +- WEB-INF/lib/ttDate.class.php | 1 - WEB-INF/lib/ttFavReportHelper.class.php | 4 +- 4 files changed, 7 insertions(+), 360 deletions(-) delete mode 100644 WEB-INF/lib/DateAndTime.class.php diff --git a/WEB-INF/lib/DateAndTime.class.php b/WEB-INF/lib/DateAndTime.class.php deleted file mode 100644 index e72245985..000000000 --- a/WEB-INF/lib/DateAndTime.class.php +++ /dev/null @@ -1,348 +0,0 @@ -$sDate parsed, or false on error. - */ - -function my_strptime($sDate, $sFormat) -{ - $aResult = array - ( - 'tm_sec' => 0, - 'tm_min' => 0, - 'tm_hour' => 0, - 'tm_mday' => 1, - 'tm_mon' => 0, - 'tm_year' => 0, - 'tm_wday' => 0, - 'tm_yday' => 0, - 'unparsed' => $sDate, - ); - - while($sFormat != "") - { - // ===== Search a %x element, Check the static string before the %x ===== - $nIdxFound = strpos($sFormat, '%'); - if($nIdxFound === false) - { - - // There is no more format. Check the last static string. - $aResult['unparsed'] = ($sFormat == $sDate) ? "" : $sDate; - break; - } - - $sFormatBefore = mb_substr($sFormat, 0, $nIdxFound); - $sDateBefore = mb_substr($sDate, 0, $nIdxFound); - - if($sFormatBefore != $sDateBefore) break; - - // ===== Read the value of the %x found ===== - $sFormat = mb_substr($sFormat, $nIdxFound); - $sDate = mb_substr($sDate, $nIdxFound); - - $aResult['unparsed'] = $sDate; - - $sFormatCurrent = mb_substr($sFormat, 0, 2); - $sFormatAfter = mb_substr($sFormat, 2); - - $nValue = -1; - $sDateAfter = ""; - switch($sFormatCurrent) - { - case '%S': // Seconds after the minute (0-59) - - sscanf($sDate, "%2d%[^\\n]", $nValue, $sDateAfter); - - if(($nValue < 0) || ($nValue > 59)) return false; - - $aResult['tm_sec'] = $nValue; - break; - - // ---------- - case '%M': // Minutes after the hour (0-59) - sscanf($sDate, "%2d%[^\\n]", $nValue, $sDateAfter); - - if(($nValue < 0) || ($nValue > 59)) return false; - - $aResult['tm_min'] = $nValue; - break; - - // ---------- - case '%H': // Hour since midnight (0-23) - sscanf($sDate, "%2d%[^\\n]", $nValue, $sDateAfter); - - if(($nValue < 0) || ($nValue > 23)) return false; - - $aResult['tm_hour'] = $nValue; - break; - - // ---------- - case '%d': // Day of the month (1-31) - sscanf($sDate, "%2d%[^\\n]", $nValue, $sDateAfter); - - if(($nValue < 1) || ($nValue > 31)) return false; - - $aResult['tm_mday'] = $nValue; - break; - - // ---------- - case '%m': // Months since January (0-11) - sscanf($sDate, "%2d%[^\\n]", $nValue, $sDateAfter); - - if(($nValue < 1) || ($nValue > 12)) return false; - - $aResult['tm_mon'] = ($nValue - 1); - break; - - // ---------- - case '%Y': // Years since 1900 - sscanf($sDate, "%4d%[^\\n]", $nValue, $sDateAfter); - - if($nValue < 1900) return false; - - $aResult['tm_year'] = ($nValue - 1900); - break; - - // ---------- - default: - //sscanf($sDate, "%s%[^\\n]", $skip, $sDateAfter); - preg_match('/^(.+)(\s|$)/uU', $sDate, $matches); - if (isset($matches[1])) { - $sDateAfter = mb_substr($sDate, mb_strlen($matches[1])); - } else { - $sDateAfter = ''; - } - //break 2; // Break Switch and while - break; - } - - // ===== Next please ===== - $sFormat = $sFormatAfter; - $sDate = $sDateAfter; - - $aResult['unparsed'] = $sDate; - - } // END while($sFormat != "") - - - // ===== Create the other value of the result array ===== - $nParsedDateTimestamp = mktime($aResult['tm_hour'], $aResult['tm_min'], $aResult['tm_sec'], - $aResult['tm_mon'] + 1, $aResult['tm_mday'], $aResult['tm_year'] + 1900); - - // Before PHP 5.1 return -1 when error - if(($nParsedDateTimestamp === false) - ||($nParsedDateTimestamp === -1)) return false; - - $aResult['tm_wday'] = (int) strftime("%w", $nParsedDateTimestamp); // Days since Sunday (0-6) - $aResult['tm_yday'] = (strftime("%j", $nParsedDateTimestamp) - 1); // Days since January 1 (0-365) - - return $aResult; -} // END of function - -class DateAndTime { - var $mHour = 0; - var $mMinute = 0; - var $mSecond = 0; - var $mMonth; - var $mDay; // day of week - var $mDate; // day of month - var $mYear; - var $mIntrFormat = "%d.%m.%Y %H:%M:%S"; //29.02.2004 16:21:42 internal format date - var $mLocalFormat; - var $mParseResult = 0; - var $mAutoComplete = true; - - /** - * Constructor - * - * @param String $format - * @param String $strfDateTime - * @return DateAndTime - */ - function __construct($format="",$strfDateTime="") { - $this->mLocalFormat = ($format ? $format : $this->mIntrFormat); - $d = ($strfDateTime ? $strfDateTime : $this->do_strftime($this->mLocalFormat)); - $this->parseVal($d); - } - - function setFormat($format) { - $this->mLocalFormat = $format; - } - - function getFormat() { - return $this->mLocalFormat; - } - - //01 to 31 - function getDate() { return $this->mDate; } - - //0 (for Sunday) through 6 (for Saturday) - function getDay() { return $this->mDay; } - - //01 through 12 - function getMonth() { return $this->mMonth; } - - //1999 or 2003 - function getYear() { return $this->mYear; } - - function setDate($value) { $this->mDate = $value; } - function setMonth($value) { $this->mMonth = $value; } - function setYear($value) { $this->mYear = $value; } - - function setTimestamp($ts) { - $this->mDate = date("d",$ts); - $this->mDay = date("w",$ts); - $this->mMonth = date("m",$ts); - $this->mYear = date("Y",$ts); - $this->mHour = date("H",$ts); - $this->mMinute = date("i",$ts); - $this->mSecond = date("s",$ts); - } - - /** - * Return UNIX timestamp - */ - function getTimestamp() { - return @mktime($this->mHour, $this->mMinute, $this->mSecond, $this->mMonth, $this->mDate, $this->mYear); - } - - function compare($datetime) { - $ts1 = $this->getTimestamp(); - $ts2 = $datetime->getTimestamp(); - if ($ts1<$ts2) return -1; - if ($ts1==$ts2) return 0; - if ($ts1>$ts2) return 1; - } - - function toString($format="") { - if ($this->mParseResult==0) { - if ($format) { - return $this->do_strftime($format, $this->getTimestamp()); - } else { - return $this->do_strftime($this->mLocalFormat, $this->getTimestamp()); - } - } else { - if ($format) { - return $this->do_strftime($format); - } else { - return $this->do_strftime($this->mLocalFormat); - } - } - } - - function parseVal($szDate, $format="") { - $useformat = ($format ? $format : $this->mLocalFormat); - $res = my_strptime($szDate, $useformat); - if ($res !== false) { - $this->mDate = $res['tm_mday']; - $this->mDay = $res['tm_wday']; - $this->mMonth = $res['tm_mon'] + 1; // tm_mon - Months since January (0-11) - $this->mYear = 1900 + $res['tm_year']; // tm_year - Years since 1900 - $this->mHour = $res['tm_hour']; - $this->mMinute = $res['tm_min']; - $this->mSecond = $res['tm_sec']; - $this->mParseResult = 0; - } elseif ($this->mAutoComplete) { - $this->setTimestamp(time()); - $this->mParseResult = 1; - } - } - - function isError() { - if ($this->mParseResult != 0) return true; - return false; - } - - function before(/*DateAndTime*/ $obj) { - if ($this->getTimestamp() < $obj->getTimestamp()) return true; - return false; - } - - function after(/*DateAndTime*/ $obj) { - if ($this->getTimestamp() > $obj->getTimestamp()) return true; - return false; - } - - function equals(/*DateAndTime*/ $obj) { - if ($this->getTimestamp() == $obj->getTimestamp()) return true; - return false; - } - - function decDay(/*int*/$days=1) { - $this->setTimestamp(@mktime($this->mHour, $this->mMinute, $this->mSecond, $this->mMonth, $this->mDate - $days, $this->mYear)); - } - - function incDay(/*int*/$days=1) { - $this->setTimestamp(@mktime($this->mHour, $this->mMinute, $this->mSecond, $this->mMonth, $this->mDate + $days, $this->mYear)); - } - - /** - * @param $format string Datetime format string - * @return string Preprocessed string with all locale-depended format - * characters replaced by localized i18n strings. - */ - function preprocessFormatString($format) { - global $i18n; - - // replace locale-dependent strings - $format = str_replace('%a', mb_substr($i18n->getWeekDayName($this->mDay), 0, 3, 'utf-8'), $format); - $format = str_replace('%A', $i18n->getWeekDayName($this->mDay), $format); - /* This block is commented out because we currently do not use these formatters. - $abbrev_month = mb_substr($i18n->monthNames[$this->mMonth], 0, 3, 'utf-8'); - $format = str_replace('%b', $abbrev_month, $format); - $format = str_replace('%h', $abbrev_month, $format); - $format = str_replace('%z', date('O'), $format); - $format = str_replace('%Z', date('O'), $format); // format as 'O' for consistency with JS strftime - if (strpos($format, '%c') !== false) { - $format = str_replace('%c', $this->preprocessFormatString('%a %d %b %Y %T %Z'), $format); - }*/ - return $format; - } - - function do_strftime($format, $timestamp = null) - { - if (!is_null($timestamp)) { - return strftime($this->preprocessFormatString($format), $timestamp); - } else { - return strftime($this->preprocessFormatString($format)); - } - } -} diff --git a/WEB-INF/lib/form/DateField.class.php b/WEB-INF/lib/form/DateField.class.php index 922e8bf5e..d349d5687 100644 --- a/WEB-INF/lib/form/DateField.class.php +++ b/WEB-INF/lib/form/DateField.class.php @@ -3,20 +3,18 @@ License: See license.txt */ import('form.TextField'); -import('DateAndTime'); +import('ttDate'); class DateField extends TextField { var $mWeekStartDay = 0; var $mDateFormat = "d/m/Y"; var $lToday = "Today"; - var $mDateObj; var $lCalendarButtons = array('today'=>'Today', 'close'=>'Close'); function __construct($name) { $this->class = 'DateField'; $this->name = $name; - $this->mDateObj = new DateAndTime(); $this->localize(); } @@ -24,8 +22,6 @@ function localize() { global $user; global $i18n; - $this->mDateObj->setFormat($user->getDateFormat()); - $this->mMonthNames = $i18n->monthNames; $this->mWeekDayShortNames = $i18n->weekdayShortNames; $this->lToday = $i18n->get('label.today'); @@ -39,15 +35,15 @@ function localize() { // set current value taken from session or database function setValueSafe($value) { if (isset($value) && (strlen($value) > 0)) { - $this->mDateObj->parseVal($value, DB_DATEFORMAT); - $this->value = $this->mDateObj->toString($this->mDateFormat); //? + $ttDate = new ttDate($value); + $this->value = $ttDate->toString($this->mDateFormat); } } // get value for storing in session or database function getValueSafe() { if (strlen($this->value)>0) { - $this->mDateObj->parseVal($this->value, $this->mDateFormat); //? - return $this->mDateObj->toString(DB_DATEFORMAT); + $ttDate = new ttDate($this->value, $this->mDateFormat); + return $ttDate->toString(); } else { return null; } diff --git a/WEB-INF/lib/ttDate.class.php b/WEB-INF/lib/ttDate.class.php index 3b798214a..25dc4874a 100644 --- a/WEB-INF/lib/ttDate.class.php +++ b/WEB-INF/lib/ttDate.class.php @@ -5,7 +5,6 @@ import('I18n'); // ttDate class is used to represent a date in Time Tracker. -// It is a planned replacement for DateAndTime class, which is problematic with php8.1. class ttDate { var $year; // year diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 9e1827e09..3de0c94c9 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -340,11 +340,11 @@ static function loadReport(&$bean) { $bean->setAttribute('users_inactive', explode(',', $val['users'])); $bean->setAttribute('period', $val['period']); if ($val['period_start']) { - $dt = new DateAndTime(DB_DATEFORMAT, $val['period_start']); + $dt = new ttDate($val['period_start']); $bean->setAttribute('start_date', $dt->toString($user->getDateFormat())); } if ($val['period_end']) { - $dt = new DateAndTime(DB_DATEFORMAT, $val['period_end']); + $dt = new ttDate($val['period_end']); $bean->setAttribute('end_date', $dt->toString($user->getDateFormat())); } $bean->setAttribute('chclient', $val['show_client']); From 886f8979d84e84a4b67207ec512d5e794f34e455 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 15 Apr 2022 14:19:03 +0000 Subject: [PATCH 1736/1848] Fixed ttUser::getUserDetails to work on top managers in subgroups. --- WEB-INF/lib/ttUser.class.php | 2 +- initialize.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 7114bc7c6..e0565b3dd 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -603,7 +603,7 @@ function getUserDetails($user_id) { // Determine max rank. If we are searching in on behalf group // then rank restriction does not apply. - $max_rank = $this->behalfGroup ? MAX_RANK : $this->rank; + $max_rank = $this->behalfGroup ? MAX_RANK + 1 : $this->rank; $sql = "select u.id, u.name, u.login, u.role_id, u.client_id, u.status, u.rate, u.quota_percent, u.email from tt_users u". " left join tt_roles r on (u.role_id = r.id)". diff --git a/initialize.php b/initialize.php index 17750f01b..8709beede 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.5.5710"); +define("APP_VERSION", "1.21.5.5712"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From b292d803a1bd81bb82cff089e7d19e2786e7319a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 15 Apr 2022 16:02:52 +0000 Subject: [PATCH 1737/1848] Fixed browser_today population on time.php. --- WEB-INF/templates/time.tpl | 2 +- initialize.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index b04959cfc..6f6f73942 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -122,7 +122,7 @@ function handleStop(buttonElement) { {if $time_records} - +
{$i18n.label.files} + {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} + {if ($record.duration == '0:00' && $record.start <> '')} + + {/if} {$i18n.label.edit} {/if}
diff --git a/initialize.php b/initialize.php index 8709beede..b5707136e 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.5.5712"); +define("APP_VERSION", "1.21.5.5713"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From e5a3f1ce50205b3fa4b6bc1ca3570ab29e75d101 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 15 Apr 2022 18:06:47 +0000 Subject: [PATCH 1738/1848] Improved a check for browser today. --- WEB-INF/lib/common.lib.php | 16 ++++++++++++++++ expense_edit.php | 2 +- expenses.php | 2 +- initialize.php | 2 +- puncher.php | 2 +- time.php | 4 ++-- time_edit.php | 2 +- week.php | 2 +- 8 files changed, 24 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 2d8e287d5..52d82ed36 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -308,6 +308,22 @@ function ttValidDbDateFormatDate($val) return checkdate($date_parts[1], $date_parts[2], $date_parts[0]); } +// ttValidBrowserToday is used to check browser today parameter for sanity. +function ttValidBrowserToday($val) +{ + if (!ttValidDbDateFormatDate($val)) + return false; + + // Check if browser today is after server tomorrow. + $browser_today = new ttDate($val); + $server_tomorrow = new ttDate(); + $server_tomorrow->incrementDay(); + if ($browser_today->after($server_tomorrow)) + return false; + + return true; +} + // ttValidTime is used to check user input for time post. function ttValidTime($val) { diff --git a/expense_edit.php b/expense_edit.php index e57db88d9..0281c2cff 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -30,7 +30,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + if ($browser_today && !ttValidBrowserToday($browser_today)) { header('Location: access_denied.php'); exit(); } diff --git a/expenses.php b/expenses.php index 34169b7dc..b86c34d5a 100644 --- a/expenses.php +++ b/expenses.php @@ -47,7 +47,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + if ($browser_today && !ttValidBrowserToday($browser_today)) { header('Location: access_denied.php'); exit(); } diff --git a/initialize.php b/initialize.php index b5707136e..f91645a76 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.5.5713"); +define("APP_VERSION", "1.21.5.5714"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/puncher.php b/puncher.php index 2b25462d3..b959dcfbc 100644 --- a/puncher.php +++ b/puncher.php @@ -24,7 +24,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + if ($browser_today && !ttValidBrowserToday($browser_today)) { header('Location: access_denied.php'); exit(); } diff --git a/time.php b/time.php index faf064a4a..329203449 100644 --- a/time.php +++ b/time.php @@ -41,7 +41,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + if ($browser_today && !ttValidBrowserToday($browser_today)) { header('Location: access_denied.php'); exit(); } @@ -59,7 +59,7 @@ // Validate that browser_date parameter is in correct format. $browser_date = $request->getParameter('browser_date'); - if ($browser_date && !ttValidDbDateFormatDate($browser_date)) { + if ($browser_date && !ttValidBrowserToday($browser_date)) { header('Location: access_denied.php'); exit(); } diff --git a/time_edit.php b/time_edit.php index 03c721193..ad673ffe1 100644 --- a/time_edit.php +++ b/time_edit.php @@ -27,7 +27,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + if ($browser_today && !ttValidBrowserToday($browser_today)) { header('Location: access_denied.php'); exit(); } diff --git a/week.php b/week.php index 92eb95ee3..cb3a1d9f8 100644 --- a/week.php +++ b/week.php @@ -47,7 +47,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { + if ($browser_today && !ttValidBrowserToday($browser_today)) { header('Location: access_denied.php'); exit(); } From aa5adfb54c3823b3172280be5914534e98279587 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 16 Apr 2022 13:24:42 +0000 Subject: [PATCH 1739/1848] Improved handling of future entries by tolerating out of time synced browsers. --- WEB-INF/lib/common.lib.php | 16 ---------------- expense_edit.php | 6 ++++-- expenses.php | 6 ++++-- initialize.php | 2 +- puncher.php | 2 +- time.php | 8 +++++--- time_edit.php | 6 ++++-- week.php | 2 +- 8 files changed, 20 insertions(+), 28 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 52d82ed36..2d8e287d5 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -308,22 +308,6 @@ function ttValidDbDateFormatDate($val) return checkdate($date_parts[1], $date_parts[2], $date_parts[0]); } -// ttValidBrowserToday is used to check browser today parameter for sanity. -function ttValidBrowserToday($val) -{ - if (!ttValidDbDateFormatDate($val)) - return false; - - // Check if browser today is after server tomorrow. - $browser_today = new ttDate($val); - $server_tomorrow = new ttDate(); - $server_tomorrow->incrementDay(); - if ($browser_today->after($server_tomorrow)) - return false; - - return true; -} - // ttValidTime is used to check user input for time post. function ttValidTime($val) { diff --git a/expense_edit.php b/expense_edit.php index 0281c2cff..98098a19f 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -30,7 +30,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidBrowserToday($browser_today)) { + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { header('Location: access_denied.php'); exit(); } @@ -155,7 +155,9 @@ // Prohibit creating entries in future. if (!$user->isOptionEnabled('future_entries')) { $browser_today = new ttDate($request->getParameter('browser_today', null)); - if ($new_date->after($browser_today)) + $server_tomorrow = new ttDate(); + $server_tomorrow->incrementDay(); + if ($new_date->after($browser_today) || $new_date->after($server_tomorrow)) $err->add($i18n->get('error.future_date')); } if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); diff --git a/expenses.php b/expenses.php index b86c34d5a..ba091a63e 100644 --- a/expenses.php +++ b/expenses.php @@ -47,7 +47,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidBrowserToday($browser_today)) { + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { header('Location: access_denied.php'); exit(); } @@ -203,7 +203,9 @@ // Prohibit creating entries in future. if (!$user->isOptionEnabled('future_entries')) { $browser_today = new ttDate($request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) + $server_tomorrow = new ttDate(); + $server_tomorrow->incrementDay(); + if ($selected_date->after($browser_today) || $selected_date->after($server_tomorrow)) $err->add($i18n->get('error.future_date')); } // Finished validating input data. diff --git a/initialize.php b/initialize.php index f91645a76..a67bd3444 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.5.5714"); +define("APP_VERSION", "1.21.5.5715"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/puncher.php b/puncher.php index b959dcfbc..2b25462d3 100644 --- a/puncher.php +++ b/puncher.php @@ -24,7 +24,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidBrowserToday($browser_today)) { + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { header('Location: access_denied.php'); exit(); } diff --git a/time.php b/time.php index 329203449..766ee5fd1 100644 --- a/time.php +++ b/time.php @@ -41,7 +41,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidBrowserToday($browser_today)) { + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { header('Location: access_denied.php'); exit(); } @@ -59,7 +59,7 @@ // Validate that browser_date parameter is in correct format. $browser_date = $request->getParameter('browser_date'); - if ($browser_date && !ttValidBrowserToday($browser_date)) { + if ($browser_date && !ttValidDbDateFormatDate($browser_date)) { header('Location: access_denied.php'); exit(); } @@ -417,7 +417,9 @@ // Prohibit creating entries in future. if (!$user->isOptionEnabled('future_entries')) { $browser_today = new ttDate($request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) + $server_tomorrow = new ttDate(); + $server_tomorrow->incrementDay(); + if ($selected_date->after($browser_today) || $selected_date->after($server_tomorrow)) $err->add($i18n->get('error.future_date')); } diff --git a/time_edit.php b/time_edit.php index ad673ffe1..7c3491eab 100644 --- a/time_edit.php +++ b/time_edit.php @@ -27,7 +27,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidBrowserToday($browser_today)) { + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { header('Location: access_denied.php'); exit(); } @@ -332,7 +332,9 @@ // Prohibit creating entries in future. if ($err->no() && !$user->isOptionEnabled('future_entries')) { $browser_today = new ttDate($request->getParameter('browser_today', null)); - if ($new_date->after($browser_today)) + $server_tomorrow = new ttDate(); + $server_tomorrow->incrementDay(); + if ($new_date->after($browser_today) || $new_date->after($server_tomorrow)) $err->add($i18n->get('error.future_date')); } diff --git a/week.php b/week.php index cb3a1d9f8..92eb95ee3 100644 --- a/week.php +++ b/week.php @@ -47,7 +47,7 @@ if ($request->isPost()) { // Validate that browser_today parameter is in correct format. $browser_today = $request->getParameter('browser_today'); - if ($browser_today && !ttValidBrowserToday($browser_today)) { + if ($browser_today && !ttValidDbDateFormatDate($browser_today)) { header('Location: access_denied.php'); exit(); } From 855e71a0b04fdc3bc449b961c56dcaa495daec3a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 16 Apr 2022 14:31:43 +0000 Subject: [PATCH 1740/1848] Cosmetic improvement to handling of future entries. --- WEB-INF/lib/ttWeekViewHelper.class.php | 4 +++- initialize.php | 2 +- puncher.php | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index deefd8a17..9908d12b4 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -504,7 +504,9 @@ static function insertDurationFromWeekView($fields, $custom_fields, $err) { // Prohibit creating entries in future. if (!$user->isOptionEnabled('future_entries') && $fields['browser_today']) { $objBrowserToday = new ttDate($fields['browser_today']); - if ($objEntryDate->after($objBrowserToday)) { + $server_tomorrow = new ttDate(); + $server_tomorrow->incrementDay(); + if ($objEntryDate->after($objBrowserToday) || $objEntryDate->after($server_tomorrow)) { $err->add($i18n->get('error.future_date')); return false; } diff --git a/initialize.php b/initialize.php index a67bd3444..3a99f5184 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.5.5715"); +define("APP_VERSION", "1.21.5.5716"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/puncher.php b/puncher.php index 2b25462d3..9714ac242 100644 --- a/puncher.php +++ b/puncher.php @@ -235,9 +235,9 @@ } // Finished validating user input. - // Prohibit creating entries in future. Tricky with a bogus browser_today data in post. + // Prohibit creating entries in future. if (!$user->isOptionEnabled('future_entries')) { - // Just check if the date we are using is after server tomorrow. + // $date_today is already browser_today, just check if the date we are using is after server tomorrow. $server_tomorrow = new ttDate(); $server_tomorrow->incrementDay(); if ($date_today->after($server_tomorrow)) From 38797d661ba091cc7fbb8f92e2a9dc4ef94f8750 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 19 Apr 2022 15:55:49 +0000 Subject: [PATCH 1741/1848] Introduced an option defining whether or not to show weekends on week view. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/week_view.tpl | 9 +++++++++ initialize.php | 2 +- week.php | 27 ++++++++++++++++++++++++++- week_view.php | 4 ++++ 34 files changed, 74 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 7964ede5e..1326d15aa 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -243,6 +243,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Només totals', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 5b930374b..d65c6dab3 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -252,6 +252,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Pouze součty', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 9c4d6c216..3fba73805 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -236,6 +236,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Kun Total', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 2cf17c453..fe4874640 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -228,6 +228,8 @@ 'label.mark_paid' => 'Als bezahlt setzen', 'label.week_note' => 'Wochennotiz', 'label.week_list' => 'Wochenliste', +// TODO: translate the following: +// 'label.weekends' => 'Weekends', 'label.work_units' => 'Arbeitseinheiten', 'label.work_units_short' => 'Einheiten', 'label.totals_only' => 'Nur Gesamtstunden', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index bffac8f7b..5b433b0a6 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -214,6 +214,7 @@ 'label.mark_paid' => 'Mark paid', 'label.week_note' => 'Week note', 'label.week_list' => 'Week list', +'label.weekends' => 'Weekends', 'label.work_units' => 'Work units', 'label.work_units_short' => 'Units', 'label.totals_only' => 'Totals only', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 3d16d8e27..f57f5795e 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -246,6 +246,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Solo totales', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 849eff788..57b92ff3c 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -244,6 +244,8 @@ 'label.mark_paid' => 'Märgi makstuks', 'label.week_note' => 'Nädala märge', 'label.week_list' => 'Nädala nimekiri', +// TODO: translate the following: +// 'label.weekends' => 'Weekends', 'label.work_units' => 'Töö ühikud', 'label.work_units_short' => 'Ühikud', 'label.totals_only' => 'Ainult summad', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index bdddffa4c..62b70671d 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -248,6 +248,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 074ee794b..fa1dd9739 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -240,6 +240,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Vain yhteissummat', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 548d6e0ce..7472ddf62 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -234,6 +234,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Totaux uniquement', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 4de8f91d2..93fb5fba5 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -229,6 +229,7 @@ 'label.week_note' => 'Σημείωση εβδομάδας', 'label.week_list' => 'Λίστα εβδομάδων', // TODO: translate the following. +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Σύνολα μόνο', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 6abbd474e..388622c2a 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -255,6 +255,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'labl.totals_only' => 'סיכומים בלבד', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index b90ffdc56..635147d8c 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -249,6 +249,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 34ca37457..55ea5deb4 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -233,6 +233,7 @@ 'label.week_note' => 'Nota settimanale', 'label.week_list' => 'Lista settimanale', // TODO: translate the following. +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Solo i totali', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 8794e2edd..0cf547754 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -252,6 +252,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => '全体だけ', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 69f6fd6ce..426484617 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -252,6 +252,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => '오직 전체만', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 012f9d148..eacfd5a17 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -209,6 +209,8 @@ 'label.mark_paid' => 'Markeer als betaald', 'label.week_note' => 'Week aantekening', 'label.week_list' => 'Week overzicht', +// TODO: translate the following. +// 'label.weekends' => 'Weekends', 'label.work_units' => 'Werk eenheid', 'label.work_units_short' => 'Eenheid', 'label.totals_only' => 'Alleen totalen', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 9ffef3209..dd92cc788 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -252,6 +252,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 430416f5b..50ac9c62d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -241,6 +241,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Tylko sumy', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index d156ccda8..0b250d69c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -211,6 +211,8 @@ 'label.mark_paid' => 'Marcar como pago', 'label.week_note' => 'Anotação da semana', 'label.week_list' => 'Lista da semana', +// TODO: translate the following. +// 'label.weekends' => 'Weekends', 'label.work_units' => 'Unidades de trabalho', 'label.work_units_short' => 'Unidades', 'label.totals_only' => 'Somente totais', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 4277ff18f..e7b16d92a 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -238,6 +238,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 755e2c470..b160169d4 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -250,6 +250,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Numai totaluri', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 61777ff47..f24aa6f7a 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -209,6 +209,7 @@ 'label.mark_paid' => 'Отметить оплату', 'label.week_note' => 'Комментарий недели', 'label.week_list' => 'Список недели', +'label.weekends' => 'Выходные', 'label.work_units' => 'Единицы работы', 'label.work_units_short' => 'Единицы', 'label.totals_only' => 'Только итоги', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index fb8fae3e4..ca4f0535a 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -244,6 +244,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Iba celkové', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 02e79b401..574c32f09 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -234,6 +234,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 3917fc0a1..068678867 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -240,6 +240,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', 'label.totals_only' => 'Samo zbirno', // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index c638d213b..9f5725b86 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -235,6 +235,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Visa endast summeringar', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index c55b901e5..f8fa7dd2b 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -257,6 +257,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', 'label.totals_only' => 'Sadece toplamlar', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 2550f7589..ca1709d3b 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -245,6 +245,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 08928decc..c59a87efe 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -250,6 +250,7 @@ // 'label.mark_paid' => 'Mark paid', // 'label.week_note' => 'Week note', // 'label.week_list' => 'Week list', +// 'label.weekends' => 'Weekends', // 'label.work_units' => 'Work units', // 'label.work_units_short' => 'Units', // 'label.totals_only' => 'Totals only', diff --git a/WEB-INF/templates/week_view.tpl b/WEB-INF/templates/week_view.tpl index 3226e0c44..00e6cd1d4 100644 --- a/WEB-INF/templates/week_view.tpl +++ b/WEB-INF/templates/week_view.tpl @@ -39,6 +39,15 @@ License: See license.txt *} + + + + + +
{$forms.weekViewForm.weekends.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$forms.weekViewForm.btn_save.control}
{$forms.weekViewForm.close} diff --git a/initialize.php b/initialize.php index 3a99f5184..7b2064ad4 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.5.5716"); +define("APP_VERSION", "1.21.6.5717"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/week.php b/week.php index 92eb95ee3..302e4dfb3 100644 --- a/week.php +++ b/week.php @@ -73,6 +73,7 @@ if ($showTask) $taskRequired = $user->getConfigOption('task_required'); $showWeekNote = $user->isOptionEnabled('week_note'); $showWeekNotes = $user->isOptionEnabled('week_notes'); +$showWeekends = $user->isOptionEnabled('weekends'); $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showFiles = $user->isPluginEnabled('at'); @@ -158,6 +159,22 @@ // Get column headers, which are day numbers in month. $dayHeaders = ttWeekViewHelper::getDayHeadersForWeek($startDate->toString()); $lockedDays = ttWeekViewHelper::getLockedDaysForWeek($startDate->toString()); +// If we are not showing weekends, reduce the above arrays to 5 days only. +$weekend_start_idx = $weekend_end_idx = 0; +if (!$showWeekends) { + if (defined('WEEKEND_START_DAY')) { + $weekend_start_idx = (7 + WEEKEND_START_DAY - $weekStartDay) % 7; + $weekend_end_idx = (7 + WEEKEND_START_DAY + 1 - $weekStartDay) % 7; + } else { + $weekend_start_idx = 6 - $weekStartDay; + $weekend_end_idx = (7 - $weekStartDay) % 7; + } + unset($dayHeaders[$weekend_start_idx]); + unset($dayHeaders[$weekend_end_idx]); + unset($lockedDays[$weekend_start_idx]); + unset($lockedDays[$weekend_end_idx]); +} + // Get already existing records. $records = ttWeekViewHelper::getRecordsForInterval($startDate->toString(), $endDate->toString(), $showFiles); // Build data array for the table. Format is described in ttWeekViewHelper::getDataForWeekView function. @@ -273,8 +290,16 @@ function render(&$table, $value, $row, $column, $selected = false) { $table->setData($dataArray); // Add columns to table. $table->addColumn(new TableColumn('label', '', new LabelCellRenderer(), $dayTotals['label'])); + + + for ($i = 0; $i < 7; $i++) { - $table->addColumn(new TableColumn($dayHeaders[$i], $dayHeaders[$i], new WeekViewCellRenderer(), $dayTotals[$dayHeaders[$i]])); + if ($showWeekends) + $table->addColumn(new TableColumn($dayHeaders[$i], $dayHeaders[$i], new WeekViewCellRenderer(), $dayTotals[$dayHeaders[$i]])); + else { + if ($i <> $weekend_start_idx && $i <> $weekend_end_idx) + $table->addColumn(new TableColumn($dayHeaders[$i], $dayHeaders[$i], new WeekViewCellRenderer(), $dayTotals[$dayHeaders[$i]])); + } } $table->setInteractive(false); $form->addInputElement($table); diff --git a/week_view.php b/week_view.php index 1718afd4b..7db10226a 100644 --- a/week_view.php +++ b/week_view.php @@ -18,11 +18,13 @@ $cl_week_note = (bool)$request->getParameter('week_note'); $cl_week_list = (bool)$request->getParameter('week_list'); $cl_notes = (bool)$request->getParameter('notes'); + $cl_weekends = (bool)$request->getParameter('weekends'); } else { $cl_week_menu = $config->getDefinedValue('week_menu'); $cl_week_note = $config->getDefinedValue('week_note'); $cl_week_list = $config->getDefinedValue('week_list'); $cl_notes = $config->getDefinedValue('week_notes'); + $cl_weekends = $config->getDefinedValue('weekends'); } $form = new Form('weekViewForm'); @@ -30,6 +32,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'week_note','value'=>$cl_week_note)); $form->addInput(array('type'=>'checkbox','name'=>'week_list','value'=>$cl_week_list)); $form->addInput(array('type'=>'checkbox','name'=>'notes','value'=>$cl_notes)); +$form->addInput(array('type'=>'checkbox','name'=>'weekends','value'=>$cl_weekends)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()){ @@ -38,6 +41,7 @@ $config->setDefinedValue('week_note', $cl_week_note); $config->setDefinedValue('week_list', $cl_week_list); $config->setDefinedValue('week_notes', $cl_notes); + $config->setDefinedValue('weekends', $cl_weekends); if (!$user->updateGroup(array('config' => $config->getConfig()))) { $err->add($i18n->get('error.db')); } From f3ecd48c47df8af907cb46dec59cdd62793535e6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 19 Apr 2022 16:00:27 +0000 Subject: [PATCH 1742/1848] Fixed label in html. --- WEB-INF/templates/week_view.tpl | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/week_view.tpl b/WEB-INF/templates/week_view.tpl index 00e6cd1d4..9cd7b90a2 100644 --- a/WEB-INF/templates/week_view.tpl +++ b/WEB-INF/templates/week_view.tpl @@ -39,9 +39,9 @@ License: See license.txt *}
{$forms.weekViewForm.weekends.control} {$i18n.label.what_is_it} {$i18n.label.what_is_it} diff --git a/initialize.php b/initialize.php index 7b2064ad4..89c734ad6 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.6.5717"); +define("APP_VERSION", "1.21.6.5718"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From dcfeafbc71bb9e1329f997bfc7e7b42050174453 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 26 Apr 2022 15:52:14 +0000 Subject: [PATCH 1743/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 3 +-- initialize.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index eacfd5a17..949a3ac83 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -209,8 +209,7 @@ 'label.mark_paid' => 'Markeer als betaald', 'label.week_note' => 'Week aantekening', 'label.week_list' => 'Week overzicht', -// TODO: translate the following. -// 'label.weekends' => 'Weekends', +'label.weekends' => 'Weekeinden', 'label.work_units' => 'Werk eenheid', 'label.work_units_short' => 'Eenheid', 'label.totals_only' => 'Alleen totalen', diff --git a/initialize.php b/initialize.php index 89c734ad6..53810201d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.6.5718"); +define("APP_VERSION", "1.21.6.5719"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 761d451e6382b59fd96f133b5c9dc9cca3ccb753 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 30 Jun 2022 14:00:35 +0000 Subject: [PATCH 1744/1848] Starting to work on filtering by notes in reports. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/reports.tpl | 8 ++++++++ reports.php | 5 +++++ 32 files changed, 69 insertions(+) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 1326d15aa..f2eec1b5a 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -474,6 +474,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Seleccionar període de temps', 'form.reports.set_period' => 'o establir dates', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Mostrar camps', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d65c6dab3..8573d71c2 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -482,6 +482,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Výberte období', 'form.reports.set_period' => 'nebo určete dny', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Zobrazit pole', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 3fba73805..dd1abd396 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -459,6 +459,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Vælg en periode', 'form.reports.set_period' => 'eller sæt datoer', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Vis felter', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index fe4874640..e295e7281 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -442,6 +442,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Zeitraum auswählen', 'form.reports.set_period' => 'oder Datum eingeben', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Felder anzeigen', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 5b433b0a6..5df99c403 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -425,6 +425,7 @@ 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Select time period', 'form.reports.set_period' => 'or set dates', +'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Show fields', 'form.reports.time_fields' => 'Time fields', 'form.reports.user_fields' => 'User fields', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index f57f5795e..7c59d3ae5 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -487,6 +487,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Seleccionar período de tiempo', 'form.reports.set_period' => 'o establecer fechas', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Mostrar campos', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 57b92ff3c..7a53024b7 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -472,6 +472,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Vali ajaperiood', 'form.reports.set_period' => 'või märgi kuupäevad', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Näita välju', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 62b70671d..2963414ee 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -480,6 +480,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'انتخاب بازه زمانی', 'form.reports.set_period' => 'یا تعیین تاریخ', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'نمایش فیلدها', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index fa1dd9739..112dc6b6a 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -465,6 +465,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Valitse ajanjakso', 'form.reports.set_period' => 'tai aseta päivät', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Näytä kentät', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 7472ddf62..a1268d1a7 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -456,6 +456,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Sélectionner la période de temps', 'form.reports.set_period' => 'ou dates indiquées', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Afficher les champs', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 93fb5fba5..9f1bf5d93 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -451,6 +451,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Επιλογή χρονικής περιόδου', 'form.reports.set_period' => 'ή εύρος ημερομηνιών', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Εμφάνιση πεδίων', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 388622c2a..3167fd8d9 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -483,6 +483,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'בחר תקופת זמן', 'form.reports.set_period' => 'או הגדר תאריכים', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'הראה שדות', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 635147d8c..636c29d07 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -478,6 +478,7 @@ 'form.reports.select_period' => 'Jelölj meg egy időszakot', 'form.reports.set_period' => 'vagy állíts be konkrét dátumot', // TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', // 'form.reports.show_fields' => 'Show fields', // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 55ea5deb4..d517fdede 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -464,6 +464,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Seleziona il periodo di tempo', 'form.reports.set_period' => 'oppure setta le date', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Mostra i campi', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 0cf547754..59500e015 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -482,6 +482,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => '時間期間の選択', 'form.reports.set_period' => 'あるいは日付を設定', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'フィールドの表示', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 426484617..e2f16ccec 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -480,6 +480,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => '시간 기간을 선택', 'form.reports.set_period' => '혹은 날짜를 설정', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => '필드들을 보기', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 949a3ac83..9f846bc5f 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -411,6 +411,8 @@ 'form.reports.include_pending' => 'in afwachting', 'form.reports.select_period' => 'Kies periode', 'form.reports.set_period' => 'of stel datums in', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Toon velden', 'form.reports.time_fields' => 'Tijd velden', 'form.reports.user_fields' => 'Medewerker velden', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index dd92cc788..cba06a82f 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -482,6 +482,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Velg tidsperiode', 'form.reports.set_period' => 'eller sett dato', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Vis feltene', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 50ac9c62d..3470add1b 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -467,6 +467,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Wybierz okres', 'form.reports.set_period' => 'lub ustaw daty', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Pokaż pola', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 0b250d69c..60d505762 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -414,6 +414,8 @@ 'form.reports.include_pending' => 'pendente', 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Exibir campos', 'form.reports.time_fields' => 'Campos de tempo', 'form.reports.user_fields' => 'Campos de usuário', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index e7b16d92a..d5a4413a2 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -459,6 +459,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Exibir campos', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index b160169d4..f450bfd4e 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -482,6 +482,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Alege perioada', 'form.reports.set_period' => 'sau introdu intervalul de date', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Arata campuri', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index f24aa6f7a..47f87d496 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -412,6 +412,7 @@ 'form.reports.include_pending' => 'в ожидании', 'form.reports.select_period' => 'Выберите интервал времени', 'form.reports.set_period' => 'или укажите даты', +'form.reports.note_containing' => 'Комментарий содержит', 'form.reports.show_fields' => 'Показывать поля', 'form.reports.time_fields' => 'Поля времени', 'form.reports.user_fields' => 'Поля пользователя', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index ca4f0535a..1909ec9d1 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -470,6 +470,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Vyberte časový rozsah', 'form.reports.set_period' => 'alebo nastavte dátumy', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Zobraziť polia', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 574c32f09..304da23a0 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -456,6 +456,7 @@ // 'form.reports.include_pending' => 'pending', // 'form.reports.select_period' => 'Select time period', // 'form.reports.set_period' => 'or set dates', +// 'form.reports.note_containing' => 'Note containing', // 'form.reports.show_fields' => 'Show fields', // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 068678867..d1fb802e8 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -467,6 +467,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Odaberi vremenski raspon', 'form.reports.set_period' => 'ili podesi datum', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Prikaži polja u izveštaju', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 9f5725b86..1df983ecc 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -465,6 +465,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Välj intervall', 'form.reports.set_period' => 'eller ställ in datum', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Visa fält', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index f8fa7dd2b..c6fe800a6 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -493,6 +493,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => 'Zaman aralığını seç', 'form.reports.set_period' => 'ya da tarihleri belirle', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => 'Alanları göster', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index ca1709d3b..5b701c851 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -471,6 +471,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => '选择时间段', 'form.reports.set_period' => '或设定日期', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => '显示栏目', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index c59a87efe..14ef3c269 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -474,6 +474,8 @@ // 'form.reports.include_pending' => 'pending', 'form.reports.select_period' => '選擇時間段', 'form.reports.set_period' => '或設定日期', +// TODO: translate the following. +// 'form.reports.note_containing' => 'Note containing', 'form.reports.show_fields' => '顯示欄目', // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index aa8e9d633..d2dfcb475 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -358,6 +358,14 @@ License: See license.txt *}
{$forms.reportForm.notes_containing.control}
diff --git a/reports.php b/reports.php index 858ca61cb..8cf3736b1 100644 --- a/reports.php +++ b/reports.php @@ -239,6 +239,11 @@ $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start_date')); $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'end_date')); +// Add control for notes containing. +if (isTrue('FILTER_BY_NOTES_DEBUG')) { + $form->addInput(array('type'=>'text','maxlength'=>'256','name'=>'notes_containing')); +} + // Add checkboxes for "Show fields" block. if ($showClient) $form->addInput(array('type'=>'checkbox','name'=>'chclient')); From a18e57436cb9170c22c6de7128053113913e289e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 6 Jul 2022 19:19:56 +0000 Subject: [PATCH 1745/1848] Initial implementation of report filter by notes. --- WEB-INF/lib/ttFavReportHelper.class.php | 7 +++++-- WEB-INF/lib/ttReportHelper.class.php | 17 +++++++++++++++-- WEB-INF/templates/reports.tpl | 6 +++--- dbinstall.php | 9 +++++---- initialize.php | 2 +- mysql.sql | 3 ++- reports.php | 2 +- 7 files changed, 32 insertions(+), 14 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 3de0c94c9..df756649e 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -98,7 +98,7 @@ static function insertReport($fields) { $sql = "insert into tt_fav_reports". " (name, user_id, group_id, org_id, report_spec, client_id, project_id, task_id,". - " billable, approved, invoice, timesheet, paid_status, users, period, period_start,". + " billable, approved, invoice, timesheet, paid_status, note_containing, users, period, period_start,". " period_end, show_client, show_invoice, show_paid, show_ip,". " show_project, show_timesheet, show_start, show_duration, show_cost,". " show_task, show_end, show_note, show_approved, show_work_units,". @@ -110,7 +110,7 @@ static function insertReport($fields) { $mdb2->quote($fields['project']).", ".$mdb2->quote($fields['task']).", ". $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['approved']).", ". $mdb2->quote($fields['invoice']).", ".$mdb2->quote($fields['timesheet']).", ". - $mdb2->quote($fields['paid_status']).", ". + $mdb2->quote($fields['paid_status']).", ".$mdb2->quote($fields['note_containing']).",". $mdb2->quote($fields['users']).", ".$mdb2->quote($fields['period']).", ". $mdb2->quote($fields['from']).", ".$mdb2->quote($fields['to']).", ". $fields['chclient'].", ".$fields['chinvoice'].", ".$fields['chpaid'].", ".$fields['chip'].", ". @@ -146,6 +146,7 @@ static function updateReport($fields) { "invoice = ".$mdb2->quote($fields['invoice']).", ". "timesheet = ".$mdb2->quote($fields['timesheet']).", ". "paid_status = ".$mdb2->quote($fields['paid_status']).", ". + "note_containing = ".$mdb2->quote($fields['note_containing']).", ". "users = ".$mdb2->quote($fields['users']).", ". "period = ".$mdb2->quote($fields['period']).", ". "period_start = ".$mdb2->quote($fields['from']).", ". @@ -233,6 +234,7 @@ static function saveReport($bean) { 'paid_status'=>$bean->getAttribute('paid_status'), 'invoice'=>$bean->getAttribute('invoice'), 'timesheet'=>$bean->getAttribute('timesheet'), + 'note_containing'=>$bean->getAttribute('note_containing'), 'users'=>$users, 'period'=>$bean->getAttribute('period'), 'from'=>$from, @@ -336,6 +338,7 @@ static function loadReport(&$bean) { $bean->setAttribute('invoice', $val['invoice']); $bean->setAttribute('paid_status', $val['paid_status']); $bean->setAttribute('timesheet', $val['timesheet']); + $bean->setAttribute('note_containing', $val['note_containing']); $bean->setAttribute('users_active', explode(',', $val['users'])); $bean->setAttribute('users_inactive', explode(',', $val['users'])); $bean->setAttribute('period', $val['period']); diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 693fe6521..45b6ec1b6 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -116,6 +116,12 @@ static function getWhere($options) { $user_list_part = " and l.user_id = ".$user->getUser(); $user_list_part .= " and l.group_id = $group_id and l.org_id = $org_id"; + // Prepare part for note_containing using LIKE operator. + $note_containing_part = ''; + if (isset($options['note_containing']) && !empty($options['note_containing'])) { + $note_containing_part = " and l.comment like ".$mdb2->quote('%'.$options['note_containing'].'%'); + } + // Prepare sql query part for where. $dateFormat = $user->getDateFormat(); if (isset($options['period']) && $options['period']) @@ -127,7 +133,7 @@ static function getWhere($options) { new ttDate($options['period_end'], $dateFormat)); } $where = " where l.status = 1 and l.date >= '".$period->getStartDate()."' and l.date <= '".$period->getEndDate()."'". - " $user_list_part $dropdown_parts $cf_text_parts"; + $user_list_part.$dropdown_parts.$cf_text_parts.$note_containing_part; return $where; } @@ -198,6 +204,12 @@ static function getExpenseWhere($options) { $user_list_part = " and ei.user_id = ".$user->getUser(); $user_list_part .= " and ei.group_id = $group_id and ei.org_id = $org_id"; + // Prepare part for note_containing using LIKE operator. + $note_containing_part = ''; + if (isset($options['note_containing']) && !empty($options['note_containing'])) { + $note_containing_part = " and ei.name like ".$mdb2->quote('%'.$options['note_containing'].'%'); + } + // Prepare sql query part for where. $dateFormat = $user->getDateFormat(); if (isset($options['period']) && $options['period']) @@ -209,7 +221,7 @@ static function getExpenseWhere($options) { new ttDate($options['period_end'], $dateFormat)); } $where = " where ei.status = 1 and ei.date >= '".$period->getStartDate()."' and ei.date <= '".$period->getEndDate()."'". - " $user_list_part $dropdown_parts $cf_text_parts"; + $user_list_part.$dropdown_parts.$cf_text_parts.$note_containing_part; return $where; } @@ -1541,6 +1553,7 @@ static function getReportOptions($bean) { $options['period'] = $bean->getAttribute('period'); $options['period_start'] = $bean->getAttribute('start_date'); $options['period_end'] = $bean->getAttribute('end_date'); + $options['note_containing'] = $bean->getAttribute('note_containing'); $options['show_client'] = $bean->getAttribute('chclient'); $options['show_invoice'] = $bean->getAttribute('chinvoice'); $options['show_approved'] = $bean->getAttribute('chapproved'); diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index d2dfcb475..3edec9d82 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -359,10 +359,10 @@ License: See license.txt *} {/if} {if isTrue('FILTER_BY_NOTES_DEBUG')} - + - - + + {/if} diff --git a/dbinstall.php b/dbinstall.php index f8e1b9362..bc0db6a0d 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1151,7 +1151,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to12102"]) { + if ($_POST["convert11900to12107"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1197,6 +1197,7 @@ function ttGenerateKeys() { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.21.0') set rights = replace(rights, ',manage_work', '')"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.21.0') set rights = replace(rights, ',update_work', '')"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.21.2', modified = now() where param_name = 'version_db' and param_value = '1.21.0'"); + ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `note_containing` varchar(80) default NULL after `paid_status`"); } if ($_POST["cleanup"]) { @@ -1247,7 +1248,7 @@ function ttGenerateKeys() {

DB Install

{$forms.reportForm.notes_containing.control}{$forms.reportForm.note_containing.control}
-
Create database structure (v1.21.2) + Create database structure (v1.21.7)
(applies only to new installations, do not execute when updating)
@@ -1296,8 +1297,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.21.2)Update database structure (v1.19 to v1.21.7)
diff --git a/initialize.php b/initialize.php index 53810201d..7ab839782 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.6.5719"); +define("APP_VERSION", "1.21.7.5720"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mysql.sql b/mysql.sql index 0856f94a0..4fd33fa95 100644 --- a/mysql.sql +++ b/mysql.sql @@ -273,6 +273,7 @@ CREATE TABLE `tt_fav_reports` ( `invoice` tinyint(4) default NULL, # whether to include invoiced, not invoiced, or all records `timesheet` tinyint(4) default NULL, # include records with a specific timesheet status, or all records `paid_status` tinyint(4) default NULL, # whether to include paid, not paid, or all records + `note_containing` varchar(80) default NULL, # include only records with notes containing this text `users` text default NULL, # Comma-separated list of user ids. Nothing here means "all" users. `period` tinyint(4) default NULL, # selected period type for report `period_start` date default NULL, # period start @@ -621,4 +622,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.21.2', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.21.7', now()); # TODO: change when structure changes. diff --git a/reports.php b/reports.php index 8cf3736b1..0dbc79a8d 100644 --- a/reports.php +++ b/reports.php @@ -241,7 +241,7 @@ // Add control for notes containing. if (isTrue('FILTER_BY_NOTES_DEBUG')) { - $form->addInput(array('type'=>'text','maxlength'=>'256','name'=>'notes_containing')); + $form->addInput(array('type'=>'text','maxlength'=>'80','name'=>'note_containing')); } // Add checkboxes for "Show fields" block. From d50ff284a5dcb55e3fd276f5499ef05a700a41a7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Jul 2022 15:56:44 +0000 Subject: [PATCH 1746/1848] Removed FILTER_BY_NOTES_DEBUG condition. --- WEB-INF/templates/reports.tpl | 2 -- dbinstall.php | 1 + initialize.php | 2 +- reports.php | 4 +--- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 3edec9d82..51c98212c 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -358,14 +358,12 @@ License: See license.txt *}
{$forms.reportForm.note_containing.control}
diff --git a/dbinstall.php b/dbinstall.php index bc0db6a0d..85d3f021a 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1198,6 +1198,7 @@ function ttGenerateKeys() { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.21.0') set rights = replace(rights, ',update_work', '')"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.21.2', modified = now() where param_name = 'version_db' and param_value = '1.21.0'"); ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `note_containing` varchar(80) default NULL after `paid_status`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.21.7', modified = now() where param_name = 'version_db' and param_value = '1.21.2'"); } if ($_POST["cleanup"]) { diff --git a/initialize.php b/initialize.php index 7ab839782..0eb176f01 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.7.5720"); +define("APP_VERSION", "1.21.7.5721"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports.php b/reports.php index 0dbc79a8d..65aba65d9 100644 --- a/reports.php +++ b/reports.php @@ -240,9 +240,7 @@ $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'end_date')); // Add control for notes containing. -if (isTrue('FILTER_BY_NOTES_DEBUG')) { - $form->addInput(array('type'=>'text','maxlength'=>'80','name'=>'note_containing')); -} +$form->addInput(array('type'=>'text','maxlength'=>'80','name'=>'note_containing')); // Add checkboxes for "Show fields" block. if ($showClient) From 01bb80be971ad6c7d685c88c9da0150060eb4ff0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 8 Jul 2022 16:11:18 +0000 Subject: [PATCH 1747/1848] Fixed export / import for note_containing in fav reports. --- WEB-INF/lib/ttGroupExportHelper.class.php | 1 + WEB-INF/lib/ttOrgExportHelper.class.php | 28 ++--------------------- WEB-INF/lib/ttOrgImportHelper.class.php | 5 ++-- initialize.php | 2 +- 4 files changed, 7 insertions(+), 29 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index a464f2e25..b7b6491e5 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -566,6 +566,7 @@ function writeData() { $fav_report_part .= " invoice=\"".$fav_report['invoice']."\""; $fav_report_part .= " timesheet=\"".$fav_report['timesheet']."\""; $fav_report_part .= " paid_status=\"".$fav_report['paid_status']."\""; + $fav_report_part .= " note_containing=\"".$fav_report['note_containing']."\""; $fav_report_part .= " users=\"".$user_list."\""; $fav_report_part .= " period=\"".$fav_report['period']."\""; $fav_report_part .= " period_start=\"".$fav_report['period_start']."\""; diff --git a/WEB-INF/lib/ttOrgExportHelper.class.php b/WEB-INF/lib/ttOrgExportHelper.class.php index 277eac3ab..9380231e4 100644 --- a/WEB-INF/lib/ttOrgExportHelper.class.php +++ b/WEB-INF/lib/ttOrgExportHelper.class.php @@ -1,30 +1,6 @@ $attrs['INVOICE'], 'timesheet' => $attrs['TIMESHEET'], 'paid_status' => $attrs['PAID_STATUS'], + 'note_containing' => $attrs['NOTE_CONTAINING'], 'users' => $user_list, 'period' => $attrs['PERIOD'], 'from' => $attrs['PERIOD_START'], @@ -1049,7 +1050,7 @@ private function insertFavReport($fields) { $sql = "insert into tt_fav_reports". " (name, user_id, group_id, org_id, report_spec, client_id, project_id, task_id,". - " billable, approved, invoice, timesheet, paid_status, users, period, period_start, period_end,". + " billable, approved, invoice, timesheet, paid_status, note_containing, users, period, period_start, period_end,". " show_client, show_invoice, show_paid, show_ip,". " show_project, show_timesheet, show_start, show_duration, show_cost,". " show_task, show_end, show_note, show_approved, show_work_units,". @@ -1060,7 +1061,7 @@ private function insertFavReport($fields) { $mdb2->quote($fields['project']).", ".$mdb2->quote($fields['task']).", ". $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['approved']).", ". $mdb2->quote($fields['invoice']).", ".$mdb2->quote($fields['timesheet']).", ". - $mdb2->quote($fields['paid_status']).", ". + $mdb2->quote($fields['paid_status']).", ".$mdb2->quote($fields['note_containing']).", ". $mdb2->quote($fields['users']).", ".$mdb2->quote($fields['period']).", ". $mdb2->quote($fields['from']).", ".$mdb2->quote($fields['to']).", ". $fields['chclient'].", ".$fields['chinvoice'].", ".$fields['chpaid'].", ".$fields['chip'].", ". diff --git a/initialize.php b/initialize.php index 0eb176f01..183c62f99 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.7.5721"); +define("APP_VERSION", "1.21.7.5722"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 821535bfa70fae447bede1c617e375458dd31751 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 19 Aug 2022 13:45:10 +0000 Subject: [PATCH 1748/1848] Resolved a few compatibility issues with php8. --- WEB-INF/lib/ttOrgImportHelper.class.php | 6 ++++-- initialize.php | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 61ed9ec78..92ba6276f 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -167,6 +167,7 @@ function startElement($parser, $name, $attrs) { // We get here when processing tags for the current group. // Prepare a list of task ids. + $mapped_tasks = null; if ($attrs['TASKS']) { $tasks = explode(',', $attrs['TASKS']); foreach ($tasks as $id) @@ -193,6 +194,7 @@ function startElement($parser, $name, $attrs) { // We get here when processing tags for the current group. // Prepare a list of project ids. + $mapped_projects = array(); if ($attrs['PROJECTS']) { $projects = explode(',', $attrs['PROJECTS']); foreach ($projects as $id) @@ -218,7 +220,6 @@ function startElement($parser, $name, $attrs) { if ($name == 'USER') { // We get here when processing tags for the current group. - $role_id = $attrs['ROLE_ID'] === '0' ? $this->top_role_id : $this->currentGroupRoleMap[$attrs['ROLE_ID']]; // 0 (not null) means top manager role. $user_id = $this->insertUser(array( @@ -899,7 +900,7 @@ private function insertProject($fields) $org_id = (int) $fields['org_id']; $name = $fields['name']; $description = $fields['description']; - $tasks = $fields['tasks']; + $tasks = isset($fields['tasks']) ? $fields['tasks'] : array(); $comma_separated = implode(',', $tasks); // This is a comma-separated list of associated task ids. $status = $fields['status']; @@ -1014,6 +1015,7 @@ private function insertClient($fields) $address = $fields['address']; $tax = $fields['tax']; $projects = $fields['projects']; + $comma_separated = null; if ($projects) $comma_separated = implode(',', $projects); // This is a comma-separated list of associated projects ids. $status = $fields['status']; diff --git a/initialize.php b/initialize.php index 183c62f99..f16a12b24 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.7.5722"); +define("APP_VERSION", "1.21.8.5723"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 8392a26f00e6303095a2ff06680f054ea4fb431f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 20 Aug 2022 14:22:15 +0000 Subject: [PATCH 1749/1848] Fixed a bug in export-import. --- WEB-INF/lib/ttGroupExportHelper.class.php | 1 + WEB-INF/lib/ttOrgImportHelper.class.php | 8 +++++--- initialize.php | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index b7b6491e5..fb0f60025 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -424,6 +424,7 @@ function writeData() { $custom_field_option_part = $this->indentation.' '."customFieldOptionMap[$option['id']]."\""; $custom_field_option_part .= " field_id=\"".$this->customFieldMap[$option['field_id']]."\""; $custom_field_option_part .= " value=\"".htmlspecialchars($option['value'])."\""; + $custom_field_option_part .= " status=\"".$option['status']."\""; $custom_field_option_part .= ">\n"; fwrite($this->file, $custom_field_option_part); } diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 92ba6276f..aae3267c9 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -349,7 +349,8 @@ function startElement($parser, $name, $attrs) { 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, 'field_id' => $this->currentGroupCustomFieldMap[$attrs['FIELD_ID']], - 'value' => $attrs['VALUE'])); + 'value' => $attrs['VALUE'], + 'status' => $attrs['STATUS'])); if ($custom_field_option_id) { // Add a mapping. $this->currentGroupCustomFieldOptionMap[$attrs['ID']] = $custom_field_option_id; @@ -1153,9 +1154,10 @@ private function insertCustomFieldOption($fields) { $org_id = (int) $fields['org_id']; $field_id = (int) $fields['field_id']; $value = $fields['value']; + $status = $fields['status']; - $sql = "insert into tt_custom_field_options (group_id, org_id, field_id, value)". - " values ($group_id, $org_id, $field_id, ".$mdb2->quote($value).")"; + $sql = "insert into tt_custom_field_options (group_id, org_id, field_id, value, status)". + " values ($group_id, $org_id, $field_id, ".$mdb2->quote($value).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/initialize.php b/initialize.php index f16a12b24..073178888 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.8.5723"); +define("APP_VERSION", "1.21.9.5724"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From a3ec5e331f92641bb774b6f0310303d3043023be Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 16 Sep 2022 13:02:36 +0000 Subject: [PATCH 1750/1848] Fixed a JavaScript error condition (issue #128). --- WEB-INF/templates/user_edit.tpl | 6 +++++- initialize.php | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index 744e8c40e..e4d916a5c 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -57,7 +57,11 @@ function setRate(element) { // handleClientRole - manages visibility and content of controls related to client role, // also hides and unselects projects when client role is selected. function handleClientRole() { - var selectedRoleId = document.getElementById("role").value; + var roleControl = document.getElementById("role"); + if (roleControl == null) { + return; // Role control not available, nothing to do... + } + var selectedRoleId = roleControl.value; var clientControl = document.getElementById("client"); var clientBlock = document.getElementById("client_block"); var nonClientBlock = document.getElementById("non_client_block"); diff --git a/initialize.php b/initialize.php index 073178888..c5cb7fe3d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.9.5724"); +define("APP_VERSION", "1.21.9.5725"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 20ec9b24e53bc00b14241c6041dbd6c0f1fb0666 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Sep 2022 20:51:28 +0000 Subject: [PATCH 1751/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 3 +-- initialize.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 9f846bc5f..2e87007cd 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -411,8 +411,7 @@ 'form.reports.include_pending' => 'in afwachting', 'form.reports.select_period' => 'Kies periode', 'form.reports.set_period' => 'of stel datums in', -// TODO: translate the following. -// 'form.reports.note_containing' => 'Note containing', +'form.reports.note_containing' => 'Notitie bevat', 'form.reports.show_fields' => 'Toon velden', 'form.reports.time_fields' => 'Tijd velden', 'form.reports.user_fields' => 'Medewerker velden', diff --git a/initialize.php b/initialize.php index c5cb7fe3d..92a3f3134 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.9.5725"); +define("APP_VERSION", "1.21.9.5726"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 491f6c4a35c723ab7e6ddd58c0065166dcfff25d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 17 Oct 2022 15:17:19 +0000 Subject: [PATCH 1752/1848] Starting to implement cost per hour column on reports. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/display_options.tpl | 10 ++++++++++ display_options.php | 4 ++++ initialize.php | 2 +- 33 files changed, 46 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index f2eec1b5a..ae5a1df73 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -677,5 +677,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 8573d71c2..18c04aa69 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -689,5 +689,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index dd1abd396..9e4a61c96 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -655,5 +655,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index e295e7281..a2e730ddf 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -630,5 +630,6 @@ // TODO: translate the following. // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 5df99c403..f55cef6f3 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -601,5 +601,6 @@ 'form.display_options.note_on_separate_row' => 'Note on separate row', 'form.display_options.not_complete_days' => 'Not complete days', 'form.display_options.inactive_projects' => 'Inactive projects', +'form.display_options.cost_per_hour' => 'Cost per hour', 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 7c59d3ae5..b7ec4116c 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -692,5 +692,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 7a53024b7..0b2fd1d8c 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -665,5 +665,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 2963414ee..ec3dfe6d6 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -678,5 +678,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 112dc6b6a..28033da2a 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -662,5 +662,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a1268d1a7..20bc298f0 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -651,5 +651,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 9f1bf5d93..db2aa859e 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -644,5 +644,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 3167fd8d9..ef6e20f35 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -683,5 +683,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 636c29d07..5987b8850 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -680,5 +680,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index d517fdede..63c2ada5d 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -657,5 +657,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 59500e015..5e7070b1b 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -684,5 +684,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index e2f16ccec..a4ea97c23 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -682,5 +682,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 2e87007cd..73265f98d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -586,5 +586,7 @@ 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', // Translator (Henk) comment: "kolom is the right word in Dutch." 'form.display_options.not_complete_days' => 'Niet complete dagen', 'form.display_options.inactive_projects' => 'Niet actieve projecten', +// TODO: translate the following. +// 'form.display_options.cost_per_hour' => 'Cost per hour', 'form.display_options.custom_css' => 'Aangepaste CSS', ); diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index cba06a82f..8e3c4c888 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -684,5 +684,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 3470add1b..bf04ee74f 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -663,5 +663,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 60d505762..36dca948c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -594,6 +594,7 @@ 'form.display_options.not_complete_days' => 'Dias não completos', // TODO: translate the following. // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', 'form.display_options.custom_css' => 'CSS customizado', ); diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d5a4413a2..cce36ad07 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -662,5 +662,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index f450bfd4e..03e7a992e 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -685,5 +685,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 47f87d496..5a037b846 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -587,5 +587,6 @@ 'form.display_options.note_on_separate_row' => 'Комментарий в отдельном ряду', 'form.display_options.not_complete_days' => 'Незавершенные дни', 'form.display_options.inactive_projects' => 'Неактивные проекты', +'form.display_options.cost_per_hour' => 'Стоимость за час', 'form.display_options.custom_css' => 'Пользовательская CSS', ); diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 1909ec9d1..c3ad4da53 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -667,5 +667,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 304da23a0..04e709748 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -657,5 +657,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index d1fb802e8..9823f810e 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -665,5 +665,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 1df983ecc..4250318c2 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -663,5 +663,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index c6fe800a6..32838159e 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -698,5 +698,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5b701c851..967a172ef 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -673,5 +673,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 14ef3c269..2fd31a762 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -676,5 +676,6 @@ // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', // 'form.display_options.inactive_projects' => 'Inactive projects', +// 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', ); diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index 6486c0b25..c09a18e9b 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -49,6 +49,16 @@ License: See license.txt *} {$i18n.label.what_is_it} +{if defined('REPORT_COST_PER_HOUR')} + + + + + +{/if} diff --git a/display_options.php b/display_options.php index 6e0ccc548..e449c3c91 100644 --- a/display_options.php +++ b/display_options.php @@ -21,6 +21,7 @@ $cl_record_custom_fields = (bool)$request->getParameter('record_custom_fields'); $cl_report_note_on_separate_row = (bool)$request->getParameter('report_note_on_separate_row'); $cl_report_inactive_projects = (bool)($request->getParameter('report_inactive_projects')); + $cl_report_cost_per_hour = (bool)$request->getParameter('report_cost_per_hour'); $cl_custom_css = trim($request->getParameter('custom_css')); } else { $cl_time_note_on_separate_row = $config->getDefinedValue('time_note_on_separate_row'); @@ -28,6 +29,7 @@ $cl_record_custom_fields = $config->getDefinedValue('record_custom_fields'); $cl_report_note_on_separate_row = $config->getDefinedValue('report_note_on_separate_row'); $cl_report_inactive_projects = $config->getDefinedValue('report_inactive_projects'); + $cl_report_cost_per_hour = $config->getDefinedValue('report_cost_per_hour'); $cl_custom_css = $user->getCustomCss(); } @@ -49,6 +51,7 @@ // Reports. $form->addInput(array('type'=>'checkbox','name'=>'report_note_on_separate_row','value'=>$cl_report_note_on_separate_row)); $form->addInput(array('type'=>'checkbox','name'=>'report_inactive_projects','value'=>$cl_report_inactive_projects)); +$form->addInput(array('type'=>'checkbox','name'=>'report_cost_per_hour','value'=>$cl_report_cost_per_hour)); // TODO: add PDF break controller here. $form->addInput(array('type'=>'textarea','name'=>'custom_css','value'=>$cl_custom_css)); @@ -66,6 +69,7 @@ $config->setDefinedValue('record_custom_fields', $cl_record_custom_fields); $config->setDefinedValue('report_note_on_separate_row', $cl_report_note_on_separate_row); $config->setDefinedValue('report_inactive_projects', $cl_report_inactive_projects); + $config->setDefinedValue('report_cost_per_hour', $cl_report_cost_per_hour); if ($user->updateGroup(array( 'config' => $config->getConfig(), 'custom_css' => $cl_custom_css))) { diff --git a/initialize.php b/initialize.php index 92a3f3134..86aad8046 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.9.5726"); +define("APP_VERSION", "1.21.9.5727"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 69de200456a6ad941f2a268f2efb406512b3973e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 17 Oct 2022 18:50:39 +0000 Subject: [PATCH 1753/1848] Work in progress on including cost per hour in reports. --- WEB-INF/lib/ttReportHelper.class.php | 13 ++++++-- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/puncher.tpl | 2 +- WEB-INF/templates/report.tpl | 45 ++++++++++++++++++---------- WEB-INF/templates/time.tpl | 2 +- WEB-INF/templates/week.tpl | 2 +- report.php | 8 ++++- 36 files changed, 87 insertions(+), 21 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 45b6ec1b6..d15d1e9bf 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -333,12 +333,19 @@ static function getItems($options) { // Handle cost. $includeCost = $options['show_cost']; if ($includeCost) { - if (MODE_TIME == $trackingMode) + $includeCostPerHour = $user->getConfigOption('report_cost_per_hour'); + if (MODE_TIME == $trackingMode) { + if ($includeCostPerHour) + array_push($fields, "cast(l.billable * coalesce(u.rate, 0) as decimal(10,2)) as cost_per_hour"); // Use default user rate. array_push($fields, "cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use default user rate. - else + } else { + if ($includeCostPerHour) + array_push($fields, "cast(l.billable * coalesce(upb.rate, 0) as decimal(10,2)) as cost_per_hour"); // Use project rate for user. array_push($fields, "cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use project rate for user. + } array_push($fields, "null as expense"); } + // Add the fields used to determine if we show an edit icon for record. array_push($fields, 'l.approved'); array_push($fields, 'l.timesheet_id'); @@ -501,6 +508,8 @@ static function getItems($options) { // Use the note field to print item name. if ($options['show_note']) array_push($fields, 'ei.name as note'); + if ($user->getConfigOption('report_cost_per_hour')) + array_push($fields, 'null as cost_per_hour'); // null for cost_per_hour. array_push($fields, 'ei.cost as cost'); array_push($fields, 'ei.cost as expense'); // Add the fields used to determine if we show an edit icon for record. diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index ae5a1df73..a06c8a692 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -494,6 +494,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportar', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 18c04aa69..e8d297edc 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -502,6 +502,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportovat', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 9e4a61c96..6e27e5370 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -477,6 +477,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Eksport', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index a2e730ddf..8d5e030c3 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -459,6 +459,8 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportiere', +// TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', 'form.report.assign_to_invoice' => 'Zu Rechnung hinzufügen', // TODO: translate the following. // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index f55cef6f3..2f42d2730 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -440,6 +440,7 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Export', +'form.report.per_hour' => 'Per hour', 'form.report.assign_to_invoice' => 'Assign to invoice', 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index b7ec4116c..6dbfd29a8 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -507,6 +507,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportar', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 0b2fd1d8c..dc08bd01a 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -489,6 +489,8 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Eksport', +// TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', 'form.report.assign_to_invoice' => 'Lisa arvele', // TODO: translate the following. // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index ec3dfe6d6..f8d8f6843 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -498,6 +498,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'پشتیبانی', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 28033da2a..8d5ec21ec 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -483,6 +483,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Vie', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 20bc298f0..8e7289715 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -474,6 +474,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exporter', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index db2aa859e..dc03db958 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -468,6 +468,8 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Εξαγωγή', +// TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', 'form.report.assign_to_invoice' => 'Ανάθεση στο τιμολόγιο', // TODO: translate the following. // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index ef6e20f35..5249ee8e9 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -502,6 +502,7 @@ // TODO: form.report.export is just "Export" now in the English file. Shorten this translation. 'form.report.export' => 'ייצא נתונים בתבנית', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 5987b8850..f19593ba7 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -496,6 +496,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportálása', // TODO: is this correct? // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 63c2ada5d..f936ef123 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -481,6 +481,8 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Esporta', +// TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', 'form.report.assign_to_invoice' => 'Assegna alla fattura', // TODO: translate the following. // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 5e7070b1b..02d4ad227 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -502,6 +502,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => '輸出する', // TODO: is this correct? // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index a4ea97c23..491631d04 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -500,6 +500,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => '익스포트', // TODO: is this correct? // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 73265f98d..90ee07697 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -426,6 +426,8 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exporteer', +// TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', 'form.report.assign_to_invoice' => 'Voeg toe aan factuur', 'form.report.assign_to_timesheet' => 'Wijs toe aan tijdenoverzicht', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 8e3c4c888..9fd520436 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -501,6 +501,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Eksporter', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index bf04ee74f..325948cdd 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -485,6 +485,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Eksport', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 36dca948c..279d9eb68 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -430,6 +430,8 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportar', +// TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', 'form.report.assign_to_invoice' => 'Atribuir a fatura', 'form.report.assign_to_timesheet' => 'Atribuir a planilha de horas', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index cce36ad07..d5c248b80 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -477,6 +477,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). // TODO: translate the following. // 'form.report.export' => 'Export', +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 03e7a992e..0984a7796 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -501,6 +501,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exporta', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 5a037b846..faab0e60d 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -427,6 +427,7 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Экспортировать', +'form.report.per_hour' => 'За час', 'form.report.assign_to_invoice' => 'Включить в счёт', 'form.report.assign_to_timesheet' => 'Включить в табель', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index c3ad4da53..8ba546295 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -488,6 +488,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportovať', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 04e709748..d041eaee1 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -473,6 +473,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). // TODO: translate the following. // 'form.report.export' => 'Export', +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 9823f810e..ac51518df 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -485,6 +485,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Izvoz', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 4250318c2..3c43c91cb 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -483,6 +483,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportera som', // TODO: translate the following. +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 32838159e..d37a1c547 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -513,6 +513,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). // TODO: translate the following. // 'form.report.export' => 'Export', +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 967a172ef..93c85118a 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -491,6 +491,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). // TODO: translate the following. // 'form.report.export' => 'Export', +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 2fd31a762..75ac102bf 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -494,6 +494,7 @@ // (after generating a report at https://timetracker.anuko.com/reports.php). // TODO: translate the following. // 'form.report.export' => 'Export', +// 'form.report.per_hour' => 'Per hour', // 'form.report.assign_to_invoice' => 'Assign to invoice', // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/WEB-INF/templates/puncher.tpl b/WEB-INF/templates/puncher.tpl index 9190af396..98bd5ca24 100644 --- a/WEB-INF/templates/puncher.tpl +++ b/WEB-INF/templates/puncher.tpl @@ -145,7 +145,7 @@ startTimer(); {if $show_client} {/if} - {* record custom fileds *} + {* record custom fields *} {if $show_record_custom_fields && isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {assign var="control_name" value='time_field_'|cat:$timeField['id']} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 8ae981a3b..3bd9f448c 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -38,7 +38,7 @@ License: See license.txt *} {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - {* user custom fileds *} + {* user custom fields *} {if isset($custom_fields) && $custom_fields->userFields} {foreach $custom_fields->userFields as $userField} {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} @@ -48,7 +48,7 @@ License: See license.txt *} {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} - {* time custom fileds *} + {* time custom fields *} {if isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} @@ -60,7 +60,10 @@ License: See license.txt *} {if $bean->getAttribute('chduration')}{/if} {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chcost')} + {if $show_cost_per_hour}{/if} + + {/if} {if $bean->getAttribute('chapproved')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} @@ -79,7 +82,7 @@ License: See license.txt *} {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - {* user custom fileds *} + {* user custom fields *} {if isset($custom_fields) && $custom_fields->userFields} {foreach $custom_fields->userFields as $userField} {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} @@ -90,7 +93,7 @@ License: See license.txt *} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} - {* time custom fileds *} + {* time custom fields *} {if isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} @@ -102,7 +105,10 @@ License: See license.txt *} {if $bean->getAttribute('chduration')}{/if} {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chcost')} + {if $show_cost_per_hour}{/if} + + {/if} {if $bean->getAttribute('chapproved')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} @@ -120,7 +126,7 @@ License: See license.txt *} {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - {* user custom fileds *} + {* user custom fields *} {if isset($custom_fields) && $custom_fields->userFields} {foreach $custom_fields->userFields as $userField} {assign var="control_name" value='user_field_'|cat:$userField['id']} @@ -131,7 +137,7 @@ License: See license.txt *} {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} - {* time custom fileds *} + {* time custom fields *} {if isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {assign var="control_name" value='time_field_'|cat:$timeField['id']} @@ -144,7 +150,10 @@ License: See license.txt *} {if $bean->getAttribute('chduration')}{/if} {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chcost')} + {if $show_cost_per_hour}{/if} + + {/if} {if $bean->getAttribute('chapproved')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} @@ -180,7 +189,7 @@ License: See license.txt *} {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - {* user custom fileds *} + {* user custom fields *} {if isset($custom_fields) && $custom_fields->userFields} {foreach $custom_fields->userFields as $userField} {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} @@ -190,7 +199,7 @@ License: See license.txt *} {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} - {* time custom fileds *} + {* time custom fields *} {if isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} @@ -202,7 +211,10 @@ License: See license.txt *} {if $bean->getAttribute('chduration')}{/if} {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chcost')} + {if $show_cost_per_hour}{/if} + + {/if} {if $bean->getAttribute('chapproved')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} @@ -218,7 +230,7 @@ License: See license.txt *} {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} - {* user custom fileds *} + {* user custom fields *} {if isset($custom_fields) && $custom_fields->userFields} {foreach $custom_fields->userFields as $userField} {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} @@ -228,7 +240,7 @@ License: See license.txt *} {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} - {* time custom fileds *} + {* time custom fields *} {if isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} @@ -240,7 +252,10 @@ License: See license.txt *} {if $bean->getAttribute('chduration')}{/if} {if $bean->getAttribute('chunits')}{/if} {if $bean->getAttribute('chnote') && !$note_on_separate_row}{/if} - {if $bean->getAttribute('chcost')}{/if} + {if $bean->getAttribute('chcost')} + {if $show_cost_per_hour}{/if} + + {/if} {if $bean->getAttribute('chapproved')}{/if} {if $bean->getAttribute('chpaid')}{/if} {if $bean->getAttribute('chip')}{/if} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index 6f6f73942..b601531ba 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -160,7 +160,7 @@ function handleStop(buttonElement) { {if $show_client} {/if} - {* record custom fileds *} + {* record custom fields *} {if $show_record_custom_fields && isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {assign var="control_name" value='time_field_'|cat:$timeField['id']} diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl index 41568f601..74e94053f 100644 --- a/WEB-INF/templates/week.tpl +++ b/WEB-INF/templates/week.tpl @@ -130,7 +130,7 @@ function fillDropdowns() { {foreach $time_records as $record} - {* record custom fileds *} + {* record custom fields *} {if $show_record_custom_fields && isset($custom_fields) && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} {assign var="control_name" value='time_field_'|cat:$timeField['id']} diff --git a/report.php b/report.php index bd2576f14..38e57fe23 100644 --- a/report.php +++ b/report.php @@ -18,6 +18,7 @@ // End of access checks. $config = new ttConfigHelper($user->getConfig()); +$show_cost_per_hour = $config->getDefinedValue('report_cost_per_hour'); if ($user->isPluginEnabled('ap')) { $cl_mark_approved_select_option = $request->getParameter('mark_approved_select_options', ($request->isPost() ? null : @$_SESSION['mark_approved_select_option'])); @@ -298,7 +299,11 @@ if ($bean->getAttribute('chduration')) $colspan++; if (!$user->getConfigOption('report_note_on_separate_row') && $bean->getAttribute('chnote')) $colspan++; if ($bean->getAttribute('chunits')) $colspan++; -if ($bean->getAttribute('chcost')) $colspan++; +if ($bean->getAttribute('chcost')) { + if ($show_cost_per_hour) + $colspan++; + $colspan++; +} if ($bean->getAttribute('chapproved')) $colspan++; if ($bean->getAttribute('chpaid')) $colspan++; if ($bean->getAttribute('chip')) $colspan++; @@ -316,6 +321,7 @@ $smarty->assign('report_items', $report_items); $smarty->assign('subtotals', $subtotals); $smarty->assign('totals', $totals); +$smarty->assign('show_cost_per_hour', $show_cost_per_hour); $smarty->assign('note_on_separate_row', $user->getConfigOption('report_note_on_separate_row')); $smarty->assign('colspan', $colspan); $smarty->assign('bean', $bean); From 350f206391875be2a1b1e3847f80030aca02210f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 18 Oct 2022 18:02:06 +0000 Subject: [PATCH 1754/1848] Fixed report exports for cost_per_hour column. --- WEB-INF/lib/ttReportHelper.class.php | 4 ++++ initialize.php | 2 +- report.php | 2 +- tofile.php | 20 +++++++++++++++++--- topdf.php | 7 +++++++ 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index d15d1e9bf..cfcc64356 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -613,6 +613,10 @@ static function getItems($options) { if($val['finish'] != '') $val['finish'] = ttTimeHelper::to12HourFormat($val['finish']); } + if (isset($val['cost_per_hour'])) { + if ('.' != $decimalMark) + $val['cost_per_hour'] = str_replace('.', $decimalMark, $val['cost_per_hour']); + } if (isset($val['cost'])) { if ('.' != $decimalMark) $val['cost'] = str_replace('.', $decimalMark, $val['cost']); diff --git a/initialize.php b/initialize.php index 86aad8046..ed2fe659a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.9.5727"); +define("APP_VERSION", "1.21.9.5728"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/report.php b/report.php index 38e57fe23..4945ac173 100644 --- a/report.php +++ b/report.php @@ -18,7 +18,7 @@ // End of access checks. $config = new ttConfigHelper($user->getConfig()); -$show_cost_per_hour = $config->getDefinedValue('report_cost_per_hour'); +$show_cost_per_hour = $config->getDefinedValue('report_cost_per_hour') && ($user->can('manage_invoices') || $user->isClient()); if ($user->isPluginEnabled('ap')) { $cl_mark_approved_select_option = $request->getParameter('mark_approved_select_options', ($request->isPost() ? null : @$_SESSION['mark_approved_select_option'])); diff --git a/tofile.php b/tofile.php index 530d2f7df..6ea39ad82 100644 --- a/tofile.php +++ b/tofile.php @@ -20,6 +20,8 @@ $custom_fields = new CustomFields(); } +$show_cost_per_hour = $user->getConfigOption('report_cost_per_hour') && ($user->can('manage_invoices') || $user->isClient()); + // Report settings are stored in session bean before we get here. $bean = new ActionForm('reportBean', new Form('reportForm'), $request); @@ -123,6 +125,11 @@ } if ($bean->getAttribute('chunits')) print "\t\n"; if ($bean->getAttribute('chnote')) print "\t\n"; + if ($bean->getAttribute('chcost') && $show_cost_per_hour) { + print "\t\n"; + } if ($bean->getAttribute('chcost')) { print "\tcan('manage_invoices') || $user->isClient()) @@ -213,7 +220,11 @@ if ($bean->getAttribute('chduration')) print ',"'.$i18n->get('label.duration').'"'; if ($bean->getAttribute('chunits')) print ',"'.$i18n->get('label.work_units_short').'"'; if ($bean->getAttribute('chnote')) print ',"'.$i18n->get('label.note').'"'; - if ($bean->getAttribute('chcost')) print ',"'.$i18n->get('label.cost').'"'; + if ($bean->getAttribute('chcost')) { + if ($show_cost_per_hour) + print ',"'.$i18n->get('form.report.per_hour').'"'; + print ',"'.$i18n->get('label.cost').'"'; + } if ($bean->getAttribute('chapproved')) print ',"'.$i18n->get('label.approved').'"'; if ($bean->getAttribute('chpaid')) print ',"'.$i18n->get('label.paid').'"'; if ($bean->getAttribute('chip')) print ',"'.$i18n->get('label.ip').'"'; @@ -255,10 +266,13 @@ if ($bean->getAttribute('chunits')) print ',"'.$item['units'].'"'; if ($bean->getAttribute('chnote')) print ',"'.ttNeutralizeForCsv($item['note']).'"'; if ($bean->getAttribute('chcost')) { - if ($user->can('manage_invoices') || $user->isClient()) + if ($user->can('manage_invoices') || $user->isClient()) { + if ($show_cost_per_hour) + print ',"'.$item['cost_per_hour'].'"'; print ',"'.$item['cost'].'"'; - else + } else { print ',"'.$item['expense'].'"'; + } } if ($bean->getAttribute('chapproved')) print ',"'.$item['approved'].'"'; if ($bean->getAttribute('chpaid')) print ',"'.$item['paid'].'"'; diff --git a/topdf.php b/topdf.php index 85ff8d84e..931fa8145 100644 --- a/topdf.php +++ b/topdf.php @@ -38,6 +38,7 @@ $config = new ttConfigHelper($user->getConfig()); $show_note_column = $bean->getAttribute('chnote') && !$config->getDefinedValue('report_note_on_separate_row'); $show_note_row = $bean->getAttribute('chnote') && $config->getDefinedValue('report_note_on_separate_row'); +$show_cost_per_hour = $config->getDefinedValue('report_cost_per_hour') && ($user->can('manage_invoices') || $user->isClient()); // There are 2 variations of report: totals only, or normal. Totals only means that the report // is grouped by either date, user, client, project, or task and user only needs to see subtotals by group. @@ -152,6 +153,7 @@ if ($bean->getAttribute('chduration')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chunits')) { $colspan++; $html .= "'; } if ($show_note_column) { $colspan++; $html .= ''; } + if ($bean->getAttribute('chcost') && $show_cost_per_hour) { $colspan++; $html .= "'; } if ($bean->getAttribute('chcost')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chapproved')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chpaid')) { $colspan++; $html .= "'; } @@ -266,6 +268,11 @@ if ($bean->getAttribute('chduration')) $html .= "'; if ($bean->getAttribute('chunits')) $html .= "'; if ($show_note_column) $html .= ''; + if ($bean->getAttribute('chcost') && $show_cost_per_hour) { + $html .= "'; + } if ($bean->getAttribute('chcost')) { $html .= "'; if ($show_note_column) $body .= ''; + if ($show_cost_per_hour) + $body .= ''; if ($options['show_cost']) $body .= ''; if ($options['show_approved']) @@ -1263,6 +1267,7 @@ static function prepareReportBody($options, $comment = null) if ($options['show_duration']) $body .= ''; if ($options['show_work_units']) $body .= ''; if ($show_note_column) $body .= ''; + if ($show_cost_per_hour) $body .= ''; if ($options['show_cost']) { $body .= ''; if ($show_note_column) $body .= ''; + if ($show_cost_per_hour) + $body .= ''; if ($options['show_cost']) $body .= ''; if ($options['show_approved']) { @@ -1382,6 +1389,7 @@ static function prepareReportBody($options, $comment = null) if ($options['show_duration']) $body .= ''; if ($options['show_work_units']) $body .= ''; if ($show_note_column) $body .= ''; + if ($show_cost_per_hour) $body .= ''; if ($options['show_cost']) { $body .= ''; if ($options['show_work_units']) $body .= ''; if ($show_note_column) $body .= ''; + if ($show_cost_per_hour) $body .= ''; if ($options['show_cost']) { $body .= ' -{if defined('REPORT_COST_PER_HOUR')} @@ -58,7 +57,6 @@ License: See license.txt *} {$i18n.label.what_is_it} -{/if} diff --git a/initialize.php b/initialize.php index 25386c623..e58e54a1b 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.9.5729"); +define("APP_VERSION", "1.21.10.5730"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From dc03995e430b92b0e3f814d32f586a994996dc81 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 20 Oct 2022 22:01:13 +0000 Subject: [PATCH 1757/1848] German translation improved. --- WEB-INF/resources/de.lang.php | 3 +-- initialize.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 8d5e030c3..95d9af2ca 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -459,8 +459,7 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exportiere', -// TODO: translate the following. -// 'form.report.per_hour' => 'Per hour', +'form.report.per_hour' => 'Stundensatz', 'form.report.assign_to_invoice' => 'Zu Rechnung hinzufügen', // TODO: translate the following. // 'form.report.assign_to_timesheet' => 'Assign to timesheet', diff --git a/initialize.php b/initialize.php index e58e54a1b..90872e605 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.10.5730"); +define("APP_VERSION", "1.21.10.5731"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From e8b8d42fc07ebce3d8a08303c21c488a3165019e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 21 Oct 2022 14:53:20 +0000 Subject: [PATCH 1758/1848] Starting to work on project custom fields. --- WEB-INF/templates/cf_custom_fields.tpl | 2 ++ cf_custom_field_add.php | 16 ++++++++++++---- initialize.php | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/cf_custom_fields.tpl b/WEB-INF/templates/cf_custom_fields.tpl index 70253cb3f..812943db8 100644 --- a/WEB-INF/templates/cf_custom_fields.tpl +++ b/WEB-INF/templates/cf_custom_fields.tpl @@ -19,6 +19,8 @@ License: See license.txt *} {elseif CustomFields::ENTITY_USER == $field['entity_type']} + {elseif CustomFields::ENTITY_PROJECT == $field['entity_type']} + {else} {/if} diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index 6cfd87256..38d672822 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -27,10 +27,18 @@ $form = new Form('fieldForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>'')); -$form->addInput(array('type'=>'combobox','name'=>'entity', - 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('entity.time'), - CustomFields::ENTITY_USER=>$i18n->get('entity.user')) -)); +if (defined('DEBUG_PROJECT_CUSTOM_FIELDS')) { + $form->addInput(array('type'=>'combobox','name'=>'entity', + 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('entity.time'), + CustomFields::ENTITY_USER=>$i18n->get('entity.user'), + CustomFields::ENTITY_PROJECT=>$i18n->get('entity.project')) + )); +} else { + $form->addInput(array('type'=>'combobox','name'=>'entity', + 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('entity.time'), + CustomFields::ENTITY_USER=>$i18n->get('entity.user')) + )); +} $form->addInput(array('type'=>'combobox','name'=>'type', 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->get('label.type_text'), CustomFields::TYPE_DROPDOWN=>$i18n->get('label.type_dropdown')) diff --git a/initialize.php b/initialize.php index 90872e605..6033d935a 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.10.5731"); +define("APP_VERSION", "1.21.10.5732"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From b0381c6478f062d37bdbb38714d23ee6c2151805 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 21 Oct 2022 16:16:14 +0000 Subject: [PATCH 1759/1848] Work in progress on project custom fields. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/reports.tpl | 16 +++++++++++++--- initialize.php | 2 +- plugins/CustomFields.class.php | 29 ++--------------------------- reports.php | 17 +++++++++++++++++ 34 files changed, 65 insertions(+), 31 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index a06c8a692..13d8237c2 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -480,6 +480,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Agrupar per', 'form.reports.group_by_no' => '--- no agrupar ---', 'form.reports.group_by_date' => 'data', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index e8d297edc..4a93086de 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -488,6 +488,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Seskupit podle', // TODO: translate the following. // 'form.reports.group_by_no' => '--- no grouping ---', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 6e27e5370..595590f0a 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -465,6 +465,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Gruppér ved', 'form.reports.group_by_no' => '--- Ingen gruppereing ---', 'form.reports.group_by_date' => 'Dato', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 95d9af2ca..209df6b72 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -448,6 +448,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Gruppieren nach', 'form.reports.group_by_no' => '--- keine Gruppierung ---', 'form.reports.group_by_date' => 'Datum', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 2f42d2730..83808aa40 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -429,6 +429,7 @@ 'form.reports.show_fields' => 'Show fields', 'form.reports.time_fields' => 'Time fields', 'form.reports.user_fields' => 'User fields', +'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Group by', 'form.reports.group_by_no' => '--- no grouping ---', 'form.reports.group_by_date' => 'date', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 6dbfd29a8..507bbcaac 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -493,6 +493,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Agrupar por', 'form.reports.group_by_no' => '--- no agrupar ---', 'form.reports.group_by_date' => 'fecha', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index dc08bd01a..0295dc70f 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -478,6 +478,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Grupeeri', 'form.reports.group_by_no' => '--- grupeerimata ---', 'form.reports.group_by_date' => 'kuupäev', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f8d8f6843..078872026 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -486,6 +486,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'گروه بندی شده با', 'form.reports.group_by_no' => '--- بدون گروه ---', 'form.reports.group_by_date' => 'تاریخ', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 8d5ec21ec..e9e92e018 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -471,6 +471,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Ryhmittelyperuste', 'form.reports.group_by_no' => '--- ei ryhmitystä ---', 'form.reports.group_by_date' => 'päivä', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 8e7289715..145fcb289 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -462,6 +462,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Regroupés par', 'form.reports.group_by_no' => '--- Aucun regroupement ---', 'form.reports.group_by_date' => 'Date', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index dc03db958..6265976d7 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -457,6 +457,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Ομαδοποίηση με βάση', 'form.reports.group_by_no' => '--- χωρίς ομαδοποίηση ---', 'form.reports.group_by_date' => 'ημερομηνία', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 5249ee8e9..727b0b761 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -489,6 +489,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'סדר לפי', 'form.reports.group_by_no' => '--- ללא סדר ---', 'form.reports.group_by_date' => 'תאריך', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index f19593ba7..8b0be9524 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -482,6 +482,7 @@ // 'form.reports.show_fields' => 'Show fields', // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Csoportosítva', 'form.reports.group_by_no' => '--- csoportosítás nélkül ---', 'form.reports.group_by_date' => 'dátum', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index f936ef123..d283830a1 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -470,6 +470,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Raggruppa per', 'form.reports.group_by_no' => '--- non raggruppare ---', 'form.reports.group_by_date' => 'data', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 02d4ad227..112e454cc 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -488,6 +488,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => '次のようにグループ化', 'form.reports.group_by_no' => '--- グループの機能がありません ---', 'form.reports.group_by_date' => '日付', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 491631d04..6bb78d772 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -486,6 +486,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => '다음것에 의한 그룹화', 'form.reports.group_by_no' => '--- 그룹화되지 않음 ---', 'form.reports.group_by_date' => '날짜', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 90ee07697..38d93efdb 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -415,6 +415,8 @@ 'form.reports.show_fields' => 'Toon velden', 'form.reports.time_fields' => 'Tijd velden', 'form.reports.user_fields' => 'Medewerker velden', +// TODO: translate the following. +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Groeperen op', 'form.reports.group_by_no' => '--- niet groeperen ---', 'form.reports.group_by_date' => 'datum', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 9fd520436..18e1ee69f 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -488,6 +488,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', 'form.reports.group_by_date' => 'dato', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 325948cdd..b7dd5024c 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -473,6 +473,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Grupowanie wg', 'form.reports.group_by_no' => '--- bez grupowania ---', 'form.reports.group_by_date' => 'daty', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 279d9eb68..fff94fa3d 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -419,6 +419,8 @@ 'form.reports.show_fields' => 'Exibir campos', 'form.reports.time_fields' => 'Campos de tempo', 'form.reports.user_fields' => 'Campos de usuário', +// TODO: translate the following. +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Agrupar por', 'form.reports.group_by_no' => '--- sem agrupar ---', 'form.reports.group_by_date' => 'data', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d5c248b80..075e7b41c 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -465,6 +465,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', // 'form.reports.group_by_date' => 'date', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 0984a7796..0d8fe6d1f 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -488,6 +488,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Grupat dupa', 'form.reports.group_by_no' => '--- fara grupare ---', 'form.reports.group_by_date' => 'data', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index faab0e60d..805be45b5 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -416,6 +416,7 @@ 'form.reports.show_fields' => 'Показывать поля', 'form.reports.time_fields' => 'Поля времени', 'form.reports.user_fields' => 'Поля пользователя', +'form.reports.project_fields' => 'Поля проекта', 'form.reports.group_by' => 'Группировать по', 'form.reports.group_by_no' => '--- без группировки ---', 'form.reports.group_by_date' => 'дате', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 8ba546295..e57e63d74 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -476,6 +476,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', 'form.reports.group_by_date' => 'dátum', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index d041eaee1..8ea8c445e 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -460,6 +460,7 @@ // 'form.reports.show_fields' => 'Show fields', // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', // 'form.reports.group_by_date' => 'date', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index ac51518df..055545b37 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -473,6 +473,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Grupiši po', 'form.reports.group_by_no' => '--- nemoj grupisati ---', 'form.reports.group_by_date' => 'datum', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 3c43c91cb..e0d212b9e 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -471,6 +471,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Gruppera efter', 'form.reports.group_by_no' => '--- Ingen gruppering ---', 'form.reports.group_by_date' => 'Datum', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index d37a1c547..098871718 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -499,6 +499,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => 'Gruplandırma kıstas', 'form.reports.group_by_no' => '--- gruplama yok ---', 'form.reports.group_by_date' => 'tarih', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 93c85118a..87f1cc1c9 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -477,6 +477,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => '分组方式', 'form.reports.group_by_no' => '--- 没有分组 ---', 'form.reports.group_by_date' => '日期', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 75ac102bf..181756e77 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -480,6 +480,7 @@ // TODO: translate the following. // 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', +// 'form.reports.project_fields' => 'Project fields', 'form.reports.group_by' => '分組方式', 'form.reports.group_by_no' => '--- 沒有分組 ---', 'form.reports.group_by_date' => '日期', diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 51c98212c..370a6d462 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -245,9 +245,6 @@ function handleCheckboxes() { } -{* Copyright (c) Anuko International Ltd. https://www.anuko.com -License: See license.txt *} - {$forms.reportForm.open}
{$forms.displayOptionsForm.report_cost_per_hour.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
{$i18n.form.display_options.custom_css}
{$record.client|escape}
{$i18n.label.date}{$i18n.label.user}{$i18n.label.client}{$i18n.label.project}{$i18n.label.task}{$i18n.label.duration}{$i18n.label.work_units_short}{$i18n.label.note}{$i18n.label.cost}{$i18n.form.report.per_hour}{$i18n.label.cost}{$i18n.label.approved}{$i18n.label.paid}{$i18n.label.ip}
{$i18n.label.subtotal}{$subtotals[$prev_grouped_by]['user']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$subtotals[$prev_grouped_by]['time']}{$subtotals[$prev_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}
{$item.date}{$item.user|escape}{$item.client|escape}{$item.project|escape}{$item.task|escape}{$item.duration}{$item.units}{$item.note|escape}{if $user->can('manage_invoices') || $user->isClient()}{$item.cost}{else}{$item.expense}{/if}{if $user->can('manage_invoices') || $user->isClient()}{$item.cost_per_hour}{/if}{if $user->can('manage_invoices') || $user->isClient()}{$item.cost}{else}{$item.expense}{/if}{if $item.approved == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{if $item.modified}{$item.modified_ip} {$item.modified}{else}{$item.created_ip} {$item.created}{/if}{$i18n.label.subtotal}{$subtotals[$cur_grouped_by]['user']|escape}{$subtotals[$cur_grouped_by]['client']|escape}{$subtotals[$cur_grouped_by]['project']|escape}{$subtotals[$cur_grouped_by]['task']|escape}{$subtotals[$cur_grouped_by]['time']}{$subtotals[$cur_grouped_by]['units']}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$cur_grouped_by]['cost']}{else}{$subtotals[$cur_grouped_by]['expenses']}{/if}{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$cur_grouped_by]['cost']}{else}{$subtotals[$cur_grouped_by]['expenses']}{/if}
{$i18n.label.total}{$totals['time']}{$totals['units']}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}{$record.client|escape}
{$record.date}".$i18n->get('label.duration').'".$i18n->get('label.work_units_short').''.$i18n->get('label.note').'".$i18n->get('form.report.per_hour').'".$i18n->get('label.cost').'".$i18n->get('label.approved').'".$i18n->get('label.paid').'".$item['duration'].'".$item['units'].''.htmlspecialchars($item['note']).'"; + $html .= $item['cost_per_hour']; + $html .= '"; if ($user->can('manage_invoices') || $user->isClient()) From 85c1f6d14ceb9df215bae6c7478bc0ec363e2b77 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 18 Oct 2022 18:16:56 +0000 Subject: [PATCH 1755/1848] Fixed emailed reports for cost_per_hour column. --- WEB-INF/lib/ttReportHelper.class.php | 9 +++++++++ initialize.php | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index cfcc64356..056f4d4fb 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1037,6 +1037,7 @@ static function prepareReportBody($options, $comment = null) $config = new ttConfigHelper($user->getConfig()); $show_note_column = $options['show_note'] && !$config->getDefinedValue('report_note_on_separate_row'); $show_note_row = $options['show_note'] && $config->getDefinedValue('report_note_on_separate_row'); + $show_cost_per_hour = $options['show_cost'] && $config->getDefinedValue('report_cost_per_hour') && ($user->can('manage_invoices') || $user->isClient()); $items = ttReportHelper::getItems($options); $grouping = ttReportHelper::grouping($options); @@ -1085,6 +1086,7 @@ static function prepareReportBody($options, $comment = null) if ($options['show_end']) $colspan++; if ($options['show_duration']) $colspan++; if ($options['show_work_units']) $colspan++; + if ($show_cost_per_hour) $colspan++; if ($options['show_cost']) $colspan++; if ($options['show_approved']) $colspan++; if ($options['show_paid']) $colspan++; @@ -1201,6 +1203,8 @@ static function prepareReportBody($options, $comment = null) $body .= ''.$i18n->get('label.work_units_short').''.$i18n->get('label.note').''.$i18n->get('form.report.per_hour').''.$i18n->get('label.cost').''.$subtotals[$prev_grouped_by]['time'].''.$subtotals[$prev_grouped_by]['units'].''; $body .= ($canViewReports || $isClient) ? $subtotals[$prev_grouped_by]['cost'] : $subtotals[$prev_grouped_by]['expenses']; @@ -1318,6 +1323,8 @@ static function prepareReportBody($options, $comment = null) $body .= ''.$record['units'].''.htmlspecialchars($record['note']).''.$record['cost_per_hour'].''.$record['cost'].''.$subtotals[$cur_grouped_by]['time'].''.$subtotals[$cur_grouped_by]['units'].''; $body .= ($canViewReports || $isClient) ? $subtotals[$cur_grouped_by]['cost'] : $subtotals[$cur_grouped_by]['expenses']; @@ -1424,6 +1432,7 @@ static function prepareReportBody($options, $comment = null) if ($options['show_duration']) $body .= ''.$totals['time'].''.$totals['units'].''.htmlspecialchars($user->currency).' '; $body .= ($canViewReports || $isClient) ? $totals['cost'] : $totals['expenses']; diff --git a/initialize.php b/initialize.php index ed2fe659a..25386c623 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.9.5728"); +define("APP_VERSION", "1.21.9.5729"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From bd30ae8c78ced5dea93d10b0153f5b677e87891c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 18 Oct 2022 19:32:54 +0000 Subject: [PATCH 1756/1848] Finished adding cost per hour column in reports. --- WEB-INF/templates/display_options.tpl | 2 -- initialize.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index c09a18e9b..5b487ec85 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -49,7 +49,6 @@ License: See license.txt *} {$i18n.label.what_is_it}
{$i18n.form.display_options.custom_css}
{$i18n.entity.time}{$i18n.entity.user}{$i18n.entity.project}
@@ -513,6 +510,19 @@ License: See license.txt *} {/foreach} {/if} +{if isset($custom_fields) && $custom_fields->projectFields} + + {foreach $custom_fields->projectFields as $projectField} + {assign var="control_name" value='project_field_'|cat:$projectField['id']} + {assign var="checkbox_control_name" value='show_project_field_'|cat:$projectField['id']} + + + + + + + {/foreach} +{/if}
{$i18n.label.fav_report}:
{$i18n.form.reports.project_fields}
{$forms.reportForm.$control_name.control} {$forms.reportForm.$checkbox_control_name.control}
diff --git a/initialize.php b/initialize.php index 6033d935a..e6e457301 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.10.5732"); +define("APP_VERSION", "1.21.10.5733"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 4e2f13195..0e52871e2 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -1,31 +1,6 @@ projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,)); + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'data'=>CustomFields::getOptions($projectField['id']), + 'empty'=>array(''=>$i18n->get('dropdown.all')))); + } + // Also add a checkbox (to print the field or not). + $form->addInput(array('type'=>'checkbox','name'=>$checkbox_field_name)); + } +} + // Add group by control. $group_by_options['no_grouping'] = $i18n->get('form.reports.group_by_no'); $group_by_options['date'] = $i18n->get('form.reports.group_by_date'); From ac2e96281d8be1c80d50cc08290609b60fc9f997 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 21 Oct 2022 19:28:55 +0000 Subject: [PATCH 1760/1848] Added handling of custom fields on project_add, project_edit, and project_delete pages. --- WEB-INF/lib/ttProjectHelper.class.php | 11 ++++ WEB-INF/templates/project_add.tpl | 11 ++++ WEB-INF/templates/project_edit.tpl | 12 +++++ project_add.php | 54 +++++++++++++++++-- project_edit.php | 75 ++++++++++++++++++++++++--- user_edit.php | 2 +- 6 files changed, 153 insertions(+), 12 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index e1d5754c5..e6459bd04 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -220,6 +220,17 @@ static function delete($id) { if (!ttClientHelper::deleteProject($id)) return false; + // Mark project custom fields as deleted, + require_once('plugins/CustomFields.class.php'); + $entity_type = CustomFields::ENTITY_PROJECT; + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($user->id); + $sql = "update tt_entity_custom_fields set status = null $modified_part". + " where entity_type = $entity_type and entity_id = $id". + " and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + // Update entities_modified, too. if (!ttGroupHelper::updateEntitiesModified()) return false; diff --git a/WEB-INF/templates/project_add.tpl b/WEB-INF/templates/project_add.tpl index 8cc43fcaa..7b1fd835c 100644 --- a/WEB-INF/templates/project_add.tpl +++ b/WEB-INF/templates/project_add.tpl @@ -15,6 +15,17 @@ License: See license.txt *} +{if isset($custom_fields) && $custom_fields->projectFields} + {foreach $custom_fields->projectFields as $projectField} + {assign var="control_name" value='project_field_'|cat:$projectField['id']} + + + + + + + {/foreach} +{/if} {if $show_files} diff --git a/WEB-INF/templates/project_edit.tpl b/WEB-INF/templates/project_edit.tpl index 3ecc85a84..4e3b02e79 100644 --- a/WEB-INF/templates/project_edit.tpl +++ b/WEB-INF/templates/project_edit.tpl @@ -15,6 +15,18 @@ License: See license.txt *} +{if isset($custom_fields) && $custom_fields->projectFields} + {foreach $custom_fields->projectFields as $projectField} + {assign var="control_name" value='project_field_'|cat:$projectField['id']} + + + + + + + {/foreach} +{/if} + diff --git a/project_add.php b/project_add.php index 35b45c97a..859fdc259 100644 --- a/project_add.php +++ b/project_add.php @@ -19,6 +19,13 @@ } // End of access checks. +// Use custom fields plugin if it is enabled. +if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + $smarty->assign('custom_fields', $custom_fields); +} + $showFiles = $user->isPluginEnabled('at'); $users = ttGroupHelper::getActiveUsers(); foreach ($users as $user_item) @@ -35,6 +42,18 @@ $cl_description = trim($request->getParameter('description')); $cl_users = $request->getParameter('users', array()); $cl_tasks = $request->getParameter('tasks', array()); + // If we have project custom fields - collect input. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $control_name = 'project_field_'.$projectField['id']; + $projectCustomFields[$projectField['id']] = array('field_id' => $projectField['id'], + 'control_name' => $control_name, + 'label' => $projectField['label'], + 'type' => $projectField['type'], + 'required' => $projectField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } } else { foreach ($users as $user_item) $cl_users[] = $user_item['id']; @@ -45,6 +64,20 @@ $form = new Form('projectForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); +// If we have custom fields - add controls for them. +if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$projectCustomFields[$projectField['id']]['value'])); + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'data'=>CustomFields::getOptions($projectField['id']), + 'value'=>$projectCustomFields[$projectField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } + } +} if ($showFiles) $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); $form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); @@ -56,26 +89,37 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + // Validate input in project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($projectCustomFields as $projectField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($projectField['value'], !$projectField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($projectField['label'])); + } + } if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); if ($err->no()) { if (!ttProjectHelper::getProjectByName($cl_name)) { - $id = ttProjectHelper::insert(array('name' => $cl_name, + $project_id = ttProjectHelper::insert(array('name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, 'tasks' => $cl_tasks, 'status' => ACTIVE)); - + // Insert project custom fields if we have them. + $result = true; + if ($project_id && isset($custom_fields) && $custom_fields->projectFields) { + $result = $custom_fields->insertEntityFields(CustomFields::ENTITY_PROJECT, $project_id, $projectCustomFields); + } // Put a new file in storage if we have it. - if ($id && $showFiles && $_FILES['newfile']['name']) { + if ($project_id && $showFiles && $_FILES['newfile']['name']) { $fileHelper = new ttFileHelper($err); $fields = array('entity_type'=>'project', - 'entity_id' => $id, + 'entity_id' => $project_id, 'file_name' => $_FILES['newfile']['name']); $fileHelper->putFile($fields); } - if ($id) { + if ($project_id && $result) { header('Location: projects.php'); exit(); } else diff --git a/project_edit.php b/project_edit.php index 7d8e113dd..a0190ff83 100644 --- a/project_edit.php +++ b/project_edit.php @@ -24,6 +24,13 @@ } // End of access checks. +// Use custom fields plugin if it is enabled. +if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + $smarty->assign('custom_fields', $custom_fields); +} + $users = ttGroupHelper::getActiveUsers(); foreach ($users as $user_item) $all_users[$user_item['id']] = $user_item['name']; @@ -39,9 +46,33 @@ $cl_status = $request->getParameter('status'); $cl_users = $request->getParameter('users', array()); $cl_tasks = $request->getParameter('tasks', array()); + // If we have project custom fields - collect input. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $control_name = 'project_field_'.$projectField['id']; + $projectCustomFields[$projectField['id']] = array('field_id' => $projectField['id'], + 'control_name' => $control_name, + 'label' => $projectField['label'], + 'type' => $projectField['type'], + 'required' => $projectField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } } else { $cl_name = $project['name']; $cl_description = $project['description']; + // If we have project custom fields - collect values from database. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $control_name = 'project_field_'.$projectField['id']; + $projectCustomFields[$projectField['id']] = array('field_id' => $projectField['id'], + 'control_name' => $control_name, + 'label' => $projectField['label'], + 'type' => $projectField['type'], + 'required' => $projectField['required'], + 'value' => $custom_fields->getEntityFieldValue(CustomFields::ENTITY_PROJECT, $cl_project_id, $projectField['id'], $projectField['type'])); + } + } $cl_status = $project['status']; $cl_users = ttProjectHelper::getAssignedUsers($cl_project_id); $cl_tasks = explode(',', $project['tasks']); @@ -51,6 +82,20 @@ $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); +// If we have custom fields - add controls for them. +if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$projectCustomFields[$projectField['id']]['value'])); + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'data'=>CustomFields::getOptions($projectField['id']), + 'value'=>$projectCustomFields[$projectField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } + } +} $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); @@ -63,6 +108,13 @@ // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + // Validate input in project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($projectCustomFields as $projectField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($projectField['value'], !$projectField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($projectField['label'])); + } + } if (!ttValidStatus($cl_status)) $err->add($i18n->get('error.field'), $i18n->get('label.status')); if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); @@ -72,28 +124,39 @@ $existing_project = ttProjectHelper::getProjectByName($cl_name); if (!$existing_project || ($cl_project_id == $existing_project['id'])) { // Update project information. - if (ttProjectHelper::update(array( + $result = ttProjectHelper::update(array( 'id' => $cl_project_id, 'name' => $cl_name, 'description' => $cl_description, 'status' => $cl_status, 'users' => $cl_users, - 'tasks' => $cl_tasks))) { + 'tasks' => $cl_tasks)); + // Update project custom fields if we have them. + if ($result && isset($custom_fields) && $custom_fields->projectFields) { + $result = $custom_fields->updateEntityFields(CustomFields::ENTITY_PROJECT, $cl_project_id, $projectCustomFields); + } + if ($result) { header('Location: projects.php'); exit(); - } else + } else $err->add($i18n->get('error.db')); - } else + } else $err->add($i18n->get('error.object_exists')); } if ($request->getParameter('btn_copy')) { if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array('name' => $cl_name, + $project_id = ttProjectHelper::insert(array('name' => $cl_name, 'description' => $cl_description, 'users' => $cl_users, 'tasks' => $cl_tasks, - 'status' => ACTIVE))) { + 'status' => ACTIVE)); + // Insert project custom fields if we have them. + $result = true; + if ($project_id && isset($custom_fields) && $custom_fields->projectFields) { + $result = $custom_fields->insertEntityFields(CustomFields::ENTITY_PROJECT, $project_id, $projectCustomFields); + } + if ($project_id && $result) { header('Location: projects.php'); exit(); } else diff --git a/user_edit.php b/user_edit.php index 6bdbef693..0633e8a1f 100644 --- a/user_edit.php +++ b/user_edit.php @@ -199,7 +199,7 @@ function render(&$table, $value, $row, $column, $selected = false) { if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); if (!ttValidStatus($cl_status)) $err->add($i18n->get('error.field'), $i18n->get('label.status')); if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); - // Validate input in user custom fields. + // Validate input in user custom fields. if (isset($custom_fields) && $custom_fields->userFields) { foreach ($userCustomFields as $userField) { // Validation is the same for text and dropdown fields. From 2700f1d275ac01a18beeae8f9d3cd124fc214193 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 22 Oct 2022 13:51:57 +0000 Subject: [PATCH 1761/1848] Added a condition on including project custom fields on reports. --- WEB-INF/templates/reports.tpl | 2 +- initialize.php | 2 +- reports.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 370a6d462..6a5ecbbe0 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -510,7 +510,7 @@ function handleCheckboxes() { {/foreach} {/if} -{if isset($custom_fields) && $custom_fields->projectFields} +{if $show_project && isset($custom_fields) && $custom_fields->projectFields} {foreach $custom_fields->projectFields as $projectField} {assign var="control_name" value='project_field_'|cat:$projectField['id']} diff --git a/initialize.php b/initialize.php index e6e457301..f31382c7f 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.10.5733"); +define("APP_VERSION", "1.21.10.5734"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports.php b/reports.php index 2fb61ccdf..6d5b441a4 100644 --- a/reports.php +++ b/reports.php @@ -316,7 +316,7 @@ } // If we have projects custom fields - add controls for them. -if (isset($custom_fields) && $custom_fields->projectFields) { +if ($showProject && isset($custom_fields) && $custom_fields->projectFields) { foreach ($custom_fields->projectFields as $projectField) { $field_name = 'project_field_'.$projectField['id']; $checkbox_field_name = 'show_'.$field_name; From 318f74cc352cbbbd049077bc61375d7e2d4d6ff1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 22 Oct 2022 19:11:06 +0000 Subject: [PATCH 1762/1848] Made progress on including project custom fields on reports. --- WEB-INF/lib/ttProjectHelper.class.php | 2 +- WEB-INF/lib/ttReportHelper.class.php | 276 +++++++++++++++++++++++++- WEB-INF/templates/report.tpl | 36 ++++ initialize.php | 2 +- reports.php | 7 + 5 files changed, 318 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index e6459bd04..bd166e864 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -166,7 +166,7 @@ static function getProjectByName($name) { } - // delete - deletes things associated with a project and marks the project as deleted. + // delete - deletes things associated with a project and marks the project and its custom fields as deleted. static function delete($id) { global $user; $mdb2 = getConnection(); diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 056f4d4fb..85c4d80b4 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -108,6 +108,30 @@ static function getWhere($options) { } } + // Add project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $field_value = $options[$field_name]; + if ($projectField['type'] == CustomFields::TYPE_DROPDOWN && $field_value) { + $cfoTable = 'cfo'.$projectField['id']; + $dropdown_parts .= " and $cfoTable.id = $field_value"; + } + } + } + + // Continue preparing part for text custom fields using LIKE operator. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $field_value = $options[$field_name]; + if ($projectField['type'] == CustomFields::TYPE_TEXT && $field_value) { + $ecfTableName = 'ecf'.$projectField['id']; + $cf_text_parts .= " and $ecfTableName.value like ".$mdb2->quote("%$field_value%"); + } + } + } + // Prepare sql query part for user list. $userlist = isset($options['users']) ? $options['users'] : '-1'; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) @@ -196,6 +220,30 @@ static function getExpenseWhere($options) { } } + // Add project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $field_value = $options[$field_name]; + if ($projectField['type'] == CustomFields::TYPE_DROPDOWN && $field_value) { + $cfoTable = 'cfo'.$projectField['id']; + $dropdown_parts .= " and $cfoTable.id = $field_value"; + } + } + } + + // Continue prparing parts for text custom fields using LIKE operator. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $field_value = $options[$field_name]; + if ($projectField['type'] == CustomFields::TYPE_TEXT && $field_value) { + $ecfTableName = 'ecf'.$projectField['id']; + $cf_text_parts .= " and $ecfTableName.value like ".$mdb2->quote("%$field_value%"); + } + } + } + // Prepare sql query part for user list. $userlist = isset($options['users']) ? $options['users'] : '-1'; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) @@ -306,6 +354,22 @@ static function getItems($options) { } } } + // Add project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($options[$checkbox_field_name] || ttReportHelper::groupingBy($field_name, $options)) { + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + $ecfTableName = 'ecf'.$projectField['id']; + array_push($fields, "$ecfTableName.value as $field_name"); + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTableName = 'cfo'.$projectField['id']; + array_push($fields, "$cfoTableName.value as $field_name"); + } + } + } + } // Add start time. if ($options['show_start']) { array_push($fields, "l.start as unformatted_start"); @@ -372,8 +436,7 @@ static function getItems($options) { // Prepare sql query part for left joins. $left_joins = null; - // Left joins for custom fields. - // 1 join is required for each text field, 2 joins for each dropdown. + // Left joins for user custom fields. if (isset($custom_fields) && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; @@ -393,6 +456,26 @@ static function getItems($options) { } } } + // Left joins for project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_field_name = 'show_'.$field_name; + $entity_type = CustomFields::ENTITY_PROJECT; + if ($options[$field_name] || $options[$checkbox_field_name] || ttReportHelper::groupingBy($field_name, $options)) { + $ecfTable = 'ecf'.$projectField['id']; + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$projectField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } if ($options['show_client'] || $grouping_by_client) $left_joins .= " left join tt_clients c on (c.id = l.client_id)"; if (($canViewReports || $isClient) && $options['show_invoice']) @@ -495,6 +578,22 @@ static function getItems($options) { } } } + // Add project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($options[$checkbox_field_name] || ttReportHelper::groupingBy($field_name, $options)) { + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + $ecfTableName = 'ecf'.$projectField['id']; + array_push($fields, "$ecfTableName.value as $field_name"); + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTableName = 'cfo'.$projectField['id']; + array_push($fields, "$cfoTableName.value as $field_name"); + } + } + } + } if ($options['show_start']) { array_push($fields, 'null'); // null for unformatted_start. array_push($fields, 'null'); // null for start. @@ -557,6 +656,26 @@ static function getItems($options) { } } } + // Left joins for project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_field_name = 'show_'.$field_name; + $entity_type = CustomFields::ENTITY_PROJECT; + if ($options[$field_name] || $options[$checkbox_field_name] || ttReportHelper::groupingBy($field_name, $options)) { + $ecfTable = 'ecf'.$projectField['id']; + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$projectField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } if ($canViewReports || $isClient) $left_joins .= " left join tt_users u on (u.id = ei.user_id)"; if ($options['show_client'] || $grouping_by_client) @@ -826,6 +945,26 @@ static function getTotals($options) } } } + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $field_value = $options[$field_name]; + $entity_type = CustomFields::ENTITY_PROJECT; + if ($field_value) { + // We need to add left joins when input is not null. + $ecfTable = 'ecf'.$projectField['id']; + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$projectField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } if (isset($options['show_cost']) && $options['show_cost']) { if (MODE_TIME == $trackingMode) { $left_joins .= " left join tt_users u on (l.user_id = u.id)"; @@ -876,6 +1015,26 @@ static function getTotals($options) } } } + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $field_value = $options[$field_name]; + $entity_type = CustomFields::ENTITY_PROJECT; + if ($field_value) { + // We need to add left joins when input is not null. + $ecfTable = 'ecf'.$projectField['id']; + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$projectField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $left_joins $where"; @@ -1617,7 +1776,15 @@ static function getReportOptions($bean) { } } - // TODO: add project fields here. + // Project fields. + if ($custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $control_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$control_name; + $options[$control_name] = $bean->getAttribute($control_name); + $options[$checkbox_control_name] = $bean->getAttribute($checkbox_control_name); + } + } } $options['group_by1'] = $bean->getAttribute('group_by1'); @@ -1795,6 +1962,19 @@ static function makeSingleDropdownConcatCustomFieldPart($dropdown_value) { } } } + // Iterate through project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + if ($dropdown_value == $field_name) { + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + return (", ' - ', coalesce(ecf".$projectField['id'].".value, 'Null')"); + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + return (", ' - ', coalesce(cfo".$projectField['id'].".value, 'Null')"); + } + } + } + } // Iterate through time custom fields. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { @@ -1829,6 +2009,19 @@ static function makeSingleDropdownConcatCustomFieldExpensesPart($dropdown_value) } } } + // Iterate through project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + if ($dropdown_value == $field_name) { + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + return (", ' - ', coalesce(ecf".$projectField['id'].".value, 'Null')"); + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + return (", ' - ', coalesce(cfo".$projectField['id'].".value, 'Null')"); + } + } + } + } // Iterate through time custom fields. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { @@ -1882,6 +2075,19 @@ static function makeSingleDropdownGroupByCustomFieldPart($dropdown_value) { } } } + // Iterate through project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + if ($dropdown_value == $field_name) { + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + return (", ecf".$projectField['id'].".value as $field_name"); + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + return (", cfo".$projectField['id'].".value as $field_name"); + } + } + } + } // Iterate through time custom fields. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { @@ -1916,6 +2122,19 @@ static function makeSingleDropdownGroupByCustomFieldExpensesPart($dropdown_value } } } + // Iterate through project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + if ($dropdown_value == $field_name) { + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + return (", ecf".$projectField['id'].".value as $field_name"); + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + return (", cfo".$projectField['id'].".value as $field_name"); + } + } + } + } // Iterate through time custom fields. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { @@ -2151,6 +2370,27 @@ static function makeJoinPart($options) { } } } + // Left joins for project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $field_value = $options[$field_name]; + $entity_type = CustomFields::ENTITY_PROJECT; + if ($field_value || ttReportHelper::groupingBy($field_name, $options)) { + // We need to add left joins when input is not null. + $ecfTable = 'ecf'.$projectField['id']; + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$projectField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } // Prepare inner joins. $inner_joins = null; @@ -2240,6 +2480,27 @@ static function makeJoinExpensesPart($options) { } } } + // Left joins for project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $field_value = $options[$field_name]; + $entity_type = CustomFields::ENTITY_PROJECT; + if ($field_value || ttReportHelper::groupingBy($field_name, $options)) { + // We need to add left joins when input is not null. + $ecfTable = 'ecf'.$projectField['id']; + if ($projectField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + } elseif ($projectField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$projectField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.project_id and $ecfTable.field_id = ".$projectField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } return $left_joins; } @@ -2299,6 +2560,15 @@ static function makeGroupByHeaderPart($dropdown_value) { } } } + // Process project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + if ($dropdown_value == $field_name) { + return $projectField['label']; + } + } + } // Return null if nothing is found. return null; diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 3bd9f448c..b63e505f8 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -47,6 +47,13 @@ License: See license.txt *} {/if} {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} + {* project custom fields *} + {if isset($custom_fields) && $custom_fields->projectFields} + {foreach $custom_fields->projectFields as $projectField} + {assign var="checkbox_control_name" value='show_project_field_'|cat:$projectField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} {if $bean->getAttribute('chtask')}{/if} {* time custom fields *} {if isset($custom_fields) && $custom_fields->timeFields} @@ -91,6 +98,13 @@ License: See license.txt *} {/if} {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} + {* project custom fields *} + {if isset($custom_fields) && $custom_fields->projectFields} + {foreach $custom_fields->projectFields as $projectField} + {assign var="checkbox_control_name" value='show_project_field_'|cat:$projectField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} {if $bean->getAttribute('chtask')}{/if} {* time custom fields *} @@ -136,6 +150,14 @@ License: See license.txt *} {/if} {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} + {* project custom fields *} + {if isset($custom_fields) && $custom_fields->projectFields} + {foreach $custom_fields->projectFields as $projectField} + {assign var="control_name" value='project_field_'|cat:$projectField['id']} + {assign var="checkbox_control_name" value='show_project_field_'|cat:$projectField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} {if $bean->getAttribute('chtask')}{/if} {* time custom fields *} {if isset($custom_fields) && $custom_fields->timeFields} @@ -198,6 +220,13 @@ License: See license.txt *} {/if} {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} + {* project custom fields *} + {if isset($custom_fields) && $custom_fields->projectFields} + {foreach $custom_fields->projectFields as $projectField} + {assign var="checkbox_control_name" value='show_project_field_'|cat:$projectField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} {if $bean->getAttribute('chtask')}{/if} {* time custom fields *} {if isset($custom_fields) && $custom_fields->timeFields} @@ -239,6 +268,13 @@ License: See license.txt *} {/if} {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} + {* project custom fields *} + {if isset($custom_fields) && $custom_fields->projectFields} + {foreach $custom_fields->projectFields as $projectField} + {assign var="checkbox_control_name" value='show_project_field_'|cat:$projectField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} {if $bean->getAttribute('chtask')}{/if} {* time custom fields *} {if isset($custom_fields) && $custom_fields->timeFields} diff --git a/initialize.php b/initialize.php index f31382c7f..90cd73473 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.10.5734"); +define("APP_VERSION", "1.21.10.5735"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports.php b/reports.php index 6d5b441a4..057787e7c 100644 --- a/reports.php +++ b/reports.php @@ -357,6 +357,13 @@ $group_by_options[$field_name] = $userField['label']; } } +// If we have project custom fields - add group by options for them. +if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $group_by_options[$field_name] = $projectField['label']; + } +} $group_by_options_size = sizeof($group_by_options); $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by1','data'=>$group_by_options)); if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by2','data'=>$group_by_options)); From 3837b1a97765e4533b3aa4baf13cc9c78cc6a3fe Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 23 Oct 2022 15:29:04 +0000 Subject: [PATCH 1763/1848] Fixed pdf reports for per hour cost column, fixed all report exports for project custom fields. --- WEB-INF/lib/common.lib.php | 14 +++++++-- WEB-INF/lib/ttReportHelper.class.php | 11 +++++-- initialize.php | 2 +- tofile.php | 24 ++++++++++++++++ topdf.php | 43 ++++++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 2d8e287d5..370816cba 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -555,7 +555,7 @@ function ttMitigateCSRF() { return true; } -// ttStartsWith functions checks if a string starts with a given substring. +// ttStartsWith function checks if a string starts with a given substring. function ttStartsWith($string, $startString) { if (is_null($string)) @@ -565,7 +565,7 @@ function ttStartsWith($string, $startString) return (substr($string, 0, $len) === $startString); } -// ttEndsWith functions checks if a string ends with a given substring. +// ttEndsWith function checks if a string ends with a given substring. function ttEndsWith($string, $endString) { $len = strlen($endString); @@ -573,6 +573,16 @@ function ttEndsWith($string, $endString) return (substr($string, -$len) === $endString); } +// ttContains functions checks if a string contains a given substring. +function ttContains($string, $part) +{ + // Note: in php8 we can use str_contanins. + if (strpos($string, $part) !== false) + return true; + + return false; +} + // ttDateToUserFormat converts a date from database format to user format. function ttDateToUserFormat($date) { diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 85c4d80b4..6cfc1464a 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -232,7 +232,7 @@ static function getExpenseWhere($options) { } } - // Continue prparing parts for text custom fields using LIKE operator. + // Continue preparing parts for text custom fields using LIKE operator. if (isset($custom_fields) && $custom_fields->projectFields) { foreach ($custom_fields->projectFields as $projectField) { $field_name = 'project_field_'.$projectField['id']; @@ -2533,7 +2533,7 @@ static function makeGroupByHeaderPart($dropdown_value) { // First, try to get a label from a translation file, which is the most likely scenario // such as grouping by date, user, project, or task. - if (!ttStartsWith($dropdown_value, 'time_field_') && !ttStartsWith($dropdown_value, 'user_field_')) { + if (!ttContains($dropdown_value, '_field_')) { $key = 'label.'.$dropdown_value; $part = $i18n->get($key); if ($part) return $part; @@ -2605,6 +2605,13 @@ static function makeGroupByHeader($options) { // makeGroupByXmlTag creates an xml tag for a totals only report using group_by1, // group_by2, and group_by3 values passed in $options. static function makeGroupByXmlTag($options) { + // Note: there is a problem with this function for custom fields. + // Returned xml tags are like "project_field_1134" and not their user entered labels. + // This is on purpose because we are trying to avoid potential XML parsing problems. + // See https://stackoverflow.com/questions/1478486/using-in-xml-element-name + // Perhaps review this if someone complains, but there are W3C standard (section 2.3) rules + // on names (including starting character). + $tag = ''; if ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') { // We have group_by1. diff --git a/initialize.php b/initialize.php index 90cd73473..d24ca7fa9 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.10.5735"); +define("APP_VERSION", "1.21.11.5736"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/tofile.php b/tofile.php index 6ea39ad82..0134885f8 100644 --- a/tofile.php +++ b/tofile.php @@ -106,6 +106,14 @@ } if ($bean->getAttribute('chclient')) print "\t\n"; if ($bean->getAttribute('chproject')) print "\t\n"; + // Project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) print "\t<$field_name>\n"; + } + } if ($bean->getAttribute('chtask')) print "\t\n"; // Time custom fields. if (isset($custom_fields) && $custom_fields->timeFields) { @@ -206,6 +214,14 @@ } if ($bean->getAttribute('chclient')) print ',"'.$i18n->get('label.client').'"'; if ($bean->getAttribute('chproject')) print ',"'.$i18n->get('label.project').'"'; + // Project custom field labels. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) print ',"'.ttNeutralizeForCsv($projectField['label']).'"'; + } + } if ($bean->getAttribute('chtask')) print ',"'.$i18n->get('label.task').'"'; // Time custom field labels. if (isset($custom_fields) && $custom_fields->timeFields) { @@ -246,6 +262,14 @@ } if ($bean->getAttribute('chclient')) print ',"'.ttNeutralizeForCsv($item['client']).'"'; if ($bean->getAttribute('chproject')) print ',"'.ttNeutralizeForCsv($item['project']).'"'; + // Project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) print ',"'.ttNeutralizeForCsv($item[$field_name]).'"'; + } + } if ($bean->getAttribute('chtask')) print ',"'.ttNeutralizeForCsv($item['task']).'"'; // Time custom fields. if (isset($custom_fields) && $custom_fields->timeFields) { diff --git a/topdf.php b/topdf.php index 931fa8145..4e1e677db 100644 --- a/topdf.php +++ b/topdf.php @@ -139,6 +139,14 @@ } if ($bean->getAttribute('chclient')) { $colspan++; $html .= ''; } if ($bean->getAttribute('chproject')) { $colspan++; $html .= ''; } + // Project custom field labels. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) { $colspan++; $html .= ''; } + } + } if ($bean->getAttribute('chtask')) { $colspan++; $html .= ''; } // Time custom field labels. if (isset($custom_fields) && $custom_fields->timeFields) { @@ -194,6 +202,14 @@ $html .= htmlspecialchars($subtotals[$prev_grouped_by]['project']); $html .= ''; } + // Project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } + } if ($bean->getAttribute('chtask')) { $html .= ''; if ($bean->getAttribute('chunits')) $html .= "'; if ($show_note_column) $html .= ''; + if ($bean->getAttribute('chcost') && $show_cost_per_hour) $html .= ''; if ($bean->getAttribute('chcost')) { $html .= "'; if ($bean->getAttribute('chproject')) $html .= ''; + // Project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } + } if ($bean->getAttribute('chtask')) $html .= ''; // Time custom fields. if (isset($custom_fields) && $custom_fields->timeFields) { @@ -339,6 +364,14 @@ $html .= htmlspecialchars($subtotals[$prev_grouped_by]['project']); $html .= ''; } + // Project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } + } if ($bean->getAttribute('chtask')) { $html .= ''; if ($bean->getAttribute('chunits')) $html .= "'; if ($show_note_column) $html .= ''; + if ($bean->getAttribute('chcost') && $show_cost_per_hour) $html .= ''; if ($bean->getAttribute('chcost')) { $html .= "'; if ($bean->getAttribute('chproject')) $html .= ''; + // Project custom fields. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } + } if ($bean->getAttribute('chtask')) $html .= ''; // Time custom fields. if (isset($custom_fields) && $custom_fields->timeFields) { @@ -402,6 +444,7 @@ if ($bean->getAttribute('chduration')) $html .= "'; if ($bean->getAttribute('chunits')) $html .= "'; if ($show_note_column) $html .= ''; + if ($bean->getAttribute('chcost') && $show_cost_per_hour) $html .= ''; if ($bean->getAttribute('chcost')) { $html .= "'; if ($options['show_project']) $body .= ''; + // Project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_task']) $body .= ''; // Time custom fields. @@ -1412,6 +1428,14 @@ static function prepareReportBody($options, $comment = null) } if ($options['show_client']) $body .= ''; if ($options['show_project']) $body .= ''; + // Project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_task']) $body .= ''; // Time custom fields. if ($custom_fields && $custom_fields->timeFields) { @@ -1462,6 +1486,14 @@ static function prepareReportBody($options, $comment = null) $body .= ''; if ($options['show_project']) $body .= ''; + // Project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_task']) $body .= ''; // Time custom fields. @@ -1534,6 +1566,14 @@ static function prepareReportBody($options, $comment = null) } if ($options['show_client']) $body .= ''; if ($options['show_project']) $body .= ''; + // Project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_task']) $body .= ''; // Time custom fields. if ($custom_fields && $custom_fields->timeFields) { @@ -1577,6 +1617,14 @@ static function prepareReportBody($options, $comment = null) } if ($options['show_client']) $body .= ''; if ($options['show_project']) $body .= ''; + // Project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_task']) $body .= ''; // Time custom fields. if ($custom_fields && $custom_fields->timeFields) { diff --git a/initialize.php b/initialize.php index d24ca7fa9..d310471ee 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.11.5736"); +define("APP_VERSION", "1.21.11.5737"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 95481ddf41d2914555d8b48b6dcfd7acb7aa25f1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 23 Oct 2022 16:15:16 +0000 Subject: [PATCH 1765/1848] Fixed fav reports to keep project custom fields settings. --- WEB-INF/lib/ttFavReportHelper.class.php | 23 +++++++++++++++++++++++ initialize.php | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index df756649e..0d8cc071f 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -328,6 +328,17 @@ static function loadReport(&$bean) { $bean->setAttribute($checkbox_field_name, $checkbox_value); } } + // Project custom field settings. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_field_name = 'show_'.$field_name; + $field_value = ttFavReportHelper::getFieldSettingFromReportSpec($field_name, $report_spec); + $bean->setAttribute($field_name, $field_value); + $checkbox_value = ttFavReportHelper::getFieldSettingFromReportSpec($checkbox_field_name, $report_spec); + $bean->setAttribute($checkbox_field_name, $checkbox_value); + } + } } $bean->setAttribute('client', $val['client_id']); @@ -579,6 +590,18 @@ static function makeReportSpec($bean) { } } + // Add project custom field settings. + if (isset($custom_fields) && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $field_value = str_replace(',',',',$bean->getAttribute($field_name)); + $checkbox_field_name = 'show_'.$field_name; + $checkbox_field_value = (int) $bean->getAttribute($checkbox_field_name); + if ($field_value) $reportSpecArray[] = $field_name.':'.$field_value; + if ($checkbox_field_value) $reportSpecArray[] = $checkbox_field_name.':1'; + } + } + $reportSpec = null; if (isset($reportSpecArray)) $reportSpec = implode(',', $reportSpecArray); diff --git a/initialize.php b/initialize.php index d310471ee..5ff396459 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.11.5737"); +define("APP_VERSION", "1.21.11.5738"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 10713c13048462dbd2c33c7cc38492f4c7a140af Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 23 Oct 2022 16:24:37 +0000 Subject: [PATCH 1766/1848] Fixed adjusting fav report options for cron. --- WEB-INF/lib/ttFavReportHelper.class.php | 12 +++++++++++- initialize.php | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 0d8cc071f..00a1bd5bb 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -541,7 +541,17 @@ static function adjustOptions($options) { $options[$checkbox_field_name] = $checkbox_value; } } - // TODO: add project fields here. + // Project fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_field_name = 'show_'.$field_name; + $field_value = ttFavReportHelper::getFieldSettingFromReportSpec($field_name, $report_spec); + $options[$field_name] = $field_value; + $checkbox_value = ttFavReportHelper::getFieldSettingFromReportSpec($checkbox_field_name, $report_spec); + $options[$checkbox_field_name] = $checkbox_value; + } + } } // Adjust period_start and period_end to user date format. diff --git a/initialize.php b/initialize.php index 5ff396459..5fd8012f6 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.11.5738"); +define("APP_VERSION", "1.21.11.5739"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 00a75a7ed04fa22de4211891580deee454f04ec2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 23 Oct 2022 16:32:14 +0000 Subject: [PATCH 1767/1848] Initial implementation of project custom fields. --- cf_custom_field_add.php | 17 +++++------------ initialize.php | 2 +- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index 38d672822..c10803758 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -27,18 +27,11 @@ $form = new Form('fieldForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>'')); -if (defined('DEBUG_PROJECT_CUSTOM_FIELDS')) { - $form->addInput(array('type'=>'combobox','name'=>'entity', - 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('entity.time'), - CustomFields::ENTITY_USER=>$i18n->get('entity.user'), - CustomFields::ENTITY_PROJECT=>$i18n->get('entity.project')) - )); -} else { - $form->addInput(array('type'=>'combobox','name'=>'entity', - 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('entity.time'), - CustomFields::ENTITY_USER=>$i18n->get('entity.user')) - )); -} +$form->addInput(array('type'=>'combobox','name'=>'entity', + 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('entity.time'), + CustomFields::ENTITY_USER=>$i18n->get('entity.user'), + CustomFields::ENTITY_PROJECT=>$i18n->get('entity.project')) +)); $form->addInput(array('type'=>'combobox','name'=>'type', 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->get('label.type_text'), CustomFields::TYPE_DROPDOWN=>$i18n->get('label.type_dropdown')) diff --git a/initialize.php b/initialize.php index 5fd8012f6..552e5e2cb 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.11.5739"); +define("APP_VERSION", "1.21.12.5740"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From c0ae1e6d07f2a64e4d54e47133b5bfda29ffcf87 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 25 Oct 2022 16:26:46 +0000 Subject: [PATCH 1768/1848] Added a what is it link explaining note cotaining option in reports. --- WEB-INF/templates/reports.tpl | 5 ++++- initialize.php | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 6a5ecbbe0..42cdd661f 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -358,7 +358,10 @@ function handleCheckboxes() { - +
{$forms.projectForm.description.control}
{$forms.projectForm.$control_name.control}
{$forms.projectForm.description.control}
{$forms.projectForm.$control_name.control}
{$i18n.form.reports.project_fields}
{$i18n.label.client}{$i18n.label.project}{{$projectField['label']|escape}}{$i18n.label.task}{$subtotals[$prev_grouped_by]['client']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$item.client|escape}{$item.project|escape}{$item.$control_name|escape}{$item.task|escape}{$subtotals[$cur_grouped_by]['client']|escape}{$subtotals[$cur_grouped_by]['project']|escape}{$subtotals[$cur_grouped_by]['task']|escape}'.$i18n->get('label.client').''.$i18n->get('label.project').''.htmlspecialchars($projectField['label']).''.$i18n->get('label.task').''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['task']); @@ -212,6 +228,7 @@ if ($bean->getAttribute('chduration')) $html .= "".$subtotals[$prev_grouped_by]['time'].'".$subtotals[$prev_grouped_by]['units'].'"; if ($user->can('manage_invoices') || $user->isClient()) @@ -254,6 +271,14 @@ } if ($bean->getAttribute('chclient')) $html .= ''.htmlspecialchars($item['client']).''.htmlspecialchars($item['project']).''.htmlspecialchars($item[$field_name]).''.htmlspecialchars($item['task']).''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['task']); @@ -357,6 +390,7 @@ if ($bean->getAttribute('chduration')) $html .= "".$subtotals[$prev_grouped_by]['time'].'".$subtotals[$prev_grouped_by]['units'].'"; if ($user->can('manage_invoices') || $user->isClient()) @@ -388,6 +422,14 @@ } if ($bean->getAttribute('chclient')) $html .= '".$totals['time'].'".$totals['units'].'".htmlspecialchars($user->currency).' '; if ($user->can('manage_invoices') || $user->isClient()) From 0ec60fc296df0ca7447db3e2b725c8bbcac24e39 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 23 Oct 2022 15:46:07 +0000 Subject: [PATCH 1764/1848] Fixed emailed reports to handle project custom fields. --- WEB-INF/lib/common.lib.php | 2 +- WEB-INF/lib/ttReportHelper.class.php | 48 ++++++++++++++++++++++++++++ initialize.php | 2 +- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 370816cba..0f38f80fa 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -573,7 +573,7 @@ function ttEndsWith($string, $endString) return (substr($string, -$len) === $endString); } -// ttContains functions checks if a string contains a given substring. +// ttContains function checks if a string contains a given substring. function ttContains($string, $part) { // Note: in php8 we can use str_contanins. diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 6cfc1464a..a3f894497 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1232,6 +1232,14 @@ static function prepareReportBody($options, $comment = null) } if ($options['show_client']) $colspan++; if ($options['show_project']) $colspan++; + // Project custom fields. + if ($custom_fields && $custom_fields->projectFields) { + foreach ($custom_fields->projectFields as $projectField) { + $field_name = 'project_field_'.$projectField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $colspan++; + } + } if ($options['show_task']) $colspan++; // Time custom fields. if ($custom_fields && $custom_fields->timeFields) { @@ -1342,6 +1350,14 @@ static function prepareReportBody($options, $comment = null) $body .= ''.$i18n->get('label.client').''.$i18n->get('label.project').''.htmlspecialchars($projectField['label']).''.$i18n->get('label.task').''.$subtotals[$prev_grouped_by]['client'].''.$subtotals[$prev_grouped_by]['project'].''.$subtotals[$prev_grouped_by]['task'].''.htmlspecialchars($record['client']).''.htmlspecialchars($record['project']).''.htmlspecialchars($record[$field_name]).''.htmlspecialchars($record['task']).''.$subtotals[$prev_grouped_by]['client'].''.$subtotals[$prev_grouped_by]['project'].''.$subtotals[$prev_grouped_by]['task'].'
{$forms.reportForm.note_containing.control}{$forms.reportForm.note_containing.control} + {$i18n.label.what_is_it} + {$i18n.label.what_is_it} +
diff --git a/initialize.php b/initialize.php index 552e5e2cb..0e90ef89d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.12.5740"); +define("APP_VERSION", "1.21.12.5741"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 3102ef6e950150eccccee5f63922bf25fae8a83c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 27 Oct 2022 15:18:50 +0000 Subject: [PATCH 1769/1848] Version change for 1.22 release. --- initialize.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initialize.php b/initialize.php index 0e90ef89d..7fcb17aa2 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.21.12.5741"); +define("APP_VERSION", "1.22.0.5742"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From c4d2026603df8fa31a31f2ea440df436d67df7a7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 27 Oct 2022 19:55:16 +0000 Subject: [PATCH 1770/1848] Addressed some php8 warnings. --- WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/lib/ttWeekViewHelper.class.php | 108 +++++++++++++++++++------ initialize.php | 2 +- 3 files changed, 86 insertions(+), 26 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index e0565b3dd..2e7ff2793 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -682,7 +682,7 @@ function updateGroup($fields) { $name_part = $description_part = $currency_part = $lang_part = $decimal_mark_part = $date_format_part = $time_format_part = $week_start_part = $tracking_mode_part = $project_required_part = $record_type_part = $bcc_email_part = $allow_ip_part = - $plugins_part = $config_part = $custom_css_part = $lock_spec_part = $holidays_part = $workday_minutes_part = ''; + $password_complexity_part = $plugins_part = $config_part = $custom_css_part = $lock_spec_part = $holidays_part = $workday_minutes_part = ''; if (isset($fields['name'])) $name_part = ', name = '.$mdb2->quote($fields['name']); if (isset($fields['description'])) $description_part = ', description = '.$mdb2->quote($fields['description']); if (isset($fields['currency'])) $currency_part = ', currency = '.$mdb2->quote($fields['currency']); diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index 9908d12b4..4ee5346a9 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -167,22 +167,37 @@ static function getDataForWeekView($records, $dayHeaders) { global $i18n; $dataArray = array(); + $includeWeekends = $user->isOptionEnabled('weekends'); $includeNotes = $user->isOptionEnabled('week_notes'); // Construct the first row for a brand new entry. $dataArray[] = array('row_id' => null,'label' => $i18n->get('form.week.new_entry').':'); // Insert row. // Insert empty cells with proper control ids. - for ($i = 0; $i < 7; $i++) { - $control_id = '0_'. $dayHeaders[$i]; - $dataArray[0][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + if ($includeWeekends) { + for ($i = 0; $i < 7; $i++) { + $control_id = '0_'. $dayHeaders[$i]; + $dataArray[0][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + } + } else { + for ($i = 1; $i < 6; $i++) { + $control_id = '0_'. $dayHeaders[$i]; + $dataArray[0][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + } } if ($includeNotes) { // Construct the second row for daily comments for a brand new entry. $dataArray[] = array('row_id' => null,'label' => $i18n->get('label.notes').':'); // Insert row. // Insert empty cells with proper control ids. - for ($i = 0; $i < 7; $i++) { - $control_id = '1_'. $dayHeaders[$i]; - $dataArray[1][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + if ($includeWeekends) { + for ($i = 0; $i < 7; $i++) { + $control_id = '1_'. $dayHeaders[$i]; + $dataArray[1][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + } + } else { + for ($i = 1; $i < 6; $i++) { + $control_id = '1_'. $dayHeaders[$i]; + $dataArray[1][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + } } } @@ -205,18 +220,32 @@ static function getDataForWeekView($records, $dayHeaders) { $dataArray[] = array('row_id' => $row_id,'label' => ttWeekViewHelper::makeRowLabel($record)); $pos = ttWeekViewHelper::findRow($row_id, $dataArray); // Insert empty cells with proper control ids. - for ($i = 0; $i < 7; $i++) { - $control_id = $pos.'_'. $dayHeaders[$i]; - $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + if ($includeWeekends) { + for ($i = 0; $i < 7; $i++) { + $control_id = $pos.'_'. $dayHeaders[$i]; + $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + } + } else { + for ($i = 1; $i < 6; $i++) { + $control_id = $pos.'_'. $dayHeaders[$i]; + $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + } } // Insert row for comments. if ($includeNotes) { $dataArray[] = array('row_id' => $row_id.'_notes','label' => $i18n->get('label.notes').':'); $pos++; // Insert empty cells with proper control ids. - for ($i = 0; $i < 7; $i++) { - $control_id = $pos.'_'. $dayHeaders[$i]; - $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + if ($includeWeekends) { + for ($i = 0; $i < 7; $i++) { + $control_id = $pos.'_'. $dayHeaders[$i]; + $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + } + } else { + for ($i = 1; $i < 6; $i++) { + $control_id = $pos.'_'. $dayHeaders[$i]; + $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + } } $pos--; } @@ -267,21 +296,38 @@ static function prePopulateFromPastWeeks($startDate, $dayHeaders) { } } + // We will need this for iterations below. + $includeWeekends = $user->isOptionEnabled('weekends'); + // Construct the first row for a brand new entry. $dataArray[] = array('row_id' => null,'label' => $i18n->get('form.week.new_entry').':'); // Insert row. // Insert empty cells with proper control ids. - for ($i = 0; $i < 7; $i++) { - $control_id = '0_'. $dayHeaders[$i]; - $dataArray[0][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + if ($includeWeekends) { + for ($i = 0; $i < 7; $i++) { + $control_id = '0_'. $dayHeaders[$i]; + $dataArray[0][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + } + } else { + for ($i = 1; $i < 6; $i++) { + $control_id = '0_'. $dayHeaders[$i]; + $dataArray[0][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + } } $includeNotes = $user->isOptionEnabled('week_notes'); if ($includeNotes) { // Construct the second row for daily comments for a brand new entry. $dataArray[] = array('row_id' => null,'label' => $i18n->get('label.notes').':'); // Insert row. // Insert empty cells with proper control ids. - for ($i = 0; $i < 7; $i++) { - $control_id = '1_'. $dayHeaders[$i]; - $dataArray[1][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + if ($includeWeekends) { + for ($i = 0; $i < 7; $i++) { + $control_id = '1_'. $dayHeaders[$i]; + $dataArray[1][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + } + } else { + for ($i = 1; $i < 6; $i++) { + $control_id = '1_'. $dayHeaders[$i]; + $dataArray[1][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + } } } @@ -296,18 +342,32 @@ static function prePopulateFromPastWeeks($startDate, $dayHeaders) { $dataArray[] = array('row_id' => $row_id,'label' => ttWeekViewHelper::makeRowLabel($record)); $pos = ttWeekViewHelper::findRow($row_id, $dataArray); // Insert empty cells with proper control ids. - for ($i = 0; $i < 7; $i++) { - $control_id = $pos.'_'. $dayHeaders[$i]; - $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + if ($includeWeekends) { + for ($i = 0; $i < 7; $i++) { + $control_id = $pos.'_'. $dayHeaders[$i]; + $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + } + } else { + for ($i = 1; $i < 6; $i++) { + $control_id = $pos.'_'. $dayHeaders[$i]; + $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'duration' => null); + } } // Insert row for comments. if ($includeNotes) { $dataArray[] = array('row_id' => $row_id.'_notes','label' => $i18n->get('label.notes').':'); $pos++; // Insert empty cells with proper control ids. - for ($i = 0; $i < 7; $i++) { - $control_id = $pos.'_'. $dayHeaders[$i]; - $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + if ($includeWeekends) { + for ($i = 0; $i < 7; $i++) { + $control_id = $pos.'_'. $dayHeaders[$i]; + $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + } + } else { + for ($i = 1; $i < 6; $i++) { + $control_id = $pos.'_'. $dayHeaders[$i]; + $dataArray[$pos][$dayHeaders[$i]] = array('control_id' => $control_id, 'tt_log_id' => null,'note' => null); + } } $pos--; } diff --git a/initialize.php b/initialize.php index 7fcb17aa2..04f1245cf 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.0.5742"); +define("APP_VERSION", "1.22.0.5743"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From c2c48e291c4b12bb2e8fb5c64fc25ea5d1ae17b5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 28 Oct 2022 13:57:06 +0000 Subject: [PATCH 1771/1848] Fixed a bug on week view related to locking. Addressed a few php8 warnings. --- WEB-INF/templates/charts.tpl | 2 +- WEB-INF/templates/expenses.tpl | 2 +- WEB-INF/templates/time.tpl | 2 +- WEB-INF/templates/timesheets.tpl | 2 +- WEB-INF/templates/week.tpl | 2 +- initialize.php | 2 +- week.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/charts.tpl b/WEB-INF/templates/charts.tpl index ff15ea8f2..b38988e89 100644 --- a/WEB-INF/templates/charts.tpl +++ b/WEB-INF/templates/charts.tpl @@ -25,7 +25,7 @@ function adjustTodayLinks() {
{$forms.chartForm.date.control}
-{if $user_dropdown} +{if isset($user_dropdown)} diff --git a/WEB-INF/templates/expenses.tpl b/WEB-INF/templates/expenses.tpl index 5b1da05fc..859ae3506 100644 --- a/WEB-INF/templates/expenses.tpl +++ b/WEB-INF/templates/expenses.tpl @@ -119,7 +119,7 @@ function recalculateCost() {
{$forms.expensesForm.date.control}
{$forms.chartForm.date.control}
-{if $user_dropdown} +{if isset($user_dropdown)} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index b601531ba..fa24e8062 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -23,7 +23,7 @@ function handleStop(buttonElement) {
{$forms.timeRecordForm.date.control}
{$forms.expensesForm.date.control}
-{if $user_dropdown} +{if isset($user_dropdown)} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index e5f9abdb6..2bd927369 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -7,7 +7,7 @@ License: See license.txt *} {$forms.timesheetsForm.open}
{$forms.timeRecordForm.date.control}
-{if $user_dropdown} +{if isset($user_dropdown)} diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl index 74e94053f..6032d4eb5 100644 --- a/WEB-INF/templates/week.tpl +++ b/WEB-INF/templates/week.tpl @@ -28,7 +28,7 @@ function fillDropdowns() {
{$forms.weekTimeForm.date.control}
-{if $user_dropdown} +{if isset($user_dropdown)} diff --git a/initialize.php b/initialize.php index 04f1245cf..1ebbab823 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.0.5743"); +define("APP_VERSION", "1.22.1.5744"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/week.php b/week.php index 302e4dfb3..9d96abfbe 100644 --- a/week.php +++ b/week.php @@ -228,7 +228,7 @@ function render(&$table, $value, $row, $column, $selected = false) { $field = new TextField($field_name); // Disable control if the date is locked. global $lockedDays; - if ($lockedDays[$column-1]) + if ($lockedDays[$column]) $field->setEnabled(false); $field->setFormName($table->getFormName()); $field->setStyle('width: 60px;'); // TODO: need to style everything properly, eventually. From 50796b8d606dae53f1c39fa08e44be4f86e863f4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 28 Oct 2022 15:40:46 +0000 Subject: [PATCH 1772/1848] Addressed a few more php8 warnings. --- WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/lib/ttUserHelper.class.php | 3 ++- initialize.php | 2 +- topdf.php | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 2e7ff2793..b32c27792 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -151,7 +151,7 @@ function __construct($login, $id = null) { // getUser returns user id on behalf of whom the current user is operating. function getUser() { - return ($this->behalfUser ? $this->behalfUser->id : $this->id); + return (isset($this->behalfUser) ? $this->behalfUser->id : $this->id); } // getName returns user name on behalf of whom the current user is operating. diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index 122c7889c..2aeada43c 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -68,7 +68,8 @@ static function getUserIdByTmpRef($ref) { if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - return $val['user_id']; + if ($val) + return $val['user_id']; } return false; } diff --git a/initialize.php b/initialize.php index 1ebbab823..432cbb891 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.1.5744"); +define("APP_VERSION", "1.22.1.5745"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/topdf.php b/topdf.php index 4e1e677db..6393d5f55 100644 --- a/topdf.php +++ b/topdf.php @@ -55,6 +55,7 @@ $totals = ttReportHelper::getTotals($options); // Totals for the entire report. // Assign variables that are used to print subtotals. +$print_subtotals = $first_pass = false; if ($items && $grouping) { $print_subtotals = true; $first_pass = true; From 89cae455e41364dec480637ec387e3e849e84c25 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 5 Nov 2022 14:59:31 +0000 Subject: [PATCH 1773/1848] Started work on adding a fav report selector on charts. --- WEB-INF/templates/charts.tpl | 67 ++++++++++++++++++++++++++++++------ charts.php | 16 ++++++++- initialize.php | 2 +- 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/WEB-INF/templates/charts.tpl b/WEB-INF/templates/charts.tpl index b38988e89..ee0c48346 100644 --- a/WEB-INF/templates/charts.tpl +++ b/WEB-INF/templates/charts.tpl @@ -19,26 +19,59 @@ function adjustTodayLinks() { } } } + +// handleFavReportSelection - manages visibility of controls that are not relevant +// when a fav report is selected. +function handleFavReportSelection() { + var selectedFavReportId = document.getElementById("favorite_report").value; + + var userLabel = document.getElementById("user_label"); + var userControl = document.getElementById("user_control"); + var intervalLabel = document.getElementById("interval_label"); + var intervalControl = document.getElementById("interval_control"); + + if (selectedFavReportId == -1) { + if (userLabel != null) { + userLabel.style.display = ""; + } + if (userControl != null) { + userControl.style.display = ""; + } + if (intervalLabel != null) { + intervalLabel.style.display = ""; + } + if (intervalControl != null) { + intervalControl.style.display = ""; + } + } else { + if (userLabel != null) { + userLabel.style.display = "none"; + } + if (userControl != null) { + userControl.style.display = "none"; + } + if (intervalLabel != null) { + intervalLabel.style.display = "none"; + } + if (intervalControl != null) { + intervalControl.style.display = "none"; + } + } +} {$forms.chartForm.open}
{$forms.chartForm.date.control}
{$forms.weekTimeForm.date.control}
-{if isset($user_dropdown)} - +{if defined('FAV_REPORTS_ON_CHARTS_DEBUG')} + - - + + {/if} - - - - - - {if $chart_selector} @@ -47,6 +80,20 @@ function adjustTodayLinks() { {/if} +{if isset($user_dropdown)} + + + + + + +{/if} + + + + + +
{$forms.chartForm.date.control}
{$forms.chartForm.user.control}{$forms.chartForm.favorite_report.control}
{$forms.chartForm.interval.control}
{$forms.chartForm.user.control}
{$forms.chartForm.interval.control}
diff --git a/charts.php b/charts.php index 1ad1c88d9..10335594a 100644 --- a/charts.php +++ b/charts.php @@ -12,6 +12,7 @@ import('PieChartEx'); import('ttUserHelper'); import('ttTeamHelper'); +import('ttFavReportHelper'); define('ALL_USERS_OPTION_ID', -1); // An identifier for "all users" seclection in User dropdown. @@ -106,7 +107,7 @@ // Set user selection to all users, if necessary. $allUsersSetInSession = @$_SESSION['chart_all_users']; if ($allUsersSetInSession) - $userDropdownSelectionId = constant('ALL_USERS_OPTION_ID'); + $userDropdownSelectionId = constant('ALL_USERS_OPTION_ID'); } // Elements of chartForm. @@ -177,6 +178,19 @@ $largeScreenCalendarRowSpan += 2; } +// Fav report control. +if (defined('FAV_REPORTS_ON_CHARTS_DEBUG')) { + // Get saved favorite reports for user. + $report_list = ttFavReportHelper::getReports(); + $chart_form->addInput(array('type'=>'combobox', + 'name'=>'favorite_report', + 'onchange'=>'handleFavReportSelection();this.form.submit();', + 'data'=>$report_list, + 'datakeys'=>array('id','name'), + 'empty'=>array('-1'=>$i18n->get('dropdown.no')))); + $largeScreenCalendarRowSpan += 2; +} + // Calendar. $chart_form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar diff --git a/initialize.php b/initialize.php index 432cbb891..8bc3c5f4c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.1.5745"); +define("APP_VERSION", "1.22.1.5746"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 6f0f261a87ab5c4bd59866a45c087f17af044cd3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 5 Nov 2022 16:17:41 +0000 Subject: [PATCH 1774/1848] Some progress on handling fav reports in charts. --- charts.php | 97 ++++++++++++++++++++++++++++---------------------- initialize.php | 2 +- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/charts.php b/charts.php index 10335594a..aa0b9bd51 100644 --- a/charts.php +++ b/charts.php @@ -79,10 +79,9 @@ $_SESSION['date'] = $cl_date; if ($request->isPost()) { - $cl_interval = (int)$request->getParameter('interval'); - if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; - $_SESSION['chart_interval'] = $cl_interval; - $uc->setValue(SYSC_CHART_INTERVAL, $cl_interval); + $cl_fav_report = (int)$request->getParameter('favorite_report'); + if (!$cl_fav_report) $cl_fav_report = -1; + $_SESSION['fav_report'] = $cl_fav_report; $cl_type = (int)$request->getParameter('type'); if (!$cl_type) $cl_type = ttChartHelper::adjustType($cl_type); @@ -91,12 +90,16 @@ // Remember all users selection in session. $_SESSION['chart_all_users'] = $userDropdownSelectionId == constant('ALL_USERS_OPTION_ID') ? true : false; -} else { - // Initialize chart interval. - $cl_interval = @$_SESSION['chart_interval']; - if (!$cl_interval) $cl_interval = $uc->getValue(SYSC_CHART_INTERVAL); + + $cl_interval = (int)$request->getParameter('interval'); if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; $_SESSION['chart_interval'] = $cl_interval; + $uc->setValue(SYSC_CHART_INTERVAL, $cl_interval); +} else { + // Initialize fav report selector. + $cl_fav_report = @$_SESSION['fav_report']; + if (!$cl_fav_report) $cl_fav_report = -1; + $_SESSION['fav_report'] = $cl_fav_report; // Initialize chart type. $cl_type = @$_SESSION['chart_type']; @@ -108,12 +111,53 @@ $allUsersSetInSession = @$_SESSION['chart_all_users']; if ($allUsersSetInSession) $userDropdownSelectionId = constant('ALL_USERS_OPTION_ID'); + + // Initialize chart interval. + $cl_interval = @$_SESSION['chart_interval']; + if (!$cl_interval) $cl_interval = $uc->getValue(SYSC_CHART_INTERVAL); + if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; + $_SESSION['chart_interval'] = $cl_interval; } // Elements of chartForm. $chart_form = new Form('chartForm'); $largeScreenCalendarRowSpan = 1; // Number of rows calendar spans on large screens. +// Fav report control. +if (defined('FAV_REPORTS_ON_CHARTS_DEBUG')) { + // Get saved favorite reports for user. + $report_list = ttFavReportHelper::getReports(); + $chart_form->addInput(array('type'=>'combobox', + 'name'=>'favorite_report', + 'onchange'=>'handleFavReportSelection();this.form.submit();', + 'data'=>$report_list, + 'value' => $cl_fav_report, + 'datakeys'=>array('id','name'), + 'empty'=>array('-1'=>$i18n->get('dropdown.no')))); + $largeScreenCalendarRowSpan += 2; +} + +// Chart type options. +$chart_selector = (MODE_PROJECTS_AND_TASKS == $tracking_mode || $user->isPluginEnabled('cl')); +if ($chart_selector) { + $types = array(); + if (MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode) + $types[CHART_PROJECTS] = $i18n->get('dropdown.projects'); + if (MODE_PROJECTS_AND_TASKS == $tracking_mode) + $types[CHART_TASKS] = $i18n->get('dropdown.tasks'); + if ($user->isPluginEnabled('cl')) + $types[CHART_CLIENTS] = $i18n->get('dropdown.clients'); + + // Add chart type dropdown. + $chart_form->addInput(array('type' => 'combobox', + 'onchange' => 'this.form.submit();', + 'name' => 'type', + 'value' => $cl_type, + 'data' => $types + )); + $largeScreenCalendarRowSpan += 2; +} + // User dropdown. Changes the user "on behalf" of whom we are working. if ($user->can('view_charts') || $user->can('view_all_charts')) { $rank = $user->getMaxRankForGroup($user->getGroup()); @@ -157,44 +201,11 @@ )); $largeScreenCalendarRowSpan += 2; -// Chart type options. -$chart_selector = (MODE_PROJECTS_AND_TASKS == $tracking_mode || $user->isPluginEnabled('cl')); -if ($chart_selector) { - $types = array(); - if (MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode) - $types[CHART_PROJECTS] = $i18n->get('dropdown.projects'); - if (MODE_PROJECTS_AND_TASKS == $tracking_mode) - $types[CHART_TASKS] = $i18n->get('dropdown.tasks'); - if ($user->isPluginEnabled('cl')) - $types[CHART_CLIENTS] = $i18n->get('dropdown.clients'); - - // Add chart type dropdown. - $chart_form->addInput(array('type' => 'combobox', - 'onchange' => 'this.form.submit();', - 'name' => 'type', - 'value' => $cl_type, - 'data' => $types - )); - $largeScreenCalendarRowSpan += 2; -} - -// Fav report control. -if (defined('FAV_REPORTS_ON_CHARTS_DEBUG')) { - // Get saved favorite reports for user. - $report_list = ttFavReportHelper::getReports(); - $chart_form->addInput(array('type'=>'combobox', - 'name'=>'favorite_report', - 'onchange'=>'handleFavReportSelection();this.form.submit();', - 'data'=>$report_list, - 'datakeys'=>array('id','name'), - 'empty'=>array('-1'=>$i18n->get('dropdown.no')))); - $largeScreenCalendarRowSpan += 2; -} - // Calendar. $chart_form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar // Get data for our chart. +// TODO: adjust this call below for fav report selection. $totals = ttChartHelper::getTotals($userDropdownSelectionId, $cl_type, $cl_date, $cl_interval); $smarty->assign('totals', $totals); @@ -243,7 +254,7 @@ $smarty->assign('large_screen_calendar_row_span', $largeScreenCalendarRowSpan); $smarty->assign('img_file_name', $img_ref); $smarty->assign('chart_selector', $chart_selector); -$smarty->assign('onload', 'onLoad="adjustTodayLinks()"'); +$smarty->assign('onload', 'onLoad="adjustTodayLinks();handleFavReportSelection();"'); $smarty->assign('forms', array($chart_form->getName() => $chart_form->toArray())); $smarty->assign('title', $i18n->get('title.charts')); $smarty->assign('content_page_name', 'charts.tpl'); diff --git a/initialize.php b/initialize.php index 8bc3c5f4c..c99e16dc3 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.1.5746"); +define("APP_VERSION", "1.22.1.5747"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 6b0489f569695247ba373b3a8c3e39f96fe7eacb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 5 Nov 2022 17:30:23 +0000 Subject: [PATCH 1775/1848] Initial implenentation of fav reports on charts. --- WEB-INF/lib/ttChartHelper.class.php | 100 +++++++++++++++++++++++++++- charts.php | 6 +- initialize.php | 2 +- 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttChartHelper.class.php b/WEB-INF/lib/ttChartHelper.class.php index f0523036d..7ee712796 100644 --- a/WEB-INF/lib/ttChartHelper.class.php +++ b/WEB-INF/lib/ttChartHelper.class.php @@ -4,6 +4,8 @@ import('ttPeriod'); import('ttTimeHelper'); +import('ttFavReportHelper'); +import('ttReportHelper'); // Definitions for chart types. define('CHART_PROJECTS', 1); @@ -13,7 +15,7 @@ // Class ttChartHelper is a helper class for charts. class ttChartHelper { - // getTotals - returns total times by project or task for a given user in a specified period. + // getTotals - returns total times by project, task, or client for a given user in a specified period. static function getTotals($user_id, $chart_type, $selected_date, $interval_type) { global $user; @@ -123,6 +125,102 @@ static function getTotals($user_id, $chart_type, $selected_date, $interval_type) return $result; } + + // getTotals - returns total times by project, task, or client for a selected fav report. + static function getTotalsForFavReport($fav_report_id, $chart_type) { + + global $user; + + // Use custom fields plugin if it is enabled. + if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + } + + $result = array(); + $mdb2 = getConnection(); + + // Get favorite report details. + $options = ttFavReportHelper::getReportOptions($fav_report_id); + if (!$options) + return $result; // Return empty array if something went wrong. + + $options = ttFavReportHelper::adjustOptions($options); + + // Obtain the where clause for fav report. + $where = ttReportHelper::getWhere($options); + + // Build sql query according to selected chart type. + if (CHART_PROJECTS == $chart_type) { + // Data for projects. + $sql = "select p.name as name, sum(time_to_sec(l.duration)) as time from tt_log l + left join tt_projects p on (p.id = l.project_id) + $where group by l.project_id"; + } elseif (CHART_TASKS == $chart_type) { + // Data for tasks. + $sql = "select t.name as name, sum(time_to_sec(l.duration)) as time from tt_log l + left join tt_tasks t on (t.id = l.task_id) + $where group by l.task_id"; + } elseif (CHART_CLIENTS == $chart_type) { + // Data for clients. + $sql = "select c.name as name, sum(time_to_sec(l.duration)) as time from tt_log l + left join tt_clients c on (c.id = l.client_id) + $where group by l.client_id"; + } + + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + if ($val['time'] > 0) // Only positive totals make sense in pie charts. Skip negatives entirely. + $result[] = array('name'=>$val['name'],'time'=>$val['time']); // name - entity name, time - total for entity in seconds. + } + } + + // Get total time. We'll need it to calculate percentages (for labels to the right of diagram). + $total = 0; + foreach ($result as $one_val) { + $total += $one_val['time']; + } + // Add a string representation of time + percentage to names. Example: "Time Tracker (1:15 - 6%)". + foreach ($result as &$one_val) { + $percent = round(100*$one_val['time']/$total).'%'; + $one_val['name'] .= ' ('.ttTimeHelper::minutesToDuration($one_val['time'] / 60).' - '.$percent.')'; + } + + // Note: the remaining code here is needed to display labels on the side of the diagram. + // We print labels ourselves (not using libchart.php) because quality of libchart labels is not good. + + // Note: Optimize this sorting and reversing. + $result = mu_sort($result, 'time'); + $result = array_reverse($result); // This is to assign correct colors to labels. + + // Add color to array items. This is used in labels on the side of a chart. + $colors = array( + array(2, 78, 0), + array(148, 170, 36), + array(233, 191, 49), + array(240, 127, 41), + array(243, 63, 34), + array(190, 71, 47), + array(135, 81, 60), + array(128, 78, 162), + array(121, 75, 255), + array(142, 165, 250), + array(162, 254, 239), + array(137, 240, 166), + array(104, 221, 71), + array(98, 174, 35), + array(93, 129, 1) + ); + for ($i = 0; $i < count($result); $i++) { + $color = $colors[$i%count($colors)]; + $result[$i]['color_html'] = sprintf('#%02x%02x%02x', $color[0], $color[1], $color[2]); + } + + return $result; + } + + // adjustType - adjust chart type to something that is available for a group. static function adjustType($requested_type) { global $user; diff --git a/charts.php b/charts.php index aa0b9bd51..9a67e86e9 100644 --- a/charts.php +++ b/charts.php @@ -205,8 +205,10 @@ $chart_form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar // Get data for our chart. -// TODO: adjust this call below for fav report selection. -$totals = ttChartHelper::getTotals($userDropdownSelectionId, $cl_type, $cl_date, $cl_interval); +if ($cl_fav_report == -1) + $totals = ttChartHelper::getTotals($userDropdownSelectionId, $cl_type, $cl_date, $cl_interval); +else + $totals = ttChartHelper::getTotalsForFavReport($cl_fav_report, $cl_type); $smarty->assign('totals', $totals); // Prepare chart for drawing. diff --git a/initialize.php b/initialize.php index c99e16dc3..c54bf1d79 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.1.5747"); +define("APP_VERSION", "1.22.2.5748"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From e9193034b33070e621e010ff13accee708fa7b3a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Nov 2022 13:26:53 +0000 Subject: [PATCH 1776/1848] Removed debug condition for fav reports on charts feature. --- WEB-INF/templates/charts.tpl | 2 -- charts.php | 21 +++++++++------------ initialize.php | 2 +- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/WEB-INF/templates/charts.tpl b/WEB-INF/templates/charts.tpl index ee0c48346..41a6fd1e7 100644 --- a/WEB-INF/templates/charts.tpl +++ b/WEB-INF/templates/charts.tpl @@ -64,14 +64,12 @@ function handleFavReportSelection() {
{$forms.chartForm.date.control}
-{if defined('FAV_REPORTS_ON_CHARTS_DEBUG')} -{/if} {if $chart_selector} diff --git a/charts.php b/charts.php index 9a67e86e9..1fd7792b3 100644 --- a/charts.php +++ b/charts.php @@ -124,18 +124,15 @@ $largeScreenCalendarRowSpan = 1; // Number of rows calendar spans on large screens. // Fav report control. -if (defined('FAV_REPORTS_ON_CHARTS_DEBUG')) { - // Get saved favorite reports for user. - $report_list = ttFavReportHelper::getReports(); - $chart_form->addInput(array('type'=>'combobox', - 'name'=>'favorite_report', - 'onchange'=>'handleFavReportSelection();this.form.submit();', - 'data'=>$report_list, - 'value' => $cl_fav_report, - 'datakeys'=>array('id','name'), - 'empty'=>array('-1'=>$i18n->get('dropdown.no')))); - $largeScreenCalendarRowSpan += 2; -} +$report_list = ttFavReportHelper::getReports(); +$chart_form->addInput(array('type'=>'combobox', + 'name'=>'favorite_report', + 'onchange'=>'handleFavReportSelection();this.form.submit();', + 'data'=>$report_list, + 'value' => $cl_fav_report, + 'datakeys'=>array('id','name'), + 'empty'=>array('-1'=>$i18n->get('dropdown.no')))); +$largeScreenCalendarRowSpan += 2; // Chart type options. $chart_selector = (MODE_PROJECTS_AND_TASKS == $tracking_mode || $user->isPluginEnabled('cl')); diff --git a/initialize.php b/initialize.php index c54bf1d79..43ef2f378 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.2.5748"); +define("APP_VERSION", "1.22.2.5749"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 876d5387cce5819f2724e7dab3407ae44ccdb1a3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Nov 2022 13:47:57 +0000 Subject: [PATCH 1777/1848] Improved charts by hiding calendar for fav reports. --- WEB-INF/templates/charts.tpl | 18 ++++++++++++++++-- initialize.php | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/charts.tpl b/WEB-INF/templates/charts.tpl index 41a6fd1e7..27d335ffb 100644 --- a/WEB-INF/templates/charts.tpl +++ b/WEB-INF/templates/charts.tpl @@ -29,6 +29,8 @@ function handleFavReportSelection() { var userControl = document.getElementById("user_control"); var intervalLabel = document.getElementById("interval_label"); var intervalControl = document.getElementById("interval_control"); + var smallScreenCalendarDiv = document.getElementById("small_screen_calendar"); + var largeScreenCalendarDiv = document.getElementById("large_screen_calendar"); if (selectedFavReportId == -1) { if (userLabel != null) { @@ -43,6 +45,12 @@ function handleFavReportSelection() { if (intervalControl != null) { intervalControl.style.display = ""; } + if (smallScreenCalendarDiv != null) { + smallScreenCalendarDiv.style.display = ""; + } + if (largeScreenCalendarDiv != null) { + largeScreenCalendarDiv.style.display = ""; + } } else { if (userLabel != null) { userLabel.style.display = "none"; @@ -56,14 +64,20 @@ function handleFavReportSelection() { if (intervalControl != null) { intervalControl.style.display = "none"; } + if (smallScreenCalendarDiv != null) { + smallScreenCalendarDiv.style.display = "none"; + } + if (largeScreenCalendarDiv != null) { + largeScreenCalendarDiv.style.display = "none"; + } } } {$forms.chartForm.open} -
{$forms.chartForm.date.control}
+
{$forms.chartForm.date.control}
{$forms.chartForm.date.control}
{$forms.chartForm.favorite_report.control}
- + diff --git a/initialize.php b/initialize.php index 43ef2f378..60af5b19d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.2.5749"); +define("APP_VERSION", "1.22.2.5750"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 66d2e4776f8e906b233783d91632f1aa0a80a287 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 18 Nov 2022 14:19:31 +0000 Subject: [PATCH 1778/1848] Removed a redundant call in puncher. --- initialize.php | 2 +- puncher.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/initialize.php b/initialize.php index 60af5b19d..71a97bb7b 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.2.5750"); +define("APP_VERSION", "1.22.2.5751"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/puncher.php b/puncher.php index 9714ac242..26b371fcd 100644 --- a/puncher.php +++ b/puncher.php @@ -324,7 +324,6 @@ $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); $smarty->assign('task_required', $taskRequired); -$smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); $smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('time_records', $timeRecords); $smarty->assign('show_record_custom_fields', $user->isOptionEnabled('record_custom_fields')); From 4692f7163525e25c5efff09de72bd3fb73690f08 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 6 Dec 2022 22:02:58 +0000 Subject: [PATCH 1779/1848] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 9 +++------ initialize.php | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 38d93efdb..c162f858d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -415,8 +415,7 @@ 'form.reports.show_fields' => 'Toon velden', 'form.reports.time_fields' => 'Tijd velden', 'form.reports.user_fields' => 'Medewerker velden', -// TODO: translate the following. -// 'form.reports.project_fields' => 'Project fields', +'form.reports.project_fields' => 'Project velden', 'form.reports.group_by' => 'Groeperen op', 'form.reports.group_by_no' => '--- niet groeperen ---', 'form.reports.group_by_date' => 'datum', @@ -428,8 +427,7 @@ // Report form. See example at https://timetracker.anuko.com/report.php // (after generating a report at https://timetracker.anuko.com/reports.php). 'form.report.export' => 'Exporteer', -// TODO: translate the following. -// 'form.report.per_hour' => 'Per hour', +'form.report.per_hour' => 'Per uur', 'form.report.assign_to_invoice' => 'Voeg toe aan factuur', 'form.report.assign_to_timesheet' => 'Wijs toe aan tijdenoverzicht', @@ -590,7 +588,6 @@ 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', // Translator (Henk) comment: "kolom is the right word in Dutch." 'form.display_options.not_complete_days' => 'Niet complete dagen', 'form.display_options.inactive_projects' => 'Niet actieve projecten', -// TODO: translate the following. -// 'form.display_options.cost_per_hour' => 'Cost per hour', +'form.display_options.cost_per_hour' => 'Kosten per uur', 'form.display_options.custom_css' => 'Aangepaste CSS', ); diff --git a/initialize.php b/initialize.php index 71a97bb7b..6c62a5c94 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.2.5751"); +define("APP_VERSION", "1.22.2.5752"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 136681fa3019c4e80ef9e93a59d5334925486121 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 8 Dec 2022 16:36:09 +0000 Subject: [PATCH 1780/1848] Added previous month option on charts. --- WEB-INF/lib/ttChartHelper.class.php | 4 ++++ WEB-INF/lib/ttPeriod.class.php | 12 ++++++------ charts.php | 1 + initialize.php | 2 +- reports.php | 6 +++--- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttChartHelper.class.php b/WEB-INF/lib/ttChartHelper.class.php index 7ee712796..eaa5a4c07 100644 --- a/WEB-INF/lib/ttChartHelper.class.php +++ b/WEB-INF/lib/ttChartHelper.class.php @@ -37,6 +37,10 @@ static function getTotals($user_id, $chart_type, $selected_date, $interval_type) $period = new ttPeriod(new ttDate($selected_date), INTERVAL_THIS_MONTH); break; + case INTERVAL_PREVIOUS_MONTH: + $period = new ttPeriod(new ttDate($selected_date), INTERVAL_PREVIOUS_MONTH); + break; + case INTERVAL_THIS_YEAR: $period = new ttPeriod(new ttDate($selected_date), INTERVAL_THIS_YEAR); break; diff --git a/WEB-INF/lib/ttPeriod.class.php b/WEB-INF/lib/ttPeriod.class.php index 1d63ad9d1..0dcbf71c1 100644 --- a/WEB-INF/lib/ttPeriod.class.php +++ b/WEB-INF/lib/ttPeriod.class.php @@ -7,9 +7,9 @@ define('INTERVAL_THIS_MONTH', 3); define('INTERVAL_THIS_YEAR', 4); define('INTERVAL_ALL_TIME', 5); -define('INTERVAL_LAST_WEEK', 6); -define('INTERVAL_LAST_MONTH', 7); -define('INTERVAL_LAST_DAY', 8); +define('INTERVAL_PREVIOUS_WEEK', 6); +define('INTERVAL_PREVIOUS_MONTH', 7); +define('INTERVAL_PREVIOUS_DAY', 8); class ttPeriod { var $startDate; // ttDate object. @@ -34,7 +34,7 @@ function __construct($ttDateInstance, $period_type = INTERVAL_THIS_MONTH) { $this->endDate->setFromUnixTimestamp($ttDateInstance->getTimestamp()); break; - case INTERVAL_LAST_DAY: + case INTERVAL_PREVIOUS_DAY: $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-1,$t_arr[5])); $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-1,$t_arr[5])); break; @@ -44,7 +44,7 @@ function __construct($ttDateInstance, $period_type = INTERVAL_THIS_MONTH) { $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+6+$startWeekBias,$t_arr[5])); break; - case INTERVAL_LAST_WEEK: + case INTERVAL_PREVIOUS_WEEK: $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]-7+$startWeekBias,$t_arr[5])); $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]-1+$startWeekBias,$t_arr[5])); break; @@ -54,7 +54,7 @@ function __construct($ttDateInstance, $period_type = INTERVAL_THIS_MONTH) { $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+2,0,$t_arr[5])); break; - case INTERVAL_LAST_MONTH: + case INTERVAL_PREVIOUS_MONTH: $this->startDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4],1,$t_arr[5])); $this->endDate->setFromUnixTimestamp(mktime(0,0,0,$t_arr[4]+1,0,$t_arr[5])); break; diff --git a/charts.php b/charts.php index 1fd7792b3..a4c24f0a0 100644 --- a/charts.php +++ b/charts.php @@ -186,6 +186,7 @@ $intervals[INTERVAL_THIS_DAY] = $i18n->get('dropdown.selected_day'); $intervals[INTERVAL_THIS_WEEK] = $i18n->get('dropdown.selected_week'); $intervals[INTERVAL_THIS_MONTH] = $i18n->get('dropdown.selected_month'); +$intervals[INTERVAL_PREVIOUS_MONTH] = $i18n->get('dropdown.previous_month'); $intervals[INTERVAL_THIS_YEAR] = $i18n->get('dropdown.selected_year'); $intervals[INTERVAL_ALL_TIME] = $i18n->get('dropdown.all_time'); diff --git a/initialize.php b/initialize.php index 6c62a5c94..d499de945 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.2.5752"); +define("APP_VERSION", "1.22.2.5753"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/reports.php b/reports.php index 057787e7c..fd4ca156b 100644 --- a/reports.php +++ b/reports.php @@ -229,11 +229,11 @@ $form->addInput(array('type'=>'combobox', 'name'=>'period', 'data'=>array(INTERVAL_THIS_MONTH=>$i18n->get('dropdown.current_month'), - INTERVAL_LAST_MONTH=>$i18n->get('dropdown.previous_month'), + INTERVAL_PREVIOUS_MONTH=>$i18n->get('dropdown.previous_month'), INTERVAL_THIS_WEEK=>$i18n->get('dropdown.current_week'), - INTERVAL_LAST_WEEK=>$i18n->get('dropdown.previous_week'), + INTERVAL_PREVIOUS_WEEK=>$i18n->get('dropdown.previous_week'), INTERVAL_THIS_DAY=>$i18n->get('dropdown.current_day'), - INTERVAL_LAST_DAY=>$i18n->get('dropdown.previous_day')), + INTERVAL_PREVIOUS_DAY=>$i18n->get('dropdown.previous_day')), 'empty'=>array(''=>$i18n->get('dropdown.select')))); // Add controls for start and end dates. $form->addInput(array('type'=>'datefield','maxlength'=>'20','name'=>'start_date')); From 700d2e19cd276432dd03e3817a5e03aa056ea3cc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 18 Dec 2022 13:53:20 +0000 Subject: [PATCH 1781/1848] Started to work on custom translation feature. --- dbinstall.php | 10 ++++++---- initialize.php | 2 +- mysql.sql | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/dbinstall.php b/dbinstall.php index 85d3f021a..c79cd558a 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1151,7 +1151,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to12107"]) { + if ($_POST["convert11900to12203"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1199,6 +1199,8 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.21.2', modified = now() where param_name = 'version_db' and param_value = '1.21.0'"); ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `note_containing` varchar(80) default NULL after `paid_status`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.21.7', modified = now() where param_name = 'version_db' and param_value = '1.21.2'"); + ttExecute("ALTER TABLE `tt_groups` ADD `custom_translation` text default NULL AFTER `custom_css`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.22.3', modified = now() where param_name = 'version_db' and param_value = '1.21.7'"); } if ($_POST["cleanup"]) { @@ -1249,7 +1251,7 @@ function ttGenerateKeys() {

DB Install

{$forms.chartForm.date.control}
{$forms.chartForm.date.control}
-
Create database structure (v1.21.7) + Create database structure (v1.22.3)
(applies only to new installations, do not execute when updating)
@@ -1298,8 +1300,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.21.7)Update database structure (v1.19 to v1.22.3)
diff --git a/initialize.php b/initialize.php index d499de945..7c1e90f6e 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.2.5753"); +define("APP_VERSION", "1.22.3.5754"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mysql.sql b/mysql.sql index 4fd33fa95..d50b6c46c 100644 --- a/mysql.sql +++ b/mysql.sql @@ -39,6 +39,7 @@ CREATE TABLE `tt_groups` ( `custom_logo` tinyint(4) default 0, # whether to use a custom logo or not `config` text default NULL, # miscellaneous group configuration settings `custom_css` text default NULL, # custom css for group + `custom_translation` text default NULL, # custom translation for group `created` datetime default NULL, # creation timestamp `created_ip` varchar(45) default NULL, # creator ip `created_by` int(11) default NULL, # creator user_id @@ -622,4 +623,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.21.7', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.22.3', now()); # TODO: change when structure changes. From 6908f224aa200ae785a9b819ca73f81bb9af6f7f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 18 Dec 2022 15:03:08 +0000 Subject: [PATCH 1782/1848] Added localization string for custom translation. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + initialize.php | 2 +- 31 files changed, 33 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 13d8237c2..3cb547511 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -681,4 +681,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 4a93086de..2c32c9641 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -693,4 +693,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 595590f0a..8c86b742d 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -659,4 +659,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 209df6b72..eadc49e74 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -634,4 +634,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 83808aa40..c1defcb5f 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -605,4 +605,5 @@ 'form.display_options.inactive_projects' => 'Inactive projects', 'form.display_options.cost_per_hour' => 'Cost per hour', 'form.display_options.custom_css' => 'Custom CSS', +'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 507bbcaac..63e6fbac5 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -696,4 +696,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 0295dc70f..59f6ecf5e 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -670,4 +670,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 078872026..bfe8044d5 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -682,4 +682,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index e9e92e018..d5cbe9286 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -666,4 +666,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 145fcb289..a0df933eb 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -655,4 +655,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 6265976d7..c5c0c2b7a 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -649,4 +649,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 727b0b761..1d0c24f40 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -687,4 +687,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 8b0be9524..4c133d9fd 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -684,4 +684,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index d283830a1..7cf157ba7 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -662,4 +662,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 112e454cc..16a882f83 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -688,4 +688,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 6bb78d772..f0c695e03 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -686,4 +686,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index c162f858d..febb14a98 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -590,4 +590,6 @@ 'form.display_options.inactive_projects' => 'Niet actieve projecten', 'form.display_options.cost_per_hour' => 'Kosten per uur', 'form.display_options.custom_css' => 'Aangepaste CSS', +// TODO: translate the following. +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 18e1ee69f..ec80e93eb 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -688,4 +688,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index b7dd5024c..e6eba0521 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -667,4 +667,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index fff94fa3d..04f860459 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -600,5 +600,7 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', 'form.display_options.custom_css' => 'CSS customizado', +// TODO: translate the following. +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 075e7b41c..fdedcf435 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -666,4 +666,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 0d8fe6d1f..55d010f86 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -689,4 +689,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 805be45b5..3e804c7da 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -591,4 +591,5 @@ 'form.display_options.inactive_projects' => 'Неактивные проекты', 'form.display_options.cost_per_hour' => 'Стоимость за час', 'form.display_options.custom_css' => 'Пользовательская CSS', +'form.display_options.custom_translation' => 'Пользовательский перевод', ); diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index e57e63d74..1802f518a 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -671,4 +671,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 8ea8c445e..cd6149671 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -661,4 +661,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 055545b37..18c64ec78 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -669,4 +669,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index e0d212b9e..6b2a0d2bc 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -667,4 +667,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 098871718..0473d081c 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -702,4 +702,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 87f1cc1c9..44dc443ee 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -677,4 +677,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 181756e77..e5faa1cbf 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -680,4 +680,5 @@ // 'form.display_options.inactive_projects' => 'Inactive projects', // 'form.display_options.cost_per_hour' => 'Cost per hour', // 'form.display_options.custom_css' => 'Custom CSS', +// 'form.display_options.custom_translation' => 'Custom translation', ); diff --git a/initialize.php b/initialize.php index 7c1e90f6e..54e0c36d0 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.3.5754"); +define("APP_VERSION", "1.22.3.5755"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 08fbd9a080c042685df6ccc40b9fd0eba0914795 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Dec 2022 15:44:16 +0000 Subject: [PATCH 1783/1848] Work in progress on custom translation. --- WEB-INF/lib/common.lib.php | 14 ++++++++++++++ WEB-INF/lib/ttUser.class.php | 17 ++++++++++++++--- WEB-INF/templates/display_options.tpl | 7 +++++++ default.css | 4 ++-- display_options.php | 7 ++++++- initialize.php | 2 +- 6 files changed, 44 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 0f38f80fa..7a79e0a74 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -162,6 +162,20 @@ function ttValidCss($val) return true; } +// ttValidTranslation is used to check user input for custom translation. +function ttValidTranslation($val) +{ + $val = trim($val); + if (strlen($val) == 0) + return true; + + // String must not contain any tags. + if (stristr($val, '<')) + return false; + + return false; // Not implemented yet. +} + // ttValidTemplateText is used to check template-based user input. // When templates are used, required input parts must be filled by user. // We identify these parts by 3 "stop sign" emojis (aka "octagonal sign" U+1F6D1). diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index b32c27792..37591fa5f 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -50,6 +50,7 @@ class ttUser { var $config = null; // Comma-separated list of miscellaneous config options. var $configHelper = null; // An instance of ttConfigHelper class. var $custom_css = null; // Custom css. + var $custom_translation = null; // Custom translation. var $custom_logo = 0; // Whether to use a custom logo for group. var $lock_spec = null; // Cron specification for record locking. @@ -73,7 +74,8 @@ function __construct($login, $id = null) { $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id,". " u.quota_percent, u.email, g.org_id, g.group_key, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format,". " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.record_type,". - " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.custom_css, g.holidays, g.workday_minutes, g.custom_logo". + " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.custom_css, g.custom_translation,". + " g.holidays, g.workday_minutes, g.custom_logo". " FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; if ($id) $sql .= "u.id = $id"; @@ -131,6 +133,7 @@ function __construct($login, $id = null) { $this->allow_overlap = $this->configHelper->getDefinedValue('allow_overlap'); $this->custom_css = $val['custom_css']; + $this->custom_translation = $val['custom_translation']; // Set "on behalf" id and name (user). if (isset($_SESSION['behalf_id'])) { @@ -290,6 +293,11 @@ function getCustomCss() { return ($this->behalfGroup ? $this->behalfGroup->custom_css : $this->custom_css); } + // getCustomTranslation returns custom translation for active group. + function getCustomTranslation() { + return ($this->behalfGroup ? $this->behalfGroup->custom_translation : $this->custom_translation); + } + // can - determines whether user has a right to do something. function can($do_something) { return in_array($do_something, $this->rights); @@ -682,7 +690,8 @@ function updateGroup($fields) { $name_part = $description_part = $currency_part = $lang_part = $decimal_mark_part = $date_format_part = $time_format_part = $week_start_part = $tracking_mode_part = $project_required_part = $record_type_part = $bcc_email_part = $allow_ip_part = - $password_complexity_part = $plugins_part = $config_part = $custom_css_part = $lock_spec_part = $holidays_part = $workday_minutes_part = ''; + $password_complexity_part = $plugins_part = $config_part = $custom_css_part = $custom_translation_part = $lock_spec_part = + $holidays_part = $workday_minutes_part = ''; if (isset($fields['name'])) $name_part = ', name = '.$mdb2->quote($fields['name']); if (isset($fields['description'])) $description_part = ', description = '.$mdb2->quote($fields['description']); if (isset($fields['currency'])) $currency_part = ', currency = '.$mdb2->quote($fields['currency']); @@ -702,6 +711,7 @@ function updateGroup($fields) { if (isset($fields['plugins'])) $plugins_part = ', plugins = '.$mdb2->quote($fields['plugins']); if (isset($fields['config'])) $config_part = ', config = '.$mdb2->quote($fields['config']); if (isset($fields['custom_css'])) $custom_css_part = ', custom_css = '.$mdb2->quote($fields['custom_css']); + if (isset($fields['custom_translation'])) $custom_translation_part = ', custom_translation = '.$mdb2->quote($fields['custom_translation']); if (isset($fields['lock_spec'])) $lock_spec_part = ', lock_spec = '.$mdb2->quote($fields['lock_spec']); if (isset($fields['holidays'])) $holidays_part = ', holidays = '.$mdb2->quote($fields['holidays']); if (isset($fields['workday_minutes'])) $workday_minutes_part = ', workday_minutes = '.$mdb2->quote($fields['workday_minutes']); @@ -709,7 +719,8 @@ function updateGroup($fields) { $parts = trim($name_part.$description_part.$currency_part.$lang_part.$decimal_mark_part.$date_format_part. $time_format_part.$week_start_part.$tracking_mode_part.$project_required_part.$record_type_part. - $bcc_email_part.$allow_ip_part.$password_complexity_part.$plugins_part.$config_part.$custom_css_part.$lock_spec_part.$holidays_part.$workday_minutes_part.$modified_part, ','); + $bcc_email_part.$allow_ip_part.$password_complexity_part.$plugins_part.$config_part.$custom_css_part. + $custom_translation_part.$lock_spec_part.$holidays_part.$workday_minutes_part.$modified_part, ','); $sql = "update tt_groups set $parts where id = $group_id and org_id = $this->org_id"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index 5b487ec85..a6abe34f2 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -63,6 +63,13 @@ License: See license.txt *}
{$forms.displayOptionsForm.custom_css.control}
{$i18n.label.what_is_it}
{$i18n.form.display_options.custom_translation}
{$forms.displayOptionsForm.custom_translation.control}
{$i18n.label.what_is_it}
{$forms.displayOptionsForm.btn_save.control}
{$forms.displayOptionsForm.close} diff --git a/default.css b/default.css index 98e40562a..38de0f53f 100644 --- a/default.css +++ b/default.css @@ -363,7 +363,7 @@ input[type="text"].short-text-field { } /* textareas for fields */ -#description, #address, #item_name, #comment, #custom_css, #content { +#description, #address, #item_name, #comment, #custom_css, #custom_translation, #content { width: 220px; border-radius: 4px; border: 1px solid #c9c9c9; @@ -371,7 +371,7 @@ input[type="text"].short-text-field { } /* textareas with focus */ -#description:focus, #address:focus, #item_name:focus, #comment:focus, #custom_css:focus, #content:focus { +#description:focus, #address:focus, #item_name:focus, #comment:focus, #custom_css:focus, #custom_translation:focus, #content:focus { background-color: yellow; border: 1px solid black; outline: none; diff --git a/display_options.php b/display_options.php index e449c3c91..e0b7bc987 100644 --- a/display_options.php +++ b/display_options.php @@ -23,6 +23,7 @@ $cl_report_inactive_projects = (bool)($request->getParameter('report_inactive_projects')); $cl_report_cost_per_hour = (bool)$request->getParameter('report_cost_per_hour'); $cl_custom_css = trim($request->getParameter('custom_css')); + $cl_custom_translation = trim($request->getParameter('custom_translation')); } else { $cl_time_note_on_separate_row = $config->getDefinedValue('time_note_on_separate_row'); $cl_time_not_complete_days = $config->getDefinedValue('time_not_complete_days'); @@ -31,6 +32,7 @@ $cl_report_inactive_projects = $config->getDefinedValue('report_inactive_projects'); $cl_report_cost_per_hour = $config->getDefinedValue('report_cost_per_hour'); $cl_custom_css = $user->getCustomCss(); + $cl_custom_translation = $user->getCustomTranslation(); } $form = new Form('displayOptionsForm'); @@ -55,11 +57,13 @@ // TODO: add PDF break controller here. $form->addInput(array('type'=>'textarea','name'=>'custom_css','value'=>$cl_custom_css)); +$form->addInput(array('type'=>'textarea','name'=>'custom_translation','value'=>$cl_custom_translation)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()){ // Validate user input. if (!ttValidCss($cl_custom_css)) $err->add($i18n->get('error.field'), $i18n->get('form.display_options.custom_css')); + if (!ttValidTranslation($cl_custom_translation)) $err->add($i18n->get('error.field'), $i18n->get('form.display_options.custom_translation')); // Finished validating user input. if ($err->no()) { @@ -72,7 +76,8 @@ $config->setDefinedValue('report_cost_per_hour', $cl_report_cost_per_hour); if ($user->updateGroup(array( 'config' => $config->getConfig(), - 'custom_css' => $cl_custom_css))) { + 'custom_css' => $cl_custom_css, + 'custom_translation' => $cl_custom_translation))) { header('Location: success.php'); exit(); } else diff --git a/initialize.php b/initialize.php index 54e0c36d0..bb1aa4f95 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.3.5755"); +define("APP_VERSION", "1.22.3.5756"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From bd106a61bb80f88b7c4d6b7f7e3d2e28441f3851 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Dec 2022 21:26:01 +0000 Subject: [PATCH 1784/1848] More progress on custom translation feature. --- WEB-INF/lib/I18n.class.php | 40 +++++++++++++++++++++++++++++++++-- WEB-INF/lib/common.lib.php | 43 +++++++++++++++++++++++++++++++++++--- initialize.php | 2 +- 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/I18n.class.php b/WEB-INF/lib/I18n.class.php index 1760da48a..99015a93e 100644 --- a/WEB-INF/lib/I18n.class.php +++ b/WEB-INF/lib/I18n.class.php @@ -51,9 +51,16 @@ function get($key) { return $value; } + // get - keyExists determines if a key exists. + function keyExists($key) { + $value = $this->get($key); + return ($value != null && strlen($value) > 0); + } + // load - loads localized strings into $keys array by first going through the default file (en.lang.php) - // and then through the requested language file (which is supplied as parameter). - // This means we end up with default English strings when keys are missing in the translation file. + // and then through the requested language file (which is supplied as parameter), + // (this means we end up with default English strings when keys are missing in the translation file), + // and then from a group custom translation field, if available. function load($langName) { // Load default English keys first. $defaultFileName = RESOURCE_DIR . '/' . $this->defaultLang . '.lang.php'; @@ -105,6 +112,35 @@ function load($langName) { } } } + + // Now load custom translation for group. + global $user; + $customTranslation = $user->getCustomTranslation(); + if ($customTranslation != null) { + $lines = preg_split("/\r\n|\n|\r/", $customTranslation); + for ($i = 0; $i < count($lines); $i++) { + $parts = explode('=', $lines[$i]); + if (count($parts) != 2) continue; + + $key = trim($parts[0]); + $value = trim($parts[1]); + if (!$value) continue; + + $value = htmlspecialchars(trim($parts[1])); + + $pos = strpos($key, "."); + if (!($pos === false)) { + $p = explode(".", $key); + $str = ""; + foreach ($p as $w) { + $str .= "[\"".$w."\"]"; + } + eval("\$this->keys".$str."='".$value."';"); + } else { + $this->keys[$key] = $value; + } + } + } } // hasLang determines if a file for requested language exists. diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 7a79e0a74..85ece4480 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -169,11 +169,48 @@ function ttValidTranslation($val) if (strlen($val) == 0) return true; - // String must not contain any tags. - if (stristr($val, '<')) + // Validate lines. + $lines = preg_split("/\r\n|\n|\r/", $val); + for ($i = 0; $i < count($lines); $i++) { + if (!ttValidTranslationLine($lines[$i])) + return false; + } + + return true; +} + +// ttValidTranslationLine is used to check an individual line in custom translation. +function ttValidTranslationLine($val) +{ + $val = trim($val); + if (strlen($val) == 0) + return false; // Empty line is not valid. + + $parts = explode('=', $val); + if (count($parts) != 2) { + // We need exactly 2 parts. return false; + } + + $key = trim($parts[0]); + global $i18n; + if (!$i18n->keyExists($key)) { + // Key does not exist. + return false; + } - return false; // Not implemented yet. + $value = trim($parts[1]); + if (!$value) { + // Do not allow empty values. + return false; + } + + // Prohibit apostrophes in values for now until I figure out how to handle them properly. + if (ttContains($value, "'")) { + return false; + } + + return true; } // ttValidTemplateText is used to check template-based user input. diff --git a/initialize.php b/initialize.php index bb1aa4f95..060c63ea2 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.3.5756"); +define("APP_VERSION", "1.22.3.5757"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From cd24019d91a1582bbe50c1e65a047c97fc9f19b1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 20 Dec 2022 15:40:01 +0000 Subject: [PATCH 1785/1848] Allowed empty custom translation strings and also containing single quotes. --- WEB-INF/lib/I18n.class.php | 8 ++++---- WEB-INF/lib/common.lib.php | 11 ----------- WEB-INF/resources/ca.lang.php | 3 ++- WEB-INF/resources/cs.lang.php | 3 ++- WEB-INF/resources/da.lang.php | 3 ++- WEB-INF/resources/de.lang.php | 3 ++- WEB-INF/resources/en.lang.php | 3 ++- WEB-INF/resources/es.lang.php | 3 ++- WEB-INF/resources/et.lang.php | 3 ++- WEB-INF/resources/fa.lang.php | 4 +++- WEB-INF/resources/fi.lang.php | 3 ++- WEB-INF/resources/fr.lang.php | 3 ++- WEB-INF/resources/gr.lang.php | 3 ++- WEB-INF/resources/he.lang.php | 3 ++- WEB-INF/resources/hu.lang.php | 3 ++- WEB-INF/resources/it.lang.php | 3 ++- WEB-INF/resources/ja.lang.php | 3 ++- WEB-INF/resources/ko.lang.php | 3 ++- WEB-INF/resources/nl.lang.php | 3 ++- WEB-INF/resources/no.lang.php | 3 ++- WEB-INF/resources/pl.lang.php | 3 ++- WEB-INF/resources/pt-br.lang.php | 3 ++- WEB-INF/resources/pt.lang.php | 3 ++- WEB-INF/resources/ro.lang.php | 3 ++- WEB-INF/resources/ru.lang.php | 3 ++- WEB-INF/resources/sk.lang.php | 3 ++- WEB-INF/resources/sl.lang.php | 3 ++- WEB-INF/resources/sr.lang.php | 3 ++- WEB-INF/resources/sv.lang.php | 3 ++- WEB-INF/resources/tr.lang.php | 3 ++- WEB-INF/resources/zh-cn.lang.php | 3 ++- WEB-INF/resources/zh-tw.lang.php | 3 ++- initialize.php | 2 +- 33 files changed, 66 insertions(+), 46 deletions(-) diff --git a/WEB-INF/lib/I18n.class.php b/WEB-INF/lib/I18n.class.php index 99015a93e..bd4e9ffd3 100644 --- a/WEB-INF/lib/I18n.class.php +++ b/WEB-INF/lib/I18n.class.php @@ -54,7 +54,7 @@ function get($key) { // get - keyExists determines if a key exists. function keyExists($key) { $value = $this->get($key); - return ($value != null && strlen($value) > 0); + return ($value !== null); } // load - loads localized strings into $keys array by first going through the default file (en.lang.php) @@ -124,9 +124,9 @@ function load($langName) { $key = trim($parts[0]); $value = trim($parts[1]); - if (!$value) continue; - - $value = htmlspecialchars(trim($parts[1])); + // Escape single quotes and backslashes. + $value = addcslashes($value, "'\\"); + $value = htmlspecialchars($value); $pos = strpos($key, "."); if (!($pos === false)) { diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 85ece4480..86570a5f0 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -199,17 +199,6 @@ function ttValidTranslationLine($val) return false; } - $value = trim($parts[1]); - if (!$value) { - // Do not allow empty values. - return false; - } - - // Prohibit apostrophes in values for now until I figure out how to handle them properly. - if (ttContains($value, "'")) { - return false; - } - return true; } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 3cb547511..327132ed8 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Catalan (Català)'; diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 2c32c9641..c89457e6d 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. // Note to translators: Use proper capitalization rules for your language. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 8c86b742d..6fe93c261 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Danish (Dansk)'; diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index eadc49e74..9cb0340b9 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'German (Deutsch)'; diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index c1defcb5f..5858b63d4 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'English'; diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 63e6fbac5..b302de1c4 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Spanish (Español)'; diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 59f6ecf5e..19a74b4cd 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. // Note to translators: Use proper capitalization rules for your language. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index bfe8044d5..32dacdf00 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -2,8 +2,10 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. + $i18n_language = 'Persian (فارسی)'; // TODO: translate the following. $i18n_months = array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index d5cbe9286..cdfc4c5fe 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Finnish (Suomi)'; diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a0df933eb..b488be0bc 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'French (Français)'; diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index c5c0c2b7a..34f1890eb 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Greek (Ελληνικά)'; diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 1d0c24f40..585a7ec2f 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Hebrew (עברית)'; diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 4c133d9fd..e2d7500d3 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. // Note to translators: Use proper capitalization rules for your language. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 7cf157ba7..73ca8a022 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. // Note to translators: Use proper capitalization rules for your language. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 16a882f83..0de6e88ea 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Japanese (日本語)'; diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index f0c695e03..fcbe14d24 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Korean (한국어)'; diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index febb14a98..16fe1ecf8 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Dutch (Nederlands)'; diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index ec80e93eb..720f71f34 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Norwegian (Norsk)'; diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index e6eba0521..69dddf311 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Polish (Polski)'; diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 04f860459..c9a4ad998 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Portuguese (Português Brasileiro)'; diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index fdedcf435..abcd5793f 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. // Note to translators: Please use proper capitalization rules for your language. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 55d010f86..03db7da44 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. // Note to translators: Please use proper capitalization rules for your language. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3e804c7da..6c924df2d 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Russian (Русский)'; diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 1802f518a..0404fb8d0 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Slovak (Slovenčina)'; diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index cd6149671..b3153ad79 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. // Note to translators: Use proper capitalization rules for your language. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 18c64ec78..6902d9223 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Serbian (Srpski)'; diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 6b2a0d2bc..dba0fd6f2 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Swedish (Svenska)'; diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 0473d081c..f2531ee76 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. // Note to translators: Use proper capitalization rules for your language. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 44dc443ee..d30515863 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Chinese (简体中文)'; diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index e5faa1cbf..890244f66 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -2,7 +2,8 @@ /* Copyright (c) Anuko International Ltd. https://www.anuko.com License: See license.txt */ -// Note: escape apostrophes with THREE backslashes, like here: choisir l\\\'option. +// Note: escape apostrophes with THREE backslashes, like here: 'choisir l\\\'option'. +// Alternatively: use one backslash and surround by double-quotes: "choisir l\'option". // Other characters (such as double-quotes in http links, etc.) do not have to be escaped. $i18n_language = 'Chinese (簡體中文)'; diff --git a/initialize.php b/initialize.php index 060c63ea2..55613a09d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.3.5757"); +define("APP_VERSION", "1.22.3.5758"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 3c7b6f53a0f34d7b9fa712b9a0a7d48f21081b3e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Dec 2022 13:50:06 +0000 Subject: [PATCH 1786/1848] Initial release of custom translation feature in display options. --- WEB-INF/templates/display_options.tpl | 2 -- initialize.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index a6abe34f2..0d0418af9 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -63,13 +63,11 @@ License: See license.txt *}
{$forms.displayOptionsForm.custom_css.control}
{$i18n.label.what_is_it}
{$i18n.form.display_options.custom_translation}
{$forms.displayOptionsForm.custom_translation.control}
{$i18n.label.what_is_it}
{$forms.displayOptionsForm.btn_save.control}
{$forms.displayOptionsForm.close} diff --git a/initialize.php b/initialize.php index 55613a09d..afb52e81d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.3.5758"); +define("APP_VERSION", "1.22.4.5759"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From f7dbaf2086bb5793ef5e5ecacc74709ac1c7a947 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 23 Dec 2022 13:01:08 +0000 Subject: [PATCH 1787/1848] Dutch transation improved. --- WEB-INF/resources/nl.lang.php | 3 +-- initialize.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 16fe1ecf8..2ca444c0a 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -591,6 +591,5 @@ 'form.display_options.inactive_projects' => 'Niet actieve projecten', 'form.display_options.cost_per_hour' => 'Kosten per uur', 'form.display_options.custom_css' => 'Aangepaste CSS', -// TODO: translate the following. -// 'form.display_options.custom_translation' => 'Custom translation', +'form.display_options.custom_translation' => 'Maatwerk vertaling', ); diff --git a/initialize.php b/initialize.php index afb52e81d..08bcf66e8 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.4.5759"); +define("APP_VERSION", "1.22.4.5760"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From a38d8502bbcea6f0d877ca4ea0ba202a0a830790 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Dec 2022 16:04:57 +0000 Subject: [PATCH 1788/1848] Fixed export-import for custom_css and custom_translation fields. --- WEB-INF/lib/ttGroupExportHelper.class.php | 3 ++- WEB-INF/lib/ttOrgImportHelper.class.php | 6 ++++-- initialize.php | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index fb0f60025..ecd4f80ac 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -137,7 +137,8 @@ function writeData() { $group_part .= " workday_minutes=\"".$group['workday_minutes']."\""; $group_part .= " custom_logo=\"".$group['custom_logo']."\""; $group_part .= " config=\"".$group['config']."\""; - $group_part .= " custom_css=\"".$group['custom_css']."\""; + $group_part .= " custom_css=\"".htmlspecialchars($group['custom_css'])."\""; + $group_part .= " custom_translation=\"".htmlspecialchars($group['custom_translation'])."\""; $group_part .= ">\n"; // Write group info. diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index aae3267c9..cc0ecf1d8 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -99,7 +99,8 @@ function startElement($parser, $name, $attrs) { 'workday_minutes' => $attrs['WORKDAY_MINUTES'], 'custom_logo' => $attrs['CUSTOM_LOGO'], 'config' => $attrs['CONFIG'], - 'custom_css' => $attrs['CUSTOM_CSS'])); + 'custom_css' => $attrs['CUSTOM_CSS'], + 'custom_translation' => $attrs['CUSTOM_TRANSLATION'])); // Special handling for top group. if (!$this->org_id && $this->current_group_id) { @@ -685,7 +686,7 @@ private function createGroup($fields) { $columns = '(parent_id, org_id, group_key, name, description, currency, decimal_mark, lang, date_format, time_format,'. ' week_start, tracking_mode, project_required, record_type, bcc_email,'. ' allow_ip, password_complexity, plugins, lock_spec,'. - ' workday_minutes, config, custom_css, created, created_ip, created_by)'; + ' workday_minutes, config, custom_css, custom_translation, created, created_ip, created_by)'; $values = ' values ('; $values .= $mdb2->quote($fields['parent_id']); @@ -710,6 +711,7 @@ private function createGroup($fields) { $values .= ', '.(int)$fields['workday_minutes']; $values .= ', '.$mdb2->quote($fields['config']); $values .= ', '.$mdb2->quote($fields['custom_css']); + $values .= ', '.$mdb2->quote($fields['custom_translation']); $values .= ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$user->id; $values .= ')'; diff --git a/initialize.php b/initialize.php index 08bcf66e8..fb76ba64d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.4.5760"); +define("APP_VERSION", "1.22.4.5761"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From afa80d3b183cadcc586b6ffb3d33f0f4e156e1f8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 28 Dec 2022 16:53:14 +0000 Subject: [PATCH 1789/1848] Fixed a bug with deleting custom field dropdown options with 0 as name. --- cf_dropdown_option_delete.php | 2 +- initialize.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cf_dropdown_option_delete.php b/cf_dropdown_option_delete.php index e6eeeeb75..cb8c8a31a 100644 --- a/cf_dropdown_option_delete.php +++ b/cf_dropdown_option_delete.php @@ -17,7 +17,7 @@ } $cl_id = (int)$request->getParameter('id'); $option = CustomFields::getOptionName($cl_id); -if (!$option) { +if ($option == null || $option === false) { header('Location: access_denied.php'); exit(); } diff --git a/initialize.php b/initialize.php index fb76ba64d..5a0189f28 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.4.5761"); +define("APP_VERSION", "1.22.5.5762"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 17705ca52e9e9fbc8cf6c209afecc9c4d5969d7d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 29 Dec 2022 16:10:51 +0000 Subject: [PATCH 1790/1848] Work in progress improving German translation. --- WEB-INF/resources/de.lang.php | 99 ++++++++++++++--------------------- initialize.php | 2 +- 2 files changed, 40 insertions(+), 61 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 9cb0340b9..8f0aae4c2 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -20,19 +20,16 @@ 'menu.logout' => 'Abmelden', 'menu.forum' => 'Forum', 'menu.help' => 'Hilfe', -// TODO: translate the following. -// 'menu.register' => 'Register', +'menu.register' => 'Registrieren', 'menu.profile' => 'Profil', 'menu.group' => 'Gruppe', 'menu.plugins' => 'Erweiterungen', 'menu.time' => 'Zeiten', -// TODO: translate the following. -// 'menu.puncher' => 'Punch', +'menu.puncher' => 'Stempeluhr', 'menu.week' => 'Woche', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Berichte', -// TODO: translate the following. -// 'menu.timesheets' => 'Timesheets', +'menu.timesheets' => 'Arbeitszeittabellen', 'menu.charts' => 'Diagramme', 'menu.projects' => 'Projekte', 'menu.tasks' => 'Aufgaben', @@ -52,8 +49,7 @@ 'error.access_denied' => 'Zugriff verweigert.', 'error.sys' => 'Systemfehler.', 'error.db' => 'Datenbankfehler.', -// TODO: translate the following. -// 'error.registered_recently' => 'Registered recently.', +'error.registered_recently' => 'Kürzlich registriert.', 'error.feature_disabled' => 'Funktion ist deaktiviert.', 'error.field' => 'Ungültige "{0}" Daten.', 'error.empty' => 'Feld "{0}" ist leer.', @@ -65,40 +61,34 @@ 'error.report' => 'Bericht auswählen.', 'error.record' => 'Eintrag auswählen.', 'error.auth' => 'Benutzername oder Passwort ungültig.', -// TODO: translate the following. -// 'error.2fa_code' => 'Invalid 2FA code.', -// 'error.weak_password' => 'Weak password.', +'error.2fa_code' => 'Ungültiger 2FA-Code.', +'error.weak_password' => 'Schwaches Passwort.', 'error.user_exists' => 'Benutzer mit diesem Konto ist bereits vorhanden.', 'error.object_exists' => 'Objekt mit diesem Namen ist bereits vorhanden.', 'error.invoice_exists' => 'Rechnung mit dieser Nummer existiert bereits.', 'error.role_exists' => 'Rolle mit diesem Rang existiert bereits.', 'error.no_invoiceable_items' => 'Keine Einträge zur Rechnungsstellung gefunden.', -// TODO: translate the following. -// 'error.no_records' => 'There are no records.', +'error.no_records' => 'Es gibt keine Einträge.', 'error.no_login' => 'Benutzer mit diesen Anmeldedaten nicht vorhanden.', 'error.no_groups' => 'Die Datenbank ist leer. Als Administrator anmelden und ein neues Gruppe erzeugen.', 'error.upload' => 'Fehler beim hochladen einer Datei.', 'error.range_locked' => 'Zeitinterval ist gesperrt.', -'error.mail_send' => 'Fehler beim versenden einer E-Mail.', -// TODO: improve the translation above by adding MAIL_SMTP_DEBUG part. -// 'error.mail_send' => 'Error sending mail. Use MAIL_SMTP_DEBUG for diagnostics.', +'error.mail_send' => 'Fehler beim versenden einer E-Mail. Verwenden Sie MAIL_SMTP_DEBUG für die Diagnose.', 'error.no_email' => 'Dieser Benutzer besitzt keine e-Mail Adresse.', 'error.uncompleted_exists' => 'Unvollständiger Eintrag bereits vorhanden. Schließen oder Löschen.', 'error.goto_uncompleted' => 'Zum unvollständigen Eintrag gehen.', 'error.overlap' => 'Der Zeitinterval überschneidet sich mit vorhandenen Einträgen.', 'error.future_date' => 'Datum ist in der Zukunft.', -// TODO: translate the following. -// 'error.xml' => 'Error in XML file at line %d: %s.', -// 'error.cannot_import' => 'Cannot import: %s.', -// 'error.format' => 'Invalid file format.', -// 'error.user_count' => 'Limit on user count.', -// 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage server error.', // See comment in English file. +'error.xml' => 'Fehler in der XML-Datei in der Zeile %d: %s.', +'error.cannot_import' => 'Kann nicht importiert werden: %s.', +'error.format' => 'Ungültiges Dateiformat.', +'error.user_count' => 'Begrenzung der Benutzeranzahl erreicht.', +'error.expired' => 'Ablaufdatum erreicht.', +'error.file_storage' => 'Dateispeicherserver-Fehler.', // Warning messages. 'warn.sure' => 'Sind Sie sicher?', -// TODO: translate the following. -// 'warn.confirm_save' => 'Date has changed. Confirm saving, not copying this item.', +'warn.confirm_save' => 'Das Datum hat sich geändert. Bestätigen Sie das Speichern, nicht das Kopieren dieses Elements.', // Success messages. 'msg.success' => 'Operation vollständig abgeschlossen.', @@ -120,19 +110,14 @@ 'button.export' => 'Gruppe exportieren', 'button.import' => 'Gruppe importieren', 'button.close' => 'Schließen', -// TODO: translate the following. -// 'button.start' => 'Start', +'button.start' => 'Start', 'button.stop' => 'Stop', -// TODO: translate the following. -// (PR#81 suggested 'Freigeben / Genehmigen' for 'Approve' and 'Freigabe zurücknehmen' for 'Disapprove'. -// The problem is they do not appear precise, deviate from the meaning of approval / disaproval of report items.) -// 'button.approve' => 'Approve', (suggested 'Freigeben / Genehmigen' does not appear precise) -// 'button.disapprove' => 'Disapprove', -// 'button.sync' => 'Sync', // Used in Android app. The meaning is to synchronize offline time records with server. +'button.approve' => 'Annehmen', +'button.disapprove' => 'Ablehnen', +'button.sync' => 'Sync', // Labels for controls on forms. Labels in this section are used on multiple forms. -// TODO: translate the following. -// 'label.menu' => 'Menu', +'label.menu' => 'Menü', 'label.group_name' => 'Gruppenname', 'label.address' => 'Adresse', 'label.currency' => 'Währung', @@ -152,9 +137,8 @@ 'label.end_date' => 'Enddatum', 'label.user' => 'Benutzer', 'label.users' => 'Personen', -// TODO: translate the following. -// 'label.group' => 'Group', -// 'label.subgroups' => 'Subgroups', +'label.group' => 'Gruppe', +'label.subgroups' => 'Untergruppen', 'label.roles' => 'Rollen', 'label.client' => 'Kunde', 'label.clients' => 'Kunden', @@ -185,8 +169,7 @@ 'label.select_none' => 'Alle abwählen', 'label.day_view' => 'Tagesansicht', 'label.week_view' => 'Wochenansicht', -// TODO: translate the following: -// 'label.puncher' => 'Puncher', +'label.puncher' => 'Stempeluhr', 'label.id' => 'ID', 'label.language' => 'Sprache', 'label.decimal_mark' => 'Dezimaltrennzeichen', @@ -213,8 +196,7 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Benutzerfelder', 'label.monthly_quotas' => 'Monatliche Quoten', -// TODO: translate the following. -// 'label.entity' => 'Entity', +'label.entity' => 'Einheit', 'label.type' => 'Typ', 'label.type_dropdown' => 'Ausklappen', 'label.type_text' => 'Text', @@ -229,33 +211,30 @@ 'label.mark_paid' => 'Als bezahlt setzen', 'label.week_note' => 'Wochennotiz', 'label.week_list' => 'Wochenliste', -// TODO: translate the following: -// 'label.weekends' => 'Weekends', +'label.weekends' => 'Wochenenden', 'label.work_units' => 'Arbeitseinheiten', 'label.work_units_short' => 'Einheiten', 'label.totals_only' => 'Nur Gesamtstunden', 'label.quota' => 'Quote', -// TODO: translate the following. -// 'label.timesheet' => 'Timesheet', -// 'label.submitted' => 'Submitted', -// 'label.approved' => 'Approved', -// 'label.approval' => 'Report approval', -// 'label.mark_approved' => 'Mark approved', -// 'label.template' => 'Template', -// 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_note' => 'Prepopulate Note field', -// 'label.attachments' => 'Attachments', -// 'label.files' => 'Files', -// 'label.file' => 'File', +'label.timesheet' => 'Arbeitszeittabelle', +'label.submitted' => 'Eingereicht', +'label.approved' => 'Genehmigt', +'label.approval' => 'Genehmigung des Berichts', +'label.mark_approved' => 'Als genehmigt markieren', +'label.template' => 'Vorlage', +'label.bind_templates_with_projects' => 'Vorlagen mit Projekten verbinden', +'label.prepopulate_note' => 'Notizfeld vorab ausfüllen', +'label.attachments' => 'Anhänge', +'label.files' => 'Dateien', +'label.file' => 'Datei', 'label.active_users' => 'Aktive Nutzer', 'label.inactive_users' => 'Inaktive Nutzer', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. -// TODO: translate the following. -// 'entity.time' => 'time', -// 'entity.user' => 'user', -// 'entity.project' => 'project', +'entity.time' => 'Zeit', +'entity.user' => 'Benutzer', +'entity.project' => 'Projekt', // Form titles. 'title.error' => 'Fehler', diff --git a/initialize.php b/initialize.php index 5a0189f28..e71ea88f8 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.5.5762"); +define("APP_VERSION", "1.22.5.5763"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 9acc6b2db4c3739bd89632bc1d36216099799931 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 29 Dec 2022 21:44:28 +0000 Subject: [PATCH 1791/1848] Continued to improve German translation. --- WEB-INF/resources/de.lang.php | 78 +++++++++++++++-------------------- initialize.php | 2 +- 2 files changed, 34 insertions(+), 46 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 8f0aae4c2..d0bbf01b9 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -240,8 +240,7 @@ 'title.error' => 'Fehler', 'title.success' => 'Erfol', 'title.login' => 'Anmelden', -// TODO: translate the follolwing. -// 'title.2fa' => 'Two Factor Authentication', +'title.2fa' => 'Zwei-Faktor-Authentifizierung', 'title.groups' => 'Gruppen', 'title.add_group' => 'Gruppe anlegen', 'title.edit_group' => 'Gruppe bearbeiten', @@ -251,9 +250,8 @@ 'title.time' => 'Zeiten', 'title.edit_time_record' => 'Bearbeiten des Stundeneintrags', 'title.delete_time_record' => 'Eintrag löschen', -// TODO: Translate the following. -// 'title.time_files' => 'Time Record Files', -// 'title.puncher' => 'Puncher', +'title.time_files' => 'Zeiterfassungsdateien', +'title.puncher' => 'Stempeluhr', 'title.expenses' => 'Kosten', 'title.edit_expense' => 'Kostenposition ändern', 'title.delete_expense' => 'Kostenposition löschen', @@ -262,10 +260,9 @@ 'title.reports' => 'Berichte', 'title.report' => 'Bericht', 'title.send_report' => 'Bericht senden', -// TODO: Translate the following. -// 'title.timesheets' => 'Timesheets', -// 'title.timesheet' => 'Timesheet', -// 'title.timesheet_files' => 'Timesheet Files', +'title.timesheets' => 'Arbeitszeittabellen', +'title.timesheet' => 'Arbeitszeittabelle', +'title.timesheet_files' => 'Arbeitszeittabellendateien', 'title.invoice' => 'Rechnung', 'title.send_invoice' => 'Rechnung senden', 'title.charts' => 'Diagramme', @@ -298,10 +295,9 @@ 'title.add_notification' => 'Benachrichtigung hinzufügen', 'title.edit_notification' => 'Benachrichtigung bearbeiten', 'title.delete_notification' => 'Benachrichtigung löschen', -// TODO: translate the following. -// 'title.add_timesheet' => 'Adding Timesheet', -// 'title.edit_timesheet' => 'Editing Timesheet', -// 'title.delete_timesheet' => 'Deleting Timesheet', +'title.add_timesheet' => 'Arbeitszeittabelle hinzufügen', +'title.edit_timesheet' => 'Arbeitszeittabelle bearbeiten', +'title.delete_timesheet' => 'Arbeitszeittabelle löschen', 'title.monthly_quotas' => 'Monatliche Quoten', 'title.export' => 'Daten exportieren', 'title.import' => 'Daten importieren', @@ -321,14 +317,13 @@ 'title.week_view' => 'Wochenansicht', 'title.swap_roles' => 'Tausche Rollen', 'title.work_units' => 'Arbeitseinheiten', -// TODO: translate the following. -// 'title.templates' => 'Templates', -// 'title.add_template' => 'Adding Template', -// 'title.edit_template' => 'Editing Template', -// 'title.delete_template' => 'Deleting Template', -// 'title.edit_file' => 'Editing File', -// 'title.delete_file' => 'Deleting File', -// 'title.download_file' => 'Downloading File', +'title.templates' => 'Vorlagen', +'title.add_template' => 'Vorlage hinzufügen', +'title.edit_template' => 'Vorlage bearbeiten', +'title.delete_template' => 'Vorlage löschen', +'title.edit_file' => 'Datei bearbeiten', +'title.delete_file' => 'Datei löschen', +'title.download_file' => 'Datei herunterladen', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. @@ -352,20 +347,17 @@ 'dropdown.clients' => 'Kunden', 'dropdown.select' => '--- auswählen ---', 'dropdown.select_invoice' => '--- Rechnung auswählen ---', -// TODO: translate the following. -// 'dropdown.select_timesheet' => '--- select timesheet ---', +'dropdown.select_timesheet' => '--- Arbeitszeittabelle auswählen ---', 'dropdown.status_active' => 'aktiv', 'dropdown.status_inactive' => 'inaktiv', 'dropdown.delete' => 'löschen', 'dropdown.do_not_delete' => 'nicht löschen', -// TODO: translate the following. -// 'dropdown.approved' => 'approved', -// 'dropdown.not_approved' => 'not approved', +'dropdown.approved' => 'genehmigt', +'dropdown.not_approved' => 'abgelehnt', 'dropdown.paid' => 'bezahlt', 'dropdown.not_paid' => 'nicht bezahlt', -// TODO: translate the following. -// 'dropdown.ascending' => 'ascending', -// 'dropdown.descending' => 'descending', +'dropdown.ascending' => 'aufsteigend', +'dropdown.descending' => 'absteigend', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases @@ -377,14 +369,12 @@ 'form.login.about' => 'Anuko Time Tracker ist ein Open-Source Zeiterfassungssystem.', // Email subject and body for two-factor authentication. -// TODO: translate the following. -// 'email.2fa_code.subject' => 'Anuko Time Tracker two-factor authentication code', -// 'email.2fa_code.body' => "Dear User,\n\nYour two-factor authentication code is:\n\n%s\n\n", +'email.2fa_code.subject' => 'Anuko Time Tracker Zwei-Faktor-Authentifizierungscode', +'email.2fa_code.body' => "Sehr geehrter Benutzer,\n\nIhr Zwei-Faktor-Authentifizierungscode lautet:\n\n%s\n\n", // Two-factor authentication form. See example at https://timetracker.anuko.com/2fa.php. -// TODO: translate the following. -// 'form.2fa.hint' => 'Check your email for 2FA code and enter it here.', -// 'form.2fa.2fa_code' => '2FA code', +'form.2fa.hint' => 'Überprüfen Sie Ihre E-Mails auf den 2FA-Code und geben Sie ihn hier ein.', +'form.2fa.2fa_code' => '2FA-Code', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Anfrage zur Zurücksetzung des Passwortes wurde per E-mail gesendet.', @@ -416,19 +406,17 @@ 'form.reports.include_not_billable' => 'nicht in Rechnung stellen', 'form.reports.include_invoiced' => 'berechnet', 'form.reports.include_not_invoiced' => 'nicht berechnet', -// TODO: translate the following. -// 'form.reports.include_assigned' => 'assigned', -// 'form.reports.include_not_assigned' => 'not assigned', -// 'form.reports.include_pending' => 'pending', +'form.reports.include_pending' => 'Ausstehend', 'form.reports.select_period' => 'Zeitraum auswählen', 'form.reports.set_period' => 'oder Datum eingeben', -// TODO: translate the following. -// 'form.reports.note_containing' => 'Note containing', +// TODO: review form.reports.note_containing translation for accuracy. +// This is basically a string filter in user notes, see https://www.anuko.com/time-tracker/what-is/note-containing.htm +'form.reports.note_containing' => 'Enthält Notitz', // The concern is that it may be translated as "Containing a note", which is different + // from "Note containing a substring in this field." 'form.reports.show_fields' => 'Felder anzeigen', -// TODO: translate the following. -// 'form.reports.time_fields' => 'Time fields', -// 'form.reports.user_fields' => 'User fields', -// 'form.reports.project_fields' => 'Project fields', +'form.reports.time_fields' => 'Zeitfelder', +'form.reports.user_fields' => 'Benutzerfelder', +'form.reports.project_fields' => 'Projektfelder', 'form.reports.group_by' => 'Gruppieren nach', 'form.reports.group_by_no' => '--- keine Gruppierung ---', 'form.reports.group_by_date' => 'Datum', diff --git a/initialize.php b/initialize.php index e71ea88f8..fb4b2f494 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.5.5763"); +define("APP_VERSION", "1.22.5.5764"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From eb8a5bab0ad7cf9654c40fcf005d6021f3756044 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 30 Dec 2022 16:08:27 +0000 Subject: [PATCH 1792/1848] Work in progress on German translation. Almost done. --- WEB-INF/resources/de.lang.php | 58 ++++++++++++++++------------------- initialize.php | 2 +- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index d0bbf01b9..0217fa236 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -430,18 +430,21 @@ 'form.report.export' => 'Exportiere', 'form.report.per_hour' => 'Stundensatz', 'form.report.assign_to_invoice' => 'Zu Rechnung hinzufügen', -// TODO: translate the following. +// TODO: REVIEW the following. // 'form.report.assign_to_timesheet' => 'Assign to timesheet', +// See how this feature works: https://www.anuko.com/time-tracker/user-guide/timesheets.htm +// Basically, we are selecting records in a report and assign them TO (include IN) one of timesheets. +// The concern is that it is now translated as "Assign timesheet", which is different from how +// form.report.assign_to_invoice above is translated. +'form.report.assign_to_timesheet' => 'Arbeitszeittabelle zuweisen', // Timesheets form. See example at https://timetracker.anuko.com/timesheets.php -// TODO: translate the following. -// 'form.timesheets.active_timesheets' => 'Active Timesheets', -// 'form.timesheets.inactive_timesheets' => 'Inactive Timesheets', +'form.timesheets.active_timesheets' => 'Aktive Arbeitszeittabellen', +'form.timesheets.inactive_timesheets' => 'Inaktive Arbeitszeittabellen', // Templates form. See example at https://timetracker.anuko.com/templates.php -// TODO: translate the following. -// 'form.templates.active_templates' => 'Active Templates', -// 'form.templates.inactive_templates' => 'Inactive Templates', +'form.templates.active_templates' => 'Aktive Vorlagen', +'form.templates.inactive_templates' => 'Inaktive Vorlagen', // Invoice form. See example at https://timetracker.anuko.com/invoice_view.php // (you can get to this form after generating an invoice). @@ -466,8 +469,7 @@ 'form.tasks.inactive_tasks' => 'Inaktive Tasks', // Users form. See example at https://timetracker.anuko.com/users.php -// TODO: translate the following. -// 'form.users.uncompleted_entry_today' => 'User has an uncompleted time entry today', +'form.users.uncompleted_entry_today' => 'Der Benutzer hat heute einen nicht abgeschlossenen Zeiteintrag', 'form.users.uncompleted_entry' => 'Nutzer hat einen unvollständigen Zeiteintrag', 'form.users.role' => 'Rolle', 'form.users.manager' => 'Manager', @@ -521,21 +523,18 @@ 'form.group_edit.type_all' => 'alle', 'form.group_edit.type_start_finish' => 'Start und Ende', 'form.group_edit.type_duration' => 'Dauer', -'form.group_edit.punch_mode' => 'Stechuhr-Modus', -// TODO: translate the following. -// 'form.group_edit.one_uncompleted' => 'One uncompleted', +'form.group_edit.punch_mode' => 'Stempeluhr-Modus', +'form.group_edit.one_uncompleted' => 'Eine unvollendete', 'form.group_edit.allow_overlap' => 'Erlaube Überschneidung', 'form.group_edit.future_entries' => 'Einträge in der Zukunft', 'form.group_edit.uncompleted_indicators' => 'Zeige unfertige Einträge', 'form.group_edit.confirm_save' => 'Speichern bestätigen', -// TODO: translate the following. -// 'form.group_edit.advanced_settings' => 'Advanced settings', +'form.group_edit.advanced_settings' => 'Erweiterte Einstellungen', // Advanced Group Settings form. See example at https://timetracker.anuko.com/group_advanced_edit.php. 'form.group_advanced_edit.allow_ip' => 'Erlaube IP', -// TODO: Translate the following. -// 'form.group_advanced_edit.password_complexity' => 'Password complexity', -// 'form.group_advanced_edit.2fa' => 'Two factor authentication', +'form.group_advanced_edit.password_complexity' => 'Komplexität des Passworts', +'form.group_advanced_edit.2fa' => 'Zwei-Faktor-Authentifizierung', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Sind Sie sicher, dass Sie die gesamte Gruppe löschen möchten?', @@ -569,7 +568,6 @@ 'role.client.low_case_label' => 'Kunde', // TODO: translate the following. // 'role.client.description' => 'A client can view its own data.', -'role.client.description' => 'Ein Kunde kann zu ihm gehörende Berichte und Rechnungen ansehen.', 'role.supervisor.label' => 'Dienstvorgesetzter', 'role.supervisor.low_case_label' => 'Dienstvorgesetzter', 'role.supervisor.description' => 'Eine Person mit ein paar Administrationsrechten.', @@ -587,20 +585,18 @@ 'role.admin.description' => 'Aadminsitrator der Seite.', // Timesheet View form. See example at https://timetracker.anuko.com/timesheet_view.php. -// TODO: translate the following. -// 'form.timesheet_view.submit_subject' => 'Timesheet approval request', -// 'form.timesheet_view.submit_body' => "A new timesheet requires approval.

User: %s.", -// 'form.timesheet_view.approve_subject' => 'Timesheet approved', -// 'form.timesheet_view.approve_body' => "Your timesheet %s was approved.

%s", -// 'form.timesheet_view.disapprove_subject' => 'Timesheet not approved', -// 'form.timesheet_view.disapprove_body' => "Your timesheet %s was not approved.

%s", +'form.timesheet_view.submit_subject' => 'Antrag auf Genehmigung der Arbeitszeittabelle', +'form.timesheet_view.submit_body' => "Eine neue Arbeitszeittabelle muss genehmigt werden.

Benutzer: %s.", +'form.timesheet_view.approve_subject' => 'Arbeitszeittabelle genehmigt', +'form.timesheet_view.approve_body' => "Ihre Arbeitszeittabelle %s wurde genehmigt.

%s", +'form.timesheet_view.disapprove_subject' => 'Arbeitszeittabelle nicht genehmigt', +'form.timesheet_view.disapprove_body' => "Ihre Arbeitszeittabelle %s wurde nicht genehmigt.

%s", // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.note_on_separate_row' => 'Beschreibung in separater Zeile', -// TODO: translate the following. -// 'form.display_options.not_complete_days' => 'Not complete days', -// 'form.display_options.inactive_projects' => 'Inactive projects', -// 'form.display_options.cost_per_hour' => 'Cost per hour', -// 'form.display_options.custom_css' => 'Custom CSS', -// 'form.display_options.custom_translation' => 'Custom translation', +'form.display_options.not_complete_days' => 'Nicht vollständige Tage', +'form.display_options.inactive_projects' => 'Inaktive Projekte', +'form.display_options.cost_per_hour' => 'Kosten pro Stunde', +'form.display_options.custom_css' => 'Benutzerdefiniertes CSS', +'form.display_options.custom_translation' => 'Benutzerdefinierte Übersetzung', ); diff --git a/initialize.php b/initialize.php index fb4b2f494..67bd4373c 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.5.5764"); +define("APP_VERSION", "1.22.5.5765"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ae138917e7a9e4bf5efcf36bd7969303a0831d19 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 31 Dec 2022 14:48:48 +0000 Subject: [PATCH 1793/1848] Bug fixes related to using 0 as entity name. --- WEB-INF/lib/form/TextField.class.php | 2 +- WEB-INF/lib/ttAdmin.class.php | 7 +++++-- admin_group_delete.php | 2 +- admin_group_edit.php | 2 +- cf_dropdown_option_delete.php | 2 +- cf_dropdown_option_edit.php | 2 +- initialize.php | 2 +- plugins/CustomFields.class.php | 8 +++++--- 8 files changed, 16 insertions(+), 11 deletions(-) diff --git a/WEB-INF/lib/form/TextField.class.php b/WEB-INF/lib/form/TextField.class.php index 91f8b5c2a..bfc0e551f 100644 --- a/WEB-INF/lib/form/TextField.class.php +++ b/WEB-INF/lib/form/TextField.class.php @@ -56,7 +56,7 @@ function getHtml() { if (!empty($this->on_change)) $html .= " onchange=\"$this->on_change\""; } - $html .= " value=\"".htmlspecialchars($this->getValue() ? $this->getValue() : '')."\""; + $html .= " value=\"".htmlspecialchars($this->getValue())."\""; if(!$this->isEnabled()) $html .= " readonly"; $html .= ">\n"; diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index 35a26afbe..00bd0ff59 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -150,6 +150,8 @@ static function updateSelf($fields) { // getGroupName obtains group name. static function getGroupName($group_id) { + $group_id = (int) $group_id; // Just in case because it is used in sql. + $result = array(); $mdb2 = getConnection(); @@ -158,10 +160,11 @@ static function getGroupName($group_id) { $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - return $val['name']; + if (isset($val['name'])) + return $val['name']; } - return false; + return null; } // getOrgDetails obtains group name and its top manager details. diff --git a/admin_group_delete.php b/admin_group_delete.php index 0cea02b32..909b2347a 100644 --- a/admin_group_delete.php +++ b/admin_group_delete.php @@ -13,7 +13,7 @@ } $group_id = (int)$request->getParameter('id'); $group_name = ttAdmin::getGroupName($group_id); -if (!($group_id && $group_name)) { +if (!($group_id && $group_name != null)) { header('Location: access_denied.php'); exit(); } diff --git a/admin_group_edit.php b/admin_group_edit.php index 81588ebec..496c7b8fb 100644 --- a/admin_group_edit.php +++ b/admin_group_edit.php @@ -14,7 +14,7 @@ } $group_id = (int)$request->getParameter('id'); $group_name = ttAdmin::getGroupName($group_id); -if (!($group_id && $group_name)) { +if (!($group_id && $group_name != null)) { header('Location: access_denied.php'); exit(); } diff --git a/cf_dropdown_option_delete.php b/cf_dropdown_option_delete.php index cb8c8a31a..50c685014 100644 --- a/cf_dropdown_option_delete.php +++ b/cf_dropdown_option_delete.php @@ -17,7 +17,7 @@ } $cl_id = (int)$request->getParameter('id'); $option = CustomFields::getOptionName($cl_id); -if ($option == null || $option === false) { +if ($option == null) { header('Location: access_denied.php'); exit(); } diff --git a/cf_dropdown_option_edit.php b/cf_dropdown_option_edit.php index eee02f63c..2477b057c 100644 --- a/cf_dropdown_option_edit.php +++ b/cf_dropdown_option_edit.php @@ -17,7 +17,7 @@ } $cl_id = (int)$request->getParameter('id'); $cl_name = CustomFields::getOptionName($cl_id); -if (!$cl_name) { +if ($cl_name == null) { header('Location: access_denied.php'); exit(); } diff --git a/initialize.php b/initialize.php index 67bd4373c..b6d48738d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.5.5765"); +define("APP_VERSION", "1.22.6.5766"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 0e52871e2..b4839cf1b 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -221,6 +221,8 @@ static function getOptionName($id) { global $user; $mdb2 = getConnection(); + $id = (int) $id; // Just in case. Better safe than sorry as it is used in sql. + $group_id = $user->getGroup(); $org_id = $user->org_id; @@ -229,10 +231,10 @@ static function getOptionName($id) { $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { $val = $res->fetchRow(); - $name = $val['value']; - return $name; + if (isset($val['value'])) + return $val['value']; } - return false; + return null; } // getFields returns an array of custom fields for group. From aa8c6961dcce1ae929f1108033871f9574bddae5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 31 Dec 2022 15:17:40 +0000 Subject: [PATCH 1794/1848] Fixes related to using 0 in fields. --- WEB-INF/lib/ttAdmin.class.php | 3 ++- admin_options.php | 2 +- initialize.php | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index 00bd0ff59..4a631d5e3 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -138,7 +138,8 @@ static function updateSelf($fields) { // Update self. $user_id = $user->id; $login_part = 'login = '.$mdb2->quote($fields['login']); - if ($fields['password1']) + $password_part = ''; + if (isset($fields['password1'])) $password_part = ', password = md5('.$mdb2->quote($fields['password1']).')'; $name_part = ', name = '.$mdb2->quote($fields['name']); $email_part = ', email = '.$mdb2->quote($fields['email']); diff --git a/admin_options.php b/admin_options.php index 84a0ed3a5..aed852320 100644 --- a/admin_options.php +++ b/admin_options.php @@ -48,7 +48,7 @@ // If we change login, it must be unique. if ($cl_login != $user->login && ttUserHelper::getUserByLogin($cl_login)) $err->add($i18n->get('error.user_exists')); - if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { + if (!$auth->isPasswordExternal() && ($cl_password1 != null || $cl_password2 != null)) { if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); if (!ttValidString($cl_password2)) diff --git a/initialize.php b/initialize.php index b6d48738d..3e332ebab 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.6.5766"); +define("APP_VERSION", "1.22.6.5767"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From d019c044c0e8d21ce463f680fd45f86fcf6c8014 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 1 Jan 2023 16:21:43 +0000 Subject: [PATCH 1795/1848] Disallowed adding a duplicate custom field with the same name and entity type. --- cf_custom_field_add.php | 2 +- initialize.php | 2 +- plugins/CustomFields.class.php | 21 +++++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index c10803758..87d46bcd5 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -15,7 +15,6 @@ header('Location: feature_disabled.php'); exit(); } -$fields = CustomFields::getFields(); // End of access checks. if ($request->isPost()) { @@ -42,6 +41,7 @@ if ($request->isPost()) { // Validate user input. if (!ttValidString($cl_field_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (CustomFields::getFieldByName($cl_field_name, $cl_entity_type) != null) $err->add($i18n->get('error.object_exists')); if ($err->no()) { $res = CustomFields::insertField($cl_field_name, $cl_entity_type, $cl_field_type, $cl_required); diff --git a/initialize.php b/initialize.php index 3e332ebab..e43e33d3e 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.6.5767"); +define("APP_VERSION", "1.22.6.5768"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index b4839cf1b..b561af804 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -278,6 +278,27 @@ static function getField($id) { return false; } + // getFieldByName returns a custom field by name and its entity type. + static function getFieldByName($fieldName, $entityType) { + global $user; + $mdb2 = getConnection(); + + $entityType = (int) $entityType; // Just in case. + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select label, type, required from tt_custom_fields" . + " where label = ". $mdb2->quote($fieldName) . " and entity_type = $entityType". + " and group_id = $group_id and org_id = $org_id and status is not null"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if (isset($val)) + return $val; + } + return null; + } + // getFieldIdForOption returns field id from an associated option id. static function getFieldIdForOption($option_id) { global $user; From e0b9d2112e4b8134839e9540acb6d133bf1dce6b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 2 Jan 2023 17:15:59 +0000 Subject: [PATCH 1796/1848] Fixed a printing problem by eliminating a 1st page break for large reports. --- default.css | 13 +++++++++++++ initialize.php | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index 38de0f53f..7c88fc2d6 100644 --- a/default.css +++ b/default.css @@ -145,6 +145,19 @@ div.page-hint { border-collapse: collapse; } +/* For printing large tables that do not fit into one page, we have to change the display +property to "block" and also use "break-before: avoid;". This eliminates a page break between +header and large table on print previews. I could not accomplish this with inline-block +because break-before is apparently ignored for inline elements. +inline-block above in itself is needed for nice horizontal centering on screen. */ +@media print +{ + .x-scrollable-table { display: block; break-before: avoid; break-after: auto; } + /* Not sure if we need this, keep commented out for now. + .x-scrollable-table tr { page-break-inside:avoid; page-break-after:auto; } + .x-scrollable-table td { page-break-inside:avoid; page-break-after:auto; } */ +} + /* th in x-scrollable-table */ .x-scrollable-table th { white-space: nowrap; diff --git a/initialize.php b/initialize.php index e43e33d3e..c43bafddd 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.6.5768"); +define("APP_VERSION", "1.22.7.5769"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 791d64428e8242a5bc4fd8af311c36ba1379d602 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 2 Jan 2023 20:57:22 +0000 Subject: [PATCH 1797/1848] A fix for invoices to allow 0 as invoice name. --- WEB-INF/lib/ttInvoiceHelper.class.php | 3 +-- initialize.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 2ac63db44..44206fa0e 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -298,8 +298,7 @@ static function createInvoice($fields) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $name = $fields['name']; - if (!$name) return false; + $name = isset($fields['name']) ? $fields['name'] : null; $client_id = (int) $fields['client_id']; diff --git a/initialize.php b/initialize.php index c43bafddd..9f8a7a45f 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.7.5769"); +define("APP_VERSION", "1.22.7.5770"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From b3f906536d4f6e8e9eb64e6b7a8c4a7db2969b06 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 5 Jan 2023 15:48:15 +0000 Subject: [PATCH 1798/1848] Some fixes for incompatible database structure. --- WEB-INF/lib/ttUser.class.php | 162 +++++++++++++++++++---------------- default.css | 5 +- initialize.php | 2 +- login.php | 12 ++- 4 files changed, 98 insertions(+), 83 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 37591fa5f..2e86eacb9 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -62,6 +62,9 @@ class ttUser { var $behalfUser = null; // A ttBehalfUser instance with on behalf user attributes. var $behalfGroup = null; // A ttGroup instance with on behalf group attributes. + var $initialized = false; // Set to true when an object is initialized. + + // Constructor. function __construct($login, $id = null) { if (!$login && !$id) { @@ -69,86 +72,93 @@ function __construct($login, $id = null) { return; } - $mdb2 = getConnection(); - - $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id,". - " u.quota_percent, u.email, g.org_id, g.group_key, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format,". - " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.record_type,". - " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.custom_css, g.custom_translation,". - " g.holidays, g.workday_minutes, g.custom_logo". - " FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; - if ($id) - $sql .= "u.id = $id"; - else - $sql .= "u.login = ".$mdb2->quote($login); - $sql .= " AND u.status = 1"; + try { + $mdb2 = getConnection(); + + $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id,". + " u.quota_percent, u.email, g.org_id, g.group_key, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format,". + " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.record_type,". + " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.custom_css, g.custom_translation,". + " g.holidays, g.workday_minutes, g.custom_logo". + " FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; + if ($id) + $sql .= "u.id = $id"; + else + $sql .= "u.login = ".$mdb2->quote($login); + $sql .= " AND u.status = 1"; + + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) { + return; + } - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) { - return; - } + $val = $res->fetchRow(); + if ($val['id'] > 0) { + $this->login = $val['login']; + $this->name = $val['name']; + $this->id = $val['id']; + $this->org_id = $val['org_id']; + $this->group_id = $val['group_id']; + $this->group_key = $val['group_key']; + if ($this->org_id == $this->group_key) $this->org_key = $val['group_key']; + $this->role_id = $val['role_id']; + $this->role_name = $val['role_name']; + $this->rights = explode(',', $val['rights']); + $this->rank = $val['rank']; + $this->client_id = $val['client_id']; + $this->is_client = $this->client_id && !in_array('track_own_time', $this->rights); + if ($val['quota_percent']) $this->quota_percent = $val['quota_percent']; + $this->email = $val['email']; + if ($val['lang']) $this->lang = $val['lang']; + if ($val['decimal_mark']) $this->decimal_mark = $val['decimal_mark']; + $this->date_format = $val['date_format']; + $this->time_format = $val['time_format']; + $this->week_start = $val['week_start']; + $this->tracking_mode = $val['tracking_mode']; + $this->project_required = $val['project_required']; + $this->record_type = $val['record_type']; + $this->bcc_email = $val['bcc_email']; + $this->allow_ip = $val['allow_ip']; + $this->password_complexity = $val['password_complexity']; + $this->group_name = $val['group_name']; + $this->currency = $val['currency']; + $this->plugins = $val['plugins']; + $this->lock_spec = $val['lock_spec']; + $this->holidays = $val['holidays']; + $this->workday_minutes = $val['workday_minutes']; + $this->custom_logo = $val['custom_logo']; + + // TODO: refactor this. + $this->config = $val['config']; + $this->configHelper = new ttConfigHelper($val['config']); + + // Set user config options. + $this->punch_mode = $this->configHelper->getDefinedValue('punch_mode'); + $this->allow_overlap = $this->configHelper->getDefinedValue('allow_overlap'); + + $this->custom_css = $val['custom_css']; + $this->custom_translation = $val['custom_translation']; + + // Set "on behalf" id and name (user). + if (isset($_SESSION['behalf_id'])) { + $this->behalf_id = $_SESSION['behalf_id']; + $this->behalf_name = $_SESSION['behalf_name']; + + $this->behalfUser = new ttBehalfUser($this->behalf_id, $this->org_id); + } + // Set "on behalf" id and name (group). + if (isset($_SESSION['behalf_group_id'])) { + $this->behalf_group_id = $_SESSION['behalf_group_id']; + $this->behalf_group_name = $_SESSION['behalf_group_name']; - $val = $res->fetchRow(); - if ($val['id'] > 0) { - $this->login = $val['login']; - $this->name = $val['name']; - $this->id = $val['id']; - $this->org_id = $val['org_id']; - $this->group_id = $val['group_id']; - $this->group_key = $val['group_key']; - if ($this->org_id == $this->group_key) $this->org_key = $val['group_key']; - $this->role_id = $val['role_id']; - $this->role_name = $val['role_name']; - $this->rights = explode(',', $val['rights']); - $this->rank = $val['rank']; - $this->client_id = $val['client_id']; - $this->is_client = $this->client_id && !in_array('track_own_time', $this->rights); - if ($val['quota_percent']) $this->quota_percent = $val['quota_percent']; - $this->email = $val['email']; - if ($val['lang']) $this->lang = $val['lang']; - if ($val['decimal_mark']) $this->decimal_mark = $val['decimal_mark']; - $this->date_format = $val['date_format']; - $this->time_format = $val['time_format']; - $this->week_start = $val['week_start']; - $this->tracking_mode = $val['tracking_mode']; - $this->project_required = $val['project_required']; - $this->record_type = $val['record_type']; - $this->bcc_email = $val['bcc_email']; - $this->allow_ip = $val['allow_ip']; - $this->password_complexity = $val['password_complexity']; - $this->group_name = $val['group_name']; - $this->currency = $val['currency']; - $this->plugins = $val['plugins']; - $this->lock_spec = $val['lock_spec']; - $this->holidays = $val['holidays']; - $this->workday_minutes = $val['workday_minutes']; - $this->custom_logo = $val['custom_logo']; - - // TODO: refactor this. - $this->config = $val['config']; - $this->configHelper = new ttConfigHelper($val['config']); - - // Set user config options. - $this->punch_mode = $this->configHelper->getDefinedValue('punch_mode'); - $this->allow_overlap = $this->configHelper->getDefinedValue('allow_overlap'); - - $this->custom_css = $val['custom_css']; - $this->custom_translation = $val['custom_translation']; - - // Set "on behalf" id and name (user). - if (isset($_SESSION['behalf_id'])) { - $this->behalf_id = $_SESSION['behalf_id']; - $this->behalf_name = $_SESSION['behalf_name']; - - $this->behalfUser = new ttBehalfUser($this->behalf_id, $this->org_id); + $this->behalfGroup = new ttGroup($this->behalf_group_id, $this->org_id); + } } - // Set "on behalf" id and name (group). - if (isset($_SESSION['behalf_group_id'])) { - $this->behalf_group_id = $_SESSION['behalf_group_id']; - $this->behalf_group_name = $_SESSION['behalf_group_name']; - $this->behalfGroup = new ttGroup($this->behalf_group_id, $this->org_id); - } + $this->initialized = true; + } + catch (Exception $e) { + error_log("Exception raised in ttUser constructor: ".$e->getMessage()); } } diff --git a/default.css b/default.css index 7c88fc2d6..d1a77ebd8 100644 --- a/default.css +++ b/default.css @@ -148,8 +148,9 @@ div.page-hint { /* For printing large tables that do not fit into one page, we have to change the display property to "block" and also use "break-before: avoid;". This eliminates a page break between header and large table on print previews. I could not accomplish this with inline-block -because break-before is apparently ignored for inline elements. -inline-block above in itself is needed for nice horizontal centering on screen. */ +because break-before is apparently ignored for inline-block elements. +inline-block above in itself is needed for nice horizontal centering on screen. +A side effect of this is that printed tables are not horizontally centered. */ @media print { .x-scrollable-table { display: block; break-before: avoid; break-after: auto; } diff --git a/initialize.php b/initialize.php index 9f8a7a45f..e2f8a2e23 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,7 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.7.5770"); +define("APP_VERSION", "1.22.8.5771"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/login.php b/login.php index f5dd8eec1..2d9dde044 100644 --- a/login.php +++ b/login.php @@ -55,13 +55,17 @@ if ($err->no() && $loginSucceeded) { $user = new ttUser(null, $auth->getUserId()); - // Determine if we have to additionally use two-factor authentication. - $config = $user->getConfigHelper(); - $use2FA = $config->getDefinedValue('2fa'); + if ($user->initialized) { + // Determine if we have to additionally use two-factor authentication. + $config = $user->getConfigHelper(); + $use2FA = $config->getDefinedValue('2fa'); + } else { + $err->add($i18n->get('error.db')); + } } // If we have to use 2FA, email auth code to user and redirect to 2fa.php. - if ($use2FA && !$user->can('override_2fa')) { + if ($err->no() && $use2FA && !$user->can('override_2fa')) { // To keep things simple, we use the same code as for password resets. $cryptographically_strong = true; $random_bytes = openssl_random_pseudo_bytes(16, $cryptographically_strong); From 94765d3b81cbbe5feb8d0a2418e3f29d06c61740 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 6 Jan 2023 16:22:10 +0000 Subject: [PATCH 1799/1848] An attempt to better support php8.1 or greater. --- initialize.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/initialize.php b/initialize.php index e2f8a2e23..0ed4d1d7d 100644 --- a/initialize.php +++ b/initialize.php @@ -12,7 +12,13 @@ // Disable displaying errors on screen. ini_set('display_errors', 'Off'); -define("APP_VERSION", "1.22.8.5771"); +// Disable mysqli fatal error behaviour when using php8.1 or greater. +// See https://php.watch/versions/8.1/mysqli-error-mode +if (version_compare(phpversion(), '8.1', '>=')) { + mysqli_report(MYSQLI_REPORT_OFF); +} + +define("APP_VERSION", "1.22.9.5772"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 6bce8835b9b5a5c185ba44a652b9955993ff27a2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 7 Jan 2023 18:12:18 +0000 Subject: [PATCH 1800/1848] Addressed a few more php8.0 warnings. --- dbinstall.php | 44 ++++++++++++++++++++++---------------------- initialize.php | 2 +- time.php | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/dbinstall.php b/dbinstall.php index c79cd558a..2db0bebca 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -201,7 +201,7 @@ function ttGenerateKeys() { if ($_POST) { print "Processing...
\n"; - if ($_POST["crstructure"]) { + if (array_key_exists('crstructure', $_POST)) { $sqlQuery = join("\n", file("mysql.sql")); $sqlQuery = str_replace("TYPE=MyISAM","",$sqlQuery); $queries = explode(";",$sqlQuery); @@ -215,7 +215,7 @@ function ttGenerateKeys() { } } - if ($_POST["convert5to7"]) { + if (array_key_exists('convert5to7', $_POST)) { ttExecute("alter table `activity_log` CHANGE al_comment al_comment text"); ttExecute("CREATE TABLE `sysconfig` (`sysc_id` int(11) unsigned NOT NULL auto_increment,`sysc_name` varchar(32) NOT NULL default '',`sysc_value` varchar(70) default NULL, PRIMARY KEY (`sysc_id`), UNIQUE KEY `sysc_id` (`sysc_id`), UNIQUE KEY `sysc_name` (`sysc_name`))"); ttExecute("alter table `companies` add c_locktime int(4) default -1"); @@ -229,7 +229,7 @@ function ttGenerateKeys() { ttExecute("alter table users drop `u_aprojects`"); } - if ($_POST["convert7to133"]) { + if (array_key_exists('convert7to133', $_POST)) { ttExecute("ALTER TABLE users ADD COLUMN u_lang VARCHAR(20) DEFAULT NULL"); ttExecute("ALTER TABLE users ADD COLUMN u_email VARCHAR(100) DEFAULT NULL"); ttExecute("ALTER TABLE `activity_log` drop `al_proof`"); @@ -244,7 +244,7 @@ function ttGenerateKeys() { // The update_projects function updates p_activities field in the projects table so that we could // improve performance of the application by using this field instead of activity_bind table. - if ($_POST["update_projects"]) { + if (array_key_exists('update_projects', $_POST)) { $mdb2 = getConnection(); // $sql = "select p_id from projects where p_status = 1 and p_activities is NULL"; $sql = "select p_id from projects where p_status = 1"; @@ -281,15 +281,15 @@ function ttGenerateKeys() { } } - if ($_POST["convert133to1340"]) { + if (array_key_exists('convert133to1340', $_POST)) { ttExecute("ALTER TABLE companies ADD COLUMN c_show_pie smallint(2) DEFAULT 1"); ttExecute("ALTER TABLE companies ADD COLUMN c_pie_mode smallint(2) DEFAULT 1"); ttExecute("ALTER TABLE companies ADD COLUMN c_lang varchar(20) default NULL"); } // The update_companies function sets up c_show_pie, c_pie_mode, and c_lang - // fields in the companies table from the corresponding manager fields. - if ($_POST["update_companies"]) { + // fields in the companies table from the corresponding manager fields. + if (array_key_exists('update_companies', $_POST)) { $mdb2 = getConnection(); // Get all active managers. $sql = "select u_company_id, u_show_pie, u_pie_mode, u_lang from users @@ -316,7 +316,7 @@ function ttGenerateKeys() { } } - if ($_POST["convert1340to1485"]) { + if (array_key_exists('convert1340to1485', $_POST)) { ttExecute("ALTER TABLE users DROP u_show_pie"); ttExecute("ALTER TABLE users DROP u_pie_mode"); ttExecute("ALTER TABLE users DROP u_lang"); @@ -421,7 +421,7 @@ function ttGenerateKeys() { } // The update_to_team_id function sets team_id field projects, activities, and clients tables. - if ($_POST["update_to_team_id"]) { + if (array_key_exists('update_to_team_id', $_POST)) { $mdb2 = getConnection(); // Update projects. @@ -518,7 +518,7 @@ function ttGenerateKeys() { print "Updated $clients_updated clients...
\n"; } - if ($_POST["convert1485to1579"]) { + if (array_key_exists('convert1485to1579', $_POST)) { ttExecute("ALTER TABLE tt_fav_reports MODIFY id int(11) NOT NULL auto_increment"); ttExecute("RENAME TABLE clients TO tt_clients"); ttExecute("ALTER TABLE tt_clients CHANGE clnt_id id int(11) NOT NULL AUTO_INCREMENT"); @@ -625,7 +625,7 @@ function ttGenerateKeys() { ttExecute("create index invoice_idx on tt_log(invoice_id)"); } - if ($_POST["convert1579to1600"]) { + if (array_key_exists('convert1579to1600', $_POST)) { ttExecute("ALTER TABLE tt_invoices ADD COLUMN date date NOT NULL"); ttExecute("ALTER TABLE tt_teams ADD COLUMN custom_logo tinyint(4) default '0'"); ttExecute("ALTER TABLE tt_tasks ADD COLUMN description varchar(255) default NULL"); @@ -643,7 +643,7 @@ function ttGenerateKeys() { } // The update_clients function updates projects field in tt_clients table. - if ($_POST["update_clients"]) { + if (array_key_exists('update_clients', $_POST)) { $mdb2 = getConnection(); $sql = "select id from tt_clients where status = 1 or status = 0"; $res = $mdb2->query($sql); @@ -682,7 +682,7 @@ function ttGenerateKeys() { } // The update_custom_fields function updates option_id field in tt_custom_field_log table. - if ($_POST['update_custom_fields']) { + if (array_key_exists('update_custom_fields', $_POST)) { $mdb2 = getConnection(); $sql = "update tt_custom_field_log set option_id = value where option_id is null and value is not null and field_id in (select id from tt_custom_fields where type = 2)"; $affected = $mdb2->exec($sql); @@ -693,7 +693,7 @@ function ttGenerateKeys() { } // The update_tracking_mode function sets the tracking_mode field in tt_teams table to 2 (== MODE_PROJECTS_AND_TASKS). - if ($_POST['update_tracking_mode']) { + if (array_key_exists('update_tracking_mode', $_POST)) { $mdb2 = getConnection(); $sql = "update tt_teams set tracking_mode = 2 where tracking_mode = 0"; $affected = $mdb2->exec($sql); @@ -703,7 +703,7 @@ function ttGenerateKeys() { print "Updated $affected teams...
\n"; } - if ($_POST["convert1600to11400"]) { + if (array_key_exists('convert1600to11400', $_POST)) { ttExecute("DROP TABLE IF EXISTS tt_invoice_headers"); ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `client_id` int(11) default NULL"); ttExecute("ALTER TABLE tt_fav_reports ADD COLUMN `cf_1_option_id` int(11) default NULL"); @@ -751,7 +751,7 @@ function ttGenerateKeys() { ttExecute("ALTER TABLE `tt_log` ADD `paid` tinyint(4) NULL default '0' AFTER `billable`"); } - if ($_POST["convert11400to11744"]) { + if (array_key_exists('convert11400to11744', $_POST)) { ttExecute("ALTER TABLE `tt_teams` DROP `address`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `report_spec` text default NULL AFTER `user_id`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `paid_status` tinyint(4) default NULL AFTER `invoice`"); @@ -794,7 +794,7 @@ function ttGenerateKeys() { } // The update_role_id function assigns a role_id to users, who don't have it. - if ($_POST['update_role_id']) { + if (array_key_exists('update_role_id', $_POST)) { import('I18n'); $mdb2 = getConnection(); @@ -833,7 +833,7 @@ function ttGenerateKeys() { print "Updated $users_updated users...
\n"; } - if ($_POST["convert11744to11797"]) { + if (array_key_exists('convert11744to11797', $_POST)) { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); ttExecute("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and `rank` = 512) where role = 324"); @@ -938,7 +938,7 @@ function ttGenerateKeys() { } // The update_group_id function updates group_id field in tt_log and tt_expense_items tables. - if ($_POST["update_group_id"]) { + if (array_key_exists('update_group_id', $_POST)) { $mdb2 = getConnection(); $sql = "(select distinct user_id from tt_log where group_id is null) union distinct (select distinct user_id from tt_expense_items where group_id is null)"; @@ -984,7 +984,7 @@ function ttGenerateKeys() { print "Updated $tt_expense_items_updated tt_expense_items records...
\n"; } - if ($_POST["convert11797to11900"]) { + if (array_key_exists('convert11797to11900', $_POST)) { ttExecute("ALTER TABLE `tt_fav_reports` CHANGE `group_by` `group_by1` varchar(20) default NULL"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by2` varchar(20) default NULL AFTER `group_by1`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `group_by3` varchar(20) default NULL AFTER `group_by2`"); @@ -1151,7 +1151,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to12203"]) { + if (array_key_exists('convert11900to12203', $_POST)) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1203,7 +1203,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.22.3', modified = now() where param_name = 'version_db' and param_value = '1.21.7'"); } - if ($_POST["cleanup"]) { + if (array_key_exists('cleanup', $_POST)) { $mdb2 = getConnection(); $inactive_orgs = ttOrgHelper::getInactiveOrgs(); diff --git a/initialize.php b/initialize.php index 0ed4d1d7d..705d2db19 100644 --- a/initialize.php +++ b/initialize.php @@ -18,7 +18,7 @@ mysqli_report(MYSQLI_REPORT_OFF); } -define("APP_VERSION", "1.22.9.5772"); +define("APP_VERSION", "1.22.9.5773"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 766ee5fd1..931436fae 100644 --- a/time.php +++ b/time.php @@ -386,7 +386,7 @@ if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } - if (strlen($cl_duration) == 0) { + if ($cl_duration == null || strlen($cl_duration) == 0) { if ($cl_start || $cl_finish) { if (!ttTimeHelper::isValidTime($cl_start)) $err->add($i18n->get('error.field'), $i18n->get('label.start')); From 0ade9c1b7310e67ac38ee9426f27253a703a32a0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 8 Jan 2023 15:24:49 +0000 Subject: [PATCH 1801/1848] Improved handling of a situation when mysqli_report function is not available. --- initialize.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/initialize.php b/initialize.php index 705d2db19..3c8191921 100644 --- a/initialize.php +++ b/initialize.php @@ -15,10 +15,13 @@ // Disable mysqli fatal error behaviour when using php8.1 or greater. // See https://php.watch/versions/8.1/mysqli-error-mode if (version_compare(phpversion(), '8.1', '>=')) { - mysqli_report(MYSQLI_REPORT_OFF); + if (function_exists('mysqli_report')) + mysqli_report(MYSQLI_REPORT_OFF); + else + die("mysqli_report function is not available."); // No point to continue as mysqli will not work. } -define("APP_VERSION", "1.22.9.5773"); +define("APP_VERSION", "1.22.9.5774"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 88c0ea1884e59e7f1275cff94ca888962750a1e8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 8 Jan 2023 20:23:12 +0000 Subject: [PATCH 1802/1848] Updated smarty for better compatibility with php8.1. --- WEB-INF/lib/smarty/Autoloader.php | 9 +- WEB-INF/lib/smarty/Smarty.class.php | 35 ++++---- WEB-INF/lib/smarty/bootstrap.php | 2 +- WEB-INF/lib/smarty/debug.tpl | 53 +++++++----- WEB-INF/lib/smarty/functions.php | 51 +++++++++++ .../plugins/function.html_select_date.php | 73 ++++++++-------- .../lib/smarty/plugins/function.mailto.php | 28 ++++--- WEB-INF/lib/smarty/plugins/function.math.php | 4 +- .../smarty/plugins/modifier.capitalize.php | 2 + WEB-INF/lib/smarty/plugins/modifier.count.php | 36 ++++++++ .../smarty/plugins/modifier.date_format.php | 3 +- .../lib/smarty/plugins/modifier.escape.php | 84 ++----------------- .../lib/smarty/plugins/modifier.explode.php | 25 ++++++ .../smarty/plugins/modifier.number_format.php | 26 ++++++ .../lib/smarty/plugins/modifier.truncate.php | 6 +- .../plugins/modifiercompiler.escape.php | 49 +++-------- .../smarty/plugins/modifiercompiler.nl2br.php | 23 +++++ .../smarty/plugins/modifiercompiler.round.php | 23 +++++ .../plugins/modifiercompiler.str_repeat.php | 23 +++++ .../plugins/modifiercompiler.strip_tags.php | 4 +- .../plugins/modifiercompiler.strlen.php | 23 +++++ .../plugins/modifiercompiler.unescape.php | 26 ++++-- .../smarty/plugins/modifiercompiler.upper.php | 4 +- .../smarty/plugins/shared.mb_str_replace.php | 36 +++++++- WEB-INF/lib/smarty/readme | 7 -- .../sysplugins/smarty_cacheresource.php | 4 +- .../smarty_cacheresource_keyvaluestore.php | 4 +- .../smarty_internal_cacheresource_file.php | 2 +- .../smarty_internal_compile_block.php | 4 +- .../smarty_internal_compile_function.php | 8 +- .../smarty_internal_compile_include.php | 4 +- .../smarty_internal_compile_insert.php | 2 +- ...nternal_compile_private_foreachsection.php | 6 +- ...arty_internal_compile_private_modifier.php | 3 + ...ernal_compile_private_print_expression.php | 2 +- ...ernal_compile_private_special_variable.php | 6 +- .../smarty_internal_config_file_compiler.php | 10 ++- .../sysplugins/smarty_internal_debug.php | 4 +- .../smarty_internal_extension_handler.php | 28 +++---- .../smarty_internal_method_loadplugin.php | 4 +- .../smarty_internal_method_mustcompile.php | 2 +- .../smarty_internal_runtime_codeframe.php | 9 +- .../smarty_internal_runtime_make_nocache.php | 2 +- .../smarty_internal_runtime_writefile.php | 15 +--- .../sysplugins/smarty_internal_template.php | 5 +- .../smarty_internal_templatebase.php | 2 +- .../smarty_internal_templatecompilerbase.php | 19 +++-- .../smarty_internal_testinstall.php | 2 +- .../lib/smarty/sysplugins/smarty_resource.php | 4 +- .../sysplugins/smarty_resource_custom.php | 15 +++- .../lib/smarty/sysplugins/smarty_security.php | 34 +------- .../lib/smarty/sysplugins/smarty_variable.php | 1 + .../sysplugins/smartycompilerexception.php | 28 +++++++ dbinstall.php | 21 +++-- initialize.php | 2 +- 55 files changed, 563 insertions(+), 344 deletions(-) create mode 100644 WEB-INF/lib/smarty/functions.php create mode 100644 WEB-INF/lib/smarty/plugins/modifier.count.php create mode 100644 WEB-INF/lib/smarty/plugins/modifier.explode.php create mode 100644 WEB-INF/lib/smarty/plugins/modifier.number_format.php create mode 100644 WEB-INF/lib/smarty/plugins/modifiercompiler.nl2br.php create mode 100644 WEB-INF/lib/smarty/plugins/modifiercompiler.round.php create mode 100644 WEB-INF/lib/smarty/plugins/modifiercompiler.str_repeat.php create mode 100644 WEB-INF/lib/smarty/plugins/modifiercompiler.strlen.php delete mode 100644 WEB-INF/lib/smarty/readme diff --git a/WEB-INF/lib/smarty/Autoloader.php b/WEB-INF/lib/smarty/Autoloader.php index 1673ce2ff..da7e32abf 100644 --- a/WEB-INF/lib/smarty/Autoloader.php +++ b/WEB-INF/lib/smarty/Autoloader.php @@ -5,6 +5,11 @@ * @package Smarty */ + +if (!defined('SMARTY_HELPER_FUNCTIONS_LOADED')) { + include __DIR__ . '/functions.php'; +} + /** * Smarty Autoloader * @@ -73,7 +78,7 @@ public static function registerBC($prepend = false) */ public static function register($prepend = false) { - self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : dirname(__FILE__) . DIRECTORY_SEPARATOR; + self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : __DIR__ . DIRECTORY_SEPARATOR; self::$SMARTY_SYSPLUGINS_DIR = defined('SMARTY_SYSPLUGINS_DIR') ? SMARTY_SYSPLUGINS_DIR : self::$SMARTY_DIR . 'sysplugins' . DIRECTORY_SEPARATOR; spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend); @@ -89,7 +94,7 @@ public static function autoload($class) if ($class[ 0 ] !== 'S' || strpos($class, 'Smarty') !== 0) { return; } - $_class = strtolower($class); + $_class = smarty_strtolower_ascii($class); if (isset(self::$rootClasses[ $_class ])) { $file = self::$SMARTY_DIR . self::$rootClasses[ $_class ]; if (is_file($file)) { diff --git a/WEB-INF/lib/smarty/Smarty.class.php b/WEB-INF/lib/smarty/Smarty.class.php index 85a3d9a6e..5d2e3a4b4 100644 --- a/WEB-INF/lib/smarty/Smarty.class.php +++ b/WEB-INF/lib/smarty/Smarty.class.php @@ -36,7 +36,7 @@ /** * */ - define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); + define('SMARTY_DIR', __DIR__ . DIRECTORY_SEPARATOR); } /** * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins. @@ -61,23 +61,20 @@ define('SMARTY_MBSTRING', function_exists('mb_get_info')); } -// Note: Nik put this back in from smarty3 for php5.4 that we still support. -// See also comment around Smarty::$_CHARSET. -if (!defined('SMARTY_RESOURCE_CHAR_SET')) { - // UTF-8 can only be done properly when mbstring is available! - /** - * @deprecated in favor of Smarty::$_CHARSET - */ - define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'); +/** + * Load helper functions + */ +if (!defined('SMARTY_HELPER_FUNCTIONS_LOADED')) { + include __DIR__ . '/functions.php'; } -// End of inserted fragment by Nik. /** * Load Smarty_Autoloader */ if (!class_exists('Smarty_Autoloader')) { - include dirname(__FILE__) . '/bootstrap.php'; + include __DIR__ . '/bootstrap.php'; } + /** * Load always needed external class files */ @@ -110,7 +107,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '4.1.0'; + const SMARTY_VERSION = '4.3.0'; /** * define variable scopes */ @@ -172,9 +169,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * The character set to adhere to (e.g. "UTF-8") */ - // public static $_CHARSET = SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'; - // Note by Nik: the above assignment only works with php >= 5.6, rolling back to SMARTY_RESOURCE_CHAR_SET as in smarty3. - public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET; + public static $_CHARSET = SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'; /** * The date format to be used internally @@ -881,7 +876,7 @@ public function getPluginsDir() $this->plugins_dir = (array)$this->plugins_dir; } foreach ($this->plugins_dir as $k => $v) { - $this->plugins_dir[ $k ] = $this->_realpath(rtrim($v, '/\\') . DIRECTORY_SEPARATOR, true); + $this->plugins_dir[ $k ] = $this->_realpath(rtrim($v ?? '', '/\\') . DIRECTORY_SEPARATOR, true); } $this->_cache[ 'plugin_files' ] = array(); $this->_pluginsDirNormalized = true; @@ -1359,7 +1354,7 @@ public function __set($name, $value) */ private function _normalizeDir($dirName, $dir) { - $this->{$dirName} = $this->_realpath(rtrim($dir, "/\\") . DIRECTORY_SEPARATOR, true); + $this->{$dirName} = $this->_realpath(rtrim($dir ?? '', "/\\") . DIRECTORY_SEPARATOR, true); } /** @@ -1381,7 +1376,7 @@ private function _normalizeTemplateConfig($isConfig) } foreach ($dir as $k => $v) { if (!isset($processed[ $k ])) { - $dir[ $k ] = $v = $this->_realpath(rtrim($v, "/\\") . DIRECTORY_SEPARATOR, true); + $dir[ $k ] = $v = $this->_realpath(rtrim($v ?? '', "/\\") . DIRECTORY_SEPARATOR, true); $processed[ $k ] = true; } } @@ -1396,7 +1391,7 @@ private function _normalizeTemplateConfig($isConfig) * * @void */ - public function muteUndefinedOrNullWarnings() { + public function muteUndefinedOrNullWarnings(): void { $this->isMutingUndefinedOrNullWarnings = true; } @@ -1404,7 +1399,7 @@ public function muteUndefinedOrNullWarnings() { * Indicates if PHP7 compatibility mode is set. * @bool */ - public function isMutingUndefinedOrNullWarnings() { + public function isMutingUndefinedOrNullWarnings(): bool { return $this->isMutingUndefinedOrNullWarnings; } diff --git a/WEB-INF/lib/smarty/bootstrap.php b/WEB-INF/lib/smarty/bootstrap.php index 2c830468e..a226ac04e 100644 --- a/WEB-INF/lib/smarty/bootstrap.php +++ b/WEB-INF/lib/smarty/bootstrap.php @@ -11,6 +11,6 @@ * Load and register Smarty Autoloader */ if (!class_exists('Smarty_Autoloader')) { - include dirname(__FILE__) . '/Autoloader.php'; + include __DIR__ . '/Autoloader.php'; } Smarty_Autoloader::register(true); diff --git a/WEB-INF/lib/smarty/debug.tpl b/WEB-INF/lib/smarty/debug.tpl index edc7bef98..4f82a5820 100644 --- a/WEB-INF/lib/smarty/debug.tpl +++ b/WEB-INF/lib/smarty/debug.tpl @@ -1,9 +1,9 @@ {capture name='_smarty_debug' assign=debug_output} - - + + Smarty Debug Console - @@ -112,11 +115,11 @@

included templates & config files (load time in seconds)

{foreach $template_data as $template} - {$template.name} -
   + {$template.name} +
   (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"}) -
+
{/foreach}
{/if} @@ -125,13 +128,22 @@ {foreach $assigned_vars as $vars} - - + + + - - {/foreach}

${$vars@key}

- {if isset($vars['nocache'])}Nocache
{/if} - {if isset($vars['scope'])}Origin: {$vars['scope']|debug_print_var nofilter}{/if} +
+

${$vars@key}

+ {if isset($vars['nocache'])}Nocache
{/if} + {if isset($vars['scope'])}Origin: {$vars['scope']|debug_print_var nofilter}{/if} +
+

Value

+ {$vars['value']|debug_print_var:10:80 nofilter} +
+ {if isset($vars['attributes'])} +

Attributes

+ {$vars['attributes']|debug_print_var nofilter} + {/if}

Value

{$vars['value']|debug_print_var:10:80 nofilter}
{if isset($vars['attributes'])}

Attributes

{$vars['attributes']|debug_print_var nofilter} {/if}
@@ -139,11 +151,14 @@ {foreach $config_vars as $vars} - - + + - {/foreach} diff --git a/WEB-INF/lib/smarty/functions.php b/WEB-INF/lib/smarty/functions.php new file mode 100644 index 000000000..bac00e521 --- /dev/null +++ b/WEB-INF/lib/smarty/functions.php @@ -0,0 +1,51 @@ + $_value) { switch ($_key) { case 'time': - if (!is_array($_value) && $_value !== null) { - $template->_checkPlugins( - array( - array( - 'function' => 'smarty_make_timestamp', - 'file' => SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php' - ) - ) - ); - $time = smarty_make_timestamp($_value); - } + $$_key = $_value; // we'll handle conversion below break; case 'month_names': if (is_array($_value) && count($_value) === 12) { @@ -178,43 +169,59 @@ function smarty_function_html_select_date($params, Smarty_Internal_Template $tem } // Note: date() is faster than strftime() // Note: explode(date()) is faster than date() date() date() - if (isset($params[ 'time' ]) && is_array($params[ 'time' ])) { - if (isset($params[ 'time' ][ $prefix . 'Year' ])) { + + if (isset($time) && is_array($time)) { + if (isset($time[$prefix . 'Year'])) { // $_REQUEST[$field_array] given - foreach (array( - 'Y' => 'Year', - 'm' => 'Month', - 'd' => 'Day' - ) as $_elementKey => $_elementName) { + foreach ([ + 'Y' => 'Year', + 'm' => 'Month', + 'd' => 'Day' + ] as $_elementKey => $_elementName) { $_variableName = '_' . strtolower($_elementName); $$_variableName = - isset($params[ 'time' ][ $prefix . $_elementName ]) ? $params[ 'time' ][ $prefix . $_elementName ] : + isset($time[$prefix . $_elementName]) ? $time[$prefix . $_elementName] : date($_elementKey); } - } elseif (isset($params[ 'time' ][ $field_array ][ $prefix . 'Year' ])) { + } elseif (isset($time[$field_array][$prefix . 'Year'])) { // $_REQUEST given - foreach (array( - 'Y' => 'Year', - 'm' => 'Month', - 'd' => 'Day' - ) as $_elementKey => $_elementName) { + foreach ([ + 'Y' => 'Year', + 'm' => 'Month', + 'd' => 'Day' + ] as $_elementKey => $_elementName) { $_variableName = '_' . strtolower($_elementName); - $$_variableName = isset($params[ 'time' ][ $field_array ][ $prefix . $_elementName ]) ? - $params[ 'time' ][ $field_array ][ $prefix . $_elementName ] : date($_elementKey); + $$_variableName = isset($time[$field_array][$prefix . $_elementName]) ? + $time[$field_array][$prefix . $_elementName] : date($_elementKey); } } else { // no date found, use NOW - list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d')); + [$_year, $_month, $_day] = explode('-', date('Y-m-d')); } + } elseif (isset($time) && preg_match("/(\d*)-(\d*)-(\d*)/", $time, $matches)) { + $_year = $_month = $_day = null; + if ($matches[1] > '') $_year = (int) $matches[1]; + if ($matches[2] > '') $_month = (int) $matches[2]; + if ($matches[3] > '') $_day = (int) $matches[3]; } elseif ($time === null) { if (array_key_exists('time', $params)) { - $_year = $_month = $_day = $time = null; + $_year = $_month = $_day = null; } else { - list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d')); + [$_year, $_month, $_day] = explode('-', date('Y-m-d')); } } else { - list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time)); + $template->_checkPlugins( + array( + array( + 'function' => 'smarty_make_timestamp', + 'file' => SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php' + ) + ) + ); + $time = smarty_make_timestamp($time); + [$_year, $_month, $_day] = explode('-', date('Y-m-d', $time)); } + // make syntax "+N" or "-N" work with $start_year and $end_year // Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr foreach (array( @@ -309,8 +316,8 @@ function smarty_function_html_select_date($params, Smarty_Internal_Template $tem for ($i = 1; $i <= 12; $i++) { $_val = sprintf('%02d', $i); $_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[ $i ]) : - ($month_format === '%m' ? $_val : strftime($month_format, $_month_timestamps[ $i ])); - $_value = $month_value_format === '%m' ? $_val : strftime($month_value_format, $_month_timestamps[ $i ]); + ($month_format === '%m' ? $_val : @strftime($month_format, $_month_timestamps[ $i ])); + $_value = $month_value_format === '%m' ? $_val : @strftime($month_value_format, $_month_timestamps[ $i ]); $_html_months .= '' . $option_separator; } diff --git a/WEB-INF/lib/smarty/plugins/function.mailto.php b/WEB-INF/lib/smarty/plugins/function.mailto.php index 834d0535a..671ac0694 100644 --- a/WEB-INF/lib/smarty/plugins/function.mailto.php +++ b/WEB-INF/lib/smarty/plugins/function.mailto.php @@ -48,8 +48,13 @@ */ function smarty_function_mailto($params) { - static $_allowed_encoding = - array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true); + static $_allowed_encoding = [ + 'javascript' => true, + 'javascript_charcode' => true, + 'hex' => true, + 'none' => true + ]; + $extra = ''; if (empty($params[ 'address' ])) { trigger_error("mailto: missing 'address' parameter", E_USER_WARNING); @@ -57,19 +62,19 @@ function smarty_function_mailto($params) } else { $address = $params[ 'address' ]; } + $text = $address; + // netscape and mozilla do not decode %40 (@) in BCC field (bug?) // so, don't encode it. - $search = array('%40', '%2C'); - $replace = array('@', ','); - $mail_parms = array(); + $mail_parms = []; foreach ($params as $var => $value) { switch ($var) { case 'cc': case 'bcc': case 'followupto': if (!empty($value)) { - $mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value)); + $mail_parms[] = $var . '=' . str_replace(['%40', '%2C'], ['@', ','], rawurlencode($value)); } break; case 'subject': @@ -83,6 +88,7 @@ function smarty_function_mailto($params) default: } } + if ($mail_parms) { $address .= '?' . join('&', $mail_parms); } @@ -94,19 +100,21 @@ function smarty_function_mailto($params) ); return; } + + $string = '' . htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, Smarty::$_CHARSET) . ''; + if ($encode === 'javascript') { - $string = '' . $text . ''; $js_encode = ''; for ($x = 0, $_length = strlen($string); $x < $_length; $x++) { $js_encode .= '%' . bin2hex($string[ $x ]); } return ''; } elseif ($encode === 'javascript_charcode') { - $string = '' . $text . ''; for ($x = 0, $_length = strlen($string); $x < $_length; $x++) { $ord[] = ord($string[ $x ]); } - return ''; + return ''; } elseif ($encode === 'hex') { preg_match('!^(.*)(\?.*)$!', $address, $match); if (!empty($match[ 2 ])) { @@ -129,6 +137,6 @@ function smarty_function_mailto($params) return '' . $text_encode . ''; } else { // no encoding - return '' . $text . ''; + return $string; } } diff --git a/WEB-INF/lib/smarty/plugins/function.math.php b/WEB-INF/lib/smarty/plugins/function.math.php index fd5b3d166..f9cf67fe7 100644 --- a/WEB-INF/lib/smarty/plugins/function.math.php +++ b/WEB-INF/lib/smarty/plugins/function.math.php @@ -69,8 +69,8 @@ function smarty_function_math($params, $template) // Adapted from https://www.php.net/manual/en/function.eval.php#107377 $number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number $functionsOrVars = '((?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))'; - $operators = '[+\/*\^%-]'; // Allowed math operators - $regexp = '/^(('.$number.'|'.$functionsOrVars.'|('.$functionsOrVars.'\s*\((?1)+\)|\((?1)+\)))(?:'.$operators.'(?1))?)+$/'; + $operators = '[,+\/*\^%-]'; // Allowed math operators + $regexp = '/^(('.$number.'|'.$functionsOrVars.'|('.$functionsOrVars.'\s*\((?1)*\)|\((?1)*\)))(?:'.$operators.'(?1))?)+$/'; if (!preg_match($regexp, $equation)) { trigger_error("math: illegal characters", E_USER_WARNING); diff --git a/WEB-INF/lib/smarty/plugins/modifier.capitalize.php b/WEB-INF/lib/smarty/plugins/modifier.capitalize.php index c5fc400a6..2903d61d7 100644 --- a/WEB-INF/lib/smarty/plugins/modifier.capitalize.php +++ b/WEB-INF/lib/smarty/plugins/modifier.capitalize.php @@ -22,6 +22,8 @@ */ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false) { + $string = (string) $string; + if (Smarty::$_MBSTRING) { if ($lc_rest) { // uppercase (including hyphenated words) diff --git a/WEB-INF/lib/smarty/plugins/modifier.count.php b/WEB-INF/lib/smarty/plugins/modifier.count.php new file mode 100644 index 000000000..ca35fc115 --- /dev/null +++ b/WEB-INF/lib/smarty/plugins/modifier.count.php @@ -0,0 +1,36 @@ + Prior to PHP 8.0.0, if the parameter was neither an array nor an object that implements the Countable interface, + * > 1 would be returned, unless value was null, in which case 0 would be returned. + */ + + if ($arrayOrObject instanceof Countable || is_array($arrayOrObject)) { + return count($arrayOrObject, (int) $mode); + } elseif ($arrayOrObject === null) { + return 0; + } + return 1; +} diff --git a/WEB-INF/lib/smarty/plugins/modifier.date_format.php b/WEB-INF/lib/smarty/plugins/modifier.date_format.php index 8e7e0b6e1..e3589fd07 100644 --- a/WEB-INF/lib/smarty/plugins/modifier.date_format.php +++ b/WEB-INF/lib/smarty/plugins/modifier.date_format.php @@ -78,7 +78,8 @@ function smarty_modifier_date_format($string, $format = null, $default_date = '' } $format = str_replace($_win_from, $_win_to, $format); } - return strftime($format, $timestamp); + // @ to suppress deprecation errors when running in PHP8.1 or higher. + return @strftime($format, $timestamp); } else { return date($format, $timestamp); } diff --git a/WEB-INF/lib/smarty/plugins/modifier.escape.php b/WEB-INF/lib/smarty/plugins/modifier.escape.php index 47489aa98..11e44682e 100644 --- a/WEB-INF/lib/smarty/plugins/modifier.escape.php +++ b/WEB-INF/lib/smarty/plugins/modifier.escape.php @@ -23,95 +23,25 @@ */ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) { - static $_double_encode = true; static $is_loaded_1 = false; static $is_loaded_2 = false; if (!$char_set) { $char_set = Smarty::$_CHARSET; } + + $string = (string)$string; + switch ($esc_type) { case 'html': - if ($_double_encode) { - // php >=5.3.2 - go native - return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); - } else { - if ($double_encode) { - // php <5.2.3 - only handle double encoding - return htmlspecialchars($string, ENT_QUOTES, $char_set); - } else { - // php <5.2.3 - prevent double encoding - $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); - $string = htmlspecialchars($string, ENT_QUOTES, $char_set); - $string = str_replace( - array( - '%%%SMARTY_START%%%', - '%%%SMARTY_END%%%' - ), - array( - '&', - ';' - ), - $string - ); - return $string; - } - } + return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); // no break case 'htmlall': if (Smarty::$_MBSTRING) { - // mb_convert_encoding ignores htmlspecialchars() - if ($_double_encode) { - // php >=5.3.2 - go native - $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); - } else { - if ($double_encode) { - // php <5.2.3 - only handle double encoding - $string = htmlspecialchars($string, ENT_QUOTES, $char_set); - } else { - // php <5.2.3 - prevent double encoding - $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); - $string = htmlspecialchars($string, ENT_QUOTES, $char_set); - $string = - str_replace( - array( - '%%%SMARTY_START%%%', - '%%%SMARTY_END%%%' - ), - array( - '&', - ';' - ), - $string - ); - return $string; - } - } - // htmlentities() won't convert everything, so use mb_convert_encoding - return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set); + $string = mb_convert_encoding($string, 'UTF-8', $char_set); + return htmlentities($string, ENT_QUOTES, 'UTF-8', $double_encode); } // no MBString fallback - if ($_double_encode) { - return htmlentities($string, ENT_QUOTES, $char_set, $double_encode); - } else { - if ($double_encode) { - return htmlentities($string, ENT_QUOTES, $char_set); - } else { - $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); - $string = htmlentities($string, ENT_QUOTES, $char_set); - $string = str_replace( - array( - '%%%SMARTY_START%%%', - '%%%SMARTY_END%%%' - ), - array( - '&', - ';' - ), - $string - ); - return $string; - } - } + return htmlentities($string, ENT_QUOTES, $char_set, $double_encode); // no break case 'url': return rawurlencode($string); diff --git a/WEB-INF/lib/smarty/plugins/modifier.explode.php b/WEB-INF/lib/smarty/plugins/modifier.explode.php new file mode 100644 index 000000000..5186fde3d --- /dev/null +++ b/WEB-INF/lib/smarty/plugins/modifier.explode.php @@ -0,0 +1,25 @@ +=8.1 + return explode($separator, $string ?? '', $limit ?? PHP_INT_MAX); +} diff --git a/WEB-INF/lib/smarty/plugins/modifier.number_format.php b/WEB-INF/lib/smarty/plugins/modifier.number_format.php new file mode 100644 index 000000000..8c612601f --- /dev/null +++ b/WEB-INF/lib/smarty/plugins/modifier.number_format.php @@ -0,0 +1,26 @@ +=8.1 + return number_format($num ?? 0.0, $decimals, $decimal_separator, $thousands_separator); +} diff --git a/WEB-INF/lib/smarty/plugins/modifier.truncate.php b/WEB-INF/lib/smarty/plugins/modifier.truncate.php index 33e7e53aa..80dcdb531 100644 --- a/WEB-INF/lib/smarty/plugins/modifier.truncate.php +++ b/WEB-INF/lib/smarty/plugins/modifier.truncate.php @@ -42,8 +42,8 @@ function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_wo if (!$middle) { return mb_substr($string, 0, $length, Smarty::$_CHARSET) . $etc; } - return mb_substr($string, 0, $length / 2, Smarty::$_CHARSET) . $etc . - mb_substr($string, -$length / 2, $length, Smarty::$_CHARSET); + return mb_substr($string, 0, intval($length / 2), Smarty::$_CHARSET) . $etc . + mb_substr($string, -intval($length / 2), $length, Smarty::$_CHARSET); } return $string; } @@ -56,7 +56,7 @@ function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_wo if (!$middle) { return substr($string, 0, $length) . $etc; } - return substr($string, 0, $length / 2) . $etc . substr($string, -$length / 2); + return substr($string, 0, intval($length / 2)) . $etc . substr($string, -intval($length / 2)); } return $string; } diff --git a/WEB-INF/lib/smarty/plugins/modifiercompiler.escape.php b/WEB-INF/lib/smarty/plugins/modifiercompiler.escape.php index 70b95cc9d..602c3dbfc 100644 --- a/WEB-INF/lib/smarty/plugins/modifiercompiler.escape.php +++ b/WEB-INF/lib/smarty/plugins/modifiercompiler.escape.php @@ -18,12 +18,10 @@ * @param Smarty_Internal_TemplateCompilerBase $compiler * * @return string with compiled code - * @throws \SmartyException + * @throws SmartyException */ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompilerBase $compiler) { - static $_double_encode = true; - static $is_loaded = false; $compiler->template->_checkPlugins( array( array( @@ -41,53 +39,30 @@ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompile } switch ($esc_type) { case 'html': - if ($_double_encode) { - return 'htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' . - var_export($double_encode, true) . ')'; - } elseif ($double_encode) { - return 'htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')'; - } else { - // fall back to modifier.escape.php - } + return 'htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' . + var_export($double_encode, true) . ')'; // no break case 'htmlall': if (Smarty::$_MBSTRING) { - if ($_double_encode) { - // php >=5.2.3 - go native - return 'mb_convert_encoding(htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' . - var_export($char_set, true) . ', ' . var_export($double_encode, true) . - '), "HTML-ENTITIES", ' . var_export($char_set, true) . ')'; - } elseif ($double_encode) { - // php <5.2.3 - only handle double encoding - return 'mb_convert_encoding(htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' . - var_export($char_set, true) . '), "HTML-ENTITIES", ' . var_export($char_set, true) . ')'; - } else { - // fall back to modifier.escape.php - } + return 'htmlentities(mb_convert_encoding((string)' . $params[ 0 ] . ', \'UTF-8\', ' . + var_export($char_set, true) . '), ENT_QUOTES, \'UTF-8\', ' . + var_export($double_encode, true) . ')'; } // no MBString fallback - if ($_double_encode) { - // php >=5.2.3 - go native - return 'htmlentities(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' . - var_export($double_encode, true) . ')'; - } elseif ($double_encode) { - // php <5.2.3 - only handle double encoding - return 'htmlentities(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')'; - } else { - // fall back to modifier.escape.php - } + return 'htmlentities((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' . + var_export($double_encode, true) . ')'; // no break case 'url': - return 'rawurlencode(' . $params[ 0 ] . ')'; + return 'rawurlencode((string)' . $params[ 0 ] . ')'; case 'urlpathinfo': - return 'str_replace("%2F", "/", rawurlencode(' . $params[ 0 ] . '))'; + return 'str_replace("%2F", "/", rawurlencode((string)' . $params[ 0 ] . '))'; case 'quotes': // escape unescaped single quotes - return 'preg_replace("%(? "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", " "<\/", "

#{$vars@key}#

- {if isset($vars['scope'])}Origin: {$vars['scope']|debug_print_var nofilter}{/if} +
+

#{$vars@key}#

+ {if isset($vars['scope'])}Origin: {$vars['scope']|debug_print_var nofilter}{/if} +
+ {$vars['value']|debug_print_var:10:80 nofilter} {$vars['value']|debug_print_var:10:80 nofilter}