version 0.4 (3)

added multi language support
added french translation
added non apache (mod_rewrite) support (needs testing)
improved UI by adding more icons
improved user menu (drop down menu)
fixed date shortcut on quick task entry
fixed changing password bug
fixed logging with password bug
other minor bug fixes
This commit is contained in:
Stan Ozier 2010-06-11 12:42:24 +02:00
parent 9fed30a54b
commit b7a883778d
52 changed files with 1492 additions and 464 deletions

View File

@ -1,29 +1,32 @@
TaskFreak! Time Tracking
------------------------
version : 0.4
Requirements Requirements
------------ ------------
- apache with mod_rewrite - apache (tested) or any other webserver (not tested)
- PHP 5.3.x - PHP 5.3.x
- mySQL 4.1 or later - mySQL 4.1 or later
Setup Setup
----- -----
1) Set up your virtual host (read further below if using a subfolder instead) 1) create a mySQL database
2) create a mySQL database 2) create tables and data with taskfreak_time.sql
3) create tables and data with taskfreak_time.sql 3) open app/config/db.php and change database settings
4) open app/config/db.php and change database settings
You can stop here and have a look. You can stop here and have a look.
login is "admin" with no password login is "admin" with no password
Subfolder setup Enabling clean URLS
--------------- -------------------
If not using a virtual host, you need to change the APP_WWW_URI constant If using apache with mod_rewrite, you should enable clean URLs
in app/config/core.php
eg. if running under yourdomain.tld/taskfreak 1) copy the file htaccess from the DOCS folder to the application root folder
define('APP_WWW_URI', '/taskfreak/'); 2) change its name from htaccess to .htaccess
don't forget the trailing slash 3) open app/config/core.php, and change APP_URL_REWRITE to true
Single user Single user
@ -34,11 +37,15 @@ Search for APP_SETUP_USER_MODEL and set it up to false :
define('APP_SETUP_USER_MODEL',false); define('APP_SETUP_USER_MODEL',false);
[/code] [/code]
More options
------------
If you feel like playing so more, open app/config/app.php and look into it If you feel like playing so more, open app/config/app.php and look into it
To change the application language have a look at DOCS/translation.txt
Known bugs Known bugs
---------- ----------
- javascript calendar (jdpicker) closes when changing month or year - some errors might occur on dates depending on your time zone
- order by start, stop, or spent doesn't really make sense - order by start, stop, or spent doesn't really make sense
- very buggy under IE8, and simply unusable with older versions of IE - very buggy under IE8, and simply unusable with older versions of IE

View File

@ -1,3 +1,20 @@
TaskFreak! Time Tracking
------------------------
Version 0.4 : 2010-06-11
------------------------
Added multi language support
Added french translation
Added non apache (mod_rewrite) support (needs testing)
Improved UI by adding more icons
Improved user menu (drop down menu)
Fixed checkbox bug (checked tasks didn't change status)
Fixed date shortcut on quick task entry
Fixed javascript calendar bug when changing month or year
Fixed changing password bug
Fixed logging with password bug
Other minor bug fixes
Version 0.3 : 2010-05-30 Version 0.3 : 2010-05-30
------------------------ ------------------------
Fixed subfolder installation (virtual host no longer required) Fixed subfolder installation (virtual host no longer required)

View File

@ -1,67 +1,23 @@
-- phpMyAdmin SQL Dump CREATE TABLE IF NOT EXISTS `acl` (
-- version 3.3.1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: May 30, 2010 at 04:05 PM
-- Server version: 5.0.67
-- PHP Version: 5.3.0
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
--
-- Database: `taskfreak_timer`
--
-- --------------------------------------------------------
--
-- Table structure for table `acl`
--
DROP TABLE IF EXISTS `acl`;
CREATE TABLE `acl` (
`id` mediumint(8) unsigned NOT NULL auto_increment, `id` mediumint(8) unsigned NOT NULL auto_increment,
`name` varchar(127) NOT NULL, `name` varchar(127) NOT NULL,
`section` varchar(63) NOT NULL, `section` varchar(63) NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Dumping data for table `acl`
--
INSERT INTO `acl` VALUES(1, 'task_see_all', 'general'); INSERT INTO `acl` VALUES(1, 'task_see_all', 'general');
INSERT INTO `acl` VALUES(2, 'admin_user', 'general'); INSERT INTO `acl` VALUES(2, 'admin_user', 'general');
-- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS `acl_user` (
--
-- Table structure for table `acl_user`
--
DROP TABLE IF EXISTS `acl_user`;
CREATE TABLE `acl_user` (
`user_id` mediumint(8) unsigned NOT NULL, `user_id` mediumint(8) unsigned NOT NULL,
`acl_id` mediumint(8) unsigned NOT NULL, `acl_id` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`user_id`,`acl_id`) PRIMARY KEY (`user_id`,`acl_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Dumping data for table `acl_user`
--
INSERT INTO `acl_user` VALUES(1, 1); INSERT INTO `acl_user` VALUES(1, 1);
INSERT INTO `acl_user` VALUES(1, 2); INSERT INTO `acl_user` VALUES(1, 2);
-- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS `member` (
--
-- Table structure for table `member`
--
DROP TABLE IF EXISTS `member`;
CREATE TABLE `member` (
`id` int(10) unsigned NOT NULL auto_increment, `id` int(10) unsigned NOT NULL auto_increment,
`nickname` varchar(30) NOT NULL, `nickname` varchar(30) NOT NULL,
`email` varchar(255) NOT NULL, `email` varchar(255) NOT NULL,
@ -81,23 +37,12 @@ CREATE TABLE `member` (
`activation` varchar(16) NOT NULL, `activation` varchar(16) NOT NULL,
`enabled` tinyint(1) unsigned NOT NULL, `enabled` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- INSERT INTO `member` VALUES(1, 'Administrator', '', 'admin', '', '12345678', 0, 'Asia/Bangkok', 0, '2010-06-11 01:30:00', '0000-00-00', '0000-00-00 00:00:00', '127.0.0.1', '0000-00-00 00:00:00', 0, 0, '', 1);
-- Dumping data for table `member` INSERT INTO `member` VALUES(2, 'Emilie', '', 'emilie', '', '12345678', 0, 'Europe/Paris', 0, '2010-06-11 01:31:00', '0000-00-00', '0000-00-00 00:00:00', '127.0.0.1', '0000-00-00 00:00:00', 0, 0, '', 1);
--
INSERT INTO `member` VALUES(1, 'Administrator', '', 'admin', '', '12345678', 0, 'Asia/Bangkok', 0, '2010-05-21 01:43:21', '0000-00-00', '2010-05-30 13:57:18', '127.0.0.1', '0000-00-00 00:00:00', 1, 0, '', 1); CREATE TABLE IF NOT EXISTS `task` (
INSERT INTO `member` VALUES(2, 'Emilie', '', 'emilie', '', '12345678', 0, 'Europe/Paris', 0, '2010-05-21 01:44:17', '0000-00-00', '0000-00-00 00:00:00', '127.0.0.1', '0000-00-00 00:00:00', 0, 0, '', 1);
-- --------------------------------------------------------
--
-- Table structure for table `task`
--
DROP TABLE IF EXISTS `task`;
CREATE TABLE `task` (
`id` int(10) unsigned NOT NULL auto_increment, `id` int(10) unsigned NOT NULL auto_increment,
`title` varchar(255) NOT NULL, `title` varchar(255) NOT NULL,
`note` text NOT NULL, `note` text NOT NULL,
@ -109,23 +54,12 @@ CREATE TABLE `task` (
`member_id` mediumint(8) unsigned NOT NULL, `member_id` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `member_id` (`member_id`) KEY `member_id` (`member_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- INSERT INTO `task` VALUES(1, 'taskfreak : README first about this beta version', 'Please keep in mind that this is a beta version. There are quite a few known bugs, a handful of unknown bugs.\r\n\r\nHere''s what you can do so far :\r\n- create, edit and archive tasks\r\n- start and stop task timers\r\n- report time spent on a task\r\n- edit your own profile\r\n- see other''s tasks (task manager only)\r\n- create and edit users (user admin only)\r\n\r\nMake sure you read the README file under the DOCS/ folder. There''s a few setup tips in there.', 5, '9999-00-00', '2010-06-11', 0, 0, 1);
-- Dumping data for table `task` INSERT INTO `task` VALUES(2, 'taskfreak : quick notes about TT 0.4', 'Here''s the list of known bugs at release time :\r\n- some errors might occur on dates depending on your time zone\r\n- order by start, stop, or spent doesn''t really make sense\r\n- very buggy under IE8, and simply unusable with older versions of IE\r\n\r\nPlease report found bugs here :\r\nhttp://forum.taskfreak.com/index.php?board=7.0', 4, '9999-00-00', '9999-00-00', 0, 0, 1);
--
INSERT INTO `task` VALUES(1, 'taskfreak : README first about this beta version', 'Please keep in mind that this is a beta version. There are quite a few known bugs, a handful of unknown bugs.\r\n\r\nHere''s what you can do so far :\r\n- create, edit and archive tasks\r\n- start and stop task timers\r\n- report time spent on a task\r\n- edit your own profile\r\n- see other''s tasks (task manager only)\r\n- create and edit users (user admin only)\r\n\r\nMake sure you read the README file under the DOCS/ folder. There''s a few setup tips in there.', 5, '9999-00-00', '2010-05-30', 0, 0, 1); CREATE TABLE IF NOT EXISTS `timer` (
INSERT INTO `task` VALUES(2, 'taskfreak : quick notes about TT 0.3', 'Here''s the list of known bugs at release time :\r\n- javascript calendar (jdpicker) closes when changing month or year\r\n- order by start, stop, or spent doesn''t really make sense\r\n- very buggy under IE8, and simply unusable with older versions of IE\r\n\r\nPlease report found bugs here :\r\nhttp://forum.taskfreak.com/index.php?board=7.0', 4, '9999-00-00', '9999-00-00', 0, 0, 1);
-- --------------------------------------------------------
--
-- Table structure for table `timer`
--
DROP TABLE IF EXISTS `timer`;
CREATE TABLE `timer` (
`task_id` int(10) unsigned NOT NULL, `task_id` int(10) unsigned NOT NULL,
`start` datetime NOT NULL, `start` datetime NOT NULL,
`stop` datetime NOT NULL, `stop` datetime NOT NULL,
@ -134,7 +68,3 @@ CREATE TABLE `timer` (
KEY `task_id` (`task_id`) KEY `task_id` (`task_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Dumping data for table `timer`
--

46
DOCS/translation.txt Normal file
View File

@ -0,0 +1,46 @@
TaskFreak! Time Tracking
------------------------
How to change the default language ?
------------------------------------
In app/config/app.php, go to the end of the file and modify its settings :
For english :
[code]
$GLOBALS['config']['lang'] = array(
'default' => 'en',
'user' => 'en',
'specialchars' => 2
);
[/code]
For french :
[code]
$GLOBALS['config']['lang'] = array(
'default' => 'fr',
'user' => 'fr',
'specialchars' => 2
);
[/code]
Note : don't bother modifying the specialchars setting
How can I translate this app to my language ?
---------------------------------------------
There's 5 files you need to look :
- lib/lang/en/config.php
- lib/lang/en/common.php
- app/lang/en/freak.php
- app/lang/en/help_multi_creation.php
- app/lang/en/help_timer_creation.php
1) Copy folder lib/lang/en to lib/lang/XX where XX is your language code
2) Copy folder app/lang/en to app/lang/XX where XX is your language code
3) Open all copied files and start translating
4) Change the application settings (read instructions above) and test it all
Then, please send them to taskfreak@gmail.com so your translation can be
included in the next TaskFreak! release

4
README
View File

@ -1,7 +1,7 @@
TaskFreak! Time Tracking TaskFreak! Time Tracking
------------------------ ------------------------
version : 0.3 version : 0.4
released : 2010-05-30 released : 2010-06-11
status : beta status : beta
------------------------ ------------------------

View File

@ -3,8 +3,8 @@
// ---- LOG and DEBUGGING ----------------------------------------------------- // ---- LOG and DEBUGGING -----------------------------------------------------
$GLOBALS['config']['log_front'] = 0; $GLOBALS['config']['log_front'] = 0;
$GLOBALS['config']['log_debug'] = 1; $GLOBALS['config']['log_debug'] = 0;
$GLOBALS['config']['log_message'] = 1; $GLOBALS['config']['log_message'] = 0;
$GLOBALS['config']['log_warn'] = 0; $GLOBALS['config']['log_warn'] = 0;
$GLOBALS['config']['log_error'] = 1; $GLOBALS['config']['log_error'] = 1;
$GLOBALS['config']['log_core'] = 0; $GLOBALS['config']['log_core'] = 0;
@ -26,14 +26,6 @@ $GLOBALS['config']['pages'] = array(
'Archives' => 'task/archives' 'Archives' => 'task/archives'
); );
// ---- LANGUAGE DEFAULTS -----------------------------------------------------
$GLOBALS['config']['lang'] = array(
'default' => 'en',
'user' => 'en',
'specialchars' => 2
);
// ---- DATE / TIME FORMATS --------------------------------------------------- // ---- DATE / TIME FORMATS ---------------------------------------------------
// date/time timezone and formats defaults // date/time timezone and formats defaults
@ -58,20 +50,20 @@ $GLOBALS['config']['task'] = array(
$GLOBALS['config']['task']['priority'] = array( $GLOBALS['config']['task']['priority'] = array(
'options' => array( 'options' => array(
1 => '1) urgent', 1 => 'urgent',
2 => '2) important', 2 => 'important',
3 => '3) quickly', 3 => 'quickly',
4 => '4) pretty soon', 4 => 'soon',
5 => '5) normal', 5 => 'normal',
6 => '6) after', 6 => 'after',
7 => '7) later', 7 => 'later',
8 => '8) anytime', 8 => 'anytime',
9 => '9) whatever' 9 => 'whenever'
), ),
'default' => 5 'default' => 5
); );
$GLOBALS['config']['task']['pagination'] = array('15'=>15,'25'=>25,'50'=>50,'all'=>0); $GLOBALS['config']['task']['pagination'] = array(15=>15,30=>30,50=>50,'all'=>0);
$GLOBALS['config']['task']['pagination_default'] = 15; $GLOBALS['config']['task']['pagination_default'] = 15;
// ---- DEFAULT Javascript ---------------------------------------------------- // ---- DEFAULT Javascript ----------------------------------------------------
@ -88,6 +80,13 @@ $GLOBALS['config']['skin'] = 'default';
// ---- LANGUAGE -------------------------------------------------------------- // ---- LANGUAGE --------------------------------------------------------------
$GLOBALS['config']['lang']['default'] = 'en'; $GLOBALS['config']['lang'] = array(
$GLOBALS['config']['lang']['user'] = 'en'; 'default' => 'en',
$GLOBALS['config']['lang']['specialchars'] = 2; 'user' => 'en',
'specialchars' => 2
);
$GLOBALS['config']['lang']['files'] = array(
'common.php' => APP_INCLUDE_PATH.'lib/lang/',
'freak.php' => APP_INCLUDE_PATH.'app/lang/'
);

View File

@ -3,8 +3,6 @@ error_reporting(E_ALL);
// --- APPLICATION SETUP ------------------------------------------------------ // --- APPLICATION SETUP ------------------------------------------------------
$GLOBALS['config'] = array();
// connect to database (see /app/config/db.php for settings) // connect to database (see /app/config/db.php for settings)
define('APP_SETUP_DATABASE', true); define('APP_SETUP_DATABASE', true);
@ -15,7 +13,7 @@ define('APP_SETUP_GLOBAL_SETTINGS', false);
define('APP_SETUP_USER_SETTINGS', false); define('APP_SETUP_USER_SETTINGS', false);
// use translation helper // use translation helper
define('APP_SETUP_TRANSLATOR', false); define('APP_SETUP_TRANSLATOR', true);
// use (trans-sessions) messaging helper // use (trans-sessions) messaging helper
define('APP_SETUP_MESSAGING', true); define('APP_SETUP_MESSAGING', true);
@ -23,6 +21,8 @@ define('APP_SETUP_MESSAGING', true);
// use navi helper // use navi helper
define('APP_SETUP_NAVI', true); define('APP_SETUP_NAVI', true);
$GLOBALS['config'] = array();
// --- USER AUTHENTICATION SETUP ---------------------------------------------- // --- USER AUTHENTICATION SETUP ----------------------------------------------
// model class used for app users // model class used for app users
@ -45,7 +45,7 @@ $GLOBALS['config']['auth'] = array(
// allow auto login (true or false) // allow auto login (true or false)
'password_recover' => true, 'password_recover' => true,
// allow password recovery (true or false) // allow password recovery (true or false)
'register' => 2 'register' => 0
// register mode // register mode
// 0: no registration, 1: account created directly (no validation) // 0: no registration, 1: account created directly (no validation)
// 2: user validation (from email), 3: admin validate account // 2: user validation (from email), 3: admin validate account
@ -62,23 +62,30 @@ define('APP_CONFIG_PATH',APP_CORE_PATH.'config/');
define('APP_MODEL_PATH',APP_CORE_PATH.'model/'); define('APP_MODEL_PATH',APP_CORE_PATH.'model/');
define('APP_CONTROLLER_PATH',APP_CORE_PATH.'controller/'); define('APP_CONTROLLER_PATH',APP_CORE_PATH.'controller/');
define('APP_VIEW_PATH',APP_CORE_PATH.'view/'); define('APP_VIEW_PATH',APP_CORE_PATH.'view/');
define('APP_CACHE_PATH',APP_ROOT_PATH.'cache/');
define('APP_INCLUDE_PATH', APP_ROOT_PATH); define('APP_INCLUDE_PATH', APP_ROOT_PATH);
define('APP_CACHE_PATH',APP_INCLUDE_PATH.'cache/');
define('APP_LIB_PATH',APP_INCLUDE_PATH.'lib/'); define('APP_LIB_PATH',APP_INCLUDE_PATH.'lib/');
define('APP_CLASS_PATH',APP_LIB_PATH.'class/'); define('APP_CLASS_PATH',APP_LIB_PATH.'class/');
define('APP_HELPER_PATH',APP_LIB_PATH.'helper/'); define('APP_HELPER_PATH',APP_LIB_PATH.'helper/');
define('APP_LANGUAGE_PATH',APP_LIB_PATH.'lang/');
define('APP_ASSET_PATH',APP_ROOT_PATH.'asset/'); define('APP_ASSET_PATH',APP_ROOT_PATH.'asset/');
define('APP_LANGUAGE_PATH',APP_ASSET_PATH.'lang/');
define('APP_PLUGIN_PATH',APP_ROOT_PATH.'plugin/'); define('APP_PLUGIN_PATH',APP_ROOT_PATH.'plugin/');
define('APP_SKIN_PATH',APP_ROOT_PATH.'skin/'); define('APP_SKIN_PATH',APP_ROOT_PATH.'skin/');
// ---- APPLICATION URLs ------------------------------------------------------ // ---- APPLICATION URLs ------------------------------------------------------
define('APP_URL_REWRITE', true); define('APP_URL_REWRITE', false);
define('APP_WWW_URI', '/');
// define('APP_WWW_URI', '/taskfreak/'); $uri = trim(substr(APP_WWW_PATH,strlen($_SERVER['DOCUMENT_ROOT'])),'/');
if (empty($uri)) {
$uri = '/';
} else {
$uri = '/'.$uri.'/';
}
define('APP_WWW_URI', $uri);
unset($uri);
define('APP_WWW_URL','http://'.$_SERVER['SERVER_NAME'].APP_WWW_URI); define('APP_WWW_URL','http://'.$_SERVER['SERVER_NAME'].APP_WWW_URI);
@ -87,7 +94,7 @@ define('APP_WWW_URL','http://'.$_SERVER['SERVER_NAME'].APP_WWW_URI);
define('APP_USER_ID_LENGTH',8); // length of user ID define('APP_USER_ID_LENGTH',8); // length of user ID
define('APP_USER_SANITIZE','/^[a-z0-9_-]+$/i'); define('APP_USER_SANITIZE','/^[a-z0-9_-]+$/i');
define('APP_USER_NAME_MIN',4); // minimum length for username define('APP_USER_NAME_MIN',4); // minimum length for username
define('APP_USER_NAME_MAX',15); // maximum length for username define('APP_USER_NAME_MAX',16); // maximum length for username
define('APP_USER_PASS_MIN',4); // minimum length for password define('APP_USER_PASS_MIN',4); // minimum length for password
define('APP_USER_PASS_MAX',16); // maximum length for password define('APP_USER_PASS_MAX',16); // maximum length for password
define('APP_PASSWORD_SANITIZE','/^[a-z0-9%!@#&*+:;,<>\.\?\|\{\}\(\)\[\]\$_-]+$/i'); define('APP_PASSWORD_SANITIZE','/^[a-z0-9%!@#&*+:;,<>\.\?\|\{\}\(\)\[\]\$_-]+$/i');

View File

@ -33,4 +33,9 @@ $GLOBALS['config']['path']['css'] = array(
$GLOBALS['config']['path']['js'] = array( $GLOBALS['config']['path']['js'] = array(
$GLOBALS['config']['skin'].'/js/', $GLOBALS['config']['skin'].'/js/',
'asset/js/' 'asset/js/'
);
$GLOBALS['config']['path']['lang'] = array(
'lib/lang/',
'app/lang/'
); );

View File

@ -4,7 +4,7 @@
* *
* @package taskfreak_tt * @package taskfreak_tt
* @author Stan Ozier <taskfreak@gmail.com> * @author Stan Ozier <taskfreak@gmail.com>
* @version 0.3 * @version 0.4
* @copyright GNU General Public License (GPL) version 3 * @copyright GNU General Public License (GPL) version 3
*/ */
@ -26,7 +26,7 @@ class Admin extends AppController {
$this->page->clean('js'); $this->page->clean('js');
} else { } else {
$this->page->add('css',array('form.css','freak.css','list.css','tracker.css','colorbox.css')); $this->page->add('css',array('form.css','freak.css','list.css','tracker.css','colorbox.css'));
// $this->page->add('js',array('jquery.form.min.js','jquery.colorbox-min.js')); $this->_addJsSettings();
$this->page->add('js','freak.js'); $this->page->add('js','freak.js');
} }
} }
@ -42,17 +42,17 @@ class Admin extends AppController {
$this->limit = $this->fc->sessionVariable('userlimit'); $this->limit = $this->fc->sessionVariable('userlimit');
$this->search = $this->fc->sessionVariable('search'); $this->search = $this->fc->sessionVariable('search');
$title = 'All users'; $title = TR::get('ui','all_users');
$filter = ''; $filter = '';
switch ($this->filter) { switch ($this->filter) {
case '1': case '1':
$title = 'Task managers'; $title = TR::get('ui','task_managers');
$filter = "actags LIKE '%task_see_all%'"; $filter = "actags LIKE '%task_see_all%'";
$this->limit = 0; $this->limit = 0;
break; break;
case '2': case '2':
$title = 'User managers'; $title = TR::get('ui','user_admins');
$filter = "actags LIKE '%admin_user%'"; $filter = "actags LIKE '%admin_user%'";
$this->limit = 0; $this->limit = 0;
break; break;
@ -101,9 +101,11 @@ class Admin extends AppController {
if ($this->fc->chkReqVar('pass1') && $this->fc->chkReqVar('pass2')) { if ($this->fc->chkReqVar('pass1') && $this->fc->chkReqVar('pass2')) {
if ($this->data->setPassword($this->fc->getReqVar('pass1'), $this->fc->getReqVar('pass2'))) { if ($this->data->setPassword($this->fc->getReqVar('pass1'), $this->fc->getReqVar('pass2'))) {
// save it all // save it all
error_log('setting new password : '.$this->fc->getReqVar('pass1'));
$this->data->ignore(); $this->data->ignore();
} else { } else {
// do not save password // do not save password
error_log('can not save password');
$this->data->ignore('password,salt'); $this->data->ignore('password,salt');
} }
} }
@ -113,10 +115,11 @@ class Admin extends AppController {
$myself = ($this->data->getUid() == $this->fc->user->getUid()); $myself = ($this->data->getUid() == $this->fc->user->getUid());
if ($this->data->save(!$myself)) { if ($this->data->save(!$myself)) {
if ($myself) { if ($myself) {
// editing own profile need to relogin // editing own profile need to reset session
error_log('updating session');
$this->data->updateSessionVariables(); $this->data->updateSessionVariables();
} }
$this->fc->autoRedirect('user saved'); $this->fc->autoRedirect('saved');
} }
} }
return true; return true;
@ -133,18 +136,18 @@ class Admin extends AppController {
$db->query('DELETE FROM '.$this->data->dbTable('acl_user').' WHERE user_id='.$this->data->getUid()); $db->query('DELETE FROM '.$this->data->dbTable('acl_user').' WHERE user_id='.$this->data->getUid());
// delete this user's tasks // delete this user's tasks
$db->query('DELETE FROM '.$this->data->dbTable('task').' WHERE member_id='.$this->data->getUid()); $db->query('DELETE FROM '.$this->data->dbTable('task').' WHERE member_id='.$this->data->getUid());
$this->fc->redirect(APP_WWW_URI.'admin','user deleted'); $this->fc->redirect($this->fc->getUrl('admin'),'deleted');
} }
} }
$this->fc->redirect(APP_WWW_URI.'admin','user deleted'); $this->fc->redirect($this->fc->getUrl('admin'),'deleted');
} }
public function switchAction() { public function switchAction() {
if (!$this->fc->user->checkAcl('task_see_all')) { if (!$this->fc->user->checkAcl('task_see_all')) {
$this->fc->redirect(APP_WWW_URI,'access_denied'); $this->fc->redirect(APP_WWW_URI,'[error]access_denied');
} }
if ($id = $this->fc->getReqVar('id')) { if ($id = $this->fc->getReqVar('id')) {
@ -156,7 +159,7 @@ class Admin extends AppController {
$this->fc->setSessionVariable('switch_id', $id); $this->fc->setSessionVariable('switch_id', $id);
$this->fc->setSessionVariable('switch_name', $obj->get('nickname')); $this->fc->setSessionVariable('switch_name', $obj->get('nickname'));
} }
$this->fc->redirect(APP_WWW_URI,'switched to '.$obj->get('nickname')); $this->fc->redirect(APP_WWW_URI,'[ui]switched');
} }
$this->switch_id = $this->fc->getSessionVariable('switch_id'); $this->switch_id = $this->fc->getSessionVariable('switch_id');
@ -202,4 +205,18 @@ class Admin extends AppController {
return true; return true;
} }
protected function _addJsSettings() {
$js = "var RELOAD_URI='".APP_WWW_URI."task/main/ajax/1'; var URLMODREWRITE=true; ";
if (!APP_URL_REWRITE) {
$js = "var RELOAD_URI='".APP_WWW_URI."?c=task&amp;a=main&amp;ajax=1'; var URLMODREWRITE=false; ";
}
// translations
$js .= "var LANGRUNNING='".TR::html('task','running')."'; ";
$js .= "var LANGCONFIRM='".TR::html('data','delete_confirm')."'; ";
$this->page->add('jsCode', $js);
}
} }

View File

@ -25,7 +25,7 @@ class Login extends AppController {
*/ */
public function mainAction() { public function mainAction() {
$this->fc->user->addHelper('html_form'); $this->fc->user->addHelper('html_form');
$this->page->set('title','TaskFreak! Login'); $this->page->set('title','TaskFreak! '.TR::get('security','login'));
$this->page->add('css',array('form.css','freak.css','login.css')); $this->page->add('css',array('form.css','freak.css','login.css'));
$this->page->add('js','form.js'); $this->page->add('js','form.js');
$this->setView('login/login'); $this->setView('login/login');

View File

@ -4,7 +4,7 @@
* *
* @package taskfreak_tt * @package taskfreak_tt
* @author Stan Ozier <taskfreak@gmail.com> * @author Stan Ozier <taskfreak@gmail.com>
* @version 0.3 * @version 0.4
* @copyright GNU General Public License (GPL) version 3 * @copyright GNU General Public License (GPL) version 3
*/ */
@ -38,45 +38,46 @@ class Task extends AppController {
} else { } else {
$this->page->add('css',array('form.css','freak.css','list.css','tracker.css','colorbox.css')); $this->page->add('css',array('form.css','freak.css','list.css','tracker.css','colorbox.css'));
// $this->page->add('js',array('jquery.form.min.js','jquery.colorbox-min.js')); // $this->page->add('js',array('jquery.form.min.js','jquery.colorbox-min.js'));
$this->_addJsSettings();
$this->page->add('js','freak.js'); $this->page->add('js','freak.js');
} }
} }
public function mainAction() { public function mainAction() {
$this->filter = $this->fc->sessionVariable('filter'); $this->filter = $this->fc->sessionVariable('filter');
$title = 'Todo'; $title = 'todo';
$filter = 'status=0 AND archived=0'; $filter = 'status=0 AND archived=0';
$this->actions = array(); $this->actions = array();
switch ($this->filter) { switch ($this->filter) {
case '1': case '1':
$title = 'Completed'; $title = 'done';
$filter = 'status=1 AND archived=0'; $filter = 'status=1 AND archived=0';
$this->actions['open'] = 'Re-open'; $this->actions['open'] = 'reopen';
$this->actions['valid'] = 'Validate'; $this->actions['valid'] = 'validate';
$this->actions['archive'] = 'Archive'; $this->actions['archive'] = 'archive';
break; break;
case '2': case '2':
$title = 'Valid'; // -TODO- check english term $title = 'valid';
$filter = 'status=2 AND archived=0'; $filter = 'status=2 AND archived=0';
$this->actions['open'] = 'Re-open'; $this->actions['open'] = 'reopen';
$this->actions['archive'] = 'Archive'; $this->actions['archive'] = 'archive';
break; break;
case '3': case '3':
$title = 'Archives'; $title = 'archives';
$filter = 'archived=1'; $filter = 'archived=1';
$this->actions['unarchive'] = 'Unarchive'; $this->actions['unarchive'] = 'unarchive';
break; break;
default: default:
$this->actions['report'] = 'Report 1 day'; $this->actions['report'] = 'postpone_1_day';
$this->actions['close'] = 'Mark as done'; $this->actions['close'] = 'mark_done';
$this->actions['valid'] = 'Validate'; $this->actions['valid'] = 'validate';
$this->actions['archive'] = 'Archive'; $this->actions['archive'] = 'archive';
break; break;
} }
$this->_taskList($filter); $this->_taskList($filter);
$this->page->set('title',$title.' | TaskFreak! Time Tracker'); $this->page->set('title',TR::get('pages',$title).' | TaskFreak! Time Tracker');
if ($this->fc->getReqVar('ajax')) { if ($this->fc->getReqVar('ajax')) {
$this->setView('include/list-'.($this->expand?'expand':'compact')); $this->setView('include/list-'.($this->expand?'expand':'compact'));
@ -91,14 +92,14 @@ class Task extends AppController {
// drop if no checkbox have been checked // drop if no checkbox have been checked
if (!$this->fc->chkReqVar('chk')) { if (!$this->fc->chkReqVar('chk')) {
// -TODO- show error // -TODO- show error
$this->fc->redirect(APP_WWW_URI.'task/main/','please mark at least one task'); $this->fc->redirect($this->fc->getUrl('task','main'),'[error]none_checked');
} }
// check action request // check action request
$action = $this->fc->chkReqVar('report,open,close,valid,archive,unarchive'); $action = $this->fc->chkReqVar('report,open,close,valid,archive,unarchive');
// do it then // do it then
TaskModel::updateManyAtOnce($action, $_POST['chk']); TaskModel::updateManyAtOnce($action, $_POST['chk']);
// reload entire page // reload entire page
$this->fc->redirect(APP_WWW_URI.'task/main/'); $this->fc->redirect($this->fc->getUrl('task','main'));
} }
/** /**
@ -123,7 +124,7 @@ class Task extends AppController {
// now start selected task // now start selected task
TimerModel::start($id); TimerModel::start($id);
$this->current = TaskSummary::loadCurrent(); $this->current = TaskSummary::loadCurrent();
$this->jsCode .= "clockstart('$id')"; $this->jsCode .= "clockstart('$id');$('#drun button').wTip();";
} }
$this->setView('include/timer'); $this->setView('include/timer');
$this->view(); $this->view();
@ -159,7 +160,7 @@ class Task extends AppController {
$this->jsCode .= "clockreport('$cid');clockstatus('paused');"; $this->jsCode .= "clockreport('$cid');clockstatus('paused');";
} else { } else {
// nope, requested task is not running, show error // nope, requested task is not running, show error
$this->jsCode = "alert('error trying to pause')"; $this->jsCode = "alert('".TR::get('error','action_failed')."')";
FC::log_debug('error trying to pause non running task'); FC::log_debug('error trying to pause non running task');
} }
break; break;
@ -173,7 +174,7 @@ class Task extends AppController {
if (TimerModel::stop($id)) { if (TimerModel::stop($id)) {
$this->jsCode = "clockstatus();"; $this->jsCode = "clockstatus();";
} else { } else {
$this->jsCode = "alert('task already stopped');"; $this->jsCode = "alert('".TR::get('error','action_failed')."');";
} }
$this->current = false; $this->current = false;
break; break;
@ -273,7 +274,7 @@ class Task extends AppController {
$this->timer = new TimerModel(); $this->timer = new TimerModel();
$this->timer->addHelper('html_form'); $this->timer->addHelper('html_form');
$this->page->set('title','Todo details | TaskFreak! Time Tracker'); $this->page->set('title',TR::get('pages','view_task').' | TaskFreak! Time Tracker');
// $this->page->add('js',array('jquery.dateentry.pack.js','jquery.timeentry.pack.js')); // $this->page->add('js',array('jquery.dateentry.pack.js','jquery.timeentry.pack.js'));
$this->setView('view'); $this->setView('view');
$this->view(); $this->view();
@ -282,7 +283,7 @@ class Task extends AppController {
public function createAction() { public function createAction() {
$this->_loadTask(); $this->_loadTask();
$this->data->addHelper('html_form'); $this->data->addHelper('html_form');
$this->page->set('title','Create Multiple Todos | TaskFreak! Time Tracker'); $this->page->set('title',TR::get('pages','create_tasks').' | TaskFreak! Time Tracker');
$this->setView('create'); $this->setView('create');
$this->view(); $this->view();
} }
@ -305,14 +306,14 @@ class Task extends AppController {
} }
} }
} }
$this->fc->redirect(APP_WWW_URI.'task/main',$i.' task(s) created !'); $this->fc->redirect($this->fc->getUrl('task','main'),'created'); // -TODO- show $i
} }
public function editAction() { public function editAction() {
$this->_loadTask(); $this->_loadTask();
$this->data->addHelper('html_form'); $this->data->addHelper('html_form');
$this->page->set('title',($this->data->getUid()?'Edit':'Create').' Todo | TaskFreak! Time Tracker'); $this->page->set('title',TR::get('pages',($this->data->getUid()?'edit':'create').'_task').' | TaskFreak! Time Tracker');
$this->setView('edit'); $this->setView('edit');
$this->view(); $this->view();
} }
@ -342,4 +343,18 @@ class Task extends AppController {
return $this->data->getUid(); return $this->data->getUid();
} }
protected function _addJsSettings() {
$js = "var RELOAD_URI='".APP_WWW_URI."task/main/ajax/1'; var URLMODREWRITE=true; ";
if (!APP_URL_REWRITE) {
$js = "var RELOAD_URI='".APP_WWW_URI."?c=task&amp;a=main&amp;ajax=1'; var URLMODREWRITE=false; ";
}
// translations
$js .= "var LANGRUNNING='".TR::html('task','running')."'; ";
$js .= "var LANGCONFIRM='".TR::html('data','delete_confirm')."'; ";
$this->page->add('jsCode', $js);
}
} }

View File

@ -4,7 +4,7 @@
* *
* @package taskfreak_tt * @package taskfreak_tt
* @author Stan Ozier <taskfreak@gmail.com> * @author Stan Ozier <taskfreak@gmail.com>
* @version 0.3 * @version 0.4
* @copyright GNU General Public License (GPL) version 3 * @copyright GNU General Public License (GPL) version 3
*/ */
@ -79,7 +79,7 @@ class Timer extends AppController {
echo '<script type="text/javascript">'; echo '<script type="text/javascript">';
echo "reloadList(); window.setTimeout('$.fn.colorbox.close()',1000);"; echo "reloadList(); window.setTimeout('$.fn.colorbox.close()',1000);";
echo '</script>'; echo '</script>';
echo '<p class="empty">time added</p>'; echo '<p class="empty">'.TR::html('message','time_added').'</p>';
return false; return false;
} }
@ -89,7 +89,7 @@ class Timer extends AppController {
$start = $this->fc->getReqVar('start'); $start = $this->fc->getReqVar('start');
if (empty($id) || empty($start)) { if (empty($id) || empty($start)) {
$this->fc->redirect(APP_WWW_URI,'ERROR:missing parameters'); $this->fc->redirect(APP_WWW_URI,'[error]action_failed');
} }
// delete timer // delete timer
@ -115,7 +115,7 @@ class Timer extends AppController {
echo "reloadList();"; echo "reloadList();";
echo '</script>'; echo '</script>';
} else { } else {
$this->fc->redirect(APP_WWW_URI,'Timer deleted'); $this->fc->redirect(APP_WWW_URI,'deleted');
} }
} else { } else {
// error deleting // error deleting
@ -124,7 +124,7 @@ class Timer extends AppController {
echo 'alert("can not delete timer");'; echo 'alert("can not delete timer");';
echo '</script>'; echo '</script>';
} else { } else {
$this->fc->redirect(APP_WWW_URI,'Timer NOT deleted'); $this->fc->redirect(APP_WWW_URI,'[error]action_deleted');
} }
} }

120
app/lang/en/freak.php Normal file
View File

@ -0,0 +1,120 @@
<?php
/**
* TaskFreak!
*
* @package taskfreak
* @author Stan Ozier <taskfreak@gmail.com>
* @version 0.4
* @copyright GNU General Public License (GPL) version 3
*/
$GLOBALS['lang']['task'] = array(
'priority' => 'priority',
'spent' => 'spent',
'note' => 'note',
'todo' => 'todo',
'done' => 'done',
'valid' => 'valid',
'archived' => 'archived',
'running' => 'running',
'paused' => 'paused'
);
$GLOBALS['lang']['priority'] = array(
'urgent' => 'urgent',
'important' => 'important',
'high' => 'high',
'quickly' => 'quickly',
'pretty_soon' => 'pretty soon',
'soon' => 'soon',
'normal' => 'normal',
'after' => 'after',
'later' => 'later',
'low' => 'low',
'anytime' => 'anytime',
'whenever' => 'whenever'
);
$GLOBALS['lang']['ui'] = array(
'reload' => 'reload',
'reload_list' => 'reload list',
'task' => 'task',
'tasks' => 'tasks',
'create_single' => 'create single task',
'create_multi' => 'create multiple task',
'edit_task' => 'edit task',
'delete_task' => 'delete task',
'start_task' => 'start task',
'mark_archived' => 'mark task as archived',
'done_confirm' => 'really mark this task as completed ?',
'compact' => 'compact',
'expand' => 'expand',
'select_all' => 'select all',
'info' => 'info',
'history' => 'history',
'history_empty' => 'no time reports yet',
'report_spent' => 'report time spent',
'total' => 'total',
'user_menu' => 'show user menu',
'admin' => 'admin',
'settings' => 'settings',
'all_users' => 'all users',
'switch' => 'switch',
'switch_user' => 'see other user\'s tasks',
'select_user' => 'select user whose tasks you want to see',
'switched' => 'switched to another user',
'task_manager' => 'task manager',
'task_managers' => 'task managers',
'user_admin' => 'user admin',
'user_admins' => 'user admins',
'last_visit' => 'last visit',
'preferences' => 'my preferences',
'create_user' => 'create user',
'edit_user' => 'edit user',
'delete_user' => 'delete user'
);
$GLOBALS['lang']['pages'] = array(
'todo' => 'todo',
'done' => 'done',
'valid' => 'valid',
'archives' => 'archives',
'edit_task' => 'edit task',
'create_task' => 'create task',
'create_tasks' => 'create multiple tasks',
'view_task' => 'task details'
);
$arrMess = array(
'task_created' => 'task created',
'task_updated' => 'task updated',
'%_task_created' => '% task(s) created',
'task_deleted' => 'task deleted',
'time_added' => 'work time reported'
);
// we're adding these translations to the standard messages translations
$GLOBALS['lang']['message'] = $GLOBALS['lang']['message']+$arrMess;
$arrButton = array(
'pause' => 'pause',
'resume' => 'resume',
'done' => 'done',
'reopen' => 're-open',
'postpone_1_day' => 'postpone 1 day',
'postpone_2_days' => 'postpone 2 days',
'postpone_1_week' => 'postpone 1 week',
'postpone_2_weeks' => 'postpone 2 weeks',
'postpone_1_month' => 'postpone 1 month',
'postpone_2_months' => 'postpone 2 months',
'postpone_1_year' => 'postpone 1 year',
'postpone_2_years' => 'postpone 2 years',
'mark_done' => 'mark as done',
'validate' => 'validate',
'archive' => 'archive',
'unarchive' => 'unarchive',
'save_report' => 'save_report',
'save_task' => 'save task',
'save_and_start' => 'save and start'
);
// we're adding these translations to the standard button translations
$GLOBALS['lang']['button'] = $GLOBALS['lang']['button']+$arrButton;

View File

@ -0,0 +1,19 @@
<p>Enter one task per line.</p>
<h4>Task format</h4>
<p>Task format : [date] [priority] [label :] task title<br />
<small>fields within brackets are optional</small></p>
<p><em>date</em> can be :</p>
<ul>
<li>a date in format dd/mm[/yy]</li>
<li>a + followed by number of days in the future</li>
<li>a - means no deadline</li>
<li>nothing means deadline is today</li>
</ul>
<p><em>priority</em> is a number between 1 and 9, followed by a )<br />
<small>&laquo; 1) &raquo; for urgent tasks, &laquo; 5) &raquo; for normal priority</small></p>
<p><em>label</em> is optional</p>
<h4>Defaults for multiple tasks</h4>
<p>a line starting by a * sets up defaults</p>
<p>Format is : * [date] [label]<br />
<small>&laquo; * +1 taskfreak &raquo; or &laquo; * 12/04 &raquo;</small></p>
<p>reset defaults with a line with &laquo; ** &raquo;</p>

View File

@ -0,0 +1,8 @@
<p>Enter either :</p>
<ul>
<li>A start time only (will calculate time from then until now)</li>
<li>A time spent only (will consider you've just finished the task)</li>
<li>A start time and an stop time</li>
<li>A start time and a time spent</li>
<li>A stop time and a time spent</li>
</ul>

120
app/lang/fr/freak.php Normal file
View File

@ -0,0 +1,120 @@
<?php
/**
* TaskFreak!
*
* @package taskfreak
* @author Stan Ozier <taskfreak@gmail.com>
* @version 0.4
* @copyright GNU General Public License (GPL) version 3
*/
$GLOBALS['lang']['task'] = array(
'priority' => 'priorité',
'spent' => 'durée',
'note' => 'note',
'todo' => 'à faire',
'done' => 'effectué',
'valid' => 'validé',
'archived' => 'archivé',
'running' => 'en cours',
'paused' => 'en pause`'
);
$GLOBALS['lang']['priority'] = array(
'urgent' => 'urgent',
'important' => 'important',
'high' => 'haute',
'quickly' => 'dès que possible',
'pretty_soon' => 'rapidement',
'soon' => 'bientôt',
'normal' => 'normal',
'after' => 'après',
'later' => 'plus tard',
'low' => 'faible',
'anytime' => 'bien plus tard',
'whenever' => 'peu importe'
);
$GLOBALS['lang']['ui'] = array(
'reload' => 'recharger',
'reload_list' => 'recharger la liste',
'task' => 'tâche',
'tasks' => 'tâches',
'create_single' => 'créer une tâche',
'create_multi' => 'créer plusieurs tâches',
'edit_task' => 'modifier tâche',
'delete_task' => 'supprimer tâche',
'start_task' => 'démarrer la tâche',
'mark_archived' => 'marquer comme archivé',
'done_confirm' => 'vraiment marquer comme effectuée?',
'compact' => 'compacte',
'expand' => 'étendue',
'select_all' => 'tout sélectionner',
'info' => 'info',
'history' => 'historique',
'history_empty' => 'aucune durée rapportée',
'report_spent' => 'rapporter une durée passée',
'total' => 'total',
'user_menu' => 'menu utilisateur',
'admin' => 'administration',
'settings' => 'paramètres',
'all_users' => 'tous utilisateurs',
'switch' => 'changer',
'switch_user' => 'changer d\'utilisateur',
'select_user' => 'choisir un utiisateur pour en voir les tâches',
'switched' => 'changement effectué',
'task_manager' => 'chef de projet',
'task_managers' => 'chefs de projet',
'user_admin' => 'administrateur',
'user_admins' => 'administrateurs',
'last_visit' => 'dernière visite',
'preferences' => 'mes préférences',
'create_user' => 'créer utilisateur',
'edit_user' => 'moditier utilisateur',
'delete_user' => 'supprimer utilisateur'
);
$GLOBALS['lang']['pages'] = array(
'todo' => 'tâches à faire',
'done' => 'tâches effectuées',
'valid' => 'tâches validées',
'archives' => 'archives',
'edit_task' => 'modifier une tâche',
'create_task' => 'créer une tâche',
'create_tasks' => 'créer plusieurs tâches',
'view_task' => 'détails de la tâche'
);
$arrMess = array(
'task_created' => 'tâche créée',
'task_updated' => 'tâche mise à jour',
'%_task_created' => '% tâche(s) crées',
'task_deleted' => 'tâche supprimée',
'time_added' => 'temps passé enregistré'
);
// we're adding these translations to the standard messages translations
$GLOBALS['lang']['message'] = $GLOBALS['lang']['message']+$arrMess;
$arrButton = array(
'pause' => 'pause',
'resume' => 'reprendre',
'done' => 'effectuée',
'reopen' => 'réouvrir',
'postpone_1_day' => 'repousser d\'un jour',
'postpone_2_days' => 'repousser de 2 jours',
'postpone_1_week' => 'repousser d\'une semaine',
'postpone_2_weeks' => 'repousser de 2 semaines',
'postpone_1_month' => 'repousser d\'un mois',
'postpone_2_months' => 'repousser de 2 mois',
'postpone_1_year' => 'repousser d\'une année',
'postpone_2_years' => 'repousser de 2 ans',
'mark_done' => 'marquer effectuée',
'validate' => 'valider',
'archive' => 'archiver',
'unarchive' => 'réactiver',
'save_report' => 'rapporter',
'save_task' => 'enregistrer la tâche',
'save_and_start' => 'enregistrer et démarrer'
);
// we're adding these translations to the standard button translations
$GLOBALS['lang']['button'] = $GLOBALS['lang']['button']+$arrButton;

View File

@ -0,0 +1,19 @@
<p>Saisir une t&acirc;che par ligne.</p>
<h4>Format de la saisie :</h4>
<p>[date] [priorit&eacute;] [mot-cl&eacute; :] titre de la t&acirc;che<br />
<small>les champs entre crochets sont facultatifs</small></p>
<p><em>date</em> peut &ecirc;tre :</p>
<ul>
<li>une date au format jj/mm[/aa]</li>
<li>un + suivi du nombre de jours dans le futur</li>
<li>un - signifie pas de date</li>
<li>pas de date signifie aujourd'hui</li>
</ul>
<p><em>priorit&eacute;</em>: un chiffre entre 1 et 9 suivi de )<br />
<small>&laquo; 1) &raquo; pour urgent, &laquo; 5) &raquo; pour normal</small></p>
<p><em>mot-cl&eacute;</em> est facultatif</p>
<h4>Valeurs par d&eacute;faut pour plusieurs t&acirc;ches</h4>
<p>commen&ccedil;er par * indique les valeurs par d&eacute;faut</p>
<p>Le format est : * [date] [mot-cl&eacute;]<br />
<small>&laquo; * +1 taskfreak &raquo; ou &laquo; * 12/04 &raquo;</small></p>
<p>annuler les valeurs par d&eacute;faut : &laquo; ** &raquo; sur une ligne</p>

View File

@ -0,0 +1,8 @@
<p>Saisir soit :</p>
<ul>
<li>Une heure de d&eacute;but (calcule le temps pass&eacute; jusqu'&agrave; maintenant)</li>
<li>Un temps pass&eacute; (consid&egrave;re que vous venez juste de terminer)</li>
<li>Une heure de d&eacute;part et une heure de fin</li>
<li>Une heure de d&eacute;part et un temps pass&eacute;</li>
<li>Une heure de fin et un temps pass&eacute;</li>
</ul>

View File

@ -4,7 +4,7 @@
* *
* @package taskfreak_tt * @package taskfreak_tt
* @author Stan Ozier <taskfreak@gmail.com> * @author Stan Ozier <taskfreak@gmail.com>
* @version 0.2 * @version 0.4
* @copyright GNU General Public License (GPL) version 3 * @copyright GNU General Public License (GPL) version 3
*/ */
@ -29,10 +29,10 @@ class MemberModel extends UserAclModel {
$arr = explode(',', $this->get('actags')); $arr = explode(',', $this->get('actags'));
$arrTrans = array(); $arrTrans = array();
if (in_array('task_see_all', $arr)) { if (in_array('task_see_all', $arr)) {
$arrTrans[] = 'task manager'; $arrTrans[] = TR::html('ui','task_manager');
} }
if (in_array('admin_user', $arr)) { if (in_array('admin_user', $arr)) {
$arrTrans[] = 'user admin'; $arrTrans[] = TR::html('ui','user_admin');
} }
return implode(', ',$arrTrans); return implode(', ',$arrTrans);
} }

View File

@ -4,7 +4,7 @@
* *
* @package taskfreak_tt * @package taskfreak_tt
* @author Stan Ozier <taskfreak@gmail.com> * @author Stan Ozier <taskfreak@gmail.com>
* @version 0.2 * @version 0.4
* @copyright GNU General Public License (GPL) version 3 * @copyright GNU General Public License (GPL) version 3
*/ */
@ -183,15 +183,15 @@ class TaskSummary extends TaskModel {
public function htmlPriority() { public function htmlPriority() {
$arr = $this->getPropertyOptions('priority'); $arr = $this->getPropertyOptions('priority');
$st = $this->get('priority'); $st = $this->get('priority');
return $arr['options'][$st]; return $st.') '.TR::html('priority',$arr['options'][$st]);
} }
public function htmlStatus() { public function htmlStatus() {
$arr = $this->getPropertyOptions('status'); $arr = $this->getPropertyOptions('status');
$str = $this->get('status'); $str = $this->get('status');
$str = $arr['options'][$str]; // -TODO- TRANSLATE $str = TR::html('task',$arr['options'][$str]);
if ($this->get('archived')) { if ($this->get('archived')) {
$str .= ' (archived)'; $str .= ' ('.TR::html('task','archived').')';
} }
return $str; return $str;
} }
@ -201,7 +201,6 @@ class TaskSummary extends TaskModel {
if ($this->isEmpty('begin')) { if ($this->isEmpty('begin')) {
return '-'; return '-';
} else { } else {
// -TODO- show in grey
return $this->html('begin',APP_DATE); return $this->html('begin',APP_DATE);
} }
} else { } else {
@ -237,11 +236,11 @@ class TaskSummary extends TaskModel {
case 9999: case 9999:
return '-'; return '-';
case -1: case -1:
return 'yesterday'; return TR::html('date','yesterday');
case 0: case 0:
return 'today'; return TR::html('date','today');
case 1: case 1:
return 'tomorrow'; return TR::html('date','tomorrow');
default: default:
return $this->html('deadline',APP_DATE); return $this->html('deadline',APP_DATE);
} }
@ -313,7 +312,7 @@ class TaskSummary extends TaskModel {
if ($stopped) { if ($stopped) {
return '--:--'; return '--:--';
} else { } else {
return 'running'; return TR::html('task','running');
} }
} }
$h = floor($spent / 60); $h = floor($spent / 60);

View File

@ -2,7 +2,7 @@
$this->incView('include/page-top', false); $this->incView('include/page-top', false);
?> ?>
<h1>Select user whose tasks you want to see</h1> <h1><?php TR::phtml('ui','select_user'); ?></h1>
<ul> <ul>
<?php <?php
while ($this->data->next()) { while ($this->data->next()) {
@ -10,7 +10,7 @@ while ($this->data->next()) {
if ($this->data->getUid() == $this->switch_id) { if ($this->data->getUid() == $this->switch_id) {
echo $this->data->html('nickname'); echo $this->data->html('nickname');
} else { } else {
echo '<a href="/admin/switch/id/'.$this->data->getUid().'">'.$this->data->html('nickname').'</a>'; echo '<a href="'.$this->fc->getUrl('admin','switch',array('id'=>$this->data->getUid())).'">'.$this->data->html('nickname').'</a>';
} }
echo '</li>'; echo '</li>';
} }

View File

@ -5,12 +5,12 @@ $this->incView('include/page-top', false);
echo '<h1>'; echo '<h1>';
if ($id = $this->data->getUid()) { if ($id = $this->data->getUid()) {
if ($id == $this->fc->user->getUid()) { if ($id == $this->fc->user->getUid()) {
echo 'My preferences'; TR::phtml('security','my_account');
} else { } else {
echo 'Edit a user'; TR::phtml('ui','edit_user');
} }
} else { } else {
echo 'Create new user'; TR::phtml('ui','create_user');
} }
echo '</h1>'; echo '</h1>';
@ -20,22 +20,22 @@ echo $this->data->iHidden('id');
?> ?>
<ol class="fields side"> <ol class="fields side">
<?php <?php
echo $this->data->iFieldLabelled('nickname','','','li class="compulsory"'); echo $this->data->iFieldLabelled('nickname',TR::html('form','nick_name'),'','li class="compulsory"');
echo $this->data->iFieldLabelled('email'); echo $this->data->iFieldLabelled('email',TR::html('form','email'));
?> ?>
<li> <li>
<label for="i_time_zone">time zone</label> <label for="i_time_zone"><?php TR::phtml('form','time_zone'); ?></label>
<?php echo $this->data->iTimeZone('time_zone'); ?> <?php echo $this->data->iTimeZone('time_zone'); ?>
</li> </li>
<?php <?php
echo $this->data->iFieldLabelled('username','','','li class="compulsory"'); echo $this->data->iFieldLabelled('username',TR::html('form','username'),'','li class="compulsory"');
?> ?>
<li> <li>
<label for="i_pass1">password</label> <label for="i_pass1"><?php TR::phtml('form','password'); ?></label>
<?php echo $this->data->iPass('pass1', false); ?> <?php echo $this->data->iPass('pass1', false); ?>
</li> </li>
<li> <li>
<label for="i_pass2">(repeat)</label> <label for="i_pass2"><?php TR::phtml('form','password_confirm'); ?></label>
<?php echo $this->data->iPass('pass2', false); ?> <?php echo $this->data->iPass('pass2', false); ?>
</li> </li>
<?php <?php
@ -43,26 +43,26 @@ echo $this->data->iHidden('id');
// can only change rights for other users // can only change rights for other users
?> ?>
<li> <li>
<label>user rights</label> <label><?php TR::phtml('form','user_rights'); ?></label>
<ul> <ul>
<li><input type="checkbox" id="i_acl_task_see_all" name="acl_task_see_all" value="1"<?php <li><input type="checkbox" id="i_acl_task_see_all" name="acl_task_see_all" value="1"<?php
if ($this->data->checkAcl('task_see_all')) echo ' checked="checked"'; if ($this->data->checkAcl('task_see_all')) echo ' checked="checked"';
?> /> <label for="i_acl_task_see_all">task manager</label></li> ?> /> <label for="i_acl_task_see_all"><?php TR::phtml('ui','task_manager'); ?></label></li>
<li><input type="checkbox" id="i_acl_admin_user" name="acl_admin_user" value="1"<?php <li><input type="checkbox" id="i_acl_admin_user" name="acl_admin_user" value="1"<?php
if ($this->data->checkAcl('admin_user')) echo ' checked="checked"'; if ($this->data->checkAcl('admin_user')) echo ' checked="checked"';
?> /> <label for="i_acl_admin_user">user admin</label></li> ?> /> <label for="i_acl_admin_user"><?php TR::phtml('ui','user_admin'); ?></label></li>
</ul> </ul>
</li> </li>
<?php <?php
} }
?> ?>
<li class="buttons"> <li class="buttons">
<button type="submit" name="save" value="1" class="save">Save</button> <button type="submit" name="save" value="1" class="save"><?php TR::phtml('button','save'); ?></button>
<?php <?php
if ($this->canDeleteThisUser) { if ($this->canDeleteThisUser) {
?> ?>
<a href="<?php echo $this->fc->getUrl('admin','delete',array('id'=>$this->data->getUid())); ?>" <a href="<?php echo $this->fc->getUrl('admin','delete',array('id'=>$this->data->getUid())); ?>"
onclick="return confirm('really delete the dude ?');" class="button marge delete">Delete</a> onclick="return confirm('<?php TR::phtml('data','delete_confirm'); ?>');" class="button marge delete"><?php TR::phtml('button','delete'); ?></a>
<?php <?php
} }
?> ?>

View File

@ -5,7 +5,7 @@ $this->incView('include/page-top', false);
<div id="dmain" class="full"> <div id="dmain" class="full">
<div id="dfilters"> <div id="dfilters">
<span> <span>
<a href="<?php echo $this->fc->getUrl('admin/edit');?>" class="ajax box new inv" title="Create new user">Create user</a> <a href="<?php echo $this->fc->getUrl('admin/edit');?>" class="ajax box new inv" title="<?php TR::phtml('ui','create_user'); ?>"><?php TR::phtml('ui','create_user'); ?></a>
</span> </span>
<ul class="links horiz"> <ul class="links horiz">
<?php <?php
@ -34,7 +34,7 @@ $this->incView('include/page-top', false);
<form id="search" action="<?php $this->fc->thisUrl(); ?>" method="get"> <form id="search" action="<?php $this->fc->thisUrl(); ?>" method="get">
<p> <p>
<input type="text" name="search" value="<?php echo $this->search; ?>" tabindex="4" /> <input type="text" name="search" value="<?php echo $this->search; ?>" tabindex="4" />
<button type="submit" name="go" value="1">search</button> <button type="submit" name="go" value="1"><?php TR::phtml('data','search'); ?></button>
<button type="button" onclick="this.form.elements[0].value='';this.form.submit()">x</button> <button type="button" onclick="this.form.elements[0].value='';this.form.submit()">x</button>
</p> </p>
</form> </form>
@ -46,8 +46,8 @@ $this->incView('include/page-top', false);
<table> <table>
<thead> <thead>
<tr> <tr>
<th>name</th> <th><?php TR::phtml('form','name'); ?></th>
<th>last visit</th> <th><?php TR::phtml('form','last_visit_date'); ?></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -56,7 +56,8 @@ $this->incView('include/page-top', false);
$id = $this->data->getUid(); $id = $this->data->getUid();
echo '<tr>'; echo '<tr>';
echo '<td>'; echo '<td>';
echo '<a href="'.$this->fc->getUrl('admin','edit',array('id'=>$id)).'" class="onhold ajax box" title="Edit user">edit</a>'; echo '<a href="'.$this->fc->getUrl('admin','edit',array('id'=>$id)).'" class="onhold ajax box" title="'
.TR::html('button','edit').'">'.TR::html('button','edit').'</a>';
echo $this->data->html('nickname'); echo $this->data->html('nickname');
if ($tmp = $this->data->htmlRights()) { if ($tmp = $this->data->htmlRights()) {
echo ' <small>'.$tmp.'</small>'; echo ' <small>'.$tmp.'</small>';
@ -71,7 +72,7 @@ $this->incView('include/page-top', false);
<?php <?php
} else { } else {
?> ?>
<p class="empty">sorry, no user found</p> <p class="empty"><?php TR::html('data','search_empty'); ?></p>
<?php <?php
} }
?> ?>

View File

@ -2,31 +2,15 @@
$this->incView('include/page-top', false); $this->incView('include/page-top', false);
?> ?>
<div id="sidepanel"> <div id="sidepanel">
<p>Enter one task per line.</p> <?php
<h4>Task format</h4> $this->fc->loadLangFile('help_multi_creation.php');
<p>Task format : [date] [priority] [label :] task title<br /> ?>
<small>fields within brackets are optional</small></p>
<p><em>date</em> can be :</p>
<ul>
<li>a date in format dd/mm[/yy]</li>
<li>a + followed by number of days in the future</li>
<li>a - means no deadline</li>
<li>nothing means deadline is today</li>
</ul>
<p><em>priority</em> is a number between 1 and 9, followed by a )<br />
<small>&laquo; 1) &raquo; for urgent tasks, &laquo; 5) &raquo; for normal priority</small></p>
<p><em>label</em> is optional</p>
<h4>Defaults for multiple tasks</h4>
<p>a line starting by a * sets up defaults</p>
<p>Format is : * [date] [label]<br />
<small>&laquo; * +1 taskfreak &raquo; or &laquo; * 12/04 &raquo;</small></p>
<p>reset defaults with a line with &laquo; ** &raquo</p>
</div> </div>
<?php <?php
$hh = new HtmlFormHelper(); $hh = new HtmlFormHelper();
echo $hh->iForm('task_batch','post',$this->fc->thisUrl()); echo $hh->iForm('task_batch','post',$this->fc->thisUrl());
echo '<p>'.$hh->iTextArea('data').'</p>'; echo '<p>'.$hh->iTextArea('data').'</p>';
echo '<p><button type="submit" name="save" value="1" class="save">Save</button></p>'; echo '<p><button type="submit" name="save" value="1" class="save">'.TR::html('button','create').'</button></p>';
echo '</form>'; echo '</form>';
$this->incView('include/page-bot', false); $this->incView('include/page-bot', false);

View File

@ -7,27 +7,27 @@ echo $this->data->iHidden('id');
?> ?>
<ol class="fields multicol top"> <ol class="fields multicol top">
<?php <?php
echo $this->data->iFieldLabelled('title','','','li id="f_title" class="nline"'); echo $this->data->iFieldLabelled('title',TR::html('form','title'),'','li id="f_title" class="nline"');
// $this->data->iFieldLabelled('begin'); -TODO- unused ATM // $this->data->iFieldLabelled('begin'); -TODO- unused ATM
echo $this->data->iFieldLabelled('deadline','','','li class="nline"'); echo $this->data->iFieldLabelled('deadline',TR::html('form','deadline'),'','li class="nline"');
?> ?>
<li> <li>
<label for="i_priority">priority</label> <label for="i_priority"><?php TR::phtml('task','priority'); ?></label>
<?php echo $this->data->iSelect('priority'); ?> <?php echo $this->data->iSelectTranslate('priority','priority'); ?>
</li> </li>
<?php <?php
echo $this->data->iFieldLabelled('note','','','li class="nline"'); echo $this->data->iFieldLabelled('note',TR::html('task','note'),'','li class="nline"');
?> ?>
<li class="nline inline"> <li class="nline inline">
<label for="i_status">status</label> : <label for="i_status"><?php TR::phtml('form','status'); ?></label> :
<?php echo $this->data->iSelect('status'); ?> <?php echo $this->data->iSelectTranslate('status','task'); ?>
</li> </li>
<li class="inline"> <li class="inline">
<?php echo $this->data->iCheckBox('archived'); ?> <?php echo $this->data->iCheckBox('archived'); ?>
<label for="i_archived">mark task as archived</label> <label for="i_archived"><?php TR::phtml('ui','mark_archived'); ?></label>
</li> </li>
<li class="nline buttons"> <li class="nline buttons">
<button type="submit" name="save" value="1" class="save">Save Task</button> <button type="submit" name="save" value="1" class="save"><?php TR::phtml('button','save_task'); ?></button>
</li> </li>
</ol> </ol>
<script type="text/javascript" src="<?php echo APP_WWW_URI.'asset/js/jquery.jdpicker.js'; ?>"></script> <script type="text/javascript" src="<?php echo APP_WWW_URI.'asset/js/jquery.jdpicker.js'; ?>"></script>

View File

@ -8,22 +8,25 @@ if ($this->data->count()) {
<th>&nbsp;</th> <th>&nbsp;</th>
<th<?php <th<?php
if ($this->order == 'deadline') echo ' class="active"'; if ($this->order == 'deadline') echo ' class="active"';
?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'deadline')); ?>">deadline</a></th> ?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'deadline')); ?>"><?php TR::phtml('form','deadline'); ?></a></th>
<th<?php <th<?php
if ($this->order == 'priority') echo ' class="active"'; if ($this->order == 'priority') echo ' class="active"';
?>> ?>>
<small><?php echo $this->data->total(); ?> item(s) found</small> <small><?php
<a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'priority')); ?>">task</a> $ct = $this->data->total();
echo $ct.' '.TR::html('data',($ct>1)?'items_found':'item_found');
?></small>
<a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'priority')); ?>"><?php TR::phtml('ui','task'); ?></a>
</th> </th>
<th<?php <th<?php
if ($this->order == 'start') echo ' class="active"'; if ($this->order == 'start') echo ' class="active"';
?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'start')); ?>">start</a></th> ?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'start')); ?>"><?php TR::phtml('form','start'); ?></a></th>
<th<?php <th<?php
if ($this->order == 'stop') echo ' class="active"'; if ($this->order == 'stop') echo ' class="active"';
?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'stop')); ?>">stop</a></th> ?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'stop')); ?>"><?php TR::phtml('form','stop'); ?></a></th>
<th<?php <th<?php
if ($this->order == 'spent') echo ' class="active"'; if ($this->order == 'spent') echo ' class="active"';
?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'spent')); ?>">spent</a></th> ?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'spent')); ?>"><?php TR::phtml('task','spent'); ?></a></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -50,11 +53,13 @@ if ($this->data->count()) {
?></td> ?></td>
<td><?php echo $this->data->htmlDeadline(); ?></td> <td><?php echo $this->data->htmlDeadline(); ?></td>
<td> <td>
<a href="<?php echo $this->fc->getUrl('task','edit',array('id'=>$id)); ?>" class="onhold ajax box" title="Edit task">edit</a>
<?php <?php
// edit link
echo '<a href="'.$this->fc->getUrl('task','edit',array('id'=>$id)).'" class="onhold ajax box" title="'
.TR::html('ui','edit_task').'">'.TR::html('button','edit').'</a>';
// priority // priority
echo '<span class="prio pr'.$this->data->get('priority'); echo '<span class="prio pr'.$this->data->get('priority');
echo '">'.$this->data->get('priority').'</span> '; echo '" title="'.$this->data->htmlPriority().'">'.$this->data->get('priority').'</span> ';
// note // note
echo '<a href="'.$this->fc->getUrl('task','view',array('id'=>$id)).'" '; echo '<a href="'.$this->fc->getUrl('task','view',array('id'=>$id)).'" ';
if ($this->data->isEmpty('note')) { if ($this->data->isEmpty('note')) {
@ -75,12 +80,12 @@ if ($this->data->count()) {
<?php <?php
if ($this->data->isOpened($this->user_id)) { if ($this->data->isOpened($this->user_id)) {
echo '<a href="'.$this->fc->getUrl('task','timer',array('id'=>$id)).'" ' echo '<a href="'.$this->fc->getUrl('task','timer',array('id'=>$id)).'" '
.'class="onhold clock ajax" title="start task" rel="drun">start</a>'; .'class="onhold clock ajax" title="'.TR::html('ui','start_task').'" rel="drun">'.TR::html('button','start').'</a>';
} }
echo '<span>'; echo '<span>';
if (!$this->expand && $cid == $id) { if (!$this->expand && $cid == $id) {
echo 'running'; echo TR::html('task','running');
} else { } else {
echo $this->data->getTimeSpent(); echo $this->data->getTimeSpent();
} }
@ -95,15 +100,15 @@ if ($this->data->count()) {
<tfoot> <tfoot>
<tr> <tr>
<td colspan="3"> <td colspan="3">
<a href="javascript:checkAll('f_tasks')">select all</a> | <a href="javascript:checkAll('f_tasks')"><?php TR::phtml('ui','select_all'); ?></a> |
<?php <?php
foreach ($this->actions as $key => $label) { foreach ($this->actions as $key => $label) {
echo ' <button type="submit" name="'.$key.'" ' echo ' <button type="submit" name="'.$key.'" '
.'value="1">'.VarStr::html($label).'</button>'; .'value="1">'.TR::html('button',$label).'</button>';
} }
?> ?>
</td> </td>
<td colspan="2">TOTAL</td> <td colspan="2"><?php TR::phtml('ui','total'); ?></td>
<td><?php echo TaskSummary::htmlTime($total); ?></td> <td><?php echo TaskSummary::htmlTime($total); ?></td>
</tr> </tr>
</tfoot> </tfoot>
@ -111,5 +116,5 @@ if ($this->data->count()) {
</form> </form>
<?php <?php
} else { } else {
echo '<p class="empty">No Task found</p>'; echo '<p class="empty">'.TR::html('error','search_empty').'</p>';
} }

View File

@ -24,22 +24,25 @@ if ($this->data->count()) {
<th>&nbsp;</th> <th>&nbsp;</th>
<th<?php <th<?php
if ($this->order == 'deadline') echo ' class="active"'; if ($this->order == 'deadline') echo ' class="active"';
?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'deadline')); ?>">deadline</a></th> ?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'deadline')); ?>"><?php TR::phtml('form','deadline'); ?></a></th>
<th<?php <th<?php
if ($this->order == 'priority') echo ' class="active"'; if ($this->order == 'priority') echo ' class="active"';
?>> ?>>
<small><?php echo count($arrData); ?> item(s) found</small> <small><?php
<a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'priority')); ?>">task</a> $ct = count($arrData);
echo $ct.' '.TR::html('data',($ct>1)?'items_found':'item_found');
?></small>
<a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'priority')); ?>"><?php TR::phtml('ui','task'); ?></a>
</th> </th>
<th<?php <th<?php
if ($this->order == 'start') echo ' class="active"'; if ($this->order == 'start') echo ' class="active"';
?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'start')); ?>">start</a></th> ?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'start')); ?>"><?php TR::phtml('form','start'); ?></a></th>
<th<?php <th<?php
if ($this->order == 'stop') echo ' class="active"'; if ($this->order == 'stop') echo ' class="active"';
?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'stop')); ?>">stop</a></th> ?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'stop')); ?>"><?php TR::phtml('form','stop'); ?></a></th>
<th<?php <th<?php
if ($this->order == 'spent') echo ' class="active"'; if ($this->order == 'spent') echo ' class="active"';
?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'spent')); ?>">spent</a></th> ?>><a href="<?php echo $this->fc->getUrl('task','main',array('order'=>'spent')); ?>"><?php TR::phtml('task','spent'); ?></a></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -81,10 +84,11 @@ if ($this->data->count()) {
echo '<td>'; echo '<td>';
// edit link // edit link
echo '<a href="/task/edit/id/'.$id.'" class="onhold ajax box" title="Edit task">edit</a>'; echo '<a href="'.$this->fc->getUrl('task','edit',array('id'=>$id)).'" class="onhold ajax box" title="'
.TR::html('ui','edit_task').'">'.TR::html('button','edit').'</a>';
// priority // priority
echo '<span class="prio pr'.$obj->get('priority'); echo '<span class="prio pr'.$obj->get('priority');
echo '">'.$obj->get('priority').'</span> '; echo '" title="'.$obj->htmlPriority().'">'.$obj->get('priority').'</span> ';
// note // note
echo '<a href="'.$this->fc->getUrl('task','view',array('id'=>$id)).'" '; echo '<a href="'.$this->fc->getUrl('task','view',array('id'=>$id)).'" ';
if ($obj->isEmpty('note')) { if ($obj->isEmpty('note')) {
@ -112,7 +116,8 @@ if ($this->data->count()) {
// subtotal // subtotal
echo '<td id="sts_'.$id,'">'; echo '<td id="sts_'.$id,'">';
if ($obj->isOpened($this->user_id)) { if ($obj->isOpened($this->user_id)) {
echo '<a href="/task/timer/id/'.$id.'" class="onhold clock ajax" title="start task" rel="drun">start</a>'; echo '<a href="'.$this->fc->getUrl('task','timer',array('id'=>$id)).'" '
.'class="onhold clock ajax" title="'.TR::html('ui','start_task').'" rel="drun">'.TR::html('button','start').'</a>';
} }
echo TaskSummary::htmlTime($subtotal); echo TaskSummary::htmlTime($subtotal);
echo '</td>'; echo '</td>';
@ -153,15 +158,15 @@ if ($this->data->count()) {
<tfoot> <tfoot>
<tr> <tr>
<td colspan="3"> <td colspan="3">
<a href="javascript:checkAll('f_tasks')">select all</a> | <a href="javascript:checkAll('f_tasks')"><?php TR::phtml('ui','select_all'); ?></a> |
<?php <?php
foreach ($this->actions as $key => $label) { foreach ($this->actions as $key => $label) {
echo ' <button type="submit" name="'.$key.'" ' echo ' <button type="submit" name="'.$key.'" '
.'value="1">'.VarStr::html($label).'</button>'; .'value="1">'.TR::html('button',$label).'</button>';
} }
?> ?>
</td> </td>
<td colspan="2">TOTAL</td> <td colspan="2"><?php TR::phtml('ui','total'); ?></td>
<td><?php echo TaskSummary::htmlTime($total); ?></td> <td><?php echo TaskSummary::htmlTime($total); ?></td>
</tr> </tr>
</tfoot> </tfoot>
@ -169,5 +174,5 @@ if ($this->data->count()) {
</form> </form>
<?php <?php
} else { } else {
echo '<p>No Task found</p>'; echo '<p class="empty">'.TR::html('error','search_empty').'</p>';
} }

View File

@ -18,21 +18,21 @@ if (isset($this->current)) {
<div id="duser"> <div id="duser">
<?php <?php
if (APP_SETUP_USER_MODEL && $this->fc->user->isLoggedIn()) { if (APP_SETUP_USER_MODEL && $this->fc->user->isLoggedIn()) {
echo $this->fc->user->html('nickname'); echo '<p><a href="javascript:showmenu()">'.$this->fc->user->html('nickname');
if ($this->fc->getSessionVariable('switch_id') != $this->fc->user->getUid()) { if ($this->fc->getSessionVariable('switch_id') != $this->fc->user->getUid()) {
echo ' as '.varStr::html($this->fc->getSessionVariable('switch_name')); echo ' as '.varStr::html($this->fc->getSessionVariable('switch_name'));
} }
echo '<br /><small>'; echo '<br /><small>'.TR::html('ui','user_menu').'</small></a></p>';
echo '<ul id="dmenu">';
if ($this->fc->user->checkAcl('task_see_all')) { if ($this->fc->user->checkAcl('task_see_all')) {
echo '<a href="'.$this->fc->getUrl('admin','switch').'" class="ajax box">switch</a> | '; echo '<li><a href="'.$this->fc->getUrl('admin','switch').'" class="ajax box">'.TR::html('ui','switch').'</a></li>';
} }
echo '<li><a href="'.$this->fc->getUrl('admin','edit',array('id'=>$this->fc->user->getUid())).'" class="ajax box">'.TR::html('security','my_account').'</a></li>';
if ($this->fc->user->checkAcl('admin_user')) { if ($this->fc->user->checkAcl('admin_user')) {
echo '<a href="'.$this->fc->getUrl('admin').'">admin</a> | '; echo '<li><a href="'.$this->fc->getUrl('admin').'">'.TR::html('ui','admin').'</a></li>';
} else {
echo '<a href="'.$this->fc->getUrl('admin','edit').'" class="ajax box">profile</a> | ';
} }
echo '<a href="'.$this->fc->getUrl('login','out').'">logout</a>'; echo '<li><a href="'.$this->fc->getUrl('login','out').'">'.TR::html('security','logout').'</a></li>';
echo '</small>'; echo '</ul>';
} else { } else {
echo 'TaskFreak!<br /><small>Time Tracking</small>'; echo 'TaskFreak!<br /><small>Time Tracking</small>';
} }

View File

@ -1,37 +1,32 @@
<?php <?php
echo $this->timer->iForm('task_timer','post',APP_WWW_URI.'timer/main'); echo $this->timer->iForm('task_timer','post',$this->fc->getUrl('timer','main'));
?> ?>
<input type="hidden" name="id" value="<?php echo $this->data->getUid(); ?>" /> <input type="hidden" name="id" value="<?php echo $this->data->getUid(); ?>" />
<ol class="fields multicol side"> <ol class="fields multicol side">
<li class="nline"> <li class="nline">
<label>date</label> <label><?php TR::phtml('form','date'); ?></label>
<input type="text" id="i_date" name="date" class="date" value="<?php echo VarDte::value(APP_SQL_TODAY); ?>" /> <input type="text" id="i_date" name="date" class="date" value="<?php echo VarDte::value(APP_SQL_TODAY); ?>" />
</li> </li>
<li class="nline"> <li class="nline">
<label>start</label> <label><?php TR::phtml('form','start'); ?></label>
<input type="text" id="i_start_time" name="start_time" class="time" /> <input type="text" id="i_start_time" name="start_time" class="time" />
</li> </li>
<li> <li>
<label>stop</label> <label><?php TR::phtml('form','stop'); ?></label>
<input type="text" id="i_stop_time" name="stop_time" class="time" /> <input type="text" id="i_stop_time" name="stop_time" class="time" />
</li> </li>
<li class="nline"> <li class="nline">
<label>spent</label> <label><?php TR::phtml('task','spent'); ?></label>
<input type="text" id="i_spent" name="spent" class="duration" value="00:00" /> <input type="text" id="i_spent" name="spent" class="duration" value="00:00" />
</li> </li>
<li class="nline buttons"> <li class="nline buttons">
<button type="submit" name="save" value="1" class="save">Save report</button> <button type="submit" name="save" value="1" class="save"><?php TR::phtml('button','save_report'); ?></button>
<a href="javascript:document.task_timer.reset()">reset</a> <a href="javascript:document.task_timer.reset()"><?php TR::phtml('button','reset'); ?></a>
</li> </li>
</ol> </ol>
<hr class="clear" /> <hr class="clear" />
<div class="help"> <div class="help">
<p>Enter either :</p> <?php
<ul> $this->fc->loadLangFile('help_timer_creation.php');
<li>A start time only (will calculate time from then until now)</li> ?>
<li>A time spent only (will consider you've just finished the task)</li>
<li>A start time and an stop time</li>
<li>A start time and a time spent</li>
<li>A stop time and a time spent</li>
</ul>
</div> </div>

View File

@ -5,9 +5,9 @@ if ($this->data->get('spent')) {
<table class="list"> <table class="list">
<thead> <thead>
<tr> <tr>
<th>start</th> <th><?php TR::phtml('form','start'); ?></th>
<th>stop</th> <th><?php TR::phtml('form','stop'); ?></th>
<th>spent</th> <th><?php TR::phtml('task','spent'); ?></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -25,7 +25,7 @@ if ($this->data->get('spent')) {
echo '<td>'.$this->data->htmlEnd().'</td>'; echo '<td>'.$this->data->htmlEnd().'</td>';
// time spent // time spent
echo '<td>'; echo '<td>';
echo '<a href="'.$this->fc->getUrl('timer','delete',$params).'" class="onhold ajax confirm" rel="tab2">delete</a>'; echo '<a href="'.$this->fc->getUrl('timer','delete',$params).'" class="onhold ajax confirm" rel="tab2">'.TR::html('button','delete').'</a>';
echo $this->data->getTimeSpent(); echo $this->data->getTimeSpent();
echo '</td>'; echo '</td>';
echo '</tr>'; echo '</tr>';
@ -34,14 +34,14 @@ if ($this->data->get('spent')) {
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="2">Total</td> <td colspan="2"><?php TR::phtml('ui','total'); ?></td>
<td><?php echo TaskSummary::htmlTime($total); ?></td> <td><?php echo TaskSummary::htmlTime($total); ?></td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
<?php <?php
} else { } else {
echo '<p class="empty">No timers yet</p>'; echo '<p class="empty">'.TR::html('ui','history_empty').'</p>';
} }
?> ?>
<p class="empty"><a href="#tab3" onclick="tabber.show(3); return false;">Report more time spent</a></p> <p class="empty"><a href="#tab3" onclick="tabber.show(3); return false;"><?php TR::phtml('ui','report_spent'); ?></a></p>

View File

@ -6,15 +6,15 @@ if ($this->current) {
if ($this->current->isEmpty('stop')) { if ($this->current->isEmpty('stop')) {
// task is running // task is running
?> ?>
<!-- button type="submit" name="pause" value="1" class="submit" tabindex="2">pause</button --> <!-- button type="submit" id="b_pause" name="pause" value="1" class="submit" tabindex="2">pause</button -->
<button type="submit" name="stop" value="1" class="submit" tabindex="2">stop</button> <button type="submit" id="b_stop" name="stop" value="1" tabindex="2"><?php TR::phtml('button','stop'); ?></button>
<button type="submit" name="close" value="1" class="warn" tabindex="3" onclick="return confirm('mark this task as done ?')">done</button> <button type="submit" id="b_close" name="close" value="1" tabindex="3" onclick="return confirm('<?php TR::phtml('ui','done_confirm'); ?>')"><?php TR::phtml('button','mark_done'); ?></button>
<?php <?php
} else { } else {
// task is paused (requested from ajax only) // task is paused (requested from ajax only)
?> ?>
<button type="submit" name="resume" value="1" class="submit" tabindex="2">resume</button> <button type="submit" id="b_resume" name="resume" value="1" tabindex="2"><?php TR::phtml('button','resume'); ?></button>
<button type="submit" name="stop" value="1" class="warn" tabindex="3">stop</button> <button type="submit" id="b_stop" name="stop" value="1" tabindex="3"><?php TR::phtml('button','stop'); ?></button>
<?php <?php
} }
?> ?>
@ -29,8 +29,8 @@ if ($this->current) {
} else { } else {
?> ?>
<div id="timerstatus"> <div id="timerstatus">
<button type="submit" name="save" value="1" class="saveadd" tabindex="2">Save</button> <button type="submit" id="b_save" name="save" value="1" tabindex="2"><?php TR::phtml('button','save'); ?></button>
<button type="submit" name="start" value="1" class="save" tabindex="3">Start</button> <button type="submit" id="b_start" name="start" value="1" tabindex="3"><?php TR::phtml('button','save_and_start'); ?></button>
</div> </div>
<p> <p>
<input type="text" name="title" value="" tabindex="1" /> <input type="text" name="title" value="" tabindex="1" />

View File

@ -4,20 +4,20 @@ $this->incView('include/page-top', false);
<form action="<?php echo $this->fc->getUrl('login'); ?>" method="post"> <form action="<?php echo $this->fc->getUrl('login'); ?>" method="post">
<?php <?php
if ($str = $this->fc->user->getAuthError()) { if ($str = $this->fc->user->getAuthError()) {
echo '<p>Can not login: '.VarStr::html($str).'</p>'; echo '<p>'.TR::html('error','login_failed').': '.TR::html('error',$str).'</p>';
} }
?> ?>
<ol class="fields side"> <ol class="fields side">
<li> <li>
<label for="i_username">Username</label> <label for="i_username"><?php TR::phtml('form','username'); ?></label>
<?php echo $this->fc->user->iText('username'); ?> <input id="i_username" type="text" name="username" value="<?php echo $this->fc->user->value('username'); ?>" />
</li> </li>
<li> <li>
<label for="i_password">Password</label> <label for="i_password"><?php TR::phtml('form','password'); ?></label>
<?php echo $this->fc->user->iPass('password'); ?> <input id="i_password" type="password" name="password" value="" />
</li> </li>
<li class="buttons"> <li class="buttons">
<button type="submit" name="login" value="1" class="submit">Login</button> <button type="submit" name="login" value="1" class="submit"><?php TR::phtml('button','login'); ?></button>
</li> </li>
</ol> </ol>
</form> </form>

View File

@ -4,9 +4,9 @@ $this->incView('include/page-top', false);
<div id="dmain" class="full"> <div id="dmain" class="full">
<div id="dfilters"> <div id="dfilters">
<span> <span>
<a href="<?php echo $this->fc->getUrl('task','edit');?>" class="ajax box new inv" title="Create single task">Create task</a> <a href="<?php echo $this->fc->getUrl('task','edit');?>" class="ajax box new inv" title="<?php TR::phtml('ui','create_single'); ?>"><?php TR::phtml('ui','create_single'); ?></a>
<a href="<?php echo $this->fc->getUrl('task','create');?>" class="ajax bigbox new multi inv" title="Create multiple tasks">Create multiple</a> <a href="<?php echo $this->fc->getUrl('task','create');?>" class="ajax bigbox new multi inv" title="<?php TR::phtml('ui','create_multi'); ?>"><?php TR::phtml('ui','create_multi'); ?></a>
<a href="<?php echo $this->fc->getUrl('task','main',array('ajax'=>1)); ?>" class="new reload inv" title="Reload list">Reload</a> <a href="<?php echo $this->fc->getUrl('task','main',array('ajax'=>1)); ?>" class="new reload inv" title="<?php TR::phtml('ui','reload_list'); ?>"><?php TR::phtml('ui','reload'); ?></a>
</span> </span>
<ul class="links horiz"> <ul class="links horiz">
<?php <?php
@ -16,7 +16,7 @@ $this->incView('include/page-top', false);
if ($this->filter == $val) { if ($this->filter == $val) {
echo ' class="active"'; echo ' class="active"';
} }
echo '><a href='.$this->fc->thisUrl(array('filter'=>$val)).'>'.$lbl.'</a></li>'; echo '><a href='.$this->fc->thisUrl(array('filter'=>$val)).'>'.TR::html('task',$lbl).'</a></li>';
} }
?> ?>
</ul> </ul>
@ -28,7 +28,7 @@ $this->incView('include/page-top', false);
if ($this->expand == $val) { if ($this->expand == $val) {
echo ' class="active"'; echo ' class="active"';
} }
echo '><a href='.$this->fc->thisUrl(array('expand'=>$val)).'>'.$lbl.'</a></li>'; echo '><a href='.$this->fc->thisUrl(array('expand'=>$val)).'>'.TR::html('ui',$lbl).'</a></li>';
} }
?> ?>
</ul> </ul>
@ -40,7 +40,7 @@ $this->incView('include/page-top', false);
if ($this->limit == $val) { if ($this->limit == $val) {
echo ' class="active"'; echo ' class="active"';
} }
echo '><a href='.$this->fc->thisUrl(array('limit'=>$val)).'>'.$lbl.'</a></li>'; echo '><a href='.$this->fc->thisUrl(array('limit'=>$val)).'>'.(is_int($lbl)?$lbl:TR::html('data',$lbl)).'</a></li>';
} }
?> ?>
</ul> </ul>
@ -48,9 +48,17 @@ $this->incView('include/page-top', false);
if ($this->search) { echo ' class="filled"'; } if ($this->search) { echo ' class="filled"'; }
?>> ?>>
<p> <p>
<?php
if (!APP_URL_REWRITE) {
?>
<input type="hidden" name="c" value="<?php echo $this->fc->controller; ?>" />
<input type="hidden" name="a" value="<?php echo $this->fc->action; ?>" />
<?php
}
?>
<input type="text" name="search" value="<?php echo $this->search; ?>" tabindex="4" /> <input type="text" name="search" value="<?php echo $this->search; ?>" tabindex="4" />
<button id="b_submit" type="submit" name="go" value="1">search</button> <button id="b_submit" type="submit" name="go" value="1"><?php TR::phtml('data','search'); ?></button>
<button id="b_clear" type="button" onclick="this.form.elements[0].value='';this.form.submit()">x</button> <button id="b_clear" type="button" onclick="this.form.elements['search'].value='';this.form.submit()">x</button>
</p> </p>
</form> </form>
</div> </div>

View File

@ -4,30 +4,30 @@ $this->incView('include/page-top', false);
<h1><?php echo $this->data->html('title'); ?></h1> <h1><?php echo $this->data->html('title'); ?></h1>
<div id="tabs" class="tabs"> <div id="tabs" class="tabs">
<ul id="tabs-nav" class="nav"> <ul id="tabs-nav" class="nav">
<li><a href="#tab1">info</a></li> <li><a href="#tab1"><?php TR::phtml('ui','info'); ?></a></li>
<li><a href="#tab2">history</a></li> <li><a href="#tab2"><?php TR::phtml('ui','history'); ?></a></li>
<li><a href="#tab3">report time spent</a></li> <li><a href="#tab3"><?php TR::phtml('ui','report_spent'); ?></a></li>
</ul> </ul>
<div id="tab1" class="tab"> <div id="tab1" class="tab">
<table class="info"> <table class="info">
<tbody> <tbody>
<tr> <tr>
<th>deadline</th> <th><?php TR::phtml('form','deadline'); ?></th>
<td><?php echo $this->data->htmlDeadline(); ?></td> <td><?php echo $this->data->htmlDeadline(); ?></td>
</tr> </tr>
<tr> <tr>
<th>priority</th> <th><?php TR::phtml('task','priority'); ?></th>
<td><?php echo $this->data->htmlPriority(); ?></td> <td><?php echo $this->data->htmlPriority(); ?></td>
</tr> </tr>
<tr> <tr>
<th>status</th> <th><?php TR::phtml('form','status'); ?></th>
<td><?php echo $this->data->htmlStatus(); ?></td> <td><?php echo $this->data->htmlStatus(); ?></td>
</tr> </tr>
<?php <?php
if (!$this->data->isEmpty('note')) { if (!$this->data->isEmpty('note')) {
?> ?>
<tr> <tr>
<th>note</th> <th><?php TR::phtml('task','note'); ?></th>
<td><?php echo $this->data->html('note'); ?></td> <td><?php echo $this->data->html('note'); ?></td>
</tr> </tr>
<?php <?php

View File

@ -1,4 +1,3 @@
var RELOAD_URI='/task/main/ajax/1';
var AUTORELOAD=300000; var AUTORELOAD=300000;
var AUTODELAY=60000; var AUTODELAY=60000;
var AUTOHIDE=2500; var AUTOHIDE=2500;
@ -18,6 +17,7 @@ function reloadList() {
$("#dlist").html(html); $("#dlist").html(html);
$('#dlist *[title]').wTip(); $('#dlist *[title]').wTip();
$('a.ajax').makeajax(); $('a.ajax').makeajax();
$('#dlist table thead tr th').makeClickable();
$('#dlist table tbody tr td').makeClickable(); $('#dlist table tbody tr td').makeClickable();
startAlive(AUTORELOAD); startAlive(AUTORELOAD);
} }
@ -61,7 +61,7 @@ function clockstart(id) {
if (el[0]) { if (el[0]) {
$('#dlist table tbody tr').removeClass('current'); $('#dlist table tbody tr').removeClass('current');
el.addClass('current'); el.addClass('current');
$('#sts_'+id+' span').html('running'); $('#sts_'+id+' span').html(LANGRUNNING);
} }
} else { } else {
timer = $('#i_timer').val(); timer = $('#i_timer').val();
@ -84,6 +84,7 @@ function clockstatus(cl) {
$(document).ready(function(){ $(document).ready(function(){
$('*[title]').wTip(); $('*[title]').wTip();
$('#drun button').wTip();
bindAjax(); bindAjax();
$('input:first').focus(); $('input:first').focus();
@ -96,8 +97,12 @@ $(document).ready(function(){
$('#drun').ajaxForm({ $('#drun').ajaxForm({
target: '#drun', target: '#drun',
data: {'ajax':'1'}, data: {'ajax':'1'},
beforeSubmit: clockstop, beforeSubmit: function() {
clockstop();
$("p#vtip").remove();
},
complete: function() { complete: function() {
$('#drun button').wTip();
$('#drun input').focus(); $('#drun input').focus();
} }
}); });
@ -106,6 +111,7 @@ $(document).ready(function(){
$('a.ajax').makeajax(); $('a.ajax').makeajax();
// bind rows/td clicks // bind rows/td clicks
$('#dlist table thead tr th').makeClickable();
$('#dlist table tbody tr td').makeClickable(); $('#dlist table tbody tr td').makeClickable();
// focus on first field when opening a cbox // focus on first field when opening a cbox
@ -117,6 +123,15 @@ $(document).ready(function(){
el = $('.reload').first(); el = $('.reload').first();
RELOAD_URI = el.attr('href'); RELOAD_URI = el.attr('href');
el.attr('href','javascript:reloadList()'); el.attr('href','javascript:reloadList()');
// enable user menu on hover
$('#duser p a').mouseenter(function() {
$('#dmenu').slideDown(100);
$('#duser').mouseleave(function() {
$('#dmenu').slideUp(100);
$(this).unbind('mouseleave');
});
});
// reload task list every 5 minutes // reload task list every 5 minutes
startAlive(AUTORELOAD); startAlive(AUTORELOAD);
@ -133,6 +148,10 @@ function cleanMessage() {
}); });
} }
function showmenu() {
$('#dmenu').slideToggle(100);
}
function startAlive(d) { function startAlive(d) {
if ($('#dlist.tasks')[0]) { if ($('#dlist.tasks')[0]) {
// console.log('start alive (delay = '+d+')'); // console.log('start alive (delay = '+d+')');
@ -168,6 +187,9 @@ jQuery.fn.makeClickable = function() {
return this.each(function() { return this.each(function() {
$(this).click(function(e) { $(this).click(function(e) {
if (e.target.nodeName == 'A') { if (e.target.nodeName == 'A') {
if (!e.target.href.match(/(ajax)/)) {
window.location.href = e.target.href;
}
return true; return true;
} }
el = $(this); el = $(this);
@ -196,8 +218,14 @@ function bindAjax() {
jQuery.fn.makeajax = function(boxed) { jQuery.fn.makeajax = function(boxed) {
return this.each(function() { return this.each(function() {
if (!this.href.match(/(ajax\/1)/)) { if (!this.href.match(/(ajax)/)) {
this.href = this.href+'/ajax/1'; if (URLMODREWRITE) {
this.href = this.href+'/ajax/1';
} else if (this.href.match(/\?/)) {
this.href = this.href+'&ajax=1';
} else {
this.href = this.href+'?ajax=1';
}
el = $(this); el = $(this);
if (el.hasClass('bigbox')) { if (el.hasClass('bigbox')) {
el.colorbox({title:'...',width:"700", height:"400"}); el.colorbox({title:'...',width:"700", height:"400"});
@ -216,7 +244,7 @@ jQuery.fn.ajaxify = function(target) {
e.preventDefault(); e.preventDefault();
el = $(this); el = $(this);
if (el.hasClass('confirm')) { if (el.hasClass('confirm')) {
if (!confirm('Really delete this item ?')) { if (!confirm('Really delete this item ?')) { // -TODO-TRANSLATE-
return false; return false;
} }
} }
@ -256,6 +284,9 @@ jQuery.fn.wTip = function() {
function(e) { function(e) {
this.t = this.title; this.t = this.title;
this.title = ''; this.title = '';
if (!this.t) {
this.t = $(this).html();
}
var inv = $(this).hasClass('inv'); var inv = $(this).hasClass('inv');
this.top = (e.pageY + yOffset); this.top = (e.pageY + yOffset);
if (inv) { if (inv) {

View File

@ -1,10 +0,0 @@
<?php
/**
* TaskFreak
*
* @author Stan Ozier <framework@tirzen.com>
* @since 0.1
* @copyright GNU Lesser General Public License (LGPL) version 3
*/
$GLOBALS['config']['lang']['specialchars'] = 2;

View File

View File

@ -4,7 +4,7 @@
* *
* @package tzn_core_classes * @package tzn_core_classes
* @author Stan Ozier <framework@tirzen.com> * @author Stan Ozier <framework@tirzen.com>
* @version 0.3 * @version 0.4
* @copyright GNU Lesser General Public License (LGPL) version 3 * @copyright GNU Lesser General Public License (LGPL) version 3
*/ */
@ -154,6 +154,7 @@ class FrontController extends HelpableSingleton {
*/ */
public function loadUserSettings() { public function loadUserSettings() {
// might overload default controller and action // might overload default controller and action
// and language
// -TODO- // -TODO-
if ($this->user->isLoggedIn()) { if ($this->user->isLoggedIn()) {
$this->setSessionDefault('usertask', $this->user->getUid()); $this->setSessionDefault('usertask', $this->user->getUid());
@ -179,6 +180,8 @@ class FrontController extends HelpableSingleton {
*/ */
public function initTranslator() { public function initTranslator() {
$this->addHelper('translator'); $this->addHelper('translator');
$this->loadLangConfig();
$this->loadLangFilesFromConfig();
} }
/** /**

View File

@ -4,7 +4,7 @@
* *
* @package tzn_core_classes * @package tzn_core_classes
* @author Stan Ozier <framework@tirzen.com> * @author Stan Ozier <framework@tirzen.com>
* @version 0.3 * @version 0.4
* @copyright GNU Lesser General Public License (LGPL) version 3 * @copyright GNU Lesser General Public License (LGPL) version 3
*/ */
@ -692,7 +692,7 @@ class VarDte extends VarAbstract
if ($t = self::strToUnix($val)) { if ($t = self::strToUnix($val)) {
return strftime(APP_DATE_SQL, $t); return strftime(APP_DATE_SQL, $t);
} }
$info['error'] = 'model_date_invalid'; $info['error'] = 'invalid_date';
return false; return false;
} }
@ -763,7 +763,7 @@ class VarDur extends VarAbstract
} }
return $t; return $t;
} else { } else {
$info['error'] = 'model_time_invalid'; $info['error'] = 'invalid_duration';
return false; return false;
} }
} }
@ -830,7 +830,7 @@ class VarTim extends VarDur
// now make GMT // now make GMT
return $t - self::getUserTimeZoneOffset(); return $t - self::getUserTimeZoneOffset();
} }
$info['error'] = 'model_time_invalid'; $info['error'] = 'invalid_time';
return false; return false;
} }
@ -886,7 +886,7 @@ class VarDtm extends VarAbstract
// return datetime in SQL format // return datetime in SQL format
return $d.' '.VarDur::workout($t); return $d.' '.VarDur::workout($t);
} }
$info['error'] = 'model_datetime_invalid'; $info['error'] = 'invalid_datetime';
return false; return false;
} }
@ -983,7 +983,7 @@ class VarStr extends VarAbstract
} }
switch ($GLOBALS['config']['lang']['specialchars']) { switch ($GLOBALS['config']['lang']['specialchars']) {
case 3: case 3:
$val = htmlentities($val); $val = htmlentities(utf8_decode($val));
break; break;
case 2: case 2:
$val = htmlspecialchars($val); $val = htmlspecialchars($val);
@ -1007,20 +1007,19 @@ class VarUsr extends VarAbstract
{ {
public static function sanitize($val, &$info) { public static function sanitize($val, &$info) {
if (!$val && in_array('compulsory', $info)) { if (!$val && in_array('compulsory', $info)) {
$info['error'] = 'user_name_invalid'; $info['error'] = 'username_invalid';
return false; return false;
} }
if ((strlen($val) < APP_USER_NAME_MIN) if ((strlen($val) < APP_USER_NAME_MIN)
|| (strlen($val) > APP_USER_NAME_MAX)) { || (strlen($val) > APP_USER_NAME_MAX)) {
$info['error'] = 'user_name_length'; $info['error'] = 'username_length';
return false; return false;
} else if (preg_match(APP_USER_SANITIZE, $val)) { } else if (preg_match(APP_USER_SANITIZE, $val)) {
return $val; return $val;
} else { } else {
$info['error'] = 'user_name_invalid'; $info['error'] = 'username_invalid';
return false; return false;
} }
return $val;
} }
public static function value($val) { public static function value($val) {
@ -1043,15 +1042,21 @@ class VarPss extends VarAbstract
return true; return true;
} }
} }
if (preg_match(APP_PASSWORD_SANITIZE, $val)) { return $val;
}
public static function checkValid($val, &$info) {
if ((strlen($val) < APP_USER_PASS_MIN)
|| (strlen($val) > APP_USER_PASS_MAX)) {
$info['error'] = 'password_length';
return false;
} else if (preg_match(APP_PASSWORD_SANITIZE, $val)) {
return $val; return $val;
} else { } else {
$info['error'] = 'password_invalid'; $info['error'] = 'password_invalid';
return false; return false;
} }
return $val;
} }
} }
/** /**
@ -1144,6 +1149,7 @@ class VarXml extends VarAbstract
/** /**
* URL Variable - URL Address * URL Variable - URL Address
* @since 0.1 * @since 0.1
* @todo check if URL is valid
*/ */
class VarUrl extends VarAbstract class VarUrl extends VarAbstract
{ {
@ -1176,7 +1182,7 @@ class VarEml extends VarAbstract
if (empty($val) || preg_match("/^[a-z0-9]([a-z0-9_\-\.\+]*)@([a-z0-9_\-\.]*)\.([a-z]{2,4})$/i",$val)) { if (empty($val) || preg_match("/^[a-z0-9]([a-z0-9_\-\.\+]*)@([a-z0-9_\-\.]*)\.([a-z]{2,4})$/i",$val)) {
return $val; return $val;
} else { } else {
$info['error'] = 'model_email_invalid'; // -TODO-TRANSLATE- $info['error'] = 'invalid_email';
return ''; return '';
} }
} }

View File

@ -4,7 +4,7 @@
* *
* @package tzn_helpers * @package tzn_helpers
* @author Stan Ozier <framework@tirzen.com> * @author Stan Ozier <framework@tirzen.com>
* @version 0.2 * @version 0.4
* @since 0.1 * @since 0.1
* @copyright GNU Lesser General Public License (LGPL) version 3 * @copyright GNU Lesser General Public License (LGPL) version 3
*/ */
@ -40,7 +40,7 @@ class AuthHelper extends Helper {
} }
if (crypt($password, $salt) != $pass) { if (crypt($password, $salt) != $pass) {
// password invalid // password invalid
$this->error = 'user_pass_invalid'; $this->error = 'password_invalid';
$this->badAccess(); $this->badAccess();
return false; return false;
} }
@ -49,7 +49,7 @@ class AuthHelper extends Helper {
$sql = "ENCRYPT('$password','$salt')"; $sql = "ENCRYPT('$password','$salt')";
if (!self::checkDbPass($sql, $pass)) { if (!self::checkDbPass($sql, $pass)) {
// password not OK // password not OK
$this->error = 'user_pass_invalid'; $this->error = 'password_invalid';
$this->badAccess(); $this->badAccess();
return false; // error or password mismatch return false; // error or password mismatch
} }
@ -58,7 +58,7 @@ class AuthHelper extends Helper {
$sql = "ENCODE('$password','$pass')"; $sql = "ENCODE('$password','$pass')";
if (!self::checkDbPass($sql, $pass)) { if (!self::checkDbPass($sql, $pass)) {
// password not OK // password not OK
$this->error = 'user_pass_invalid'; $this->error = 'password_invalid';
$this->badAccess(); $this->badAccess();
return false; // error or password mismatch return false; // error or password mismatch
} }
@ -70,7 +70,7 @@ class AuthHelper extends Helper {
$sql = "MD5('$password')"; $sql = "MD5('$password')";
if (!self::checkDbPass($sql, $pass)) { if (!self::checkDbPass($sql, $pass)) {
// password not OK // password not OK
$this->error = 'user_pass_invalid'; $this->error = 'password_invalid';
$this->badAccess(); $this->badAccess();
return false; // error or password mismatch return false; // error or password mismatch
} }
@ -86,7 +86,7 @@ class AuthHelper extends Helper {
break; break;
} }
} }
$this->error = 'user_pass_invalid'; $this->error = 'password_invalid';
$this->badAccess(); $this->badAccess();
return false; return false;
break; break;
@ -101,7 +101,7 @@ class AuthHelper extends Helper {
{ {
break; break;
} }
$this->error = 'user_pass_invalid'; $this->error = 'password_invalid';
$this->badAccess(); $this->badAccess();
return false; return false;
break; break;
@ -212,7 +212,7 @@ class AuthHelper extends Helper {
public function login($username, $password, $activation=false) { public function login($username, $password, $activation=false) {
$this->error = ''; $this->error = '';
if ($username == '') { if ($username == '') {
$this->error = 'user_name_empty'; $this->error = 'username_required';
return false; return false;
} }
if (APP_AUTH_FIELD == 'username' && (!VarUsr::sanitize($username, $error))) { if (APP_AUTH_FIELD == 'username' && (!VarUsr::sanitize($username, $error))) {
@ -225,11 +225,13 @@ class AuthHelper extends Helper {
if (!$this->obj->get('enabled')) { if (!$this->obj->get('enabled')) {
if (!$activation || $activation != $activ) { if (!$activation || $activation != $activ) {
//Account Disabled //Account Disabled
$this->error = 'user_disabled'; $this->error = 'account_disabled';
} else {
$this->error = 'account_not_active';
} }
} }
if (!$this->checkPassword($password)) { if (!$this->checkPassword($password)) {
$this->error = 'user_password_invalid'; $this->error = 'password_invalid';
} else if ($activation && $activation == $activ) { } else if ($activation && $activation == $activ) {
// activate account // activate account
$this->activateAccount(true); $this->activateAccount(true);
@ -239,7 +241,7 @@ class AuthHelper extends Helper {
return false; return false;
} }
} else { } else {
$this->error = 'user_name_not_found'; $this->error = 'username_not_found';
return false; return false;
} }
@ -435,22 +437,20 @@ class AuthHelper extends Helper {
if ($this->obj->get('salt') == "") { if ($this->obj->get('salt') == "") {
if (!$this->obj->loadByKey($key,$value)) { if (!$this->obj->loadByKey($key,$value)) {
// user not found // user not found
$this->_error['forgot'] = $key." not found"; $this->error = $key."_not_found";
return false; return false;
} }
} }
switch (APP_AUTH_PASSWORD_MODE) { switch (APP_AUTH_PASSWORD_MODE) {
case 1: case 1:
$this->generateNewSalt();
$newpass = StringHelper::genRandom(6,"123456789");
$this->obj->set('password', crypt($pass1 , $this->obj->get('salt')));
$this->updatePassword();
break;
case 2: case 2:
case 4:
case 5:
$this->generateNewSalt(); $this->generateNewSalt();
$newpass = StringHelper::genRandom(6,"123456789"); $newpass = StringHelper::genRandom(6,"123456789");
$this->obj->set('password', self::getDbPass("ENCRYPT(\"".$pass1."\",\"".$this->obj->get('salt')."\")")); $this->obj->setRawPassword($newpass, $this->obj->get('salt'));
$this->updatePassword(); $this->updatePassword();
return $newpass;
break; break;
case 3: case 3:
$strSql = "SELECT DECODE(password, '".$this->obj->get('salt') $strSql = "SELECT DECODE(password, '".$this->obj->get('salt')
@ -458,29 +458,19 @@ class AuthHelper extends Helper {
." WHERE ".$this->obj->dbUid()."='".$this->obj->getUid()."'"; ." WHERE ".$this->obj->dbUid()."='".$this->obj->getUid()."'";
if ($rows = DbConnnector::query($strSql)) { if ($rows = DbConnnector::query($strSql)) {
if (!empty($rows[0])) { if (!empty($rows[0])) {
$this->obj->password = $rows[0]->pass; return $rows[0]->pass;
return $this->obj->password;
} }
} }
$this->_error['forgot'] = "can not decode?";
return false;
break;
case 4:
case 5:
$this->generateNewSalt();
$newpass = StringHelper::genRandom(6,"123456789");
$this->password = "MD5('$newpass')";
$this->updatePassword();
break; break;
default: default:
$iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_3DES, $iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_3DES,
MCRYPT_MODE_ECB), MCRYPT_RAND); MCRYPT_MODE_ECB), MCRYPT_RAND);
$this->password = mcrypt_decrypt (MCRYPT_3DES, $this->obj->get('salt'), return mcrypt_decrypt (MCRYPT_3DES, $this->obj->get('salt'),
$passBin, MCRYPT_MODE_ECB, $iv); $passBin, MCRYPT_MODE_ECB, $iv);
return $this->password;
break; break;
} }
return $newpass; $this->error = 'password_recover';
return false;
} }
public function getLoginCountry() { public function getLoginCountry() {

View File

@ -94,7 +94,6 @@ class HtmlFormHelper extends Helper {
/** /**
* returns a field along with LABEL, all wrapped in a LI * returns a field along with LABEL, all wrapped in a LI
* @todo make the wrapper optional
* @todo missing types * @todo missing types
*/ */
public function iFieldLabelled($key, $label='', $type='', $wrap='li') { public function iFieldLabelled($key, $label='', $type='', $wrap='li') {
@ -144,7 +143,7 @@ class HtmlFormHelper extends Helper {
return false; return false;
} }
if (empty($label)) { if (empty($label)) {
$label = str_replace('_',' ',$key); // -TODO- translate $label = str_replace('_',' ',$key);
} }
return $this->_htmlWrapBegin($wrap) return $this->_htmlWrapBegin($wrap)
.'<label for="i_'.$key.'">'.$label.'</label>' .'<label for="i_'.$key.'">'.$label.'</label>'
@ -314,6 +313,30 @@ class HtmlFormHelper extends Helper {
return $str.'</select>'; return $str.'</select>';
} }
/**
* generates a select (drop down)
*/
public function iSelectTranslate($key, $section, $options='') {
if (isset($this->obj)) {
$options = $this->obj->getPropertyOptions($key);
}
if (empty($options['options'])) {
FC::log_warn("iRadio $key does not provide options");
return $key.' (no option)';
}
$str = '<select id="i_'.$key.'" name="'.$key.'">';
$i = 1;
foreach($options['options'] as $val => $lbl) {
$str .= '<option value="'.$val.'"';
if ($options['value'] == $val) {
$str .= ' selected="selected"';
}
$str .= ' value="'.$val.'">'.TR::html($section,$lbl).'</option>';
$i++;
}
return $str.'</select>';
}
/** /**
* generates a time zone drop down list * generates a time zone drop down list
*/ */

View File

@ -4,7 +4,7 @@
* *
* @package tzn_helpers * @package tzn_helpers
* @author Stan Ozier <framework@tirzen.com> * @author Stan Ozier <framework@tirzen.com>
* @since 0.3 * @version 0.4
* @copyright GNU Lesser General Public License (LGPL) version 3 * @copyright GNU Lesser General Public License (LGPL) version 3
*/ */
@ -12,6 +12,7 @@
* Translator Helper * Translator Helper
* *
* translates everything * translates everything
* @since 0.3
* @todo test it all * @todo test it all
*/ */
class TranslatorHelper { class TranslatorHelper {
@ -22,40 +23,98 @@ class TranslatorHelper {
public function __construct() { public function __construct() {
$this->langDefault = $GLOBALS['config']['lang']['default']; $this->langDefault = $GLOBALS['config']['lang']['default'];
$this->langUser = $GLOBALS['config']['lang']['user']; $this->langUser = $GLOBALS['config']['lang']['user'];
$GLOBALS['lang'] = array();
} }
public function loadLangConfig() { public function loadLangConfig() {
include_once(APP_LANGUAGE_PATH.$this->langDefault.'/config.php'); if (file_exists(APP_LANGUAGE_PATH.$this->langUser.'/config.php')) {
include_once(APP_LANGUAGE_PATH.$this->langUser.'/config.php'); include_once(APP_LANGUAGE_PATH.$this->langUser.'/config.php');
} else {
include_once(APP_LANGUAGE_PATH.$this->langDefault.'/config.php');
}
}
public function loadLangFilesFromConfig() {
foreach($GLOBALS['config']['lang']['files'] as $file => $path) {
$full = $path.$this->langUser.'/'.$file;
if (file_exists($full)) {
include_once($full);
} else {
$full = $path.$this->langDefault.'/'.$file;
if (file_exists($full)) {
include_once($full);
}
}
}
} }
public function loadLangFile($file) { public function loadLangFile($file) {
if (file_exists(APP_LANGUAGE_PATH.$this->langUser.'/'.$file.'.php')) { // try user language
include_once(APP_LANGUAGE_PATH.$this->langUser.'/'.$file.'.php'); foreach ($GLOBALS['config']['path']['lang'] as $path) {
if (file_exists(APP_INCLUDE_PATH.$path.$this->langUser.'/'.$file)) {
include_once(APP_INCLUDE_PATH.$path.$this->langUser.'/'.$file);
return true;
}
} }
if (file_exists(APP_LANGUAGE_PATH.$this->langDefault.'/'.$file.'.php')) { // not found ? try default language
include_once(APP_LANGUAGE_PATH.$this->langDefault.'/'.$file.'.php'); foreach ($GLOBALS['config']['path']['lang'] as $path) {
if (file_exists(APP_INCLUDE_PATH.$path.$this->langDefault.'/'.$file)) {
include_once(APP_INCLUDE_PATH.$path.$this->langDefault.'/'.$file);
return true;
}
}
return false;
}
public static function getRawTranslation($section, $label, $field='') {
if (!array_key_exists($section, $GLOBALS['lang'])) {
FC::log_debug('can not find section '.$section);
return str_replace('_',' ',$label);
}
if (array_key_exists($label, $GLOBALS['lang'][$section])) {
if (is_array($GLOBALS['lang'][$section][$label])) {
return $GLOBALS['lang'][$section][$label][$field];
} else {
return $GLOBALS['lang'][$section][$label];
}
} else if (array_key_exists($label, $GLOBALS['lang'][$section])) {
if (is_array($GLOBALS['lang'][$section][$label])) {
return $GLOBALS['lang'][$section][$label][$field];
} else {
return $GLOBALS['lang'][$section][$label];
}
} else {
FC::log_debug('really can not find section '.$section);
return str_replace('_',' ',$label);
} }
} }
public function getTranslation($label, $section, $field='') { public static function getTranslation($section, $label='', $field='') {
if (!array_key_exists($section, $GLOBALS['lang'][$this->langDefault])) { if (preg_match('/^\[([a-z_]+)\](.*)$/',$section, $matches)) {
return $label; $section = $matches[1];
$label = $matches[2];
} }
if (array_key_exists($label, $GLOBALS['lang'][$this->langUser][$section])) { $str = self::getRawTranslation($section, $label, $field);
if (is_array($GLOBALS['lang'][$this->langUser][$section][$label])) { if ($GLOBALS['config']['lang']['ucfirst']) {
return $GLOBALS['lang'][$this->langUser][$section][$label][$field]; return ucfirst($str);
} else {
return $GLOBALS['lang'][$this->langUser][$section][$label];
}
} else if (array_key_exists($label, $GLOBALS['lang'][$this->langDefault][$section])) {
if (is_array($GLOBALS['lang'][$this->langDefault][$section][$label])) {
return $GLOBALS['lang'][$this->langDefault][$section][$label][$field];
} else {
return $GLOBALS['lang'][$this->langDefault][$section][$label];
}
} else {
return $label;
} }
return $str;
} }
}
class TR extends TranslatorHelper {
public static function get($section, $label, $field='') {
return self::getTranslation($section, $label, $field);
}
public static function html($section, $label, $field='') {
return VarStr::html(self::getTranslation($section, $label, $field));
}
public static function phtml($section, $label, $field='') {
echo self::html($section, $label, $field);
}
} }

250
lib/lang/en/common.php Normal file
View File

@ -0,0 +1,250 @@
<?php
/**
* Tzn Framework
*
* @package tzn_language
* @author Stan Ozier <framework@tirzen.com>
* @version 0.4
* @copyright GNU Lesser General Public License (LGPL) version 3
*/
$GLOBALS['lang']['data'] = array(
'new' => 'new item',
'read' => 'read this item',
'view' => 'view details',
'modify' => 'modify item',
'delete' => 'delete this item',
'delete_confirm' => 'really delete this item ?',
'remove' => 'remove this item',
'remove_confirm' => 'really remove from the list ?',
'search' => 'search',
'next' => 'next',
'previous' => 'previous',
'next_page' => 'next page',
'previous_page' => 'previous page',
'all' => 'all',
'more' => 'more',
'less' => 'less',
'item_found' => 'item found',
'items_found' => 'items found',
'empty' => 'no data available'
);
$GLOBALS['lang']['message'] = array(
'saved' => 'data successfully saved',
'created' => 'data successfully created',
'updated' => 'data successfully updated',
'deleted' => 'data successfully deleted',
'removed' => 'data successfully removed'
);
$GLOBALS['lang']['error'] = array(
'db_no_connection' => 'can not connect to database',
'db_no_database' => 'database not found',
'db_sql_error' => 'database query error',
'sql_injection' => 'possible SQL injection intended',
'search_empty' => 'sorry, no item could be found',
'not_found' => 'data not found',
'login_failed' => 'login failed',
'access_denied' => 'access denied',
'data_denied' => 'access to data denied',
'not_found_denied' => 'data not found or access denied',
'action_failed' => 'requested action could not be performed',
'form_error' => 'form contains error(s)',
'compulsory_field' => 'information required',
'account_disabled' => 'account is disabled',
'account_expired' => 'account has expired',
'account_not_found' => 'account does not exist',
'username_required' => 'please enter your username',
'username_not_found'=> 'username does not exists',
'username_invalid' => 'not a valid username (avoid special characters or spaces)',
'username_length' => 'username must have between '.APP_USER_NAME_MIN.' and '.APP_USER_NAME_MAX.' characters',
'email_not_found' => 'email does not exists',
'password_required' => 'password required',
'password_invalid' => 'invalid password',
'password_length' => 'password must have between '.APP_USER_PASS_MIN.' and '.APP_USER_PASS_MAX.' characters',
'password_mismatch' => 'password and verification do not match',
'password_recover' => 'password can not be recovered',
'field_length' => 'too short or too long',
'field_exists' => 'this entry already exists',
'field_invalid' => 'entry is not valid',
'field_mismatch' => 'entries do not match',
'invalid_date' => 'not a valid date',
'invalid_time' => 'not a valid time',
'invalid_email' => 'e-mail address is not valid',
'invalid_duration' => 'not a valid duration',
'file_wrong_type' => 'wrong file type',
'file_empty' => 'please select a file',
'none_checked' => 'please check at least one item'
);
$GLOBALS['lang']['security'] = array(
'login' => 'login',
'logout' => 'logout',
'sign_in' => 'not a member? Sign in now',
'my_account' => 'my account',
'account' => 'account',
'account_active' => 'account is activated',
'account_not_active'=> 'account is not activated',
'account_enabled' => 'account is enabled',
'visit_count' => 'visits',
'visit_fail_count' => 'failed login attempts',
'access_denied' => 'access denied',
'permission_denied' => 'permission denied',
'session_expired' => 'your session has expired',
'login_last_date' => 'Last login date',
'login_last_address'=> 'Last login address'
);
$GLOBALS['lang']['form'] = array(
'compulsory' => 'compulsory',
'username' => 'username',
'password' => 'password',
'password_confirm' => '(verification)',
'auto_login' => 'remember me on this computer',
'password_legend' => 'enter a password (and confirm) only if you want to change it.',
'name' => 'name',
'category' => 'category',
'title' => 'title',
'last_name' => 'last name',
'middle_name' => 'middle name',
'first_name' => 'first name',
'nick_name' => 'nick name',
'address' => 'address',
'location' => 'location',
'city' => 'city',
'state' => 'state',
'state_us_only' => 'for US members only',
'country' => 'country',
'time_zone' => 'time zone',
'user_rights' => 'permissions',
'email' => 'email',
'subject' => 'subject',
'body' => 'body',
'comment' => 'comment',
'in' => 'in',
'out' => 'out',
'from' => 'from',
'to' => 'to',
'cc' => 'cc',
'url' => 'URL',
'website' => 'website',
'description' => 'description',
'user' => 'user',
'member' => 'member',
'author' => 'author',
'status' => 'status',
'file' => 'file',
'image' => 'image',
'thumbnail' => 'thumbnail',
'document' => 'document',
'file_legend' => 'please select a file by clicking the \'Browse..\' button',
'file_name' => 'filename',
'file_size' => 'file size',
'file_type' => 'file type',
'date' => 'date',
'deadline' => 'deadline',
'start' => 'start',
'stop' => 'stop',
'publish_date' => 'publish',
'post_date' => 'post',
'creation_date' => 'date of creation',
'last_change_date' => 'last update',
'last_visit_date' => 'last visit',
'last_visit_addr' => 'from',
'posted_on' => 'posted on',
'published on' => 'published on',
'by' => 'by',
'action' => 'action'
);
// buttons
$GLOBALS['lang']['button'] = array(
'add' => 'add',
'create' => 'create',
'edit' => 'edit',
'submit' => 'submit',
'login' => 'login',
'save' => 'save',
'save_changes' => 'save changes',
'save_and_add' => 'save and add more',
'save_and_close' => 'save and close',
'update' => 'update',
'cancel' => 'cancel changes',
'close' => 'close',
'reset' => 'reset form',
'delete' => 'delete',
'remove' => 'remove',
'start' => 'start',
'stop' => 'stop',
'enable' => 'enable',
'disable' => 'disable',
'activate' => 'activate',
'deactivate' => 'deactivate',
'next_step' => 'next step',
'previous_step' => 'previous step',
'back' => 'go back',
'back_to_list' => 'back to list'
);
$GLOBALS['lang']['date'] = array(
'future_pre' => 'in', // eg. "in" 2 days
'future_app' => '', // ie. when keyword needs to be appended to the date
'past_pre' => '', // eg. "il y a" 2 jours (french)
'past_app' => 'ago', // eg. 2 days "ago"
'yesterday' => 'yesterday',
'today' => 'today',
'tomorrow' => 'tomorrow',
'days' => 'days',
'day' => 'day',
'weeks' => 'weeks',
'week' => 'week',
'months' => 'months',
'month' => 'month',
'years' => 'years',
'year' => 'year',
'hour' => 'hour',
'hours' => 'hours',
'minute' => 'minute',
'minutes' => 'minutes',
'second' => 'second',
'seconds' => 'seconds',
'january' => 'january',
'february' => 'february',
'march' => 'march',
'april' => 'april',
'may' => 'may',
'june' => 'june',
'july' => 'july',
'august' => 'august',
'september' => 'september',
'october' => 'october',
'november' => 'november',
'december' => 'december',
'jan' => 'jan',
'feb' => 'feb',
'mar' => 'mar',
'apr' => 'apr',
'may' => 'may',
'jun' => 'jun',
'jul' => 'jul',
'aug' => 'aug',
'sep' => 'sep',
'oct' => 'oct',
'nov' => 'nov',
'dec' => 'dec',
'monday' => 'monday',
'tuesday' => 'tuesday',
'wednesday' => 'wednesday',
'thursday' => 'thursday',
'friday' => 'friday',
'saturday' => 'saturday',
'sunday' => 'sunday',
'mon' => 'mon',
'tue' => 'tue',
'wed' => 'wed',
'thu' => 'thu',
'fri' => 'fri',
'sat' => 'sat',
'sun' => 'sun'
);

15
lib/lang/en/config.php Normal file
View File

@ -0,0 +1,15 @@
<?php
/**
* Tzn Framework
*
* @package tzn_language
* @author Stan Ozier <framework@tirzen.com>
* @version 0.4
* @copyright GNU Lesser General Public License (LGPL) version 3
*/
$GLOBALS['config']['lang']['specialchars'] = 2;
$GLOBALS['config']['lang']['ucfirst'] = false;
setLocale(LC_ALL, 'en_EN.UTF-8', 'en_GB.utf8', 'en_US.utf8', 'en_EN', 'en');

250
lib/lang/fr/common.php Normal file
View File

@ -0,0 +1,250 @@
<?php
/**
* Tzn Framework
*
* @package tzn_language
* @author Stan Ozier <framework@tirzen.com>
* @version 0.4
* @copyright GNU Lesser General Public License (LGPL) version 3
*/
$GLOBALS['lang']['data'] = array(
'new' => 'nouvel élément',
'read' => 'lire la suite',
'view' => 'voire les détails',
'modify' => 'modifier',
'delete' => 'supprimer',
'delete_confirm' => 'réellemment supprimer cet élément ?',
'remove' => 'retirer cet élément',
'remove_confirm' => 'réellemment retirer cet élément ?',
'search' => 'chercher',
'next' => 'suivant',
'previous' => 'précédent',
'next_page' => 'page suivante',
'previous_page' => 'page précédente',
'all' => 'tous',
'more' => 'plus',
'less' => 'moins',
'item_found' => 'élément trouvé',
'items_found' => 'éléments trouvés',
'empty' => 'aucune donnée trouvée'
);
$GLOBALS['lang']['message'] = array(
'saved' => 'données enregistrées avec succès',
'created' => 'données créées avec succès',
'updated' => 'données mises à jour',
'deleted' => 'données supprimées avec succès',
'removed' => 'éléments retirés'
);
$GLOBALS['lang']['error'] = array(
'db_no_connection' => 'impossible de se connecter à la base de données',
'db_no_database' => 'base de données introuvable',
'db_sql_error' => 'échec de la requete SQL',
'sql_injection' => 'possibilité SQL injection intended',
'search_empty' => 'aucun élément trouvé',
'not_found' => 'données introuvable',
'login_failed' => 'echec de l\'identification',
'access_denied' => 'accès interdit',
'data_denied' => 'accès refusé',
'not_found_denied' => 'données non trouvées ou accès refusé',
'action_failed' => 'echec de la commande',
'form_error' => 'le formulaire content des erreurs',
'compulsory_field' => 'donnée obilgatoire',
'account_disabled' => 'compte désactivé',
'account_expired' => 'le compte a expiré',
'account_not_found' => 'compte introuvable',
'username_required' => 'veuillez saisir un nom d\'utilisateur',
'username_not_found'=> 'nom utilisateur introuvable',
'username_invalid' => 'nom utilisateur non valide (éviter espaces et caractères spéciaux)',
'username_length' => 'le nom doit avoir entre '.APP_USER_NAME_MIN.' et '.APP_USER_NAME_MAX.' caractères',
'email_not_found' => 'courriel introuvable',
'password_required' => 'mot de passe requis',
'password_invalid' => 'mauvais mot de passe',
'password_length' => 'le mot de passe doit avoir entre '.APP_USER_PASS_MIN.' et '.APP_USER_PASS_MAX.' caractères',
'password_mismatch' => 'le mot de passe ne correspond pas',
'password_recover' => 'impossible de récuperer le mot de passe',
'field_length' => 'trop court ou trop long',
'field_exists' => 'un entrée identique existe déjà',
'field_invalid' => 'donnée non valide',
'field_mismatch' => 'les données ne correspondent pas',
'invalid_date' => 'date non valide',
'invalid_time' => 'heure non valide',
'invalid_email' => 'adresse non valide',
'invalid_duration' => 'durée non valide',
'file_wrong_type' => 'mauvais type de fichier',
'file_empty' => 'veuillez sélectionner un fichier',
'none_checked' => 'veuillez sélectionner au moins un élément'
);
$GLOBALS['lang']['security'] = array(
'login' => 'connexion',
'logout' => 'déconnexion',
'sign_in' => 'pas encore membre? cliquez ici',
'my_account' => 'mon compte',
'account' => 'compte',
'account_active' => 'compte activé',
'account_not_active'=> 'compte désactivé',
'account_enabled' => 'compte activé',
'visit_count' => 'visites',
'visit_fail_count' => 'echecs de connexion',
'access_denied' => 'accès refusé',
'permission_denied' => 'permission refusée',
'session_expired' => 'votre session a expiré',
'login_last_date' => 'date dernière connexion',
'login_last_address'=> 'adresse dernière connexion'
);
$GLOBALS['lang']['form'] = array(
'compulsory' => 'requis',
'username' => 'utilisateur',
'password' => 'mot de passe',
'password_confirm' => '(vérification)',
'auto_login' => 'm\'identifier automatiquement depuis cet ordinateur',
'password_legend' => 'saisir un mot de passe uniquement pour en changer.',
'name' => 'nom',
'category' => 'catégorie',
'title' => 'titre',
'last_name' => 'nom de famille',
'middle_name' => '',
'first_name' => 'prénom',
'nick_name' => 'surnom',
'address' => 'adresse',
'location' => 'lieu',
'city' => 'ville',
'state' => 'état',
'state_us_only' => 'pour les USA uniquement',
'country' => 'pays',
'time_zone' => 'fuseau horaire',
'user_rights' => 'permissions',
'email' => 'courriel',
'subject' => 'sujet',
'body' => 'message',
'comment' => 'commentaire',
'in' => 'entrant',
'out' => 'sortant',
'from' => 'expéditeur',
'to' => 'destinatire',
'cc' => 'copie à',
'url' => 'URL',
'website' => 'site internet',
'description' => 'description',
'user' => 'utilisateur',
'member' => 'membre',
'author' => 'auteur',
'status' => 'état',
'file' => 'fichier',
'image' => 'image',
'thumbnail' => 'aperçu',
'document' => 'document',
'file_legend' => 'veuillez choisir un fichier en cliquant sur \'Parcourir...\'',
'file_name' => 'nom du fichier',
'file_size' => 'taille du fichier',
'file_type' => 'type du fichier',
'date' => 'date',
'deadline' => 'échéance',
'start' => 'début',
'stop' => 'fin',
'publish_date' => 'publication',
'post_date' => 'envoi',
'creation_date' => 'date de création',
'last_change_date' => 'dernière mise à jour',
'last_visit_date' => 'dernière visite',
'last_visit_addr' => 'depuis',
'posted_on' => 'envoyée le',
'published on' => 'publiée le',
'by' => 'par',
'action' => 'action'
);
// buttons
$GLOBALS['lang']['button'] = array(
'add' => 'ajouter',
'create' => 'créer',
'edit' => 'modifier',
'submit' => 'soumettre',
'login' => 'indentifier',
'save' => 'enregistrer',
'save_changes' => 'enregistrer les modifications',
'save_and_add' => 'enregistrer et créer à nouveau',
'save_and_close' => 'enregistrer et fermer',
'update' => 'mettre à jour',
'cancel' => 'annuler',
'close' => 'fermer',
'reset' => 'réinitialiser',
'delete' => 'supprimer',
'remove' => 'retirer',
'start' => 'démarrer',
'stop' => 'arrêter',
'enable' => 'activer',
'disable' => 'désactiver',
'activate' => 'activer',
'deactivate' => 'désactiver',
'next_step' => 'étape suivante',
'previous_step' => 'étape précédente',
'back' => 'revenir',
'back_to_list' => 'revenir en arrière'
);
$GLOBALS['lang']['date'] = array(
'future_pre' => 'dans', // eg. "in" 2 days
'future_app' => '', // ie. when keyword needs to be appended to the date
'past_pre' => 'il y a', // eg. "il y a" 2 jours (french)
'past_app' => '', // eg. 2 days "ago"
'yesterday' => 'hier',
'today' => 'aujourd\'hui',
'tomorrow' => 'demain',
'days' => 'jours',
'day' => 'jour',
'weeks' => 'semaines',
'week' => 'semaine',
'months' => 'mois',
'month' => 'mois',
'years' => 'années',
'year' => 'année',
'hour' => 'heure',
'hours' => 'heures',
'minute' => 'minute',
'minutes' => 'minutes',
'second' => 'seconde',
'seconds' => 'secondes',
'january' => 'janvier',
'february' => 'février',
'march' => 'mars',
'april' => 'avril',
'may' => 'mai',
'june' => 'juin',
'july' => 'juillet',
'august' => 'août',
'september' => 'septembre',
'october' => 'octobre',
'november' => 'novembre',
'december' => 'décembre',
'jan' => 'jan',
'feb' => 'fev',
'mar' => 'mar',
'apr' => 'avr',
'may' => 'mai',
'jun' => 'juin',
'jul' => 'juil',
'aug' => 'aout',
'sep' => 'sep',
'oct' => 'oct',
'nov' => 'nov',
'dec' => 'dec',
'monday' => 'lundi',
'tuesday' => 'mardi',
'wednesday' => 'mercredi',
'thursday' => 'jeudi',
'friday' => 'vendredi',
'saturday' => 'samedi',
'sunday' => 'dimanche',
'mon' => 'lun',
'tue' => 'mar',
'wed' => 'mer',
'thu' => 'jeu',
'fri' => 'ven',
'sat' => 'sam',
'sun' => 'dim'
);

15
lib/lang/fr/config.php Normal file
View File

@ -0,0 +1,15 @@
<?php
/**
* Tzn Framework
*
* @package tzn_language
* @author Stan Ozier <framework@tirzen.com>
* @version 0.4
* @copyright GNU Lesser General Public License (LGPL) version 3
*/
$GLOBALS['config']['lang']['specialchars'] = 3;
$GLOBALS['config']['lang']['ucfirst'] = false;
setLocale(LC_ALL, 'fr_FR.UTF-8', 'fr_FR', 'fr');

View File

@ -4,7 +4,7 @@
* *
* @package tzn_models * @package tzn_models
* @author Stan Ozier <framework@tirzen.com> * @author Stan Ozier <framework@tirzen.com>
* @version 0.2 * @version 0.4
* @since 0.1 * @since 0.1
* @copyright GNU Lesser General Public License (LGPL) version 3 * @copyright GNU Lesser General Public License (LGPL) version 3
*/ */
@ -86,38 +86,18 @@ abstract class UserModel extends Model {
'abcdefghijklmnopqrstuvwxyz' 'abcdefghijklmnopqrstuvwxyz'
.'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')); .'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'));
if ($pass1) { if ($pass1) {
if ((strlen($pass1) >= APP_USER_PASS_MIN) $arr = explode(',',$this->_properties[$key]);
&& (strlen($pass1) <= APP_USER_PASS_MAX)) $class = array_shift($arr);
if (VarPss::checkValid($pass1, $arr))
{ {
$salt = $this->get('salt'); $this->setRawPassword($pass1, $this->get('salt'));
switch (APP_AUTH_PASSWORD_MODE) {
case 1:
$this->set('password',crypt($pass1 , $salt));
break;
case 2:
$this->set('password',AuthHelper::getDbPass("ENCRYPT('$pass1','$salt')"));
break;
case 3:
$this->set('password',AuthHelper::getDbPass("ENCODE('$pass1','$salt')"));
break;
case 4:
case 5:
$this->set('password',AuthHelper::getDbPass("MD5('$pass1')"));
break;
default:
$iv = mcrypt_create_iv (mcrypt_get_iv_size(MCRYPT_3DES
, MCRYPT_MODE_ECB), MCRYPT_RAND);
$crypttext = mcrypt_encrypt(APP_AUTH_PASSWORD_MODE, $salt
, $pass1, MCRYPT_MODE_ECB, $iv);
$this->set('password',bin2hex($crypttext));
}
} else { } else {
$this->_error['password'] = 'user_pass_length'; $this->_error['password'] = 'user_pass_length';
return false; return false;
} }
} else { } else {
$this->set('password',''); $this->data['password'] = '';
} }
return true; return true;
} else { } else {
@ -129,6 +109,31 @@ abstract class UserModel extends Model {
} }
} }
public function setRawPassword($pass, $salt) {
switch (APP_AUTH_PASSWORD_MODE) {
case 1:
$this->data['password'] = crypt($pass , $salt);
break;
case 2:
$this->data['password'] = AuthHelper::getDbPass("ENCRYPT('$pass','$salt')");
break;
case 3:
$this->data['password'] = AuthHelper::getDbPass("ENCODE('$pass','$salt')");
break;
case 4:
case 5:
$this->data['password'] = AuthHelper::getDbPass("MD5('$pass')");
break;
default:
$iv = mcrypt_create_iv (mcrypt_get_iv_size(MCRYPT_3DES
, MCRYPT_MODE_ECB), MCRYPT_RAND);
$crypttext = mcrypt_encrypt(APP_AUTH_PASSWORD_MODE, $salt
, $pass, MCRYPT_MODE_ECB, $iv);
$this->data['password'] = bin2hex($crypttext);
break;
}
}
public function setupTimeZone() { public function setupTimeZone() {
if (!$this->isEmpty('time_zone')) { if (!$this->isEmpty('time_zone')) {
try { try {

View File

@ -113,31 +113,64 @@ img.frgt {
text-align: right; text-align: right;
width: 150px; width: 150px;
} }
#dtop ul { #dtop #duser p a {
padding: 12px 0 0 0;
height: 28px;
}
#dtop ul li {
float: left;
list-style: none;
margin-right: 8px;
padding: 0 0 8px 10px;
height: 20px;
}
#dtop ul li.active {
background: url(../img/top-tab.png) no-repeat left 0;
}
#dtop ul li a {
display: block;
color: #fff;
text-decoration: none; text-decoration: none;
padding: 6px 10px 0 0;
} }
#dtop ul li a:hover { #dtop #duser p a:hover {
color: #fff;
} }
#dtop ul li.active a { #dtop #duser p a small {
color: #9cf;
}
#dtop #duser p a:hover small {
color: #cce3ff;
}
#dtop #duser ul {
top: 20px;
background-color: #ccc;
border: 1px solid #999;
margin: 0;
padding: 0;
position: absolute;
right: 5px;
min-width: 150px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-border-top-right-radius: 0;
-moz-border-radius-topright: 0;
border-radius: 5px 0 5px 5px;
}
#dtop #duser ul#dmenu {
display: none;
}
#dtop #duser ul li {
font-size: 11px;
list-style: none;
padding: 0;
text-align: left;
}
#dtop #duser ul li a {
color: #333;
display: block;
text-decoration: none;
padding: 2px 4px;
}
#dtop #duser ul li:first-child a {
-webkit-border-top-left-radius: 5px;
-moz-border-radius-topleft: 5px;
border-radius: 5px 0 0 0;
}
#dtop #duser ul li:last-child a {
-webkit-border-bottom-left-radius: 5px;
-webkit-border-bottom-right-radius: 5px;
-moz-border-radius-bottomleft: 5px;
-moz-border-radius-bottomright: 5px;
border-radius: 0 0 5px 5px;
}
#dtop #duser ul li a:hover {
background-color: #fff;
color: #000; color: #000;
background: url(../img/top-tab.png) no-repeat right 0;
} }
/* search form */ /* search form */
form#search p { form#search p {

View File

@ -3,9 +3,9 @@
position: absolute; position: absolute;
top: 0; top: 0;
left: 50%; left: 50%;
margin-left: -250px; margin-left: -220px;
padding: 6px 10px; padding: 6px 10px;
width: 500px; width: 440px;
color: #036; color: #036;
background-color: transparent; background-color: transparent;
z-index: 10; z-index: 10;
@ -40,7 +40,7 @@
} }
#drun p input { #drun p input {
color: #036; color: #036;
width: 300px; width: 340px;
border: 0; border: 0;
padding: 2px 5px 3px; padding: 2px 5px 3px;
background-color: #39c; background-color: #39c;
@ -66,9 +66,15 @@
float: right; float: right;
} }
#drun button { #drun button {
opacity: 0.5; opacity: 0.85;
-moz-opacity: 0.5; -moz-opacity: 0.85;
filter: alpha(opacity=50); filter: alpha(opacity=85);
background: url(../img/buttons.png) no-repeat 0 0;
width: 34px;
height: 22px;
text-indent: -9999px;
overflow: hidden;
border: 0 none;
} }
#drun button:hover, #drun button:focus { #drun button:hover, #drun button:focus {
opacity: 1; opacity: 1;
@ -76,6 +82,24 @@
filter: alpha(opacity=100); filter: alpha(opacity=100);
outline: 0 none; outline: 0 none;
} }
#drun button#b_save {
}
#drun button#b_start {
background-position: -40px 0;
}
#drun button#b_resume {
background-position: -80px 0;
}
#drun button#b_pause {
background-position: -120px 0;
}
#drun button#b_stop {
background-position: -160px 0;
}
#drun button#b_close {
background-position: -200px 0;
}
#timerstatus.loading { #timerstatus.loading {
background: url(../img/barloader.gif) no-repeat center center; background: url(../img/barloader.gif) no-repeat center center;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB