Skip to content

Commit 8e03a5a

Browse files
committed
Merge branch 'develop'
2 parents 7e01f16 + dc2b568 commit 8e03a5a

18 files changed

+248
-70
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ before_script:
4848
script:
4949
- if [ $DEFAULT -eq 1 ]; then vendor/bin/phpunit --exclude-group deprecated,tld --stderr; fi
5050
- if [ $TLD_TEST -eq 1 ]; then vendor/bin/phpunit --group tld --stderr; fi
51-
- if [ $PHPCS -eq 1 ]; then vendor/bin/phpcs -psn --extensions=php --standard=PSR2 ./lib ./tests; fi
51+
- if [ $PHPCS -eq 1 ]; then vendor/bin/phpcs -psn --extensions=php --standard=PSR12 ./lib ./tests; fi
5252
- if [ $CODECOVERAGE -eq 1 ]; then vendor/bin/phpunit --exclude-group deprecated,tld --stderr --coverage-clover=coverage.xml; fi
5353

5454
after_success:

build/build-emoji-regex.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
require dirname(__DIR__) . '/vendor/autoload.php';
44

55
$classFile = dirname(__DIR__) . '/lib/Twitter/Text/EmojiRegex.php';
6-
$emojiDataUrl = 'https://www.unicode.org/Public/emoji/11.0/emoji-test.txt';
6+
$emojiDataUrl = 'https://www.unicode.org/Public/emoji/12.1/emoji-test.txt';
77

88
// --
99
$emojiData = file($emojiDataUrl);

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
"type": "package",
3232
"package": {
3333
"name": "twitter/twitter-text",
34-
"version": "3.0.0",
34+
"version": "3.1.0",
3535
"source": {
3636
"url": "https://github.com/twitter/twitter-text.git",
3737
"type": "git",
38-
"reference": "v3.0.0"
38+
"reference": "v3.1.0"
3939
}
4040
}
4141
}

lib/Twitter/Text/Autolink.php

Lines changed: 77 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -93,23 +93,11 @@ class Autolink
9393
protected $url_base_cash = 'https://twitter.com/search?q=%24';
9494

9595
/**
96-
* Whether to include the value 'nofollow' in the 'rel' attribute.
97-
*
98-
* @var bool
99-
*/
100-
protected $nofollow = true;
101-
102-
/**
103-
* Whether to include the value 'external' in the 'rel' attribute.
96+
* the 'rel' attribute values.
10497
*
105-
* Often this is used to be matched on in JavaScript for dynamically adding
106-
* the 'target' attribute which is deprecated in HTML 4.01. In HTML 5 it has
107-
* been undeprecated and thus the 'target' attribute can be used. If this is
108-
* set to false then the 'target' attribute will be output.
109-
*
110-
* @var bool
98+
* @var array
11199
*/
112-
protected $external = true;
100+
protected $rel = array('external', 'nofollow');
113101

114102
/**
115103
* The scope to open the link in.
@@ -209,6 +197,24 @@ public function __construct($tweet = null, $escape = true, $full_encode = false)
209197
$this->extractor = Extractor::create();
210198
}
211199

200+
/**
201+
* Set CSS class to all link types.
202+
*
203+
* @param string $v CSS class for links.
204+
*
205+
* @return Autolink Fluid method chaining.
206+
*/
207+
public function setToAllLinkClasses($v)
208+
{
209+
$this->setURLClass($v);
210+
$this->setUsernameClass($v);
211+
$this->setListClass($v);
212+
$this->setHashtagClass($v);
213+
$this->setCashtagClass($v);
214+
215+
return $this;
216+
}
217+
212218
/**
213219
* CSS class for auto-linked URLs.
214220
*
@@ -331,7 +337,7 @@ public function setCashtagClass($v)
331337
*/
332338
public function getNoFollow()
333339
{
334-
return $this->nofollow;
340+
return in_array('nofollow', $this->rel, true);
335341
}
336342

337343
/**
@@ -343,7 +349,15 @@ public function getNoFollow()
343349
*/
344350
public function setNoFollow($v)
345351
{
346-
$this->nofollow = $v;
352+
if ($v && !$this->getNoFollow()) {
353+
$this->setRel('nofollow', true);
354+
}
355+
if (!$v && $this->getNoFollow()) {
356+
$this->rel = array_filter($this->rel, function ($r) {
357+
return $r !== 'nofollow';
358+
});
359+
}
360+
347361
return $this;
348362
}
349363

@@ -359,7 +373,7 @@ public function setNoFollow($v)
359373
*/
360374
public function getExternal()
361375
{
362-
return $this->external;
376+
return in_array('external', $this->rel, true);
363377
}
364378

365379
/**
@@ -376,7 +390,15 @@ public function getExternal()
376390
*/
377391
public function setExternal($v)
378392
{
379-
$this->external = $v;
393+
if ($v && !$this->getExternal()) {
394+
$this->setRel('external', true);
395+
}
396+
if (!$v && $this->getExternal()) {
397+
$this->rel = array_filter($this->rel, function ($r) {
398+
return $r !== 'external';
399+
});
400+
}
401+
380402
return $this;
381403
}
382404

@@ -822,15 +844,9 @@ public function linkToCashtag($entity, $tweet = null)
822844
*/
823845
public function linkToText(array $entity, $text, $attributes = array())
824846
{
825-
$rel = array();
826-
if ($this->external) {
827-
$rel[] = 'external';
828-
}
829-
if ($this->nofollow) {
830-
$rel[] = 'nofollow';
831-
}
832-
if (!empty($rel)) {
833-
$attributes['rel'] = implode(' ', $rel);
847+
$rel = $this->getRel();
848+
if ($rel !== '') {
849+
$attributes['rel'] = $rel;
834850
}
835851
if ($this->target) {
836852
$attributes['target'] = $this->target;
@@ -872,6 +888,39 @@ protected function linkToTextWithSymbol(array $entity, $symbol, $linkText, array
872888
return $this->linkToText($entity, $linkText, $attributes);
873889
}
874890

891+
/**
892+
* get rel attribute
893+
*
894+
* @return string
895+
*/
896+
public function getRel()
897+
{
898+
$rel = $this->rel;
899+
$rel = array_unique($rel);
900+
901+
return implode(' ', $rel);
902+
}
903+
904+
/**
905+
* Set rel attribute.
906+
*
907+
* This method override setExternal/setNoFollow setting.
908+
*
909+
* @param string[]|string $rel the rel attribute
910+
* @param bool $merge if true, merge rel attributes instead replace.
911+
* @return $this
912+
*/
913+
public function setRel($rel, $merge = false)
914+
{
915+
if (is_string($rel)) {
916+
$rel = explode(' ', $rel);
917+
}
918+
919+
$this->rel = $merge ? array_unique(array_merge($this->rel, $rel)) : $rel;
920+
921+
return $this;
922+
}
923+
875924
/**
876925
* html escape
877926
*

lib/Twitter/Text/EmojiRegex.php

Lines changed: 7 additions & 6 deletions
Large diffs are not rendered by default.

lib/Twitter/Text/Extractor.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,10 @@ public function extractURLsWithIndices($tweet)
349349
// If protocol is missing and domain contains non-ASCII characters,
350350
// extract ASCII-only domains.
351351
if (empty($protocol)) {
352-
if (!$this->extractURLWithoutProtocol
353-
|| preg_match(Regex::getInvalidUrlWithoutProtocolPrecedingCharsMatcher(), $before)) {
352+
if (
353+
!$this->extractURLWithoutProtocol
354+
|| preg_match(Regex::getInvalidUrlWithoutProtocolPrecedingCharsMatcher(), $before)
355+
) {
354356
continue;
355357
}
356358

@@ -359,8 +361,10 @@ public function extractURLsWithIndices($tweet)
359361

360362
if (preg_match(Regex::getValidAsciiDomainMatcher(), $domain, $asciiDomain)) {
361363
// check hostname length
362-
if (isset($asciiDomain[1])
363-
&& strlen(rtrim($asciiDomain[1], '.')) > static::MAX_ASCII_HOSTNAME_LENGTH) {
364+
if (
365+
isset($asciiDomain[1])
366+
&& strlen(rtrim($asciiDomain[1], '.')) > static::MAX_ASCII_HOSTNAME_LENGTH
367+
) {
364368
continue;
365369
}
366370

@@ -374,9 +378,11 @@ public function extractURLsWithIndices($tweet)
374378
$start_position + $ascii_end_position
375379
),
376380
);
377-
if (!empty($path)
381+
if (
382+
!empty($path)
378383
|| preg_match(Regex::getValidSpecialShortDomainMatcher(), $asciiDomain[0])
379-
|| !preg_match(Regex::getInvalidCharactersMatcher(), $asciiDomain[0])) {
384+
|| !preg_match(Regex::getInvalidCharactersMatcher(), $asciiDomain[0])
385+
) {
380386
$urls[] = $last_url;
381387
}
382388
}

lib/Twitter/Text/ParseResults.php

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,25 @@ public function __get($name)
119119
*/
120120
public function __set($name, $value)
121121
{
122-
if ($name === 'displayRangeStart'
123-
&& $this->lte($value, $this->displayTextRange[1], $name, 'displayRangeEnd')) {
122+
if (
123+
$name === 'displayRangeStart'
124+
&& $this->lte($value, $this->displayTextRange[1], $name, 'displayRangeEnd')
125+
) {
124126
$this->displayTextRange[0] = (int)$value;
125-
} elseif ($name === 'displayRangeEnd'
126-
&& $this->gte($value, $this->displayTextRange[0], $name, 'displayRangeStart')) {
127+
} elseif (
128+
$name === 'displayRangeEnd'
129+
&& $this->gte($value, $this->displayTextRange[0], $name, 'displayRangeStart')
130+
) {
127131
$this->displayTextRange[1] = (int)$value;
128-
} elseif ($name === 'validRangeStart'
129-
&& $this->lte($value, $this->validTextRange[1], $name, 'validRangeEnd')) {
132+
} elseif (
133+
$name === 'validRangeStart'
134+
&& $this->lte($value, $this->validTextRange[1], $name, 'validRangeEnd')
135+
) {
130136
$this->validTextRange[0] = (int)$value;
131-
} elseif ($name === 'validRangeEnd'
132-
&& $this->gte($value, $this->validTextRange[0], $name, 'validRangeStart')) {
137+
} elseif (
138+
$name === 'validRangeEnd'
139+
&& $this->gte($value, $this->validTextRange[0], $name, 'validRangeStart')
140+
) {
133141
$this->validTextRange[1] = (int)$value;
134142
} elseif ($name === 'valid') {
135143
$this->result[$name] = (bool)$value;

lib/Twitter/Text/Parser.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function __construct(Configuration $config = null)
5858
public function parseTweet($tweet)
5959
{
6060
if ($tweet === null || '' === $tweet) {
61-
return new ParseResults;
61+
return new ParseResults();
6262
}
6363

6464
$normalizedTweet = StringUtils::normalizeFromNFC($tweet);
@@ -96,7 +96,7 @@ public function parseTweet($tweet)
9696
$emojiLength = StringUtils::strlen($emoji);
9797
$charCount = StringUtils::charCount($emoji);
9898

99-
$weightedCount += $this->getCharacterWeight(StringUtils::substr($emoji, 0, 1), $this->config);
99+
$weightedCount += $this->config->defaultWeight;
100100
$offset += $emojiLength;
101101
$displayOffset += $charCount;
102102
if ($weightedCount <= $maxWeightedTweetLength) {

lib/Twitter/Text/TldLists.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,7 +1619,7 @@ final public static function getValidGTLD()
16191619
}
16201620

16211621
$gTLD = implode('|', static::$gTLDs);
1622-
$regex = '(?:(?:' . $gTLD . ')(?=[^0-9a-z@]|$))';
1622+
$regex = '(?:(?:' . $gTLD . ')(?=[^0-9a-z@+-]|$))';
16231623

16241624
return $regex;
16251625
}
@@ -1639,7 +1639,7 @@ final public static function getValidCcTLD()
16391639
}
16401640

16411641
$ccTLD = implode('|', static::$ccTLDs);
1642-
$regex = '(?:(?:' . $ccTLD . ')(?=[^0-9a-z@]|$))';
1642+
$regex = '(?:(?:' . $ccTLD . ')(?=[^0-9a-z@+-]|$))';
16431643

16441644
return $regex;
16451645
}

lib/Twitter/Text/Validator.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,15 @@ public function isValidURL($url, $unicode_domains = true, $require_protocol = tr
188188
list($scheme, $authority, $path, $query, $fragment) = array_pad($matches, 5, '');
189189

190190
# Check scheme, path, query, fragment:
191-
if (($require_protocol && !(
191+
if (
192+
($require_protocol && !(
192193
self::isValidMatch($scheme, Regex::getValidateUrlSchemeMatcher())
193194
&& preg_match('/^https?$/i', $scheme)
194195
))
195196
|| !self::isValidMatch($path, Regex::getValidateUrlPathMatcher())
196197
|| !self::isValidMatch($query, Regex::getValidateUrlQueryMatcher(), true)
197-
|| !self::isValidMatch($fragment, Regex::getValidateUrlFragmentMatcher(), true)) {
198+
|| !self::isValidMatch($fragment, Regex::getValidateUrlFragmentMatcher(), true)
199+
) {
198200
return false;
199201
}
200202

0 commit comments

Comments
 (0)