mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API / BUG Fix DBField summary methods
Cleanup DBField subclasses Fixes #2929 Fixes #1381 Fixes #5547 Fixes #1751
This commit is contained in:
parent
5c9044a007
commit
b7ac5c564d
@ -36,10 +36,10 @@ class DBDate extends DBField {
|
||||
/**
|
||||
* @config
|
||||
* @see DBDateTime::nice_format
|
||||
* @see Time::nice_format
|
||||
* @see DBTime::nice_format
|
||||
*/
|
||||
private static $nice_format = 'd/m/Y';
|
||||
|
||||
|
||||
public function setValue($value, $record = null, $markChanged = true) {
|
||||
if($value === false || $value === null || (is_string($value) && !strlen($value))) {
|
||||
// don't try to evaluate empty values with strtotime() below, as it returns "1970-01-01" when it should be
|
||||
@ -80,44 +80,56 @@ class DBDate extends DBField {
|
||||
|
||||
/**
|
||||
* Returns the date in the format specified by the config value nice_format, or dd/mm/yy by default
|
||||
*/
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Nice() {
|
||||
if($this->value) return $this->Format($this->config()->nice_format);
|
||||
return $this->Format($this->config()->nice_format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date in US format: “01/18/2006”
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function NiceUS() {
|
||||
if($this->value) return $this->Format('m/d/Y');
|
||||
return $this->Format('m/d/Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the year from the given date
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Year() {
|
||||
if($this->value) return $this->Format('Y');
|
||||
return $this->Format('Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Full day, of the given date.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Day(){
|
||||
if($this->value) return $this->Format('l');
|
||||
return $this->Format('l');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a full textual representation of a month, such as January.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Month() {
|
||||
if($this->value) return $this->Format('F');
|
||||
return $this->Format('F');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the short version of the month such as Jan
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ShortMonth() {
|
||||
if($this->value) return $this->Format('M');
|
||||
return $this->Format('M');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,25 +138,27 @@ class DBDate extends DBField {
|
||||
* @return string
|
||||
*/
|
||||
public function DayOfMonth($includeOrdinal = false) {
|
||||
if($this->value) {
|
||||
$format = 'j';
|
||||
if ($includeOrdinal) $format .= 'S';
|
||||
return $this->Format($format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date in the format 24 December 2006
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Long() {
|
||||
if($this->value) return $this->Format('j F Y');
|
||||
return $this->Format('j F Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date in the format 24 Dec 2006
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Full() {
|
||||
if($this->value) return $this->Format('j M Y');
|
||||
return $this->Format('j M Y');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,6 +172,7 @@ class DBDate extends DBField {
|
||||
$date = new DateTime($this->value);
|
||||
return $date->format($format);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,6 +188,7 @@ class DBDate extends DBField {
|
||||
if($this->value) {
|
||||
return strftime($formattingString, strtotime($this->value));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,12 +233,28 @@ class DBDate extends DBField {
|
||||
else return "$d1 - $d2 $m1 $y1";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string in RFC822 format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Rfc822() {
|
||||
if($this->value) return date('r', strtotime($this->value));
|
||||
if($this->value) {
|
||||
return date('r', strtotime($this->value));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return date in RFC2822 format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Rfc2822() {
|
||||
if($this->value) return date('Y-m-d H:i:s', strtotime($this->value));
|
||||
if($this->value) {
|
||||
return date('Y-m-d H:i:s', strtotime($this->value));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function Rfc3339() {
|
||||
@ -249,7 +281,9 @@ class DBDate extends DBField {
|
||||
* @return String
|
||||
*/
|
||||
public function Ago($includeSeconds = true, $significance = 2) {
|
||||
if($this->value) {
|
||||
if(!$this->value) {
|
||||
return null;
|
||||
}
|
||||
$time = DBDatetime::now()->Format('U');
|
||||
if(strtotime($this->value) == $time || $time > strtotime($this->value)) {
|
||||
return _t(
|
||||
@ -267,7 +301,6 @@ class DBDate extends DBField {
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $includeSeconds Show seconds, or just round to "less than a minute".
|
||||
@ -304,7 +337,9 @@ class DBDate extends DBField {
|
||||
* @return string The resulting formatted period
|
||||
*/
|
||||
public function TimeDiffIn($format) {
|
||||
if(!$this->value) return false;
|
||||
if(!$this->value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$time = DBDatetime::now()->Format('U');
|
||||
$ago = abs($time - strtotime($this->value));
|
||||
@ -333,6 +368,9 @@ class DBDate extends DBField {
|
||||
case "years":
|
||||
$span = round($ago/86400/365);
|
||||
return ($span != 1) ? "{$span} "._t("Date.YEARS", "years") : "{$span} "._t("Date.YEAR", "year");
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException("Invalid format $format");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ namespace SilverStripe\ORM\FieldType;
|
||||
use Convert;
|
||||
use Exception;
|
||||
use DatetimeField;
|
||||
use InvalidArgumentException;
|
||||
use Zend_Date;
|
||||
use TemplateGlobalProvider;
|
||||
use DateTime;
|
||||
@ -75,42 +76,47 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Returns the date and time in the format specified by the config value nice_format, or 'd/m/Y g:ia'
|
||||
* by default (e.g. '31/01/2014 2:23pm').
|
||||
*
|
||||
* @return string Formatted date and time.
|
||||
*/
|
||||
public function Nice() {
|
||||
if($this->value) return $this->Format($this->config()->nice_format);
|
||||
return $this->Format($this->config()->nice_format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date and time (in 24-hour format) using the format string 'd/m/Y H:i' e.g. '28/02/2014 13:32'.
|
||||
*
|
||||
* @return string Formatted date and time.
|
||||
*/
|
||||
public function Nice24() {
|
||||
if($this->value) return $this->Format('d/m/Y H:i');
|
||||
return $this->Format('d/m/Y H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date using the format string 'd/m/Y' e.g. '28/02/2014'.
|
||||
*
|
||||
* @return string Formatted date.
|
||||
*/
|
||||
public function Date() {
|
||||
if($this->value) return $this->Format('d/m/Y');
|
||||
return $this->Format('d/m/Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time in 12-hour format using the format string 'g:ia' e.g. '1:32pm'.
|
||||
*
|
||||
* @return string Formatted time.
|
||||
*/
|
||||
public function Time() {
|
||||
if($this->value) return $this->Format('g:ia');
|
||||
return $this->Format('g:ia');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time in 24-hour format using the format string 'H:i' e.g. '13:32'.
|
||||
*
|
||||
* @return string Formatted time.
|
||||
*/
|
||||
public function Time24() {
|
||||
if($this->value) return $this->Format('H:i');
|
||||
return $this->Format('H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,7 +155,7 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider {
|
||||
* @return string Formatted date and time.
|
||||
*/
|
||||
public function URLDatetime() {
|
||||
if($this->value) return $this->Format('Y-m-d%20H:i:s');
|
||||
return $this->Format('Y-m-d%20H:i:s');
|
||||
}
|
||||
|
||||
public function scaffoldFormField($title = null, $params = null) {
|
||||
@ -187,7 +193,7 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider {
|
||||
if(self::$mock_now) {
|
||||
return self::$mock_now;
|
||||
} else {
|
||||
return DBField::create_field('SilverStripe\ORM\FieldType\DBDatetime', date('Y-m-d H:i:s'));
|
||||
return DBField::create_field('Datetime', date('Y-m-d H:i:s'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,9 +209,9 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider {
|
||||
if($datetime instanceof DBDatetime) {
|
||||
self::$mock_now = $datetime;
|
||||
} elseif(is_string($datetime)) {
|
||||
self::$mock_now = DBField::create_field('SilverStripe\ORM\FieldType\DBDatetime', $datetime);
|
||||
self::$mock_now = DBField::create_field('Datetime', $datetime);
|
||||
} else {
|
||||
throw new Exception('DBDatetime::set_mock_now(): Wrong format: ' . $datetime);
|
||||
throw new InvalidArgumentException('DBDatetime::set_mock_now(): Wrong format: ' . $datetime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +225,7 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider {
|
||||
|
||||
public static function get_template_global_variables() {
|
||||
return array(
|
||||
'Now' => array('method' => 'now', 'casting' => 'SilverStripe\ORM\FieldType\DBDatetime'),
|
||||
'Now' => array('method' => 'now', 'casting' => 'Datetime'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -51,10 +51,8 @@ class DBEnum extends DBString {
|
||||
* </code>
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|array $enum A string containing a comma separated list of options or an
|
||||
* array of Vals.
|
||||
* @param string $default The default option, which is either NULL or one of the
|
||||
* items in the enumeration.
|
||||
* @param string|array $enum A string containing a comma separated list of options or an array of Vals.
|
||||
* @param string $default The default option, which is either NULL or one of the items in the enumeration.
|
||||
*/
|
||||
public function __construct($name = null, $enum = NULL, $default = NULL) {
|
||||
if($enum) {
|
||||
@ -107,10 +105,14 @@ class DBEnum extends DBString {
|
||||
/**
|
||||
* Return a dropdown field suitable for editing this field.
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $name
|
||||
* @param bool $hasEmpty
|
||||
* @param string $value
|
||||
* @param string $emptyString
|
||||
* @return DropdownField
|
||||
*/
|
||||
public function formField($title = null, $name = null, $hasEmpty = false, $value = "", $form = null,
|
||||
$emptyString = null) {
|
||||
public function formField($title = null, $name = null, $hasEmpty = false, $value = "", $emptyString = null) {
|
||||
|
||||
if(!$title) {
|
||||
$title = $this->getName();
|
||||
@ -119,7 +121,7 @@ class DBEnum extends DBString {
|
||||
$name = $this->getName();
|
||||
}
|
||||
|
||||
$field = new DropdownField($name, $title, $this->enumValues(false), $value, $form);
|
||||
$field = new DropdownField($name, $title, $this->enumValues(false), $value);
|
||||
if($hasEmpty) {
|
||||
$field->setEmptyString($emptyString);
|
||||
}
|
||||
@ -127,10 +129,7 @@ class DBEnum extends DBString {
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DropdownField
|
||||
*/
|
||||
public function scaffoldFormField($title = null, $params = null) {
|
||||
public function scaffoldFormField($title = null) {
|
||||
return $this->formField($title);
|
||||
}
|
||||
|
||||
@ -141,7 +140,7 @@ class DBEnum extends DBString {
|
||||
*/
|
||||
public function scaffoldSearchField($title = null) {
|
||||
$anyText = _t('Enum.ANY', 'Any');
|
||||
return $this->formField($title, null, true, $anyText, null, "($anyText)");
|
||||
return $this->formField($title, null, true, $anyText, "($anyText)");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,8 +4,8 @@ namespace SilverStripe\ORM\FieldType;
|
||||
|
||||
use FormField;
|
||||
use SearchFilter;
|
||||
use SilverStripe\ORM\Connect\SS_Query;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\Queries\SQLSelect;
|
||||
use ViewableData;
|
||||
use Convert;
|
||||
use Object;
|
||||
@ -256,7 +256,7 @@ abstract class DBField extends ViewableData {
|
||||
* gets you the default representations
|
||||
* of all columns.
|
||||
*
|
||||
* @param SS_Query $query
|
||||
* @param SQLSelect $query
|
||||
*/
|
||||
public function addToQuery(&$query) {
|
||||
|
||||
@ -288,7 +288,8 @@ abstract class DBField extends ViewableData {
|
||||
* @return string
|
||||
*/
|
||||
public function forTemplate() {
|
||||
return Convert::raw2xml($this->getValue());
|
||||
// Default to XML encoding
|
||||
return $this->XML();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -369,7 +370,7 @@ abstract class DBField extends ViewableData {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function XML(){
|
||||
public function XML() {
|
||||
return Convert::raw2xml($this->RAW());
|
||||
}
|
||||
|
||||
@ -379,7 +380,7 @@ abstract class DBField extends ViewableData {
|
||||
* @return string
|
||||
*/
|
||||
public function CDATA() {
|
||||
return $this->forTemplate();
|
||||
return $this->XML();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -402,7 +403,7 @@ abstract class DBField extends ViewableData {
|
||||
if(empty($fieldName)) {
|
||||
throw new \BadMethodCallException("DBField::saveInto() Called on a nameless '" . get_class($this) . "' object");
|
||||
}
|
||||
$dataObject->$fieldName = $this->value;
|
||||
$dataObject->$fieldName = $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -440,7 +441,6 @@ abstract class DBField extends ViewableData {
|
||||
* search filters (note: parameter hack now in place to pass in the required full path - using $this->name
|
||||
* won't work)
|
||||
*
|
||||
* @param string|bool $name
|
||||
* @param string $name Override name of this field
|
||||
* @return SearchFilter
|
||||
*/
|
||||
|
@ -4,11 +4,9 @@ namespace SilverStripe\ORM\FieldType;
|
||||
|
||||
use Injector;
|
||||
use HTTP;
|
||||
use ShortcodeParser;
|
||||
use DOMDocument;
|
||||
use HTMLEditorField;
|
||||
use ShortcodeParser;
|
||||
use TextField;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Represents a large text field that contains HTML content.
|
||||
@ -32,20 +30,10 @@ class DBHTMLText extends DBText {
|
||||
|
||||
private static $casting = array(
|
||||
"AbsoluteLinks" => "HTMLFragment",
|
||||
// DBText summary methods - override to HTMLFragment
|
||||
"BigSummary" => "HTMLFragment",
|
||||
"ContextSummary" => "HTMLFragment", // Same as DBText
|
||||
"FirstParagraph" => "HTMLFragment",
|
||||
"FirstSentence" => "HTMLFragment",
|
||||
"LimitSentences" => "HTMLFragment",
|
||||
"Summary" => "HTMLFragment",
|
||||
// DBString conversion / summary methods - override to HTMLFragment
|
||||
"LimitCharacters" => "HTMLFragment",
|
||||
"LimitCharactersToClosestWord" => "HTMLFragment",
|
||||
"LimitWordCount" => "HTMLFragment",
|
||||
// DBString conversion / summary methods
|
||||
// Not overridden, but returns HTML instead of plain text.
|
||||
"LowerCase" => "HTMLFragment",
|
||||
"UpperCase" => "HTMLFragment",
|
||||
"NoHTML" => "Text", // Actually stays same as DBString cast
|
||||
);
|
||||
|
||||
/**
|
||||
@ -134,141 +122,6 @@ class DBHTMLText extends DBText {
|
||||
return parent::setOptions($options);
|
||||
}
|
||||
|
||||
public function LimitSentences($maxSentences = 2)
|
||||
{
|
||||
// @todo
|
||||
return parent::LimitSentences($maxSentences);
|
||||
}
|
||||
|
||||
public function LimitWordCount($numWords = 26, $add = '...')
|
||||
{
|
||||
// @todo
|
||||
return parent::LimitWordCount($numWords, $add);
|
||||
}
|
||||
|
||||
public function LimitCharacters($limit = 20, $add = '...')
|
||||
{
|
||||
// @todo
|
||||
return parent::LimitCharacters($limit, $add);
|
||||
}
|
||||
|
||||
public function LimitCharactersToClosestWord($limit = 20, $add = '...')
|
||||
{
|
||||
// @todo
|
||||
return parent::LimitCharactersToClosestWord($limit, $add);
|
||||
}
|
||||
|
||||
public function BigSummary($maxWords = 50)
|
||||
{
|
||||
// @todo
|
||||
return parent::BigSummary($maxWords); // TODO: Change the autogenerated stub
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a summary of the content. This will be some section of the first paragraph, limited by
|
||||
* $maxWords. All internal tags are stripped out - the return value is a string
|
||||
*
|
||||
* This is sort of the HTML aware equivilent to Text#Summary, although the logic for summarising is not exactly
|
||||
* the same
|
||||
*
|
||||
* @param int $maxWords Maximum number of words to return - may return less, but never more. Pass -1 for no limit
|
||||
* @param int $flex Number of words to search through when looking for a nice cut point
|
||||
* @param string $add What to add to the end of the summary if we cut at a less-than-ideal cut point
|
||||
* @return string A nice(ish) summary with no html tags (but possibly still some html entities)
|
||||
*
|
||||
* @see framework/core/model/fieldtypes/Text#Summary($maxWords)
|
||||
*/
|
||||
public function Summary($maxWords = 50, $flex = 15, $add = '...') {
|
||||
$str = false;
|
||||
|
||||
/* First we need the text of the first paragraph, without tags. Try using SimpleXML first */
|
||||
if (class_exists('SimpleXMLElement')) {
|
||||
$doc = new DOMDocument();
|
||||
|
||||
// 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->RAW());
|
||||
try {
|
||||
$res = $doc->loadHTML('<meta content="text/html; charset=utf-8" http-equiv="Content-type"/>' . $value);
|
||||
}
|
||||
catch (Exception $e) { $res = false; }
|
||||
restore_error_handler();
|
||||
|
||||
if ($res) {
|
||||
$xml = simplexml_import_dom($doc);
|
||||
$res = $xml->xpath('//p');
|
||||
if (!empty($res)) $str = strip_tags($res[0]->asXML());
|
||||
}
|
||||
}
|
||||
|
||||
/* If that failed, most likely the passed HTML is broken. use a simple regex + a custom more brutal strip_tags.
|
||||
* We don't use strip_tags because that does very badly on broken HTML */
|
||||
if (!$str) {
|
||||
/* See if we can pull a paragraph out*/
|
||||
|
||||
// Strip out any images in case there's one at the beginning. Not doing this will return a blank paragraph
|
||||
$str = preg_replace('{^\s*(<.+?>)*<img[^>]*>}', '', $this->value);
|
||||
if (preg_match('{<p(\s[^<>]*)?>(.*[A-Za-z]+.*)</p>}', $str, $matches)) $str = $matches[2];
|
||||
|
||||
/* If _that_ failed, just use the whole text */
|
||||
if (!$str) $str = $this->value;
|
||||
|
||||
/* Now pull out all the html-alike stuff */
|
||||
/* Take out anything that is obviously a tag */
|
||||
$str = preg_replace('{</?[a-zA-Z]+[^<>]*>}', '', $str);
|
||||
/* Strip out any left over looking bits. Textual < or > should already be encoded to < or > */
|
||||
$str = preg_replace('{</|<|>}', '', $str);
|
||||
}
|
||||
|
||||
/* Now split into words. If we are under the maxWords limit, just return the whole string (re-implode for
|
||||
* whitespace normalization) */
|
||||
$words = preg_split('/\s+/', $str);
|
||||
if ($maxWords == -1 || count($words) <= $maxWords) return implode(' ', $words);
|
||||
|
||||
/* Otherwise work backwards for a looking for a sentence ending (we try to avoid abbreviations, but aren't
|
||||
* very good at it) */
|
||||
for ($i = $maxWords; $i >= $maxWords - $flex && $i >= 0; $i--) {
|
||||
if (preg_match('/\.$/', $words[$i]) && !preg_match('/(Dr|Mr|Mrs|Ms|Miss|Sr|Jr|No)\.$/i', $words[$i])) {
|
||||
return implode(' ', array_slice($words, 0, $i+1));
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find a sentence ending quickly enough, just cut at the maxWords point and add '...' to the end
|
||||
return implode(' ', array_slice($words, 0, $maxWords)) . $add;
|
||||
}
|
||||
|
||||
public function FirstParagraph() {
|
||||
// @todo implement
|
||||
return parent::FirstParagraph();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first sentence from the first paragraph. If it can't figure out what the first paragraph is (or
|
||||
* there isn't one), it returns the same as Summary()
|
||||
*
|
||||
* This is the HTML aware equivilent to Text#FirstSentence
|
||||
*
|
||||
* @see framework/core/model/fieldtypes/Text#FirstSentence()
|
||||
*/
|
||||
public function FirstSentence() {
|
||||
/* Use summary's html processing logic to get the first paragraph */
|
||||
$paragraph = $this->Summary(-1);
|
||||
|
||||
/* Then look for the first sentence ending. We could probably use a nice regex, but for now this will do */
|
||||
$words = preg_split('/\s+/', $paragraph);
|
||||
foreach ($words as $i => $word) {
|
||||
if (preg_match('/(!|\?|\.)$/', $word) && !preg_match('/(Dr|Mr|Mrs|Ms|Miss|Sr|Jr|No)\.$/i', $word)) {
|
||||
return implode(' ', array_slice($words, 0, $i+1));
|
||||
}
|
||||
}
|
||||
|
||||
/* If we didn't find a sentence ending, use the summary. We re-call rather than using paragraph so that
|
||||
* Summary will limit the result this time */
|
||||
return $this->Summary();
|
||||
}
|
||||
|
||||
public function RAW() {
|
||||
if ($this->processShortcodes) {
|
||||
return ShortcodeParser::get_active()->parse($this->value);
|
||||
@ -287,6 +140,7 @@ class DBHTMLText extends DBText {
|
||||
}
|
||||
|
||||
public function forTemplate() {
|
||||
// Suppress XML encoding for DBHtmlText
|
||||
return $this->RAW();
|
||||
}
|
||||
|
||||
@ -364,23 +218,34 @@ class DBHTMLText extends DBText {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function scaffoldFormField($title = null, $params = null) {
|
||||
public function scaffoldFormField($title = null) {
|
||||
return new HTMLEditorField($this->name, $title);
|
||||
}
|
||||
|
||||
public function scaffoldSearchField($title = null, $params = null) {
|
||||
public function scaffoldSearchField($title = null) {
|
||||
return new TextField($this->name, $title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plain-text version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function NoHTML()
|
||||
{
|
||||
public function Plain() {
|
||||
// Preserve line breaks
|
||||
$text = preg_replace('/\<br(\s*)?\/?\>/i', "\n", $this->RAW());
|
||||
// Convert back to plain text
|
||||
return \Convert::xml2raw(strip_tags($text));
|
||||
|
||||
// Convert paragraph breaks to multi-lines
|
||||
$text = preg_replace('/\<\/p\>/i', "\n\n", $text);
|
||||
|
||||
// Strip out HTML tags
|
||||
$text = strip_tags($text);
|
||||
|
||||
// Implode >3 consecutive linebreaks into 2
|
||||
$text = preg_replace('~(\R){2,}~', "\n\n", $text);
|
||||
|
||||
// Decode HTML entities back to plain text
|
||||
return trim(\Convert::xml2raw($text));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,13 @@ class DBHTMLVarchar extends DBVarchar {
|
||||
|
||||
private static $escape_type = 'xml';
|
||||
|
||||
private static $casting = array(
|
||||
// DBString conversion / summary methods
|
||||
// Not overridden, but returns HTML instead of plain text.
|
||||
"LowerCase" => "HTMLFragment",
|
||||
"UpperCase" => "HTMLFragment",
|
||||
);
|
||||
|
||||
/**
|
||||
* Enable shortcode parsing on this field
|
||||
*
|
||||
@ -69,6 +76,7 @@ class DBHTMLVarchar extends DBVarchar {
|
||||
}
|
||||
|
||||
public function forTemplate() {
|
||||
// Suppress XML encoding for DBHtmlText
|
||||
return $this->RAW();
|
||||
}
|
||||
|
||||
@ -88,15 +96,53 @@ class DBHTMLVarchar extends DBVarchar {
|
||||
public function CDATA() {
|
||||
return sprintf(
|
||||
'<![CDATA[%s]]>',
|
||||
str_replace(']]>', ']]]]><![CDATA[>', $this->forTemplate())
|
||||
str_replace(']]>', ']]]]><![CDATA[>', $this->RAW())
|
||||
);
|
||||
}
|
||||
|
||||
public function exists() {
|
||||
return parent::exists() && $this->RAW() != '<p></p>';
|
||||
/**
|
||||
* Get plain-text version.
|
||||
*
|
||||
* Note: unlike DBHTMLText, this doesn't respect line breaks / paragraphs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Plain() {
|
||||
// Strip out HTML
|
||||
$text = strip_tags($this->RAW());
|
||||
|
||||
// Convert back to plain text
|
||||
return trim(\Convert::xml2raw($text));
|
||||
}
|
||||
|
||||
public function scaffoldFormField($title = null, $params = null) {
|
||||
/**
|
||||
* Returns true if the field has meaningful content.
|
||||
* Excludes null content like <h1></h1>, <p></p> ,etc
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function exists() {
|
||||
// If it's blank, it's blank
|
||||
if(!parent::exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If it's got a content tag
|
||||
if(preg_match('/<(img|embed|object|iframe|meta|source|link)[^>]*>/i', $this->RAW())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If it's just one or two tags on its own (and not the above) it's empty.
|
||||
// This might be <p></p> or <h1></h1> or whatever.
|
||||
if(preg_match('/^[\\s]*(<[^>]+>[\\s]*){1,2}$/', $this->RAW())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise its content is genuine content
|
||||
return true;
|
||||
}
|
||||
|
||||
public function scaffoldFormField($title = null) {
|
||||
return new HTMLEditorField($this->name, $title, 1);
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ class DBMoney extends DBComposite {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
public function Nice($options = array()) {
|
||||
|
@ -54,14 +54,20 @@ class DBMultiEnum extends DBEnum {
|
||||
|
||||
/**
|
||||
* Return a {@link CheckboxSetField} suitable for editing this field
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $name
|
||||
* @param bool $hasEmpty
|
||||
* @param string $value
|
||||
* @param string $emptyString
|
||||
* @return CheckboxSetField
|
||||
*/
|
||||
public function formField($title = null, $name = null, $hasEmpty = false, $value = "", $form = null,
|
||||
$emptyString = null) {
|
||||
public function formField($title = null, $name = null, $hasEmpty = false, $value = "", $emptyString = null) {
|
||||
|
||||
if(!$title) $title = $this->name;
|
||||
if(!$name) $name = $this->name;
|
||||
|
||||
$field = new CheckboxSetField($name, $title, $this->enumValues($hasEmpty), $value, $form);
|
||||
$field = new CheckboxSetField($name, $title, $this->enumValues($hasEmpty), $value);
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
@ -80,5 +80,6 @@ class DBPolymorphicForeignKey extends DBComposite {
|
||||
if($id && $class && is_subclass_of($class, 'SilverStripe\ORM\DataObject')) {
|
||||
return DataObject::get_by_id($class, $id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ namespace SilverStripe\ORM\FieldType;
|
||||
use SilverStripe\ORM\DB;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
|
||||
/**
|
||||
* A special type Int field used for primary keys.
|
||||
*
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
namespace SilverStripe\ORM\FieldType;
|
||||
|
||||
use Convert;
|
||||
|
||||
/**
|
||||
* An abstract base class for the string field types (i.e. Varchar and Text)
|
||||
*
|
||||
@ -23,10 +21,10 @@ abstract class DBString extends DBField {
|
||||
private static $casting = array(
|
||||
"LimitCharacters" => "Text",
|
||||
"LimitCharactersToClosestWord" => "Text",
|
||||
'LimitWordCount' => 'Text',
|
||||
"LimitWordCount" => "Text",
|
||||
"LowerCase" => "Text",
|
||||
"UpperCase" => "Text",
|
||||
'NoHTML' => 'Text',
|
||||
"Plain" => "Text",
|
||||
);
|
||||
|
||||
/**
|
||||
@ -129,10 +127,6 @@ abstract class DBString extends DBField {
|
||||
|| (!$this->getNullifyEmpty() && $value === ''); // Remove this stupid exemption in 4.0
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see core/model/fieldtypes/DBField#prepValueForDB($value)
|
||||
*/
|
||||
public function prepValueForDB($value) {
|
||||
if(!$this->nullifyEmpty && $value === '') {
|
||||
return $value;
|
||||
@ -158,17 +152,11 @@ abstract class DBString extends DBField {
|
||||
* @return string
|
||||
*/
|
||||
public function LimitCharacters($limit = 20, $add = '...') {
|
||||
$value = trim($this->RAW());
|
||||
if($this->stat('escape_type') == 'xml') {
|
||||
$value = strip_tags($value);
|
||||
$value = html_entity_decode($value, ENT_COMPAT, 'UTF-8');
|
||||
$value = (mb_strlen($value) > $limit) ? mb_substr($value, 0, $limit) . $add : $value;
|
||||
// Avoid encoding all multibyte characters as HTML entities by using htmlspecialchars().
|
||||
$value = htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
|
||||
} else {
|
||||
$value = (mb_strlen($value) > $limit) ? mb_substr($value, 0, $limit) . $add : $value;
|
||||
$value = $this->Plain();
|
||||
if(mb_strlen($value) <= $limit) {
|
||||
return $value;
|
||||
}
|
||||
return $value;
|
||||
return mb_substr($value, 0, $limit) . $add;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,27 +166,26 @@ abstract class DBString extends DBField {
|
||||
*
|
||||
* @param int $limit Number of characters to limit by
|
||||
* @param string $add Ellipsis to add to the end of truncated string
|
||||
* @return string
|
||||
* @return string Plain text value with limited characters
|
||||
*/
|
||||
public function LimitCharactersToClosestWord($limit = 20, $add = '...') {
|
||||
// Strip HTML tags if they exist in the field
|
||||
$value = strip_tags($this->RAW());
|
||||
// Safely convert to plain text
|
||||
$value = $this->Plain();
|
||||
|
||||
// Determine if value exceeds limit before limiting characters
|
||||
$exceedsLimit = mb_strlen($value) > $limit;
|
||||
|
||||
// Limit to character 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) {
|
||||
$value = html_entity_decode($value, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
$value = rtrim(mb_substr($value, 0, mb_strrpos($value, " ")), "/[\.,-\/#!$%\^&\*;:{}=\-_`~()]\s") . $add;
|
||||
|
||||
$value = htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
|
||||
if(mb_strlen($value) <= $limit) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Limit to character limit
|
||||
$value = mb_substr($value, 0, $limit);
|
||||
|
||||
// If value exceeds limit, strip punctuation off the end to the last space and apply ellipsis
|
||||
$value = preg_replace(
|
||||
'/[^\w_]+$/',
|
||||
'',
|
||||
mb_substr($value, 0, mb_strrpos($value, " "))
|
||||
) . $add;
|
||||
return $value;
|
||||
}
|
||||
|
||||
@ -211,23 +198,21 @@ abstract class DBString extends DBField {
|
||||
* @return string
|
||||
*/
|
||||
public function LimitWordCount($numWords = 26, $add = '...') {
|
||||
$value = trim(Convert::xml2raw($this->RAW()));
|
||||
$ret = explode(' ', $value, $numWords + 1);
|
||||
|
||||
if(count($ret) <= $numWords - 1) {
|
||||
$ret = $value;
|
||||
} else {
|
||||
array_pop($ret);
|
||||
$ret = implode(' ', $ret) . $add;
|
||||
$value = $this->Plain();
|
||||
$words = explode(' ', $value);
|
||||
if(count($words) <= $numWords) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
// Limit
|
||||
$words = array_slice($words, 0, $numWords);
|
||||
return implode(' ', $words) . $add;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the current value for this StringField to lowercase.
|
||||
*
|
||||
* @return string
|
||||
* @return string Text with lowercase (HTML for some subclasses)
|
||||
*/
|
||||
public function LowerCase() {
|
||||
return mb_strtolower($this->RAW());
|
||||
@ -236,7 +221,7 @@ abstract class DBString extends DBField {
|
||||
/**
|
||||
* Converts the current value for this StringField to uppercase.
|
||||
*
|
||||
* @return string
|
||||
* @return string Text with uppercase (HTML for some subclasses)
|
||||
*/
|
||||
public function UpperCase() {
|
||||
return mb_strtoupper($this->RAW());
|
||||
@ -247,7 +232,7 @@ abstract class DBString extends DBField {
|
||||
*
|
||||
* @return string Plain text
|
||||
*/
|
||||
public function NoHTML() {
|
||||
return $this->RAW();
|
||||
public function Plain() {
|
||||
return trim($this->RAW());
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class DBText extends DBString {
|
||||
|
||||
private static $casting = array(
|
||||
"BigSummary" => "Text",
|
||||
"ContextSummary" => "HTMLText", // Always returns HTML as it contains formatting and highlighting
|
||||
"ContextSummary" => "HTMLFragment", // Always returns HTML as it contains formatting and highlighting
|
||||
"FirstParagraph" => "Text",
|
||||
"FirstSentence" => "Text",
|
||||
"LimitSentences" => "Text",
|
||||
@ -72,9 +72,9 @@ class DBText extends DBString {
|
||||
public function LimitSentences($maxSentences = 2) {
|
||||
if(!is_numeric($maxSentences)) {
|
||||
throw new InvalidArgumentException("Text::LimitSentence() expects one numeric argument");
|
||||
}
|
||||
}
|
||||
|
||||
$value = $this->NoHTML();
|
||||
$value = $this->Plain();
|
||||
if( !$value ) {
|
||||
return "";
|
||||
}
|
||||
@ -114,40 +114,32 @@ class DBText extends DBString {
|
||||
* Builds a basic summary, up to a maximum number of words
|
||||
*
|
||||
* @param int $maxWords
|
||||
* @param int $maxParagraphs Optional paragraph limit
|
||||
* @param string $add
|
||||
* @return string
|
||||
*/
|
||||
public function Summary($maxWords = 50, $maxParagraphs = 1) {
|
||||
public function Summary($maxWords = 50, $add = '...') {
|
||||
// Get plain-text version
|
||||
$value = $this->NoHTML();
|
||||
$value = $this->Plain();
|
||||
if(!$value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Set max paragraphs
|
||||
if($maxParagraphs) {
|
||||
// Split on >2 linebreaks
|
||||
$paragraphs = preg_split('#\n{2,}#', $value);
|
||||
if(count($paragraphs) > $maxParagraphs) {
|
||||
$paragraphs = array_slice($paragraphs, 0, $maxParagraphs);
|
||||
}
|
||||
$value = implode("\n\n", $paragraphs);
|
||||
}
|
||||
|
||||
// Find sentences
|
||||
$sentences = explode('.', $value);
|
||||
// Split on sentences (don't remove period)
|
||||
$sentences = array_filter(array_map(function($str) {
|
||||
return trim($str);
|
||||
}, preg_split('@(?<=\.)@', $value)));
|
||||
$wordCount = count(preg_split('#\s+#', $sentences[0]));
|
||||
|
||||
// if the first sentence is too long, show only the first $maxWords words
|
||||
if($wordCount > $maxWords) {
|
||||
return implode( ' ', array_slice(explode( ' ', $sentences[0] ), 0, $maxWords)) . '...';
|
||||
return implode( ' ', array_slice(explode( ' ', $sentences[0] ), 0, $maxWords)) . $add;
|
||||
}
|
||||
|
||||
// add each sentence while there are enough words to do so
|
||||
$result = '';
|
||||
do {
|
||||
// Add next sentence
|
||||
$result .= ' ' . trim(array_shift( $sentences )).'.';
|
||||
$result .= ' ' . array_shift( $sentences );
|
||||
|
||||
// If more sentences to process, count number of words
|
||||
if($sentences) {
|
||||
@ -158,31 +150,21 @@ class DBText extends DBString {
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the same function as the big summary, but doesn't trim new paragraphs off data.
|
||||
*
|
||||
* @param int $maxWords
|
||||
* @return string
|
||||
*/
|
||||
public function BigSummary($maxWords = 50) {
|
||||
return $this->Summary($maxWords, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get first paragraph
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function FirstParagraph() {
|
||||
$value = $this->NoHTML();
|
||||
$value = $this->Plain();
|
||||
if(empty($value)) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Split paragraphs and return first
|
||||
$paragraphs = preg_split('#\n{2,}#', $value);
|
||||
return reset($paragraphs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform context searching to give some context to searches, optionally
|
||||
@ -205,7 +187,7 @@ class DBText extends DBString {
|
||||
}
|
||||
|
||||
// Get raw text value, but XML encode it (as we'll be merging with HTML tags soon)
|
||||
$text = nl2br(Convert::raw2xml($this->NoHTML()));
|
||||
$text = nl2br(Convert::raw2xml($this->Plain()));
|
||||
$keywords = Convert::raw2xml($keywords);
|
||||
|
||||
// Find the search string
|
||||
@ -230,9 +212,10 @@ class DBText extends DBString {
|
||||
if($stringPieces) {
|
||||
foreach($stringPieces as $stringPiece) {
|
||||
if(strlen($stringPiece) > 2) {
|
||||
$summary = str_ireplace(
|
||||
$stringPiece,
|
||||
"<span class=\"highlight\">$stringPiece</span>",
|
||||
// Maintain case of original string
|
||||
$summary = preg_replace(
|
||||
'/' . preg_quote($stringPiece, '/') . '/i',
|
||||
'<span class="highlight">$0</span>',
|
||||
$summary
|
||||
);
|
||||
}
|
||||
@ -245,7 +228,7 @@ class DBText extends DBString {
|
||||
if($position > 0) {
|
||||
$summary = $prefix . $summary;
|
||||
}
|
||||
if(strlen($this->value) > ($characters + $position)) {
|
||||
if(strlen($text) > ($characters + $position)) {
|
||||
$summary = $summary . $suffix;
|
||||
}
|
||||
|
||||
@ -267,14 +250,10 @@ class DBText extends DBString {
|
||||
|
||||
/** @var TextParser $obj */
|
||||
$obj = \Injector::inst()->createWithArgs($parser, [$this->forTemplate()]);
|
||||
return $obj->parse();
|
||||
return $obj->parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see DBField::scaffoldFormField()
|
||||
*/
|
||||
public function scaffoldFormField($title = null, $params = null) {
|
||||
public function scaffoldFormField($title = null) {
|
||||
if(!$this->nullifyEmpty) {
|
||||
// Allow the user to select if it's null instead of automatically assuming empty string is
|
||||
return new NullableField(new TextareaField($this->name, $title));
|
||||
@ -284,11 +263,7 @@ class DBText extends DBString {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see DBField::scaffoldSearchField()
|
||||
*/
|
||||
public function scaffoldSearchField($title = null, $params = null) {
|
||||
public function scaffoldSearchField($title = null) {
|
||||
return new TextField($this->name, $title);
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ class DBTime extends DBField {
|
||||
* @return string
|
||||
*/
|
||||
public function Nice() {
|
||||
if($this->value) return $this->Format($this->config()->nice_format);
|
||||
return $this->Format($this->config()->nice_format);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,7 +57,7 @@ class DBTime extends DBField {
|
||||
* @return string Time in 24 hour format
|
||||
*/
|
||||
public function Nice24() {
|
||||
if($this->value) return date('H:i', strtotime($this->value));
|
||||
return $this->Format('H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,7 +67,10 @@ class DBTime extends DBField {
|
||||
* @return string The date in the requested format
|
||||
*/
|
||||
public function Format($format) {
|
||||
if($this->value) return date($format, strtotime($this->value));
|
||||
if($this->value) {
|
||||
return date($format, strtotime($this->value));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function TwelveHour( $parts ) {
|
||||
|
@ -78,21 +78,29 @@ class DBVarchar extends DBString {
|
||||
|
||||
/**
|
||||
* Return the first letter of the string followed by a .
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Initial() {
|
||||
if($this->exists()) {
|
||||
$value = $this->RAW();
|
||||
return $value[0] . '.';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the given value is an absolute URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function URL() {
|
||||
$value = $this->RAW();
|
||||
if(preg_match('#^[a-zA-Z]+://#', $value)) return $value;
|
||||
else return "http://" . $value;
|
||||
if(preg_match('#^[a-zA-Z]+://#', $value)) {
|
||||
return $value;
|
||||
} else {
|
||||
return "http://" . $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,11 +111,7 @@ class DBVarchar extends DBString {
|
||||
return str_replace("\n", '\par ', $this->RAW());
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see DBField::scaffoldFormField()
|
||||
*/
|
||||
public function scaffoldFormField($title = null, $params = null) {
|
||||
public function scaffoldFormField($title = null) {
|
||||
if(!$this->nullifyEmpty) {
|
||||
// Allow the user to select if it's null instead of automatically assuming empty string is
|
||||
return new NullableField(new TextField($this->name, $title));
|
||||
|
@ -40,9 +40,13 @@ class DBYear extends DBField {
|
||||
* @param int|bool $end end date to count down to
|
||||
* @return array
|
||||
*/
|
||||
private function getDefaultOptions($start=false, $end=false) {
|
||||
if (!$start) $start = (int)date('Y');
|
||||
if (!$end) $end = 1900;
|
||||
private function getDefaultOptions($start = null, $end = null) {
|
||||
if (!$start) {
|
||||
$start = (int)date('Y');
|
||||
}
|
||||
if (!$end) {
|
||||
$end = 1900;
|
||||
}
|
||||
$years = array();
|
||||
for($i=$start;$i>=$end;$i--) {
|
||||
$years[$i] = $i;
|
||||
|
@ -311,7 +311,14 @@ class RSSFeed_Entry extends ViewableData {
|
||||
* @return DBField Returns the description of the entry.
|
||||
*/
|
||||
public function Description() {
|
||||
return $this->rssField($this->descriptionField);
|
||||
$description = $this->rssField($this->descriptionField);
|
||||
|
||||
// HTML fields need links re-written
|
||||
if($description instanceof DBHTMLText) {
|
||||
return $description->obj('AbsoluteLinks');
|
||||
}
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -191,6 +191,8 @@ class Convert {
|
||||
* Convert XML to raw text.
|
||||
* @uses html2raw()
|
||||
* @todo Currently &#xxx; entries are stripped; they should be converted
|
||||
* @param mixed $val
|
||||
* @return array|string
|
||||
*/
|
||||
public static function xml2raw($val) {
|
||||
if(is_array($val)) {
|
||||
@ -234,6 +236,7 @@ class Convert {
|
||||
* false by default.
|
||||
* @param boolean $disableExternals Disables the loading of external entities. false by default.
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function xml2array($val, $disableDoctypes = false, $disableExternals = false) {
|
||||
// Check doctype
|
||||
@ -242,6 +245,7 @@ class Convert {
|
||||
}
|
||||
|
||||
// Disable external entity loading
|
||||
$oldVal = null;
|
||||
if($disableExternals) $oldVal = libxml_disable_entity_loader($disableExternals);
|
||||
try {
|
||||
$xml = new SimpleXMLElement($val);
|
||||
@ -263,7 +267,7 @@ class Convert {
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function recursiveXMLToArray($xml) {
|
||||
if(is_object($xml) && get_class($xml) == 'SimpleXMLElement') {
|
||||
if($xml instanceof SimpleXMLElement) {
|
||||
$attributes = $xml->attributes();
|
||||
foreach($attributes as $k => $v) {
|
||||
if($v) $a[$k] = (string) $v;
|
||||
|
@ -145,3 +145,16 @@ html. To ensure that the correct encoding is used for that field in a template,
|
||||
`$Field` by itself to allow the casting helper to determine the best encoding itself.
|
||||
</div>
|
||||
|
||||
## Cast summary methods
|
||||
|
||||
Certain subclasses of DBField also have additional summary or manipulations methods, each of
|
||||
which can be chained in order to perform more complicated manipulations.
|
||||
|
||||
For instance, The following class methods can be used in templates for the below types:
|
||||
|
||||
Text / HTMLText methods:
|
||||
|
||||
* `$Plain` Will convert any HTML to plain text version. For example, could be used for plain-text
|
||||
version of emails.
|
||||
* `$LimitSentences(<num>)` Will limit to the first `<num>` sentences in the content. If called on
|
||||
HTML content this will have all HTML stripped and converted to plain text.
|
||||
|
@ -50,6 +50,7 @@
|
||||
html fields as `HTMLText(['whitelist=meta,link'])`, or use a `ShortcodeHTMLText` as
|
||||
a shorthand substitute.
|
||||
* `FormField->dontEscape` has been removed. Escaping is now managed on a class by class basis.
|
||||
* `DBString->LimitWordCountXML` removed. Use `LimitWordCount` for XML safe version.
|
||||
|
||||
## New API
|
||||
|
||||
@ -104,6 +105,11 @@
|
||||
* `FormAction::setValidationExempt` can be used to turn on or off form validation for individual actions
|
||||
* `DataObject.table_name` config can now be used to customise the database table for any record.
|
||||
* `DataObjectSchema` class added to assist with mapping between classes and tables.
|
||||
* Changes to `DBString` formatting:
|
||||
* `NoHTML` is renamed to `Plain`
|
||||
* `LimitWordCountXML` is removed. Use `LimitWordCount` instead.
|
||||
* `BigSummary` is removed. Use `Summary` instead.
|
||||
* Most limit methods on `DBHTMLText` now plain text rather than attempt to manipulate the underlying HTML.
|
||||
* `FormField::Title` and `FormField::RightTitle` are now cast as plain text by default (but can be overridden).
|
||||
|
||||
### Front-end build tooling for CMS interface
|
||||
@ -174,7 +180,7 @@ admin/font/ => admin/client/dist/font/
|
||||
* History.js
|
||||
|
||||
* `debugmethods` querystring argument has been removed from debugging.
|
||||
|
||||
|
||||
* The following ClassInfo methods are now deprecated:
|
||||
* `ClassInfo::baseDataClass` - Use `DataObject::getSchema()->baseDataClass()` instead.
|
||||
* `ClassInfo::table_for_object_field` - Use `DataObject::getSchema()->tableForField()` instead
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
|
||||
/**
|
||||
* Adds a "level up" link to a GridField table, which is useful when viewing
|
||||
* hierarchical data. Requires the managed record to have a "getParent()"
|
||||
@ -60,7 +62,7 @@ class GridFieldLevelup extends Object implements GridField_HTMLProvider {
|
||||
foreach($attrs as $k => $v) $attrsStr .= " $k=\"" . Convert::raw2att($v) . "\"";
|
||||
|
||||
$forTemplate = new ArrayData(array(
|
||||
'UpLink' => sprintf('<a%s></a>', $attrsStr)
|
||||
'UpLink' => DBField::create_field('HTMLFragment', sprintf('<a%s></a>', $attrsStr))
|
||||
));
|
||||
|
||||
return array(
|
||||
|
@ -105,7 +105,7 @@ class BBCodeParser extends TextParser {
|
||||
);
|
||||
}
|
||||
|
||||
public function useable_tagsHTML(){
|
||||
public function useable_tagsHTML() {
|
||||
$useabletags = "<ul class='bbcodeExamples'>";
|
||||
foreach($this->usable_tags()->toArray() as $tag){
|
||||
$useabletags = $useabletags."<li><span>".$tag->Example."</span></li>";
|
||||
@ -120,20 +120,13 @@ class BBCodeParser extends TextParser {
|
||||
* @return DBField
|
||||
*/
|
||||
public function parse() {
|
||||
$this->content = str_replace(array('&', '<', '>'), array('&', '<', '>'), $this->content);
|
||||
// Convert content to plain text
|
||||
$this->content = DBField::create_field('HTMLFragment', $this->content)->Plain();
|
||||
|
||||
$p = new SSHTMLBBCodeParser();
|
||||
$this->content = $p->qparse($this->content);
|
||||
unset($p);
|
||||
|
||||
$this->content = "<p>".$this->content."</p>";
|
||||
|
||||
$this->content = preg_replace('/(<p[^>]*>)\s+/i', '\\1', $this->content);
|
||||
$this->content = preg_replace('/\s+(<\/p[^>]*>)/i', '\\1', $this->content);
|
||||
|
||||
$this->content = preg_replace("/\n\s*\n/", "</p><p>", $this->content);
|
||||
$this->content = str_replace("\n", "<br />", $this->content);
|
||||
|
||||
if($this->config()->allow_smilies) {
|
||||
$smilies = array(
|
||||
'#(?<!\w):D(?!\w)#i' => " <img src='".BBCodeParser::smilies_location(). "/grin.gif'> ", // :D
|
||||
|
@ -1,4 +1,6 @@
|
||||
<?php
|
||||
use SilverStripe\Model\FieldType\DBField;
|
||||
|
||||
/**
|
||||
* Parses text in a variety of ways.
|
||||
*
|
||||
|
@ -10,7 +10,7 @@
|
||||
<item>
|
||||
<title>$Title.XML</title>
|
||||
<link>$AbsoluteLink.XML</link>
|
||||
<% if $Description %><description>$Description.AbsoluteLinks.CDATA</description><% end_if %>
|
||||
<% if $Description %><description>$Description.CDATA</description><% end_if %>
|
||||
<% if $Date %><pubDate>$Date.Rfc822</pubDate>
|
||||
<% else %><pubDate>$Created.Rfc822</pubDate><% end_if %>
|
||||
<% if $Author %><dc:creator>$Author.XML</dc:creator><% end_if %>
|
||||
|
@ -225,12 +225,19 @@ class DBFieldTest extends SapphireTest {
|
||||
|
||||
$value = '<p>üåäö&ÜÅÄÖ</p>';
|
||||
foreach ($htmlFields as $stringField) {
|
||||
$stringField = DBField::create_field($stringField, $value);
|
||||
$this->assertEquals('üåäö&ÜÅÄ...', $stringField->LimitCharacters(8));
|
||||
$stringObj = DBField::create_field($stringField, $value);
|
||||
|
||||
// Converted to plain text
|
||||
$this->assertEquals('üåäö&ÜÅÄ...', $stringObj->LimitCharacters(8));
|
||||
|
||||
// But which will be safely cast in templates
|
||||
$this->assertEquals('üåäö&ÜÅÄ...', $stringObj->obj('LimitCharacters', [8])->forTemplate());
|
||||
}
|
||||
|
||||
$this->assertEquals('ÅÄÖ', DBField::create_field('Text', 'åäö')->UpperCase());
|
||||
$this->assertEquals('åäö', DBField::create_field('Text', 'ÅÄÖ')->LowerCase());
|
||||
$this->assertEquals('<P>ÅÄÖ</P>', DBField::create_field('HTMLFragment', '<p>åäö</p>')->UpperCase());
|
||||
$this->assertEquals('<p>åäö</p>', DBField::create_field('HTMLFragment', '<p>ÅÄÖ</p>')->LowerCase());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,142 +12,385 @@ use SilverStripe\ORM\FieldType\DBField;
|
||||
*/
|
||||
class DBHTMLTextTest extends SapphireTest {
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Set test handler
|
||||
ShortcodeParser::get('htmltest')
|
||||
->register('test_shortcode', array('DBHTMLTextTest_Shortcode', 'handle_shortcode'));
|
||||
ShortcodeParser::set_active('htmltest');
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
ShortcodeParser::set_active('default');
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link HTMLText->LimitCharacters()}
|
||||
* Test {@link Text->LimitCharacters()}
|
||||
*/
|
||||
public function testLimitCharacters() {
|
||||
$cases = array(
|
||||
'The little brown fox jumped over the lazy cow.' => 'The little brown fox...',
|
||||
'<p>This is some text in a paragraph.</p>' => 'This is some text in...',
|
||||
'This text contains & in it' => 'This text contains &...'
|
||||
);
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = new DBHTMLText('Test');
|
||||
$textObj->setValue($originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->LimitCharacters());
|
||||
}
|
||||
public function providerLimitCharacters()
|
||||
{
|
||||
// HTML characters are stripped safely
|
||||
return [
|
||||
['The little brown fox jumped over the lazy cow.', 'The little brown fox...'],
|
||||
['<p>Short & Sweet</p>', 'Short & Sweet'],
|
||||
['This text contains & in it', 'This text contains &...'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testSummaryBasics() {
|
||||
$cases = array(
|
||||
'<h1>Should not take header</h1><p>Should take paragraph</p>' => 'Should take paragraph',
|
||||
'<p>Should strip <b>tags, but leave</b> text</p>' => 'Should strip tags, but leave text',
|
||||
'<p>Unclosed tags <br>should not phase it</p>' => 'Unclosed tags should not phase it',
|
||||
'<p>Second paragraph</p><p>should not cause errors or appear in output</p>' => 'Second paragraph',
|
||||
'<img src="hello" /><p>Second paragraph</p><p>should not cause errors or appear in output</p>'
|
||||
=> 'Second paragraph',
|
||||
' <img src="hello" /><p>Second paragraph</p><p>should not cause errors or appear in output</p>'
|
||||
=> 'Second paragraph',
|
||||
'<p><img src="remove me">example <img src="include me">text words hello<img src="hello"></p>'
|
||||
=> 'example text words hello',
|
||||
);
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = new DBHTMLText('Test');
|
||||
$textObj->setValue($originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->Summary());
|
||||
}
|
||||
/**
|
||||
* Test {@link DBHTMLText->LimitCharacters()}
|
||||
* @dataProvider providerLimitCharacters
|
||||
* @param string $originalValue
|
||||
* @param string $expectedValue
|
||||
*/
|
||||
public function testLimitCharacters($originalValue, $expectedValue) {
|
||||
$textObj = DBField::create_field('HTMLFragment', $originalValue);
|
||||
$result = $textObj->obj('LimitCharacters')->forTemplate();
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
public function testSummaryLimits() {
|
||||
$cases = array(
|
||||
'<p>A long paragraph should be cut off if limit is set</p>' => 'A long paragraph should be...',
|
||||
'<p>No matter <i>how many <b>tags</b></i> are in it</p>' => 'No matter how many tags...',
|
||||
'<p>A sentence is. nicer than hard limits</p>' => 'A sentence is.',
|
||||
'<p>But not. If it\'s too short</p>' => 'But not. If it\'s too...'
|
||||
);
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerLimitCharactersToClosestWord()
|
||||
{
|
||||
// HTML is converted safely to plain text
|
||||
return [
|
||||
// Standard words limited, ellipsis added if truncated
|
||||
['<p>Lorem ipsum dolor sit amet</p>', 24, 'Lorem ipsum dolor sit...'],
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = new DBHTMLText('Test');
|
||||
$textObj->setValue($originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->Summary(5, 3, '...'));
|
||||
}
|
||||
// Complete words less than the character limit don't get truncated, ellipsis not added
|
||||
['<p>Lorem ipsum</p>', 24, 'Lorem ipsum'],
|
||||
['<p>Lorem</p>', 24, 'Lorem'],
|
||||
['', 24, ''], // No words produces nothing!
|
||||
|
||||
// Special characters are encoded safely
|
||||
['Nice & Easy', 24, 'Nice & Easy'],
|
||||
|
||||
// HTML is safely converted to plain text
|
||||
['<p>Lorem ipsum dolor sit amet</p>', 24, 'Lorem ipsum dolor sit...'],
|
||||
['<p><span>Lorem ipsum dolor sit amet</span></p>', 24, 'Lorem ipsum dolor sit...'],
|
||||
['<p>Lorem ipsum</p>', 24, 'Lorem ipsum'],
|
||||
['Lorem & ipsum dolor sit amet', 24, 'Lorem & ipsum dolor sit...']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link DBHTMLText->LimitCharactersToClosestWord()}
|
||||
* @dataProvider providerLimitCharactersToClosestWord
|
||||
*
|
||||
* @param string $originalValue Raw string input
|
||||
* @param int $limit
|
||||
* @param string $expectedValue Expected template value
|
||||
*/
|
||||
public function testLimitCharactersToClosestWord($originalValue, $limit, $expectedValue) {
|
||||
$textObj = DBField::create_field('HTMLFragment', $originalValue);
|
||||
$result = $textObj->obj('LimitCharactersToClosestWord', [$limit])->forTemplate();
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
public function providerSummary()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'<p>Should strip <b>tags, but leave</b> text</p>',
|
||||
50,
|
||||
'Should strip tags, but leave text',
|
||||
],
|
||||
[
|
||||
// Line breaks are preserved
|
||||
'<p>Unclosed tags <br>should not phase it</p>',
|
||||
50,
|
||||
"Unclosed tags <br />\nshould not phase it",
|
||||
],
|
||||
[
|
||||
// Paragraphs converted to linebreak
|
||||
'<p>Second paragraph</p><p>should not cause errors or appear in output</p>',
|
||||
50,
|
||||
"Second paragraph<br />\n<br />\nshould not cause errors or appear in output",
|
||||
],
|
||||
[
|
||||
'<img src="hello" /><p>Second paragraph</p><p>should not cause errors or appear in output</p>',
|
||||
50,
|
||||
"Second paragraph<br />\n<br />\nshould not cause errors or appear in output",
|
||||
],
|
||||
[
|
||||
' <img src="hello" /><p>Second paragraph</p><p>should not cause errors or appear in output</p>',
|
||||
50,
|
||||
"Second paragraph<br />\n<br />\nshould not cause errors or appear in output",
|
||||
],
|
||||
[
|
||||
'<p><img src="remove me">example <img src="include me">text words hello<img src="hello"></p>',
|
||||
50,
|
||||
'example text words hello',
|
||||
],
|
||||
|
||||
// Shorter limits
|
||||
[
|
||||
'<p>A long paragraph should be cut off if limit is set</p>',
|
||||
5,
|
||||
'A long paragraph should be...',
|
||||
],
|
||||
[
|
||||
'<p>No matter <i>how many <b>tags</b></i> are in it</p>',
|
||||
5,
|
||||
'No matter how many tags...',
|
||||
],
|
||||
[
|
||||
'<p>A sentence is. nicer than hard limits</p>',
|
||||
5,
|
||||
'A sentence is.',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSummary
|
||||
* @param string $originalValue
|
||||
* @param int $limit
|
||||
* @param string $expectedValue
|
||||
*/
|
||||
public function testSummary($originalValue, $limit, $expectedValue) {
|
||||
$textObj = DBField::create_field('HTMLFragment', $originalValue);
|
||||
$result = $textObj->obj('Summary', [$limit])->forTemplate();
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
public function testSummaryEndings() {
|
||||
$cases = array(
|
||||
'...', ' -> more', ''
|
||||
'...',
|
||||
' -> more',
|
||||
''
|
||||
);
|
||||
|
||||
$orig = '<p>Cut it off, cut it off</p>';
|
||||
$match = 'Cut it off, cut';
|
||||
|
||||
foreach($cases as $add) {
|
||||
$textObj = new DBHTMLText();
|
||||
$textObj->setValue($orig);
|
||||
$this->assertEquals($match.$add, $textObj->Summary(4, 0, $add));
|
||||
$textObj = DBField::create_field('HTMLFragment', $orig);
|
||||
$result = $textObj->obj('Summary', [4, $add])->forTemplate();
|
||||
$this->assertEquals($match.Convert::raw2xml($add), $result);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSummaryFlexTooBigShouldNotCauseError() {
|
||||
$orig = '<p>Cut it off, cut it off</p>';
|
||||
$match = 'Cut it off, cut';
|
||||
|
||||
$textObj = new DBHTMLText();
|
||||
$textObj->setValue($orig);
|
||||
$this->assertEquals($match, $textObj->Summary(4, 10, ''));
|
||||
|
||||
public function providerFirstSentence()
|
||||
{
|
||||
return [
|
||||
// Same behaviour as DBTextTest
|
||||
['', ''],
|
||||
['First sentence.', 'First sentence.'],
|
||||
['First sentence. Second sentence', 'First sentence.'],
|
||||
['First sentence? Second sentence', 'First sentence?'],
|
||||
['First sentence! Second sentence', 'First sentence!'],
|
||||
|
||||
// DBHTHLText strips HTML first
|
||||
['<br />First sentence.', 'First sentence.'],
|
||||
['<p>First sentence. Second sentence. Third sentence</p>', 'First sentence.'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testSummaryInvalidHTML() {
|
||||
$cases = array(
|
||||
'It\'s got a <p<> tag, but<p junk true>This doesn\'t <a id="boo">make</b class="wa"> < ><any< sense</p>'
|
||||
=> 'This doesn\'t make any',
|
||||
'This doesn\'t <a style="much horray= true>even</b> < ><have< a <i>p tag' => 'This doesn\'t even have'
|
||||
);
|
||||
|
||||
foreach($cases as $orig => $match) {
|
||||
$textObj = new DBHTMLText();
|
||||
$textObj->setValue($orig);
|
||||
$this->assertEquals($match, $textObj->Summary(4, 0, ''));
|
||||
}
|
||||
/**
|
||||
* @dataProvider providerFirstSentence
|
||||
* @param string $originalValue
|
||||
* @param string $expectedValue
|
||||
*/
|
||||
public function testFirstSentence($originalValue, $expectedValue) {
|
||||
$textObj = DBField::create_field('HTMLFragment', $originalValue);
|
||||
$result = $textObj->obj('FirstSentence')->forTemplate();
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
public function testFirstSentence() {
|
||||
$many = str_repeat('many ', 100);
|
||||
$cases = array(
|
||||
'<h1>should ignore</h1><p>First sentence. Second sentence.</p>' => 'First sentence.',
|
||||
'<h1>should ignore</h1><p>First Mr. sentence. Second sentence.</p>' => 'First Mr. sentence.',
|
||||
"<h1>should ignore</h1><p>Sentence with {$many}words. Second sentence.</p>"
|
||||
=> "Sentence with {$many}words.",
|
||||
'<p>This classic picture book features a repetitive format that lends itself to audience interaction.'.
|
||||
' Illustrator Eric Carle submitted new, bolder artwork for the 25th anniversary edition.</p>'
|
||||
=> 'This classic picture book features a repetitive format that lends itself to audience interaction.'
|
||||
);
|
||||
public function providerToPlain()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'<p><img />Lots of <strong>HTML <i>nested</i></strong> tags',
|
||||
'Lots of HTML nested tags',
|
||||
],
|
||||
[
|
||||
'<p>Multi</p><p>Paragraph<br>Also has multilines.</p>',
|
||||
"Multi\n\nParagraph\nAlso has multilines.",
|
||||
],
|
||||
[
|
||||
'<p>Collapses</p><p></p><p>Excessive<br/><br /><br>Newlines</p>',
|
||||
"Collapses\n\nExcessive\n\nNewlines",
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
foreach($cases as $orig => $match) {
|
||||
$textObj = new DBHTMLText();
|
||||
$textObj->setValue($orig);
|
||||
$this->assertEquals($match, $textObj->FirstSentence());
|
||||
}
|
||||
/**
|
||||
* @dataProvider providerToPlain
|
||||
* @param string $html
|
||||
* @param string $plain
|
||||
*/
|
||||
public function testToPlain($html, $plain) {
|
||||
/** @var DBHTMLText $textObj */
|
||||
$textObj = DBField::create_field('HTMLFragment', $html);
|
||||
$this->assertEquals($plain, $textObj->Plain());
|
||||
}
|
||||
|
||||
/**
|
||||
* each test is in the format input, charactere limit, highlight, expected output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerContextSummary()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'This is some text. It is a test',
|
||||
20,
|
||||
'test',
|
||||
'... text. It is a <span class="highlight">test</span>'
|
||||
],
|
||||
[
|
||||
// Retains case of original string
|
||||
'This is some test text. Test test what if you have multiple keywords.',
|
||||
50,
|
||||
'some test',
|
||||
'This is <span class="highlight">some</span> <span class="highlight">test</span> text.'
|
||||
. ' <span class="highlight">Test</span> <span class="highlight">test</span> what if you have...'
|
||||
],
|
||||
[
|
||||
'Here is some text & HTML included',
|
||||
20,
|
||||
'html',
|
||||
'... text & <span class="highlight">HTML</span> inc...'
|
||||
],
|
||||
[
|
||||
'A dog ate a cat while looking at a Foobar',
|
||||
100,
|
||||
'a',
|
||||
// test that it does not highlight too much (eg every a)
|
||||
'A dog ate a cat while looking at a Foobar',
|
||||
],
|
||||
[
|
||||
'A dog ate a cat while looking at a Foobar',
|
||||
100,
|
||||
'ate',
|
||||
// it should highlight 3 letters or more.
|
||||
'A dog <span class="highlight">ate</span> a cat while looking at a Foobar',
|
||||
],
|
||||
|
||||
// HTML Content is plain-textified, and incorrect tags removed
|
||||
[
|
||||
'<p>A dog ate a cat while <span class="highlight">looking</span> at a Foobar</p>',
|
||||
100,
|
||||
'ate',
|
||||
// it should highlight 3 letters or more.
|
||||
'A dog <span class="highlight">ate</span> a cat while looking at a Foobar',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerContextSummary
|
||||
* @param string $originalValue Input
|
||||
* @param int $limit Numer of characters
|
||||
* @param string $keywords Keywords to highlight
|
||||
* @param string $expectedValue Expected output (XML encoded safely)
|
||||
*/
|
||||
public function testContextSummary($originalValue, $limit, $keywords, $expectedValue)
|
||||
{
|
||||
$text = DBField::create_field('HTMLFragment', $originalValue);
|
||||
$result = $text->obj('ContextSummary', [$limit, $keywords])->forTemplate();
|
||||
// it should highlight 3 letters or more.
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
public function testRAW() {
|
||||
$data = DBField::create_field('HTMLText', 'This & This');
|
||||
$this->assertEquals($data->RAW(), 'This & This');
|
||||
$data = DBField::create_field('HTMLFragment', 'This & This');
|
||||
$this->assertEquals('This & This', $data->RAW());
|
||||
|
||||
$data = DBField::create_field('HTMLText', 'This & This');
|
||||
$this->assertEquals($data->RAW(), 'This & This');
|
||||
$data = DBField::create_field('HTMLFragment', 'This & This');
|
||||
$this->assertEquals('This & This', $data->RAW());
|
||||
}
|
||||
|
||||
public function testXML() {
|
||||
$data = DBField::create_field('HTMLText', 'This & This');
|
||||
$this->assertEquals($data->XML(), 'This & This');
|
||||
$data = DBField::create_field('HTMLFragment', 'This & This');
|
||||
$this->assertEquals('This & This', $data->XML());
|
||||
$data = DBField::create_field('HTMLFragment', 'This & This');
|
||||
$this->assertEquals('This &amp; This', $data->XML());
|
||||
}
|
||||
|
||||
public function testHTML() {
|
||||
$data = DBField::create_field('HTMLText', 'This & This');
|
||||
$this->assertEquals($data->HTML(), 'This & This');
|
||||
$data = DBField::create_field('HTMLFragment', 'This & This');
|
||||
$this->assertEquals('This & This', $data->HTML());
|
||||
$data = DBField::create_field('HTMLFragment', 'This & This');
|
||||
$this->assertEquals('This &amp; This', $data->HTML());
|
||||
}
|
||||
|
||||
public function testJS() {
|
||||
$data = DBField::create_field('HTMLText', '"this is a test"');
|
||||
$this->assertEquals($data->JS(), '\"this is a test\"');
|
||||
$data = DBField::create_field('HTMLText', '"this is & test"');
|
||||
$this->assertEquals('\"this is \x26amp; test\"', $data->JS());
|
||||
}
|
||||
|
||||
public function testATT() {
|
||||
$data = DBField::create_field('HTMLText', '"this is a test"');
|
||||
$this->assertEquals($data->ATT(), '"this is a test"');
|
||||
// HTML Fragment
|
||||
$data = DBField::create_field('HTMLFragment', '"this is a test"');
|
||||
$this->assertEquals('"this is a test"', $data->ATT());
|
||||
|
||||
// HTML Text (passes shortcodes + tidy)
|
||||
$data = DBField::create_field('HTMLText', '"');
|
||||
$this->assertEquals('"', $data->ATT());
|
||||
}
|
||||
|
||||
public function testShortcodesProcessed()
|
||||
{
|
||||
/** @var DBHTMLText $obj */
|
||||
$obj = DBField::create_field(
|
||||
'HTMLText',
|
||||
'<p>Some content <strong>[test_shortcode]</strong> with shortcode</p>'
|
||||
);
|
||||
// Basic DBField methods process shortcodes
|
||||
$this->assertEquals(
|
||||
'Some content shortcode content with shortcode',
|
||||
$obj->Plain()
|
||||
);
|
||||
$this->assertEquals(
|
||||
'<p>Some content <strong>shortcode content</strong> with shortcode</p>',
|
||||
$obj->RAW()
|
||||
);
|
||||
$this->assertEquals(
|
||||
'<p>Some content <strong>shortcode content</strong> with shortcode</p>',
|
||||
$obj->XML()
|
||||
);
|
||||
$this->assertEquals(
|
||||
'<p>Some content <strong>shortcode content</strong> with shortcode</p>',
|
||||
$obj->HTML()
|
||||
);
|
||||
// Test summary methods
|
||||
$this->assertEquals(
|
||||
'Some content shortcode...',
|
||||
$obj->Summary(3)
|
||||
);
|
||||
$this->assertEquals(
|
||||
'Some content shortcode content with shortcode',
|
||||
$obj->LimitSentences(1)
|
||||
);
|
||||
$this->assertEquals(
|
||||
'Some content shortco...',
|
||||
$obj->LimitCharacters(20)
|
||||
);
|
||||
}
|
||||
|
||||
public function testParse() {
|
||||
// Test parse
|
||||
/** @var DBHTMLText $obj */
|
||||
$obj = DBField::create_field(
|
||||
'HTMLText',
|
||||
'<p>[b]Some content[/b] [test_shortcode] with shortcode</p>'
|
||||
);
|
||||
|
||||
// BBCode strips HTML and applies own formatting
|
||||
$this->assertEquals(
|
||||
'<strong>Some content</strong> shortcode content with shortcode',
|
||||
$obj->Parse('BBCodeParser')->forTemplate()
|
||||
);
|
||||
}
|
||||
|
||||
function testExists() {
|
||||
@ -322,3 +565,15 @@ class DBHTMLTextTest extends SapphireTest {
|
||||
ShortcodeParser::set_active('default');
|
||||
}
|
||||
}
|
||||
|
||||
class DBHTMLTextTest_Shortcode implements ShortcodeHandler, TestOnly {
|
||||
public static function get_shortcodes()
|
||||
{
|
||||
return 'test';
|
||||
}
|
||||
|
||||
public static function handle_shortcode($arguments, $content, $parser, $shortcode, $extra = array())
|
||||
{
|
||||
return 'shortcode content';
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ use SilverStripe\ORM\FieldType\DBField;
|
||||
|
||||
|
||||
/**
|
||||
* Tests parsing and summary methods on DBText
|
||||
*
|
||||
* @package framework
|
||||
* @subpackage tests
|
||||
*/
|
||||
@ -15,211 +17,224 @@ class DBTextTest extends SapphireTest {
|
||||
/**
|
||||
* Test {@link Text->LimitCharacters()}
|
||||
*/
|
||||
public function testLimitCharacters() {
|
||||
$cases = array(
|
||||
'The little brown fox jumped over the lazy cow.' => 'The little brown fox...',
|
||||
'<p>This is some text in a paragraph.</p>' => '<p>This is some text...'
|
||||
);
|
||||
public function providerLimitCharacters()
|
||||
{
|
||||
// Plain text values always encoded safely
|
||||
// HTML stored in non-html fields is treated literally.
|
||||
return [
|
||||
['The little brown fox jumped over the lazy cow.', 'The little brown fox...'],
|
||||
['<p>Short & Sweet</p>', '<p>Short & Sweet</p>'],
|
||||
['This text contains & in it', 'This text contains &...'],
|
||||
];
|
||||
}
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = new DBText('Test');
|
||||
$textObj->setValue($originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->LimitCharacters());
|
||||
}
|
||||
/**
|
||||
* Test {@link Text->LimitCharacters()}
|
||||
* @dataProvider providerLimitCharacters
|
||||
* @param string $originalValue
|
||||
* @param string $expectedValue
|
||||
*/
|
||||
public function testLimitCharacters($originalValue, $expectedValue) {
|
||||
$textObj = DBField::create_field('Text', $originalValue);
|
||||
$result = $textObj->obj('LimitCharacters')->forTemplate();
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerLimitCharactersToClosestWord()
|
||||
{
|
||||
return [
|
||||
// Standard words limited, ellipsis added if truncated
|
||||
['Lorem ipsum dolor sit amet', 24, 'Lorem ipsum dolor sit...'],
|
||||
|
||||
// Complete words less than the character limit don't get truncated, ellipsis not added
|
||||
['Lorem ipsum', 24, 'Lorem ipsum'],
|
||||
['Lorem', 24, 'Lorem'],
|
||||
['', 24, ''], // No words produces nothing!
|
||||
|
||||
// Special characters are encoded safely
|
||||
['Nice & Easy', 24, 'Nice & Easy'],
|
||||
|
||||
// HTML stored in non-html fields is treated literally.
|
||||
// If storing HTML you should use DBHTMLText instead
|
||||
['<p>Lorem ipsum dolor sit amet</p>', 24, '<p>Lorem ipsum dolor...'],
|
||||
['<p><span>Lorem ipsum dolor sit amet</span></p>', 24, '<p><span>Lorem ipsum...'],
|
||||
['<p>Lorem ipsum</p>', 24, '<p>Lorem ipsum</p>'],
|
||||
['Lorem & ipsum dolor sit amet', 24, 'Lorem &amp; ipsum dolor...']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link Text->LimitCharactersToClosestWord()}
|
||||
* @dataProvider providerLimitCharactersToClosestWord
|
||||
*
|
||||
* @param string $originalValue Raw string input
|
||||
* @param int $limit
|
||||
* @param string $expectedValue Expected template value
|
||||
*/
|
||||
public function testLimitCharactersToClosestWord() {
|
||||
$cases = array(
|
||||
/* Standard words limited, ellipsis added if truncated */
|
||||
'Lorem ipsum dolor sit amet' => 'Lorem ipsum dolor sit...',
|
||||
|
||||
/* Complete words less than the character limit don't get truncated, ellipsis not added */
|
||||
'Lorem ipsum' => 'Lorem ipsum',
|
||||
'Lorem' => 'Lorem',
|
||||
'' => '', // No words produces nothing!
|
||||
|
||||
/* HTML tags get stripped out, leaving the raw text */
|
||||
'<p>Lorem ipsum dolor sit amet</p>' => 'Lorem ipsum dolor sit...',
|
||||
'<p><span>Lorem ipsum dolor sit amet</span></p>' => 'Lorem ipsum dolor sit...',
|
||||
'<p>Lorem ipsum</p>' => 'Lorem ipsum',
|
||||
|
||||
/* HTML entities are treated as a single character */
|
||||
'Lorem & ipsum dolor sit amet' => 'Lorem & ipsum dolor...'
|
||||
);
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = new DBText('Test');
|
||||
$textObj->setValue($originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->LimitCharactersToClosestWord(24));
|
||||
}
|
||||
public function testLimitCharactersToClosestWord($originalValue, $limit, $expectedValue) {
|
||||
$textObj = DBField::create_field('Text', $originalValue);
|
||||
$result = $textObj->obj('LimitCharactersToClosestWord', [$limit])->forTemplate();
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link Text->LimitWordCount()}
|
||||
*/
|
||||
public function testLimitWordCount() {
|
||||
$cases = array(
|
||||
/* Standard words limited, ellipsis added if truncated */
|
||||
'The little brown fox jumped over the lazy cow.' => 'The little brown...',
|
||||
' This text has white space around the ends ' => 'This text has...',
|
||||
public function providerLimitWordCount() {
|
||||
return [
|
||||
// Standard words limited, ellipsis added if truncated
|
||||
['The little brown fox jumped over the lazy cow.', 3, 'The little brown...'],
|
||||
[' This text has white space around the ends ', 3, 'This text has...'],
|
||||
|
||||
/* Words less than the limt word count don't get truncated, ellipsis not added */
|
||||
'Two words' => 'Two words', // Two words shouldn't have an ellipsis
|
||||
'One' => 'One', // Neither should one word
|
||||
'' => '', // No words produces nothing!
|
||||
// Words less than the limt word count don't get truncated, ellipsis not added
|
||||
['Two words', 3, 'Two words'], // Two words shouldn't have an ellipsis
|
||||
['These three words', 3, 'These three words'], // Three words shouldn't have an ellipsis
|
||||
['One', 3, 'One'], // Neither should one word
|
||||
['', 3, ''], // No words produces nothing!
|
||||
|
||||
/* HTML tags get stripped out, leaving the raw text */
|
||||
'<p>Text inside a paragraph tag should also work</p>' => 'Text inside a...',
|
||||
'<p><span>Text nested inside another tag should also work</span></p>' => 'Text nested inside...',
|
||||
'<p>Two words</p>' => 'Two words'
|
||||
);
|
||||
// Text with special characters
|
||||
['Nice & Easy', 3, 'Nice & Easy'],
|
||||
['One & Two & Three', 3, 'One & Two...'],
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = new DBText('Test');
|
||||
$textObj->setValue($originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->LimitWordCount(3));
|
||||
}
|
||||
// HTML stored in non-html fields is treated literally.
|
||||
// If storing HTML you should use DBHTMLText instead
|
||||
['<p>Text inside a paragraph tag should also work</p>', 3, '<p>Text inside a...'],
|
||||
['<p>Two words</p>', 3, '<p>Two words</p>'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link Text->LimitWordCountXML()}
|
||||
* Test {@link DBText->LimitWordCount()}
|
||||
* @dataProvider providerLimitWordCount
|
||||
*
|
||||
* @param string $originalValue Raw string input
|
||||
* @param int $limit Number of words
|
||||
* @param string $expectedValue Expected template value
|
||||
*/
|
||||
public function testLimitWordCountXML() {
|
||||
$cases = array(
|
||||
'<p>Stuff & stuff</p>' => 'Stuff &...',
|
||||
"Stuff\nBlah Blah Blah" => "Stuff\nBlah Blah...",
|
||||
"Stuff<Blah Blah" => "Stuff<Blah Blah",
|
||||
"Stuff>Blah Blah" => "Stuff>Blah Blah"
|
||||
);
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = new DBText('Test');
|
||||
$textObj->setValue($originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->LimitWordCountXML(3));
|
||||
}
|
||||
public function testLimitWordCount($originalValue, $limit, $expectedValue) {
|
||||
$textObj = DBField::create_field('Text', $originalValue);
|
||||
$result = $textObj->obj('LimitWordCount', [$limit])->forTemplate();
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link Text->LimitSentences()}
|
||||
*/
|
||||
public function testLimitSentences() {
|
||||
$cases = array(
|
||||
'' => '',
|
||||
'First sentence.' => 'First sentence.',
|
||||
'First sentence. Second sentence' => 'First sentence. Second sentence.',
|
||||
'<p>First sentence.</p>' => 'First sentence.',
|
||||
'<p>First sentence. Second sentence. Third sentence</p>' => 'First sentence. Second sentence.',
|
||||
'<p>First sentence. <em>Second sentence</em>. Third sentence</p>' => 'First sentence. Second sentence.',
|
||||
'<p>First sentence. <em class="dummyClass">Second sentence</em>. Third sentence</p>'
|
||||
=> 'First sentence. Second sentence.'
|
||||
);
|
||||
public function providerLimitSentences()
|
||||
{
|
||||
return [
|
||||
['', 2, ''],
|
||||
['First sentence.', 2, 'First sentence.'],
|
||||
['First sentence. Second sentence.', 2, 'First sentence. Second sentence.'],
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = new DBText('Test');
|
||||
$textObj->setValue($originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->LimitSentences(2));
|
||||
}
|
||||
}
|
||||
|
||||
public function testFirstSentance() {
|
||||
$cases = array(
|
||||
'' => '',
|
||||
'First sentence.' => 'First sentence.',
|
||||
'First sentence. Second sentence' => 'First sentence.',
|
||||
'First sentence? Second sentence' => 'First sentence?',
|
||||
'First sentence! Second sentence' => 'First sentence!',
|
||||
'<p>First sentence.</p>' => 'First sentence.',
|
||||
'<p>First sentence. Second sentence. Third sentence</p>' => 'First sentence.',
|
||||
'<p>First sentence. <em>Second sentence</em>. Third sentence</p>' => 'First sentence.',
|
||||
'<p>First sentence. <em class="dummyClass">Second sentence</em>. Third sentence</p>'
|
||||
=> 'First sentence.'
|
||||
);
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = new DBText('Test');
|
||||
$textObj->setValue($originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->FirstSentence());
|
||||
}
|
||||
// HTML stored in non-html fields is treated literally.
|
||||
// If storing HTML you should use DBHTMLText instead
|
||||
['<p>First sentence.</p>', 2, '<p>First sentence.</p>'],
|
||||
['<p>First sentence. Second sentence. Third sentence</p>', 2, '<p>First sentence. Second sentence.'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link Text->BigSummary()}
|
||||
*/
|
||||
public function testBigSummaryPlain() {
|
||||
$cases = array(
|
||||
'<p>This text has multiple sentences. Big Summary uses this to split sentences up.</p>'
|
||||
=> 'This text has multiple...',
|
||||
'This text does not have multiple sentences' => 'This text does not...',
|
||||
'Very short' => 'Very short',
|
||||
'' => ''
|
||||
);
|
||||
* Test {@link DBText->LimitSentences()}
|
||||
*
|
||||
* @dataProvider providerLimitSentences
|
||||
* @param string $originalValue
|
||||
* @param int $limit Number of sentences
|
||||
* @param string $expectedValue Expected template value
|
||||
*/
|
||||
public function testLimitSentences($originalValue, $limit, $expectedValue) {
|
||||
$textObj = DBField::create_field('Text', $originalValue);
|
||||
$result = $textObj->obj('LimitSentences', [$limit])->forTemplate();
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = DBField::create_field('Text', $originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->BigSummary(4, true));
|
||||
}
|
||||
public function providerFirstSentence()
|
||||
{
|
||||
return [
|
||||
['', ''],
|
||||
['First sentence.', 'First sentence.'],
|
||||
['First sentence. Second sentence', 'First sentence.'],
|
||||
['First sentence? Second sentence', 'First sentence?'],
|
||||
['First sentence! Second sentence', 'First sentence!'],
|
||||
|
||||
// HTML stored in non-html fields is treated literally.
|
||||
// If storing HTML you should use DBHTMLText instead
|
||||
['<br />First sentence.', '<br />First sentence.'],
|
||||
['<p>First sentence. Second sentence. Third sentence</p>', '<p>First sentence.'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link Text->BigSummary()}
|
||||
*/
|
||||
public function testBigSummary() {
|
||||
$cases = array(
|
||||
'<strong>This</strong> text has multiple sentences. Big Summary uses this to split sentences up.</p>'
|
||||
=> '<strong>This</strong> text has multiple...',
|
||||
'This text does not have multiple sentences' => 'This text does not...',
|
||||
'Very short' => 'Very short',
|
||||
'' => ''
|
||||
);
|
||||
|
||||
foreach($cases as $originalValue => $expectedValue) {
|
||||
$textObj = DBField::create_field('Text', $originalValue);
|
||||
$this->assertEquals($expectedValue, $textObj->BigSummary(4, false));
|
||||
}
|
||||
* @dataProvider providerFirstSentence
|
||||
* @param string $originalValue
|
||||
* @param string $expectedValue
|
||||
*/
|
||||
public function testFirstSentence($originalValue, $expectedValue) {
|
||||
$textObj = DBField::create_field('Text', $originalValue);
|
||||
$result = $textObj->obj('FirstSentence')->forTemplate();
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
public function testContextSummary() {
|
||||
$testString1 = '<p>This is some text. It is a test</p>';
|
||||
$testKeywords1 = 'test';
|
||||
|
||||
$testString2 = '<p>This is some test text. Test test what if you have multiple keywords.</p>';
|
||||
$testKeywords2 = 'some test';
|
||||
|
||||
$testString3 = '<p>A dog ate a cat while looking at a Foobar</p>';
|
||||
$testKeyword3 = 'a';
|
||||
$testKeyword3a = 'ate';
|
||||
|
||||
$textObj = DBField::create_field('Text', $testString1, 'Text');
|
||||
|
||||
$this->assertEquals(
|
||||
'... text. It is a <span class="highlight">test</span>...',
|
||||
$textObj->ContextSummary(20, $testKeywords1)
|
||||
);
|
||||
|
||||
$textObj->setValue($testString2);
|
||||
|
||||
$this->assertEquals(
|
||||
'This is <span class="highlight">some</span> <span class="highlight">test</span> text.'
|
||||
. ' <span class="highlight">test</span> <span class="highlight">test</span> what if you have...',
|
||||
$textObj->ContextSummary(50, $testKeywords2)
|
||||
);
|
||||
|
||||
$textObj->setValue($testString3);
|
||||
|
||||
// test that it does not highlight too much (eg every a)
|
||||
$this->assertEquals(
|
||||
'A dog ate a cat while looking at a Foobar',
|
||||
$textObj->ContextSummary(100, $testKeyword3)
|
||||
);
|
||||
/**
|
||||
* each test is in the format input, charactere limit, highlight, expected output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerContextSummary()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'This is some text. It is a test',
|
||||
20,
|
||||
'test',
|
||||
'... text. It is a <span class="highlight">test</span>'
|
||||
],
|
||||
[
|
||||
// Retains case of original string
|
||||
'This is some test text. Test test what if you have multiple keywords.',
|
||||
50,
|
||||
'some test',
|
||||
'This is <span class="highlight">some</span> <span class="highlight">test</span> text.'
|
||||
. ' <span class="highlight">Test</span> <span class="highlight">test</span> what if you have...'
|
||||
],
|
||||
[
|
||||
'Here is some text & HTML included',
|
||||
20,
|
||||
'html',
|
||||
'... text & <span class="highlight">HTML</span> inc...'
|
||||
],
|
||||
[
|
||||
'A dog ate a cat while looking at a Foobar',
|
||||
100,
|
||||
'a',
|
||||
// test that it does not highlight too much (eg every a)
|
||||
'A dog ate a cat while looking at a Foobar',
|
||||
],
|
||||
[
|
||||
'A dog ate a cat while looking at a Foobar',
|
||||
100,
|
||||
'ate',
|
||||
// it should highlight 3 letters or more.
|
||||
'A dog <span class="highlight">ate</span> a cat while looking at a Foobar',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerContextSummary
|
||||
* @param string $originalValue Input
|
||||
* @param int $limit Numer of characters
|
||||
* @param string $keywords Keywords to highlight
|
||||
* @param string $expectedValue Expected output (XML encoded safely)
|
||||
*/
|
||||
public function testContextSummary($originalValue, $limit, $keywords, $expectedValue)
|
||||
{
|
||||
$text = DBField::create_field('Text', $originalValue);
|
||||
$result = $text->obj('ContextSummary', [$limit, $keywords])->forTemplate();
|
||||
// it should highlight 3 letters or more.
|
||||
$this->assertEquals(
|
||||
'A dog <span class="highlight">ate</span> a cat while looking at a Foobar',
|
||||
$textObj->ContextSummary(100, $testKeyword3a)
|
||||
);
|
||||
$this->assertEquals($expectedValue, $result);
|
||||
}
|
||||
|
||||
public function testRAW() {
|
||||
|
@ -159,7 +159,7 @@ class DatabaseTest extends SapphireTest {
|
||||
}
|
||||
|
||||
public function testTransactions() {
|
||||
$conn = DB::getConn();
|
||||
$conn = DB::get_conn();
|
||||
if(!$conn->supportsTransactions()) {
|
||||
$this->markTestSkipped("DB Doesn't support transactions");
|
||||
return;
|
||||
|
@ -24,8 +24,8 @@ class ViewableDataTest extends SapphireTest {
|
||||
$this->assertEquals($htmlString, $htmlField->obj('ATT')->forTemplate());
|
||||
$this->assertEquals($textString, $htmlField->obj('RAW')->forTemplate());
|
||||
$this->assertEquals('\"', $htmlField->obj('JS')->forTemplate());
|
||||
$this->assertEquals($textString, $htmlField->obj('HTML')->forTemplate());
|
||||
$this->assertEquals($textString, $htmlField->obj('XML')->forTemplate());
|
||||
$this->assertEquals($htmlString, $htmlField->obj('HTML')->forTemplate());
|
||||
$this->assertEquals($htmlString, $htmlField->obj('XML')->forTemplate());
|
||||
|
||||
$textField = DBField::create_field('Text', $textString);
|
||||
$this->assertEquals($htmlString, $textField->forTemplate());
|
||||
|
Loading…
Reference in New Issue
Block a user