]> git.sur5r.net Git - contagged/commitdiff
mod_auth_ldap, non-anon binding and openxchange support
authorDaniel Tarbuck <tarbuck@futurewest.ca>
Tue, 17 Jan 2006 11:14:59 +0000 (12:14 +0100)
committerDaniel Tarbuck <tarbuck@futurewest.ca>
Tue, 17 Jan 2006 11:14:59 +0000 (12:14 +0100)
The attached patch builds on your work in the following ways:
1. adds support for non-anonymous binding.  Leaving the extra config
variables empty results in an anonymous bind.  I haven't fully tested
this (I cannot test the anonymous case), but any problems should be
apparent immediately.

2. adds support for httpd authentication.  I use mod_auth_ldap to
authenticate access to the site.  This prevents the user having to login
twice.

3. adds support for parts of the openxchange schema
(http://www.openxchange.org). Only the parts I found useful are added.
The openxchange.schema is not included as the user that enables this is
expected to have already installed openxchange.

darcs-hash:20060117111459-bb1f7-cc6f1f6e943f5c6ffa8f393f68c32500505dae67.gz

13 files changed:
README
_htaccess [new file with mode: 0644]
config.php
entry.php
functions.php
index.php
lang/en.php
template.php
templates/entry_edit.tpl
templates/entry_show.tpl
templates/list_filter.tpl
templates/openxchange_edit.tpl [new file with mode: 0644]
templates/openxchange_show.tpl [new file with mode: 0644]

diff --git a/README b/README
index a69db6459a751255cb8fe0d5712fa68d4dddaff5..60af64cc04ff82e0a1ff2cf00512a4805b31a7ab 100644 (file)
--- a/README
+++ b/README
@@ -2,7 +2,7 @@
 
 LDAPab is a webbased address book for small companies. It features a public
 address book which is writable for all company staff and a personal address
 
 LDAPab is a webbased address book for small companies. It features a public
 address book which is writable for all company staff and a personal address
-book for each staff member. LDAPab require an already setup LDAP server to
+book for each staff member. LDAPab requires an already setup LDAP server to
 authenticate users.
 
 === REQUIREMENTS ===
 authenticate users.
 
 === REQUIREMENTS ===
@@ -18,11 +18,14 @@ with LDAP support (compiled in or as extension)
 
 Copy the contents of the .tgz file to a directory below your webserver document
 root. Make sure the webserver is able to write to the cache directory which is
 
 Copy the contents of the .tgz file to a directory below your webserver document
 root. Make sure the webserver is able to write to the cache directory which is
-used for the template engines cache files. A 'chmod 777 cache' will do.
+used for the template engine's cache files. A 'chmod 777 cache' will do.
 
 Open the config.php file in your favourite editor and edit the options
 according to your needs. Some knowlege about LDAP may come in handy.
 
 
 Open the config.php file in your favourite editor and edit the options
 according to your needs. Some knowlege about LDAP may come in handy.
 
+If HTTP auth is wanted have a look at the provided _htaccess file, edit it as
+needed and rename it back to .htaccess
+
 === SETUP THE LDAP SERVER ===
 
 The following only describes what to do for open-ldap 2.0! If you use any
 === SETUP THE LDAP SERVER ===
 
 The following only describes what to do for open-ldap 2.0! If you use any
diff --git a/_htaccess b/_htaccess
new file mode 100644 (file)
index 0000000..dbb247d
--- /dev/null
+++ b/_htaccess
@@ -0,0 +1,27 @@
+#
+# Example .htaccess to use with mod_authldap
+#
+
+AuthName "LDAPab"
+AuthType basic
+
+AuthLDAPURL "ldap://ldap/ou=people,o=cosmocode,c=de?uid?one"
+
+### LDAP Bind information
+#AuthLDAPBindDN cn=NonAnon,o=cosmocode,c=de
+#AuthLDAPBindPassword secret
+
+### For LDAP group authentication
+#AuthLDAPGroupAttribute memberUid
+#AuthLDAPGroupAttributeIsDN off
+#require group cn=Users,ou=Groups,o=cosmocode,c=de
+
+### Authorize users individually
+#require user myusername
+
+### Authorize any authenticated user
+require valid-user
+
+### Require SSL for access
+#SSLRequireSSL
+
index 31419dca562e9e1c8557404811ee1cad5ef44d3b..d269fe752f493469b24c3ee83478fef11aa41e9d 100644 (file)
@@ -3,6 +3,9 @@
   // Which LDAP Server to use?
   $conf[ldapserver]  = 'ldap';
 
   // Which LDAP Server to use?
   $conf[ldapserver]  = 'ldap';
 
+  // Which LDAP Port Server to use? (389 is standard, 636 for ssl)
+  $conf[ldapport]    = 389;
+
   // What is the root dn on this Server?
   $conf[ldaprootdn]  = 'o=cosmocode, c=de';
 
   // What is the root dn on this Server?
   $conf[ldaprootdn]  = 'o=cosmocode, c=de';
 
   // How to match users? %u is replaced by the given login
   $conf[userfilter]  = '(&(uid=%u)(objectClass=posixAccount))';
 
   // How to match users? %u is replaced by the given login
   $conf[userfilter]  = '(&(uid=%u)(objectClass=posixAccount))';
 
+  // Use these values to bind to the ldap directory when not logged in (leave blank for anonymous bind)
+  $conf[anonbinddn]  = '';
+  $conf[anonbindpw]  = '';
+
   // Which language to use (see lang directory)
   $conf[lang]        = 'de';
 
   // Which language to use (see lang directory)
   $conf[lang]        = 'de';
 
   // Where to store private contacts (relative to $conf[usertree])
   $conf[privatebook] = 'ou=contacts';
 
   // Where to store private contacts (relative to $conf[usertree])
   $conf[privatebook] = 'ou=contacts';
 
+  // Should the additional schema ldapab.schema be used? (0|1)
+  // Note: openxchange and extended are currently exclusive, do not use both at the same time!
+  $conf[extended]    = 0;
+  
+  // Should we use some parts of the openxchange.schema? (0|1)
+  // Note: openxchange and extended are currently exclusive, do not use both at the same time!
+  $conf[openxchange] = 1;
+  // Should we try to login using the username and password provided by httpd? (0|1)
+  $conf[httpd_auth]  = 1;
   // Should the additional schema ldapab.schema be used? (0|1)
   $conf[extended]    = 1;
 
   // Should the additional schema ldapab.schema be used? (0|1)
   $conf[extended]    = 1;
 
@@ -31,4 +49,5 @@
 
   // Force recompilation of smarty templates?
   $conf[smartycompile] = 0;
 
   // Force recompilation of smarty templates?
   $conf[smartycompile] = 0;
+
 ?>
 ?>
index a8550534f7a76ae47b86bc91c8c3d786e3431239..594e1eb2b95fb54d8b9e1474eb4e3749413816ee 100644 (file)
--- a/entry.php
+++ b/entry.php
@@ -41,6 +41,9 @@
   tpl_std();
   tpl_orgs();
   tpl_markers();
   tpl_std();
   tpl_orgs();
   tpl_markers();
+  tpl_categories();
+  tpl_timezone();
+  tpl_country();
   //display templates
   if($_REQUEST[mode]=='vcf'){
     $entry = $smarty->get_template_vars('entry');
   //display templates
   if($_REQUEST[mode]=='vcf'){
     $entry = $smarty->get_template_vars('entry');
@@ -132,6 +135,10 @@ print '</pre>';*/
       if($conf[extended]){
         ldap_store_objectclasses($dn,array('inetOrgPerson','contactPerson'));
       }
       if($conf[extended]){
         ldap_store_objectclasses($dn,array('inetOrgPerson','contactPerson'));
       }
+      // in openxchange mode we have to make sure the right classes are set
+      if ($conf[openxchange]){
+        ldap_store_objectclasses($dn,array('inetOrgPerson','OXUserObject'));
+      }
       //modify entry (touches only our attributes)
       foreach (array_keys($entries) as $key){
         if($key == 'dn'){
       //modify entry (touches only our attributes)
       foreach (array_keys($entries) as $key){
         if($key == 'dn'){
index e8ac472488987ad535af3cbd5278081979d0d50e..2c74c1f606e1089b0997b569b34c049383207c70 100644 (file)
@@ -13,6 +13,7 @@ function smarty_std(){
  * If it fails it redirects to login.php
  */
 function ldap_login(){
  * If it fails it redirects to login.php
  */
 function ldap_login(){
+  global $conf;
   if(!empty($_SESSION[ldapab][username])){
     //existing session! Check if valid
     if($_COOKIE[ldapabconid] != $_SESSION[ldapab][conid]){
   if(!empty($_SESSION[ldapab][username])){
     //existing session! Check if valid
     if($_COOKIE[ldapabconid] != $_SESSION[ldapab][conid]){
@@ -20,6 +21,9 @@ function ldap_login(){
        header('Location: login.php?username=');
        exit;
     }
        header('Location: login.php?username=');
        exit;
     }
+  } elseif ($conf[httpd_auth] && !empty($_SERVER[PHP_AUTH_USER])) {
+       $_SESSION[ldapab][username] = $_SERVER[PHP_AUTH_USER];
+       $_SESSION[ldapab][password] = $_SERVER[PHP_AUTH_PW];
   }
 
   if(!do_ldap_bind($_SESSION[ldapab][username],
   }
 
   if(!do_ldap_bind($_SESSION[ldapab][username],
@@ -39,7 +43,7 @@ function do_ldap_bind($user,$pass,$dn=""){
   
   //create global connection to LDAP if nessessary
   if(!$LDAP_CON){
   
   //create global connection to LDAP if nessessary
   if(!$LDAP_CON){
-    $LDAP_CON = ldap_connect($conf[ldapserver]);
+    $LDAP_CON = ldap_connect($conf[ldapserver],$conf[ldapport]);
     if(!$LDAP_CON){
       die("couldn't connect to LDAP server");
     }
     if(!$LDAP_CON){
       die("couldn't connect to LDAP server");
     }
@@ -47,7 +51,8 @@ function do_ldap_bind($user,$pass,$dn=""){
 
   if(empty($dn)){
     //anonymous bind to lookup users
 
   if(empty($dn)){
     //anonymous bind to lookup users
-    if(!ldap_bind($LDAP_CON)){
+    //blank binddn or blank bindpw will result in anonymous bind
+    if(!ldap_bind($LDAP_CON,$conf[anonbinddn],$conf[anonbindpw])){
       die("can not bind anonymously");
     }
   
       die("can not bind anonymously");
     }
   
@@ -152,6 +157,17 @@ function namedentries($flip=false){
   if($conf[extended]){
     $entries[anniversary]              = 'anniversary';
   }
   if($conf[extended]){
     $entries[anniversary]              = 'anniversary';
   }
+  if($conf[openxchange]){
+    $entries[mailDomain]               = 'domain';
+    $entries[userCountry]              = 'country';
+    $entries[birthDay]                 = 'birthday';
+    $entries[IPPhone]                  = 'ipphone';
+    $entries[OXUserCategories]         = 'categories';
+    $entries[OXUserInstantMessenger]   = 'instantmessenger';
+    $entries[OXTimeZone]               = 'timezone';
+    $entries[OXUserPosition]           = 'position';
+    $entries[relClientCert]            = 'certificate';
+  }
 
   if($flip){
     $entries = array_reverse($entries);
 
   if($flip){
     $entries = array_reverse($entries);
@@ -190,6 +206,9 @@ function prepare_ldap_entry($in){
   if($conf[extended]){
     $out[objectclass][] = 'contactPerson';
   }
   if($conf[extended]){
     $out[objectclass][] = 'contactPerson';
   }
+  if($conf[openxchange]){
+    $out[objectclass][] = 'OXUserObject';
+  }
 
   utf8_encode_array($out);
 
 
   utf8_encode_array($out);
 
index 7ff0f0761287e736a7700499ea5eadf1648de527..f797e5e0637952272bb77ffe56f1260fc8c85073 100644 (file)
--- a/index.php
+++ b/index.php
@@ -42,6 +42,9 @@
   //prepare templates
   tpl_std();
   tpl_markers();
   //prepare templates
   tpl_std();
   tpl_markers();
+  tpl_categories();
+  tpl_timezone();
+  tpl_country();
   $smarty->assign('list',$list);
   $smarty->assign('filter',$_REQUEST['filter']);
   $smarty->assign('marker',$_REQUEST['marker']);
   $smarty->assign('list',$list);
   $smarty->assign('filter',$_REQUEST['filter']);
   $smarty->assign('marker',$_REQUEST['marker']);
     $search = $_REQUEST['search'];
     $org    = $_REQUEST['org'];
     $marker = $_REQUEST['marker'];
     $search = $_REQUEST['search'];
     $org    = $_REQUEST['org'];
     $marker = $_REQUEST['marker'];
+    $categories = $_REQUEST['categories'];
     $_SESSION[ldapab][filter] = $filter;
     if(empty($filter)) $filter='a';
 
     if(!empty($marker)){
       $marker = utf8_encode($marker);
       $ldapfilter = "(&(objectClass=contactPerson)(marker=$marker))";
     $_SESSION[ldapab][filter] = $filter;
     if(empty($filter)) $filter='a';
 
     if(!empty($marker)){
       $marker = utf8_encode($marker);
       $ldapfilter = "(&(objectClass=contactPerson)(marker=$marker))";
+    }elseif(!empty($categories)){
+      $categories = utf8_encode($categories);
+      $ldapfilter = "(&(objectClass=OXUserObject)(OXUserCategories=$categories))";
     }elseif(!empty($search)){
       $search = trim($search);
       $words=preg_split('/\s+/',$search);
     }elseif(!empty($search)){
       $search = trim($search);
       $words=preg_split('/\s+/',$search);
index 1a16c6a8ee01fb20992643c94a8043ec93a1b8fc..18b0b65fd8ea0ab919af475f800cf5f30df979a3 100644 (file)
@@ -2,7 +2,7 @@
 
 $lang[ldapab]         = 'The LDAP address book';
 
 
 $lang[ldapab]         = 'The LDAP address book';
 
-$lang[name]           = 'Name';
+$lang[name]           = 'Last Name';
 $lang[givenname]      = 'First Name';
 $lang[title]          = 'Title';
 $lang[organization]   = 'Company';
 $lang[givenname]      = 'First Name';
 $lang[title]          = 'Title';
 $lang[organization]   = 'Company';
@@ -66,4 +66,16 @@ $lang[msg_uploadvcf]  = 'Upload VCard File';
 
 $lang[err_noentries]  = 'No entries';
 $lang[err_ldap]       = 'The LDAP server returned the following errors';
 
 $lang[err_noentries]  = 'No entries';
 $lang[err_ldap]       = 'The LDAP server returned the following errors';
+
+$lang[openxchange]    = 'Xchange Information';
+$lang[moreopenxchange]    = 'Xchange Information Cont\'d';
+$lang[instantmessenger] = 'Inst Msg';
+$lang[categories]     = 'Categories';
+$lang[birthday]       = 'Birthday';
+$lang[domain]         = 'Mail Domain';
+$lang[country]        = 'Country';
+$lang[certificate]    = 'x.509 Cert';
+$lang[timezone]       = 'Time Zone';
+$lang[position]       = 'Position';
+$lang[ipphone]        = 'IP Phone';
 ?>
 ?>
index 7448a2424db58020ab41a35fd127b330e49e7362..dbe4b5ec5fa0e66d72be17804137dde849e8b2c7 100644 (file)
@@ -58,6 +58,10 @@ function tpl_entry($in){
     //handle marker special in extended mode
     $out['marker'] = $in['marker'];
   }
     //handle marker special in extended mode
     $out['marker'] = $in['marker'];
   }
+  if ($conf[openxchange]){
+    //handle categories special in openxchange mode
+    $out['categories'] = $in['OXUserCategories'];
+  }
 
   //decode array
   utf8_decode_array($out);
 
   //decode array
   utf8_decode_array($out);
@@ -160,4 +164,121 @@ function tpl_orgs(){
   $smarty->assign('orgs',$orgs);
 }
 
   $smarty->assign('orgs',$orgs);
 }
 
+/**
+ * assigns all categories to the template
+ */
+function tpl_categories(){
+  global $conf;
+  global $LDAP_CON;
+  global $smarty;
+
+  if(!$conf[openxchange]) return;
+
+  $categories = array();
+
+  $sr = ldap_list($LDAP_CON,$conf[publicbook],"ObjectClass=OXUserObject",array("OXUserCategories"));
+  $result1 = ldap_get_binentries($LDAP_CON, $sr);
+  //check users private addressbook
+  if(!empty($_SESSION[ldapab][binddn])){
+    $sr = @ldap_list($LDAP_CON,
+                    $conf[privatebook].','.$_SESSION[ldapab][binddn],
+                    "ObjectClass=OXUserObject",array("OXUserCategories"));
+    $result2 = ldap_get_binentries($LDAP_CON, $sr);
+  }
+  $result = array_merge($result1,$result2);
+
+  if(count($result)){
+    foreach ($result as $entry){
+      if(count($entry['OXUserCategories'])){
+        foreach($entry['OXUserCategories'] as $category){
+          array_push($categories, $category);
+        }
+      }
+    }
+  }
+  $categories = array_unique($categories);
+  sort($categories,SORT_STRING);
+  utf8_decode_array($categories);
+  $smarty->assign('categories',$categories);
+}
+
+/**
+ * assigns all timezones to the template
+ */
+function tpl_timezone(){
+  global $conf;
+  global $LDAP_CON;
+  global $smarty;
+
+  if(!$conf[openxchange]) return;
+
+  $timezone = array();
+
+  $sr = ldap_list($LDAP_CON,$conf[publicbook],"ObjectClass=OXUserObject",array("OXTimeZone"));
+  $result1 = ldap_get_binentries($LDAP_CON, $sr);
+  //check users private addressbook
+  if(!empty($_SESSION[ldapab][binddn])){
+    $sr = @ldap_list($LDAP_CON,
+                    $conf[privatebook].','.$_SESSION[ldapab][binddn],
+                    "ObjectClass=OXUserObject",array("OXTimeZone"));
+    $result2 = ldap_get_binentries($LDAP_CON, $sr);
+  }
+  $result = array_merge($result1,$result2);
+
+  if(count($result)){
+    foreach ($result as $entry){
+      if(count($entry['OXTimeZone'])){
+        foreach($entry['OXTimeZone'] as $tz){
+          array_push($timezone, $tz);
+        }
+      }
+    }
+  }
+  $timezone = array_unique($timezone);
+  sort($timezone,SORT_STRING);
+  utf8_decode_array($timezone);
+  $smarty->assign('timezone',$timezone);
+}
+
+/**
+ * assigns all countries to the template
+ */
+function tpl_country(){
+  global $conf;
+  global $LDAP_CON;
+  global $smarty;
+
+  if(!$conf[openxchange]) return;
+
+  $country = array();
+
+  $sr = ldap_list($LDAP_CON,$conf[publicbook],"ObjectClass=OXUserObject",array("userCountry"));
+  $result1 = ldap_get_binentries($LDAP_CON, $sr);
+  //check users private addressbook
+  if(!empty($_SESSION[ldapab][binddn])){
+    $sr = @ldap_list($LDAP_CON,
+                    $conf[privatebook].','.$_SESSION[ldapab][binddn],
+                    "ObjectClass=OXUserObject",array("userCountry"));
+    $result2 = ldap_get_binentries($LDAP_CON, $sr);
+  }
+  $result = array_merge($result1,$result2);
+
+  if(count($result)){
+    foreach ($result as $entry){
+      if(count($entry['userCountry'])){
+        foreach($entry['userCountry'] as $c){
+          array_push($country, $c);
+        }
+      }
+    }
+  }
+  $country = array_unique($country);
+  sort($country,SORT_STRING);
+  utf8_decode_array($country);
+  $smarty->assign('country',$country);
+}
+
 ?>
 ?>
index de2283dddc973ec96f8309940565bced496807e1..be8f3a90603f0599a30b1481e48dfbd73954d00f 100644 (file)
     </td>
   </tr>
   {/if}
     </td>
   </tr>
   {/if}
+  {if $conf.openxchange}
+    {include file="openxchange_edit.tpl"}
+  {/if}
   <tr>
     <td colspan="2" align="center"><br><input type="submit" class="input" value="{$lang.submit}"></td>
   </tr>
   <tr>
     <td colspan="2" align="center"><br><input type="submit" class="input" value="{$lang.submit}"></td>
   </tr>
index b87a69efefe63c00b0c1acb7786e634f77ae61cc..da5f3914687b152af445c7c357f8712dd6393561 100644 (file)
     </td>
   </tr>
 </table>
     </td>
   </tr>
 </table>
+      {if $conf.openxchange}
+        {include file="openxchange_show.tpl"}
+      {/if}
 <br><br><br>
 
 <br><br><br>
 
index 1cecd9263e792b6831e6d57f523c44836ce377fb..e5c2ab57a47c2954e2872a583ddbad55a7905910 100644 (file)
   <a href="index.php?filter=other">#</a>
   <a href="index.php?filter=*">*</a>
 </td>
   <a href="index.php?filter=other">#</a>
   <a href="index.php?filter=*">*</a>
 </td>
+{if $conf.openxchange}
+<td class="filterrow" align="right">
+  <form method="get" action="index.php" style="display:inline">
+    <select name="categories" class="searchfield">
+      <option value="">--- {$lang.categories} ---</option>
+      {html_options values=$categories output=$categories selected=$smarty.request.categories}
+    </select>
+    <input type="submit" value="{$lang.search}" class="searchbutton">
+  </form>
+</td>
+{/if}
 {if $conf.extended}
 <td class="filterrow" align="right">
   <form method="get" action="index.php" style="display:inline">
 {if $conf.extended}
 <td class="filterrow" align="right">
   <form method="get" action="index.php" style="display:inline">
diff --git a/templates/openxchange_edit.tpl b/templates/openxchange_edit.tpl
new file mode 100644 (file)
index 0000000..0856a4f
--- /dev/null
@@ -0,0 +1,71 @@
+<tr>
+<td width="50%" valign="top" align="center">
+  <table>
+  <tr>
+    <td colspan="2"><b>{$lang.openxchange}</b></td>
+  </tr>
+  <tr>
+    <td align="right" valign="top">{$lang.birthday}:</td>
+    <td><input type="text" class="input" name="entry[birthday]" value="{$entry.birthday|escape}"></td>
+  </tr>
+  <tr>
+    <td align="right" valign="top">{$lang.ipphone}:</td>
+    <td><input type="text" class="input" name="entry[ipphone]" value="{$entry.ipphone|escape}"></td>
+  </tr>
+  <tr>
+    <td align="right" valign="top">{$lang.instantmessenger}:</td>
+    <td><input type="text" class="input" name="entry[instantmessenger]" value="{$entry.instantmessenger|escape}"></td>
+  </tr>
+  <tr>
+    <td align="right" valign="top">{$lang.domain}:</td>
+    <td><input type="text" class="input" name="entry[domain]" value="{$entry.domain|escape}"></td>
+  </tr>
+  <tr>
+    <td align="right" valign="top">{$lang.certificate}:</td>
+    <td>
+      <textarea name="entry[certificate]" rows=6 cols=28 onClick="this.form.elements['entry[certificate]'].select();">{$entry.certificate|escape}</textarea>
+      <br>
+      <input type=button name=clearCert value="Clear" onClick="if (confirm('Are you sure?')) this.form.elements['entry[certificate]'].value='';">
+    </td>
+  </tr>
+  </table>
+</td>
+<td width="50%" valign="top" align="center">
+  <table>
+  <tr>
+    <td colspan="2"><b>{$lang.moreopenxchange}</b></td>
+  </tr>
+  <tr>
+    <td align="right" valign="top">{$lang.country}:</td>
+    <td>
+      <select name="entry[country][]" class="input">
+        <option value="">--- {$lang.select} ---</option>
+        {html_options values=$country output=$country selected=$entry.country}
+      </select><br>
+      <input type="text" class="inputbr" name="entry[country][]"><br>
+    </td>
+  </tr>
+  <tr>
+    <td align="right" valign="top">{$lang.timezone}:</td>
+    <td>
+      <select name="entry[timezone][]" class="input">
+        <option value="">--- {$lang.select} ---</option>
+        {html_options values=$timezone output=$timezone selected=$entry.timezone}
+      </select><br>
+      <input type="text" class="inputbr" name="entry[timezone][]"><br>
+    </td>
+  </tr>
+  <tr>
+    <td align="right" valign="top">{$lang.categories}:</td>
+    <td>
+      <select name="entry[categories][]" size="5" class="input" multiple="multiple">
+        {html_options values=$categories output=$categories selected=$entry.categories}
+      </select><br>
+      <input type="text" class="inputbr" name="entry[categories][]"><br>
+      <input type="text" class="inputbr" name="entry[categories][]"><br>
+    </td>
+
+  </tr>
+</table>
+</td>
+</tr>
diff --git a/templates/openxchange_show.tpl b/templates/openxchange_show.tpl
new file mode 100644 (file)
index 0000000..6f50348
--- /dev/null
@@ -0,0 +1,72 @@
+<table width="100%">
+  <tr>
+      <td width="50%" valign="top">
+       <b>{$lang.openxchange}</b>
+<dl><dd>
+  <table>
+    {if $entry.birthday}
+    <tr>
+      <td align="right">{$lang.birthday}:</td>
+      <td>{$entry.birthday}</td>
+    </tr>
+    {/if}
+    {if $entry.ipphone}
+    <tr>
+      <td align="right">{$lang.ipphone}:</td>
+      <td>{$entry.ipphone}</td>
+    </tr>
+    {/if}
+    {if $entry.instantmessenger}
+    <tr>
+      <td align="right">{$lang.instantmessenger}:</td>
+      <td>{$entry.instantmessenger}</td>
+    </tr>
+    {/if}
+    {if $entry.domain}
+    <tr>
+      <td align="right">{$lang.domain}:</td>
+      <td>{$entry.domain}</td>
+    </tr>
+    {/if}
+    {if $entry.certificate}
+    <tr>
+      <td align="right">{$lang.certificate}:</td>
+      <td><form>
+        <textarea rows=3 cols=28 name='certificate' onClick='this.form.certificate.select();'>{$entry.certificate}</textarea>
+       </form></td>
+    </tr>
+    {/if}
+  </table>
+</dd></dl>
+</td>
+      <td width="50%" valign="top">
+       <b>{$lang.moreopenxchange}</b>
+<dl><dd>
+<table >
+    {if $entry.country}
+    <tr>
+      <td align="right">{$lang.country}:</td>
+      <td>{$entry.country}</td>
+    </tr>
+    {/if}
+    {if $entry.timezone}
+    <tr>
+      <td align="right">{$lang.timezone}:</td>
+      <td>{$entry.timezone}</td>
+    </tr>
+    {/if}
+    {if $entry.categories}
+    <tr>
+      <td valign="top" align="right">{$lang.categories}:</td>
+      <td>
+        {foreach from=$entry.categories item=categories}
+          {$categories}<br>
+        {/foreach}
+      </td>
+    </tr>
+    {/if}
+</table>
+</dd></dl>
+      </td>
+  </tr>
+</table>