Sexier phonebook theme thanks to chowse, better authentication, bigger thumbnails, and CSV output support

git-svn-id: http://svn.mozilla.org/projects/phonebook/trunk@48216 4eb1ac78-321c-0410-a911-ec516a8615a5
This commit is contained in:
wlee@mozilla.com 2009-07-30 21:57:32 +00:00
Родитель 6d74e2316f
Коммит b06da0d757
8 изменённых файлов: 299 добавлений и 151 удалений

Просмотреть файл

@ -1,118 +1,207 @@
body {
font-family: Georgia, serif;
font-size: 12px;
padding: 15px;
* {
margin: 0;
background: url(background.jpg) repeat-x fixed;
}
a:link, a:visited {
color: #0489B7;
padding: 0;
font-family: inherit;
font-size: 100%;
font-weight: inherit;
font-style: inherit;
text-decoration: none;
}
list-style: none;
}
html {
font: 16px "Lucida Grande", "Lucida Sans Unicode", sans-serif;
font-weight: normal;
font-style: normal;
background: url(../img/bg.png) #67a7c7 repeat-x fixed;
color: #fff;
}
a:hover {
text-decoration: underline;
}
}
#phonebook-label {
font-weight: bold;
font-size: 2em;
margin-right: 1em;
display: inline;
}
#links, #links li {
display: inline;
}
#links li {
border-right: 1px solid black;
padding: 0 1em 0 1em;
}
#links li:last-child {
border-right: none;
}
div.vcard {
width: 26em;
padding: 1em;
margin: 0.5em;
background: rgba(255, 255, 255, 0.25);
border: 1px solid rgba(64, 64, 64, 0.5);
-moz-border-radius: 0.5em;
display: inline-block;
vertical-align: top;
min-height: 18em;
}
div.vcard img.photo {
float: right;
margin-left: 1em;
}
div.vcard p.fn {
margin: 0;
font-size: 1.25em;
font-weight: bold;
}
div.vcard p.title {
font-size: 1.2em;
}
div.vcard p.title, div.vcard p.employee-type, div.vcard p.manager {
margin: 0;
color: #555;
}
div.adr {
#header {
position: relative;
width: 60em;
margin: 1.5em auto 1.5em auto;
}
#header h1 {
position: absolute;
width: 220px;
height: 44px;
left: 0;
top: -11px;
background: url(../img/phonebook.png) no-repeat;
text-indent: -1000em;
}
}
#search-region {
display: inline;
margin-left: 240px;
font-size: .875em;
}
div.telecommunications ul {
padding-left: 0;
list-style-type: none;
}
#menu {
display: inline;
margin-left: 2em;
}
#menu li {
display: inline;
margin-left: 1.5em;
font-size: .857em;
}
#menu a {
color: #acd1e3;
}
#menu li.edit {
float: right;
padding-left: 24px;
background: url(../img/edit.png) no-repeat 0 center;
}
li.tel {
background: url(../img/phone.png) no-repeat;
height: 16px;
padding-left: 16px;
}
a[href^="mailto:"] {
background: url(../img/email.png) no-repeat;
height: 16px;
padding-left: 18px;
}
div.vcard hr {
height: 1px;
color: #555;
background-color: #555;
border: none;
}
table.edit-table tr td {
padding-bottom: 1em;
}
#results {
overflow: auto;
width: 62em;
margin: 0 auto;
}
.vcard {
display: block;
display: inline-block;
width: 31em;
vertical-align: top;
margin-top: 1em;
}
.vcard .header,
.vcard .body,
.vcard .footer {
width: 434px;
padding: 0 20px;
margin: 0 auto;
}
.vcard .header {
position: relative;
height: 45px;
background: url(../img/vcard_header.png) no-repeat;
}
.vcard .header h2 {
position: absolute;
left: 20px;
top: 12px;
font-family: georgia, sans-serif;
font-size: 1.31em;
color: #fff;
}
.vcard .body {
overflow: auto;
min-height: 200px;
padding-top: 10px;
padding-bottom: 10px;
background: url(../img/vcard_body.png) repeat-y;
font-size: .875em;
color: #343434;
line-height: 1.3;
}
.vcard .body a {
color: #276787;
}
.vcard .body div,
.vcard .body ul {
padding: .375em 0;
padding-left: 24px;
border-bottom: 1px dotted #acd1e3;
background-repeat: no-repeat;
background-position: 0 .375em;
}
.vcard .body div:first-child {
padding-top: 0;
}
.vcard .body div:last-child {
padding-bottom: 0;
border-bottom: none;
}
.vcard .body li,
.vcard .body p {
}
.vcard .photo {
float: right;
padding: 0 0 1em 1em;
background: #fff;
}
.vcard .body div.employee {
padding-left: 0;
padding-top: 0;
padding-bottom: .75em;
border-bottom: none;
}
.vcard .title {
font-family: georgia, serif;
font-size: 1.28em;
color: #000;
}
.vcard .employee-type {
font-family: georgia, serif;
color: #686868;
}
.vcard .manager {
font-family: georgia, serif;
}
.vcard .adr {
background-image: url(../img/world.png);
}
.vcard .telecommunications {
background-image: url(../img/telephone.png);
}
.vcard .email {
background-image: url(../img/email.png);
}
.vcard .bugmail {
background-image: url(../img/bugzilla.png);
}
.vcard .im {
background-image: url(../img/im.png);
}
.vcard .note {
background-image: url(../img/work.png);
}
.vcard .footer {
height: 36px;
background: url(../img/vcard_footer.png) no-repeat;
}
#email-alias-add, #phone-number-add, #im-add {
padding-left: 18px;
background: url(../img/add.png) no-repeat;
}
}
a.remove-link {
a.remove-link {
padding-left: 16px;
background: url(../img/remove.png) no-repeat;
}
}
td input + a {
margin-left: 0.5em;
}
table.edit-table {
font-size: 12px;
}
table.edit-table a {
color: #acd1e3
}
table.edit-table td {
padding: 0.5em;
}
table.edit-table tr td:first-child {
vertical-align: top;
}
td input + a {
margin-left: 0.5em;
}
.autocomplete-w1 {
background:url(../img/shadow.png) no-repeat bottom right;
@ -120,8 +209,9 @@ td input + a {
top: 4px;
left: 3px;
/* IE6 fix: */
_background: none;_top: 1px;
}
_background: none;
_top: 1px;
}
.autocomplete {
width: 300px;
@ -136,20 +226,19 @@ td input + a {
_height: 350px;
_margin: 0px 6px 6px 0;
overflow-x: hidden;
}
}
.autocomplete .selected {
background: #CCC;
}
.autocomplete .selected {
background: #CCC;
}
.autocomplete div {
padding: 2px 5px;
white-space: nowrap;
}
.autocomplete strong {
font-weight: normal;
color: #0489B7;
}
.autocomplete div {
padding: 2px 5px;
white-space: nowrap;
}
.autocomplete strong {
font-weight: normal;
color: #0489B7;
}

Просмотреть файл

@ -1,14 +1,34 @@
<?php
function ask() {
header('WWW-Authenticate: Basic realm="Mozilla Corporation - LDAP Login"');
}
function wail_and_bail() {
header('HTTP/1.0 401 Unauthorized');
ask();
print "<h1>401 Unauthorized</h1>";
die;
}
function get_ldap_connection() {
$ldapconn = ldap_connect(LDAP_HOST);
if (!isset($_SERVER["PHP_AUTH_USER"])) {
header('WWW-Authenticate: Basic realm="Mozilla Corporation - LDAP Login"');
ask();
wail_and_bail();
} else {
// Check for validity of login
if (preg_match("/[a-z]+@mozilla\\.com/", $_SERVER["PHP_AUTH_USER"])) {
$user_dn = "mail=". $_SERVER["PHP_AUTH_USER"] .",o=com,dc=mozilla";
$password = $_SERVER["PHP_AUTH_PW"];
} else {
wail_and_bail();
}
}
$user_dn = "mail=". $_SERVER["PHP_AUTH_USER"] .",o=com,dc=mozilla";
if (!ldap_bind($ldapconn, $user_dn, $_SERVER['PHP_AUTH_PW'])) {
wail_and_bail();
die(ldap_error($ldapconn));
}

Просмотреть файл

@ -68,29 +68,32 @@
});
var listify = function(a) {
return "<ul>" + $A(a).map(function(x) {
return $A(a).map(function(x) {
return "<li>" + x + "</li>";
}).join('') + "</ul>";
}).join('');
};
var emailLinkify = function(s) {
return '<a class="value" href="mailto:#{s}">#{s}</a>'.interpolate({s: s});
return '<li><a class="value" href="mailto:#{s}">#{s}</a></li>'.interpolate({s: s});
};
var processors = $H({
"email": emailLinkify,
"emailalias": emailLinkify.wrap(function(original, email) {
email = Object.isString(email) ? [email] : $A(email);
return ", " + email.map(original).join(", ");
return email.map(original);
}),
"employeetype": function(l) { return l.join(", "); },
"im": listify,
"im": listify.wrap(function(original, im) {
return im ? ('<ul class="im">' + original(im) + '</ul>') : '';
}),
"mobile": listify.wrap(function(original, list) {
return original(list).replace(/<li>/, '<li class="tel">');
return '<ul class="telecommunications">' +
original(list).replace(/<li>/, '<li class="tel">') + '</ul>';
}),
"description": function(s) {
return '<p class="note">I work on: #{s}</p>'.interpolate({s: s});
return '<div class="note">I work on: #{s}</div>'.interpolate({s: s});
},
"other": function(s) {
return "<hr />" + s;
return '<div class="other">' + s + '</div>';
},
"manager": function(m) {
return '<p class="manager">Manager: <a href="#search/#{email}">#{name}</a></p>'.interpolate({
@ -98,7 +101,10 @@
name: m.cn
});
},
"telephonenumber": function(x) { return "ext. " + x; }
"telephonenumber": function(x) { return "ext. " + x; },
"bugzillaemail": function(s) {
return '<ul class="bugmail"><li><a title="Bugmail">#{s}</a></li></ul>'.interpolate({s: s});
}
});
function startSearch() {
@ -139,22 +145,24 @@
function template(person) {
return [
'#{picture}<p class="fn">#{cn}</p>',
'<p class="title">#{title}</p>',
'<p class="employee-type">#{employeetype}</p>',
'<div class="adr">#{telephonenumber} @ ',
'<span class="locality">#{physicaldeliveryofficename}</span>',
'</div>',
'#{manager}',
'<div class="telecommunications">',
'<div class="header"><h2 class="fn">#{cn}</h2></div>',
'<div class="body">#{picture}',
'<div class="employee">',
'<p class="title">#{title}</p>',
'<p class="employee-type">#{employeetype}</p>',
'#{manager}',
'</div>',
'<ul class="adr"><li>#{telephonenumber} @ ',
'<span class="locality">#{physicaldeliveryofficename}</span>',
'</li></ul>',
// '#{bugzillaemail}',
'#{mobile}',
'<p class="email">',
'#{email}#{emailalias}',
'</p>',
'<ul class="email">#{email}#{emailalias}</ul>',
'#{bugzillaemail}',
'#{im}',
'</div>',
'#{description}',
'#{other}'
'#{description}',
'#{other}',
'</div><div class="footer"></div>'
].join('').interpolate(person);
}
});
@ -164,14 +172,16 @@
<body>
<div id="header">
<form action="search.php" method="get" id="phonebook-search">
<label for="text" id="phonebook-label">Phonebook</label>
<input type="text" name="query" id="text" />
<input type="submit" value="Search" id="search" />
<ul id="links">
<h1>Phonebook</h1>
<div id="search-region">
<input type="text" name="query" id="text" />
<input type="submit" value="Search" id="search" />
</div>
<ul id="menu">
<li><a href="./#search/*">Everyone</a></li>
<li><a href="https://intranet.mozilla.org/">Intranet</a></li>
<li><a href="https://intranet.mozilla.org/OfficeLocations">Office Locations</a></li>
<li><a href="edit.php" id="edit-entry">Edit Entry</a></li>
<li><a href="https://intranet.mozilla.org/OfficeLocations">Offices</a></li>
<li class="edit"><a href="edit.php" id="edit-entry">Edit My Entry</a></li>
</ul>
</form>
</div>

Просмотреть файл

@ -3,7 +3,7 @@ ini_set("include_path", ini_get("include_path").':'.dirname(dirname(__FILE__)));
error_reporting(E_ALL);
ini_set("display_errors", 1);
ini_set("memory_limit", "32M");
ini_set("memory_limit", "64M");
define("MEMCACHE_ENABLED", true);
$easteregg = false;
$prototype = false;

23
output-csv.inc Normal file
Просмотреть файл

@ -0,0 +1,23 @@
<?php
function output_csv($data) {
header("Content-Type: text/csv");
$f = fopen("php://output", 'w');
global $editable_fields;
fputcsv($f, $editable_fields);
foreach ($data as $pto) {
$row = array();
foreach ($editable_fields as $field) {
$field = strtolower($field);
$value = isset($pto[$field]) ? $pto[$field] : '';
if (is_array($value)) {
$value = implode(", ", $value);
}
$row[] = $value;
}
fputcsv($f, $row);
}
fclose($f);
die;
}

Просмотреть файл

@ -2,4 +2,5 @@
require_once("output-json.inc");
require_once("output-vcard.inc");
require_once("output-autocomplete.inc");
require_once("output-csv.inc");

Просмотреть файл

@ -3,8 +3,11 @@
require_once('init.php');
define("NULL_PIC", dirname(__FILE__) . "/img/null.jpg");
$width = "120";
$height = "150";
// $width = "120";
// $height = "150";
$width = "140";
$height = "175";
//if (!empty($_GET['width']) {
// $width = $_GET['width']);

Просмотреть файл

@ -88,14 +88,16 @@
<div id="header">
<form action="search.php" method="get" id="phonebook-search">
<label for="text" id="phonebook-label">Phonebook</label>
<input type="text" name="search" id="text" />
<input type="submit" value="Search" id="search" />
<ul id="links">
<h1>Phonebook</h1>
<div id="search-region">
<input type="text" name="query" id="text" />
<input type="submit" value="Search" id="search" />
</div>
<ul id="menu">
<li><a href="./#search/*">Everyone</a></li>
<li><a href="https://intranet.mozilla.org/">Intranet</a></li>
<li><a href="https://intranet.mozilla.org/OfficeLocations">Office Locations</a></li>
<li><a href="edit.php" id="edit-entry">Edit Entry</a></li>
<li><a href="https://intranet.mozilla.org/OfficeLocations">Offices</a></li>
<li class="edit"><a href="edit.php" id="edit-entry">Edit My Entry</a></li>
</ul>
</form>
</div>