123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224 |
- <?php
- /* this file stores all of the functions that are used
- over all of the other files. */
- ini_set("log_errors", 1);
- $srv = $user_settings['instance'];
- //$token = ($token != false ? msc($token,'d') : false);
- $token = ($token != false ? $token : false);
- // FUNCTIONS THAT HAVE TO DO WITH INSTANCE COMMUNICATION AND RETRIEVAL
- /* a function to make an authenticated general GET api call to the logged-in instance.
- - $url is a string of an api call like "account/:id/statuses"
-
- - returns the array conversion of the json response
- */
- function api_get($url) {
- global $srv;
- global $token;
- $curl = curl_init();
- curl_setopt($curl, CURLOPT_URL, "https://$srv/api/v1/" . $url);
- if (!is_null($token)) {
- curl_setopt($curl, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- }
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- $result = curl_exec($curl);
- curl_close($curl);
- return json_decode($result, true);
- }
- /* same as above but used in some newer api endpoinds (v2) */
- function api_getv2($url) {
- global $srv;
- global $token;
- $curl = curl_init();
- curl_setopt($curl, CURLOPT_URL, "https://$srv/api/v2/" . $url);
- if (!is_null($token)) {
- curl_setopt($curl, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- }
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- $result = curl_exec($curl);
- curl_close($curl);
- return json_decode($result, true);
- }
- /* a function to make an authenticated general POST api call to the logged-in instance.
- - $url is a string of an api call like "account/:id/statuses"
-
- - returns the array conversion of the json response
- */
- function api_post($url, $array) {
- global $srv;
- global $token;
- $cSession = curl_init();
- curl_setopt($cSession, CURLOPT_HEADER, false);
- curl_setopt($cSession, CURLOPT_POST, 1);
- curl_setopt($cSession, CURLOPT_URL, "https://$srv/api/v1/" . $url);
- if (!is_null($token)) {
- curl_setopt($cSession, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- }
- curl_setopt($cSession, CURLOPT_POSTFIELDS, http_build_query($array));
- curl_setopt($cSession, CURLOPT_RETURNTRANSFER, true);
- $result = curl_exec($cSession);
- curl_close($cSession);
- return json_decode($result, true);
- }
- /* a function to make an authenticated general DELETE api call to the logged-in instance.
- - $url is a string of an api call like "statuses/delete/:id"
-
- - returns the array conversion of the json response
- */
- function api_delete($url, $array) {
- global $srv;
- global $token;
- $cSession = curl_init();
- curl_setopt($cSession, CURLOPT_HEADER, false);
- curl_setopt($cSession, CURLOPT_POST, 1);
- curl_setopt($cSession, CURLOPT_URL, "https://$srv/api/v1/" . $url);
- curl_setopt($cSession, CURLOPT_CUSTOMREQUEST, "DELETE");
- if (!is_null($token)) {
- curl_setopt($cSession, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- }
- curl_setopt($cSession, CURLOPT_POSTFIELDS, http_build_query($array));
- curl_setopt($cSession, CURLOPT_RETURNTRANSFER, true);
- $result = curl_exec($cSession);
- curl_close($cSession);
- return json_decode($result, true);
- }
- /* a function to make an authenticated general PATCH api call to the logged-in instance.
- - $url is a string of an api call like "account/:id/statuses"
-
- - returns the array conversion of the json response
- */
- function api_patch($url, $array) {
- global $srv;
- global $token;
- $cSession = curl_init();
- curl_setopt($cSession, CURLOPT_HEADER, false);
- curl_setopt($cSession, CURLOPT_POST, 1);
- curl_setopt($cSession, CURLOPT_URL, "https://$srv/api/v1/" . $url);
- curl_setopt($cSession, CURLOPT_CUSTOMREQUEST, "PATCH");
- if (!is_null($token)) {
- curl_setopt($cSession, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- }
- curl_setopt($cSession, CURLOPT_POSTFIELDS, http_build_query($array));
- curl_setopt($cSession, CURLOPT_RETURNTRANSFER, true);
- $result = curl_exec($cSession);
- curl_close($cSession);
- return json_decode($result, true);
- }
- /* Function to upload files to the profile of the authenticated user
- - $type can be 'avatar' or 'header'
-
- - returns the json of the api call
- */
- function upload_profile($file,$type){
- global $srv;
- global $token;
-
- $mime = get_mime($file);
- $info = pathinfo($file);
- $name = $info['basename'];
- $output = new CURLFile($file, $mime, $name);
- $cSession = curl_init();
- curl_setopt($cSession, CURLOPT_URL, "https://$srv/api/v1/accounts/update_credentials");
- curl_setopt($cSession, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($cSession, CURLOPT_POST, 1);
- curl_setopt($cSession, CURLOPT_CUSTOMREQUEST, "PATCH");
- curl_setopt($cSession, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- curl_setopt($cSession, CURLOPT_POSTFIELDS, array(
- $type => $output
- ));
- $result = curl_exec($cSession);
- curl_close($cSession);
- return $result;
- }
- /* this function fetches all the data from a profile (bio, username, relationships, etc)
- - $user is the id of the queried user
-
- - returns the array conversion of the json response
- */
- function user_info($user) {
- global $user_settings;
- $info = api_get("accounts/" . $user);
- $rel = api_get("accounts/relationships?id=" . $user);
- return array(
- $info,
- $rel
- );
- }
- /* this function fetches the context (the previous posts and replies) of a specified post
- - $post = ID of the post queried.
-
- - returns an array conversion of the json response
- */
- function context($post) {
- global $srv;
- global $token;
- $curl = curl_init();
- curl_setopt($curl, CURLOPT_URL, "https://$srv/api/v1/statuses/$post/context");
- if (!is_null($token)) {
- curl_setopt($curl, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- }
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- $result = curl_exec($curl);
- curl_close($curl);
- return $result;
- }
- /* a function to fav or unfav a specified post
- - $post = ID of the post queried.
- - $mode can be true if is a fav or false if it's an unfav
-
- - returns the number of favs of the post after the specified action or "error"
- if there was an error performing the action
- */
- function favourite($post, $mode) {
- $result = api_post(($mode == true ? "statuses/$post/favourite" : "statuses/$post/unfavourite"),array());
- if (isset($result['favourites_count'])) {
- return $result['favourites_count'];
- }
- else {
- return "error";
- }
- }
- /* a function to reblog or unreblog a specified post
- - $post = ID of the post queried.
- - $mode can be true if is a reblog or false if it's an unreblog
-
- - returns the number of reblogs of the post after the specified action or "error"
- if there was an error performing the action
- */
- function reblog($post, $mode) {
- $result = api_post(($mode == true ? "statuses/$post/reblog" : "statuses/$post/unreblog"),array());
- if (isset($result['reblog']['reblogs_count'])) {
- return $result['reblog']['reblogs_count'];
- }
- elseif (isset($result['reblogs_count'])) {
- return $result['reblogs_count'];
- }
- else {
- return "error";
- }
- }
- /* function to delete a post
- - $id is the id of the post to delete
-
- - returns 1 if the post was deleted succesfully or 0 if there was an error
- */
- function delpost($id) {
- global $srv;
- global $token;
- if (!is_null($token)) {
- $curl = curl_init();
- curl_setopt($curl, CURLOPT_HEADER, false);
- curl_setopt($curl, CURLOPT_POST, 1);
- curl_setopt($curl, CURLOPT_URL, "https://$srv/api/v1/statuses/$id");
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
- curl_setopt($curl, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- $result = curl_exec($curl);
- curl_close($curl);
- $result = json_decode($result, true);
- if (empty($result)) {
- return "1";
- }
- else {
- return "0";
- }
- }
- }
- /* function to issue a vote to a poll
- - $id is the id of the poll to vote on
-
- - $choices is a comma separated string of the choices that will be voted.
- */
- function vote($poll, $choices) {
- global $srv;
- global $token;
- if (!is_null($token)) {
- $cSession = curl_init();
- curl_setopt($cSession, CURLOPT_URL, "https://$srv/api/v1/polls/$poll/votes");
- curl_setopt($cSession, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($cSession, CURLOPT_POST, 1);
- curl_setopt($cSession, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- $query = "";
- $choicelist = explode(",",$choices);
- foreach($choicelist as $choice){
- $query .= "choices[]=$choice&";
- }
-
- curl_setopt($cSession, CURLOPT_POSTFIELDS, $query);
- $result = curl_exec($cSession);
- curl_close($cSession);
- return $result;
- }
- else {
- return false;
- }
- }
- /* function to send a new post to the logged in instance
- - $text = the body of the message
- - $media = array of uploaded media id's
- - $reply = the id of a post being replied to, can be null.
- - $markdown = specify if the post uses markdown (unused at this moment)
- - $scope = the scope of the post (public, private, unlisted or direct)
- - $sensitive = bool to specify if the post media is sensitive
- - $spoiler = string of the title of the post
-
- - returns the json of the api response
- */
- function sendpost($text, $media, $reply = null, $markdown = false, $scope = "public", $sensitive = false, $spoiler = false) {
- global $srv;
- global $token;
- if (!is_null($token)) {
- $cSession = curl_init();
- curl_setopt($cSession, CURLOPT_URL, "https://$srv/api/v1/statuses");
- curl_setopt($cSession, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($cSession, CURLOPT_POST, 1);
- curl_setopt($cSession, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- $query = "";
- $query .= "status=" . urlencode(html_entity_decode($text, ENT_QUOTES)) . "&visibility=" . $scope;;
- if (!is_null($reply) && $reply != "null") {
- $query .= "&in_reply_to_id=" . $reply;
- }
- if ($markdown == true) {
- $query .= "&content_type=text/markdown";
- }
- if ($sensitive == 'true') {
- $query .= "&sensitive=true";
- }
- if ($spoiler == true) {
- $query .= "&spoiler_text=" . $spoiler;
- }
- if (!is_null($media)) {
- foreach ($media as $mid) {
- $query .= "&media_ids[]=" . $mid;
- }
- }
-
- curl_setopt($cSession, CURLOPT_POSTFIELDS, $query);
- $result = curl_exec($cSession);
- curl_close($cSession);
- return $result;
- }
- else {
- return false;
- }
- }
- /* uploads a file to the logged in instance.
- - $file = path of the file to upload on local storage
-
- - returns an array where:
- 0: the ID of the uploaded file
- 1: the url of the file (if the file isn't an image, returns a placeholder)
- */
- function uploadpic($file) {
- global $srv;
- global $token;
- if (!is_null($token)) {
- $mime = get_mime($file);
- $info = pathinfo($file);
- $name = $info['basename'];
- $output = new CURLFile($file, $mime, $name);
- $cSession = curl_init();
- curl_setopt($cSession, CURLOPT_URL, "https://$srv/api/v1/media");
- curl_setopt($cSession, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($cSession, CURLOPT_POST, 1);
- curl_setopt($cSession, CURLOPT_HTTPHEADER, array(
- 'Authorization: Bearer ' . $token
- ));
- curl_setopt($cSession, CURLOPT_POSTFIELDS, array(
- 'file' => $output
- ));
- $result = curl_exec($cSession);
- curl_close($cSession);
- echo $result;
- $array = json_decode($result, true);
- $ext = explode(".", $array['url']);
- $ext = end($ext);
- $ext = explode("?", $ext) [0];
- if (in_array($ext, array('jpg','jpeg','gif','png','svg','webm'))) {
- $file = $array['url'];
- } elseif (in_array($ext, array('mp4','webp','ogv'))) {
- $file = "img/vid.png";
- } elseif (in_array($ext, array('mp3','ogg','oga','opus'))) {
- $file = "img/aud.png";
- } else {
- $file = "img/doc.png";
- }
- return json_encode(array(
- $array['id'],
- $file
- ));
- }
- else {
- return false;
- }
- }
- /* this is used to register DashFE as an application on an instance
- mostly used when logging in
- - $instance = the url of the instance where to log in
-
- - returns the array conversion of the json response
- */
- function register_app($instance) {
- global $setting;
- $cSession = curl_init();
- curl_setopt($cSession, CURLOPT_URL, "https://$instance/api/v1/apps");
- curl_setopt($cSession, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($cSession, CURLOPT_HEADER, false);
- curl_setopt($cSession, CURLOPT_POST, 1);
- curl_setopt($cSession, CURLOPT_POSTFIELDS, http_build_query(array(
- 'client_name' => $setting['appname'],
- 'redirect_uris' => $setting['url'],
- 'scopes' => 'read write follow'
- )));
- $result = curl_exec($cSession);
- curl_close($cSession);
- return json_decode($result, true);
- }
- /* this function will get all the notes (reblogs and favs) that has an specified post
- - $thread = the id of the post queried
-
- - returns an array with all the notes
- each note is another array where:
- 0 = type of note ("reb" reblog or "fab" favorite)
- 1 = array of the details of the user, converted from the json of the api response.
- */
- function getnotes($thread) {
- global $user_settings;
- global $token;
- global $srv;
- global $setting;
- global $logedin;
- @$reb = array(
- api_get("statuses/" . $thread . "/reblogged_by")
- );
- @$fab = array(
- api_get("statuses/" . $thread . "/favourited_by")
- );
- $limit = (count($reb[0]) > count($fab[0]) ? count($reb[0]) - 1 : count($fab[0]) - 1);
- $notes = array();
- $index = 0;
- for ($i = 0;$i <= $limit;$i++) {
- if (isset($reb[0][$i])) {
- $notes[$index][0] = "reb";
- $notes[$index][1] = $reb[0][$i];
- $index++;
- }
- if (isset($fab[0][$i])) {
- $notes[$index][0] = "fav";
- $notes[$index][1] = $fab[0][$i];
- $index++;
- }
- }
- return $notes;
- }
- /* this function will fetch replies of a post
- - $thread = the id of the post from where to fetch replies
- - $since = id of a post. If specified, the function will fetch the replies
- only since the specified id.
-
- - returns an array with all the replies
- each element is another array where:
- 'mode' = type of the reply (ancestor or descendant)
- 'content' = array of the contents of the reply, converted from the json of the api response.
- */
- function getreplies($thread, $since = false) {
- global $user_settings;
- global $token;
- global $srv;
- global $setting;
- global $logedin;
- $context = json_decode(context($thread) , true);
- $array = array();
- if (!empty($context['ancestors'])) {
- if ($since == false) {
- foreach ($context['ancestors'] as $elem) {
- $elem['type'] = 'ancestor';
- $array[] = $elem;
- }
- }
- }
- $flag = 0;
- if (!empty($context['descendants'])) {
- foreach ($context['descendants'] as $elem) {
- if (($since != false && $flag == 1) || $since == false) {
- $elem['type'] = 'descendant';
- $array[] = $elem;
- }
- if ($since != false && $elem['id'] == $since) {
- $flag = 1;
- }
- }
- }
- $replies = array();
- foreach ($array as $item) {
- $reply['mode'] = "";
- if ($item['type'] == 'ancestor') {
- $reply['mode'] = "ancestor";
- }
- $replies[] = array(
- 'mode' => $reply['mode'],
- 'content' => $item
- );
- }
- return $replies;
- }
- /* this function takes some options from the init.php file and the user_settings cookie
- and fetches all the posts of the appropiate timeline
- - $query = an array with a set of elements generated by the file "include/init.php"
-
- - returns an array of the posts list fetched converted from the json response of the api.
- */
- function timeline($query) {
- global $token;
- global $srv;
- $notes = "";
-
- $hq = array();
- $hq['limit'] = 10;
- $hq['only_media'] = ($query['text'] == "off" ? 'true' : 'false');
- if ($query['next']){
- $hq['max_id'] = $query['next'];
- $next = $query['next'];
- } elseif ($query['since']) {
- $hq['since_id'] = $query['since'];
- }
-
- switch ($query['mode']) {
- case "home":
- $array = api_get("timelines/home?".http_build_query($hq));
- break;
- case "federated":
- $array = api_get("timelines/public?".http_build_query($hq));
- break;
- case "tag":
- $array = api_get("timelines/tag/" . $query['tag'] . "?".http_build_query($hq));
- break;
- case "local":
- $array = api_get("timelines/public?local=true&".http_build_query($hq));
- break;
- case "user":
- $array = api_get("accounts/" . $query['user'] . "/statuses?".http_build_query($hq));
- break;
- case "thread":
- $array = array(
- api_get("statuses/" . $query['thread'])
- );
- break;
- case "favourites":
- $array = api_get("favourites?".http_build_query($hq));
- break;
- case "direct":
- $array = api_get("timelines/direct?".http_build_query($hq));
- break;
- case "list":
- $array = api_get("timelines/list/" . $query['list'] . "?".http_build_query($hq));
- break;
- case "bookmarks":
- $array = api_get("bookmarks?".http_build_query($hq));
- break;
-
- case "search":
- $array = api_getv2("search?limit=40&q=".$query['search']."{$next}")['statuses'];
- break;
- case "account":
- $info = api_get("accounts/verify_credentials");
- $array = api_get("accounts/" . $info['id'] . "/statuses?".http_build_query($hq));
- break;
- default:
- $array = api_get("timelines/public?".http_build_query($hq));
- break;
- }
- if (!is_array($array)) {
- return false;
- }
- $next = end($array) ['id'];
- $thread = array();
- /*
- foreach ($array as $elem) {
- if ($query['replies'] == "on" || $query['mode'] == "thread") {
- $thread[] = $elem;
- }
- else {
- if ($elem['in_reply_to_id'] == null) {
- $thread[] = $elem;
- }
- }
- }*/
-
- foreach ($array as $elem) {
- if ($query['replies'] == "on" || $query['mode'] == "thread") {
- $thread[] = $elem;
- }
- else {
- if ($elem['in_reply_to_id'] == null || $elem['in_reply_to_account_id'] == $query['uid']) {
- $thread[] = $elem;
- } else {
- $rel = api_get("accounts/relationships?id=" . $elem['in_reply_to_account_id']);
- if ($rel[0]['following']){
- $thread[] = $elem;
- }
- }
- }
- }
- return $thread;
- }
- // FUNCTIONS THAT HAVE TO DO WITH RENDERING STUFF FOR THE PAGE
- /* this function is used to generate the html code of a poll */
- function renderPoll($elem) {
- global $logedin;
-
- $output = "";
- $output .= "<br>";
- $votes = $elem['poll']['votes_count'];
-
- if ($elem['poll']['voted'] || $elem['poll']['expired']) {
- $output.= "<b>Votes: $votes</b><br>";
- foreach ($elem['poll']['options'] as $option){
- $percentage = ($option['votes_count'] / $votes ) * 100;
- $output .= "<div class='polloption fixed' title='".$option['votes_count']." votes'><div class='voteBar' style='font-weight:bold; max-width:".$percentage."%;padding:1px; height:10px;'> </div>".$option['title']."</div>";
- }
- } else {
- foreach ($elem['poll']['options'] as $option){
- $output .= "<div class='polloption'>".$option['title']."</div>";
- }
- $output .= ($logedin ? "<input type='submit' class='vote' id='".$elem['poll']['id']."' value='Send Vote' style='padding:2px;' onClick='return false;'>" : "");
- }
- return $output;
- }
- /* this function is used to generate the html code of a reply */
- function render_reply($item) {
- global $user_settings;
- global $logedin;
- global $srv;
- $reply['mode'] = "";
- if (isset($item['type']) && $item['type'] == 'ancestor') {
- $reply['mode'] = "ancestor";
- }
- $reply['id'] = $item['id'];
- $reply['uid'] = $item['account']['id'];
- $reply['name'] = emojify($item['account']['display_name'], $item['account']['emojis'], 20);
- $reply['acct'] = $item['account']['acct'];
- $reply['handle'] = "@".explode("@",$item['account']['acct'])[0];
- $reply['avatar'] = $item['account']['avatar'];
- $reply['menu'] = "<ul>";
- if ($logedin) {
- $reply['menu'] .= ($item['account']['id'] == $user_settings['uid'] ? "<li><a href='?action=delete&thread=" . $item['id'] . "' onClick='return false;' class='delete fontello' id=':id:'> Delete Post</a></li>" : "");
- $reply['menu'] .= "<li><a href='?action=compose"e=" . $item['id'] . "' onClick='return false;' class='quote fontello' id='" . $item['id'] . "' style='background-color:transparent;'> Quote Post</a></li>";
- $reply['menu'] .= ($item['account']['id'] != $user_settings['uid'] ? "<li><a href='?action=mute&user=" . $item['account']['id'] . "' onClick='return false;' class='mute fontello' id='" . $item['account']['id'] . "' style='background-color:transparent;'> Mute User</a></li>" : "");
- $reply['menu'] .= ($item['account']['id'] != $user_settings['uid'] ? "<li><a href='?action=mute&thread=" . $item['account']['id'] . "' onClick='return false;' class='muteconv fontello' id='" . $item['id'] . "' style='background-color:transparent;'> Drop Thread</a></li>" : "");
- $reply['menu'] .= (isset($user_settings['pleroma']) ? "<li><a href='?action=hide&thread=" . $item['pleroma']['conversation_id'] . "' onClick='return false;' class='hide fontello' id='" . $item['pleroma']['conversation_id'] . "' style='background-color:transparent;'> Hide Thread</a></li>" : "");
- $reply['menu'] .= (isset($user_settings['pleroma']) ? "<li><a href='?action=bookmark&thread=" . $item['account']['id'] . "' onClick='return false;' class='" . ($item['bookmarked'] == true ? "un" : "") . "bookmark fontello' id='" . $item['id'] . "' style='background-color:transparent;'> " . ($item['bookmarked'] == true ? "Unb" : "B") . "ookmark</a></li>" : "");
- $reply['menu'] .= ($item['account']['id'] != $user_settings['uid'] ? "<li><a href='?action=nsfw&user=" . $item['account']['id'] . "' onClick='return false;' class='nsfw fontello' id='" . $item['account']['id'] . "' style='background-color:transparent;'> User is NSFW</a></li>" : "");
- }
- $reply['menu'] .= "<li><a target='_blank' href='" . $item['url'] . "' class='original link fontello' style='background-color:transparent;'> Original Note</a></li>";
- $reply['menu'] .= "</ul>";
- $json['id'] = $item['id'];
- $json['scope'] = $item['visibility'];
- if ($logedin) {
- $json['mentions'] = "";
- $array = $item["mentions"];
- $json['mentions'] = ($user_settings['acct'] == $item["account"]['acct'] ? "" : "@" . $item["account"]['acct']) . " ";
- if (!empty($array)) {
- foreach ($array as $mnt) {
- if ($mnt['acct'] != $user_settings['acct']) {
- $json['mentions'] .= "@" . $mnt['acct'] . " ";
- }
- }
- }
- }
- $reply['json'] = json_encode($json);
- $reply['replyto'] = ($item['in_reply_to_id'] ? " <a class='fontello link preview ldr' target='_blank' id='" . $item['in_reply_to_id'] . "' href='?thread=" . $item['in_reply_to_id'] . "'></a> " : "");
- $reply['text'] = processText($item);
- $reply['date'] = "<a class='ldr postAge' id='".strtotime($item['created_at'])."' style='text-decoration:none;' target='_blank' href='?thread=" . $item['id'] . "'>" . time_elapsed_string($item['created_at']) . "</a>";
- $reply['visibility'] = $item['visibility'];
- $reply['media'] = "";
- if (!empty($item['media_attachments'])) {
- $reply['media'] = "<div style='width:170px; display:inline-block; float:left; margin:15px 0px 10px 0px;'>";
- $images = count($item['media_attachments']);
- $class = ($images > 1 ? "class='icon'" : "");
- foreach ($item['media_attachments'] as $file) {
- $ext = explode(".", $file['url']);
- $ext = end($ext);
- $ext = explode("?", $ext) [0];
- if (in_array($ext,array('webm','mp4','ogv'))) {
- $reply['media'] .= "<div style='text-align:center; width:100%;'><video preload='metadata' width='100%' controls ".($user_settings['videoloop'] == "on" ? "loop" : "").">
- <source src='" . $file['url'] . "' type='video/".($ext == "ogv" ? "ogg" : $ext)."'>
- </video></div>
- ";
- }
- elseif (in_array($ext,array('mp3','ogg','oga','opus'))) {
- $reply['media'] .= "<div style='text-align:center; width:100%;'><audio controls>
- <source src='" . $file['url'] . "' type='audio/$ext'>
- Your browser does not support the audio tag.
- </audio> </div>";
- }
- else {
- if ($item['sensitive'] == true && $user_settings['explicit'] != 'off') {
- $reply['media'] .= "<div style='overflow:hidden; float:left; margin:2px;' $class><a target='_blank' href='" . $file['url'] . "' onClick='return false;' class='blur'><noscript><img src='" . $file['url'] . "' style='width:100%;'></noscript><img " . "data-src='" . $file['url'] . "'" . " class='' style='max-width:100%; max-height:100% vertical-align:middle;'></a><a target='_blank' href='" . $file['url'] . "' onClick='return false;' class='open-lightbox' style='display:none;'><img src='" . $file['url'] . "' class='' style='width:100%;'></a></div>";
- }
- else {
- $reply['media'] .= "<div style='margin:0px;' $class><a target='_blank' href='" . $file['url'] . "' onClick='return false;' class='open-lightbox'><img src='" . $file['url'] . "'" . " class='' style='max-width:100%; max-height:100%; vertical-align:middle;'><noscript><img src='" . $file['url'] . "' style='width:100%;'></noscript></a></div>";
- }
- }
- }
- $reply['media'] .= "</div>";
- }
- $reply['buttons'] = "
- " . ($logedin ? "<div class='felem'><a onClick='return false' class='replyform' href='?thread=" . $item['id'] . "' style='font-family:fontello'></a></div>" : "") . "
- <div class='felem'><a onClick='return false' " . ($logedin ? "class='" . ($item['favourited'] == true ? "unfav" : "fav") . "' href='?action=fav&thread=" . $item['id'] . "'" : "") . " style='font-family:fontello'> <span>" . $item['favourites_count'] . "</span></a></div>
- <div class='felem'><a onClick='return false' " . ($logedin && ($item['visibility'] != "private" || $item['visibility'] != "direct") ? "class='" . ($item['reblogged'] == true ? "unreblog" : "reblog") . "' href='?action=reblog&thread=" . $item['id'] . "'" : "") . " style='font-family:fontello'> <span>" . $item['reblogs_count'] . "</span></a></div>
- ";
- $result = themes("get","templates/reply.txt");
- foreach ($reply as $key => $elem) {
- $result = str_replace(":$key:", $elem, $result);
- }
- return $result;
- }
- /* this is the same as above but is used on other places, like user bios and places where the
- shortcodes and the emoji url is defined in the same place */
- function emojify($string, $emojis, $size = 40) {
- foreach ($emojis as $emoji) {
- $string = str_replace(":" . $emoji['shortcode'] . ":", "<img class='emoji' alt='" . $emoji['shortcode'] . "' title='" . $emoji['shortcode'] . "' src='" . $emoji['url'] . "' height=$size style='vertical-align: middle;'>", $string);
- }
- return $string;
- }
- /* This function displays the emoji list of an instance based on a search
- string given on $val */
- function emoji_list($val){
- $emojilist = api_get("/custom_emojis");
- $c = 0;
- $return = "";
- foreach ($emojilist as $emoji){
- if (starts_with($emoji['shortcode'],$val) && $c < 50){
- $return .= "<img style='margin:1px;' src='".$emoji['static_url']."' class='emoji' title='".$emoji['shortcode']."' height=40>";
- $c++;
- }
- }
- if ($c < 50){
- foreach ($emojilist as $emoji){
- if ((contains($emoji['shortcode'],$val) && !starts_with($emoji['shortcode'],$val)) && $c < 50){
- $return .= "<img style='margin:1px;' src='".$emoji['static_url']."' class='emoji' title='".$emoji['shortcode']."' height=40>";
- $c++;
- }
- }
- }
-
- return $return;
- }
- function contact_search($val){
- global $user_settings;
- $return = "";
- $list = api_get("/accounts/search?q=".$val);
- foreach ($list as $contact){
- $return .= "<div class='contact' title='@".$contact['acct']."' style='width:100%; clear:both; height:40px; display:inline-block;'>
- <div style='width:40px; height:40px; background-size:cover; background-image:url(".$contact['avatar']."); float:left;'></div>
- <div>
- <span style='font-weight:bold;'>".emojify($contact['display_name'], $contact['emojis'], 15)."</span><br>
- <span style='font-size:12px;'>".$contact['acct']."</span>
- </div>
- </div>";
- }
- return $return;
- }
- /* This function will fetch and render all the notifications since an $id
- or get a list of all past notification ($max notifications specified)
- */
- function getnotif($id = false, $max = false) {
- global $srv;
- global $token;
- global $user_settings;
- $n = "";
-
- $exclude = "";
- $exclude .= (str_split($user_settings['notif'])[0] == 0 ? "&exclude_types[]=favourite" : "");
- $exclude .= (str_split($user_settings['notif'])[1] == 0 ? "&exclude_types[]=reblog" : "");
- $exclude .= (str_split($user_settings['notif'])[2] == 0 ? "&exclude_types[]=mention" : "");
- $exclude .= (str_split($user_settings['notif'])[3] == 0 ? "&exclude_types[]=follow" : "");
-
- $notif = api_get("notifications?" . ($id == false ? "limit=9&" : "") . ($id != false ? ($max == true ? "max_id=$id" : "since_id=$id") : "").$exclude);
- if (!empty($notif)) {
- foreach ($notif as $post) {
- if (!isset($post["type"])){
- break;
- }
- $user = "<a class='link ldr uname' style='font-size:12px;' href='?user=" . $post['account']['id'] . "'>" . (empty($post['account']['display_name']) ? $post['account']['acct'] : emojify($post['account']['display_name'], $post['account']['emojis'], 10)) . "</a>";
- $preview = "";
- $buttons = "";
- $media = "";
- if (!in_array($post["type"],array("mention","favourite","reblog","follow"))){
- continue;
- }
- switch ($post["type"]) {
- case "mention":
- if ($post['status']['in_reply_to_id'] == null) {
- $type = "<span class='fontello' style='color:#62C2CC; font-size:10px;'></span>";
- $string = "mentioned you in a post";
- $preview = "<a style='text-decoration:none;' class='ldr text' href='?thread=" . $post['status']['id'] . "' target='_blank'><span style='display:block; opacity:1; font-size:10px; line-height:12px;'>" . emojify(strip_tags(trim($post['status']['content']) , '<br><br \>') , $post['status']['emojis'], 15) . "</span></a>";
- $media = (!empty($post['status']['media_attachments']) ? "<a style='text-decoration:none;' class='ldr' href='?thread=" . $post['status']['id'] . "' target='_blank'><div class='notifpic' style='flex: 0 0 60px; background-size:cover; background-image:url(" . $post['status']['media_attachments'][0]['url'] . ");'></div></a>" : "");
- }
- else {
- $type = "<span class='fontello' style='color:#62C2CC; font-size:10px;'></span>";
- $string = "replied to your post";
- foreach ($post['status']['mentions'] as $mention) {
- if(!contains($post['status']['content'],$mention['username'])) {
- $post['status']['content'] = "@" . $mention['username'] . " ".$post['status']['content'];
- }
- }
-
- $preview = "<a style='text-decoration:none;' class='ldr text' href='?thread=" . $post['status']['id'] . "' target='_blank'><span style='display:block; opacity:1; font-size:10px; line-height:12px;'>" . emojify(strip_tags(trim($post['status']['content']) , '<br><br \>') , $post['status']['emojis'], 15) . "</span></a>";
- $media = (!empty($post['status']['media_attachments']) ? "<div class='notifpic' style='flex: 0 0 60px; background-size:cover; background-image:url(" . $post['status']['media_attachments'][0]['url'] . ");'></div>" : "");
- }
- $array = $post['status']["mentions"];
- $mentions = ($user_settings['acct'] == $post['status']['account']['acct'] ? "" : "@" . $post['status']['account']['acct']) . " ";
- if (!empty($array)) {
- foreach ($array as $mnt) {
- if ($mnt['acct'] != $user_settings['acct']) {
- $mentions .= "@" . $mnt['acct'] . " ";
- }
- }
- }
- $buttons = "<div class='post_buttons' id='" . $post['status']['id'] . "' style='position:absolute; right:10px; bottom:10px; border-radius:60px; padding:5px;'>
- <div class='felem'><a onClick='return false' class='quickreply' id='" . $post['status']['id'] . "' data-mentions='" . $mentions . "' href='?thread=" . $post['status']['id'] . "' style='font-family:fontello'></a></div>
- <div class='felem'><a onClick='return false' class='" . ($post['status']['favourited'] == true ? "unfav" : "fav") . "' href='?action=fav&thread=" . $post['status']['id'] . "'" . " style='font-family:fontello'></a></div>
- <div class='felem'><a onClick='return false' " . ($post['status']['visibility'] == "public" || $post['status']['visibility'] == "unlisted" ? "class='" . ($post['status']['reblogged'] == true ? "unreblog" : "reblog") . "' href='?action=reblog&thread=" . $post['status']['id'] . "'" : "") . " style='font-family:fontello'></a></div></div>";
- break;
- case "favourite":
- $type = "<span class='fontello' style='color:#F17022; font-size:10px;'></span>";
- $string = "favourited your post";
- $preview = "<a style='text-decoration:none;' class='ldr text' href='?thread=" . $post['status']['id'] . "' target='_blank'><span style='display:block; opacity:1; font-size:10px; line-height:12px;'>" . (!empty($post['status']['content']) ? emojify(strip_tags(trim($post['status']['content']) , '<br><br \>') , $post['status']['emojis'], 15) : "Favourited your image") . "</span></a>";
- $media = (!empty($post['status']['media_attachments']) ? "<div class='notifpic' style='flex: 0 0 60px; background-size:cover; background-image:url(" . $post['status']['media_attachments'][0]['url'] . ");'></div>" : "");
- break;
- case "reblog":
- $type = "<span class='fontello' style='color:#D1DC29; font-size:10px;'></span>";
- $string = "reblogged your post";
- $preview = "<a style='text-decoration:none;' class='ldr text' href='?thread=" . $post['status']['id'] . "' target='_blank'><span style='display:block; opacity:1; font-size:10px; line-height:12px;'>" . (!empty($post['status']['content']) ? emojify(strip_tags(trim($post['status']['content']) , '<br><br \>') , $post['status']['emojis'], 15) : "Reblogged your image") . "</span></a>";
- @$media = (!is_null($post['status']['media_attachments']) ? "<div class='notifpic' style='flex: 0 0 60px; background-size:cover; background-image:url(" . $post['status']['media_attachments'][0]['url'] . ");'></div>" : "");
- break;
- case "follow":
- list($info, $rel) = user_info($post["account"]["id"]);
- $type = "<span class='fontello' style='color:#FDB813; font-size;10px;'></span>";
- $preview = "started following you";
- if ($rel[0]['following']) {
- $label = " Following";
- $class = "unfollow";
- }
- else {
- if ($info['locked']) {
- if ($rel[0]['requested']) {
- $label = " Follow Requested";
- $class = "unfollow";
- }
- else {
- $label = " Request Follow";
- $class = "follow";
- }
- }
- else {
- $label = " Follow";
- $class = "follow";
- }
- }
- $buttons .= "<div class='post_buttons' style='position:absolute; right:10px; bottom:10px; border-radius:60px; padding:5px;'><span id='" . $info['id'] . "' class='profileButton $class' style='background-color:white; font-family:sans,fontello ;font-size:13px;'>$label</span></div>";
- break;
- }
- $n .= "
- <div class='notif " . ($id == false ? "" : "new") . "' id='" . $post['id'] . "'>
- <div class='notifContents'>
- <div style='flex: 0 0 60px; background-size:cover; background-image:url(" . $post['account']['avatar'] . "); border-radius:5px;'></div>
- <div style='flex: 1; padding-left:5px; padding-right:5px; word-break: break-word; overflow:hidden;'>
- <span>$type <span style='font-size:12px; font-weight:bold;'>$user</span></span>
- " . trim($preview) . "
- $buttons
- </div>
- $media
- </div>
- </div>
- ";
- }
- return $n;
- }
- }
- /* function to parse opengraph from a html source */
- /* taken from https://ajaxhispano.com/ask/como-obtener-el-protocolo-open-graph-de-una-pagina-web-por-php-109483/ */
- function getOgTags($html)
- {
- $pattern='/<\s*meta\s+property="og:([^"]+)"\s+content="([^"]*)/i';
- if(preg_match_all($pattern, $html, $out))
- return array_combine($out[1], $out[2]);
- return array();
- }
- /* this function takes in a whole post entity and spits out the HTMLfied text of the post
- with the urls and @handles linkified and all the emojis replaced */
- function processText($elem) {
- global $user_settings;
- global $logedin;
- require_once "vendor/simple_html_dom.php";
- $content = trim(html_entity_decode($elem['content'],ENT_QUOTES));
- $content = preg_replace("/<(?=[^>]*(?:<|$))/","<",$content);
-
- if (!empty($content)) {
- $html = str_get_html($content);
- foreach ($html->find('a') as $lnk) {
-
- //remove text links to media attachments
- foreach ($elem['media_attachments'] as $f) {
- if (is_numeric(strpos($f['description'],explode("…",$lnk->innertext)[0]))) {
- $content = str_replace($lnk->outertext . "<br/>", null, $content);
- $content = str_replace("<br/>" . $lnk->outertext, null, $content);
- $content = str_replace($lnk->outertext, null, $content);
- }
- }
-
- //modify links for hashtags and external urls
- if (is_numeric(strpos($lnk->href, $user_settings['instance'])) || in_array($lnk->class, array(
- "u-url mention",
- "hashtag"
- )) || $lnk->rel == "tag") {
- $content = str_replace($lnk->outertext, $lnk->innertext, $content);
- }
- else {
- $prv = $lnk->outertext;
- $lnk->target = '_blank';
- $lnk->class = 'link external';
- $content = str_replace($prv, $lnk->outertext, $content);
- }
- }
- }
-
- $result = strip_tags($content, '<br><p><strong><a><em><strike>');
- $result = str_replace('<br />', ' <br>', $result);
-
- foreach ($elem['mentions'] as $mention) {
- if(contains($result,"@".$mention['username'])) {
- $result = str_replace("@" . $mention['username'], "<span class='user' id='" . $mention['id'] . "'><a href='?user=" . $mention['id'] . "' class='link ldr' onClick='return false;'>@" . $mention['username'] . "</a></span>", $result);
- } else {
- $result = "<span class='user' id='" . $mention['id'] . "'><a href='?user=" . $mention['id'] . "' class='link ldr' onClick='return false;'>@" . $mention['username'] . "</a></span> ".$result;
- }
- }
- $result = emojify($result, $elem['emojis']);
-
- /* We convert hashtags to clickable links. The regex detects only strings that are not part of an url.
- If the user is not logged in, it just shows the hashtag in bold.
- Regex expression got it from here https://stackoverflow.com/questions/39414007/php-find-all-hashtags-but-no-in-link
- */
- if ($logedin){
- $result = preg_replace("!(?:f|ht)tps?://[-a-zA-Zа-яА-Я()0-9@:%_+.~#?&;/=]+(*SKIP)(*F)|#(\w+)!", "<a class='ldr' href=\"./?tag=$1\"><b>#$1</b></a>", $result);
- } else {
- $result = preg_replace("!(?:f|ht)tps?://[-a-zA-Zа-яА-Я()0-9@:%_+.~#?&;/=]+(*SKIP)(*F)|#(\w+)!", "<b>#$1</b>", $result);
- }
- return $result;
- }
- // OTHER FUNCTIONS
- /* the purpose of this function is to encode the auth token
- it is not used for now */
- function msc($string, $action = 'e') {
- // you may change these values to your own
- $secret_key = 'yAmfVhZwm0749FSY24dC';
- $secret_iv = 'm37uvAeKjYLKdI1lPkcJ';
- $output = false;
- $encrypt_method = "AES-256-CBC";
- $key = hash('sha256', $secret_key);
- $iv = substr(hash('sha256', $secret_iv) , 0, 16);
- if ($action == 'e') {
- $output = base64_encode(openssl_encrypt($string, $encrypt_method, $key, 0, $iv));
- }
- else if ($action == 'd') {
- $output = openssl_decrypt(base64_decode($string) , $encrypt_method, $key, 0, $iv);
- }
- return $output;
- }
- /* this function extracts the urls from a text and return them in an array */
- function get_urls($input) {
- $pattern = '$(https?://[a-z0-9_./?=&-~]+)(?![^<>]*>)$i';
- if (preg_match_all($pattern, $input, $matches)) {
- list($dummy, $links) = ($matches);
- return $links;
- }
- return false;
- }
- /* general function to check if one strings starts with a given search */
- function starts_with($string,$search){
- if (substr(strtolower($string),0,strlen($search)) == strtolower($search)){
- return true;
- }
- return false;
- }
- /* general function to check if one strings contains with a given search */
- function contains($string,$search){
- if (is_numeric(strpos(strtolower($string),strtolower($search)))){
- return true;
- }
- return false;
- }
- /* same as avobe but check against all elements of an array */
- function contains_any($where, $array)
- {
- $n = 1;
- foreach ($array as $elem)
- {
- if (is_numeric(strpos($where, $elem)))
- {
- return $n;
- }
- $n++;
- }
- return false;
- }
- /* this function just reduces an image to a 1x1 pixel image to get the overall color.
- */
- function averageColor($url) {
- @$image = imagecreatefromstring(file_get_contents($url));
- if (!$image) {
- $mainColor = "CCCCCC";
- }
- else {
- $thumb = imagecreatetruecolor(1, 1);
- imagecopyresampled($thumb, $image, 0, 0, 0, 0, 1, 1, imagesx($image) , imagesy($image));
- $mainColor = strtoupper(dechex(imagecolorat($thumb, 0, 0)));
- }
- return $mainColor;
- }
- /* function used in the process of uploading a file */
- function get_mime($filename) {
- $result = new finfo();
- if (is_resource($result) === true) {
- return $result->file($filename, FILEINFO_MIME_TYPE);
- }
- return false;
- }
- function sanitize($text){
- return preg_replace("/[^a-zA-Z0-9.]+/", "", $text);
- }
- function themes($mode,$name = false){
- global $user_settings;
- switch ($mode){
- case "list":
- $themes = scandir("themes/");
- $themelist = array();
- foreach ($themes as $elem){
- if ($elem != ".." && $elem != "." && $elem != "custom" && is_dir("themes/".$elem)){
- $themelist[] = $elem;
- }
- }
- return $themelist;
-
- case "file":
- $theme = sanitize($user_settings['theme']);
- if (file_exists("themes/$theme/$name")){
- return "themes/$theme/$name";
- } else {
- return "$name";
- }
-
- case "get":
- $theme = sanitize($user_settings['theme']);
- if (file_exists("themes/$theme/$name")){
- return file_get_contents("themes/$theme/$name");
- } else {
- return file_get_contents("$name");
- }
- }
- }
- function time_elapsed_string($datetime, $full = false) {
- $now = new DateTime;
- $ago = new DateTime($datetime);
- $diff = $now->diff($ago);
- $diff->w = floor($diff->d / 7);
- $diff->d -= $diff->w * 7;
- $string = array(
- 'y' => 'year',
- 'm' => 'month',
- 'w' => 'week',
- 'd' => 'day',
- 'h' => 'hour',
- 'i' => 'minute',
- 's' => 'second',
- );
- foreach ($string as $k => &$v) {
- if ($diff->$k) {
- $v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
- } else {
- unset($string[$k]);
- }
- }
- if (!$full) $string = array_slice($string, 0, 1);
- return $string ? implode(', ', $string) . ' ago' : 'just now';
- }
- function getHeaders($respHeaders) {
- $headers = array();
- $headerText = substr($respHeaders, 0, strpos($respHeaders, "\r\n\r\n"));
- foreach (explode("\r\n", $headerText) as $i => $line) {
- if ($i === 0) {
- $headers['http_code'] = $line;
- } else {
- list ($key, $value) = explode(': ', $line);
- $headers[$key] = $value;
- }
- }
- return $headerText;
- }
|