More work in progress on roles. Implemented status edit for roles.
authorNik Okuntseff <support@anuko.com>
Sat, 24 Feb 2018 21:52:18 +0000 (21:52 +0000)
committerNik Okuntseff <support@anuko.com>
Sat, 24 Feb 2018 21:52:18 +0000 (21:52 +0000)
34 files changed:
WEB-INF/lib/ttRoleHelper.class.php
WEB-INF/lib/ttTaskHelper.class.php
WEB-INF/resources/ca.lang.php
WEB-INF/resources/cs.lang.php
WEB-INF/resources/da.lang.php
WEB-INF/resources/de.lang.php
WEB-INF/resources/en.lang.php
WEB-INF/resources/es.lang.php
WEB-INF/resources/et.lang.php
WEB-INF/resources/fa.lang.php
WEB-INF/resources/fi.lang.php
WEB-INF/resources/fr.lang.php
WEB-INF/resources/he.lang.php
WEB-INF/resources/hu.lang.php
WEB-INF/resources/it.lang.php
WEB-INF/resources/ja.lang.php
WEB-INF/resources/ko.lang.php
WEB-INF/resources/nl.lang.php
WEB-INF/resources/no.lang.php
WEB-INF/resources/pl.lang.php
WEB-INF/resources/pt-br.lang.php
WEB-INF/resources/pt.lang.php
WEB-INF/resources/ro.lang.php
WEB-INF/resources/ru.lang.php
WEB-INF/resources/sk.lang.php
WEB-INF/resources/sl.lang.php
WEB-INF/resources/sr.lang.php
WEB-INF/resources/sv.lang.php
WEB-INF/resources/tr.lang.php
WEB-INF/resources/zh-cn.lang.php
WEB-INF/resources/zh-tw.lang.php
WEB-INF/templates/footer.tpl
WEB-INF/templates/role_edit.tpl [new file with mode: 0644]
role_edit.php [new file with mode: 0644]

index 08e1a21..957bcda 100644 (file)
@@ -50,6 +50,42 @@ class ttRoleHelper {
     return false;
   }
 
+  // The getRoleByName looks up a role by name.
+  static function getRoleByName($role_name) {
+
+    $mdb2 = getConnection();
+    global $user;
+
+    $sql = "select id from tt_roless where team_id = $user->team_id and name = ".
+      $mdb2->quote($role_name)." and (status = 1 or status = 0)";
+    $res = $mdb2->query($sql);
+
+    if (!is_a($res, 'PEAR_Error')) {
+      $val = $res->fetchRow();
+      if ($val['id'])
+        return $val;
+    }
+    return false;
+  }
+
+  // update function updates a role in the database.
+  static function update($fields)
+  {
+    global $user;
+    $mdb2 = getConnection();
+
+    $id = (int)$fields['id'];
+    $name = $fields['name'];
+    $description = $fields['description'];
+    $status = (int)$fields['status'];
+    // TODO: add rights later when we have them.
+
+    $sql = "update tt_roles set name = ".$mdb2->quote($name).", description = ".$mdb2->quote($description).
+      ", status = $status where id = $id and team_id = $user->team_id";
+    $affected = $mdb2->exec($sql);
+    return (!is_a($affected, 'PEAR_Error'));
+  }
+
   // delete - marks the role as deleted.
   static function delete($role_id) {
     global $user;
index d238bfb..2bb99da 100644 (file)
@@ -79,13 +79,12 @@ class ttTaskHelper {
 
     $sql = "select id from tt_tasks where team_id = $user->team_id and name = ".
       $mdb2->quote($task_name)." and (status = 1 or status = 0)";
-       $res = $mdb2->query($sql);
+      $res = $mdb2->query($sql);
 
-       if (!is_a($res, 'PEAR_Error')) {
+      if (!is_a($res, 'PEAR_Error')) {
       $val = $res->fetchRow();
-         if ($val['id']) {
+      if ($val['id'])
         return $val;
-      }
     }
     return false;
   }
@@ -185,7 +184,7 @@ class ttTaskHelper {
     return $last_id;
   }
  
- // update function updates a task in database.
+ // update function updates a task in the database.
   static function update($fields)
   {
     global $user;
index 3ea8edc..4fe1148 100644 (file)
@@ -92,6 +92,7 @@ $i18n_key_words = array(
 'error.auth' => 'Usuari o parula de pas incorrecta.',
 // TODO: translate the following.
 // 'error.user_exists' => 'User with this login already exists.',
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Ja existeix un projecte amb aquest nom.',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index e7e7318..5a04757 100644 (file)
@@ -94,6 +94,7 @@ $i18n_key_words = array(
 'error.auth' => 'Nesprávné jméno nebo heslo.',
 // TODO: translate the following.
 // 'error.user_exists' => 'User with this login already exists.',
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Projekt tohoto jména již existuje.',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index 177b2d1..b5ec4b2 100644 (file)
@@ -80,6 +80,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'Forkert brugernavn eller adgangskode.',
 'error.user_exists' => 'Brugernavn eksistere allerede.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Der eksiterer allerede et projekt med det navn.',
 'error.task_exists' => 'Opgavenavn eksistere allerede.',
 'error.client_exists' => 'Der eksistere allerede en klient med dette navn.',
index ea9460e..3cd9568 100644 (file)
@@ -80,6 +80,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'Benutzername oder Passwort ungültig.',
 'error.user_exists' => 'Benutzer mit diesem Konto ist bereits vorhanden.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Es gibt bereits ein Projekt mit diesem Namen.',
 'error.task_exists' => 'Task mit diesem Namen existiert bereits.',
 'error.client_exists' => 'Der Kunde mit dem Namen existiert schon.',
index 6ddf977..408c039 100644 (file)
@@ -80,6 +80,7 @@ $i18n_key_words = array(
 'error.record' => 'Select record.',
 'error.auth' => 'Incorrect login or password.',
 'error.user_exists' => 'User with this login already exists.',
+'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Project with this name already exists.',
 'error.task_exists' => 'Task with this name already exists.',
 'error.client_exists' => 'Client with this name already exists.',
index 069527d..7e61892 100644 (file)
@@ -90,6 +90,7 @@ $i18n_key_words = array(
 'error.auth' => 'Usuario o contraseña incorrecta.',
 // TODO: translate the following.
 // 'error.user_exists' => 'User with this login already exists.',
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Ya existe un proyecto con este nombre.',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index 01aefb2..b572ae9 100644 (file)
@@ -94,6 +94,7 @@ $i18n_key_words = array(
 'error.auth' => 'Vale login või salasõna.',
 // TODO: translate the following.
 // 'error.user_exists' => 'User with this login already exists.',
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Selle nimega projekt on juba olemas.',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index 8b02375..020b403 100644 (file)
@@ -86,6 +86,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'نام کاربری یا رمز عبور اشتباه است.',
 'error.user_exists' => 'کاربری با این نام کاربری موجود است.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'پروژه ای با این نام موجود است.',
 'error.task_exists' => 'وظیفه ای با این نام هم اکنون وجود دارد.',
 'error.client_exists' => 'مشتری با این نام هم اکنون وجود دارد.',
index 68e953a..c608cb8 100644 (file)
@@ -82,6 +82,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'Virheellinen käyttäjänimi tai salasana.',
 'error.user_exists' => 'Tämä käyttäjänimi on jo olemassa.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Tämän niminen projekti on jo olemassa.',
 'error.task_exists' => 'Tämän niminen tehtävä on jo olemassa.',
 'error.client_exists' => 'Tämän niminen asiakas on jo olemassa.',
index e22f856..76457f3 100644 (file)
@@ -80,6 +80,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'Nom d\\\'utilisateur ou mot de passe incorrect.',
 'error.user_exists' => 'Un utilisateur avec cet identifiant existe déjà.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Un projet avec ce nom existe déjà.',
 'error.task_exists' => 'Une tâche avec ce nom existe déjà.',
 'error.client_exists' => 'Un client avec ce nom existe déjà.',
index 1c7d48d..9a3a14a 100644 (file)
@@ -96,6 +96,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'שם משתמש או סיסמה שגויים',
 'error.user_exists' => 'שם משתמש כבר קיים',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'שם פרוייקט כבר קיים',
 'error.task_exists' => 'קיימת משימה עם שם דומה',
 'error.client_exists' => 'שם לקוח כבר קיים',
index 9704884..88db668 100644 (file)
@@ -91,6 +91,7 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 // 'error.auth' => 'Incorrect login or password.',
 // 'error.user_exists' => 'User with this login already exists.',
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Ilyen nevű projekt már létezik.',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index 141a6f8..37407a9 100644 (file)
@@ -81,6 +81,8 @@ $i18n_key_words = array(
 'error.record' => 'Seleziona record.',
 'error.auth' => 'Login o password errati.',
 'error.user_exists' => 'Esiste già un utente con questo username.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Esiste già un progetto con questo nome.',
 'error.task_exists' => 'Esiste già un compito con questo nome.',
 'error.client_exists' => 'Esiste già un cliente con questo nome.',
index 42c2f10..0c857f9 100644 (file)
@@ -91,6 +91,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => '不正確なログインあるいはパスワードが不正確です。',
 'error.user_exists' => 'このログインと関連されたユーザーは既に存在します。',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'この名前のプロジェクトは既に存在します。',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index 005fb34..115cfe0 100644 (file)
@@ -91,6 +91,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => '부정확한 로그인 혹은 암호가 틀립니다.',
 'error.user_exists' => '본 로그인과 연계된 사용자가 이미 있습니다.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => '본 이름과 연계된 프로젝트가 이미 있습니다.',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index 36ab344..9cc82c8 100644 (file)
@@ -79,6 +79,8 @@ $i18n_key_words = array(
 'error.record' => 'Selecteer record.', // TODO: why not Kies as above?
 'error.auth' => 'Onjuiste inlognaam of wachtwoord.',
 'error.user_exists' => 'Een gebruiker met deze inlognaam bestaat al.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Een project met deze naam bestaat al.',
 'error.task_exists' => 'Er bestaat al een taak met deze naam.',
 'error.client_exists' => 'Een klant met deze naam bestaat al.',
index c7573be..a369452 100644 (file)
@@ -90,6 +90,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'Feil brukernavn eller passord.',
 'error.user_exists' => 'Bruker med et slikt brukernavn eksisterer allerede.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Et prosjekt med dette navnet er allerede opprettet.',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index a91a754..27466aa 100644 (file)
@@ -83,6 +83,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'Błędny login lub hasło.',
 'error.user_exists' => 'Użytkownik o takiej nazwie już istnieje.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Projekt o takiej nazwie już istnieje.',
 'error.task_exists' => 'Zadanie o takiej nazwie już istnieje.',
 'error.client_exists' => 'Klient o takiej nazwie już istnieje.',
index aecc222..f6e7448 100644 (file)
@@ -81,6 +81,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'Usuário ou senha incorretos.',
 'error.user_exists' => 'Já existe usuário com este login.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Já existe projeto com este nome.',
 'error.task_exists' => 'Já existe tarefa com este nome.',
 'error.client_exists' => 'Já existe cliente com este nome.',
index 6aeed5e..2a4f3a1 100644 (file)
@@ -91,6 +91,7 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 // 'error.auth' => 'Incorrect login or password.',
 // 'error.user_exists' => 'User with this login already exists.',
+// 'error.object_exists' => 'Object with this name already exists.',
 // 'error.project_exists' => 'Project with this name already exists.',
 // 'error.task_exists' => 'Task with this name already exists.',
 // 'error.client_exists' => 'Client with this name already exists.',
index 9dd29a1..c9893fa 100644 (file)
@@ -97,6 +97,7 @@ $i18n_key_words = array(
 'error.auth' => 'Nume de utilizator sau parola incorecta.',
 // TODO: translate the following.
 // 'error.user_exists' => 'User with this login already exists.',
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Proiectul cu acest nume exista deja.',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index 84a7e4c..e84243a 100644 (file)
@@ -79,6 +79,7 @@ $i18n_key_words = array(
 'error.record' => 'Выберите запись.',
 'error.auth' => 'Неправильно введен логин или пароль.',
 'error.user_exists' => 'Пользователь с таким логином уже существует.',
+'error.object_exists' => 'Объект с таким именем уже есть.',
 'error.project_exists' => 'Проект с таким именем уже есть.',
 'error.task_exists' => 'Задача с таким названием уже есть.',
 'error.client_exists' => 'Клиент с таким именем уже есть.',
index 90b8b0a..f1a6d41 100644 (file)
@@ -85,6 +85,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'Nesprávne prihlasovacie meno alebo heslo.',
 'error.user_exists' => 'Používateľ s týmto prihlasovacím menom už existuje.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Projekt s týmto názvom už existuje.',
 'error.task_exists' => 'Úloha s týmto názvom už existuje.',
 'error.client_exists' => 'Klient s týmto menom už existuje.',
index 7222889..689fcca 100644 (file)
@@ -90,6 +90,7 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 // 'error.auth' => 'Incorrect login or password.',
 // 'error.user_exists' => 'User with this login already exists.',
+// 'error.object_exists' => 'Object with this name already exists.',
 // 'error.project_exists' => 'Project with this name already exists.',
 // 'error.task_exists' => 'Task with this name already exists.',
 // 'error.client_exists' => 'Client with this name already exists.',
index 5137ef3..bf1e605 100644 (file)
@@ -80,6 +80,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'Pogrešno korisničko ime ili lozinka.',
 'error.user_exists' => 'Korisnik pod ovim imenom već postoji.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Projekat pod ovim nazivom već postoji.',
 'error.task_exists' => 'Zadatak pod ovim nazivom već postoji.',
 'error.client_exists' => 'Klijent pod ovim imenom već postoji.',
index ba55c2c..f75436d 100644 (file)
@@ -81,6 +81,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => 'Ogiltigt användarnamn eller lösenord.',
 'error.user_exists' => 'Det finns redan en användare med det här användarnamnet.',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Det finns redan ett projekt med det här namnet.',
 'error.task_exists' => 'Det finns redan en arbetsuppgift med det här namnet.',
 'error.client_exists' => 'Det finns redan en kund med det här namnet.',
index 8a9f197..54b4d83 100644 (file)
@@ -99,6 +99,7 @@ $i18n_key_words = array(
 'error.auth' => 'Hatalı kullanıcı adı veya parola.',
 // TODO: translate the following.
 // 'error.user_exists' => 'User with this login already exists.',
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => 'Bu isimde proje zaten vardır.',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index ae04c02..a1700c9 100644 (file)
@@ -83,6 +83,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => '不正确的用户名或密码。',
 'error.user_exists' => '该用户登录信息已经存在。',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => '该项目名称已经存在。',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index 8424008..f0675a6 100644 (file)
@@ -89,6 +89,8 @@ $i18n_key_words = array(
 // 'error.record' => 'Select record.',
 'error.auth' => '不正確的用戶名或密碼。',
 'error.user_exists' => '該使用者登錄資訊已經存在。',
+// TODO: translate the following.
+// 'error.object_exists' => 'Object with this name already exists.',
 'error.project_exists' => '該專案名稱已經存在。',
 // TODO: translate the following.
 // 'error.task_exists' => 'Task with this name already exists.',
index f377346..6c2702e 100644 (file)
@@ -12,7 +12,7 @@
       <br>
       <table cellspacing="0" cellpadding="4" width="100%" border="0">
         <tr>
-          <td align="center">&nbsp;Anuko Time Tracker 1.17.32.4026 | Copyright &copy; <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
+          <td align="center">&nbsp;Anuko Time Tracker 1.17.32.4027 | Copyright &copy; <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
             <a href="https://www.anuko.com/lp/tt_4.htm" target="_blank">{$i18n.footer.credits}</a> |
             <a href="https://www.anuko.com/lp/tt_5.htm" target="_blank">{$i18n.footer.license}</a> |
             <a href="https://www.anuko.com/lp/tt_7.htm" target="_blank">{$i18n.footer.improve}</a>
diff --git a/WEB-INF/templates/role_edit.tpl b/WEB-INF/templates/role_edit.tpl
new file mode 100644 (file)
index 0000000..7a20d6a
--- /dev/null
@@ -0,0 +1,33 @@
+{$forms.roleForm.open}
+<table cellspacing="4" cellpadding="7" border="0">
+  <tr>
+    <td>
+      <table cellspacing="1" cellpadding="2" border="0">
+        <tr>
+          <td align="right">{$i18n.label.thing_name} (*):</td>
+          <td>{$forms.roleForm.name.control}</td>
+        </tr>
+        <tr>
+          <td align = "right">{$i18n.label.description}:</td>
+          <td>{$forms.roleForm.description.control}</td>
+        </tr>
+        <tr>
+          <td align = "right">{$i18n.label.status}:</td>
+          <td>{$forms.roleForm.status.control}</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>{$i18n.label.required_fields}</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>&nbsp;</td>
+        </tr>
+        <tr>
+          <td colspan="2" align="center" height="50">{$forms.roleForm.btn_save.control}</td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+{$forms.roleForm.close}
diff --git a/role_edit.php b/role_edit.php
new file mode 100644 (file)
index 0000000..94d47e6
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+// +----------------------------------------------------------------------+
+// | Anuko Time Tracker
+// +----------------------------------------------------------------------+
+// | Copyright (c) Anuko International Ltd. (https://www.anuko.com)
+// +----------------------------------------------------------------------+
+// | LIBERAL FREEWARE LICENSE: This source code document may be used
+// | by anyone for any purpose, and freely redistributed alone or in
+// | combination with other software, provided that the license is obeyed.
+// |
+// | There are only two ways to violate the license:
+// |
+// | 1. To redistribute this code in source form, with the copyright
+// |    notice or license removed or altered. (Distributing in compiled
+// |    forms without embedded copyright notices is permitted).
+// |
+// | 2. To redistribute modified versions of this code in *any* form
+// |    that bears insufficient indications that the modifications are
+// |    not the work of the original author(s).
+// |
+// | This license applies to this document only, not any other software
+// | that it may be combined with.
+// |
+// +----------------------------------------------------------------------+
+// | Contributors:
+// | https://www.anuko.com/time_tracker/credits.htm
+// +----------------------------------------------------------------------+
+
+require_once('initialize.php');
+import('form.Form');
+import('ttTeamHelper'); // TODO: remove this?
+import('ttTaskHelper'); // TODO: remove this?
+import('ttRoleHelper');
+
+// Access check.
+if (!ttAccessCheck(right_manage_team)) {
+  header('Location: access_denied.php');
+  exit();
+}
+
+$cl_role_id = (int)$request->getParameter('id');
+
+if ($request->isPost()) {
+  $cl_name = trim($request->getParameter('name'));
+  $cl_description = trim($request->getParameter('description'));
+  $cl_status = $request->getParameter('status');
+} else {
+  $role = ttRoleHelper::get($cl_role_id);
+  $cl_name = $role['name'];
+  $cl_description = $role['description'];
+  $cl_status = $role['status'];
+}
+
+$form = new Form('roleForm');
+$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_role_id));
+$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name));
+$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description));
+$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,
+  'data'=>array(ACTIVE=>$i18n->getKey('dropdown.status_active'),INACTIVE=>$i18n->getKey('dropdown.status_inactive'))));
+$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save')));
+
+if ($request->isPost()) {
+  // Validate user input.
+  if (!ttValidString($cl_name)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.thing_name'));
+  if (!ttValidString($cl_description, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.description'));
+
+  if ($err->no()) {
+    $existing_role = ttRoleHelper::getRoleByName($cl_name);
+    if (!$existing_role || ($cl_role_id == $existing_role['id'])) {
+      // Update role information.
+      if (ttRoleHelper::update(array(
+        'id' => $cl_role_id,
+        'name' => $cl_name,
+        'description' => $cl_description,
+        'status' => $cl_status))) {
+        header('Location: roles.php');
+        exit();
+      } else
+        $err->add($i18n->getKey('error.db'));
+    } else
+      $err->add($i18n->getKey('error.object_exists'));
+  }
+} // isPost
+
+$smarty->assign('forms', array($form->getName()=>$form->toArray()));
+$smarty->assign('title', $i18n->getKey('title.edit_role'));
+$smarty->assign('content_page_name', 'role_edit.tpl');
+$smarty->display('index.tpl');