PageRenderTime 43ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/include/vCard.php

https://github.com/vincentamari/SuperSweetAdmin
PHP | 385 lines | 291 code | 47 blank | 47 comment | 81 complexity | f6b2d22c63948aaedc60e32b21cb33ef MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, AGPL-3.0, LGPL-2.1
  1. <?php
  2. if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
  3. /*********************************************************************************
  4. * SugarCRM is a customer relationship management program developed by
  5. * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
  6. *
  7. * This program is free software; you can redistribute it and/or modify it under
  8. * the terms of the GNU Affero General Public License version 3 as published by the
  9. * Free Software Foundation with the addition of the following permission added
  10. * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  11. * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
  12. * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  13. *
  14. * This program is distributed in the hope that it will be useful, but WITHOUT
  15. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16. * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  17. * details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License along with
  20. * this program; if not, see http://www.gnu.org/licenses or write to the Free
  21. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  22. * 02110-1301 USA.
  23. *
  24. * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
  25. * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
  26. *
  27. * The interactive user interfaces in modified source and object code versions
  28. * of this program must display Appropriate Legal Notices, as required under
  29. * Section 5 of the GNU Affero General Public License version 3.
  30. *
  31. * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  32. * these Appropriate Legal Notices must retain the display of the "Powered by
  33. * SugarCRM" logo. If the display of the logo is not reasonably feasible for
  34. * technical reasons, the Appropriate Legal Notices must display the words
  35. * "Powered by SugarCRM".
  36. ********************************************************************************/
  37. /*********************************************************************************
  38. * Description:
  39. ********************************************************************************/
  40. class vCard
  41. {
  42. protected $properties = array();
  43. protected $name = 'no_name';
  44. public function clear()
  45. {
  46. $this->properties = array();
  47. }
  48. function loadContact($contactid, $module='Contacts') {
  49. global $app_list_strings;
  50. require_once($GLOBALS['beanFiles'][$GLOBALS['beanList'][$module]]);
  51. $contact = new $GLOBALS['beanList'][$module]();
  52. $contact->retrieve($contactid);
  53. // cn: bug 8504 - CF/LB break Outlook's vCard import
  54. $bad = array("\n", "\r");
  55. $good = array("=0A", "=0D");
  56. $encoding = '';
  57. if(strpos($contact->primary_address_street, "\n") || strpos($contact->primary_address_street, "\r")) {
  58. $contact->primary_address_street = str_replace($bad, $good, $contact->primary_address_street);
  59. $encoding = 'QUOTED-PRINTABLE';
  60. }
  61. $this->setName(from_html($contact->first_name), from_html($contact->last_name), $app_list_strings['salutation_dom'][from_html($contact->salutation)]);
  62. if ( isset($contact->birthdate) )
  63. $this->setBirthDate(from_html($contact->birthdate));
  64. $this->setPhoneNumber(from_html($contact->phone_fax), 'FAX');
  65. $this->setPhoneNumber(from_html($contact->phone_home), 'HOME');
  66. $this->setPhoneNumber(from_html($contact->phone_mobile), 'CELL');
  67. $this->setPhoneNumber(from_html($contact->phone_work), 'WORK');
  68. $this->setEmail(from_html($contact->email1));
  69. $this->setAddress(from_html($contact->primary_address_street), from_html($contact->primary_address_city), from_html($contact->primary_address_state), from_html($contact->primary_address_postalcode), from_html($contact->primary_address_country), 'WORK', $encoding);
  70. if ( isset($contact->account_name) )
  71. $this->setORG(from_html($contact->account_name), from_html($contact->department));
  72. else
  73. $this->setORG('', from_html($contact->department));
  74. $this->setTitle($contact->title);
  75. }
  76. function setTitle($title){
  77. $this->setProperty("TITLE",$title );
  78. }
  79. function setORG($org, $dep){
  80. $this->setProperty("ORG","$org;$dep" );
  81. }
  82. function setAddress($address, $city, $state,$postal, $country, $type, $encoding=''){
  83. if(!empty($encoding)) {
  84. $encoding = ";ENCODING={$encoding}";
  85. }
  86. $this->setProperty("ADR;$type$encoding",";;$address;$city;$state;$postal;$country" );
  87. }
  88. function setName($first_name, $last_name, $prefix){
  89. $this->name = strtr($first_name.'_'.$last_name, ' ' , '_');
  90. $this->setProperty('N',$last_name.';'.$first_name.';;'.$prefix );
  91. $this->setProperty('FN',"$prefix $first_name $last_name");
  92. }
  93. function setEmail($address){
  94. $this->setProperty('EMAIL;INTERNET', $address);
  95. }
  96. function setPhoneNumber( $number, $type)
  97. {
  98. if($type != 'FAX') {
  99. $this->setProperty("TEL;$type", $number);
  100. }
  101. else {
  102. $this->setProperty("TEL;WORK;$type", $number);
  103. }
  104. }
  105. function setBirthDate($date){
  106. $this->setProperty('BDAY',$date);
  107. }
  108. function getProperty($name){
  109. if(isset($this->properties[$name]))
  110. return $this->properties[$name];
  111. return null;
  112. }
  113. function setProperty($name, $value){
  114. $this->properties[$name] = $value;
  115. }
  116. function toString(){
  117. global $locale;
  118. $temp = "BEGIN:VCARD\n";
  119. foreach($this->properties as $key=>$value){
  120. if(!empty($value)) {
  121. $temp .= $key. ';CHARSET='.strtolower($locale->getExportCharset()).':'.$value."\n";
  122. } else {
  123. $temp .= $key. ':'.$value."\n";
  124. }
  125. }
  126. $temp.= "END:VCARD\n";
  127. return $temp;
  128. }
  129. function saveVCard(){
  130. global $locale;
  131. $content = $this->toString();
  132. if ( !defined('SUGAR_PHPUNIT_RUNNER') ) {
  133. header("Content-Disposition: attachment; filename={$this->name}.vcf");
  134. header("Content-Type: text/x-vcard; charset=".$locale->getExportCharset());
  135. header("Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
  136. header("Last-Modified: " . TimeDate::httpTime() );
  137. header("Cache-Control: max-age=0");
  138. header("Pragma: public");
  139. header("Content-Length: ".strlen($content));
  140. }
  141. print $locale->translateCharset($content, 'UTF-8', $locale->getExportCharset());
  142. }
  143. function importVCard($filename, $module='Contacts'){
  144. global $current_user;
  145. $lines = file($filename);
  146. $start = false;
  147. $contact = loadBean($module);
  148. $contact->title = 'imported';
  149. $contact->assigned_user_id = $current_user->id;
  150. $fullname = '';
  151. $email_suffix = 1;
  152. for($index = 0; $index < sizeof($lines); $index++){
  153. $line = $lines[$index];
  154. // check the encoding and change it if needed
  155. $locale = new Localization();
  156. $encoding = $locale->detectCharset($line);
  157. if ( $encoding != $GLOBALS['sugar_config']['default_charset'] ) {
  158. $line = $locale->translateCharset($line,$encoding);
  159. }
  160. $line = trim($line);
  161. if($start){
  162. //VCARD is done
  163. if(substr_count(strtoupper($line), 'END:VCARD')){
  164. if(!isset($contact->last_name)){
  165. $contact->last_name = $fullname;
  166. }
  167. break;
  168. }
  169. $keyvalue = explode(':',$line);
  170. if(sizeof($keyvalue)==2){
  171. $value = $keyvalue[1];
  172. for($newindex= $index + 1; $newindex < sizeof($lines), substr_count($lines[$newindex], ':') == 0; $newindex++){
  173. $value .= $lines[$newindex];
  174. $index = $newindex;
  175. }
  176. $values = explode(';',$value );
  177. $key = strtoupper($keyvalue[0]);
  178. $key = strtr($key, '=', '');
  179. $key = strtr($key, ',',';');
  180. $keys = explode(';' ,$key);
  181. if($keys[0] == 'TEL'){
  182. if(substr_count($key, 'WORK') > 0){
  183. if(substr_count($key, 'FAX') > 0){
  184. if(!isset($contact->phone_fax)){
  185. $contact->phone_fax = $value;
  186. }
  187. }else{
  188. if(!isset($contact->phone_work)){
  189. $contact->phone_work = $value;
  190. }
  191. }
  192. }
  193. if(substr_count($key, 'HOME') > 0){
  194. if(substr_count($key, 'FAX') > 0){
  195. if(!isset($contact->phone_fax)){
  196. $contact->phone_fax = $value;
  197. }
  198. }else{
  199. if(!isset($contact->phone_home)){
  200. $contact->phone_home = $value;
  201. }
  202. }
  203. }
  204. if(substr_count($key, 'CELL') > 0){
  205. if(!isset($contact->phone_mobile)){
  206. $contact->phone_mobile = $value;
  207. }
  208. }
  209. if(substr_count($key, 'FAX') > 0){
  210. if(!isset($contact->phone_fax)){
  211. $contact->phone_fax = $value;
  212. }
  213. }
  214. }
  215. if($keys[0] == 'N'){
  216. if(sizeof($values) > 0)
  217. $contact->last_name = $values[0];
  218. if(sizeof($values) > 1)
  219. $contact->first_name = $values[1];
  220. if(sizeof($values) > 2)
  221. $contact->salutation = $values[2];
  222. }
  223. if($keys[0] == 'FN'){
  224. $fullname = $value;
  225. }
  226. }
  227. if($keys[0] == 'ADR'){
  228. if(substr_count($key, 'WORK') > 0 && (substr_count($key, 'POSTAL') > 0|| substr_count($key, 'PARCEL') == 0)){
  229. if(!isset($contact->primary_address_street) && sizeof($values) > 2){
  230. $textBreaks = array("\n", "\r");
  231. $vcardBreaks = array("=0A", "=0D");
  232. $contact->primary_address_street = str_replace($vcardBreaks, $textBreaks, $values[2]);
  233. }
  234. if(!isset($contact->primary_address_city) && sizeof($values) > 3){
  235. $contact->primary_address_city = $values[3];
  236. }
  237. if(!isset($contact->primary_address_state) && sizeof($values) > 4){
  238. $contact->primary_address_state = $values[4];
  239. }
  240. if(!isset($contact->primary_address_postalcode) && sizeof($values) > 5){
  241. $contact->primary_address_postalcode = $values[5];
  242. }
  243. if(!isset($contact->primary_address_country) && sizeof($values) > 6){
  244. $contact->primary_address_country = $values[6];
  245. }
  246. }
  247. }
  248. if($keys[0] == 'TITLE'){
  249. $contact->title = $value;
  250. }
  251. if($keys[0] == 'EMAIL'){
  252. $field = 'email' . $email_suffix;
  253. if(!isset($contact->$field)) {
  254. $contact->$field = $value;
  255. }
  256. if($email_suffix == 1) {
  257. $_REQUEST['email1'] = $value;
  258. }
  259. $email_suffix++;
  260. }
  261. if($keys[0] == 'ORG'){
  262. $GLOBALS['log']->debug('I found a company name');
  263. if(!empty($value)){
  264. $GLOBALS['log']->debug('I found a company name (fer real)');
  265. if ( is_a($contact,"Contact") || is_a($contact,"Lead") ) {
  266. $GLOBALS['log']->debug('And Im dealing with a person!');
  267. $accountBean = loadBean('Accounts');
  268. // It's a contact, we better try and match up an account
  269. $full_company_name = trim($values[0]);
  270. // Do we have a full company name match?
  271. $result = $accountBean->retrieve_by_string_fields(array('name' => $full_company_name, 'deleted' => 0));
  272. if ( ! isset($result->id) ) {
  273. // Try to trim the full company name down, see if we get some other matches
  274. $vCardTrimStrings = array('/ltd\.*/i'=>'',
  275. '/llc\.*/i'=>'',
  276. '/gmbh\.*/i'=>'',
  277. '/inc\.*/i'=>'',
  278. '/\.com/i'=>'',
  279. );
  280. // Allow users to override the trimming strings
  281. if ( file_exists('custom/include/vCardTrimStrings.php') ) {
  282. require_once('custom/include/vCardTrimStrings.php');
  283. }
  284. $short_company_name = trim(preg_replace(array_keys($vCardTrimStrings),$vCardTrimStrings,$full_company_name)," ,.");
  285. $GLOBALS['log']->debug('Trying an extended search for: '.$short_company_name);
  286. $result = $accountBean->retrieve_by_string_fields(array('name' => $short_company_name, 'deleted' => 0));
  287. }
  288. if ( is_a($contact,"Lead") || ! isset($result->id) ) {
  289. // We could not find a parent account, or this is a lead so only copy the name, no linking
  290. $GLOBALS['log']->debug("Did not find a matching company ($full_company_name)");
  291. $contact->account_id = '';
  292. $contact->account_name = $full_company_name;
  293. } else {
  294. $GLOBALS['log']->debug("Found a matching company: ".$result->name);
  295. $contact->account_id = $result->id;
  296. $contact->account_name = $result->name;
  297. }
  298. $contact->department = $values[1];
  299. } else{
  300. $contact->department = $value;
  301. }
  302. }
  303. }
  304. }
  305. //FOUND THE BEGINING OF THE VCARD
  306. if(!$start && substr_count(strtoupper($line), 'BEGIN:VCARD')){
  307. $start = true;
  308. }
  309. }
  310. if ( is_a($contact, "Contact") && empty($contact->account_id) && !empty($contact->account_name) ) {
  311. $GLOBALS['log']->debug("Look ma! I'm creating a new account: ".$contact->account_name);
  312. // We need to create a new account
  313. $accountBean = loadBean('Accounts');
  314. // Populate the newly created account with all of the contact information
  315. foreach ( $contact->field_defs as $field_name => $field_def ) {
  316. if ( !empty($contact->$field_name) ) {
  317. $accountBean->$field_name = $contact->$field_name;
  318. }
  319. }
  320. $accountBean->name = $contact->account_name;
  321. $accountBean->save();
  322. $contact->account_id = $accountBean->id;
  323. }
  324. $contactId = $contact->save();
  325. return $contactId;
  326. }
  327. }
  328. ?>