|
|
@@ -46,6 +46,14 @@ class TextHelper extends AppHelper {
|
|
|
public $helpers = array('Html');
|
|
|
|
|
|
/**
|
|
|
+ * An array of md5sums and their contents.
|
|
|
+ * Used when inserting links into text.
|
|
|
+ *
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ protected $_placeholders = array();
|
|
|
+
|
|
|
+/**
|
|
|
* Highlights a given phrase in a text. You can specify any expression in highlighter that
|
|
|
* may include the \1 expression to include the $phrase found.
|
|
|
*
|
|
|
@@ -112,86 +120,126 @@ class TextHelper extends AppHelper {
|
|
|
* Adds links (<a href=....) to a given text, by finding text that begins with
|
|
|
* strings like http:// and ftp://.
|
|
|
*
|
|
|
- * @param string $text Text to add links to
|
|
|
- * @param array $htmlOptions Array of HTML options.
|
|
|
+ * ### Options
|
|
|
+ *
|
|
|
+ * - `escape` Control HTML escaping of input. Defaults to true.
|
|
|
+ *
|
|
|
+ * @param string $text Text
|
|
|
+ * @param array $options Array of HTML options, and options listed above.
|
|
|
* @return string The text with links
|
|
|
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::autoLinkUrls
|
|
|
*/
|
|
|
- public function autoLinkUrls($text, $htmlOptions = array()) {
|
|
|
- $this->_linkOptions = $htmlOptions;
|
|
|
+ public function autoLinkUrls($text, $options = array()) {
|
|
|
+ $this->_placeholders = array();
|
|
|
+ $options += array('escape' => true);
|
|
|
+
|
|
|
$text = preg_replace_callback(
|
|
|
'#(?<!href="|src="|">)((?:https?|ftp|nntp)://[^\s<>()]+)#i',
|
|
|
- array(&$this, '_linkBareUrl'),
|
|
|
+ array(&$this, '_insertPlaceHolder'),
|
|
|
$text
|
|
|
);
|
|
|
- return preg_replace_callback(
|
|
|
+ $text = preg_replace_callback(
|
|
|
'#(?<!href="|">)(?<!http://|https://|ftp://|nntp://)(www\.[^\n\%\ <]+[^<\n\%\,\.\ <])(?<!\))#i',
|
|
|
- array(&$this, '_linkUrls'),
|
|
|
+ array(&$this, '_insertPlaceHolder'),
|
|
|
$text
|
|
|
);
|
|
|
+ if ($options['escape']) {
|
|
|
+ $text = h($text);
|
|
|
+ }
|
|
|
+ return $this->_linkUrls($text, $options);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Links urls that include http://
|
|
|
+ * Saves the placeholder for a string, for later use. This gets around double
|
|
|
+ * escaping content in URL's.
|
|
|
*
|
|
|
- * @param array $matches
|
|
|
- * @return string
|
|
|
- * @see TextHelper::autoLinkUrls()
|
|
|
+ * @param array $matches An array of regexp matches.
|
|
|
+ * @return string Replaced values.
|
|
|
*/
|
|
|
- protected function _linkBareUrl($matches) {
|
|
|
- return $this->Html->link($matches[0], $matches[0], $this->_linkOptions);
|
|
|
+ protected function _insertPlaceHolder($matches) {
|
|
|
+ $key = md5($matches[0]);
|
|
|
+ $this->_placeholders[$key] = $matches[0];
|
|
|
+ return $key;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Links urls missing http://
|
|
|
+ * Replace placeholders with links.
|
|
|
*
|
|
|
- * @param array $matches
|
|
|
- * @return string
|
|
|
- * @see TextHelper::autoLinkUrls()
|
|
|
+ * @param string $text The text to operate on.
|
|
|
+ * @param array $htmlOptions The options for the generated links.
|
|
|
+ * @return string The text with links inserted.
|
|
|
*/
|
|
|
- protected function _linkUrls($matches) {
|
|
|
- return $this->Html->link($matches[0], 'http://' . $matches[0], $this->_linkOptions);
|
|
|
+ protected function _linkUrls($text, $htmlOptions) {
|
|
|
+ $replace = array();
|
|
|
+ foreach ($this->_placeholders as $md5 => $url) {
|
|
|
+ $link = $url;
|
|
|
+ if (!preg_match('#^[a-z]+\://#', $url)) {
|
|
|
+ $url = 'http://' . $url;
|
|
|
+ }
|
|
|
+ $replace[$md5] = $this->Html->link($link, $url, $htmlOptions);
|
|
|
+ }
|
|
|
+ return strtr($text, $replace);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Links email addresses
|
|
|
*
|
|
|
- * @param array $matches
|
|
|
+ * @param string $text The text to operate on
|
|
|
+ * @param array $options An array of options to use for the HTML.
|
|
|
* @return string
|
|
|
- * @see TextHelper::autoLinkUrls()
|
|
|
+ * @see TextHelper::autoLinkEmails()
|
|
|
*/
|
|
|
- protected function _linkEmails($matches) {
|
|
|
- return $this->Html->link($matches[0], 'mailto:' . $matches[0], $this->_linkOptions);
|
|
|
+ protected function _linkEmails($text, $options) {
|
|
|
+ $replace = array();
|
|
|
+ foreach ($this->_placeholders as $md5 => $url) {
|
|
|
+ $replace[$md5] = $this->Html->link($url, 'mailto:' . $url, $options);
|
|
|
+ }
|
|
|
+ return strtr($text, $replace);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Adds email links (<a href="mailto:....) to a given text.
|
|
|
*
|
|
|
+ * ### Options
|
|
|
+ *
|
|
|
+ * - `escape` Control HTML escaping of input. Defaults to true.
|
|
|
+ *
|
|
|
* @param string $text Text
|
|
|
- * @param array $options Array of HTML options.
|
|
|
+ * @param array $options Array of HTML options, and options listed above.
|
|
|
* @return string The text with links
|
|
|
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::autoLinkEmails
|
|
|
*/
|
|
|
public function autoLinkEmails($text, $options = array()) {
|
|
|
- $this->_linkOptions = $options;
|
|
|
+ $options += array('escape' => true);
|
|
|
+ $this->_placeholders = array();
|
|
|
+
|
|
|
$atom = '[a-z0-9!#$%&\'*+\/=?^_`{|}~-]';
|
|
|
- return preg_replace_callback(
|
|
|
+ $text = preg_replace_callback(
|
|
|
'/(' . $atom . '+(?:\.' . $atom . '+)*@[a-z0-9-]+(?:\.[a-z0-9-]+)+)/i',
|
|
|
- array(&$this, '_linkEmails'),
|
|
|
+ array(&$this, '_insertPlaceholder'),
|
|
|
$text
|
|
|
);
|
|
|
+ if ($options['escape']) {
|
|
|
+ $text = h($text);
|
|
|
+ }
|
|
|
+ return $this->_linkEmails($text, $options);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Convert all links and email adresses to HTML links.
|
|
|
*
|
|
|
+ * ### Options
|
|
|
+ *
|
|
|
+ * - `escape` Control HTML escaping of input. Defaults to true.
|
|
|
+ *
|
|
|
* @param string $text Text
|
|
|
- * @param array $options Array of HTML options.
|
|
|
+ * @param array $options Array of HTML options, and options listed above.
|
|
|
* @return string The text with links
|
|
|
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::autoLink
|
|
|
*/
|
|
|
public function autoLink($text, $options = array()) {
|
|
|
- return $this->autoLinkEmails($this->autoLinkUrls($text, $options), $options);
|
|
|
+ $text = $this->autoLinkUrls($text, $options);
|
|
|
+ return $this->autoLinkEmails($text, array_merge($options, array('escape' => false)));
|
|
|
}
|
|
|
|
|
|
/**
|