Beispiel #1
0
 /**
  * Reads a property or component from a line.
  *
  * @return void
  */
 protected function readProperty($line)
 {
     if ($this->options & self::OPTION_FORGIVING) {
         $propNameToken = 'A-Z0-9\\-\\._\\/';
     } else {
         $propNameToken = 'A-Z0-9\\-\\.';
     }
     $paramNameToken = 'A-Z0-9\\-';
     $safeChar = '^";:,';
     $qSafeChar = '^"';
     $regex = "/\n            ^(?P<name> [{$propNameToken}]+ ) (?=[;:])        # property name\n            |\n            (?<=:)(?P<propValue> .+)\$                      # property value\n            |\n            ;(?P<paramName> [{$paramNameToken}]+) (?=[=;:])  # parameter name\n            |\n            (=|,)(?P<paramValue>                           # parameter value\n                (?: [{$safeChar}]*) |\n                \"(?: [{$qSafeChar}]+)\"\n            ) (?=[;:,])\n            /xi";
     //echo $regex, "\n"; die();
     preg_match_all($regex, $line, $matches, PREG_SET_ORDER);
     $property = ['name' => null, 'parameters' => [], 'value' => null];
     $lastParam = null;
     /**
      * Looping through all the tokens.
      *
      * Note that we are looping through them in reverse order, because if a
      * sub-pattern matched, the subsequent named patterns will not show up
      * in the result.
      */
     foreach ($matches as $match) {
         if (isset($match['paramValue'])) {
             if ($match['paramValue'] && $match['paramValue'][0] === '"') {
                 $value = substr($match['paramValue'], 1, -1);
             } else {
                 $value = $match['paramValue'];
             }
             $value = $this->unescapeParam($value);
             if (is_null($lastParam)) {
                 throw new ParseException('Invalid Mimedir file. Line starting at ' . $this->startLine . ' did not follow iCalendar/vCard conventions');
             }
             if (is_null($property['parameters'][$lastParam])) {
                 $property['parameters'][$lastParam] = $value;
             } elseif (is_array($property['parameters'][$lastParam])) {
                 $property['parameters'][$lastParam][] = $value;
             } else {
                 $property['parameters'][$lastParam] = [$property['parameters'][$lastParam], $value];
             }
             continue;
         }
         if (isset($match['paramName'])) {
             $lastParam = strtoupper($match['paramName']);
             if (!isset($property['parameters'][$lastParam])) {
                 $property['parameters'][$lastParam] = null;
             }
             continue;
         }
         if (isset($match['propValue'])) {
             $property['value'] = $match['propValue'];
             continue;
         }
         if (isset($match['name']) && $match['name']) {
             $property['name'] = strtoupper($match['name']);
             continue;
         }
         // @codeCoverageIgnoreStart
         throw new \LogicException('This code should not be reachable');
         // @codeCoverageIgnoreEnd
     }
     if (is_null($property['value'])) {
         $property['value'] = '';
     }
     if (!$property['name']) {
         if ($this->options & self::OPTION_IGNORE_INVALID_LINES) {
             return false;
         }
         throw new ParseException('Invalid Mimedir file. Line starting at ' . $this->startLine . ' did not follow iCalendar/vCard conventions');
     }
     // vCard 2.1 states that parameters may appear without a name, and only
     // a value. We can deduce the value based on it's name.
     //
     // Our parser will get those as parameters without a value instead, so
     // we're filtering these parameters out first.
     $namedParameters = [];
     $namelessParameters = [];
     foreach ($property['parameters'] as $name => $value) {
         if (!is_null($value)) {
             $namedParameters[$name] = $value;
         } else {
             $namelessParameters[] = $name;
         }
     }
     $propObj = $this->root->createProperty($property['name'], null, $namedParameters);
     foreach ($namelessParameters as $namelessParameter) {
         $propObj->add(null, $namelessParameter);
     }
     if (strtoupper($propObj['ENCODING']) === 'QUOTED-PRINTABLE') {
         $propObj->setQuotedPrintableValue($this->extractQuotedPrintableValue());
     } else {
         $charset = $this->charset;
         if ($this->root->getDocumentType() === Document::VCARD21 && isset($propObj['CHARSET'])) {
             // vCard 2.1 allows the character set to be specified per property.
             $charset = (string) $propObj['CHARSET'];
         }
         switch ($charset) {
             case 'UTF-8':
                 break;
             case 'ISO-8859-1':
                 $property['value'] = utf8_encode($property['value']);
                 break;
             case 'Windows-1252':
                 $property['value'] = mb_convert_encoding($property['value'], 'UTF-8', $charset);
                 break;
             default:
                 throw new ParseException('Unsupported CHARSET: ' . $propObj['CHARSET']);
         }
         $propObj->setRawMimeDirValue($property['value']);
     }
     return $propObj;
 }