home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 April / CMCD0404.ISO / Software / Freeware / Programare / dotproject / lib / PEAR / Contact_Vcard_Build.php next >
PHP Script  |  2003-09-15  |  60KB  |  2,321 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */ 
  3. // +----------------------------------------------------------------------+ 
  4. // | PHP version 4                                                        | 
  5. // +----------------------------------------------------------------------+ 
  6. // | Copyright (c) 1997-2002 The PHP Group                                | 
  7. // +----------------------------------------------------------------------+ 
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        | 
  10. // | available at through the world-wide-web at                           | 
  11. // | http://www.php.net/license/2_02.txt.                                 | 
  12. // | If you did not receive a copy of the PHP license and are unable to   | 
  13. // | obtain it through the world-wide-web, please send a note to          | 
  14. // | license@php.net so we can mail you a copy immediately.               | 
  15. // +----------------------------------------------------------------------+ 
  16. // | Authors: Paul M. Jones <pjones@ciaweb.net>                           | 
  17. // +----------------------------------------------------------------------+ 
  18. // 
  19. // $Id: Contact_Vcard_Build.php,v 1.1 2003/09/15 09:59:57 gregorerhardt Exp $
  20.  
  21. //dP dotproject | gregorerhardt 20030909:
  22. //dP commented out some lines for running without PEAR base class
  23. //dP all these commented lines begin with //dP
  24. //dP changes concern in particular PEAR error handling
  25. //dP this is not the original Contact_Vcard_Build.php file.
  26. //dP to get the original file:     check pear.php.net or
  27. //dP                contact the author mentioned above
  28.  
  29. /**
  30. * This class builds a single vCard (version 3.0 or 2.1).
  31. *
  32. * General note: we use the terms "set" "add" and "get" as function
  33. * prefixes.
  34. * "Set" means there is only one iteration of a component, and it has
  35. * only one value repetition, so you set the whole thing at once.
  36. * "Add" means eith multiple iterations of a component are allowed, or
  37. * that there is only one iteration allowed but there can be multiple
  38. * value repetitions, so you add iterations or repetitions to the current
  39. * stack.
  40. * "Get" returns the full vCard line for a single iteration.
  41. * @author Paul M. Jones <pjones@ciaweb.net>
  42. * @package Contact_Vcard
  43. * @version $Revision: 1.1 $
  44. */
  45.  
  46.  
  47. // Part numbers for N components
  48. define('VCARD_N_FAMILY',     0);
  49. define('VCARD_N_GIVEN',      1);
  50. define('VCARD_N_ADDL',       2);
  51. define('VCARD_N_PREFIX',     3);
  52. define('VCARD_N_SUFFIX',     4);
  53.  
  54. // Part numbers for ADR components
  55. define('VCARD_ADR_POB',      0);
  56. define('VCARD_ADR_EXTEND',   1);
  57. define('VCARD_ADR_STREET',   2);
  58. define('VCARD_ADR_LOCALITY', 3);
  59. define('VCARD_ADR_REGION',   4);
  60. define('VCARD_ADR_POSTCODE', 5);
  61. define('VCARD_ADR_COUNTRY',  6);
  62.  
  63. // Part numbers for GEO components
  64. define('VCARD_GEO_LAT',      0);
  65. define('VCARD_GEO_LON',      1);
  66.  
  67.  
  68. class Contact_Vcard_Build {
  69.     
  70.     
  71.     /**
  72.     * 
  73.     * Values for vCard components.
  74.     * 
  75.     * @access public
  76.     * @var array
  77.     * 
  78.     */
  79.     
  80.     var $value = array();
  81.     
  82.     
  83.     /**
  84.     * 
  85.     * Parameters for vCard components.
  86.     * 
  87.     * @access public
  88.     * @var array
  89.     * 
  90.     */
  91.     
  92.     var $param = array();
  93.     
  94.     
  95.     /**
  96.     *
  97.     * Tracks which component (N, ADR, TEL, etc) value was last set or added.
  98.     * Used when adding parameters automatically to the proper component.
  99.     *
  100.     * @var string
  101.     *
  102.     */
  103.     
  104.     var $autoparam = null;
  105.     
  106.     
  107.     /**
  108.     *
  109.     * Constructor.
  110.     *
  111.     * @access public
  112.     *
  113.     * @param string $version The vCard version to build; affects which
  114.     * parameters are allowed and which components are returned by
  115.     * fetch().
  116.     * 
  117.     * @return void
  118.     * 
  119.     * @see Contact_Vcard_Build::fetch()
  120.     *
  121.     */
  122.     
  123.     function Contact_Vcard_Build($version = '3.0')
  124.     {
  125.        //dP $this->PEAR();
  126.        //dP $this->setErrorHandling(PEAR_ERROR_PRINT);
  127.         $this->reset($version);
  128.     }
  129.  
  130.  
  131.     /**
  132.     *
  133.     * Prepares a string so it may be safely used as vCard values.  DO
  134.     * NOT use this with binary encodings.  Operates on text in-place;
  135.     * does not return a value.  Recursively descends into arrays.
  136.     *
  137.     * Escapes a string so that...
  138.     *     ; => \;
  139.     *     , => \,
  140.     *     newline => literal \n
  141.     *
  142.     * @access public
  143.     *
  144.     * @param mixed $text The string or array or strings to escape.
  145.     *
  146.     * @return mixed Void on success, or a PEAR_Error object on failure.
  147.     *
  148.     */
  149.  
  150.     function escape(&$text)
  151.     {
  152.         if (is_object($text)) {
  153.  
  154.            //dP return $this->raiseError('The escape() method works only with string literals and arrays.');
  155.  
  156.         } elseif (is_array($text)) {
  157.  
  158.             foreach ($text as $key => $val) {
  159.                 $this->escape($val);
  160.                 $text[$key] = $val;
  161.             }
  162.  
  163.         } else {
  164.  
  165.             // escape semicolons not led by a backslash
  166.             $regex = '(?<!\\\\)(\;)';
  167.             $text = preg_replace("/$regex/i", "\\;", $text);
  168.  
  169.             // escape commas not led by a backslash
  170.             $regex = '(?<!\\\\)(\,)';
  171.             $text = preg_replace("/$regex/i", "\\,", $text);
  172.  
  173.             // escape newlines
  174.             $regex = '\\n';
  175.             $text = preg_replace("/$regex/i", "\\n", $text);
  176.  
  177.         }
  178.     }
  179.  
  180.  
  181.     /**
  182.     *
  183.     * Adds a parameter value for a given component and parameter name.
  184.     *
  185.     * Note that although vCard 2.1 allows you to specify a parameter
  186.     * value without a name (e.g., "HOME" instead of "TYPE=HOME") this
  187.     * class is not so lenient.  ;-)    You must specify a parameter name
  188.     * (TYPE, ENCODING, etc) when adding a parameter.  Call multiple
  189.     * times if you want to add multiple values to the same parameter.
  190.     * E.g.:
  191.     *
  192.     * $vcard = new Contact_Vcard_Build();
  193.     *
  194.     * // set "TYPE=HOME,PREF" for the first TEL component
  195.     * $vcard->addParam('TEL', 0, 'TYPE', 'HOME');
  196.     * $vcard->addParam('TEL', 0, 'TYPE', 'PREF');
  197.     *
  198.     * @access public
  199.     *
  200.     * @param string $param_name The parameter name, such as TYPE, VALUE,
  201.     * or ENCODING.
  202.     *
  203.     * @param string $param_value The parameter value.
  204.     *
  205.     * @param string $comp The vCard component for which this is a
  206.     * paramter (ADR, TEL, etc).  If null, will be the component that was
  207.     * last set or added-to.
  208.     *
  209.     * @param mixed $iter An integer vCard component iteration that this
  210.     * is a param for.  E.g., if you have more than one ADR component, 0
  211.     * refers to the first ADR, 1 to the second ADR, and so on.  If null,
  212.     * the parameter will be added to the last component iteration
  213.     * available.
  214.     *
  215.     * @return mixed Void on success, or a PEAR_Error object on failure.
  216.     *
  217.     */
  218.  
  219.     function addParam($param_name, $param_value, $comp = null,
  220.         $iter = null)
  221.     {
  222.         // if component is not specified, default to the last component
  223.         // that was set or added.
  224.         if ($comp === null) {
  225.             $comp = $this->autoparam;
  226.         }
  227.  
  228.         // using a null iteration means the param should be associated
  229.         // with the latest/most-recent iteration of the selected
  230.         // component.
  231.         if ($iter === null) {
  232.             $iter = count($this->value[$comp]) - 1;
  233.         }
  234.  
  235.         // massage the text arguments
  236.         $comp = strtoupper(trim($comp));
  237.         $param_name = strtoupper(trim($param_name));
  238.         $param_value = trim($param_value);
  239.  
  240.         if (! is_integer($iter) || $iter < 0) {
  241.  
  242.           //dP  return $this->raiseError("$iter is not a valid iteration number for $comp; must be a positive integer.");
  243.  
  244.         } else {
  245.  
  246.             $result = $this->validateParam($param_name, $param_value, $comp, $iter);
  247.  
  248.            //dP if (PEAR::isError($result)) {
  249.            //dP     return $result;
  250.            //dP } else {
  251.                 $this->param[$comp][$iter][$param_name][] = $param_value;
  252.            //dP }
  253.  
  254.         }
  255.     }
  256.  
  257.  
  258.     /**
  259.     *
  260.     * Validates parameter names and values based on the vCard version
  261.     * (2.1 or 3.0).
  262.     *
  263.     * @access public
  264.     *
  265.     * @param string $name The parameter name (e.g., TYPE or ENCODING).
  266.     *
  267.     * @param string $text The parameter value (e.g., HOME or BASE64).
  268.     *
  269.     * @param string $comp Optional, the component name (e.g., ADR or
  270.     * PHOTO).  Only used for error messaging.
  271.     *
  272.     * @param string $iter Optional, the iteration of the component.
  273.     * Only used for error messaging.
  274.     *
  275.     * @return mixed Boolean true if the parameter is valid, or a
  276.     * PEAR_Error object if not.
  277.     *
  278.     */
  279.  
  280.     function validateParam($name, $text, $comp = null, $iter = null)
  281.     {
  282.         $name = strtoupper($name);
  283.         $text = strtoupper($text);
  284.  
  285.         // all param values must have only the characters A-Z 0-9 and -.
  286.         if (preg_match('/[^a-zA-Z0-9\-]/i', $text)) {
  287.  
  288.          //dP   $result = $this->raiseError("vCard [$comp] [$iter] [$name]: The parameter value may contain only a-z, A-Z, 0-9, and dashes (-).");
  289.  
  290.         } elseif ($this->value['VERSION'][0][0][0] == '2.1') {
  291.  
  292.             // Validate against version 2.1 (pretty strict)
  293.  
  294.             $types = array (
  295.                 'DOM', 'INTL', 'POSTAL', 'PARCEL','HOME', 'WORK',
  296.                 'PREF', 'VOICE', 'FAX', 'MSG', 'CELL', 'PAGER',
  297.                 'BBS', 'MODEM', 'CAR', 'ISDN', 'VIDEO',
  298.                 'AOL', 'APPLELINK', 'ATTMAIL', 'CIS', 'EWORLD',
  299.                 'INTERNET', 'IBMMAIL', 'MCIMAIL',
  300.                 'POWERSHARE', 'PRODIGY', 'TLX', 'X400',
  301.                 'GIF', 'CGM', 'WMF', 'BMP', 'MET', 'PMB', 'DIB',
  302.                 'PICT', 'TIFF', 'PDF', 'PS', 'JPEG', 'QTIME',
  303.                 'MPEG', 'MPEG2', 'AVI',
  304.                 'WAVE', 'AIFF', 'PCM',
  305.                 'X509', 'PGP'
  306.             );
  307.             
  308.             
  309.             switch ($name) {
  310.             
  311.             case 'TYPE':
  312.                 if (! in_array($text, $types)) {
  313.                 //dP   $result = $this->raiseError("vCard 2.1 [$comp] [$iter]: $text is not a recognized TYPE.");
  314.                 } else {
  315.                     $result = true;
  316.                 }
  317.                 break;
  318.  
  319.             case 'ENCODING':
  320.                 if ($text != '7BIT' &&
  321.                     $text != '8BIT' &&
  322.                     $text != 'BASE64' &&
  323.                     $text != 'QUOTED-PRINTABLE') {
  324.                   //dP  $result = $this->raiseError("vCard 2.1 [$comp] [$iter]: $text is not a recognized ENCODING.");
  325.                 } else {
  326.                     $result = true;
  327.                 }
  328.                 break;
  329.  
  330.             case 'CHARSET':
  331.                 // all charsets are OK
  332.                 $result = true;
  333.                 break;
  334.  
  335.             case 'LANGUAGE':
  336.                 // all languages are OK
  337.                 $result = true;
  338.                 break;
  339.  
  340.             case 'VALUE':
  341.                 if ($text != 'INLINE' &&
  342.                     $text != 'CONTENT-ID' &&
  343.                     $text != 'CID' &&
  344.                     $text != 'URL' &&
  345.                     $text != 'VCARD') {
  346.                   //dP  $result = $this->raiseError("vCard 2.1 [$comp] [$iter]: $text is not a recognized VALUE.");
  347.                 } else {
  348.                     $result = true;
  349.                 }
  350.                 break;
  351.  
  352.             default:
  353.               //dP  $result = $this->raiseError("vCard 2.1 [$comp] [$iter]: $name is an unknown or invalid parameter name.");
  354.                 break;
  355.             }
  356.  
  357.         } elseif ($this->value['VERSION'][0][0][0] == '3.0') {
  358.  
  359.             // Validate against version 3.0 (pretty lenient)
  360.  
  361.             switch ($name) {
  362.  
  363.             case 'TYPE':
  364.                 // all types are OK
  365.                 $result = true;
  366.                 break;
  367.  
  368.             case 'LANGUAGE':
  369.                 // all languages are OK
  370.                 $result = true;
  371.                 break;
  372.  
  373.             case 'ENCODING':
  374.                 if ($text != '8BIT' &&
  375.                     $text != 'B') {
  376.                 //dP    $result = $this->raiseError("vCard 3.0 [$comp] [$iter]: The only allowed ENCODING parameters are 8BIT and B.");
  377.                 } else {
  378.                     $result = true;
  379.                 }
  380.                 break;
  381.  
  382.             case 'VALUE':
  383.                 if ($text != 'BINARY' &&
  384.                     $text != 'PHONE-NUMBER' &&
  385.                     $text != 'TEXT' &&
  386.                     $text != 'URI' &&
  387.                     $text != 'UTC-OFFSET' &&
  388.                     $text != 'VCARD') {
  389.                   //dP  $result = $this->raiseError("vCard 3.0 [$comp] [$iter]: The only allowed VALUE parameters are BINARY, PHONE-NUMBER, TEXT, URI, UTC-OFFSET, and VCARD.");
  390.                 } else {
  391.                     $result = true;
  392.                 }
  393.                 break;
  394.  
  395.             default:
  396.                //dP $result = $this->raiseError("vCard 3.0 [$comp] [$iter]: Unknown or invalid parameter name ($name).");
  397.                 break;
  398.  
  399.             }
  400.  
  401.         } else {
  402.  
  403.         //dP    $result = $this->raiseError("[$comp] [$iter] Unknown vCard version number or other error.");
  404.  
  405.         }
  406.  
  407.         return $result;
  408.  
  409.     }
  410.  
  411.  
  412.     /**
  413.     *
  414.     * Gets back the parameter string for a given component.
  415.     *
  416.     * @access public
  417.     *
  418.     * @param string $comp The component to get parameters for (ADR, TEL,
  419.     * etc).
  420.     *
  421.     * @param int $iter The vCard component iteration to get the param
  422.     * list for.  E.g., if you have more than one ADR component, 0 refers
  423.     * to the first ADR, 1 to the second ADR, and so on.
  424.     * 
  425.     * @return string
  426.     * 
  427.     */
  428.  
  429.     function getParam($comp, $iter = 0)
  430.     {
  431.         $comp = strtoupper($comp);
  432.         $text = '';
  433.         
  434.         if (is_array($this->param[$comp][$iter])) {
  435.             
  436.             // loop through the array of parameters for
  437.             // the component
  438.             
  439.             foreach ($this->param[$comp][$iter] as $param_name => $param_val) {
  440.                 
  441.                 // if there were previous parameter names, separate with
  442.                 // a semicolon
  443.                 if ($text != '') {
  444.                     $text .= ';';
  445.                 }
  446.                 
  447.                 if ($param_val === null) {
  448.                     
  449.                     // no parameter value was specified, which is typical
  450.                     // for vCard version 2.1 -- the name is the value.
  451.                     $this->escape($param_name);
  452.                     $text .= $param_name;
  453.                     
  454.                 } else {
  455.                     // set the parameter name...
  456.                     $text .= strtoupper($param_name) . '=';
  457.                     
  458.                     // ...then escape and comma-separate the parameter
  459.                     // values.
  460.                     $this->escape($param_val);
  461.                     $text .= implode(',', $param_val);
  462.                 }
  463.             }
  464.         }
  465.         
  466.         // if there were no parameters, this will be blank.
  467.         return $text;
  468.     }
  469.     
  470.     
  471.     /**
  472.     * 
  473.     * Resets the vCard values and params to be blank.
  474.     * 
  475.     * @access public
  476.     * 
  477.     * @param string $version The vCard version to reset to ('2.1' or
  478.     * '3.0' -- default is the same version as previously set).
  479.     *
  480.     * @return void
  481.     * 
  482.     */
  483.     
  484.     function reset($version = null)
  485.     {
  486.         $prev = $this->value['VERSION'][0][0][0];
  487.         
  488.         $this->value = array();
  489.         $this->param = array();
  490.         $this->autoparam = null;
  491.         
  492.         if ($version === null) {
  493.             $this->setVersion($prev);
  494.         } else {
  495.             $this->setVersion($version);
  496.         }
  497.     }
  498.     
  499.     
  500.     /**
  501.     * 
  502.     * Gets the left-side/prefix/before-the-colon (metadata) part of a
  503.     * vCard line, including the component identifier, the parameter
  504.     * list, and a colon.
  505.     * 
  506.     * @access public
  507.     * 
  508.     * @param string $comp The component to get metadata for (ADR, TEL,
  509.     * etc).
  510.     * 
  511.     * @param int $iter The vCard component iteration to get the metadata
  512.     * for.  E.g., if you have more than one ADR component, 0 refers to
  513.     * the first ADR, 1 to the second ADR, and so on.
  514.     * 
  515.     * @return string The line prefix metadata.
  516.     * 
  517.     */
  518.     
  519.     function getMeta($comp, $iter = 0)
  520.     {
  521.         $params = $this->getParam($comp, $iter);
  522.         
  523.         if (trim($params) == '') {
  524.             // no parameters
  525.             $text = $comp . ':';
  526.         } else {
  527.             // has parameters.  put an extra semicolon in.
  528.             $text = $comp . ';' . $params . ':';
  529.         }
  530.         
  531.         return $text;
  532.     }
  533.     
  534.     
  535.     /**
  536.     *
  537.     * Generic, all-purpose method to store a string or array in
  538.     * $this->value, in a way suitable for later output as a vCard
  539.     * element.  This forces the value to be the passed text or array
  540.     * value, overriding any prior values.
  541.     * 
  542.     * @access public
  543.     *
  544.     * @param string $comp The component to set the value for ('N',
  545.     * 'ADR', etc).
  546.     * 
  547.     * @param int $iter The component-iteration to set the value for.
  548.     * 
  549.     * @param int $part The part number of the component-iteration to set
  550.     * the value for.
  551.     * 
  552.     * @param mixed $text A string or array; the set of repeated values
  553.     * for this component-iteration part.
  554.     * 
  555.     * @return void
  556.     * 
  557.     */
  558.  
  559.     function setValue($comp, $iter, $part, $text)
  560.     {
  561.         $comp = strtoupper($comp);
  562.         settype($text, 'array');
  563.         $this->value[$comp][$iter][$part] = $text;
  564.         $this->autoparam = $comp;
  565.     }
  566.     
  567.     
  568.     /**
  569.     *
  570.     * Generic, all-purpose method to add a repetition of a string or
  571.     * array in $this->value, in a way suitable for later output as a
  572.     * vCard element.  This appends the value to be the passed text or
  573.     * array value, leaving any prior values in place.
  574.     * 
  575.     * @access public
  576.     *
  577.     * @param string $comp The component to set the value for ('N',
  578.     * 'ADR', etc).
  579.     * 
  580.     * @param int $iter The component-iteration to set the value for.
  581.     * 
  582.     * @param int $part The part number of the component-iteration to set
  583.     * the value for.
  584.     * 
  585.     * @param mixed $text A string or array; the set of repeated values
  586.     * for this component-iteration part.
  587.     * 
  588.     * @return void
  589.     * 
  590.     */
  591.     
  592.     function addValue($comp, $iter, $part, $text)
  593.     {
  594.         $comp = strtoupper($comp);
  595.         settype($text, 'array');
  596.         foreach ($text as $val) {
  597.             $this->value[$comp][$iter][$part][] = $val;
  598.         }
  599.         $this->autoparam = $comp;
  600.     }
  601.     
  602.     
  603.     /**
  604.     *
  605.     * Generic, all-purpose method to get back the data stored in $this->value.
  606.     * 
  607.     * @access public
  608.     *
  609.     * @param string $comp The component to set the value for ('N',
  610.     * 'ADR', etc).
  611.     * 
  612.     * @param int $iter The component-iteration to set the value for.
  613.     * 
  614.     * @param int $part The part number of the component-iteration to get
  615.     * the value for.
  616.     * 
  617.     * @param mixed $rept The repetition number within the part to get;
  618.     * if null, get all repetitions of the part within the iteration.
  619.     * 
  620.     * @return string The value, escaped and delimited, of all
  621.     * repetitions in the component-iteration part (or specific
  622.     * repetition within the part).
  623.     * 
  624.     */
  625.     
  626.     function getValue($comp, $iter = 0, $part = 0, $rept = null)
  627.     {
  628.         if ($rept === null &&
  629.             is_array($this->value[$comp][$iter][$part]) ) {
  630.             
  631.             // get all repetitions of a part
  632.             $list = array();
  633.             foreach ($this->value[$comp][$iter][$part] as $key => $val) {
  634.                 $list[] = trim($val);
  635.             }
  636.             
  637.             $this->escape($list);
  638.             return implode(',', $list);
  639.             
  640.         } else {
  641.             
  642.             // get a specific repetition of a part
  643.             $text = trim($this->value[$comp][$iter][$part][$rept]);
  644.             $this->escape($text);
  645.             return $text;
  646.             
  647.         }
  648.     }
  649.     
  650.     
  651.     /**
  652.     * 
  653.     * Sets the full N component of the vCard.  Will replace all other
  654.     * values.  There can only be one N component per vCard.
  655.     * 
  656.     * @access public
  657.     * 
  658.     * @param mixed $family Single (string) or multiple (array)
  659.     * family/last name.
  660.     * 
  661.     * @param mixed $given Single (string) or multiple (array)
  662.     * given/first name.
  663.     * 
  664.     * @param mixed $addl Single (string) or multiple (array)
  665.     * additional/middle name.
  666.     * 
  667.     * @param mixed $prefix Single (string) or multiple (array) honorific
  668.     * prefix such as Mr., Miss, etc.
  669.     * 
  670.     * @param mixed $suffix Single (string) or multiple (array) honorific
  671.     * suffix such as III, Jr., Ph.D., etc.
  672.     * 
  673.     * @return void
  674.     * 
  675.     */
  676.     
  677.     function setName($family, $given, $addl, $prefix, $suffix)
  678.     {
  679.         $this->autoparam = 'N';
  680.         $this->setValue('N', 0, VCARD_N_FAMILY, $family);
  681.         $this->setValue('N', 0, VCARD_N_GIVEN, $given);
  682.         $this->setValue('N', 0, VCARD_N_ADDL, $addl);
  683.         $this->setValue('N', 0, VCARD_N_PREFIX, $prefix);
  684.         $this->setValue('N', 0, VCARD_N_SUFFIX, $suffix);
  685.     }
  686.     
  687.     
  688.     /**
  689.     * 
  690.     * Gets back the full N component (first iteration only, since there
  691.     * can only be one N component per vCard).
  692.     * 
  693.     * @access public
  694.     *
  695.     * @return string The first N component-interation of the vCard.
  696.     * 
  697.     */
  698.     
  699.     function getName()
  700.     {
  701.         return $this->getMeta('N', 0) .
  702.             $this->getValue('N', 0, VCARD_N_FAMILY) . ';' .
  703.             $this->getValue('N', 0, VCARD_N_GIVEN) . ';' .
  704.             $this->getValue('N', 0, VCARD_N_ADDL) . ';' .
  705.             $this->getValue('N', 0, VCARD_N_PREFIX) . ';' .
  706.             $this->getValue('N', 0, VCARD_N_SUFFIX);
  707.     }
  708.     
  709.     
  710.     
  711.     /**
  712.     * 
  713.     * Sets the FN component of the card.  If no text is passed as the
  714.     * FN value, constructs an FN automatically from N components.  There
  715.     * is only one FN iteration per vCard.
  716.     * 
  717.     * @access public
  718.     * 
  719.     * @param string $text Override the automatic generation of FN from N
  720.     * elements with the specified text.
  721.     * 
  722.     * @return mixed Void on success, or a PEAR_Error object on failure.
  723.     * 
  724.     */
  725.     
  726.     function setFormattedName($text = null)
  727.     {
  728.         $this->autoparam = 'FN';
  729.         
  730.         if ($text === null) {
  731.             
  732.             // no text was specified for the FN, so build it
  733.             // from the current N components if an N exists
  734.             if (is_array($this->value['N'])) {
  735.                 
  736.                 // build from N.
  737.                 // first (given) name, first iteration, first repetition
  738.                 $text .= $this->getValue('N', 0, VCARD_N_GIVEN, 0);
  739.             
  740.                 // add a space after, if there was text
  741.                 if ($text != '') {
  742.                     $text .= ' ';
  743.                 }
  744.                 
  745.                 // last (family) name, first iteration, first repetition
  746.                 $text .= $this->getValue('N', 0, VCARD_N_FAMILY, 0);
  747.                 
  748.                 // add a space after, if there was text
  749.                 if ($text != '') {
  750.                     $text .= ' ';
  751.                 }
  752.                 
  753.                 // last-name suffix, first iteration, first repetition
  754.                 $text .= $this->getValue('N', 0, VCARD_N_SUFFIX, 0);
  755.                 
  756.                 
  757.             } else {
  758.                 
  759.                 // no N exists, and no FN was set, so return.
  760.              //dP   return $this->raiseError('FN not specified and N not set; cannot set FN.');
  761.                 
  762.             }
  763.         
  764.         }
  765.         
  766.         $this->setValue('FN', 0, 0, $text);
  767.         
  768.     }
  769.     
  770.     
  771.     /**
  772.     * 
  773.     * Gets back the full FN component value.  Only ever returns iteration
  774.     * zero, because only one FN component is allowed per vCard.
  775.     * 
  776.     * @access public
  777.     * 
  778.     * @return string The FN value of the vCard.
  779.     * 
  780.     */
  781.     
  782.     function getFormattedName()
  783.     {
  784.         return $this->getMeta('FN', 0) . $this->getValue('FN', 0, 0);
  785.     }
  786.     
  787.     
  788.     /**
  789.     * 
  790.     * Sets the version of the the vCard.  Only one iteration.
  791.     * 
  792.     * @access public
  793.     * 
  794.     * @param string $text The text value of the verson text ('3.0' or '2.1').
  795.     * 
  796.     * @return mixed Void on success, or a PEAR_Error object on failure.
  797.     * 
  798.     */
  799.     
  800.     function setVersion($text = '3.0')
  801.     {
  802.         $this->autoparam = 'VERSION';
  803.         if ($text != '3.0' && $text != '2.1') {
  804.         //dP    return $this->raiseError('Version must be 3.0 or 2.1 to be valid.');
  805.         } else {
  806.             $this->setValue('VERSION', 0, 0, $text);
  807.         }
  808.     }
  809.     
  810.     
  811.     /**
  812.     * 
  813.     * Gets back the version of the the vCard.  Only one iteration.
  814.     * 
  815.     * @access public
  816.     * 
  817.     * @return string The data-source of the vCard.
  818.     * 
  819.     */
  820.     
  821.     function getVersion()
  822.     {
  823.         return $this->getMeta('VERSION', 0) .
  824.             $this->getValue('VERSION', 0);
  825.     }
  826.     
  827.     
  828.     /**
  829.     * 
  830.     * Sets the data-source of the the vCard.  Only one iteration.
  831.     * 
  832.     * @access public
  833.     * 
  834.     * @param string $text The text value of the data-source text.
  835.     * 
  836.     * @return void
  837.     * 
  838.     */
  839.     
  840.     function setSource($text)
  841.     {
  842.         $this->autoparam = 'SOURCE';
  843.         $this->setValue('SOURCE', 0, 0, $text);
  844.     }
  845.     
  846.     
  847.     /**
  848.     * 
  849.     * Gets back the data-source of the the vCard.  Only one iteration.
  850.     * 
  851.     * @access public
  852.     * 
  853.     * @return string The data-source of the vCard.
  854.     * 
  855.     */
  856.     
  857.     function getSource()
  858.     {
  859.         return $this->getMeta('SOURCE', 0) .
  860.             $this->getValue('SOURCE', 0, 0);
  861.     }
  862.     
  863.     
  864.     /**
  865.     * 
  866.     * Sets the displayed name of the vCard data-source.  Only one iteration.
  867.     * If no name is specified, copies the value of SOURCE.
  868.     * 
  869.     * @access public
  870.     * 
  871.     * @param string $text The text value of the displayed data-source
  872.     * name.  If null, copies the value of SOURCE.
  873.     * 
  874.     * @return mixed Void on success, or a PEAR_Error object on failure.
  875.     * 
  876.     */
  877.     
  878.     function setSourceName($text = null)
  879.     {
  880.         $this->autoparam = 'NAME';
  881.         
  882.         if ($text === null) {
  883.             if (is_array($this->value['SOURCE'])) {
  884.                 $text = $this->getValue('SOURCE', 0, 0);
  885.             } else {
  886.            //dP     return $this->raiseError('NAME not specified and SOURCE not set; cannot set NAME.');
  887.             }
  888.         }
  889.         
  890.         $this->setValue('NAME', 0, 0, $text);
  891.     }
  892.     
  893.     
  894.     /**
  895.     * 
  896.     * Gets back the displayed data-source name of the the vCard.  Only
  897.     * one iteration.
  898.     * 
  899.     * @access public
  900.     * 
  901.     * @return string The data-source name of the vCard.
  902.     * 
  903.     */
  904.     
  905.     function getSourceName()
  906.     {
  907.         return $this->getMeta('NAME', 0) .
  908.             $this->getValue('NAME', 0, 0);
  909.     }
  910.     
  911.     
  912.     
  913.     
  914.     /**
  915.     * 
  916.     * Sets the value of the PHOTO component.  There is only one allowed
  917.     * per vCard.
  918.     *
  919.     * @access public
  920.     * 
  921.     * @param string $text The value to set for this component.
  922.     *
  923.     * @return void
  924.     * 
  925.     */
  926.     
  927.     function setPhoto($text)
  928.     {
  929.         $this->autoparam = 'PHOTO';
  930.         $this->setValue('PHOTO', 0, 0, $text);
  931.     }
  932.     
  933.     
  934.     
  935.     /**
  936.     * 
  937.     * Gets back the value of the PHOTO component.  There is only one
  938.     * allowed per vCard.
  939.     *
  940.     * @access public
  941.     * 
  942.     * @return string The value of this component.
  943.     * 
  944.     */
  945.     
  946.     function getPhoto()
  947.     {
  948.         return $this->getMeta('PHOTO') .
  949.             $this->getValue('PHOTO', 0, 0);
  950.     }
  951.     
  952.     
  953.     
  954.  
  955.     /**
  956.     * 
  957.     * Sets the value of the LOGO component.  There is only one allowed
  958.     * per vCard.
  959.     *
  960.     * @access public
  961.     * 
  962.     * @param string $text The value to set for this component.
  963.     *
  964.     * @return void
  965.     * 
  966.     */
  967.     
  968.     function setLogo($text)
  969.     {
  970.         $this->autoparam = 'LOGO';
  971.         $this->setValue('LOGO', 0, 0, $text);
  972.     }
  973.     
  974.     
  975.     
  976.     /**
  977.     * 
  978.     * Gets back the value of the LOGO component.  There is only one
  979.     * allowed per vCard.
  980.     *
  981.     * @access public
  982.     * 
  983.     * @return string The value of this component.
  984.     * 
  985.     */
  986.     
  987.     function getLogo()
  988.     {
  989.         return $this->getMeta('LOGO') . $this->getValue('LOGO', 0, 0);
  990.     }
  991.     
  992.     
  993.     
  994.     /**
  995.     * 
  996.     * Sets the value of the SOUND component.  There is only one allowed
  997.     * per vCard.
  998.     *
  999.     * @access public
  1000.     * 
  1001.     * @param string $text The value to set for this component.
  1002.     *
  1003.     * @return void
  1004.     * 
  1005.     */
  1006.     
  1007.     function setSound($text)
  1008.     {
  1009.         $this->autoparam = 'SOUND';
  1010.         $this->setValue('SOUND', 0, 0, $text);
  1011.     }
  1012.     
  1013.     
  1014.     /**
  1015.     * 
  1016.     * Gets back the value of the SOUND component.  There is only one
  1017.     * allowed per vCard.
  1018.     *
  1019.     * @access public
  1020.     * 
  1021.     * @return string The value of this component.
  1022.     *
  1023.     */
  1024.     
  1025.     function getSound()
  1026.     {
  1027.         return $this->getMeta('SOUND') .
  1028.             $this->getValue('SOUND', 0, 0);
  1029.     }
  1030.     
  1031.     
  1032.     /**
  1033.     * 
  1034.     * Sets the value of the KEY component.  There is only one allowed
  1035.     * per vCard.
  1036.     *
  1037.     * @access public
  1038.     * 
  1039.     * @param string $text The value to set for this component.
  1040.     *
  1041.     * @return void
  1042.     * 
  1043.     */
  1044.     
  1045.     function setKey($text)
  1046.     {
  1047.         $this->autoparam = 'KEY';
  1048.         $this->setValue('KEY', 0, 0, $text);
  1049.     }
  1050.     
  1051.     
  1052.     
  1053.     /**
  1054.     * 
  1055.     * Gets back the value of the KEY component.  There is only one
  1056.     * allowed per vCard.
  1057.     *
  1058.     * @access public
  1059.     * 
  1060.     * @return string The value of this component.
  1061.     * 
  1062.     */
  1063.     
  1064.     function getKey()
  1065.     {
  1066.         return $this->getMeta('KEY') . $this->getValue('KEY', 0, 0);
  1067.     }
  1068.     
  1069.     
  1070.     /**
  1071.     * 
  1072.     * Sets the value of the BDAY component.  There is only one allowed
  1073.     * per vCard. Date format is "yyyy-mm-dd[Thh:ii[:ss[Z|-06:00]]]".
  1074.     *
  1075.     * @access public
  1076.     * 
  1077.     * @param string $text The value to set for this component.
  1078.     *
  1079.     * @return void
  1080.     * 
  1081.     */
  1082.     
  1083.     
  1084.     function setBirthday($text)
  1085.     {
  1086.         $this->autoparam = 'BDAY';
  1087.         $this->setValue('BDAY', 0, 0, $text);
  1088.     }
  1089.     
  1090.  
  1091.     /**
  1092.     * 
  1093.     * Gets back the value of the BDAY component.  There is only one
  1094.     * allowed per vCard.
  1095.     *
  1096.     * @access public
  1097.     * 
  1098.     * @return string The value of this component.
  1099.     * 
  1100.     */
  1101.     
  1102.     function getBirthday()
  1103.     {
  1104.         return $this->getMeta('BDAY') . $this->getValue('BDAY', 0, 0);
  1105.     }
  1106.     
  1107.     
  1108.     /**
  1109.     * 
  1110.     * Sets the value of the TZ component.  There is only one allowed per
  1111.     * vCard.
  1112.     *
  1113.     * @access public
  1114.     * 
  1115.     * @param string $text The value to set for this component.
  1116.     *
  1117.     * @return void
  1118.     * 
  1119.     */
  1120.     
  1121.     function setTZ($text)
  1122.     {
  1123.         $this->autoparam = 'TZ';
  1124.         $this->setValue('TZ', 0, 0, $text);
  1125.     }
  1126.     
  1127.     
  1128.     /**
  1129.     * 
  1130.     * Gets back the value of the TZ component.  There is only one
  1131.     * allowed per vCard.
  1132.     *
  1133.     * @access public
  1134.     * 
  1135.     * @return string The value of this component.
  1136.     * 
  1137.     */
  1138.     
  1139.     function getTZ()
  1140.     {
  1141.         return $this->getMeta('TZ') . $this->getValue('TZ', 0, 0);
  1142.     }
  1143.     
  1144.     
  1145.     /**
  1146.     * 
  1147.     * Sets the value of the MAILER component.  There is only one allowed
  1148.     * per vCard.
  1149.     *
  1150.     * @access public
  1151.     * 
  1152.     * @param string $text The value to set for this component.
  1153.     *
  1154.     * @return void
  1155.     * 
  1156.     */
  1157.     
  1158.     function setMailer($text)
  1159.     {
  1160.         $this->autoparam = 'MAILER';
  1161.         $this->setValue('MAILER', 0, 0, $text);
  1162.     }
  1163.     
  1164.     
  1165.     /**
  1166.     * 
  1167.     * Gets back the value of the MAILER component.  There is only one
  1168.     * allowed per vCard.
  1169.     *
  1170.     * @access public
  1171.     * 
  1172.     * @return string The value of this component.
  1173.     * 
  1174.     */
  1175.     
  1176.     function getMailer()
  1177.     {
  1178.         return $this->getMeta('MAILER') .
  1179.             $this->getValue('MAILER', 0, 0);
  1180.     }
  1181.     
  1182.     /**
  1183.     * 
  1184.     * Sets the value of the NOTE component.  There is only one allowed
  1185.     * per vCard.
  1186.     *
  1187.     * @access public
  1188.     * 
  1189.     * @param string $text The value to set for this component.
  1190.     *
  1191.     * @return void
  1192.     * 
  1193.     */
  1194.     
  1195.     function setNote($text)
  1196.     {
  1197.         $this->autoparam = 'NOTE';
  1198.         $this->setValue('NOTE', 0, 0, $text);
  1199.     }
  1200.     
  1201.     
  1202.     /**
  1203.     * 
  1204.     * Gets back the value of the NOTE component.  There is only one
  1205.     * allowed per vCard.
  1206.     *
  1207.     * @access public
  1208.     * 
  1209.     * @return string The value of this component.
  1210.     * 
  1211.     */
  1212.     
  1213.     function getNote()
  1214.     {
  1215.         return $this->getMeta('NOTE') . $this->getValue('NOTE', 0, 0);
  1216.     }
  1217.     
  1218.     
  1219.     /**
  1220.     * 
  1221.     * Sets the value of the TITLE component.  There is only one allowed
  1222.     * per vCard.
  1223.     *
  1224.     * @access public
  1225.     * 
  1226.     * @param string $text The value to set for this component.
  1227.     *
  1228.     * @return void
  1229.     * 
  1230.     */
  1231.     
  1232.     function setTitle($text)
  1233.     {
  1234.         $this->autoparam = 'TITLE';
  1235.         $this->setValue('TITLE', 0, 0, $text);
  1236.     }
  1237.     
  1238.     
  1239.     /**
  1240.     * 
  1241.     * Gets back the value of the TITLE component.  There is only one
  1242.     * allowed per vCard.
  1243.     *
  1244.     * @access public
  1245.     * 
  1246.     * @return string The value of this component.
  1247.     * 
  1248.     */
  1249.     
  1250.     function getTitle()
  1251.     {
  1252.         return $this->getMeta('TITLE') .
  1253.             $this->getValue('TITLE', 0, 0);
  1254.     }
  1255.     
  1256.     
  1257.     /**
  1258.     * 
  1259.     * Sets the value of the ROLE component.  There is only one allowed
  1260.     * per vCard.
  1261.     *
  1262.     * @access public
  1263.     * 
  1264.     * @param string $text The value to set for this component.
  1265.     *
  1266.     * @return void
  1267.     * 
  1268.     */
  1269.     
  1270.     function setRole($text)
  1271.     {
  1272.         $this->autoparam = 'ROLE';
  1273.         $this->setValue('ROLE', 0, 0, $text);
  1274.     }
  1275.     
  1276.     
  1277.     /**
  1278.     * 
  1279.     * Gets back the value of the ROLE component.  There is only one
  1280.     * allowed per vCard.
  1281.     *
  1282.     * @access public
  1283.     * 
  1284.     * @return string The value of this component.
  1285.     * 
  1286.     */
  1287.     
  1288.     function getRole()
  1289.     {
  1290.         return $this->getMeta('ROLE') . $this->getValue('ROLE', 0, 0);
  1291.     }
  1292.     
  1293.     
  1294.  
  1295.  
  1296.     /**
  1297.     * 
  1298.     * Sets the value of the URL component.  There is only one allowed
  1299.     * per vCard.
  1300.     *
  1301.     * @access public
  1302.     * 
  1303.     * @param string $text The value to set for this component.
  1304.     *
  1305.     * @return void
  1306.     * 
  1307.     */
  1308.     
  1309.     function setURL($text)
  1310.     {
  1311.         $this->autoparam = 'URL';
  1312.         $this->setValue('URL', 0, 0, $text);
  1313.     }
  1314.     
  1315.     
  1316.     /**
  1317.     * 
  1318.     * Gets back the value of the URL component.  There is only one
  1319.     * allowed per vCard.
  1320.     *
  1321.     * @access public
  1322.     * 
  1323.     * @return string The value of this component.
  1324.     * 
  1325.     */
  1326.     
  1327.     function getURL()
  1328.     {
  1329.         return $this->getMeta('URL') . $this->getValue('URL', 0, 0);
  1330.     }
  1331.     
  1332.     
  1333.     /**
  1334.     * 
  1335.     * Sets the value of the CLASS component.  There is only one allowed
  1336.     * per vCard.
  1337.     *
  1338.     * @access public
  1339.     * 
  1340.     * @param string $text The value to set for this component.
  1341.     *
  1342.     * @return void
  1343.     * 
  1344.     */
  1345.     
  1346.     function setClass($text)
  1347.     {
  1348.         $this->autoparam = 'CLASS';
  1349.         $this->setValue('CLASS', 0, 0, $text);
  1350.     }
  1351.     
  1352.     
  1353.     /**
  1354.     * 
  1355.     * Gets back the value of the CLASS component.  There is only one
  1356.     * allowed per vCard.
  1357.     *
  1358.     * @access public
  1359.     * 
  1360.     * @return string The value of this component.
  1361.     * 
  1362.     */
  1363.  
  1364.     function getClass()
  1365.     {
  1366.         return $this->getMeta('CLASS') .
  1367.             $this->getValue('CLASS', 0, 0);
  1368.     }
  1369.     
  1370.     
  1371.     /**
  1372.     * 
  1373.     * Sets the value of the SORT-STRING component.  There is only one
  1374.     * allowed per vCard.
  1375.     *
  1376.     * @access public
  1377.     * 
  1378.     * @param string $text The value to set for this component.
  1379.     *
  1380.     * @return void
  1381.     * 
  1382.     */
  1383.     
  1384.     function setSortString($text)
  1385.     {
  1386.         $this->autoparam = 'SORT-STRING';
  1387.         $this->setValue('SORT-STRING', 0, 0, $text);
  1388.     }
  1389.     
  1390.     
  1391.     /**
  1392.     * 
  1393.     * Gets back the value of the SORT-STRING component.  There is only
  1394.     * one allowed per vCard.
  1395.     * 
  1396.     * @access public
  1397.     * 
  1398.     * @return string The value of this component.
  1399.     * 
  1400.     */
  1401.     
  1402.     function getSortString()
  1403.     {
  1404.         return $this->getMeta('SORT-STRING') .
  1405.             $this->getValue('SORT-STRING', 0, 0);
  1406.     }
  1407.     
  1408.     
  1409.     /**
  1410.     * 
  1411.     * Sets the value of the PRODID component.  There is only one allowed
  1412.     * per vCard.
  1413.     * 
  1414.     * @access public
  1415.     * 
  1416.     * @param string $text The value to set for this component.
  1417.     * 
  1418.     * @return void
  1419.     * 
  1420.     */
  1421.     
  1422.     function setProductID($text)
  1423.     {
  1424.         $this->autoparam = 'PRODID';
  1425.         $this->setValue('PRODID', 0, 0, $text);
  1426.     }
  1427.     
  1428.     
  1429.     /**
  1430.     *
  1431.     * Gets back the value of the PRODID component.  There is only one
  1432.     * allowed per vCard.
  1433.     * 
  1434.     * @access public
  1435.     * 
  1436.     * @return string The value of this component.
  1437.     * 
  1438.     */
  1439.     
  1440.     function getProductID()
  1441.     {
  1442.         return $this->getMeta('PRODID') .
  1443.             $this->getValue('PRODID', 0, 0);
  1444.     }
  1445.     
  1446.     
  1447.     
  1448.     
  1449.     /**
  1450.     * 
  1451.     * Sets the value of the REV component.  There is only one allowed
  1452.     * per vCard.
  1453.     * 
  1454.     * @access public
  1455.     * 
  1456.     * @param string $text The value to set for this component.
  1457.     * 
  1458.     * @return void
  1459.     * 
  1460.     */
  1461.     
  1462.     function setRevision($text)
  1463.     {
  1464.         $this->autoparam = 'REV';
  1465.         $this->setValue('REV', 0, 0, $text);
  1466.     }
  1467.     
  1468.     
  1469.     /**
  1470.     * 
  1471.     * Gets back the value of the REV component.  There is only one
  1472.     * allowed per vCard.
  1473.     * 
  1474.     * @access public
  1475.     * 
  1476.     * @return string The value of this component.
  1477.     * 
  1478.     */
  1479.     
  1480.     function getRevision()
  1481.     {
  1482.         return $this->getMeta('REV') . $this->getValue('REV', 0, 0);
  1483.     }
  1484.     
  1485.     
  1486.     /**
  1487.     * 
  1488.     * Sets the value of the UID component.  There is only one allowed
  1489.     * per vCard.
  1490.     * 
  1491.     * @access public
  1492.     * 
  1493.     * @param string $text The value to set for this component.
  1494.     * 
  1495.     * @return void
  1496.     * 
  1497.     */
  1498.  
  1499.     function setUniqueID($text)
  1500.     {
  1501.         $this->autoparam = 'UID';
  1502.         $this->setValue('UID', 0, 0, $text);
  1503.     }
  1504.     
  1505.     
  1506.     /**
  1507.     * 
  1508.     * Gets back the value of the UID component.  There is only one
  1509.     * allowed per vCard.
  1510.     * 
  1511.     * @access public
  1512.     * 
  1513.     * @return string The value of this component.
  1514.     * 
  1515.     */
  1516.     
  1517.     function getUniqueID()
  1518.     {
  1519.         return $this->getMeta('UID') . $this->getValue('UID', 0, 0);
  1520.     }
  1521.     
  1522.     
  1523.     /**
  1524.     * 
  1525.     * Sets the value of the AGENT component.  There is only one allowed
  1526.     * per vCard.
  1527.     * 
  1528.     * @access public
  1529.     * 
  1530.     * @param string $text The value to set for this component.
  1531.     * 
  1532.     * @return void
  1533.     * 
  1534.     */
  1535.     
  1536.     function setAgent($text)
  1537.     {
  1538.         $this->autoparam = 'AGENT';
  1539.         $this->setValue('AGENT', 0, 0, $text);
  1540.     }
  1541.     
  1542.     
  1543.     /**
  1544.     * 
  1545.     * Gets back the value of the AGENT component.  There is only one
  1546.     * allowed per vCard.
  1547.     * 
  1548.     * @access public
  1549.     * 
  1550.     * @return string The value of this component.
  1551.     * 
  1552.     */
  1553.     
  1554.     function getAgent()
  1555.     {
  1556.         return $this->getMeta('AGENT') .
  1557.             $this->getValue('AGENT', 0, 0);
  1558.     }
  1559.     
  1560.     
  1561.     /**
  1562.     * 
  1563.     * Sets the value of both parts of the GEO component.  There is only
  1564.     * one GEO component allowed per vCard.
  1565.     * 
  1566.     * @access public
  1567.     *
  1568.     * @param string $lat The value to set for the longitude part
  1569.     * (decimal, + or -).
  1570.     * 
  1571.     * @param string $lon The value to set for the latitude part
  1572.     * (decimal, + or -).
  1573.     * 
  1574.     * @return void
  1575.     * 
  1576.     */
  1577.     
  1578.     function setGeo($lat, $lon)
  1579.     {
  1580.         $this->autoparam = 'GEO';
  1581.         $this->setValue('GEO', 0, VCARD_GEO_LAT, $lat);
  1582.         $this->setValue('GEO', 0, VCARD_GEO_LON, $lon);
  1583.     }
  1584.     
  1585.     
  1586.     /**
  1587.     * 
  1588.     * Gets back the value of the GEO component.  There is only one
  1589.     * allowed per vCard.
  1590.     *
  1591.     * @access public
  1592.     * 
  1593.     * @return string The value of this component.
  1594.     * 
  1595.     */
  1596.     
  1597.     function getGeo()
  1598.     {
  1599.         return $this->getMeta('GEO', 0) .
  1600.             $this->getValue('GEO', 0, VCARD_GEO_LAT, 0) . ';' .
  1601.             $this->getValue('GEO', 0, VCARD_GEO_LON, 0);
  1602.     }
  1603.     
  1604.     
  1605.     /**
  1606.     * 
  1607.     * Sets the value of one entire ADR iteration.  There can be zero,
  1608.     * one, or more ADR components in a vCard.
  1609.     *
  1610.     * @access public
  1611.     * 
  1612.     * @param mixed $pob String (one repetition) or array (multiple
  1613.     * reptitions) of the p.o. box part of the ADR component iteration.
  1614.     * 
  1615.     * @param mixed $extend String (one repetition) or array (multiple
  1616.     * reptitions) of the "extended address" part of the ADR component
  1617.     * iteration.
  1618.     * 
  1619.     * @param mixed $street String (one repetition) or array (multiple
  1620.     * reptitions) of the street address part of the ADR component
  1621.     * iteration.
  1622.     * 
  1623.     * @param mixed $locality String (one repetition) or array (multiple
  1624.     * reptitions) of the locailty (e.g., city) part of the ADR component
  1625.     * iteration.
  1626.     * 
  1627.     * @param mixed $region String (one repetition) or array (multiple
  1628.     * reptitions) of the region (e.g., state, province, or governorate)
  1629.     * part of the ADR component iteration.
  1630.     * 
  1631.     * @param mixed $postcode String (one repetition) or array (multiple
  1632.     * reptitions) of the postal code (e.g., ZIP code) part of the ADR
  1633.     * component iteration.
  1634.     *
  1635.     * @param mixed $country String (one repetition) or array (multiple
  1636.     * reptitions) of the country-name part of the ADR component
  1637.     * iteration.
  1638.     * 
  1639.     * @return void
  1640.     * 
  1641.     */
  1642.     
  1643.     function addAddress($pob, $extend, $street, $locality, $region,
  1644.         $postcode, $country)
  1645.     {
  1646.         $this->autoparam = 'ADR';
  1647.         $iter = count($this->value['ADR']);
  1648.         $this->setValue('ADR', $iter, VCARD_ADR_POB,       $pob);
  1649.         $this->setValue('ADR', $iter, VCARD_ADR_EXTEND,    $extend);
  1650.         $this->setValue('ADR', $iter, VCARD_ADR_STREET,    $street);
  1651.         $this->setValue('ADR', $iter, VCARD_ADR_LOCALITY,  $locality);
  1652.         $this->setValue('ADR', $iter, VCARD_ADR_REGION,    $region);
  1653.         $this->setValue('ADR', $iter, VCARD_ADR_POSTCODE,  $postcode);
  1654.         $this->setValue('ADR', $iter, VCARD_ADR_COUNTRY,   $country);
  1655.     }
  1656.     
  1657.     
  1658.     /**
  1659.     * 
  1660.     * Gets back the value of one ADR component iteration.
  1661.     *
  1662.     * @access public
  1663.     * 
  1664.     * @param int $iter The component iteration-number to get the value
  1665.     * for.
  1666.     * 
  1667.     * @return mixed The value of this component iteration, or a
  1668.     * PEAR_Error if the iteration is not valid.
  1669.     * 
  1670.     */
  1671.     
  1672.     function getAddress($iter)
  1673.     {
  1674.         if (! is_integer($iter) || $iter < 0) {
  1675.             
  1676.           //dP  return $this->raiseError('ADR iteration number not valid.');
  1677.         
  1678.         } else {
  1679.             
  1680.             return $this->getMeta('ADR', $iter) .
  1681.                 $this->getValue('ADR', $iter, VCARD_ADR_POB) . ';' .
  1682.                 $this->getValue('ADR', $iter, VCARD_ADR_EXTEND) . ';' .
  1683.                 $this->getValue('ADR', $iter, VCARD_ADR_STREET) . ';' .
  1684.                 $this->getValue('ADR', $iter, VCARD_ADR_LOCALITY) . ';' .
  1685.                 $this->getValue('ADR', $iter, VCARD_ADR_REGION) . ';' .
  1686.                 $this->getValue('ADR', $iter, VCARD_ADR_POSTCODE) . ';' .
  1687.                 $this->getValue('ADR', $iter, VCARD_ADR_COUNTRY);
  1688.         }
  1689.     }
  1690.     
  1691.     
  1692.     /**
  1693.     * 
  1694.     * Sets the value of one LABEL component iteration.  There can be
  1695.     * zero, one, or more component iterations in a vCard.
  1696.     *
  1697.     * @access public
  1698.     * 
  1699.     * @param string $text The value to set for this component.
  1700.     *
  1701.     * @return void
  1702.     *
  1703.     */
  1704.     
  1705.     function addLabel($text)
  1706.     {
  1707.         $this->autoparam = 'LABEL';
  1708.         $iter = count($this->value['LABEL']);
  1709.         $this->setValue('LABEL', $iter, 0, $text);
  1710.     }
  1711.     
  1712.     
  1713.     /**
  1714.     * 
  1715.     * Gets back the value of one iteration of the LABEL component. 
  1716.     * There can be zero, one, or more component iterations in a vCard.
  1717.     *
  1718.     * @access public
  1719.     * 
  1720.     * @param int $iter The component iteration-number to get the value
  1721.     * for.
  1722.     *
  1723.     * @return mixed The value of this component, or a PEAR_Error if
  1724.     * the iteration number is not valid.
  1725.     * 
  1726.     */
  1727.     
  1728.     function getLabel($iter)
  1729.     {
  1730.         if (! is_integer($iter) || $iter < 0) {
  1731.          //dP   return $this->raiseError('LABEL iteration number not valid.');
  1732.         } else {
  1733.             return $this->getMeta('LABEL', $iter) .
  1734.                 $this->getValue('LABEL', $iter, 0);
  1735.         }
  1736.     }
  1737.     
  1738.     
  1739.     /**
  1740.     * 
  1741.     * Sets the value of one TEL component iteration.  There can be zero,
  1742.     * one, or more component iterations in a vCard.
  1743.     *
  1744.     * @access public
  1745.     * 
  1746.     * @param string $text The value to set for this component.
  1747.     *
  1748.     * @return void
  1749.     * 
  1750.     */
  1751.     
  1752.     function addTelephone($text)
  1753.     {
  1754.         $this->autoparam = 'TEL';
  1755.         $iter = count($this->value['TEL']);
  1756.         $this->setValue('TEL', $iter, 0, $text);
  1757.     }
  1758.     
  1759.     
  1760.     /**
  1761.     * 
  1762.     * Gets back the value of one iteration of the TEL component.  There
  1763.     * can be zero, one, or more component iterations in a vCard.
  1764.     *
  1765.     * @access public
  1766.     * 
  1767.     * @param int $iter The component iteration-number to get the value
  1768.     * for.
  1769.     *
  1770.     * @return mixed The value of this component, or a PEAR_Error if the
  1771.     * iteration number is not valid.
  1772.     * 
  1773.     */
  1774.     
  1775.     function getTelephone($iter)
  1776.     {
  1777.         if (! is_integer($iter) || $iter < 0) {
  1778.        //dP     return $this->raiseError('TEL iteration number not valid.');
  1779.         } else {
  1780.             return $this->getMeta('TEL', $iter) .
  1781.                 $this->getValue('TEL', $iter, 0);
  1782.         }
  1783.     }
  1784.     
  1785.     /**
  1786.     * 
  1787.     * Sets the value of one EMAIL component iteration.  There can be zero,
  1788.     * one, or more component iterations in a vCard.
  1789.     *
  1790.     * @access public
  1791.     * 
  1792.     * @param string $text The value to set for this component.
  1793.     *
  1794.     * @return void
  1795.     * 
  1796.     */
  1797.     
  1798.     function addEmail($text)
  1799.     {
  1800.         $this->autoparam = 'EMAIL';
  1801.         $iter = count($this->value['EMAIL']);
  1802.         $this->setValue('EMAIL', $iter, 0, $text);
  1803.     }
  1804.     
  1805.     
  1806.     /**
  1807.     * 
  1808.     * Gets back the value of one iteration of the EMAIL component.  There can
  1809.     * be zero, one, or more component iterations in a vCard.
  1810.     *
  1811.     * @access public
  1812.     * 
  1813.     * @param int $iter The component iteration-number to get the value
  1814.     * for.
  1815.     *
  1816.     * @return mixed The value of this component, or a PEAR_Error if the
  1817.     * iteration number is not valid.
  1818.     * 
  1819.     */
  1820.     
  1821.     function getEmail($iter)
  1822.     {
  1823.         if (! is_integer($iter) || $iter < 0) {
  1824.        //dP     return $this->raiseError('EMAIL iteration number not valid.');
  1825.         } else {
  1826.             return $this->getMeta('EMAIL', $iter) .
  1827.                 $this->getValue('EMAIL', $iter, 0);
  1828.         }
  1829.     }
  1830.     
  1831.     
  1832.     /**
  1833.     * 
  1834.     * Sets the full value of the NICKNAME component.  There is only one
  1835.     * component iteration allowed per vCard, but there may be multiple
  1836.     * value repetitions in the iteration.
  1837.     *
  1838.     * @access public
  1839.     * 
  1840.     * @param mixed $text String (one repetition) or array (multiple
  1841.     * reptitions) of the component iteration value.
  1842.     *
  1843.     * @return void
  1844.     * 
  1845.     */
  1846.  
  1847.     function addNickname($text)
  1848.     {
  1849.         $this->autoparam = 'NICKNAME';
  1850.         $this->addValue('NICKNAME', 0, 0, $text);
  1851.     }
  1852.     
  1853.     
  1854.     /**
  1855.     * 
  1856.     * Gets back the value of the NICKNAME component.  There is only one
  1857.     * component allowed per vCard, but there may be multiple value
  1858.     * repetitions in the iteration.
  1859.     *
  1860.     * @access public
  1861.     * 
  1862.     * @return string The value of this component.
  1863.     * 
  1864.     */
  1865.     
  1866.     function getNickname()
  1867.     {
  1868.         return $this->getMeta('NICKNAME') .
  1869.             $this->getValue('NICKNAME', 0, 0);
  1870.     }
  1871.     
  1872.     
  1873.     
  1874.     /**
  1875.     * 
  1876.     * Sets the full value of the CATEGORIES component.  There is only
  1877.     * one component iteration allowed per vCard, but there may be
  1878.     * multiple value repetitions in the iteration.
  1879.     *
  1880.     * @access public
  1881.     * 
  1882.     * @param mixed $text String (one repetition) or array (multiple
  1883.     * reptitions) of the component iteration value.
  1884.     *
  1885.     * @return void
  1886.     * 
  1887.     */
  1888.     
  1889.     function addCategories($text, $append = true)
  1890.     {
  1891.         $this->autoparam = 'CATEGORIES';
  1892.         $this->addValue('CATEGORIES', 0, 0, $text);
  1893.     }
  1894.     
  1895.     
  1896.     /**
  1897.     * 
  1898.     * Gets back the value of the CATEGORIES component.  There is only
  1899.     * one component allowed per vCard, but there may be multiple value
  1900.     * repetitions in the iteration.
  1901.     *
  1902.     * @access public
  1903.     * 
  1904.     * @return string The value of this component.
  1905.     * 
  1906.     */
  1907.     
  1908.     function getCategories()
  1909.     {
  1910.         return $this->getMeta('CATEGORIES', 0) .
  1911.             $this->getValue('CATEGORIES', 0, 0);
  1912.     }
  1913.     
  1914.     
  1915.     /**
  1916.     * 
  1917.     * Sets the full value of the ORG component.  There can be only one
  1918.     * ORG component in a vCard.
  1919.     * 
  1920.     * The ORG component can have one or more parts (as opposed to
  1921.     * repetitions of values within those parts).  The first part is the
  1922.     * highest-level organization, the second part is the next-highest,
  1923.     * the third part is the third-highest, and so on.  There can by any
  1924.     * number of parts in one ORG iteration.  (This is different from
  1925.     * other components, such as NICKNAME, where an iteration has only
  1926.     * one part but may have many repetitions within that part.)
  1927.     * 
  1928.     * @access public
  1929.     * 
  1930.     * @param mixed $text String (one ORG part) or array (of ORG
  1931.     * parts) to use as the value for the component iteration.
  1932.     * 
  1933.     * @return void
  1934.     * 
  1935.     */
  1936.     
  1937.     function addOrganization($text)
  1938.     {
  1939.         $this->autoparam = 'ORG';
  1940.         
  1941.         settype($text, 'array');
  1942.         
  1943.         $base = count($this->value['ORG'][0]);
  1944.         
  1945.         // start at the original base point, and add
  1946.         // new parts
  1947.         foreach ($text as $part => $val) {
  1948.             $this->setValue('ORG', 0, $base + $part, $val);
  1949.         }
  1950.     }
  1951.     
  1952.     
  1953.     /**
  1954.     * 
  1955.     * Gets back the value of the ORG component.
  1956.     * 
  1957.     * @return string The value of this component.
  1958.     * 
  1959.     */
  1960.  
  1961.     function getOrganization()
  1962.     {
  1963.         $text = $this->getMeta('ORG', 0);
  1964.         
  1965.         $k = count($this->value['ORG'][0]);
  1966.         $last = $k - 1;
  1967.         
  1968.         for ($part = 0; $part < $k; $part++) {
  1969.         
  1970.             $text .= $this->getValue('ORG', 0, $part);
  1971.             
  1972.             if ($part != $last) {
  1973.                 $text .= ';';
  1974.             }
  1975.  
  1976.         }
  1977.         
  1978.         return $text;
  1979.     }
  1980.     
  1981.     
  1982.     /**
  1983.     * 
  1984.     * Builds a vCard from a Contact_Vcard_Parse result array.  Only send
  1985.     * one vCard from the parse-results.
  1986.     *
  1987.     * Usage (to build from first vCard in parsed results):
  1988.     * 
  1989.     * $parse = new Contact_Vcard_Parse(); // new parser
  1990.     * $info = $parse->fromFile('sample.vcf'); // parse file
  1991.     * 
  1992.     * $vcard = new Contact_Vcard_Build(); // new builder
  1993.     * $vcard->setFromArray($info[0]); // [0] is the first card
  1994.     * 
  1995.     * 
  1996.     * @access public
  1997.     * 
  1998.     * @param array $src One vCard entry as parsed using
  1999.     * Contact_Vcard_Parse.
  2000.     * 
  2001.     * @return void
  2002.     * 
  2003.     * @see Contact_Vcard_Parse::fromFile()
  2004.     * 
  2005.     * @see Contact_Vcard_Parse::fromText()
  2006.     * 
  2007.     */
  2008.     
  2009.     function setFromArray($src)
  2010.     {
  2011.         // reset to a blank values and params
  2012.         $this->value = array();
  2013.         $this->param = array();
  2014.         
  2015.         // loop through components (N, ADR, TEL, etc)
  2016.         foreach ($src AS $comp => $comp_val) {
  2017.             
  2018.             // set the autoparam property. not really needed, but let's
  2019.             // behave after an expected fashion, shall we?  ;-)
  2020.             $this->autoparam = $comp; 
  2021.             
  2022.             // iteration number of each component
  2023.             foreach ($comp_val AS $iter => $iter_val) {
  2024.                 
  2025.                 // value or param?
  2026.                 foreach ($iter_val AS $kind => $kind_val) {
  2027.                 
  2028.                     // part number
  2029.                     foreach ($kind_val AS $part => $part_val) {
  2030.                         
  2031.                         // repetition number and text value
  2032.                         foreach ($part_val AS $rept => $text) {
  2033.                             
  2034.                             // ignore data when $kind is neither 'value'
  2035.                             // nor 'param'
  2036.                             if (strtolower($kind) == 'value') {
  2037.                                 $this->value[strtoupper($comp)][$iter][$part][$rept] = $text;
  2038.                             } elseif (strtolower($kind) == 'param') {
  2039.                                 $this->param[strtoupper($comp)][$iter][$part][$rept] = $text;
  2040.                             }
  2041.                             
  2042.                         }
  2043.                     }
  2044.                 }
  2045.             }
  2046.         }
  2047.     }
  2048.     
  2049.     
  2050.     /**
  2051.     *
  2052.     * Fetches a full vCard text block based on $this->value and
  2053.     * $this->param. The order of the returned components is similar to
  2054.     * their order in RFC 2426.  Honors the value of
  2055.     * $this->value['VERSION'] to determine which vCard components are
  2056.     * returned (2.1- or 3.0-compliant).
  2057.     *
  2058.     * @access public
  2059.     * @return string A properly formatted vCard text block.
  2060.     *
  2061.     */
  2062.     
  2063.     function fetch()
  2064.     {
  2065.         // vCard version is required
  2066.         if (! is_array($this->value['VERSION'])) {
  2067.        //dP     return $this->raiseError('VERSION not set (required).');
  2068.         }
  2069.  
  2070.         // FN component is required
  2071.         if (! is_array($this->value['FN'])) {
  2072.        //dP     return $this->raiseError('FN component not set (required).');
  2073.         }
  2074.  
  2075.         // N component is required
  2076.         if (! is_array($this->value['N'])) {
  2077.        //dP     return $this->raiseError('N component not set (required).');
  2078.         }
  2079.  
  2080.         // initialize the vCard lines
  2081.         $lines = array();
  2082.  
  2083.         // begin (required)
  2084.         $lines[] = "BEGIN:VCARD";
  2085.  
  2086.         // version (required)
  2087.         // available in both 2.1 and 3.0
  2088.         $lines[] = $this->getVersion();
  2089.  
  2090.         // formatted name (required)
  2091.         // available in both 2.1 and 3.0
  2092.         $lines[] = $this->getFormattedName();
  2093.  
  2094.         // structured name (required)
  2095.         // available in both 2.1 and 3.0
  2096.         $lines[] = $this->getName();
  2097.  
  2098.         // profile (3.0 only)
  2099.         if ($this->value['VERSION'][0][0][0] == '3.0') {
  2100.             $lines[] = "PROFILE:VCARD";
  2101.         }
  2102.  
  2103.         // displayed name of the data source  (3.0 only)
  2104.         if (is_array($this->value['NAME']) &&
  2105.             $this->value['VERSION'][0][0][0] == '3.0') {
  2106.             $lines[] = $this->getSourceName();
  2107.         }
  2108.  
  2109.         // data source (3.0 only)
  2110.         if (is_array($this->value['SOURCE']) &&
  2111.             $this->value['VERSION'][0][0][0] == '3.0') {
  2112.             $lines[] = $this->getSource();
  2113.         }
  2114.  
  2115.         // nicknames (3.0 only)
  2116.         if (is_array($this->value['NICKNAME']) &&
  2117.             $this->value['VERSION'][0][0][0] == '3.0') {
  2118.             $lines[] = $this->getNickname();
  2119.         }
  2120.  
  2121.         // personal photo
  2122.         // available in both 2.1 and 3.0
  2123.         if (is_array($this->value['PHOTO'])) {
  2124.             $lines[] = $this->getPhoto();
  2125.         }
  2126.  
  2127.         // bday
  2128.         // available in both 2.1 and 3.0
  2129.         if (is_array($this->value['BDAY'])) {
  2130.             $lines[] = $this->getBirthday();
  2131.         }
  2132.  
  2133.         // adr
  2134.         // available in both 2.1 and 3.0
  2135.         if (is_array($this->value['ADR'])) {
  2136.             foreach ($this->value['ADR'] as $key => $val) {
  2137.                 $lines[] = $this->getAddress($key);
  2138.             }
  2139.         }
  2140.  
  2141.         // label
  2142.         // available in both 2.1 and 3.0
  2143.         if (is_array($this->value['LABEL'])) {
  2144.             foreach ($this->value['LABEL'] as $key => $val) {
  2145.                 $lines[] = $this->getLabel($key);
  2146.             }
  2147.         }
  2148.  
  2149.         // tel
  2150.         // available in both 2.1 and 3.0
  2151.         if (is_array($this->value['TEL'])) {
  2152.             foreach ($this->value['TEL'] as $key => $val) {
  2153.                 $lines[] = $this->getTelephone($key);
  2154.             }
  2155.         }
  2156.  
  2157.         // email
  2158.         // available in both 2.1 and 3.0
  2159.         if (is_array($this->value['EMAIL'])) {
  2160.             foreach ($this->value['EMAIL'] as $key => $val) {
  2161.                 $lines[] = $this->getEmail($key);
  2162.             }
  2163.         }
  2164.  
  2165.         // mailer
  2166.         // available in both 2.1 and 3.0
  2167.         if (is_array($this->value['MAILER'])) {
  2168.             $lines[] = $this->getMailer();
  2169.         }
  2170.  
  2171.         // tz
  2172.         // available in both 2.1 and 3.0
  2173.         if (is_array($this->value['TZ'])) {
  2174.             $lines[] = $this->getTZ();
  2175.         }
  2176.  
  2177.         // geo
  2178.         // available in both 2.1 and 3.0
  2179.         if (is_array($this->value['GEO'])) {
  2180.             $lines[] = $this->getGeo();
  2181.         }
  2182.  
  2183.         // title
  2184.         // available in both 2.1 and 3.0
  2185.         if (is_array($this->value['TITLE'])) {
  2186.             $lines[] = $this->getTitle();
  2187.         }
  2188.  
  2189.         // role
  2190.         // available in both 2.1 and 3.0
  2191.         if (is_array($this->value['ROLE'])) {
  2192.             $lines[] = $this->getRole();
  2193.         }
  2194.  
  2195.         // company logo
  2196.         // available in both 2.1 and 3.0
  2197.         if (is_array($this->value['LOGO'])) {
  2198.             $lines[] = $this->getLogo();
  2199.         }
  2200.         
  2201.         // agent
  2202.         // available in both 2.1 and 3.0
  2203.         if (is_array($this->value['AGENT'])) {
  2204.             $lines[] = $this->getAgent();
  2205.         }
  2206.         
  2207.         // org
  2208.         // available in both 2.1 and 3.0
  2209.         if (is_array($this->value['ORG'])) {
  2210.             $lines[] = $this->getOrganization();
  2211.         }
  2212.         
  2213.         // categories (3.0 only)
  2214.         if (is_array($this->value['CATEGORIES']) &&
  2215.             $this->value['VERSION'][0][0][0] == '3.0') {
  2216.             $lines[] = $this->getCategories();
  2217.         }
  2218.         
  2219.         // note
  2220.         // available in both 2.1 and 3.0
  2221.         if (is_array($this->value['NOTE'])) {
  2222.             $lines[] = $this->getNote();
  2223.         }
  2224.         
  2225.         // prodid (3.0 only)
  2226.         if (is_array($this->value['PRODID']) &&
  2227.             $this->value['VERSION'][0][0][0] == '3.0') {
  2228.             $lines[] = $this->getProductID();
  2229.         }
  2230.         
  2231.         // rev
  2232.         // available in both 2.1 and 3.0
  2233.         if (is_array($this->value['REV'])) {
  2234.             $lines[] = $this->getRevision();
  2235.         }
  2236.         
  2237.         // sort-string (3.0 only)
  2238.         if (is_array($this->value['SORT-STRING']) &&
  2239.             $this->value['VERSION'][0][0][0] == '3.0') {
  2240.             $lines[] = $this->getSortString();
  2241.         }
  2242.         
  2243.         // name-pronounciation sound
  2244.         // available in both 2.1 and 3.0
  2245.         if (is_array($this->value['SOUND'])) {
  2246.             $lines[] = $this->getSound();
  2247.         }
  2248.         
  2249.         // uid
  2250.         // available in both 2.1 and 3.0
  2251.         if (is_array($this->value['UID'])) {
  2252.             $lines[] = $this->getUniqueID();
  2253.         }
  2254.         
  2255.         // url
  2256.         // available in both 2.1 and 3.0
  2257.         if (is_array($this->value['URL'])) {
  2258.             $lines[] = $this->getURL();
  2259.         }
  2260.         
  2261.         // class (3.0 only)
  2262.         if (is_array($this->value['CLASS']) &&
  2263.             $this->value['VERSION'][0][0][0] == '3.0') {
  2264.             $lines[] = $this->getClass();
  2265.         }
  2266.         
  2267.         // key
  2268.         // available in both 2.1 and 3.0
  2269.         if (is_array($this->value['KEY'])) {
  2270.             $lines[] = $this->getKey();
  2271.         }
  2272.         
  2273.         // required
  2274.         $lines[] = "END:VCARD";
  2275.         
  2276.         // version 3.0 uses \n for new lines,
  2277.         // version 2.1 uses \r\n
  2278.         $newline = "\n";
  2279.         if ($this->value['VERSION'][0][0][0] == '2.1') {
  2280.             $newline = "\r\n";
  2281.         }
  2282.         
  2283.         // fold lines at 75 characters
  2284.         $regex = "(.{1,75})";
  2285.            foreach ($lines as $key => $val) {
  2286.             if (strlen($val) > 75) {
  2287.                 // we trim to drop the last newline, which will be added
  2288.                 // again by the implode function at the end of fetch()
  2289.                 $lines[$key] = trim(preg_replace("/$regex/i", "\\1$newline ", $val));
  2290.             }
  2291.         }
  2292.         
  2293.         // compile the array of lines into a single text block
  2294.         // and return
  2295.         return implode($newline, $lines);
  2296.     }
  2297.     
  2298.  
  2299.     /**
  2300.     *
  2301.     * Emulated destructor.
  2302.     *
  2303.     * @access private
  2304.     * @return boolean true
  2305.     *
  2306.     */
  2307.     
  2308.     function _Contact_Vcard_Build()
  2309.     {
  2310.         return true;
  2311.     }
  2312. }
  2313.  
  2314. ?>
  2315.