/lib/Twitter/Autolink.php
PHP | 449 lines | 145 code | 37 blank | 267 comment | 13 complexity | ff4190db996bee7e3613b51b29fc8631 MD5 | raw file
Possible License(s): Apache-2.0
- <?php
- /**
- * @author Mike Cochrane <mikec@mikenz.geek.nz>
- * @author Nick Pope <nick@nickpope.me.uk>
- * @copyright Copyright © 2010, Mike Cochrane, Nick Pope
- * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
- * @package Twitter
- */
- require_once 'Regex.php';
- /**
- * Twitter Autolink Class
- *
- * Parses tweets and generates HTML anchor tags around URLs, usernames,
- * username/list pairs and hashtags.
- *
- * Originally written by {@link http://github.com/mikenz Mike Cochrane}, this
- * is based on code by {@link http://github.com/mzsanford Matt Sanford} and
- * heavily modified by {@link http://github.com/ngnpope Nick Pope}.
- *
- * @author Mike Cochrane <mikec@mikenz.geek.nz>
- * @author Nick Pope <nick@nickpope.me.uk>
- * @copyright Copyright © 2010, Mike Cochrane, Nick Pope
- * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License v2.0
- * @package Twitter
- */
- class Twitter_Autolink extends Twitter_Regex {
- /**
- * CSS class for auto-linked URLs.
- *
- * @var string
- */
- protected $class_url = 'url';
- /**
- * CSS class for auto-linked username URLs.
- *
- * @var string
- */
- protected $class_user = 'username';
- /**
- * CSS class for auto-linked list URLs.
- *
- * @var string
- */
- protected $class_list = 'list';
- /**
- * CSS class for auto-linked hashtag URLs.
- *
- * @var string
- */
- protected $class_hash = 'hashtag';
- /**
- * URL base for username links (the username without the @ will be appended).
- *
- * @var string
- */
- protected $url_base_user = 'http://twitter.com/';
- /**
- * URL base for list links (the username/list without the @ will be appended).
- *
- * @var string
- */
- protected $url_base_list = 'http://twitter.com/';
- /**
- * URL base for hashtag links (the hashtag without the # will be appended).
- *
- * @var string
- */
- protected $url_base_hash = 'http://twitter.com/search?q=%23';
- /**
- * Whether to include the value 'nofollow' in the 'rel' attribute.
- *
- * @var bool
- */
- protected $nofollow = true;
- /**
- * Whether to include the value 'external' in the 'rel' attribute.
- *
- * Often this is used to be matched on in JavaScript for dynamically adding
- * the 'target' attribute which is deprecated in HTML 4.01. In HTML 5 it has
- * been undeprecated and thus the 'target' attribute can be used. If this is
- * set to false then the 'target' attribute will be output.
- *
- * @var bool
- */
- protected $external = true;
- /**
- * The scope to open the link in.
- *
- * Support for the 'target' attribute was deprecated in HTML 4.01 but has
- * since been reinstated in HTML 5. To output the 'target' attribute you
- * must disable the adding of the string 'external' to the 'rel' attribute.
- *
- * @var string
- */
- protected $target = '_blank';
- /**
- * Provides fluent method chaining.
- *
- * @param string $tweet The tweet to be converted.
- * @param bool $full_encode Whether to encode all special characters.
- *
- * @see __construct()
- *
- * @return Twitter_Autolink
- */
- public static function create($tweet, $full_encode = false) {
- return new self($tweet, $full_encode);
- }
- /**
- * Reads in a tweet to be parsed and converted to contain links.
- *
- * As the intent is to produce links and output the modified tweet to the
- * user, we take this opportunity to ensure that we escape user input.
- *
- * @see htmlspecialchars()
- *
- * @param string $tweet The tweet to be converted.
- * @param bool $escape Whether to escape the tweet (default: true).
- * @param bool $full_encode Whether to encode all special characters.
- */
- public function __construct($tweet, $escape = true, $full_encode = false) {
- if ($escape) {
- if ($full_encode) {
- parent::__construct(htmlentities($tweet, ENT_QUOTES, 'UTF-8', false));
- } else {
- parent::__construct(htmlspecialchars($tweet, ENT_QUOTES, 'UTF-8', false));
- }
- } else {
- parent::__construct($tweet);
- }
- }
- /**
- * CSS class for auto-linked URLs.
- *
- * @return string CSS class for URL links.
- */
- public function getURLClass() {
- return $this->class_url;
- }
- /**
- * CSS class for auto-linked URLs.
- *
- * @param string $v CSS class for URL links.
- *
- * @return Twitter_Autolink Fluid method chaining.
- */
- public function setURLClass($v) {
- $this->class_url = trim($v);
- return $this;
- }
- /**
- * CSS class for auto-linked username URLs.
- *
- * @return string CSS class for username links.
- */
- public function getUsernameClass() {
- return $this->class_user;
- }
- /**
- * CSS class for auto-linked username URLs.
- *
- * @param string $v CSS class for username links.
- *
- * @return Twitter_Autolink Fluid method chaining.
- */
- public function setUsernameClass($v) {
- $this->class_user = trim($v);
- return $this;
- }
- /**
- * CSS class for auto-linked username/list URLs.
- *
- * @return string CSS class for username/list links.
- */
- public function getListClass() {
- return $this->class_list;
- }
- /**
- * CSS class for auto-linked username/list URLs.
- *
- * @param string $v CSS class for username/list links.
- *
- * @return Twitter_Autolink Fluid method chaining.
- */
- public function setListClass($v) {
- $this->class_list = trim($v);
- return $this;
- }
- /**
- * CSS class for auto-linked hashtag URLs.
- *
- * @return string CSS class for hashtag links.
- */
- public function getHashtagClass() {
- return $this->class_hash;
- }
- /**
- * CSS class for auto-linked hashtag URLs.
- *
- * @param string $v CSS class for hashtag links.
- *
- * @return Twitter_Autolink Fluid method chaining.
- */
- public function setHashtagClass($v) {
- $this->class_hash = trim($v);
- return $this;
- }
- /**
- * Whether to include the value 'nofollow' in the 'rel' attribute.
- *
- * @return bool Whether to add 'nofollow' to the 'rel' attribute.
- */
- public function getNoFollow() {
- return $this->nofollow;
- }
- /**
- * Whether to include the value 'nofollow' in the 'rel' attribute.
- *
- * @param bool $v The value to add to the 'target' attribute.
- *
- * @return Twitter_Autolink Fluid method chaining.
- */
- public function setNoFollow($v) {
- $this->nofollow = $v;
- return $this;
- }
- /**
- * Whether to include the value 'external' in the 'rel' attribute.
- *
- * Often this is used to be matched on in JavaScript for dynamically adding
- * the 'target' attribute which is deprecated in HTML 4.01. In HTML 5 it has
- * been undeprecated and thus the 'target' attribute can be used. If this is
- * set to false then the 'target' attribute will be output.
- *
- * @return bool Whether to add 'external' to the 'rel' attribute.
- */
- public function getExternal() {
- return $this->external;
- }
- /**
- * Whether to include the value 'external' in the 'rel' attribute.
- *
- * Often this is used to be matched on in JavaScript for dynamically adding
- * the 'target' attribute which is deprecated in HTML 4.01. In HTML 5 it has
- * been undeprecated and thus the 'target' attribute can be used. If this is
- * set to false then the 'target' attribute will be output.
- *
- * @param bool $v The value to add to the 'target' attribute.
- *
- * @return Twitter_Autolink Fluid method chaining.
- */
- public function setExternal($v) {
- $this->external = $v;
- return $this;
- }
- /**
- * The scope to open the link in.
- *
- * Support for the 'target' attribute was deprecated in HTML 4.01 but has
- * since been reinstated in HTML 5. To output the 'target' attribute you
- * must disable the adding of the string 'external' to the 'rel' attribute.
- *
- * @return string The value to add to the 'target' attribute.
- */
- public function getTarget() {
- return $this->target;
- }
- /**
- * The scope to open the link in.
- *
- * Support for the 'target' attribute was deprecated in HTML 4.01 but has
- * since been reinstated in HTML 5. To output the 'target' attribute you
- * must disable the adding of the string 'external' to the 'rel' attribute.
- *
- * @param string $v The value to add to the 'target' attribute.
- *
- * @return Twitter_Autolink Fluid method chaining.
- */
- public function setTarget($v) {
- $this->target = trim($v);
- return $this;
- }
- /**
- * Adds links to all elements in the tweet.
- *
- * @return string The modified tweet.
- */
- public function addLinks() {
- $original = $this->tweet;
- $this->tweet = $this->addLinksToURLs();
- $this->tweet = $this->addLinksToHashtags();
- $this->tweet = $this->addLinksToUsernamesAndLists();
- $modified = $this->tweet;
- $this->tweet = $original;
- return $modified;
- }
- /**
- * Adds links to hashtag elements in the tweet.
- *
- * @return string The modified tweet.
- */
- public function addLinksToHashtags() {
- return preg_replace_callback(
- self::REGEX_HASHTAG,
- array($this, '_addLinksToHashtags'),
- $this->tweet);
- }
- /**
- * Adds links to URL elements in the tweet.
- *
- * @return string The modified tweet.
- */
- public function addLinksToURLs() {
- return preg_replace_callback(
- self::$REGEX_VALID_URL,
- array($this, '_addLinksToURLs'),
- $this->tweet);
- }
- /**
- * Adds links to username/list elements in the tweet.
- *
- * @return string The modified tweet.
- */
- public function addLinksToUsernamesAndLists() {
- return preg_replace_callback(
- self::REGEX_USERNAME_LIST,
- array($this, '_addLinksToUsernamesAndLists'),
- $this->tweet);
- }
- /**
- * Wraps a tweet element in an HTML anchor tag using the provided URL.
- *
- * This is a helper function to perform the generation of the link.
- *
- * @param string $url The URL to use as the href.
- * @param string $class The CSS class(es) to apply (space separated).
- * @param string $element The tweet element to wrap.
- *
- * @return string The tweet element with a link applied.
- */
- protected function wrap($url, $class, $element) {
- $link = '<a';
- if ($class) $link .= ' class="'.$class.'"';
- $link .= ' href="'.$url.'"';
- $rel = array();
- if ($this->external) $rel[] = 'external';
- if ($this->nofollow) $rel[] = 'nofollow';
- if (!empty($rel)) $link .= ' rel="'.implode(' ', $rel).'"';
- if ($this->target) $link .= ' target="'.$this->target.'"';
- $link .= '>'.$element.'</a>';
- return $link;
- }
- /**
- * Callback used by the method that adds links to hashtags.
- *
- * @see addLinksToHashtags()
- *
- * @param array $matches The regular expression matches.
- *
- * @return string The link-wrapped hashtag.
- */
- protected function _addLinksToHashtags($matches) {
- $replacement = $matches[1];
- $element = $matches[2] . $matches[3];
- $url = $this->url_base_hash . $matches[3];
- $replacement .= $this->wrap($url, $this->class_hash, $element);
- return $replacement;
- }
- /**
- * Callback used by the method that adds links to URLs.
- *
- * @see addLinksToURLs()
- *
- * @param array $matches The regular expression matches.
- *
- * @return string The link-wrapped URL.
- */
- protected function _addLinksToURLs($matches) {
- list($all, $before, $url, $protocol, $domain, $path, $query) = array_pad($matches, 7, '');
- $url = htmlspecialchars($url, ENT_QUOTES, 'UTF-8', false);
- if (!$protocol) return $all;
- return $before . $this->wrap($url, $this->class_url, $url);
- }
- /**
- * Callback used by the method that adds links to username/list pairs.
- *
- * @see addLinksToUsernamesAndLists()
- *
- * @param array $matches The regular expression matches.
- *
- * @return string The link-wrapped username/list pair.
- */
- protected function _addLinksToUsernamesAndLists($matches) {
- list($all, $before, $at, $username, $slash_listname, $after) = array_pad($matches, 6, '');
- # If $after is not empty, there is an invalid character.
- if (!empty($after)) return $all;
- if (!empty($slash_listname)) {
- # Replace the list and username
- $element = $username . substr($slash_listname, 0, 26);
- $class = $this->class_list;
- $url = $this->url_base_list . $element;
- $postfix = substr($slash_listname, 26);
- } else {
- # Replace the username
- $element = $username;
- $class = $this->class_user;
- $url = $this->url_base_user . $element;
- $postfix = '';
- }
- return $before . $at . $this->wrap($url, $class, $element) . $postfix . $after;
- }
- }