From d1e7e527ba63d2edea7b50689e5090dad2b8bfa4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 10 Jan 2023 16:31:12 +0100 Subject: [PATCH] Debug virtual card --- htdocs/core/class/vcard.class.php | 226 ++++++++++++++++++++---------- htdocs/public/users/view.php | 106 +++++++++----- htdocs/user/virtualcard.php | 8 ++ 3 files changed, 230 insertions(+), 110 deletions(-) diff --git a/htdocs/core/class/vcard.class.php b/htdocs/core/class/vcard.class.php index 8a62c0aea5e..0e9372360e6 100644 --- a/htdocs/core/class/vcard.class.php +++ b/htdocs/core/class/vcard.class.php @@ -117,22 +117,25 @@ class vCard if ($type != "") { $key .= ";".$type; } - $key .= ";".$this->encoding; - $this->properties[$key] = 'VALUE=uri:tel:'.encode($number); + $key .= ";VALUE=uri"; + //$key .= ";".$this->encoding; + $this->properties[$key] = 'tel:'.$number; } /** * mise en forme de la photo * warning NON TESTE ! * - * @param string $type Type 'image/gif' + * @param string $type Type 'image/jpeg' or 'JPEG' * @param string $photo Photo * @return void */ public function setPhoto($type, $photo) { // $type = "GIF" | "JPEG" - $this->properties["PHOTO;MEDIATYPE=$type;ENCODING=BASE64"] = base64_encode($photo); + //$this->properties["PHOTO;MEDIATYPE=$type;ENCODING=BASE64"] = base64_encode($photo); + $this->properties["PHOTO;MEDIATYPE=$type"] = $photo; // must be url of photo + //$this->properties["PHOTO;TYPE=$type;ENCODING=BASE64"] = base64_encode($photo); // must be content of image } /** @@ -152,13 +155,14 @@ class vCard * @param string $family Family name * @param string $first First name * @param string $additional Additional (e.g. second name, nick name) - * @param string $prefix Prefix (e.g. "Mr.", "Ms.", "Prof.") + * @param string $prefix Title prefix (e.g. "Mr.", "Ms.", "Prof.") * @param string $suffix Suffix (e.g. "sen." for senior, "jun." for junior) * @return void */ public function setName($family = "", $first = "", $additional = "", $prefix = "", $suffix = "") { - $this->properties["N;".$this->encoding] = encode($family).";".encode($first).";".encode($additional).";".encode($prefix).";".encode($suffix); + //$this->properties["N;".$this->encoding] = encode($family).";".encode($first).";".encode($additional).";".encode($prefix).";".encode($suffix); + $this->properties["N"] = encode($family).";".encode($first).";".encode($additional).";".encode($prefix).";".encode($suffix); $this->filename = "$first%20$family.vcf"; if (empty($this->properties["FN"])) { $this->setFormattedName(trim("$prefix $first $additional $family $suffix")); @@ -173,8 +177,9 @@ class vCard */ public function setBirthday($date) { - // $date format is YYYY-MM-DD - RFC 2425 and RFC 2426 - $this->properties["BDAY"] = dol_print_date($date, 'dayrfc'); + // $date format is YYYY-MM-DD - RFC 2425 and RFC 2426 for vcard v3 + // $date format is YYYYMMDD or ISO8601 for vcard v4 + $this->properties["BDAY"] = dol_print_date($date, 'dayxcard'); } /** @@ -309,7 +314,7 @@ class vCard */ public function setProdId($prodid) { - $this->properties["PRODID;".$this->encoding] = encode($prodid); + $this->properties["PRODID"] = encode($prodid); } @@ -321,7 +326,7 @@ class vCard */ public function setUID($uid) { - $this->properties["UID;".$this->encoding] = encode($uid); + $this->properties["UID"] = encode($uid); } @@ -355,7 +360,7 @@ class vCard foreach ($this->properties as $key => $value) { $text .= $key.":".$value."\r\n"; } - $text .= "REV:".date("Y-m-d")."T".date("H:i:s")."Z\r\n"; + $text .= "REV:".date("Ymd")."T".date("His")."Z\r\n"; //$text .= "MAILER: Dolibarr\r\n"; $text .= "END:VCARD\r\n"; return $text; @@ -374,12 +379,13 @@ class vCard /** * Return a VCARD string * - * @param Object $object Object (User, Contact) - * @param Societe $company Company - * @param Translate $langs Lang object - * @return string String + * @param Object $object Object (User or Contact) + * @param Societe|null $company Company. May be null + * @param Translate $langs Lang object + * @param string $urlphoto Full public URL of photo + * @return string String */ - public function buildVCardString($object, $company, $langs) + public function buildVCardString($object, $company, $langs, $urlphoto = '') { global $dolibarr_main_instance_unique_id; @@ -389,70 +395,136 @@ class vCard $this->setName($object->lastname, $object->firstname, "", $object->civility_code, ""); $this->setFormattedName($object->getFullName($langs, 1)); - $this->setPhoneNumber($object->office_phone, "TYPE=WORK,VOICE"); - $this->setPhoneNumber($object->personal_mobile, "TYPE=HOME,VOICE"); - $this->setPhoneNumber($object->user_mobile, "TYPE=CELL,VOICE"); - $this->setPhoneNumber($object->office_fax, "TYPE=WORK,FAX"); - - $country = $object->country_code ? $object->country : ''; - - $this->setAddress("", "", $object->address, $object->town, $object->state, $object->zip, $country, "TYPE=WORK"); - //$this->setLabel("", "", $object->address, $object->town, $object->state, $object->zip, $country, "TYPE=WORK"); - - $this->setEmail($object->email, "TYPE=WORK"); - $this->setNote($object->note_public); - $this->setTitle($object->job); - - // For user, type=home - // For contact, this is not defined - $this->setURL($object->url, "TYPE=HOME"); - - if (is_object($company)) { - $this->setURL($company->url, "TYPE=WORK"); - - if (!$object->office_phone) { - $this->setPhoneNumber($company->phone, "TYPE=WORK,VOICE"); - } - if (!$object->office_fax) { - $this->setPhoneNumber($company->fax, "TYPE=WORK,FAX"); - } - if (!$object->zip) { - $this->setAddress("", "", $company->address, $company->town, $company->state, $company->zip, $company->country, "TYPE=WORK"); - } - - // when company e-mail is empty, use only user e-mail - if (empty(trim($company->email))) { - // was set before, don't set twice - } elseif (empty(trim($object->email))) { - // when user e-mail is empty, use only company e-mail - $this->setEmail($company->email, "TYPE=WORK"); - } else { - $tmpuser2 = explode("@", trim($object->email)); - $tmpcompany = explode("@", trim($company->email)); - - if (strtolower(end($tmpuser2)) == strtolower(end($tmpcompany))) { - // when e-mail domain of user and company are the same, use user e-mail at first (and company e-mail at second) - $this->setEmail($object->email, "TYPE=WORK"); - - // support by Microsoft Outlook (2019 and possible earlier) - $this->setEmail($company->email, ''); - } else { - // when e-mail of user and company complete different use company e-mail at first (and user e-mail at second) - $this->setEmail($company->email, "TYPE=WORK"); - - // support by Microsoft Outlook (2019 and possible earlier) - $this->setEmail($object->email, ''); - } - } - - // Si user lie a un tiers non de type "particulier" - if ($company->typent_code != 'TE_PRIVATE') { - $this->setOrg($company->name); + if ($urlphoto) { + $mimetype = dol_mimetype($urlphoto); + if ($mimetype) { + $this->setPhoto($mimetype, $urlphoto); } } - // Personal informations - $this->setPhoneNumber($object->personal_mobile, "TYPE=HOME,VOICE"); + if ($object->office_phone) { + $this->setPhoneNumber($object->office_phone, "TYPE=WORK,VOICE"); + } + /* disabled + if ($object->personal_mobile) { + $this->setPhoneNumber($object->personal_mobile, "TYPE=CELL,VOICE"); + }*/ + if ($object->user_mobile) { + $this->setPhoneNumber($object->user_mobile, "TYPE=CELL,VOICE"); + } + if ($object->office_fax) { + $this->setPhoneNumber($object->office_fax, "TYPE=WORK,FAX"); + } + + if (!empty($object->socialnetworks)) { + foreach ($object->socialnetworks as $key => $val) { + $urlsn = ''; + if ($key == 'linkedin') { + if (!preg_match('/^http/', $val)) { + $urlsn = 'https://www.'.$key.'.com/company/'.urlencode($val); + } else { + $urlsn = $val; + } + } elseif ($key == 'youtube') { + if (!preg_match('/^http/', $val)) { + $urlsn = 'https://www.'.$key.'.com/user/'.urlencode($val); + } else { + $urlsn = $val; + } + } else { + if (!preg_match('/^http/', $val)) { + $urlsn = 'https://www.'.$key.'.com/'.urlencode($val); + } else { + $urlsn = $val; + } + } + if ($urlsn) { + $this->properties["socialProfile;type=".$key] = $urlsn; + } + } + } + + $country = $object->country_code ? $object->country : ''; + + if ($object->address || $object->town || $object->state || $object->zip || $object->country) { + $this->setAddress("", "", $object->address, $object->town, $object->state, $object->zip, $country, "TYPE=WORK"); + //$this->setLabel("", "", $object->address, $object->town, $object->state, $object->zip, $country, "TYPE=HOME"); + } + + if ($object->email) { + $this->setEmail($object->email, "TYPE=WORK"); + } + /* disabled + if ($object->personal_email) { + $this->setEmail($object->personal_email, "TYPE=HOME"); + } */ + if ($object->note_public) { + $this->setNote($object->note_public); + } + if ($object->job) { + $this->setTitle($object->job); + } + + // For user, type=home + // For contact, $object->url is not defined + if ($object->url) { + $this->setURL($object->url, ""); + } + + if (is_object($company)) { + // Si user linked to a thirdparty and not a physical people + if ($company->typent_code != 'TE_PRIVATE') { + $this->setOrg($company->name); + } + + $this->setURL($company->url, ""); + + if ($company->phone && $company->phone != $object->office_phone) { + $this->setPhoneNumber($company->phone, "TYPE=WORK,VOICE"); + } + if ($company->fax && $company->fax != $object->office_fax) { + $this->setPhoneNumber($company->fax, "TYPE=WORK,FAX"); + } + if ($company->address || $company->town || $company->state || $company->zip || $company->country) { + $this->setAddress("", "", $company->address, $company->town, $company->state, $company->zip, $company->country, "TYPE=WORK"); + } + + if ($company->email && $company->email != $object->email) { + $this->setEmail($company->email, "TYPE=WORK"); + } + + /* + if (!empty($company->socialnetworks)) { + foreach ($company->socialnetworks as $key => $val) { + $urlsn = ''; + if ($key == 'linkedin') { + if (!preg_match('/^http/', $val)) { + $urlsn = 'https://www.'.$key.'.com/company/'.urlencode($val); + } else { + $urlsn = $val; + } + } elseif ($key == 'youtube') { + if (!preg_match('/^http/', $val)) { + $urlsn = 'https://www.'.$key.'.com/user/'.urlencode($val); + } else { + $urlsn = $val; + } + } else { + if (!preg_match('/^http/', $val)) { + $urlsn = 'https://www.'.$key.'.com/'.urlencode($val); + } else { + $urlsn = $val; + } + } + if ($urlsn) { + $this->properties["socialProfile;type=".$key] = $urlsn; + } + } + } + */ + } + + // Birthday if ($object->birth) { $this->setBirthday($object->birth); } diff --git a/htdocs/public/users/view.php b/htdocs/public/users/view.php index ba1a6dd0908..ec5f53377c2 100644 --- a/htdocs/public/users/view.php +++ b/htdocs/public/users/view.php @@ -91,13 +91,79 @@ if ($cancel) { */ $form = new Form($db); +$v = new vCard(); + $company = $mysoc; -if ($mode == 'vcard') { - // We create VCard - $v = new vCard(); +$modulepart = 'userphotopublic'; +$dir = $conf->user->dir_output; - $output = $v->buildVCardString($object, $company, $langs); +// Show logo (search order: logo defined by ONLINE_SIGN_LOGO_suffix, then ONLINE_SIGN_LOGO_, then small company logo, large company logo, theme logo, common logo) +// Define logo and logosmall +$logo = ''; +$logosmall = ''; +if (!empty($object->photo)) { + if (dolIsAllowedForPreview($object->photo)) { + $logosmall = get_exdir(0, 0, 0, 0, $object, 'user').'photos/'.getImageFileNameForSize($object->photo, '_small'); + $logo = get_exdir(0, 0, 0, 0, $object, 'user').'photos/'.$object->photo; + //$originalfile = get_exdir(0, 0, 0, 0, $object, 'user').'photos/'.$object->photo; + } +} +//print ''."\n"; +// Define urllogo +$urllogo = ''; +$urllogofull = ''; +if (!empty($logosmall) && is_readable($dir.'/'.$logosmall)) { + $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$conf->entity.'&securekey='.urlencode($securekey).'&file='.urlencode($logosmall); + $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart='.$modulepart.'&entity='.$conf->entity.'&securekey='.urlencode($securekey).'&file='.urlencode($logosmall); +} elseif (!empty($logo) && is_readable($dir.'/'.$logo)) { + $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$conf->entity.'&securekey='.urlencode($securekey).'&file='.urlencode($logo); + $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart='.$modulepart.'&entity='.$conf->entity.'&securekey='.urlencode($securekey).'&file='.urlencode($logo); +} + +// Clean data we don't want on public page +if (getDolUserInt('USER_PUBLIC_HIDE_PHOTO', 0, $object)) { + $logo = ''; + $logosmall = ''; + $urllogo = ''; + $urllogofull = ''; +} +if (getDolUserInt('USER_PUBLIC_HIDE_JOBPOSITION', 0, $object)) { + $object->job = ''; +} +if (getDolUserInt('USER_PUBLIC_HIDE_EMAIL', 0, $object)) { + $object->email = ''; +} +if (getDolUserInt('USER_PUBLIC_HIDE_EMAIL', 0, $object)) { + $object->job = ''; +} +if (getDolUserInt('USER_PUBLIC_HIDE_OFFICE_PHONE', 0, $object)) { + $object->office_phone = ''; +} +if (getDolUserInt('USER_PUBLIC_HIDE_OFFICE_FAX', 0, $object)) { + $object->office_fax = ''; +} +if (getDolUserInt('USER_PUBLIC_HIDE_USER_MOBILE', 0, $object)) { + $object->user_mobile = ''; +} +if (getDolUserInt('USER_PUBLIC_HIDE_BIRTH', 0, $object)) { + $object->birth = ''; +} +if (getDolUserInt('USER_PUBLIC_HIDE_SOCIALNETWORKS', 0, $object)) { + $object->socialnetworks = ''; +} +if (getDolUserInt('USER_PUBLIC_HIDE_COMPANY', 0, $object)) { + $company = null; +} + + +// Output vcard +if ($mode == 'vcard') { + // Reset data no selected for public VCard + + + // We create VCard + $output = $v->buildVCardString($object, $company, $langs, $urllogofull); $filename = trim(urldecode($v->getFileName())); // "Nom prenom.vcf" $filenameurlencoded = dol_sanitizeFileName(urlencode($filename)); @@ -147,34 +213,6 @@ print ''; print "\n"; print ''."\n"; -$modulepart = 'userphotopublic'; -$imagesize = 'small'; -$dir = $conf->user->dir_output; -$email = $object->email; - -// Show logo (search order: logo defined by ONLINE_SIGN_LOGO_suffix, then ONLINE_SIGN_LOGO_, then small company logo, large company logo, theme logo, common logo) -// Define logo and logosmall -$logo = ''; -$logosmall = ''; -if (!empty($object->photo)) { - if (dolIsAllowedForPreview($object->photo)) { - $logosmall = get_exdir(0, 0, 0, 0, $object, 'user').'photos/'.getImageFileNameForSize($object->photo, '_small'); - $logo = get_exdir(0, 0, 0, 0, $object, 'user').'photos/'.$object->photo; - //$originalfile = get_exdir(0, 0, 0, 0, $object, 'user').'photos/'.$object->photo; - } -} -//print ''."\n"; -// Define urllogo -$urllogo = ''; -$urllogofull = ''; -if (!empty($logosmall) && is_readable($conf->user->dir_output.'/'.$logosmall)) { - $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$conf->entity.'&securekey='.urlencode($securekey).'&file='.urlencode($logosmall); - $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart='.$modulepart.'&entity='.$conf->entity.'&securekey='.urlencode($securekey).'&file='.urlencode($logosmall); -} elseif (!empty($logo) && is_readable($conf->user->dir_output.'/'.$logo)) { - $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$conf->entity.'&securekey='.urlencode($securekey).'&file='.urlencode($logo); - $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart='.$modulepart.'&entity='.$conf->entity.'&securekey='.urlencode($securekey).'&file='.urlencode($logo); -} - // Output html code for logo print '
'; print '
'; @@ -211,9 +249,11 @@ $socialnetworksdict = getArrayOfSocialNetworks(); // Show barcode $showbarcode = GETPOST('nobarcode') ? 0 : 1; if ($showbarcode) { + $qrcodecontent = $output = $v->buildVCardString($object, $company, $langs); + print '
'; print '
'; - print ''; + print ''; print '
'; print '
'; } diff --git a/htdocs/user/virtualcard.php b/htdocs/user/virtualcard.php index 8d023c2c9a9..c2de7e17b06 100644 --- a/htdocs/user/virtualcard.php +++ b/htdocs/user/virtualcard.php @@ -73,6 +73,7 @@ if ($action == 'update') { $tmparray['USER_PUBLIC_HIDE_OFFICE_PHONE'] = (GETPOST('USER_PUBLIC_HIDE_OFFICE_PHONE') ? 1 : 0); $tmparray['USER_PUBLIC_HIDE_OFFICE_FAX'] = (GETPOST('USER_PUBLIC_HIDE_OFFICE_FAX') ? 1 : 0); $tmparray['USER_PUBLIC_HIDE_USER_MOBILE'] = (GETPOST('USER_PUBLIC_HIDE_USER_MOBILE') ? 1 : 0); + $tmparray['USER_PUBLIC_HIDE_BIRTH'] = (GETPOST('USER_PUBLIC_HIDE_BIRTH') ? 1 : 0); $tmparray['USER_PUBLIC_HIDE_SOCIALNETWORKS'] = (GETPOST('USER_PUBLIC_HIDE_SOCIALNETWORKS') ? 1 : 0); $tmparray['USER_PUBLIC_HIDE_COMPANY'] = (GETPOST('USER_PUBLIC_HIDE_COMPANY') ? 1 : 0); $tmparray['USER_PUBLIC_MORE'] = (GETPOST('USER_PUBLIC_MORE') ? GETPOST('USER_PUBLIC_MORE') : ''); @@ -230,6 +231,13 @@ if (getDolUserInt('USER_ENABLE_PUBLIC', 0, $object)) { print $form->selectyesno("USER_PUBLIC_HIDE_USER_MOBILE", (getDolUserInt('USER_PUBLIC_HIDE_USER_MOBILE', 0, $object) ? getDolUserInt('USER_PUBLIC_HIDE_USER_MOBILE', 0, $object) : 0), 1); print "\n"; + // User mobile + print ''; + print $langs->trans("HideOnVCard", $langs->transnoentitiesnoconv("Birthdate")); + print ''; + print $form->selectyesno("USER_PUBLIC_HIDE_BIRTH", (getDolUserInt('USER_PUBLIC_HIDE_BIRTH', 0, $object) ? getDolUserInt('USER_PUBLIC_HIDE_BIRTH', 0, $object) : 0), 1); + print "\n"; + // Social networks print ''; print $langs->trans("HideOnVCard", $langs->transnoentitiesnoconv("SocialNetworks"));