+
+ // Methods to detect server types
+
+ // Non endpoint specific methods
+ const DETECT_MANUAL = 0;
+ const DETECT_HEADER = 1;
+ const DETECT_BODY = 2;
+
+ // Implementation specific endpoints
+ const DETECT_FRIENDIKA = 10;
+ const DETECT_FRIENDICA = 11;
+ const DETECT_STATUSNET = 12;
+ const DETECT_GNUSOCIAL = 13;
+ const DETECT_CONFIG_JSON = 14; // Statusnet, GNU Social, Older Hubzilla/Redmatrix
+ const DETECT_SITEINFO_JSON = 15; // Newer Hubzilla
+ const DETECT_MASTODON_API = 16;
+ const DETECT_STATUS_PHP = 17; // Nextcloud
+ const DETECT_V1_CONFIG = 18;
+ const DETECT_PUMPIO = 19;
+
+ // Standardized endpoints
+ const DETECT_STATISTICS_JSON = 100;
+ const DETECT_NODEINFO_1 = 101;
+ const DETECT_NODEINFO_2 = 102;
+
+ /**
+ * Check for the existance of a server and adds it in the background if not existant
+ *
+ * @param string $url
+ * @param boolean $only_nodeinfo
+ * @return void
+ */
+ public static function add(string $url, bool $only_nodeinfo = false)
+ {
+ if (self::getID($url, false)) {
+ return;
+ }
+
+ Worker::add(PRIORITY_LOW, 'UpdateGServer', $url, $only_nodeinfo);
+ }
+
+ /**
+ * Get the ID for the given server URL
+ *
+ * @param string $url
+ * @param boolean $no_check Don't check if the server hadn't been found
+ * @return int gserver id
+ */
+ public static function getID(string $url, bool $no_check = false)
+ {
+ if (empty($url)) {
+ return null;
+ }
+
+ $url = self::cleanURL($url);
+
+ $gserver = DBA::selectFirst('gserver', ['id'], ['nurl' => Strings::normaliseLink($url)]);
+ if (DBA::isResult($gserver)) {
+ Logger::info('Got ID for URL', ['id' => $gserver['id'], 'url' => $url, 'callstack' => System::callstack(20)]);
+ return $gserver['id'];
+ }
+
+ if ($no_check || !self::check($url)) {
+ return null;
+ }
+
+ return self::getID($url, true);
+ }
+
+ /**
+ * Retrieves all the servers which base domain are matching the provided domain pattern
+ *
+ * The pattern is a simple fnmatch() pattern with ? for single wildcard and * for multiple wildcard
+ *
+ * @param string $pattern
+ * @return array
+ * @throws Exception
+ */
+ public static function listByDomainPattern(string $pattern): array
+ {
+ $likePattern = 'http://' . strtr($pattern, ['_' => '\_', '%' => '\%', '?' => '_', '*' => '%']);
+
+ // The SUBSTRING_INDEX returns everything before the eventual third /, which effectively trims an
+ // eventual server path and keep only the server domain which we're matching against the pattern.
+ $sql = "SELECT `gserver`.*, COUNT(*) AS `contacts`
+ FROM `gserver`
+ LEFT JOIN `contact` ON `gserver`.`id` = `contact`.`gsid`
+ WHERE SUBSTRING_INDEX(`gserver`.`nurl`, '/', 3) LIKE ?
+ AND NOT `gserver`.`failed`
+ GROUP BY `gserver`.`id`";
+
+ $stmt = DI::dba()->p($sql, $likePattern);
+
+ return DI::dba()->toArray($stmt);
+ }
+