t('PEAR Contact_Vcard_Build'), 'value' => $init ? t('Available.') : t('Not available.'), 'description' => t(l('PEAR Contact_Vcard_Build package', 'http://pear.php.net/package/Contact_Vcard_Build') .' for vcard generation.'), 'severity' => $init ? REQUIREMENT_OK : REQUIREMENT_ERROR, ); } return $requirement; } /** * Implementation of hook_help(). */ function vcard_help($section) { switch ($section) { case 'admin/help#vcard': return t("
vCard automates the exchange of personal information typically found on a traditional business card. vCard is used in applications such as Internet mail, voice mail, Web browsers, telephony applications, call centers, video conferencing, PIMs (Personal Information Managers), PDAs (Personal Data Assistants), pagers, fax, office equipment, and smart cards. vCard information goes way beyond simple text, and includes elements like pictures, company logos, live Web addresses, and so on.
Web browsers and !aggregation_tools can also extract and use vCard-like information when it is displayed on the page using !hcard - an embedded !microformat. Read the vCard module's INSTALL.txt documentation for more information on how to add hCard support to your theme.
",
array(
'!aggregation_tools' => l('aggregation tools', 'https://addons.mozilla.org/en-US/firefox/addon/2240'),
'!hcard' => l('hCard', 'http://microformats.org/wiki/hcard'),
'!microformat' => l('microformat', 'http://microformats.org'),
)
);
break;
case 'admin/user/profile':
return t("
For assistance setting up a default profile with common fields, visit
the VCard settings which can preset an automatic profile definition.
To enable machine-readable microformats
for your profiles, see the vCard help and README.
",
array(
'!vcard_settings_link' => url('admin/settings/vcard'),
'!vcard_help_link' => url('admin/help/vcard'),
'!microformat_link' => url('http://microformats.org'),
)
);
case 'admin/settings/vcard':
return t("
Profile fields are added and administered on
the Profile Configuration page.
",
array(
'!profile_settings_link' => url('admin/user/profile'),
)
);
}
}
/**
* Implementation of hook_menu().
*/
function vcard_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/settings/vcard',
'title' => t('vCard'),
'callback' => 'drupal_get_form',
'callback arguments' => 'vcard_admin_settings',
'description' => 'Configure the profile field mapuserpings.',
'access' => user_access('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
);
}
else {
if (arg(0) == 'user' && is_numeric(arg(1))) {
$items[] = array(
'path' => 'user/'. arg(1) .'/vcard',
'title' => t('vcard'),
'type' => MENU_CALLBACK,
'callback' => 'vcard_fetch',
'access' => user_access('access user profiles'),
);
}
}
return $items;
}
/**
* Callback for administration page.
*/
function vcard_admin_settings() {
if (!_vcard_init()) {
drupal_set_message(t('The PEAR package Contact_Vcard_Build (required by vcard.module) has not been installed properly, please read INSTALL.txt.'), 'error');
}
$form['field_mappings'] = array(
'#type' => 'fieldset',
'#title' => t('Field Mappings'),
'#description' => t('This section is only enabled if the "profiles" module is enabled. When enabled it will provide a dropdown selection box for each defined profile item of type textfield, textarea, or url.'),
);
$form['auto_create'] = array(
'#type' => 'submit',
'#value' => t('Auto-create profile fields'),
'#description' => t("Attempt to create the normal required profile fields, if you haven't already done so'"),
);
$form['#submit']['vcard_auto_create_profile_submit'] = array();
$options = array('' => 'Select a property');
$options = $options + _vcard_properties();
foreach (_vcard_profile_fields() as $fid => $title) {
$form['field_mappings']['vcard_profile_'. $fid] = array(
'#type' => 'select',
'#title' => t('Property for ') . $title,
'#default_value' => variable_get('vcard_profile_'. $fid, ''),
'#options' => $options,
);
}
return system_settings_form($form);
}
/**
* Implementation of hook_user().
* Adds a vcard icon and link to the user page
*/
function vcard_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case 'view':
if (_vcard_init()) {
$items[] = array(
'value' => theme('image', drupal_get_path('module', 'vcard') .'/vcard.png', t('Download vcard')) .' '. l(t('Download vcard'), 'user/'. $account->uid .'/vcard', NULL, NULL, NULL, FALSE, TRUE),
);
return array(t('vCard') => $items);
}
}
}
/**
* VCard for direct download
*/
function vcard_fetch() {
$account = user_load(array('uid' => arg(1)));
$vcard = _vcard_init();
$first = vcard_get_field('givenname', $account);
$last = vcard_get_field('familyname', $account);
if (!empty($first) && !empty($last)) {
$vcard->setName($last, $first, '', '', '');
$vcard->setFormattedName($first .' '. $last);
}
else {
$vcard->setName($account->name, '', '', '', '');
$vcard->setFormattedname($account->name);
}
$vcard->addEmail($account->mail);
$vcard->addNickname($account->name);
// Birthday
$birthday = vcard_get_field('birthday', $account);
if (!empty($birthday)) {
if (is_array($birthday)) {
$bday = $birthday['year'] .'-'. $birthday['month'] .'-'. $birthday['day'];
$vcard->setBirthday($bday);
}
else {
$vcard->setBirthday($bday);
}
}
// Organization
$org = vcard_get_field('organization', $account);
if (!empty($org)) {
$vcard->addOrganization($org);
}
// URL
$url = vcard_get_field('url', $account);
if (!empty($url)) {
$vcard->setURL($url);
}
// Telephone
$tel = vcard_get_field('telephone', $account);
if (!empty($tel)) {
$vcard->addTelephone($tel);
}
// Address
$street = vcard_get_field('street', $account);
$city = vcard_get_field('city', $account);
$province = vcard_get_field('province', $account);
$postal = vcard_get_field('postal', $account);
$country = vcard_get_field('country', $account);
$vcard->addAddress('', '', $street, $city, $province, $postal, $country);
if ($account->location['latitude'] && $account->location['longitude']) {
$vcard->setGeo($account->location['latitude'], $account->location['longitude']);
}
header('Content-type: text/x-vcard');
header('Content-Disposition: attachment; filename="'. $account->name .'.vcf"');
print $vcard->fetch();
exit;
}
/**
* Displays user contact information decorated with hCard microformats.
*
* Use this in your theme to replace theme_user_profile() or
* theme_profile_listing()
*
* Uses hCard as the default xHTML
* see http://microformats.org/wiki/hcard
*
* @param $account user object
* @param $fields a structured (nested) array of profile field definitions and
* values. Access visibility (public/private etc) has already filtered them to
* the ones that should be displayed. Settings are on the profile fields
* 'visibility' setting. If not set, all account info may be displayed!
*/
function theme_vcard($account, $fields = NULL) {
if(! $fields) { $fields = array() ; }
// Flatten the fields (which may have previously been grouped by category) so I can access them directly by id
$all_fields = array();
foreach ($fields as $category => $items) {
if(is_array($items)){
$all_fields = array_merge($all_fields, $items);
}
else {
$all_fields[$items->name] = $items;
}
}
#drupal_set_message(''. print_r($all_fields, 1) .'
');
// For privacy, only profile fields that have an entry in 'fields' should be displayed
// Respect this by only accessing values listed in $fields
if(! empty($all_fields)){
foreach ($account as $var => $val) {
if (! $all_fields[$var]) {
if (($var != 'picture') && ($var != 'name')) {
// Temporarily blank this info
unset($account->$var);
}
}
}
}
// photo
if (variable_get('user_pictures', 0)) {
if ($account->picture && file_exists($account->picture)) {
$picture = file_create_url($account->picture);
}
else if (variable_get('user_picture_default', '')) {
$picture = variable_get('user_picture_default', '');
}
if ($picture) {
$photo = '
';
}
}
$url = vcard_get_field('url', $account);
// name
$firstname = vcard_get_field('givenname', $account);
$lastname = vcard_get_field('familyname', $account);
if ($firstname && $lastname) {
$name = '';
if ($url) {$name .= ''; }
$name .= ''. $firstname ."\n";
$name .= ''. $lastname ."\n";
if ($url) {$name .= ""; }
$name .= ''. $account->name ."\n";
$name .= "\n";
}
else {
$name = ''. $account->name ."\n";
}
$street = vcard_get_field('street', $account);
$city = vcard_get_field('city', $account);
$province = vcard_get_field('province', $account);
$postal = vcard_get_field('postal', $account);
$country = vcard_get_field('country', $account);
if ($street || $city || $province || $postal || $country ) {
$address = '';
$address .= ($street) ? ''. $street ."\n" : '';
$address .= ($city) ? ''. $city ."\n" : '';
$address .= ($province) ? ''. $province ."\n" : '';
$address .= ($postal) ? ''. $postal ."\n" : '';
$address .= ($country) ? ''. $country ."\n" : '';
$address .= "\n";
}
if ($telephone = vcard_get_field('telephone', $account)) {
$tel = ''. $telephone ."\n";
}
if ($org = vcard_get_field('organization', $account)) {
$org = ''. $org ."\n";
}
$output .= '';
$output .= $photo;
$output .= $name;
$output .= $org;
$output .= $address;
$output .= $tel;
$output .= '
';
$output .= "\n";
return $output;
}
/**
*
*/
function vcard_get_field($field, $account) {
$vcard_map = _vcard_get_map($account);
return $vcard_map[$field];
}
/**
* Ensures the vcard PEAR library is available and returns the vCard builder
* object.
*
* @return vCard object, null if library is not available.
*/
function _vcard_init() {
if (@include_once('Contact_Vcard_Build.php')) {
$vcard = new Contact_Vcard_Build();
}
return $vcard ? $vcard : FALSE;
}
/**
*
*/
function _vcard_profile_fields() {
$output = array();
$result = db_query("SELECT fid, title FROM {profile_fields}");
while ($row = db_fetch_object($result)) {
$output[$row->fid] = $row->title;
}
return $output;
}
/**
*
*/
function _vcard_properties() {
return array(
'givenname' => t('Given Name'),
'familyname' => t('Family name'),
'birthday' => t('Birthday'),
'organization' => t('Organization'),
'telephone' => t('Telephone'),
'url' => t('URL'),
'street' => t('Street'),
'city' => t('City'),
'postal' => t('Postal'),
'province' => t('Province'),
'country' => t('Country'),
);
}
/**
*
*/
function _vcard_get_map($account) {
$map = array();
$result = db_query('SELECT fid, name FROM {profile_fields}');
while ($field = db_fetch_object($result)) {
$mapped = variable_get('vcard_profile_'. $field->fid, 0);
if ($mapped) {
$map[$mapped] = $account->{$field->name};
}
}
return $map;
}
/**
* Add an action to auto-create a detailed contact profile with consistant
* names.
*
* Capture the vcard settings submission, and act on the button if pressed.
*
* Although I could have just over-written everything, instead I take care to
* absorb half-profiles that have already been made, possibly with different
* names, and not replace anything that already works OK. This process just adds
* the supplimental contact vCard fields. Thus it should be safe to run as an
* upgrade over anything you already have.
*/
function vcard_auto_create_profile_submit($form_id, $form_values) {
if ($form_values['op'] == t('Auto-create profile fields')) {
drupal_set_message(t("Creating required profile fields"));
$required_fields = _vcard_properties();
// Load in all currently existing fields, to see what exists and what they are matched to so far.
$available_fields = array();
$available_fields_result = db_query('SELECT * FROM {profile_fields} ORDER BY weight ');
while ($field = db_fetch_object($available_fields_result)) {
// Index these on a version of the internal id, not the text label
$key = preg_replace('|^profile_|', '', $field->name);
if ($linked = variable_get('vcard_profile_'. $field->fid, "")) {
// This field is already linked to a vcard tag. Add it to the index in the right place
$key = $linked;
}
// There may be confusion if there are more than one field named the same. Don't do that.
if (! $available_fields[$key]) {
$available_fields[$key] = $field;
}
}
$vcard_fields = _vcard_profile_fields();
foreach ($required_fields as $required_field_id => $required_field_label) {
// Check if a field with its label is already existing
if (in_array($required_field_id, array_keys($available_fields))) {
$field_def = $available_fields[$required_field_id];
drupal_set_message(t(
"%field_label already exists as a profile field. %alt_name",
array(
'%field_label' => $required_field_label,
'!field_link' => url('admin/user/profile/edit/'. $field_def->fid),
'%alt_name' => (($field_def->title != $required_field_label) ? " (called $field_def->title)" : "")
)
));
}
else {
// need to make it
drupal_set_message(t("Creating profile field ") . $required_field_label);
// @see profile_field_form_submit()
$field_def = array(
'title' => $required_field_label,
'name' => 'profile_'. $required_field_id,
'explanation' => '',
'category' => 'Contact Information',
'type' => 'textfield',
'weight' => 0,
'required' => 0,
'register' => 1,
'visibility' => 2,
);
if ($required_field_id == 'url') {$field_def['type']='url';}
if ($required_field_id == 'birthday') {$field_def['type']='date';}
db_query("
INSERT INTO {profile_fields}
(title, name, explanation, category, type, weight, required, register, visibility, autocomplete, options, page)
VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, '%s', '%s')",
$field_def['title'], $field_def['name'], $field_def['explanation'], $field_def['category'], $field_def['type'], $field_def['weight'], $field_def['required'], $field_def['register'], $field_def['visibility'], $field_def['autocomplete'], $field_def['options'], $field_def['page']
);
// retrieve its new ID
$result = db_query('SELECT * FROM {profile_fields} WHERE name = "%s"', $field_def['name']);
$field_def = db_fetch_object($result);
}
// Now check the right profile field is matched up with the right vcard field
if ($field_def && (variable_get('vcard_profile_'. $field_def->fid, '') != $required_field_id)) {
drupal_set_message(t(
"Assigning profile field %fid (%title) to vcard key %required_field_id",
array(
'%fid' => $field_def->fid,
'%title' => $field_def->title,
'%required_field_id' => $required_field_id,
'!field_link' => url('admin/user/profile/edit/'. $field_def->fid)
)
));
variable_set('vcard_profile_'. $field_def->fid, $required_field_id);
}
}
drupal_set_message(t("
Created profile fields! You may want to review the profile settings
individually to ensure their display order and public visibility
settings are right for you.
By default they are all displayed on the users profile page.
"));
}
}