Skip to content

Commit 4f42118

Browse files
author
Andrea Zanelli
committed
Update TwitterTextFormatter class with text templates and other things
1 parent 55f7ff6 commit 4f42118

1 file changed

Lines changed: 223 additions & 47 deletions

File tree

php-twitter-text-formatter/TwitterTextFormatter.php

Lines changed: 223 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
/**
66
* Twitter Text Formatter : format twitter timeline text in html.
77
*
8-
* @author Netgloo <info@netgloo.com>
9-
* @version 1.0
8+
* @author Netgloo <info@netgloo.com>
109
*/
1110
class TwitterTextFormatter {
1211

@@ -15,20 +14,102 @@ class TwitterTextFormatter {
1514
/**
1615
* Return the tweet text formatted with the tweet's entities.
1716
*
17+
* Default configs:
18+
*
19+
* $configs = [
20+
* 'show_retweeted_by' => true,
21+
*
22+
* 'retweeted_by_template' =>
23+
* '<em> Retweeted by {{user_name}}</em>',
24+
*
25+
* 'hashtag_link_template' =>
26+
* '<a href="{{hashtag_link}}" rel="nofollow" target="_blank">' .
27+
* '#{{hashtag_text}}</a>',
28+
*
29+
* 'url_link_template' =>
30+
* '<a href="{{url_link}}" rel="nofollow" target="_blank" ' .
31+
* 'title="{{url_title}}">{{url_text}}</a>',
32+
*
33+
* 'user_mention_link_template' =>
34+
* '<a href="{{user_mention_link}}" rel="nofollow" target="_blank" ' .
35+
* title="{{user_mention_title}}">@{{user_mention_text}}</a>',
36+
*
37+
* 'media_link_template' =>
38+
* '<a href="{{media_link}}" rel="nofollow" target="_blank" ' .
39+
* 'title="{{media_title}}">{{media_text}}</a>'
40+
* ];
41+
*
1842
* @param $tweet (Object)
43+
* @param $configs (Array)
1944
* @return (String)
2045
*/
21-
public static function format_text($tweet, $show_retweeted_by = true) {
46+
public static function format_text($tweet, $configs = []) {
47+
48+
// Set up configs
49+
50+
self::set_default(
51+
$configs,
52+
'show_retweeted_by',
53+
true
54+
);
2255

23-
// Retweeted
56+
self::set_default(
57+
$configs,
58+
'retweeted_by_template',
59+
'<em> Retweeted by {{user_name}}</em>'
60+
);
61+
62+
self::set_default(
63+
$configs,
64+
'hashtag_link_template',
65+
'<a href="{{hashtag_link}}" rel="nofollow" target="_blank">' .
66+
'#{{hashtag_text}}</a>'
67+
);
68+
69+
self::set_default(
70+
$configs,
71+
'url_link_template',
72+
'<a href="{{url_link}}" rel="nofollow" target="_blank" ' .
73+
'title="{{url_title}}">{{url_text}}</a>'
74+
);
75+
76+
self::set_default(
77+
$configs,
78+
'user_mention_link_template',
79+
'<a href="{{user_mention_link}}" rel="nofollow" target="_blank" ' .
80+
'title="{{user_mention_title}}">@{{user_mention_text}}</a>'
81+
);
82+
83+
self::set_default(
84+
$configs,
85+
'media_link_template',
86+
'<a href="{{media_link}}" rel="nofollow" target="_blank" ' .
87+
'title="{{media_title}}">{{media_text}}</a>'
88+
);
89+
90+
// Is retweeted?
2491
if (isset($tweet->retweeted_status)) {
92+
2593
$user_name = $tweet->user->name;
26-
$retweeted_by = $show_retweeted_by ?
27-
"<em> Retweeted by {$user_name}</em>" : '';
28-
return self::parse_tweet_text($tweet->retweeted_status) . $retweeted_by;
94+
$retweeted_by = '';
95+
96+
// If show retweeted by, then prepare the "retweeted by" text
97+
if ($configs['show_retweeted_by']) {
98+
$retweeted_by = $configs['retweeted_by_template'];
99+
$retweeted_by = str_replace(
100+
'{{user_name}}',
101+
$user_name,
102+
$retweeted_by
103+
);
104+
}
105+
106+
// Return the parsed re-tweet
107+
$res = self::parse_tweet_text($tweet->retweeted_status, $configs);
108+
return $res . $retweeted_by;
29109
}
30110

31-
return self::parse_tweet_text($tweet);
111+
// Return the parsed tweet
112+
return self::parse_tweet_text($tweet, $configs);
32113
}
33114

34115
// --------------------------------------------------------------------------
@@ -44,62 +125,136 @@ public static function format_text($tweet, $show_retweeted_by = true) {
44125
* Credits: this function is a modified version of the one from Jacob
45126
* Emerick's Blog (http://goo.gl/lhu8Ix)
46127
*/
47-
private static function parse_tweet_text($tweet) {
48-
49-
// Define patterns for each entity
50-
$hashtag_link_pattern =
51-
'<a href="http://twitter.com/search?q=%23{{1}}&src=hash" ' .
52-
'rel="nofollow" target="_blank">#{{2}}</a>';
53-
$url_link_pattern =
54-
'<a href="{{1}}" rel="nofollow" target="_blank" title="{{2}}">{{3}}</a>';
55-
$user_mention_link_pattern =
56-
'<a href="http://twitter.com/{{1}}" rel="nofollow" target="_blank" ' .
57-
'title="{{2}}">@{{3}}</a>';
58-
$media_link_pattern =
59-
'<a href="{{1}}" rel="nofollow" target="_blank" title="{{2}}">{{3}}</a>';
128+
private static function parse_tweet_text($tweet, $configs) {
60129

61130
// Collects the set of entities
62131
$entity_holder = array();
63132

133+
// Hashtags
64134
if (isset($tweet->entities->hashtags)) {
135+
136+
$template = $configs['hashtag_link_template'];
137+
65138
foreach ($tweet->entities->hashtags as $hashtag) {
66-
$replace = $hashtag_link_pattern;
67-
$replace = str_replace('{{1}}', strtolower($hashtag->text), $replace);
68-
$replace = str_replace('{{2}}', $hashtag->text, $replace);
139+
140+
// Link: https://twitter.com/hashtag/{{1}}?src=hash
141+
$hashtag_link = str_replace(
142+
'{{1}}',
143+
strtolower($hashtag->text),
144+
'https://twitter.com/hashtag/{{1}}?src=hash'
145+
);
146+
147+
$replace = str_replace(
148+
'{{hashtag_link}}',
149+
$hashtag_link,
150+
$template
151+
);
152+
153+
$replace = str_replace(
154+
'{{hashtag_text}}',
155+
$hashtag->text,
156+
$replace
157+
);
158+
69159
self::add_entity($entity_holder, $hashtag, $replace);
70-
}
71-
}
72160

161+
} // foreach
162+
163+
} // if
164+
165+
// Urls
73166
if (isset($tweet->entities->urls)) {
167+
168+
$template = $configs['url_link_template'];
169+
74170
foreach ($tweet->entities->urls as $url) {
75-
$replace = $url_link_pattern;
76-
$replace = str_replace('{{1}}', $url->url, $replace);
77-
$replace = str_replace('{{2}}', $url->expanded_url, $replace);
78-
$replace = str_replace('{{3}}', $url->display_url, $replace);
171+
172+
$replace = str_replace(
173+
'{{url_link}}',
174+
$url->url,
175+
$template
176+
);
177+
$replace = str_replace(
178+
'{{url_title}}',
179+
$url->expanded_url,
180+
$replace
181+
);
182+
$replace = str_replace(
183+
'{{url_text}}',
184+
$url->display_url,
185+
$replace
186+
);
187+
79188
self::add_entity($entity_holder, $url, $replace);
80-
}
81-
}
82189

190+
} // foreach
191+
192+
} // if
193+
194+
// User mentions
83195
if (isset($tweet->entities->user_mentions)) {
196+
197+
$template = $configs['user_mention_link_template'];
198+
84199
foreach ($tweet->entities->user_mentions as $user_mention) {
85-
$replace = $user_mention_link_pattern;
200+
201+
// Link: https://twitter.com/{{1}}
202+
$user_mention_link = str_replace(
203+
'{{1}}',
204+
strtolower($user_mention->screen_name),
205+
'https://twitter.com/{{1}}'
206+
);
207+
208+
$replace = str_replace(
209+
'{{user_mention_link}}',
210+
$user_mention_link,
211+
$template
212+
);
86213
$replace = str_replace(
87-
'{{1}}', strtolower($user_mention->screen_name), $replace);
88-
$replace = str_replace('{{2}}', $user_mention->name, $replace);
89-
$replace = str_replace('{{3}}', $user_mention->screen_name, $replace);
214+
'{{user_mention_title}}',
215+
$user_mention->name,
216+
$replace
217+
);
218+
$replace = str_replace(
219+
'{{user_mention_text}}',
220+
$user_mention->screen_name,
221+
$replace
222+
);
223+
90224
self::add_entity($entity_holder, $user_mention, $replace);
91-
}
92-
}
93225

226+
} // foreach
227+
228+
} // if
229+
230+
// Media
94231
if (isset($tweet->entities->media)) {
232+
233+
$template = $configs['media_link_template'];
234+
95235
foreach ($tweet->entities->media as $media) {
96-
$replace = $media_link_pattern;
97-
$replace = str_replace('{{1}}', $media->url, $replace);
98-
$replace = str_replace('{{2}}', $media->expanded_url, $replace);
99-
$replace = str_replace('{{3}}', $media->display_url, $replace);
236+
237+
$replace = str_replace(
238+
'{{media_link}}',
239+
$media->url,
240+
$template
241+
);
242+
$replace = str_replace(
243+
'{{media_title}}',
244+
$media->expanded_url,
245+
$replace
246+
);
247+
$replace = str_replace(
248+
'{{media_text}}',
249+
$media->display_url,
250+
$replace
251+
);
252+
100253
self::add_entity($entity_holder, $media, $replace);
101-
}
102-
}
254+
255+
} // foreach
256+
257+
} // if
103258

104259
// Sort the entities in reverse order by their starting index
105260
krsort($entity_holder);
@@ -124,7 +279,11 @@ private static function parse_tweet_text($tweet) {
124279
/**
125280
* Add an entity to the entity_holder.
126281
*/
127-
private static function add_entity(&$entity_holder, $tweet_entity, $replace) {
282+
private static function add_entity(
283+
&$entity_holder,
284+
$tweet_entity,
285+
$replace
286+
) {
128287

129288
$entity = new \stdClass();
130289
$entity->start = $tweet_entity->indices[0];
@@ -142,7 +301,12 @@ private static function add_entity(&$entity_holder, $tweet_entity, $replace) {
142301
* String replacement supporting UTF-8 encoding.
143302
*/
144303
private static function mb_substr_replace(
145-
$string, $replacement, $start, $length = null, $encoding = null) {
304+
$string,
305+
$replacement,
306+
$start,
307+
$length = null,
308+
$encoding = null
309+
) {
146310

147311
$strlen = mb_strlen($string, $encoding);
148312
$first_piece = mb_substr($string, 0, $start, $encoding) . $replacement;
@@ -157,4 +321,16 @@ private static function mb_substr_replace(
157321

158322
// --------------------------------------------------------------------------
159323

160-
} // class TwitterTextFormatter
324+
/**
325+
* Set a default value for the given key.
326+
*/
327+
private static function set_default(&$array, $key, $default) {
328+
if (!isset($array[$key])) {
329+
$array[$key] = $default;
330+
}
331+
return;
332+
}
333+
334+
// --------------------------------------------------------------------------
335+
336+
} // class

0 commit comments

Comments
 (0)