浏览代码

Contacts: Added Times/Timer to track support.

Nate Jones 10 年之前
父节点
当前提交
2b852c34d2
共有 10 个文件被更改,包括 1094 次插入2 次删除
  1. 59 0
      app_config.php
  2. 153 0
      app_languages.php
  3. 22 1
      contact_edit.php
  4. 1 1
      contact_settings.php
  5. 63 0
      contact_time_delete.php
  6. 231 0
      contact_time_edit.php
  7. 372 0
      contact_timer.php
  8. 56 0
      contact_timer_inc.php
  9. 137 0
      contact_times.php
  10. 二进制
      resources/images/icon_timer.png

+ 59 - 0
app_config.php

@@ -169,6 +169,20 @@
 		$apps[$x]['permissions'][$y]['name'] = "contact_extension_view";
 		$apps[$x]['permissions'][$y]['name'] = "contact_extension_view";
 		$apps[$x]['permissions'][$y]['groups'][] = "superadmin";
 		$apps[$x]['permissions'][$y]['groups'][] = "superadmin";
 		$apps[$x]['permissions'][$y]['groups'][] = "admin";
 		$apps[$x]['permissions'][$y]['groups'][] = "admin";
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'contact_time_view';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'contact_time_add';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'contact_time_edit';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		$y++;
+		$apps[$x]['permissions'][$y]['name'] = 'contact_time_delete';
+		$apps[$x]['permissions'][$y]['groups'][] = 'superadmin';
+		$y++;
+
 
 
 	//schema details
 	//schema details
 		$y = 0; //table array index
 		$y = 0; //table array index
@@ -699,4 +713,49 @@
 		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "Enter the URL description.";
 		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "Enter the URL description.";
 		$z++;
 		$z++;
 
 
+		$y = 9; //table array index
+		$apps[$x]['db'][$y]['table'] = 'v_contact_times';
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'domain_uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'foreign';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['table'] = 'v_domains';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['field'] = 'domain_uuid';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'contact_time_uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'primary';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'contact_uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'foreign';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['table'] = 'v_contact';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['field'] = 'contact_uuid';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'user_uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = 'uuid';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = 'char(36)';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['type'] = 'foreign';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['table'] = 'v_users';
+		$apps[$x]['db'][$y]['fields'][$z]['key']['reference']['field'] = 'user_uuid';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'time_start';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'timestamp';
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = 'Start';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'time_stop';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'timestamp';
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = 'Stop';
+		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = 'time_description';
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = 'text';
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = 'Description';
+		$z++;
+
 ?>
 ?>

+ 153 - 0
app_languages.php

@@ -27,6 +27,24 @@ $text['title-contacts']['pl'] = "Kontakty";
 $text['title-contacts']['uk'] = "Контакти";
 $text['title-contacts']['uk'] = "Контакти";
 $text['title-contacts']['sv-se'] = "Kontakter";
 $text['title-contacts']['sv-se'] = "Kontakter";
 
 
+$text['title-contact_time_edit']['en-us'] = "Time Edit";
+$text['title-contact_time_edit']['es-cl'] = "Tiempo de Redacción";
+$text['title-contact_time_edit']['pt-pt'] = "Tempo Editar";
+$text['title-contact_time_edit']['fr-fr'] = "Modifier Temps";
+$text['title-contact_time_edit']['pt-br'] = "Tempo Editar";
+$text['title-contact_time_edit']['pl'] = "Czas Edycja";
+$text['title-contact_time_edit']['uk'] = "час Редагувати";
+$text['title-contact_time_edit']['sv-se'] = "Redigera Tid";
+
+$text['title-contact_time_add']['en-us'] = "Time Add";
+$text['title-contact_time_add']['es-cl'] = "Tiempo Agregar";
+$text['title-contact_time_add']['pt-pt'] = "Time Adicionar";
+$text['title-contact_time_add']['fr-fr'] = "Ajouter Temps";
+$text['title-contact_time_add']['pt-br'] = "Time Adicionar";
+$text['title-contact_time_add']['pl'] = "Czas Dodawania";
+$text['title-contact_time_add']['uk'] = "час додавання";
+$text['title-contact_time_add']['sv-se'] = "Time Lägg";
+
 $text['title-contact_setting_edit']['en-us'] = "Contact Setting Edit";
 $text['title-contact_setting_edit']['en-us'] = "Contact Setting Edit";
 $text['title-contact_setting_edit']['es-cl'] = "Configuraciones de contacto";
 $text['title-contact_setting_edit']['es-cl'] = "Configuraciones de contacto";
 $text['title-contact_setting_edit']['pt-pt'] = "Definições do Contacto";
 $text['title-contact_setting_edit']['pt-pt'] = "Definições do Contacto";
@@ -593,6 +611,69 @@ $text['label-true']['pl'] = "Tak";
 $text['label-true']['uk'] = "Так";
 $text['label-true']['uk'] = "Так";
 $text['label-true']['sv-se'] = "Sann";
 $text['label-true']['sv-se'] = "Sann";
 
 
+$text['label-time_user']['en-us'] = "User";
+$text['label-time_user']['es-cl'] = "Usuario";
+$text['label-time_user']['pt-pt'] = "Usuário";
+$text['label-time_user']['fr-fr'] = "Utilisateur";
+$text['label-time_user']['pt-br'] = "Usuário";
+$text['label-time_user']['pl'] = "Użytkownik";
+$text['label-time_user']['uk'] = "Користувач";
+$text['label-time_user']['sv-se'] = "Användare";
+
+$text['label-time_timer']['en-us'] = "Timer";
+$text['label-time_timer']['es-cl'] = "Timer";
+$text['label-time_timer']['pt-pt'] = "Cronômetro";
+$text['label-time_timer']['fr-fr'] = "Minuteur";
+$text['label-time_timer']['pt-br'] = "Cronômetro";
+$text['label-time_timer']['pl'] = "Regulator Czasowy";
+$text['label-time_timer']['uk'] = "таймер";
+$text['label-time_timer']['sv-se'] = "Timer";
+
+$text['label-time_time']['en-us'] = "Time";
+$text['label-time_time']['es-cl'] = "Tiempo";
+$text['label-time_time']['pt-pt'] = "Tempo";
+$text['label-time_time']['fr-fr'] = "Temps";
+$text['label-time_time']['pt-br'] = "Tempo";
+$text['label-time_time']['pl'] = "Czas";
+$text['label-time_time']['uk'] = "час";
+$text['label-time_time']['sv-se'] = "Tid";
+
+$text['label-time_duration']['en-us'] = "Duration";
+$text['label-time_duration']['es-cl'] = "Duración";
+$text['label-time_duration']['pt-pt'] = "Duração";
+$text['label-time_duration']['fr-fr'] = "Durée";
+$text['label-time_duration']['pt-br'] = "Duração";
+$text['label-time_duration']['pl'] = "Czas Trwania";
+$text['label-time_duration']['uk'] = "тривалість";
+$text['label-time_duration']['sv-se'] = "Varaktighet";
+
+$text['label-time_stop']['en-us'] = "Stop";
+$text['label-time_stop']['es-cl'] = "Deténgase";
+$text['label-time_stop']['pt-pt'] = "Pare";
+$text['label-time_stop']['fr-fr'] = "Stop";
+$text['label-time_stop']['pt-br'] = "Pare";
+$text['label-time_stop']['pl'] = "Stop";
+$text['label-time_stop']['uk'] = "стоп";
+$text['label-time_stop']['sv-se'] = "Stanna";
+
+$text['label-time_start']['en-us'] = "Start";
+$text['label-time_start']['es-cl'] = "Comienzo";
+$text['label-time_start']['pt-pt'] = "Começo";
+$text['label-time_start']['fr-fr'] = "Début";
+$text['label-time_start']['pt-br'] = "Começo";
+$text['label-time_start']['pl'] = "Początek";
+$text['label-time_start']['uk'] = "початок";
+$text['label-time_start']['sv-se'] = "Start";
+
+$text['label-time_description']['en-us'] = "Description";
+$text['label-time_description']['es-cl'] = "Descripción";
+$text['label-time_description']['pt-pt'] = "Descrição";
+$text['label-time_description']['fr-fr'] = "Description";
+$text['label-time_description']['pt-br'] = "Descrição";
+$text['label-time_description']['pl'] = "Opis";
+$text['label-time_description']['uk'] = "Опис";
+$text['label-time_description']['sv-se'] = "Beskrivning";
+
 $text['label-text']['en-us'] = "Text";
 $text['label-text']['en-us'] = "Text";
 $text['label-text']['es-cl'] = "Texto";
 $text['label-text']['es-cl'] = "Texto";
 $text['label-text']['pt-pt'] = "Texto";
 $text['label-text']['pt-pt'] = "Texto";
@@ -1355,6 +1436,33 @@ $text['header-contact_url-add']['pl'] = "Dodaj kontakt URL ";
 $text['header-contact_url-add']['uk'] = "";
 $text['header-contact_url-add']['uk'] = "";
 $text['header-contact_url-add']['sv-se'] = "Lägg Till Kontakt URL";
 $text['header-contact_url-add']['sv-se'] = "Lägg Till Kontakt URL";
 
 
+$text['header_contact_times']['en-us'] = "Times";
+$text['header_contact_times']['es-cl'] = "Veces";
+$text['header_contact_times']['pt-pt'] = "Vezes";
+$text['header_contact_times']['fr-fr'] = "Fois";
+$text['header_contact_times']['pt-br'] = "Vezes";
+$text['header_contact_times']['pl'] = "Czasy";
+$text['header_contact_times']['uk'] = "раз";
+$text['header_contact_times']['sv-se'] = "Gånger";
+
+$text['header-contact_time_edit']['en-us'] = "Time Edit";
+$text['header-contact_time_edit']['es-cl'] = "Tiempo de Redacción";
+$text['header-contact_time_edit']['pt-pt'] = "Tempo Editar";
+$text['header-contact_time_edit']['fr-fr'] = "Modifier Temps";
+$text['header-contact_time_edit']['pt-br'] = "Tempo Editar";
+$text['header-contact_time_edit']['pl'] = "Czas Edycja";
+$text['header-contact_time_edit']['uk'] = "час Редагувати";
+$text['header-contact_time_edit']['sv-se'] = "Redigera Tid";
+
+$text['header-contact_time_add']['en-us'] = "Time Add";
+$text['header-contact_time_add']['es-cl'] = "Tiempo Agregar";
+$text['header-contact_time_add']['pt-pt'] = "Time Adicionar";
+$text['header-contact_time_add']['fr-fr'] = "Ajouter Temps";
+$text['header-contact_time_add']['pt-br'] = "Time Adicionar";
+$text['header-contact_time_add']['pl'] = "Czas Dodawania";
+$text['header-contact_time_add']['uk'] = "час додавання";
+$text['header-contact_time_add']['sv-se'] = "Time Lägg";
+
 $text['header-contact_setting_edit']['en-us'] = "Contact Setting Edit";
 $text['header-contact_setting_edit']['en-us'] = "Contact Setting Edit";
 $text['header-contact_setting_edit']['es-cl'] = "Configuraciones de contacto";
 $text['header-contact_setting_edit']['es-cl'] = "Configuraciones de contacto";
 $text['header-contact_setting_edit']['pt-pt'] = "Definições do Contacto";
 $text['header-contact_setting_edit']['pt-pt'] = "Definições do Contacto";
@@ -1488,6 +1596,15 @@ $text['description-url_primary']['pl'] = "Ustaw jako podstawowy adres URL dla te
 $text['description-url_primary']['uk'] = "";
 $text['description-url_primary']['uk'] = "";
 $text['description-url_primary']['sv-se'] = "Ställ in som primär URL för denna kontakt.";
 $text['description-url_primary']['sv-se'] = "Ställ in som primär URL för denna kontakt.";
 
 
+$text['description_timer']['en-us'] = "Stop the Timer before closing the window, if desired.";
+$text['description_timer']['es-cl'] = "Detenga el temporizador antes de cerrar la ventana, si se desea.";
+$text['description_timer']['pt-pt'] = "Parar o temporizador antes de fechar a janela, se desejar.";
+$text['description_timer']['fr-fr'] = "Arrêter le retardateur avant la fermeture de la fenêtre, si désiré.";
+$text['description_timer']['pt-br'] = "Parar o temporizador antes de fechar a janela, se desejar.";
+$text['description_timer']['pl'] = "Zatrzymac samowyzwalacz przed zamknieciem okna, w razie potrzeby.";
+$text['description_timer']['uk'] = "Зупинити таймер перед закриттям вікна, якщо це необхідно.";
+$text['description_timer']['sv-se'] = "Stoppa timer innan du stänger fönstret, om så önskas.";
+
 $text['description-shared_import']['en-us'] = "Share contacts with other users on the domain.";
 $text['description-shared_import']['en-us'] = "Share contacts with other users on the domain.";
 $text['description-shared_import']['es-cl'] = "Comparte estos contactos con otros usuarios en el dominio.";
 $text['description-shared_import']['es-cl'] = "Comparte estos contactos con otros usuarios en el dominio.";
 $text['description-shared_import']['pt-pt'] = "Compartilhe estes contatos com outros usuários do domínio.";
 $text['description-shared_import']['pt-pt'] = "Compartilhe estes contatos com outros usuários do domínio.";
@@ -2089,6 +2206,42 @@ $text['button-upload']['pl'] = "Wyślij";
 $text['button-upload']['uk'] = "Завантажити";
 $text['button-upload']['uk'] = "Завантажити";
 $text['button-upload']['sv-se'] = "Ladda Upp";
 $text['button-upload']['sv-se'] = "Ladda Upp";
 
 
+$text['button-time']['en-us'] = "Time";
+$text['button-time']['es-cl'] = "Tiempo";
+$text['button-time']['pt-pt'] = "Tempo";
+$text['button-time']['fr-fr'] = "Temps";
+$text['button-time']['pt-br'] = "Tempo";
+$text['button-time']['pl'] = "Czas";
+$text['button-time']['uk'] = "час";
+$text['button-time']['sv-se'] = "Tid";
+
+$text['button-timer']['en-us'] = "Timer";
+$text['button-timer']['es-cl'] = "Timer";
+$text['button-timer']['pt-pt'] = "Cronômetro";
+$text['button-timer']['fr-fr'] = "Minuteur";
+$text['button-timer']['pt-br'] = "Cronômetro";
+$text['button-timer']['pl'] = "Regulator Czasowy";
+$text['button-timer']['uk'] = "таймер";
+$text['button-timer']['sv-se'] = "Timer";
+
+$text['button-stop']['en-us'] = "Stop";
+$text['button-stop']['es-cl'] = "Deténgase";
+$text['button-stop']['pt-pt'] = "Pare";
+$text['button-stop']['fr-fr'] = "Stop";
+$text['button-stop']['pt-br'] = "Pare";
+$text['button-stop']['pl'] = "Stop";
+$text['button-stop']['uk'] = "стоп";
+$text['button-stop']['sv-se'] = "Stanna";
+
+$text['button-start']['en-us'] = "Start";
+$text['button-start']['es-cl'] = "Comienzo";
+$text['button-start']['pt-pt'] = "Começo";
+$text['button-start']['fr-fr'] = "Début";
+$text['button-start']['pt-br'] = "Começo";
+$text['button-start']['pl'] = "Początek";
+$text['button-start']['uk'] = "початок";
+$text['button-start']['sv-se'] = "Start";
+
 $text['button-sign_out']['en-us'] = "Sign Out";
 $text['button-sign_out']['en-us'] = "Sign Out";
 $text['button-sign_out']['es-cl'] = "Desconectar";
 $text['button-sign_out']['es-cl'] = "Desconectar";
 $text['button-sign_out']['pt-pt'] = "Sair";
 $text['button-sign_out']['pt-pt'] = "Sair";

+ 22 - 1
contact_edit.php

@@ -17,7 +17,7 @@
 
 
 	The Initial Developer of the Original Code is
 	The Initial Developer of the Original Code is
 	Mark J Crane <[email protected]>
 	Mark J Crane <[email protected]>
-	Portions created by the Initial Developer are Copyright (C) 2008-2012
+	Portions created by the Initial Developer are Copyright (C) 2008-2015
 	the Initial Developer. All Rights Reserved.
 	the Initial Developer. All Rights Reserved.
 
 
 	Contributor(s):
 	Contributor(s):
@@ -338,6 +338,26 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) {
 	echo "<td valign='top' width='70%' align='right'>\n";
 	echo "<td valign='top' width='70%' align='right'>\n";
 	echo "	<input type='button' class='btn' name='' alt='".$text['button-back']."' onclick=\"window.location='contacts.php?".$_GET["query_string"]."'\" value='".$text['button-back']."'>\n";
 	echo "	<input type='button' class='btn' name='' alt='".$text['button-back']."' onclick=\"window.location='contacts.php?".$_GET["query_string"]."'\" value='".$text['button-back']."'>\n";
 	if ($action == "update") {
 	if ($action == "update") {
+		if (permission_exists('contact_time_add')) {
+			//detect timer state (and start time)
+			$sql = "select ";
+			$sql .= "time_start ";
+			$sql .= "from v_contact_times ";
+			$sql .= "where domain_uuid = '".$_SESSION['domain_uuid']."' ";
+			$sql .= "and user_uuid = '".$_SESSION['user']['user_uuid']."' ";
+			$sql .= "and contact_uuid = '".$contact_uuid."' ";
+			$sql .= "and time_start is not null ";
+			$sql .= "and time_stop is null ";
+			$prep_statement = $db->prepare(check_sql($sql));
+			$prep_statement->execute();
+			$result = $prep_statement->fetch(PDO::FETCH_NAMED);
+			if ($result['time_start'] != '') {
+				$time_start = $result['time_start'];
+				$btn_mod = "style='background-color: #a00; background-image: none;'";
+			}
+			unset ($sql, $prep_statement, $result);
+			echo "	<input type='button' class='btn' ".$btn_mod." alt='".$text['button-timer']."' ".(($time_start != '') ? "title='".$time_start."'" : null)." onclick=\"window.open('contact_timer.php?contact_uuid=".$contact_uuid."','contact_time_".$contact_uuid."','width=300, height=350, top=30, left='+(screen.width - 350)+', menubar=no, scrollbars=no, status=no, toolbar=no, resizable=no');\" value='".$text['button-timer']."'>\n";
+		}
 		echo "	<input type='button' class='btn' name='' alt='".$text['button-qr_code']."' onclick=\"$('#qr_code_container').fadeIn(400);\" value='".$text['button-qr_code']."'>\n";
 		echo "	<input type='button' class='btn' name='' alt='".$text['button-qr_code']."' onclick=\"$('#qr_code_container').fadeIn(400);\" value='".$text['button-qr_code']."'>\n";
 		echo "	<input type='button' class='btn' name='' alt='".$text['button-vcard']."' onclick=\"window.location='contacts_vcard.php?id=".$contact_uuid."&type=download'\" value='".$text['button-vcard']."'>\n";
 		echo "	<input type='button' class='btn' name='' alt='".$text['button-vcard']."' onclick=\"window.location='contacts_vcard.php?id=".$contact_uuid."&type=download'\" value='".$text['button-vcard']."'>\n";
 	}
 	}
@@ -706,6 +726,7 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) {
 		if (permission_exists('contact_extension_view')) { require "contact_extensions.php"; }
 		if (permission_exists('contact_extension_view')) { require "contact_extensions.php"; }
 		if (permission_exists('contact_relation_view')) { require "contact_relations.php"; }
 		if (permission_exists('contact_relation_view')) { require "contact_relations.php"; }
 		if (permission_exists('contact_note_view')) { require "contact_notes.php"; }
 		if (permission_exists('contact_note_view')) { require "contact_notes.php"; }
+		if (permission_exists('contact_time_view')) { require "contact_times.php"; }
 		if (permission_exists('contact_setting_view')) { require "contact_settings.php"; }
 		if (permission_exists('contact_setting_view')) { require "contact_settings.php"; }
 		echo "</td>\n";
 		echo "</td>\n";
 	}
 	}

+ 1 - 1
contact_settings.php

@@ -106,7 +106,7 @@ else {
 			echo "	</td>\n";
 			echo "	</td>\n";
 			echo "	<td valign='top' class='".$row_style[$c]."' style='text-align: center;'>".ucwords($row['contact_setting_enabled'])."&nbsp;</td>\n";
 			echo "	<td valign='top' class='".$row_style[$c]."' style='text-align: center;'>".ucwords($row['contact_setting_enabled'])."&nbsp;</td>\n";
 			echo "	<td valign='top' class='row_stylebg'>".$row['contact_setting_description']."&nbsp;</td>\n";
 			echo "	<td valign='top' class='row_stylebg'>".$row['contact_setting_description']."&nbsp;</td>\n";
-			echo "	<td class='list_control_icons'>";
+			echo "	<td class='list_control_icons' nowrap>";
 			if (permission_exists('contact_setting_edit')) {
 			if (permission_exists('contact_setting_edit')) {
 				echo "<a href='contact_setting_edit.php?contact_uuid=".$row['contact_uuid']."&id=".$row['contact_setting_uuid']."' alt='".$text['button-edit']."'>$v_link_label_edit</a>";
 				echo "<a href='contact_setting_edit.php?contact_uuid=".$row['contact_uuid']."&id=".$row['contact_setting_uuid']."' alt='".$text['button-edit']."'>$v_link_label_edit</a>";
 			}
 			}

+ 63 - 0
contact_time_delete.php

@@ -0,0 +1,63 @@
+<?php
+/*
+	FusionPBX
+	Version: MPL 1.1
+
+	The contents of this file are subject to the Mozilla Public License Version
+	1.1 (the "License"); you may not use this file except in compliance with
+	the License. You may obtain a copy of the License at
+	http://www.mozilla.org/MPL/
+
+	Software distributed under the License is distributed on an "AS IS" basis,
+	WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+	for the specific language governing rights and limitations under the
+	License.
+
+	The Original Code is FusionPBX
+
+	The Initial Developer of the Original Code is
+	Mark J Crane <[email protected]>
+	Portions created by the Initial Developer are Copyright (C) 2008-2015
+	the Initial Developer. All Rights Reserved.
+
+	Contributor(s):
+	Mark J Crane <[email protected]>
+*/
+require_once "root.php";
+require_once "resources/require.php";
+require_once "resources/check_auth.php";
+if (permission_exists('contact_time_delete')) {
+	//access granted
+}
+else {
+	echo "access denied";
+	exit;
+}
+
+//add multi-lingual support
+	$language = new text;
+	$text = $language->get();
+
+//get the http values and set as variables
+	if (count($_GET) > 0) {
+		$contact_time_uuid = check_str($_GET["id"]);
+		$contact_uuid = check_str($_GET["contact_uuid"]);
+	}
+
+//delete the record
+	if (strlen($contact_time_uuid) > 0) {
+		$sql = "delete from v_contact_times ";
+		$sql .= "where domain_uuid = '".$domain_uuid."' ";
+		$sql .= "and contact_uuid = '".$contact_uuid."' ";
+		$sql .= "and contact_time_uuid = '".$contact_time_uuid."' ";
+		$prep_statement = $db->prepare(check_sql($sql));
+		$prep_statement->execute();
+		unset($sql);
+	}
+
+//redirect the browser
+	$_SESSION["message"] = $text['message-delete'];
+	header("Location: contact_edit.php?id=".$contact_uuid);
+	return;
+
+?>

+ 231 - 0
contact_time_edit.php

@@ -0,0 +1,231 @@
+<?php
+/*
+	FusionPBX
+	Version: MPL 1.1
+
+	The contents of this file are subject to the Mozilla Public License Version
+	1.1 (the "License"); you may not use this file except in compliance with
+	the License. You may obtain a copy of the License at
+	http://www.mozilla.org/MPL/
+
+	Software distributed under the License is distributed on an "AS IS" basis,
+	WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+	for the specific language governing rights and limitations under the
+	License.
+
+	The Original Code is FusionPBX
+
+	The Initial Developer of the Original Code is
+	Mark J Crane <[email protected]>
+	Portions created by the Initial Developer are Copyright (C) 2008-2012
+	the Initial Developer. All Rights Reserved.
+
+	Contributor(s):
+	Mark J Crane <[email protected]>
+*/
+require_once "root.php";
+require_once "resources/require.php";
+require_once "resources/check_auth.php";
+if (permission_exists('contact_time_edit') || permission_exists('contact_time_add')) {
+	//access granted
+}
+else {
+	echo "access denied";
+	exit;
+}
+
+//add multi-lingual support
+	$language = new text;
+	$text = $language->get();
+
+//action add or update
+	if (isset($_REQUEST["id"])) {
+		$action = "update";
+		$contact_time_uuid = check_str($_REQUEST["id"]);
+	}
+	else {
+		$action = "add";
+	}
+
+if (strlen($_GET["contact_uuid"]) > 0) {
+	$contact_uuid = check_str($_GET["contact_uuid"]);
+}
+
+//get http post variables and set them to php variables
+	if (count($_POST)>0) {
+		$time_start = check_str($_POST["time_start"]);
+		$time_stop = check_str($_POST["time_stop"]);
+		$time_description = check_str($_POST["time_description"]);
+	}
+
+if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) {
+
+	$msg = '';
+	if ($action == "update") {
+		$contact_time_uuid = check_str($_POST["contact_time_uuid"]);
+	}
+
+	//check for all required data
+		if (strlen($msg) > 0 && strlen($_POST["persistformvar"]) == 0) {
+			require_once "resources/header.php";
+			require_once "resources/persist_form_var.php";
+			echo "<div align='center'>\n";
+			echo "<table><tr><td>\n";
+			echo $msg."<br />";
+			echo "</td></tr></table>\n";
+			persistformvar($_POST);
+			echo "</div>\n";
+			require_once "resources/footer.php";
+			return;
+		}
+
+	//add or update the database
+	if ($_POST["persistformvar"] != "true") {
+
+
+		if ($action == "add") {
+			$contact_time_uuid = uuid();
+			$sql = "insert into v_contact_times ";
+			$sql .= "( ";
+			$sql .= "domain_uuid, ";
+			$sql .= "contact_time_uuid, ";
+			$sql .= "contact_uuid, ";
+			$sql .= "user_uuid, ";
+			$sql .= "time_start, ";
+			$sql .= "time_stop, ";
+			$sql .= "time_description ";
+			$sql .= ") ";
+			$sql .= "values ";
+			$sql .= "( ";
+			$sql .= "'".$_SESSION['domain_uuid']."', ";
+			$sql .= "'".$contact_time_uuid."', ";
+			$sql .= "'".$contact_uuid."', ";
+			$sql .= "'".$_SESSION["user"]["user_uuid"]."', ";
+			$sql .= "'".$time_start."', ";
+			$sql .= "'".$time_stop."', ";
+			$sql .= "'".$time_description."' ";
+			$sql .= ")";
+			$db->exec(check_sql($sql));
+			unset($sql);
+
+			$_SESSION["message"] = $text['message-add'];
+			header("Location: contact_edit.php?id=".$contact_uuid);
+			return;
+		} //if ($action == "add")
+
+		if ($action == "update") {
+			$sql = "update v_contact_times ";
+			$sql .= "set ";
+			$sql .= "time_start = '".$time_start."', ";
+			$sql .= "time_stop = '".$time_stop."', ";
+			$sql .= "time_description = '".$time_description."' ";
+			$sql .= "where ";
+			$sql .= "contact_time_uuid = '".$contact_time_uuid."' ";
+			$sql .= "and domain_uuid = '".$_SESSION['domain_uuid']."' ";
+			$sql .= "and contact_uuid = '".$contact_uuid."' ";
+			$sql .= "and user_uuid = '".$_SESSION["user"]["user_uuid"]."' ";
+			$db->exec(check_sql($sql));
+			unset($sql);
+
+			$_SESSION["message"] = $text['message-update'];
+			header("Location: contact_edit.php?id=".$contact_uuid);
+			return;
+		} //if ($action == "update")
+	} //if ($_POST["persistformvar"] != "true")
+} //(count($_POST)>0 && strlen($_POST["persistformvar"]) == 0)
+
+//pre-populate the form
+	if (count($_GET)>0 && $_POST["persistformvar"] != "true") {
+		$contact_time_uuid = $_GET["id"];
+		$sql = "select ct.*, u.username ";
+		$sql .= "from v_contact_times as ct, v_users as u ";
+		$sql .= "where ct.user_uuid = u.user_uuid ";
+		$sql .= "and ct.domain_uuid = '".$_SESSION['domain_uuid']."' ";
+		$sql .= "and u.domain_uuid = '".$_SESSION['domain_uuid']."' ";
+		$sql .= "and ct.contact_uuid = '".$contact_uuid."' ";
+		$sql .= "and contact_time_uuid = '".$contact_time_uuid."' ";
+		$sql .= "order by ct.time_start desc ";
+		$prep_statement = $db->prepare(check_sql($sql));
+		$prep_statement->execute();
+		$result = $prep_statement->fetch(PDO::FETCH_NAMED);
+		$time_start = $result["time_start"];
+		$time_stop = $result["time_stop"];
+		$time_description = $result["time_description"];
+		unset ($prep_statement);
+	}
+
+//show the header
+	require_once "resources/header.php";
+	if ($action == "update") {
+		$document['title'] = $text['title-contact_time_edit'];
+	}
+	else if ($action == "add") {
+		$document['title'] = $text['title-contact_time_add'];
+	}
+
+//show the content
+	echo "<form method='post' name='frm' action=''>\n";
+	echo "<table width='100%' border='0' cellpadding='0' cellspacing='0'>\n";
+	echo "<tr>\n";
+	echo "<td align='left' valign='top' nowrap='nowrap'><b>";
+	if ($action == "update") {
+		echo $text['header-contact_time_edit'];
+	}
+	else if ($action == "add") {
+		echo $text['header-contact_time_add'];
+	}
+	echo "</b></td>\n";
+	echo "<td align='right' valign='top'>";
+	echo "	<input type='button' class='btn' name='' alt='".$text['button-back']."' onclick=\"window.location='contact_edit.php?id=$contact_uuid'\" value='".$text['button-back']."'>";
+	echo "	<input type='submit' name='submit' class='btn' value='".$text['button-save']."'>\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+	echo "</table>\n";
+	echo "<br>\n";
+
+	echo "<table width='100%' border='0' cellpadding='0' cellspacing='0'>\n";
+
+	echo "<tr>\n";
+	echo "<td width='30%' class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-time_start']."\n";
+	echo "</td>\n";
+	echo "<td width='70%' class='vtable' align='left'>\n";
+	echo "	<input class='formfld' type='text' name='time_start' id='time_start' style='min-width: 135px; width: 135px;' data-calendar=\"{format: '%Y-%m-%d %H:%M:%S', listYears: true, hideOnPick: false, fxName: null, showButtons: true}\" value='".$time_start."'>\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-time_stop']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' align='left'>\n";
+	echo "	<input class='formfld' type='text' name='time_stop' id='time_stop' style='min-width: 135px; width: 135px;' data-calendar=\"{format: '%Y-%m-%d %H:%M:%S', listYears: true, hideOnPick: false, fxName: null, showButtons: true}\" value='".$time_stop."'>\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "	".$text['label-time_description']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' align='left'>\n";
+	echo "  <textarea class='formfld' type='text' name='time_description' id='time_description' style='width: 400px; height: 100px;'>".$time_description."</textarea>\n";
+	echo "</td>\n";
+	echo "</tr>\n";
+
+	echo "	<tr>\n";
+	echo "		<td colspan='2' align='right'>\n";
+	echo "			<br>\n";
+	echo "			<input type='hidden' name='contact_uuid' value='".$contact_uuid."'>\n";
+	if ($action == "update") {
+		echo "		<input type='hidden' name='contact_time_uuid' value='".$contact_time_uuid."'>\n";
+	}
+	echo "			<input type='submit' name='submit' class='btn' value='".$text['button-save']."'>\n";
+	echo "		</td>\n";
+	echo "	</tr>";
+	echo "</table>";
+	echo "<br><br>";
+	echo "</form>";
+
+//include the footer
+	require_once "resources/footer.php";
+?>

+ 372 - 0
contact_timer.php

@@ -0,0 +1,372 @@
+<?php
+/*
+	FusionPBX
+	Version: MPL 1.1
+
+	The contents of this file are subject to the Mozilla Public License Version
+	1.1 (the "License"); you may not use this file except in compliance with
+	the License. You may obtain a copy of the License at
+	http://www.mozilla.org/MPL/
+
+	Software distributed under the License is distributed on an "AS IS" basis,
+	WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+	for the specific language governing rights and limitations under the
+	License.
+
+	The Original Code is FusionPBX
+
+	The Initial Developer of the Original Code is
+	Mark J Crane <[email protected]>
+	Portions created by the Initial Developer are Copyright (C) 2008-2015
+	the Initial Developer. All Rights Reserved.
+
+	Contributor(s):
+	Mark J Crane <[email protected]>
+*/
+require_once "root.php";
+require_once "resources/require.php";
+require_once "resources/check_auth.php";
+if (!permission_exists('contact_time_add')) { echo "access denied"; exit; }
+
+//add multi-lingual support
+	$language = new text;
+	$text = $language->get();
+
+//get contact uuid
+	$contact_uuid = check_str($_REQUEST['contact_uuid']);
+
+//get posted variables & set time status
+	if (sizeof($_POST) > 0) {
+		$domain_uuid = check_str($_POST['domain_uuid']);
+		$contact_time_uuid = check_str($_POST['contact_time_uuid']);
+		$contact_uuid = check_str($_POST['contact_uuid']);
+		$time_action = check_str($_POST['time_action']);
+		$time_description = check_str($_POST['time_description']);
+
+		if ($time_description == 'Description...') { unset($time_description); }
+
+		if ($time_action == 'start') {
+			$contact_time_uuid = uuid();
+			$sql = "insert into v_contact_times ";
+			$sql .= "( ";
+			$sql .= "domain_uuid, ";
+			$sql .= "contact_time_uuid, ";
+			$sql .= "contact_uuid, ";
+			$sql .= "user_uuid, ";
+			$sql .= "time_start, ";
+			$sql .= "time_description ";
+			$sql .= ") ";
+			$sql .= "values ";
+			$sql .= "( ";
+			$sql .= "'".$domain_uuid."', ";
+			$sql .= "'".$contact_time_uuid."', ";
+			$sql .= "'".$contact_uuid."', ";
+			$sql .= "'".$_SESSION["user"]["user_uuid"]."', ";
+			$sql .= "'".date("Y-m-d H:i:s")."', ";
+			$sql .= "'".$time_description."' ";
+			$sql .= ")";
+			$db->exec(check_sql($sql));
+			unset($sql);
+		}
+		if ($time_action == 'stop') {
+			$sql = "update v_contact_times ";
+			$sql .= "set ";
+			$sql .= "time_stop = '".date("Y-m-d H:i:s")."', ";
+			$sql .= "time_description = '".$time_description."' ";
+			$sql .= "where ";
+			$sql .= "contact_time_uuid = '".$contact_time_uuid."' ";
+			$sql .= "and domain_uuid = '".$domain_uuid."' ";
+			$sql .= "and contact_uuid = '".$contact_uuid."' ";
+			$sql .= "and user_uuid = '".$_SESSION["user"]["user_uuid"]."' ";
+			$db->exec(check_sql($sql));
+			unset($sql);
+		}
+		header("contact_timer.php?contact_uuid=".$contact_uuid);
+	}
+
+//get contact details
+	$sql = "select ";
+	$sql .= "contact_organization, ";
+	$sql .= "contact_name_given, ";
+	$sql .= "contact_name_family, ";
+	$sql .= "contact_nickname ";
+	$sql .= "from v_contacts ";
+	$sql .= "where domain_uuid = '".$_SESSION['domain_uuid']."' ";
+	$sql .= "and contact_uuid = '".$contact_uuid."' ";
+	$prep_statement = $db->prepare(check_sql($sql));
+	$prep_statement->execute();
+	$result = $prep_statement->fetch(PDO::FETCH_NAMED);
+	if (sizeof($result) > 0) {
+		$contact_organization = $result["contact_organization"];
+		$contact_name_given = $result["contact_name_given"];
+		$contact_name_family = $result["contact_name_family"];
+		$contact_nickname = $result["contact_nickname"];
+	}
+	else {
+		exit;
+	}
+	unset ($sql, $prep_statement, $result);
+
+//determine timer state and action
+	$sql = "select ";
+	$sql .= "contact_time_uuid, ";
+	$sql .= "time_description ";
+	$sql .= "from v_contact_times ";
+	$sql .= "where domain_uuid = '".$_SESSION['domain_uuid']."' ";
+	$sql .= "and user_uuid = '".$_SESSION['user']['user_uuid']."' ";
+	$sql .= "and contact_uuid = '".$contact_uuid."' ";
+	$sql .= "and time_start is not null ";
+	$sql .= "and time_stop is null ";
+	$prep_statement = $db->prepare(check_sql($sql));
+	$prep_statement->execute();
+	$result = $prep_statement->fetch(PDO::FETCH_NAMED);
+	if (sizeof($result) > 0) {
+		$contact_time_uuid = $result["contact_time_uuid"];
+		$time_description = $result["time_description"];
+	}
+	unset ($sql, $prep_statement, $result);
+
+	$timer_state = ($contact_time_uuid != '') ? 'running' : 'stopped';
+	$timer_action = ($timer_state == 'running') ? 'stop' : 'start';
+
+//determine contact name to display
+	if ($contact_nickname != '') {
+		$contact = $contact_nickname;
+	}
+	else if ($contact_name_given != '') {
+		$contact = $contact_name_given;
+	}
+	if ($contact_name_family != '') {
+		$contact .= ($contact != '') ? ' '.$contact_name_family : $contact_name_family;
+	}
+	if ($contact_organization != '') {
+		$contact .= ($contact != '') ? ', '.$contact_organization : $contact_organization;
+	}
+?>
+
+<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'>
+<head>
+	<title>Timer: <?php echo $contact; ?></title>
+	<style>
+		body {
+			color: #5f5f5f;
+			font-size: 12px;
+			font-family: arial;
+			margin: 0;
+			padding: 15px;
+			}
+
+		b {
+			color: #952424;
+			font-size: 15px;
+			font-family: arial;
+			}
+
+		form {
+			margin: 0;
+			}
+
+		input.btn, input.button {
+			font-family: Candara, Calibri, Segoe, "Segoe UI", Optima, Arial, sans-serif;
+			padding: 2px 6px 3px 6px;
+			color: #fff;
+			font-weight: bold;
+			cursor: pointer;
+			font-size: 11px;
+			-moz-border-radius: 3px;
+			-webkit-border-radius: 3px;
+			-khtml-border-radius: 3px;
+			border-radius: 3px;
+			background-image: -moz-linear-gradient(top, #524f59 25%, #000 64%);
+			background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.25, #524f59), color-stop(0.64, #000));
+			border: 1px solid #26242a;
+			background-color: #000;
+			text-align: center;
+			text-transform: uppercase;
+			text-shadow: 0px 0px 1px rgba(0, 0, 0, 0.85);
+			opacity: 0.9;
+			-moz-opacity: 0.9;
+			}
+
+		input.btn:hover, input.button:hover, img.list_control_icon:hover {
+			box-shadow: 0 0 5px #cddaf0;
+			-webkit-box-shadow: 0 0 5px #cddaf0;
+			-moz-box-shadow: 0 0 5px #cddaf0;
+			opacity: 1.0;
+			-moz-opacity: 1.0;
+			cursor: pointer;
+			}
+
+		input.txt, textarea.txt, select.txt, .formfld {
+			font-family: arial;
+			font-size: 12px;
+			color: #000;
+			text-align: left;
+			padding: 5px;
+			border: 1px solid #c0c0c0;
+			background-color: #fff;
+			box-shadow: 0 0 3px #cddaf0 inset;
+			-moz-box-shadow: 0 0 3px #cddaf0 inset;
+			-webkit-box-shadow: 0 0 3px #cddaf0 inset;
+			border-radius: 3px;
+			-moz-border-radius: 3px;
+			-webkit-border-radius: 3px;
+			}
+
+		input.txt, .formfld {
+			transition: width 0.25s;
+			-moz-transition: width 0.25s;
+			-webkit-transition: width 0.25s;
+			max-width: 500px;
+			}
+
+		input.txt:focus, .formfld:focus {
+			-webkit-box-shadow: 0 0 5px #cddaf0;
+			-moz-box-shadow: 0 0 5px #cddaf0;
+			box-shadow: 0 0 5px #cddaf0;
+			}
+
+		td {
+			color: #5f5f5f;
+			font-size: 12px;
+			font-family: arial;
+			}
+
+		.vncell {
+			border-bottom: 1px solid #fff;
+			background-color: #e5e9f0;
+			padding: 8px;
+			text-align: right;
+			color: #000;
+			-moz-border-radius: 4px;
+			-webkit-border-radius: 4px;
+			border-radius: 4px;
+			border-right: 3px solid #e5e9f0;
+			}
+
+		DIV.timer {
+			width: 100%;
+			height: 60px;
+			text-align: center;
+			background-color: #222;
+			font-size: 50px;
+			color: #c00;
+			font-weight: bold;
+			font-family: "Courier New",Courier,"Lucida Sans Typewriter","Lucida Typewriter",monospace;
+			padding-top: 7px;
+			-moz-border-radius: 4px;
+			-webkit-border-radius: 4px;
+			border-radius: 4px;
+
+			}
+
+	</style>
+
+	<script type="text/javascript">
+		//ajax for refresh
+		var refresh = 1500;
+		var source_url = 'contact_timer_inc.php?contact_uuid=<?php echo $contact_uuid; ?>&contact_time_uuid=<?php echo $contact_time_uuid; ?>';
+		var interval_timer_id;
+
+		function loadXmlHttp(url, id) {
+			var f = this;
+			f.xmlHttp = null;
+			/*@cc_on @*/ // used here and below, limits try/catch to those IE browsers that both benefit from and support it
+			/*@if(@_jscript_version >= 5) // prevents errors in old browsers that barf on try/catch & problems in IE if Active X disabled
+			try {f.ie = window.ActiveXObject}catch(e){f.ie = false;}
+			@end @*/
+			if (window.XMLHttpRequest&&!f.ie||/^http/.test(window.location.href))
+				f.xmlHttp = new XMLHttpRequest(); // Firefox, Opera 8.0+, Safari, others, IE 7+ when live - this is the standard method
+			else if (/(object)|(function)/.test(typeof createRequest))
+				f.xmlHttp = createRequest(); // ICEBrowser, perhaps others
+			else {
+				f.xmlHttp = null;
+				 // Internet Explorer 5 to 6, includes IE 7+ when local //
+				/*@cc_on @*/
+				/*@if(@_jscript_version >= 5)
+				try{f.xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");}
+				catch (e){try{f.xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");}catch(e){f.xmlHttp=null;}}
+				@end @*/
+			}
+			if(f.xmlHttp != null){
+				f.el = document.getElementById(id);
+				f.xmlHttp.open("GET",url,true);
+				f.xmlHttp.onreadystatechange = function(){f.stateChanged();};
+				f.xmlHttp.send(null);
+			}
+		}
+
+		loadXmlHttp.prototype.stateChanged=function () {
+		if (this.xmlHttp.readyState == 4 && (this.xmlHttp.status == 200 || !/^http/.test(window.location.href)))
+			//this.el.innerHTML = this.xmlHttp.responseText;
+			document.getElementById('ajax_reponse').innerHTML = this.xmlHttp.responseText;
+			if (document.getElementById('title_script')) {
+				eval(document.getElementById('title_script').innerHTML);
+			}
+		}
+
+		<? if ($timer_state == 'running') { ?>
+			var requestTime = function() {
+				var url = source_url;
+				new loadXmlHttp(url, 'ajax_reponse');
+				refresh_start();
+			}
+
+			if (window.addEventListener) {
+				window.addEventListener('load', requestTime, false);
+			}
+			else if (window.attachEvent) {
+				window.attachEvent('onload', requestTime);
+			}
+		<? } ?>
+
+	//refresh controls
+		function refresh_start() {
+			interval_timer_id = setInterval( function() {
+				url = source_url;
+				new loadXmlHttp(url, 'ajax_reponse');
+			}, refresh);
+		}
+
+	//set window title to time when timer is running
+		function set_title(title_text) {
+			window.document.title = title_text;
+		}
+
+	</script>
+</head>
+<body>
+<img src='resources/images/icon_timer.png' style='width: 24px; height: 24px; border: none; margin-left: 15px;' alt="<?php echo $text['label-time_timer']; ?>" align='right'>
+<b><?php echo $text['label-time_timer']; ?></b>
+<br><br>
+<?php echo $text['description_timer']; ?>
+<br><br>
+<strong style='color: #000;'><?php echo $contact; ?></strong>
+<br><br>
+<div id='ajax_reponse' class='timer' <?php echo ($timer_state == 'stopped') ? "style='color: #888;'" : null; ?>>00:00:00</div>
+<br>
+<form name='frm' id='frm' method='post' action=''>
+<input type='hidden' name='domain_uuid' value="<?php echo $_SESSION['domain_uuid']; ?>">
+<input type='hidden' name='contact_time_uuid' value="<?php echo $contact_time_uuid; ?>">
+<input type='hidden' name='contact_uuid' value="<?php echo $contact_uuid; ?>">
+<input type='hidden' name='time_action' value="<?php echo $timer_action; ?>">
+<table cellpadding='0' cellspacing='0' border='0' style='width: 100%;'>
+	<tr>
+		<td class='vncell' style='text-align: center; padding: 10px;'>
+			<?php echo $text['label-description']; ?>
+			<textarea name='time_description' id='timer_description' class='formfld' style='width: 100%; height: 50px; margin-top: 5px;'><?php echo $time_description; ?></textarea>
+			<? if ($timer_state == 'stopped') { ?><script>document.getElementById('timer_description').focus();</script><? } ?>
+		</td>
+	</tr>
+</table>
+<br>
+<center>
+<? if ($timer_state == 'running') { ?>
+	<input type='submit' class='btn' value="<?php echo $text['button-stop']; ?>">
+<? } else if ($timer_state == 'stopped') { ?>
+	<input type='submit' class='btn' value="<?php echo $text['button-start']; ?>">
+<? } ?>
+</center>
+</form>
+</body>
+</html>

+ 56 - 0
contact_timer_inc.php

@@ -0,0 +1,56 @@
+<?php
+/*
+	FusionPBX
+	Version: MPL 1.1
+
+	The contents of this file are subject to the Mozilla Public License Version
+	1.1 (the "License"); you may not use this file except in compliance with
+	the License. You may obtain a copy of the License at
+	http://www.mozilla.org/MPL/
+
+	Software distributed under the License is distributed on an "AS IS" basis,
+	WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+	for the specific language governing rights and limitations under the
+	License.
+
+	The Original Code is FusionPBX
+
+	The Initial Developer of the Original Code is
+	Mark J Crane <[email protected]>
+	Portions created by the Initial Developer are Copyright (C) 2008-2015
+	the Initial Developer. All Rights Reserved.
+
+	Contributor(s):
+	Mark J Crane <[email protected]>
+*/
+require_once "root.php";
+require_once "resources/require.php";
+require_once "resources/check_auth.php";
+if (!permission_exists('contact_time_add')) { echo "access denied"; exit; }
+
+//get contact and time uuids
+	$contact_uuid = check_str($_REQUEST['contact_uuid']);
+	$contact_time_uuid = check_str($_REQUEST['contact_time_uuid']);
+
+//get time quantity
+	$sql = "select ";
+	$sql .= "time_start ";
+	$sql .= "from v_contact_times ";
+	$sql .= "where domain_uuid = '".$_SESSION['domain_uuid']."' ";
+	$sql .= "and contact_time_uuid = '".$contact_time_uuid."' ";
+	$sql .= "and user_uuid = '".$_SESSION['user']['user_uuid']."' ";
+	$sql .= "and contact_uuid = '".$contact_uuid."' ";
+	$sql .= "and time_start is not null ";
+	$sql .= "and time_stop is null ";
+	$prep_statement = $db->prepare(check_sql($sql));
+	$prep_statement->execute();
+	$result = $prep_statement->fetch(PDO::FETCH_NAMED);
+	if (sizeof($result) > 0) {
+		$time_start = strtotime($result["time_start"]);
+		$time_now = strtotime(date("Y-m-d H:i:s"));
+		$time_diff = gmdate("H:i:s", ($time_now - $time_start));
+		echo $time_diff;
+		echo "<script id='title_script'>set_title('".$time_diff."');</script>";
+	}
+	unset ($sql, $prep_statement, $result);
+?>

+ 137 - 0
contact_times.php

@@ -0,0 +1,137 @@
+<?php
+/*
+	FusionPBX
+	Version: MPL 1.1
+
+	The contents of this file are subject to the Mozilla Public License Version
+	1.1 (the "License"); you may not use this file except in compliance with
+	the License. You may obtain a copy of the License at
+	http://www.mozilla.org/MPL/
+
+	Software distributed under the License is distributed on an "AS IS" basis,
+	WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+	for the specific language governing rights and limitations under the
+	License.
+
+	The Original Code is FusionPBX
+
+	The Initial Developer of the Original Code is
+	Mark J Crane <[email protected]>
+	Portions created by the Initial Developer are Copyright (C) 2008-2015
+	the Initial Developer. All Rights Reserved.
+
+	Contributor(s):
+	Mark J Crane <[email protected]>
+*/
+require_once "root.php";
+require_once "resources/require.php";
+require_once "resources/check_auth.php";
+if (permission_exists('contact_time_view')) {
+	//access granted
+}
+else {
+	echo "access denied";
+	exit;
+}
+
+//show the content
+	echo "<table width='100%' border='0'>\n";
+	echo "<tr>\n";
+	echo "<td width='50%' align='left' nowrap='nowrap'><b>".$text['header_contact_times']."</b></td>\n";
+	echo "<td width='50%' align='right'>&nbsp;</td>\n";
+	echo "</tr>\n";
+	echo "</table>\n";
+
+	//get the contact list
+		$sql = "select ct.*, u.username ";
+		$sql .= "from v_contact_times as ct, v_users as u ";
+		$sql .= "where ct.user_uuid = u.user_uuid ";
+		$sql .= "and ct.domain_uuid = '".$domain_uuid."' ";
+		$sql .= "and u.domain_uuid = '".$domain_uuid."' ";
+		$sql .= "and ct.contact_uuid = '".$contact_uuid."' ";
+		$sql .= "order by ct.time_start desc ";
+		$prep_statement = $db->prepare(check_sql($sql));
+		$prep_statement->execute();
+		$result = $prep_statement->fetchAll(PDO::FETCH_NAMED);
+		$result_count = count($result);
+		unset ($prep_statement, $sql);
+
+	$c = 0;
+	$row_style["0"] = "row_style0";
+	$row_style["1"] = "row_style1";
+
+	echo "<table class='tr_hover' width='100%' border='0' cellpadding='0' cellspacing='0'>\n";
+	echo "<tr>\n";
+	echo "<th id='filler' style='display: none; padding: 0px;'>".img_spacer('21px', '1px', 'none')."</th>\n";
+	echo "<th width='20%'>".$text['label-time_user']."</th>\n";
+	echo "<th width='20%'>".$text['label-time_start']."</th>\n";
+	echo "<th width='20%'>".$text['label-time_duration']."</th>\n";
+	echo "<th width='40%'>".$text['label-time_description']."</th>\n";
+	echo "<td class='list_control_icons' nowrap>";
+	echo 	img_spacer('25px', '1px', 'none');
+	if (permission_exists('contact_time_add')) {
+		echo "<a href='contact_time_edit.php?contact_uuid=".$_GET['id']."' alt='".$text['button-add']."'>$v_link_label_add</a>";
+	}
+	else {
+		echo img_spacer('25px', '1px', 'none');
+	}
+	echo "</td>\n";
+	echo "</tr>\n";
+	echo "</table>\n";
+
+	echo "<div id='contact_times' style='width: 100%; overflow: auto; direction: rtl; text-align: right; margin-bottom: 23px;'>";
+	echo "<table class='tr_hover' style='width: 100%; direction: ltr; padding-left: 1px' border='0' cellpadding='0' cellspacing='0'>\n";
+	if ($result_count > 0) {
+		foreach($result as $row) {
+			if (permission_exists('contact_time_edit')) {
+				$tr_link = "href='contact_time_edit.php?contact_uuid=".$row['contact_uuid']."&id=".$row['contact_time_uuid']."'";
+			}
+			echo "<tr ".$tr_link.">\n";
+			if ($row["time_start"] != '' && $row['time_stop'] != '') {
+				$time_start = strtotime($row["time_start"]);
+				$time_stop = strtotime($row['time_stop']);
+				$time = gmdate("H:i:s", ($time_stop - $time_start));
+			}
+			else { unset($time); }
+			$tmp = explode(' ', $row['time_start']);
+			$time_start = $tmp[0];
+			echo "	<td valign='top' class='".$row_style[$c]."' width='20%'>".$row["username"]."&nbsp;</td>\n";
+			echo "	<td valign='top' class='".$row_style[$c]."' width='20%'>".$time_start."&nbsp;</td>\n";
+			echo "	<td valign='top' class='".$row_style[$c]."' width='20%'>".$time."&nbsp;</td>\n";
+			echo "	<td valign='top' class='row_stylebg' style='width: 40%; max-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;'>".$row['time_description']."&nbsp;</td>\n";
+			echo "	<td class='list_control_icons' nowrap>";
+			if (permission_exists('contact_time_edit')) {
+				echo "<a href='contact_time_edit.php?contact_uuid=".$row['contact_uuid']."&id=".$row['contact_time_uuid']."' alt='".$text['button-edit']."'>$v_link_label_edit</a>";
+			}
+			if (permission_exists('contact_time_delete')) {
+				echo "<a href='contact_time_delete.php?contact_uuid=".$row['contact_uuid']."&id=".$row['contact_time_uuid']."' alt='".$text['button-delete']."' onclick=\"return confirm('".$text['confirm-delete']."')\">$v_link_label_delete</a>";
+			}
+			echo "	</td>\n";
+			echo "</tr>\n";
+			$c = ($c) ? 0 : 1;
+		} //end foreach
+		unset($sql, $result, $row_count);
+	} //end if results
+	echo "</table>";
+	echo "</div>\n";
+
+	echo "<script>";
+	echo "	var div_times = document.getElementById('contact_times');";
+	echo "	var td_filler = document.getElementById('filler');";
+
+	echo "	if (div_times.offsetHeight > 200) { ";
+	echo "		div_times.style.height = 200; ";
+	echo "	}";
+	echo "	else {";
+	echo "		div_times.style.height = div_times.scrollHeight + 1; ";
+	echo "	}";
+	//echo "	alert('offsetHeight = '+div_times.offsetHeight+', scrollHeight = '+div_times.scrollHeight+', clientHeight = '+div_times.clientHeight);";
+	echo "	if (div_times.scrollHeight > div_times.clientHeight) {";
+	echo "		td_filler.style.display = ''; ";
+	echo "	}";
+	echo "	else {";
+	echo "		td_filler.style.display = 'none'; ";
+	echo "	}";
+	echo "</script>\n";
+
+?>

二进制
resources/images/icon_timer.png