From 2cdfe6cc21f0cb253401fa169b5e1c3bb8738d43 Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Thu, 30 Jun 2016 15:54:44 +0100 Subject: [PATCH] FIX Use RAW for DBField template helpers --- model/fieldtypes/DBField.php | 14 ++--- model/fieldtypes/HTMLText.php | 8 ++- model/fieldtypes/HTMLVarchar.php | 3 +- model/fieldtypes/StringField.php | 27 +++++---- model/fieldtypes/Text.php | 29 ++++----- model/fieldtypes/Varchar.php | 12 ++-- tests/model/HTMLTextTest.php | 100 +++++++++++++++++++++++++++++++ 7 files changed, 151 insertions(+), 42 deletions(-) diff --git a/model/fieldtypes/DBField.php b/model/fieldtypes/DBField.php index fc7f05cd9..e488939b5 100644 --- a/model/fieldtypes/DBField.php +++ b/model/fieldtypes/DBField.php @@ -219,19 +219,19 @@ abstract class DBField extends ViewableData { } public function HTMLATT() { - return Convert::raw2htmlatt($this->value); + return Convert::raw2htmlatt($this->RAW()); } public function URLATT() { - return urlencode($this->value); + return urlencode($this->RAW()); } public function RAWURLATT() { - return rawurlencode($this->value); + return rawurlencode($this->RAW()); } public function ATT() { - return Convert::raw2att($this->value); + return Convert::raw2att($this->RAW()); } public function RAW() { @@ -239,15 +239,15 @@ abstract class DBField extends ViewableData { } public function JS() { - return Convert::raw2js($this->value); + return Convert::raw2js($this->RAW()); } public function HTML(){ - return Convert::raw2xml($this->value); + return Convert::raw2xml($this->RAW()); } public function XML(){ - return Convert::raw2xml($this->value); + return Convert::raw2xml($this->RAW()); } /** diff --git a/model/fieldtypes/HTMLText.php b/model/fieldtypes/HTMLText.php index 10a3a1aeb..17107e62d 100644 --- a/model/fieldtypes/HTMLText.php +++ b/model/fieldtypes/HTMLText.php @@ -100,7 +100,7 @@ class HTMLText extends Text { // Catch warnings thrown by loadHTML and turn them into a failure boolean rather than a SilverStripe error set_error_handler(create_function('$no, $str', 'throw new Exception("HTML Parse Error: ".$str);'), E_ALL); // Nonbreaking spaces get converted into weird characters, so strip them - $value = str_replace(' ', ' ', $this->value); + $value = str_replace(' ', ' ', $this->RAW()); try { $res = $doc->loadHTML('' . $value); } @@ -241,14 +241,16 @@ class HTMLText extends Text { return false; } + $value = $this->RAW(); + // If it's got a content tag - if(preg_match('/<(img|embed|object|iframe|meta|source|link)[^>]*>/i', $this->value)) { + if(preg_match('/<(img|embed|object|iframe|meta|source|link)[^>]*>/i', $value)) { return true; } // If it's just one or two tags on its own (and not the above) it's empty. // This might be

or

or whatever. - if(preg_match('/^[\\s]*(<[^>]+>[\\s]*){1,2}$/', $this->value)) { + if(preg_match('/^[\\s]*(<[^>]+>[\\s]*){1,2}$/', $value)) { return false; } diff --git a/model/fieldtypes/HTMLVarchar.php b/model/fieldtypes/HTMLVarchar.php index 44aa54434..69df13fdc 100644 --- a/model/fieldtypes/HTMLVarchar.php +++ b/model/fieldtypes/HTMLVarchar.php @@ -31,10 +31,11 @@ class HTMLVarchar extends Varchar { else { return $this->value; } + } public function exists() { - return parent::exists() && $this->value != '

'; + return parent::exists() && $this->RAW() != '

'; } public function scaffoldFormField($title = null, $params = null) { diff --git a/model/fieldtypes/StringField.php b/model/fieldtypes/StringField.php index fe778a1a1..60aa7f7ea 100644 --- a/model/fieldtypes/StringField.php +++ b/model/fieldtypes/StringField.php @@ -84,9 +84,10 @@ abstract class StringField extends DBField { * @see core/model/fieldtypes/DBField#exists() */ public function exists() { - return $this->getValue() // All truthy values exist - || (is_string($this->getValue()) && strlen($this->getValue())) // non-empty strings exist ('0' but not (int)0) - || (!$this->getNullifyEmpty() && $this->getValue() === ''); // Remove this stupid exemption in 4.0 + $value = $this->RAW(); + return $value // All truthy values exist + || (is_string($value) && strlen($value)) // non-empty strings exist ('0' but not (int)0) + || (!$this->getNullifyEmpty() && $value === ''); // Remove this stupid exemption in 4.0 } /** @@ -118,7 +119,7 @@ abstract class StringField extends DBField { * @return string */ public function LimitCharacters($limit = 20, $add = '...') { - $value = trim($this->value); + $value = trim($this->RAW()); if($this->stat('escape_type') == 'xml') { $value = strip_tags($value); $value = html_entity_decode($value, ENT_COMPAT, 'UTF-8'); @@ -142,13 +143,13 @@ abstract class StringField extends DBField { */ public function LimitCharactersToClosestWord($limit = 20, $add = '...') { // Strip HTML tags if they exist in the field - $this->value = strip_tags($this->value); + $value = strip_tags($this->RAW()); // Determine if value exceeds limit before limiting characters - $exceedsLimit = mb_strlen($this->value) > $limit; + $exceedsLimit = mb_strlen($value) > $limit; // Limit to character limit - $value = $this->LimitCharacters($limit, ''); + $value = DBField::create_field(get_class($this), $value)->LimitCharacters($limit, ''); // If value exceeds limit, strip punctuation off the end to the last space and apply ellipsis if($exceedsLimit) { @@ -174,11 +175,11 @@ abstract class StringField extends DBField { * @return string */ public function LimitWordCount($numWords = 26, $add = '...') { - $this->value = trim(Convert::xml2raw($this->value)); - $ret = explode(' ', $this->value, $numWords + 1); + $value = trim(Convert::xml2raw($this->RAW())); + $ret = explode(' ', $value, $numWords + 1); if(count($ret) <= $numWords - 1) { - $ret = $this->value; + $ret = $value; } else { array_pop($ret); $ret = implode(' ', $ret) . $add; @@ -209,7 +210,7 @@ abstract class StringField extends DBField { * @return string */ public function LowerCase() { - return mb_strtolower($this->value); + return mb_strtolower($this->RAW()); } /** @@ -217,7 +218,7 @@ abstract class StringField extends DBField { * @return string */ public function UpperCase() { - return mb_strtoupper($this->value); + return mb_strtoupper($this->RAW()); } /** @@ -226,6 +227,6 @@ abstract class StringField extends DBField { * @return string */ public function NoHTML() { - return strip_tags($this->value); + return strip_tags($this->RAW()); } } diff --git a/model/fieldtypes/Text.php b/model/fieldtypes/Text.php index 97ad02b81..5f2ff9d7d 100644 --- a/model/fieldtypes/Text.php +++ b/model/fieldtypes/Text.php @@ -57,7 +57,7 @@ class Text extends StringField { * @return string */ public function AbsoluteLinks() { - return HTTP::absoluteURLs($this->value); + return HTTP::absoluteURLs($this->RAW()); } /** @@ -71,7 +71,7 @@ class Text extends StringField { } $output = array(); - $data = trim(Convert::xml2raw($this->value)); + $data = trim(Convert::xml2raw($this->RAW())); $sentences = explode('.', $data); if ($sentCount == 0) return ''; @@ -91,7 +91,7 @@ class Text extends StringField { * Caution: Not XML/HTML-safe - does not respect closing tags. */ public function FirstSentence() { - $paragraph = Convert::xml2raw( $this->value ); + $paragraph = Convert::xml2raw( $this->RAW() ); if( !$paragraph ) return ""; $words = preg_split('/\s+/', $paragraph); @@ -112,7 +112,7 @@ class Text extends StringField { public function Summary($maxWords = 50) { // get first sentence? // this needs to be more robust - $value = Convert::xml2raw( $this->value /*, true*/ ); + $value = Convert::xml2raw( $this->RAW() /*, true*/ ); if(!$value) return ''; // grab the first paragraph, or, failing that, the whole content @@ -154,7 +154,7 @@ class Text extends StringField { // get first sentence? // this needs to be more robust - $data = $plain ? Convert::xml2raw($this->value, true) : $this->value; + $data = $plain ? Convert::xml2raw($this->RAW(), true) : $this->RAW(); if(!$data) return ''; @@ -194,8 +194,9 @@ class Text extends StringField { public function FirstParagraph($plain = 1) { // get first sentence? // this needs to be more robust + $value = $this->RAW(); if($plain && $plain != 'html') { - $data = Convert::xml2raw($this->value, true); + $data = Convert::xml2raw($value, true); if(!$data) return ""; // grab the first paragraph, or, failing that, the whole content @@ -204,12 +205,12 @@ class Text extends StringField { return $data; } else { - if(strpos($this->value, "

") === false) return $this->value; + if(strpos($value, "

") === false) return $value; - $data = substr($this->value, 0, strpos($this->value, "

") + 4); + $data = substr($value, 0, strpos($value, "

") + 4); - if(strlen($data) < 20 && strpos($this->value, "

", strlen($data))) { - $data = substr($this->value, 0, strpos( $this->value, "

", strlen($data)) + 4 ); + if(strlen($data) < 20 && strpos($value, "

", strlen($data))) { + $data = substr($value, 0, strpos( $value, "

", strlen($data)) + 4 ); } return $data; @@ -238,7 +239,7 @@ class Text extends StringField { } // Remove HTML tags so we don't have to deal with matching tags - $text = $striphtml ? $this->NoHTML() : $this->value; + $text = $striphtml ? $this->NoHTML() : $this->RAW(); // Find the search string $position = (int) stripos($text, $string); @@ -270,7 +271,7 @@ class Text extends StringField { $summary = trim($summary); if($position > 0) $summary = $prefix . $summary; - if(strlen($this->value) > ($characters + $position)) $summary = $summary . $suffix; + if(strlen($this->RAW()) > ($characters + $position)) $summary = $summary . $suffix; return $summary; } @@ -283,14 +284,14 @@ class Text extends StringField { */ public function Parse($parser = "TextParser") { if($parser == "TextParser" || is_subclass_of($parser, "TextParser")) { - $obj = new $parser($this->value); + $obj = new $parser($this->RAW()); return $obj->parse(); } else { // Fallback to using raw2xml and show a warning // TODO Don't kill script execution, we can continue without losing complete control of the app user_error("Couldn't find an appropriate TextParser sub-class to create (Looked for '$parser')." . "Make sure it sub-classes TextParser and that you've done ?flush=1.", E_USER_WARNING); - return Convert::raw2xml($this->value); + return Convert::raw2xml($this->RAW()); } } diff --git a/model/fieldtypes/Varchar.php b/model/fieldtypes/Varchar.php index 43eb83d9c..896b24d1f 100644 --- a/model/fieldtypes/Varchar.php +++ b/model/fieldtypes/Varchar.php @@ -70,15 +70,19 @@ class Varchar extends StringField { * Return the first letter of the string followed by a . */ public function Initial() { - if($this->exists()) return $this->value[0] . '.'; + if($this->exists()) { + $value = $this->RAW(); + return $value[0] . '.'; + } } /** * Ensure that the given value is an absolute URL. */ public function URL() { - if(preg_match('#^[a-zA-Z]+://#', $this->value)) return $this->value; - else return "http://" . $this->value; + $value = $this->RAW(); + if(preg_match('#^[a-zA-Z]+://#', $value)) return $value; + else return "http://" . $value; } /** @@ -86,7 +90,7 @@ class Varchar extends StringField { * @return string */ public function RTF() { - return str_replace("\n", '\par ', $this->value); + return str_replace("\n", '\par ', $this->RAW()); } /** diff --git a/tests/model/HTMLTextTest.php b/tests/model/HTMLTextTest.php index 7bf3f908f..8a5be4116 100644 --- a/tests/model/HTMLTextTest.php +++ b/tests/model/HTMLTextTest.php @@ -212,6 +212,106 @@ class HTMLTextTest extends SapphireTest { $this->assertEquals('

[shortcode]

', (string)$field); + ShortcodeParser::set_active('default'); + } + + public function testShortCodeParsedInTemplateHelpers() { + $parser = ShortcodeParser::get('HTMLTextTest'); + $parser->register('shortcode', function($arguments, $content, $parser, $tagName, $extra) { + return 'Replaced short code with this. home'; + }); + ShortcodeParser::set_active('HTMLTextTest'); + /** @var HTMLText $field */ + $field = DBField::create_field('HTMLText', '

[shortcode]

'); + + $this->assertEquals( + '<p>Replaced short code with this. <a href="home">home</a></p>', + $field->HTMLATT() + ); + $this->assertEquals( + '%3Cp%3EReplaced+short+code+with+this.+%3Ca+href%3D%22home%22%3Ehome%3C%2Fa%3E%3C%2Fp%3E', + $field->URLATT() + ); + $this->assertEquals( + '%3Cp%3EReplaced%20short%20code%20with%20this.%20%3Ca%20href%3D%22home%22%3Ehome%3C%2Fa%3E%3C%2Fp%3E', + $field->RAWURLATT() + ); + $this->assertEquals( + '<p>Replaced short code with this. <a href="home">home</a></p>', + $field->ATT() + ); + $this->assertEquals( + '

Replaced short code with this. home

', + $field->RAW() + ); + $this->assertEquals( + '\x3cp\x3eReplaced short code with this. \x3ca href=\"home\"\x3ehome\x3c/a\x3e\x3c/p\x3e', + $field->JS() + ); + $this->assertEquals( + '<p>Replaced short code with this. <a href="home">home</a></p>', + $field->HTML() + ); + $this->assertEquals( + '<p>Replaced short code with this. <a href="home">home</a></p>', + $field->XML() + ); + $this->assertEquals( + 'Repl...', + $field->LimitCharacters(4, '...') + ); + $this->assertEquals( + 'Replaced...', + $field->LimitCharactersToClosestWord(10, '...') + ); + $this->assertEquals( + 'Replaced...', + $field->LimitWordCount(1, '...') + ); + $this->assertEquals( + '

replaced short code with this. home

', + $field->LowerCase() + ); + $this->assertEquals( + '

REPLACED SHORT CODE WITH THIS. HOME

', + $field->UpperCase() + ); + $this->assertEquals( + 'Replaced short code with this. home', + $field->NoHTML() + ); + Config::nest(); + Config::inst()->update('Director', 'alternate_base_url', 'http://example.com/'); + $this->assertEquals( + '

Replaced short code with this. home

', + $field->AbsoluteLinks() + ); + Config::unnest(); + $this->assertEquals( + 'Replaced short code with this.', + $field->LimitSentences(1) + ); + $this->assertEquals( + 'Replaced short code with this.', + $field->FirstSentence() + ); + $this->assertEquals( + 'Replaced short...', + $field->Summary(2) + ); + $this->assertEquals( + 'Replaced short code with...', + $field->BigSummary(4) + ); + $this->assertEquals( + 'Replaced short code with this. home[home]', + $field->FirstParagraph() + ); + $this->assertEquals( + 'Replaced short code with this. home', + $field->ContextSummary(500, 'short code') + ); + ShortcodeParser::set_active('default'); } }