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