$toot['id'], 'date' => $toot['created_at'] ,'url' => analyzeToot($instance, $toot['id'], $searchurl)); } return($json); } /* Find out if a toot contains the searched URL */ function analyzeToot($instance, $id, $searchurl) { debug("Searching for $searchurl in $id"); $raw = file_get_contents("$instance/api/v1/statuses/$id"); $json = json_decode($raw, true); preg_match("|$searchurl.+?(?=\")|i", $json['content'], $matches); if(!empty($matches)) { return(strtolower($matches[0])); } else { return(""); } } /* Collect all the toots */ /* get id of latest cached toot, and set as $min_id */ read_db($dbt, $toots); $toots_cached = $toots; if (!empty($toots['0']['id'])) { $min_id_cached = $toots['0']['id']; $min_id = $min_id_cached; } else { /* if cached toots do not exist, start from oldest toot */ $min_id = "0"; $min_id_cached = "0"; } /* test whether there are new toots available */ // Search for toots older than the cached latest toot ID ($min_id) $uptodate = false; while ($uptodate === false) { $toots = array_merge(collectToots($instance, $uid, $min_id, $searchurl), $toots); $min_id_new = $toots['0']['id']; // the latest ID of the recent search if ($min_id_new === $min_id) { // min_id is the latest, let's write the new DB and end this loop $uptodate = true; debug("Rewrite cache DB."); write_db($dbt, $toots); } else { // next round looks for toots newer than the newly found ID debug("Newer toots than in cache found. Starting another search for new toots"); $min_id = $min_id_new; } } /* check if URL from $search exists in $toots */ // if multiple exist, take the oldest one (highest array position) $id = array_keys(array_column($toots, 'url'), strtolower($search)); if (empty($id)) { debug("Blog URL \"$search\" has not been found"); die(); } $id = $toots[end($id)]['id']; /* Extract comments and stats from toot */ $result = ['comments' => [], 'stats' => ['reblogs' => 0, 'favs' => 0, 'replies' => 0, 'url' => '', 'root' => 0]]; function filterComments($descendants, $root, &$result) { foreach ($descendants as $d) { $result['comments'][$d['id']] = [ 'author' => [ 'display_name' => $d['account']['display_name'] ? $d['account']['display_name'] : $d['account']['username'], 'avatar' => $d['account']['avatar_static'], 'url' => $d['account']['url'] ], 'toot' => $d['content'], 'date' => $d['created_at'], 'url' => $d['uri'], 'reply_to' => $d['in_reply_to_id'], 'root' => $root, ]; } return $result; } function tootContext($instance, $id, &$result) { $raw = file_get_contents("$instance/api/v1/statuses/$id/context"); $json = json_decode($raw, true); filterComments($json['descendants'], $id, $result); } function filterStats($stats) { $result = [ 'reblogs' => (int)$stats['reblogs_count'], 'favs' => (int)$stats['favourites_count'], 'replies' => (int)$stats['replies_count'], 'url' => $stats['url'] ]; return $result; } function tootStats($instance, $id, &$result) { debug("Checking ID $id"); $raw = file_get_contents("$instance/api/v1/statuses/$id"); $json = json_decode($raw, true); $newStats = filterStats($json); $result['stats']['reblogs'] += $newStats['reblogs']; $result['stats']['favs'] += $newStats['favs']; $result['stats']['replies'] += $newStats['replies']; if (empty($result['stats']['url'])) { $result['stats']['url'] = $newStats['url']; } } // FIXME: At the moment the API doesn't return the correct replies count so I count it manually $result['stats']['replies'] = count($result['comments']); $result['stats']['root'] = $id; tootContext($instance, $id, $result); tootStats($instance, $id, $result); // headers for not caching the results header('Cache-Control: no-cache, must-revalidate'); header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // headers to tell that result is JSON header('Content-type: application/json'); echo json_encode($result); ?>