/** * Parse doc block text. * * @param string $comment doc block comment */ function __construct($comment) { // normalise EOL $regex = '/(?:\\r\\n|\\n|\\x0b|\\f|\\x85)/'; $comment = preg_replace($regex, EOL, $comment); // remove doc block line starters $regex = '#[ \\t]*(?:\\/\\*\\*|\\*\\/|\\*)?[ ]{0,1}(.*)?#'; $comment = trim(preg_replace($regex, '$1', $comment)); // parse out long and short descriptions & tags // o short desc is first non blank line. // o long desc follows // o tags are preceded by an '@' $short = $long = null; $first_blank = false; $tags = array(); $tag = new T_Pattern_Regex('/^\\@([a-z]+) *(.*)$/i'); foreach (explode(EOL, $comment) as $line) { if (!$first_blank && strlen($line) == 0) { $first_blank = true; continue; // skip line } if (!$first_blank) { $short .= $line . EOL; } elseif ($tag->isMatch($line)) { $matches = $tag->getFirstMatch($line); $name = strtolower($matches[1]); if ($name) { $content = mb_trim($matches[2]); if (strcmp($name, 'param') === 0) { $regex = new T_Pattern_Regex('/^([0-9a-z_]+(?:\\[\\])?) +\\$([0-9a-z_]+)( +.*)?$/i'); if ($regex->isMatch($content)) { $match = $regex->getFirstMatch($content); $desc = isset($match[3]) ? trim($match[3]) : null; $tags[] = new T_Code_DocBlockParamTag($name, $match[1], $match[2], $desc); } } elseif (strcmp($name, 'return') === 0 || strcmp($name, 'var') === 0) { $break = strpos($content, ' '); if ($break === false) { $type = $content; $desc = null; } else { $type = mb_substr($content, 0, $break); $desc = trim(mb_substr($content, $break + 1)); } $tags[] = new T_Code_DocBlockTypeTag($name, $type, $desc); } else { $tags[] = new T_Code_DocBlockTag($name, $content); } } } else { $long .= $line . EOL; } } $long = mb_trim($long, EOL); $short = mb_rtrim($short, EOL); if ($short) { $this->short = $short; } if ($long) { $this->long = $long; } $this->tags = $tags; }
/** * Add a header key:value pair. * * Each header is sent as "key : value" on response send. This function * automatically detects changes to encoding and content type and modifies * the internal variables storing these values. * * @param string $key header key (e.g. 'Content-Type','Location') * @param string $value header value */ function setHeader($key, $value) { $key = _transform($key, new T_Filter_HeaderKey('mb_trim')); // detect content-type (optionally with encoding) if (strcasecmp($key, 'Content-Type') === 0) { $charset = new T_Pattern_Regex('/^(.*);\\s?charset\\s?=\\s?([^\\s]+)$/'); if ($match = $charset->getFirstMatch($value)) { $this->contentType = $match[1]; $this->encoding = $match[2]; } else { $this->contentType = $value; } } else { $this->headers[$key] = $value; } }