vendor/sabre/vobject/lib/Document.php line 131

Open in your IDE?
  1. <?php
  2. namespace Sabre\VObject;
  3. /**
  4.  * Document.
  5.  *
  6.  * A document is just like a component, except that it's also the top level
  7.  * element.
  8.  *
  9.  * Both a VCALENDAR and a VCARD are considered documents.
  10.  *
  11.  * This class also provides a registry for document types.
  12.  *
  13.  * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
  14.  * @author Evert Pot (http://evertpot.com/)
  15.  * @license http://sabre.io/license/ Modified BSD License
  16.  */
  17. abstract class Document extends Component
  18. {
  19.     /**
  20.      * Unknown document type.
  21.      */
  22.     const UNKNOWN 1;
  23.     /**
  24.      * vCalendar 1.0.
  25.      */
  26.     const VCALENDAR10 2;
  27.     /**
  28.      * iCalendar 2.0.
  29.      */
  30.     const ICALENDAR20 3;
  31.     /**
  32.      * vCard 2.1.
  33.      */
  34.     const VCARD21 4;
  35.     /**
  36.      * vCard 3.0.
  37.      */
  38.     const VCARD30 5;
  39.     /**
  40.      * vCard 4.0.
  41.      */
  42.     const VCARD40 6;
  43.     /**
  44.      * The default name for this component.
  45.      *
  46.      * This should be 'VCALENDAR' or 'VCARD'.
  47.      *
  48.      * @var string
  49.      */
  50.     public static $defaultName;
  51.     /**
  52.      * List of properties, and which classes they map to.
  53.      *
  54.      * @var array
  55.      */
  56.     public static $propertyMap = [];
  57.     /**
  58.      * List of components, along with which classes they map to.
  59.      *
  60.      * @var array
  61.      */
  62.     public static $componentMap = [];
  63.     /**
  64.      * List of value-types, and which classes they map to.
  65.      *
  66.      * @var array
  67.      */
  68.     public static $valueMap = [];
  69.     /**
  70.      * Creates a new document.
  71.      *
  72.      * We're changing the default behavior slightly here. First, we don't want
  73.      * to have to specify a name (we already know it), and we want to allow
  74.      * children to be specified in the first argument.
  75.      *
  76.      * But, the default behavior also works.
  77.      *
  78.      * So the two sigs:
  79.      *
  80.      * new Document(array $children = [], $defaults = true);
  81.      * new Document(string $name, array $children = [], $defaults = true)
  82.      */
  83.     public function __construct()
  84.     {
  85.         $args func_get_args();
  86.         $name = static::$defaultName;
  87.         if (=== count($args) || is_array($args[0])) {
  88.             $children = isset($args[0]) ? $args[0] : [];
  89.             $defaults = isset($args[1]) ? $args[1] : true;
  90.         } else {
  91.             $name $args[0];
  92.             $children = isset($args[1]) ? $args[1] : [];
  93.             $defaults = isset($args[2]) ? $args[2] : true;
  94.         }
  95.         parent::__construct($this$name$children$defaults);
  96.     }
  97.     /**
  98.      * Returns the current document type.
  99.      *
  100.      * @return int
  101.      */
  102.     public function getDocumentType()
  103.     {
  104.         return self::UNKNOWN;
  105.     }
  106.     /**
  107.      * Creates a new component or property.
  108.      *
  109.      * If it's a known component, we will automatically call createComponent.
  110.      * otherwise, we'll assume it's a property and call createProperty instead.
  111.      *
  112.      * @param string $name
  113.      * @param string $arg1,... Unlimited number of args
  114.      *
  115.      * @return mixed
  116.      */
  117.     public function create($name)
  118.     {
  119.         if (isset(static::$componentMap[strtoupper($name)])) {
  120.             return call_user_func_array([$this'createComponent'], func_get_args());
  121.         } else {
  122.             return call_user_func_array([$this'createProperty'], func_get_args());
  123.         }
  124.     }
  125.     /**
  126.      * Creates a new component.
  127.      *
  128.      * This method automatically searches for the correct component class, based
  129.      * on its name.
  130.      *
  131.      * You can specify the children either in key=>value syntax, in which case
  132.      * properties will automatically be created, or you can just pass a list of
  133.      * Component and Property object.
  134.      *
  135.      * By default, a set of sensible values will be added to the component. For
  136.      * an iCalendar object, this may be something like CALSCALE:GREGORIAN. To
  137.      * ensure that this does not happen, set $defaults to false.
  138.      *
  139.      * @param string $name
  140.      * @param array  $children
  141.      * @param bool   $defaults
  142.      *
  143.      * @return Component
  144.      */
  145.     public function createComponent($name, array $children null$defaults true)
  146.     {
  147.         $name strtoupper($name);
  148.         $class Component::class;
  149.         if (isset(static::$componentMap[$name])) {
  150.             $class = static::$componentMap[$name];
  151.         }
  152.         if (is_null($children)) {
  153.             $children = [];
  154.         }
  155.         return new $class($this$name$children$defaults);
  156.     }
  157.     /**
  158.      * Factory method for creating new properties.
  159.      *
  160.      * This method automatically searches for the correct property class, based
  161.      * on its name.
  162.      *
  163.      * You can specify the parameters either in key=>value syntax, in which case
  164.      * parameters will automatically be created, or you can just pass a list of
  165.      * Parameter objects.
  166.      *
  167.      * @param string $name
  168.      * @param mixed  $value
  169.      * @param array  $parameters
  170.      * @param string $valueType  Force a specific valuetype, such as URI or TEXT
  171.      *
  172.      * @return Property
  173.      */
  174.     public function createProperty($name$value null, array $parameters null$valueType null)
  175.     {
  176.         // If there's a . in the name, it means it's prefixed by a groupname.
  177.         if (false !== ($i strpos($name'.'))) {
  178.             $group substr($name0$i);
  179.             $name strtoupper(substr($name$i 1));
  180.         } else {
  181.             $name strtoupper($name);
  182.             $group null;
  183.         }
  184.         $class null;
  185.         if ($valueType) {
  186.             // The valueType argument comes first to figure out the correct
  187.             // class.
  188.             $class $this->getClassNameForPropertyValue($valueType);
  189.         }
  190.         if (is_null($class)) {
  191.             // If a VALUE parameter is supplied, we should use that.
  192.             if (isset($parameters['VALUE'])) {
  193.                 $class $this->getClassNameForPropertyValue($parameters['VALUE']);
  194.                 if (is_null($class)) {
  195.                     throw new InvalidDataException('Unsupported VALUE parameter for '.$name.' property. You supplied "'.$parameters['VALUE'].'"');
  196.                 }
  197.             } else {
  198.                 $class $this->getClassNameForPropertyName($name);
  199.             }
  200.         }
  201.         if (is_null($parameters)) {
  202.             $parameters = [];
  203.         }
  204.         return new $class($this$name$value$parameters$group);
  205.     }
  206.     /**
  207.      * This method returns a full class-name for a value parameter.
  208.      *
  209.      * For instance, DTSTART may have VALUE=DATE. In that case we will look in
  210.      * our valueMap table and return the appropriate class name.
  211.      *
  212.      * This method returns null if we don't have a specialized class.
  213.      *
  214.      * @param string $valueParam
  215.      *
  216.      * @return string|null
  217.      */
  218.     public function getClassNameForPropertyValue($valueParam)
  219.     {
  220.         $valueParam strtoupper($valueParam);
  221.         if (isset(static::$valueMap[$valueParam])) {
  222.             return static::$valueMap[$valueParam];
  223.         }
  224.     }
  225.     /**
  226.      * Returns the default class for a property name.
  227.      *
  228.      * @param string $propertyName
  229.      *
  230.      * @return string
  231.      */
  232.     public function getClassNameForPropertyName($propertyName)
  233.     {
  234.         if (isset(static::$propertyMap[$propertyName])) {
  235.             return static::$propertyMap[$propertyName];
  236.         } else {
  237.             return Property\Unknown::class;
  238.         }
  239.     }
  240. }