How can I decode php code that using goto statement? - php

I have several large files as below:
public function index()
{
goto E9e2246508a1d047;
b59f99a7185ea4f4:
return View("\x65\155\160\154\x6f\171\x65\162\56\x74\x72\x61\156\163\141\x63\x74\x69\x6f\156\x73", ["\x70\x61\147\x65" => $F44ac1942f77c961]);
goto b4ef380f386bfff0;
E021694d1d524d6a:
$F44ac1942f77c961 = $C52f2627c8748472->lastpage();
goto b59f99a7185ea4f4;
E9e2246508a1d047:
$C52f2627c8748472 = UserTransaction::where("\165\x73\145\162\x5f\x69\x64", Auth::id())->orderBy("\143\x72\x65\141\164\x65\x64\x5f\141\x74", "\x61\163\x63")->paginate(10);
goto E021694d1d524d6a;
b4ef380f386bfff0:
}
From UnPHP - The Online PHP Decoder I decode it to :
public function index()
{
goto E9e2246508a1d047;
b59f99a7185ea4f4:
return View("employer.transactions", ["page" => $F44ac1942f77c961]);
goto b4ef380f386bfff0;
E021694d1d524d6a:
$F44ac1942f77c961 = $C52f2627c8748472->lastpage();
goto b59f99a7185ea4f4;
E9e2246508a1d047:
$C52f2627c8748472 = UserTransaction::where("user_id", Auth::id())->orderBy("created_at", "asc")->paginate(10);
goto E021694d1d524d6a;
b4ef380f386bfff0:
}
The name of the variables is not very important to me (Though it's better to be true).
But I want to delete goto command and have a clean code.

Rewrite the code with gotos:
public function index()
{
goto E9e2246508a1d047;
E9e2246508a1d047:
$C52f2627c8748472 = UserTransaction::where("user_id", Auth::id())->orderBy("created_at", "asc")->paginate(10);
goto E021694d1d524d6a;
E021694d1d524d6a:
$F44ac1942f77c961 = $C52f2627c8748472->lastpage();
goto b59f99a7185ea4f4;
b59f99a7185ea4f4:
return View("employer.transactions", ["page" => $F44ac1942f77c961]);
goto b4ef380f386bfff0;
b4ef380f386bfff0:
}
Then delete them:
public function index()
{
$C52f2627c8748472 = UserTransaction::where("user_id", Auth::id())->orderBy("created_at", "asc")->paginate(10);
$F44ac1942f77c961 = $C52f2627c8748472->lastpage();
return View("employer.transactions", ["page" => $F44ac1942f77c961]);
}

here is my solution after passing the code through the parser from your provided url:
$result = $source; // source code
$goto = []; // collect all goto blocks to remove them after
$result = preg_replace_callback('/goto (\w+);*/', function($m) use ($source, &$goto) {
$goto[] = $m[1].':';
preg_match("/{$m[1]} *:(((?!goto).)*)/s", $source, $m);
return $m[1];
}, $source);
$result = str_replace($goto, '', $result); // replace goto:
$result = preg_replace('/([\r\n])+\s+/', "\n", $result);
// view the result
echo '<pre>';
echo htmlentities($result);
echo '</pre>';die();

Related

find and convert all href url to another url php

I have a html code. now I want to find all href tags and want to convert their url into another url. I am using this code
public function convertLinks($message,$stats_code)
{
$click_link = site_url('click-'.$stats_code.'email');
$content = explode("\n", $message);
$URLs = array();
for($i=0;count($content)>$i;$i++)
{
if(preg_match('/<a href=/', $content[$i]))
{
list($Gone,$Keep) = explode("href=\"", trim($content[$i]));
list($Keep,$Gone) = explode("\">", $Keep);
$message= strtr($message, array( "$Keep" => $click_link.$Keep, ));
}
}
return $message;
}
this code is working fine but when 2 or more href links are in one line it only converts first href link and also when ancher tag also has any other tag like class or target or any other than it fails to convert links.
please give me suitable solution
thank you in advance
public function convertLinks($message,$stats_code)
{
$click_link = site_url('click-'.$stats_code.'email');
$message = str_replace('<a','{smart_href_link_epro} <a',$message);
$content = explode("{smart_href_link_epro}", $message);
$a_count = count($content);
for($i=0;$a_count>$i;$i++)
{
if(preg_match('/href=/', $content[$i]))
{
list($Lost,$Keep) = explode("href=\"", trim($content[$i]));
list($Keep,$Lost) = explode("\"", $Keep);
if($Keep!='#' && $Keep!='')
$message= strtr($message, array( "$Keep" => $click_link.base64_encode(base64_encode($Keep)), ));
}
}
return str_replace('{smart_href_link_epro}','',$message);
}
It works for me perfactly..

failure with find() function using PHP with Silex

Here is the failure message I get in Terminal running 'phpunit tests':
1) StylistTest::test_find
null does not match expected type "object".
/Users/evanbutler/Desktop/hairSalonApp/tests/StylistTest.php:163
Here's my test method:
function test_find()
{
//Arrange
$name = "Stylist Jane";
$id = 1;
$name2 = "Stylist Bob";
$id2 = 2;
$test_stylist = new Stylist($name, $id);
$test_stylist->save();
$test_stylist2 = new Stylist($name2, $id2);
$test_stylist2->save();
//Act
$result = Stylist::find($test_stylist->getId());
//Assert
$this->assertEquals($test_stylist, $result);
}
And here's my method:
static function find($search_id)
{
$found_stylist = null;
$stylists = Stylist::getAll();
foreach($stylists as $stylist) {
$stylist_id = $stylist->getId();
if ($stylist_id == $search_id) {
$found_styist = $stylist;
}
}
return $found_stylist;
}
Here's my getAll method:
static function getAll()
{
$returned_stylists = $GLOBALS['DB']->query("SELECT * FROM stylists;");
$stylists = array();
foreach($returned_stylists as $stylist) {
$name = $stylist['name'];
$id = $stylist['id'];
$new_stylist = new Stylist($name, $id);
array_push($stylists, $new_stylist);
}
return $stylists;
}
If you'd like to see all my files here's the link to the git repository:
https://github.com/evanb2/hairSalonApp.git
I've been staring at this for way too long and I'm totally stumped.
Change
$found_styist = $stylist;
to
$found_stylist = $stylist;
You need a better IDE man. Simple static analysis could tell you about the unused variable.

Eval'ing Plugins System

What would be the best way to do this?
I'm given a template with some things in it like {:HELLO-WORLD:} tags in it.
I'm also given an array like:
Array
(
[0] => Array
(
[Name] => {:HELLO-WORLD:}
[Plugin] => "<?php return 'Hello World'; ?>"
[Settings] =>
)
)
What can I do to make sure {:HELLO-WORLD:} gets replaced with the output of Hello World?
I am currently attempting:
private function PluginReplacer($arr, $str){
$gsCt = count($arr);
$kv = array();
for ($i=0;$i<$gsCt;++$i){
$kv[$arr[$i]['Name']] = $arr[$i]['Plugin'];
}
return str_replace(array_keys($kv), $this->EvalCode(array_values($kv)), $str);
}
// Eval Some Code
private function EvalCode($var){
require_once('plugins.php');
$pr = new CloudCMSPluginRunner();
$pr->Code = $var;
$pr->SitePath = GetSiteAssetsPath($this->SiteID);
$pr->RunIt();
echo $pr->Error;
}
<?php
class CloudCMSPluginRunner {
public $Code = '';
public $Error = '';
public $SitePath = '';
private $DoNotAllow = array('echo', 'eval', 'phpinfo', '/`/', 'chmod', 'chown', 'umask', 'shell_exec',
'exec', 'escapeshellcmd', 'proc_open', 'proc_terminate', 'proc_get_status',
'passthru', 'proc_nice', 'system', 'escapeshellarg', 'ob_start', 'ob_end_clean',
'ob_get_clean', 'session_start', 'putenv', 'header', 'sleep', 'uwait', 'ini_set',
'error_reporting', 'chgrp', 'basename', 'clearstatcache', 'copy', 'delete',
'dirname', 'disk_free_space', 'disk_total_space', 'diskfreespace', 'fclose',
'feof', 'fflush', 'fgetc', 'fgetcsv', 'fgets', 'fgetss', 'file_exists', 'file_get_contents',
'file_put_contents', 'file', 'fileatime', 'filectime', 'filegroup', 'fileinode', 'filemtime',
'fileowner', 'fileperms', 'filesize', 'filetype', 'flock', 'fnmatch', 'fopen', 'fpassthru',
'fputcsv', 'fputs', 'fread', 'fscanf', 'fseek', 'fstat', 'ftell', 'ftruncate', 'fwrite', 'glob',
'is_dir', 'is_executable', 'is_file', 'is_link', 'is_readable', 'is_uploaded_file', 'is_writeable',
'is_writable', 'lchgrp', 'lchown', 'link', 'linkinfo', 'lstat', 'mkdir', 'move_uploaded_file',
'parse_ini_file', 'parse_ini_string', 'pathinfo', 'pclose', 'popen', 'readfile', 'readlink',
'realpath_cache_get', 'realpath_cache_size', 'realpath', 'rename', 'rewind', 'rmdir', 'set_file_buffer',
'stat', 'symlink', 'tempnam', 'tmpfile', 'touch', 'unlink', 'chdir', 'chroot', 'closedir', 'dir',
'getcwd', 'opendir', 'readdir', 'rewinddir', 'scandir', 'dio_close', 'dio_fcntl', 'dio_open', 'dio_read',
'dio_seek', 'dio_stat', 'dio_tcsetattr', 'dio_truncate', 'dio_write', 'finfo_buffer', 'finfo_close',
'finfo_file', 'finfo_open', 'finfo_set_flags', 'mime_content_type', 'inotify_add_watch', 'inotify_init',
'inotify_queue_len', 'inotify_read', 'inotify_rm_watch', 'setproctitle', 'setthreadtitle', 'xattr_get',
'xattr_list', 'xattr_remove', 'xattr_set', 'xattr_supported');
public function RunIt(){
$valid = $this->CheckIt();
if($valid){
eval($this->Code);
}else{
// code is invalid
$this->Error = 'The code in this plugin is invalid.';
return null;
}
}
private function CheckIt(){
$ret = false;
ob_start(); // Catch potential parse error messages
$code = eval('if(0){' . "\n" . $this->Code . "\n" . '}');
ob_end_clean();
$ret = ($code !== false);
// run a check against the dissallowed
$ret = (stripos($this->Code , $this->DoNotAllow) !== false);
// make sure any path is there's and there's alone
$ret = (stripos($this->Code , $this->SitePath) !== false);
return $ret;
}
}
?>
But nothing is happenning... in fact the page I am attempting to run this on blanks out (meaning there is an error happenning)
You're generating code formatted as:
eval("function GetPageWeAreOn(){$p=explode('/',$_SERVER['REQUEST_URI']);return $p[1];}");
What's happening is that PHP is interpreting the variables wrongly - instead of passing them in to the eval'ed function, it's interpolating them first.
I've avoided the error by escaping them:
eval("function GetPageWeAreOn(){\$p=explode('/',\$_SERVER['REQUEST_URI']);return \$p[1];}");
You can avoid the need for escaping by putting your string to be eval'ed into single quotes, too - that doesn't try to interpolate variables:
eval('function GetPageWeAreOn(){$p=explode("/",$_SERVER["REQUEST_URI"]);return $p[1];}');

Escaping issue in building query dynamic function variables

I am developing a CMS which works on template page system in a different approach.
I have this object:
$structure = new stdClass;
$structure->homepage->news->method = 'get_articles_by_page_name';
$structure->homepage->news->lang_key = translate('home_news');
$structure->homepage->news->lang = $lang;
$structure->homepage->news->add_media = true;
$structure->homepage->news->media_type = 'ibs';
$structure->homepage->news->limit = '5';
$structure->homepage->news->order_by = 'a.logical_date';
$structure->homepage->news->asc_des = 'desc';
$structure->homepage->news->result_type = 'result';
This helps to get contents as following:
foreach ($structure as $page_template => $page_contents)
{
// Call Customized Content for Homepage
if($this->data['page_data']->page_view == $page_template) // homepage comes ok.
{
foreach ($page_contents as $view_var_name => $page_cdata)
{
$method = $page_cdata->method; // method names comes
$page_cdata = substr(implode(",",(array) $page_cdata),(strlen($method)+1)) . '\'';
//Returns as expected:
//**'Haberler','tr','1','ibs','5','a.logical_date','desc','result'**
$this->data[$view_var_name] = $this->publish->$method($page_cdata);
vdebug($page_cdata);
}
}
}
It suppose to call them model function of:
function get_articles_by_page_name( $lang_key='',$lang='en',$add_media=true,
media_type='ibs',$limit='0',$order_by='a.logical_date',$asc_desc='desc',$result_type='result')
However, there is a problem with. When I return to last worked query it says:
SELECT * FROM (`page`) JOIN `page_lang` ON `page`.`id_page` = `page_lang`.`id_page` WHERE `page_lang`.`title` = '\'News\',\'tr\',\'1\',\'ibs\',\'5\',\'a.logical_date\',\'desc\',\'result\''
It souldn't be like this. every thing between commas are parameters of the method function. What cause this, any idea?
Content of get_articles_by_page_name:
function get_articles_by_page_name ($lang_key='',$lang='tr',$add_media=true,$media_type='ibs',$limit='0',$order_by='a.logical_date',$asc_desc='desc',$result_type='result')
{
// Define variables
$id_page = '';
$result = '';
// Get Page Data
$page_name = $lang_key;
$get_page = $this->vayes->getJoined('page','page_lang','id_page','','',array('page_lang.title'=>$page_name),'row');
if($get_page)
{
$id_page = $get_page->id_page;
$result = $this->publish->get_articles($lang,$id_page,null,false,'',$order_by,$asc_desc,$limit,'result');
}
else
{
$result = array('No id_page specified');
}
return $result;
}
Content of get_articles:
function get_articles($lang='tr',$id_page,$id_article=null,$incl_media=true,$media_type='',$order_by='a.logical_date',$asc_desc='desc',$limit='0',$result_type='result')
{
$this->db->select('*');
$this->db->from('article a');
$this->db->join('article_lang b','b.id_article=a.id_article','left outer');
if($incl_media) {
$this->db->join('article_media c','c.id_article=b.id_article','left outer');
$this->db->join('media d','d.id_media=c.id_media','left outer');
}
if($id_article == null) { $this->db->where('a.id_page',$id_page); }
else /*------------->*/ { $this->db->where('a.id_article',$id_article); }
$this->db->where('b.lang',$lang);
$this->db->where('b.online',1);
if(($incl_media == true) AND $media_type != '' ) $this->db->where('c.usage',$media_type);
// Order Results
$this->db->order_by($order_by,$asc_desc);
// Limit Results
if ($limit) $this->db->limit($limit);
$query = $this->db->get();
if($query->num_rows() > 0)
{
$result = $query->$result_type();
$query->free_result();
return $result;
}
return false;
}
try stripslashes()
Attempting to use stripslashes on an array in 5.2.17 returns the string "Array", but in 5.3.6 it returns NULL. So using stripslashes() on an array you will need to do it recursively;
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
}
// Example
$array = array("f\\'oo", "b\\'ar", array("fo\\'o", "b\\'ar"));
$array = stripslashes_deep($array);
// Output
print_r($array);

PHP: How to use the Twitter API's data to convert URLs, mentions, and hastags in tweets to links?

I'm really stumped on how Twitter expects users of its API to convert the plaintext tweets it sends to properly linked HTML.
Here's the deal: Twitter's JSON API sends this set of information back when you request the detailed data for a tweet:
{
"created_at":"Wed Jul 18 01:03:31 +0000 2012",
"id":225395341250412544,
"id_str":"225395341250412544",
"text":"This is a test tweet. #boring #nbc http://t.co/LUfDreY6 #skronk #crux http://t.co/VpuMlaDs #twitter",
"source":"web",
"truncated":false,
"in_reply_to_status_id":null,
"in_reply_to_status_id_str":null,
"in_reply_to_user_id":null,
"in_reply_to_user_id_str":null,
"in_reply_to_screen_name":null,
"user": <REDACTED>,
"geo":null,
"coordinates":null,
"place":null,
"contributors":null,
"retweet_count":0,
"entities":{
"hashtags":[
{
"text":"boring",
"indices":[22,29]
},
{
"text":"skronk",
"indices":[56,63]
}
],
"urls":[
{
"url":"http://t.co/LUfDreY6",
"expanded_url":"http://www.twitter.com",
"display_url":"twitter.com",
"indices":[35,55]
},
{
"url":"http://t.co/VpuMlaDs",
"expanded_url":"http://www.example.com",
"display_url":"example.com",
"indices":[70,90]
}
],
"user_mentions":[
{
"screen_name":"nbc",
"name":"NBC",
"id":26585095,
"id_str":"26585095",
"indices":[30,34]
},
{
"screen_name":"crux",
"name":"Z. D. Smith",
"id":407213,
"id_str":"407213",
"indices":[64,69]
},
{
"screen_name":"twitter",
"name":"Twitter",
"id":783214,
"id_str":"783214",
"indices":[91,99]
}
]
},
"favorited":false,
"retweeted":false,
"possibly_sensitive":false
}
The interesting parts, for this question, are the text element and the entries in the hashtags, user_mentions, and urls arrays. Twitter is telling us where in the text element the hastags, mentions, and urls appear with the indices arrays... so here's the crux of the question:
How do you use those indices arrays?
You can't just use them straight up by looping over each link element with something like substr_replace, since replacing the first link element in the text will invalidate all the index values for subsequent link elements. You also can't use substr_replace's array functionality, since it only works when you give it an array of strings for the first arg, rather than a single string (I've tested this. The results are... strange).
Is there some function that can simultaneously replace multiple index-delimited substrings in a single string with different replacement strings?
All you have to do to use the indices twitter provides straight up with a simple replace is collect the replacements you want to make and then sort them backwards. You can probably find a more clever way to build $entities, I wanted them optional anyway, so I KISS as far as that went.
Either way, my point here was just to show that you don't need to explode the string and character count and whatnot. Regardless of how you do it, all you need to to is start at the end and work to the beginning of the string, and the index twitter has is still valid.
<?php
function json_tweet_text_to_HTML($tweet, $links=true, $users=true, $hashtags=true)
{
$return = $tweet->text;
$entities = array();
if($links && is_array($tweet->entities->urls))
{
foreach($tweet->entities->urls as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = "<a href='".$e->expanded_url."' target='_blank'>".$e->display_url."</a>";
$entities[] = $temp;
}
}
if($users && is_array($tweet->entities->user_mentions))
{
foreach($tweet->entities->user_mentions as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = "<a href='https://twitter.com/".$e->screen_name."' target='_blank'>#".$e->screen_name."</a>";
$entities[] = $temp;
}
}
if($hashtags && is_array($tweet->entities->hashtags))
{
foreach($tweet->entities->hashtags as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = "<a href='https://twitter.com/hashtag/".$e->text."?src=hash' target='_blank'>#".$e->text."</a>";
$entities[] = $temp;
}
}
usort($entities, function($a,$b){return($b["start"]-$a["start"]);});
foreach($entities as $item)
{
$return = substr_replace($return, $item["replacement"], $item["start"], $item["end"] - $item["start"]);
}
return($return);
}
?>
Ok so I needed to do exactly this and I solved it. Here is the function I wrote. https://gist.github.com/3337428
function parse_message( &$tweet ) {
if ( !empty($tweet['entities']) ) {
$replace_index = array();
$append = array();
$text = $tweet['text'];
foreach ($tweet['entities'] as $area => $items) {
$prefix = false;
$display = false;
switch ( $area ) {
case 'hashtags':
$find = 'text';
$prefix = '#';
$url = 'https://twitter.com/search/?src=hash&q=%23';
break;
case 'user_mentions':
$find = 'screen_name';
$prefix = '#';
$url = 'https://twitter.com/';
break;
case 'media':
$display = 'media_url_https';
$href = 'media_url_https';
$size = 'small';
break;
case 'urls':
$find = 'url';
$display = 'display_url';
$url = "expanded_url";
break;
default: break;
}
foreach ($items as $item) {
if ( $area == 'media' ) {
// We can display images at the end of the tweet but sizing needs to added all the way to the top.
// $append[$item->$display] = "<img src=\"{$item->$href}:$size\" />";
}else{
$msg = $display ? $prefix.$item->$display : $prefix.$item->$find;
$replace = $prefix.$item->$find;
$href = isset($item->$url) ? $item->$url : $url;
if (!(strpos($href, 'http') === 0)) $href = "http://".$href;
if ( $prefix ) $href .= $item->$find;
$with = "$msg";
$replace_index[$replace] = $with;
}
}
}
foreach ($replace_index as $replace => $with) $tweet['text'] = str_replace($replace,$with,$tweet['text']);
foreach ($append as $add) $tweet['text'] .= $add;
}
}
It's an edge case but the use of str_replace() in Styledev's answer could cause issues if one entity is contained within another. For example, "I'm a genius! #me #mensa" could become "I'm a genius! #me #mensa" if the shorter entity is substituted first.
This solution avoids that problem:
<?php
/**
* Hyperlinks hashtags, twitter names, and urls within the text of a tweet
*
* #param object $apiResponseTweetObject A json_decoded() one of these: https://dev.twitter.com/docs/platform-objects/tweets
* #return string The tweet's text with hyperlinks added
*/
function linkEntitiesWithinText($apiResponseTweetObject) {
// Convert tweet text to array of one-character strings
// $characters = str_split($apiResponseTweetObject->text);
$characters = preg_split('//u', $apiResponseTweetObject->text, null, PREG_SPLIT_NO_EMPTY);
// Insert starting and closing link tags at indices...
// ... for #user_mentions
foreach ($apiResponseTweetObject->entities->user_mentions as $entity) {
$link = "https://twitter.com/" . $entity->screen_name;
$characters[$entity->indices[0]] = "<a href=\"$link\">" . $characters[$entity->indices[0]];
$characters[$entity->indices[1] - 1] .= "</a>";
}
// ... for #hashtags
foreach ($apiResponseTweetObject->entities->hashtags as $entity) {
$link = "https://twitter.com/search?q=%23" . $entity->text;
$characters[$entity->indices[0]] = "<a href=\"$link\">" . $characters[$entity->indices[0]];
$characters[$entity->indices[1] - 1] .= "</a>";
}
// ... for http://urls
foreach ($apiResponseTweetObject->entities->urls as $entity) {
$link = $entity->expanded_url;
$characters[$entity->indices[0]] = "<a href=\"$link\">" . $characters[$entity->indices[0]];
$characters[$entity->indices[1] - 1] .= "</a>";
}
// ... for media
foreach ($apiResponseTweetObject->entities->media as $entity) {
$link = $entity->expanded_url;
$characters[$entity->indices[0]] = "<a href=\"$link\">" . $characters[$entity->indices[0]];
$characters[$entity->indices[1] - 1] .= "</a>";
}
// Convert array back to string
return implode('', $characters);
}
?>
Jeff's solution worked well with English text but it got broken when the tweet contained non-ASCII characters. This solution avoids that problem:
mb_internal_encoding("UTF-8");
// Return hyperlinked tweet text from json_decoded status object:
function MakeStatusLinks($status)
{$TextLength=mb_strlen($status['text']); // Number of UTF-8 characters in plain tweet.
for ($i=0;$i<$TextLength;$i++)
{$ch=mb_substr($status['text'],$i,1); if ($ch<>"\n") $ChAr[]=$ch; else $ChAr[]="\n<br/>"; // Keep new lines in HTML tweet.
}
if (isset($status['entities']['user_mentions']))
foreach ($status['entities']['user_mentions'] as $entity)
{$ChAr[$entity['indices'][0]] = "<a href='https://twitter.com/".$entity['screen_name']."'>".$ChAr[$entity['indices'][0]];
$ChAr[$entity['indices'][1]-1].="</a>";
}
if (isset($status['entities']['hashtags']))
foreach ($status['entities']['hashtags'] as $entity)
{$ChAr[$entity['indices'][0]] = "<a href='https://twitter.com/search?q=%23".$entity['text']."'>".$ChAr[$entity['indices'][0]];
$ChAr[$entity['indices'][1]-1] .= "</a>";
}
if (isset($status['entities']['urls']))
foreach ($status['entities']['urls'] as $entity)
{$ChAr[$entity['indices'][0]] = "<a href='".$entity['expanded_url']."'>".$entity['display_url']."</a>";
for ($i=$entity['indices'][0]+1;$i<$entity['indices'][1];$i++) $ChAr[$i]='';
}
if (isset($status['entities']['media']))
foreach ($status['entities']['media'] as $entity)
{$ChAr[$entity['indices'][0]] = "<a href='".$entity['expanded_url']."'>".$entity['display_url']."</a>";
for ($i=$entity['indices'][0]+1;$i<$entity['indices'][1];$i++) $ChAr[$i]='';
}
return implode('', $ChAr); // HTML tweet.
}
Here is an updated answer that works with Twitter's new Extended Mode. It combines the answer by #vita10gy and the comment by #Hugo (to make it utf8 compatible), with a few minor tweaks to work with the new api values.
function utf8_substr_replace($original, $replacement, $position, $length) {
$startString = mb_substr($original, 0, $position, "UTF-8");
$endString = mb_substr($original, $position + $length, mb_strlen($original), "UTF-8");
$out = $startString . $replacement . $endString;
return $out;
}
function json_tweet_text_to_HTML($tweet, $links=true, $users=true, $hashtags=true) {
// Media urls can show up on the end of the full_text tweet, but twitter doesn't index that url.
// The display_text_range indexes show the actual tweet text length.
// Cut the string off at the end to get rid of this unindexed url.
$return = mb_substr($tweet->full_text, $tweet->display_text_range[0],$tweet->display_text_range[1]);
$entities = array();
if($links && is_array($tweet->entities->urls))
{
foreach($tweet->entities->urls as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = " <a href='".$e->expanded_url."' target='_blank'>".$e->display_url."</a>";
$entities[] = $temp;
}
}
if($users && is_array($tweet->entities->user_mentions))
{
foreach($tweet->entities->user_mentions as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = " <a href='https://twitter.com/".$e->screen_name."' target='_blank'>#".$e->screen_name."</a>";
$entities[] = $temp;
}
}
if($hashtags && is_array($tweet->entities->hashtags))
{
foreach($tweet->entities->hashtags as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = " <a href='https://twitter.com/hashtag/".$e->text."?src=hash' target='_blank'>#".$e->text."</a>";
$entities[] = $temp;
}
}
usort($entities, function($a,$b){return($b["start"]-$a["start"]);});
foreach($entities as $item)
{
$return = utf8_substr_replace($return, $item["replacement"], $item["start"], $item["end"] - $item["start"]);
}
return($return);
}
Here is a JavaScript version (using jQuery) of vita10gy's solution
function tweetTextToHtml(tweet, links, users, hashtags) {
if (typeof(links)==='undefined') { links = true; }
if (typeof(users)==='undefined') { users = true; }
if (typeof(hashtags)==='undefined') { hashtags = true; }
var returnStr = tweet.text;
var entitiesArray = [];
if(links && tweet.entities.urls.length > 0) {
jQuery.each(tweet.entities.urls, function() {
var temp1 = {};
temp1.start = this.indices[0];
temp1.end = this.indices[1];
temp1.replacement = '' + this.display_url + '';
entitiesArray.push(temp1);
});
}
if(users && tweet.entities.user_mentions.length > 0) {
jQuery.each(tweet.entities.user_mentions, function() {
var temp2 = {};
temp2.start = this.indices[0];
temp2.end = this.indices[1];
temp2.replacement = '#' + this.screen_name + '';
entitiesArray.push(temp2);
});
}
if(hashtags && tweet.entities.hashtags.length > 0) {
jQuery.each(tweet.entities.hashtags, function() {
var temp3 = {};
temp3.start = this.indices[0];
temp3.end = this.indices[1];
temp3.replacement = '#' + this.text + '';
entitiesArray.push(temp3);
});
}
entitiesArray.sort(function(a, b) {return b.start - a.start;});
jQuery.each(entitiesArray, function() {
returnStr = substrReplace(returnStr, this.replacement, this.start, this.end - this.start);
});
return returnStr;
}
You can then use this function like so ...
for(var i in tweetsJsonObj) {
var tweet = tweetsJsonObj[i];
var htmlTweetText = tweetTextToHtml(tweet);
// Do something with the formatted tweet here ...
}
Regarding vita10gy's helpful json_tweet_text_to_HTML(), I found a tweet that it could not format correctly: 626125868247552000.
This tweet has a nonbreaking space in it. My solution was to replace the first line of the function with the following:
$return = str_replace("\xC2\xA0", ' ', $tweet->text);
Performing a str_replace() on is covered here.

Categories