users.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. <?php
  2. if (!defined('N')) {
  3. echo('You probably meant <a href="'.preg_replace('/\.php$/','',$_SERVER['REQUEST_URI']).'">this</a>.');
  4. exit(0);
  5. }
  6. echo('</nav>
  7. <div class="scrwide">
  8. <div class="scrwidein">
  9. <section class="sectcontm">
  10. <h3>Under construction.</h3>
  11. </section>
  12. </div>
  13. </div>'.N);
  14. exit(0);
  15. $bt=microtime(true);
  16. $dlanguc=strtoupper($dlang);
  17. $lc=localeconv();
  18. require '../lib/n2es.php';
  19. require '../lib/tables.php';
  20. require '../lib/grace.php';
  21. require '../lib/fnum.php';
  22. use function mysqli_real_escape_string as myesc;
  23. /*$dlang='fr';
  24. $dtzbl=array('ca'=>'Europe/Madrid','en'=>'Europe/London','es'=>'Europe/Madrid','fr'=>'Europe/Paris','it'=>'Europe/Rome');
  25. date_default_timezone_set($dtzbl[$dlang]);*/
  26. $debug='';
  27. $debug.='REQUEST_URI: '.$_SERVER['REQUEST_URI'].N;
  28. $debug.='$_GET: '.print_r($_GET,1);
  29. $debug.='LOCALE: '.$locale.N;
  30. if (array_key_exists('id',$_GET) && preg_match('/^\d+$/',$_GET['id'])) {
  31. $_GET['id']+=0;
  32. $single=true;
  33. } else {
  34. $single=false;
  35. }
  36. //$getc=count($_GET);
  37. //forzo $getc a 1 per non mostrare mai la spiega di come funziona il motore di ricerca
  38. $getc=1;
  39. if (array_key_exists('advc',$_GET)) {
  40. ($_GET['advc']=='1') ? $_GET['advc']=1 : $_GET['advc']=0;
  41. } else {
  42. $_GET['advc']=0;
  43. }
  44. $minudef=10;
  45. $minumax=10000000000;
  46. $maxudef=30000;
  47. $maxumax=10000000000;
  48. $minaudef=10;
  49. $minaumax=10000000;
  50. $minkidef=500;
  51. $minkimax=100000;
  52. echo('</nav>
  53. <div class="scrwide">
  54. <div class="scrwidein">
  55. <section class="sectcontm">
  56. <img src="'.$prepath.'imgs/helpbutti.svg" id="helpbutt" class="helpb" onmouseover="swhelpi(true);" onmouseout="swhelpi(false);" onclick="swhelp();">
  57. <h3>'._('Users').'</h3>
  58. <script language="JavaScript">
  59. let mctrlsh=false;
  60. function shmctrl() {
  61. let mctrl=document.getElementById("mctrl");
  62. let mctrlb=document.getElementById("mctrlb");
  63. let advc=document.getElementById("advc");
  64. if (mctrlsh) {
  65. //mctrl.style.display="none";
  66. mctrl.style.height="0px";
  67. //mctrlb.className="litbut";
  68. mctrlb.value="'._('Show advanced criteria').'";
  69. advc.value=0;
  70. mctrlsh=false;
  71. } else {
  72. //mctrl.style.display="block";
  73. mctrl.style.height=mctrl.scrollHeight+"px";
  74. //mctrlb.className="litbuta";
  75. mctrlb.value="'._('Hide advanced criteria').'";
  76. advc.value=1;
  77. mctrlsh=true;
  78. }
  79. }
  80. let helpsh='.(($getc==0) ? 'false' : 'true').';
  81. function swhelp() {
  82. let hdiv=document.getElementById("help");
  83. let himg=document.getElementById("helpbutt");
  84. if (helpsh) {
  85. //hdiv.style.display="none";
  86. hdiv.style.height="0px";
  87. himg.title="'._('Show introduction').'";
  88. himg.src="'.$prepath.'imgs/helpbutti.svg";
  89. helpsh=false;
  90. } else {
  91. //hdiv.style.display="block";
  92. hdiv.style.height=hdiv.scrollHeight+"px";
  93. himg.title="'._('Hide introduction').'";
  94. himg.src="'.$prepath.'imgs/helpbutta.svg";
  95. helpsh=true;
  96. }
  97. }
  98. function swhelpi(over) {
  99. let himg=document.getElementById("helpbutt"), ia;
  100. if (helpsh) {
  101. (over) ? ia="i" : ia="a";
  102. } else {
  103. (over) ? ia="a" : ia="i";
  104. }
  105. himg.src="'.$prepath.'imgs/helpbutt"+ia+".svg";
  106. }
  107. function swp(pn) {
  108. document.curvf.p.value=pn;
  109. document.curvf.submit();
  110. }
  111. function sethid(obj) {
  112. if (document.getElementById("cb"+obj).checked)
  113. document.getElementById(obj).value=1;
  114. else
  115. document.getElementById(obj).value=0;
  116. ckadvcri();
  117. }
  118. let advcri=true;
  119. function ckadvcri() {
  120. if (document.getElementById("minu").value!='.$minudef.' ||
  121. document.getElementById("maxu").value!='.$maxudef.' ||
  122. document.getElementById("minau").value!='.$minaudef.' ||
  123. document.getElementById("minki").value!='.$minkidef.' ||
  124. document.getElementById("cbnoxious").checked==false ||
  125. document.getElementById("cbcreg").checked==false ||
  126. document.getElementById("cbappr").checked==true ||
  127. document.getElementById("cblcok").checked==true) {
  128. document.getElementById("disadvcrib").value="'._('Reset all advanced criteria to default').'";
  129. advcri=false;
  130. } else {
  131. document.getElementById("disadvcrib").value="'._('Disable all advanced criteria').'";
  132. advcri=true;
  133. }
  134. }
  135. function endisadvcri() {
  136. if (advcri) {
  137. document.getElementById("minu").value="";
  138. document.getElementById("maxu").value="";
  139. document.getElementById("minau").value="";
  140. document.getElementById("minki").value="";
  141. document.getElementById("cbnoxious").checked=false;
  142. document.getElementById("noxious").value=0;
  143. document.getElementById("cbcreg").checked=false;
  144. document.getElementById("creg").value=0;
  145. document.getElementById("cbappr").checked=false;
  146. document.getElementById("appr").value=0;
  147. document.getElementById("cblcok").checked=false;
  148. document.getElementById("lcok").value=0;
  149. } else {
  150. document.getElementById("minu").value='.$minudef.';
  151. document.getElementById("maxu").value='.$maxudef.';
  152. document.getElementById("minau").value='.$minaudef.';
  153. document.getElementById("minki").value='.$minkidef.';
  154. document.getElementById("cbnoxious").checked=true;
  155. document.getElementById("noxious").value=1;
  156. document.getElementById("cbcreg").checked=true;
  157. document.getElementById("creg").value=1;
  158. document.getElementById("cbappr").checked=false;
  159. document.getElementById("appr").value=0;
  160. document.getElementById("cblcok").checked=false;
  161. document.getElementById("lcok").value=0;
  162. }
  163. ckadvcri();
  164. }
  165. </script>
  166. '.N);
  167. function nullemp($inp) {
  168. if (is_null($inp) || preg_match('/^\s*$/',$inp)===1) return(true);
  169. return(false);
  170. }
  171. function ldate($ts,$dateonly=false) {
  172. if (nullemp($ts)) return(null);
  173. $ts=round($ts);
  174. if (!$dateonly)
  175. return(gmdate('d/m/Y H:i:s e',$ts));
  176. else
  177. return(gmdate('d/m/Y',$ts));
  178. }
  179. function hspech($str) {
  180. if (nullemp($str)) return(null);
  181. return(htmlspecialchars($str,ENT_QUOTES|ENT_HTML5,'UTF-8'));
  182. }
  183. function muorimeglio($msg,$close) {
  184. global $link;
  185. if ($close)
  186. mysqli_close($link);
  187. echo('<p>'.$msg.'</p>'.N.'</section>'.N.'</div>'.N.'</div>'.N.'</body>'.N);
  188. exit(2);
  189. }
  190. function nully($str) {
  191. // "Not available" in singular form - translators, please omit "{singular}" from translation,
  192. // it's there just to diversify this "Not available" from the next one
  193. if (nullemp($str)) return('<span class="null">'._('Not available{singular}').'</span>');
  194. return($str);
  195. }
  196. function nullyp($str) {
  197. // "Not available" in plural form - translators, please omit "{plural}" from translation,
  198. // it's there just to diversify this "Not available" from the previous one
  199. if (nullemp($str)) return('<span class="null">'._('Not available{plural}').'</span>');
  200. return($str);
  201. }
  202. function strip($str,$uri) {
  203. if (nullemp($str)) return(null);
  204. while (preg_match('#^\s*<br\s*[\\\/]?>#',$str)===1) $str=preg_replace('#^\s*<br\s*[\\\/]?>#','',$str);
  205. while (preg_match('#<br\s*[\\\/]?>\s*$#',$str)===1) $str=preg_replace('#<br\s*[\\\/]?>\s*$#','',$str);
  206. while (preg_match('#<br\s*[\\\/]?>\s*<br\s*[\\\/]?>#s',$str)===1)
  207. $str=preg_replace('#<br\s*[\\\/]?>\s*<br\s*[\\\/]?>#s','<br>',$str);
  208. $str=preg_replace('#<style( [^>]*)?>.*</style>#s','',$str);
  209. $str=preg_replace('#<a href="(?![a-zA-Z]+://)([^"]+)#','<a href="https://'.$uri.'$1>',$str);
  210. $str=preg_replace('#<h[1-9][^>]*>#','<p><strong>',$str);
  211. $str=preg_replace('#</h[1-9]>#','</strong></p>',$str);
  212. $str=preg_replace(array('#</p><br>#','#</li><br>#','#</ul><br>#','#<ul><br>#'),array('</p>','</li>','</ul>','<ul>'),$str);
  213. $str=preg_replace('#<b>#','<strong>',$str);
  214. $str=preg_replace('#</b>#','</strong>',$str);
  215. $str=preg_replace('#<p></p>#','',$str);
  216. $str=strip_tags($str,'<a><br><ol><ul><li><p><div><i><b><strong><em><small><img>');
  217. return($str);
  218. }
  219. $link=mysqli_connect($conf['db_host'],$conf['db_user_name'],$conf['db_user_password'],$conf['db_name'],$conf['db_port'],$conf['db_socket']) or muorimeglio(_('Couldn’t connect to database: ').mysqli_connect_error().' ['.mysqli_connect_errno().']',false);
  220. mysqli_set_charset($link,'utf8mb4');
  221. $tables=tables($link);
  222. $res=mysqli_query($link,'SELECT COUNT(ID) AS totusers FROM Users') or muorimeglio(__LINE__.': '.mysqli_error($link),true);
  223. $row=mysqli_fetch_assoc($res);
  224. echo(_('<div id="help" class="helpd"><p class="intro">This is our search engine for Mastodon users. It works this way...</p></div>').N);
  225. printf(_('<p class="introe">We currently count <span class="statd">%s</span> Mastodon users.</p>').N, fnum($row['totusers'],$lc,0));
  226. if ((array_key_exists('noxious',$_GET) && $_GET['noxious']=='1') || !array_key_exists('noxious',$_GET)) {
  227. $_GET['cbnoxious']=' checked';
  228. $_GET['noxious']=1;
  229. } else {
  230. $_GET['cbnoxious']='';
  231. $_GET['noxious']=0;
  232. }
  233. //echo('<p>noxious: '.$_GET['noxious'].'</p>');
  234. if ((array_key_exists('creg',$_GET) && $_GET['creg']=='1') || !array_key_exists('creg',$_GET)) {
  235. $_GET['cbcreg']=' checked';
  236. $_GET['creg']=1;
  237. } else {
  238. $_GET['cbcreg']='';
  239. $_GET['creg']=0;
  240. }
  241. if (array_key_exists('appr',$_GET) && $_GET['appr']=='1') {
  242. $_GET['cbappr']=' checked';
  243. $_GET['appr']=1;
  244. } else {
  245. $_GET['cbappr']='';
  246. $_GET['appr']=0;
  247. }
  248. if (array_key_exists('lcok',$_GET) && $_GET['lcok']=='1') {
  249. $_GET['cblcok']=' checked';
  250. $_GET['lcok']=1;
  251. } else {
  252. $_GET['cblcok']='';
  253. $_GET['lcok']=0;
  254. }
  255. if (array_key_exists('lang',$_GET)) {
  256. if (preg_match('#^[0-9]+$#',$_GET['lang'])===1)
  257. $_GET['lang']=$_GET['lang']+0;
  258. else
  259. $_GET['lang']=0;
  260. } else {
  261. $res=mysqli_query($link,'SELECT ID FROM Languages WHERE Code="'.$dlang.'"') or muorimeglio(__LINE__.': '.mysqli_error($link),true);
  262. if (mysqli_num_rows($res)>0) {
  263. $row=mysqli_fetch_assoc($res);
  264. $_GET['lang']=$row['ID'];
  265. } else {
  266. $_GET['lang']=0;
  267. }
  268. }
  269. if ($_GET['lang']>5000000000) $_GET['lang']=0;
  270. if (array_key_exists('desc',$_GET) && preg_match('#^.+$#',$_GET['lang'])===1)
  271. $_GET['desc']=trim(n2es($_GET['desc']));
  272. else
  273. $_GET['desc']='';
  274. if (mb_strlen($_GET['desc'])>64) $_GET['desc']='';
  275. function ckgnum($key,$def,$max) {
  276. if (array_key_exists($key,$_GET)) {
  277. $_GET[$key]=trim($_GET[$key]);
  278. if (preg_match('#^[0-9]+$#',$_GET[$key])===1) {
  279. $_GET[$key]=$_GET[$key]+0;
  280. if ($_GET[$key]>$max) $_GET[$key]=$max;
  281. } elseif ($_GET[$key]!='') {
  282. $_GET[$key]=$def;
  283. }
  284. } else {
  285. $_GET[$key]=$def;
  286. }
  287. }
  288. ckgnum('minu',$minudef,$minumax);
  289. ckgnum('maxu',$maxudef,$maxumax);
  290. if (is_int($_GET['maxu']) && is_int($_GET['minu']) && $_GET['maxu']<$_GET['minu']) $_GET['maxu']=$_GET['minu'];
  291. ckgnum('minau',$minaudef,$minaumax);
  292. ckgnum('minki',$minkidef,$minkimax);
  293. $order=array(
  294. 'rand'=>array('t'=>_('Random, recommended first'),'q'=>'Instances.Priority DESC, Instances.RPos ASC'),
  295. // 'feat'=>array('t'=>_('Prima le consigliate'),'q'=>'Instances.Priority DESC'),
  296. // partecipazione: totusers/activeusers
  297. // 'part'=>array('t'=>_('Partecipazione (decr.)'),'q'=>'(Instances.UserCount / Instances.ActiveUsersMonth) ASC'),
  298. 'tusersa'=>array('t'=>_('By number of users, ascending'),'q'=>'Instances.UserCount ASC'),
  299. 'tusersd'=>array('t'=>_('By number of users, descending'),'q'=>'Instances.UserCount DESC'),
  300. 'ausersd'=>array('t'=>_('By number of active users, descending'),'q'=>'Instances.ActiveUsersMonth DESC'),
  301. 'kinstsd'=>array('t'=>_('By number of known instances, descending'),'q'=>'Instances.DomainCount DESC'),
  302. 'charsd'=>array('t'=>_('By maximum number of characters per toot, descending'),'q'=>'Instances.MaxTootChars DESC'),
  303. // 'open'=>array('t'=>_('Prima quelle con iscriz. aperte'),'q'=>'Instances.RegOpen DESC, Instances.RegReqApproval ASC'),
  304. // 'alph'=>array('t'=>_('Alfabetico'),'q'=>'Instances.URI ASC'),
  305. // new non ha senso di esistere visto che c'è firstseen
  306. // 'name'=>array('t'=>_('Nome (crescente)'),'q'=>'Instances.Title ASC'),
  307. // 'admc'=>array('t'=>_('Data creazione account admin'),'q'=>'IF (Instances.AdmCreatedAt IS NULL, 9999999999, Instances.AdmCreatedAt) ASC'),
  308. // 'fseena'=>array('t'=>_('Data di “avvistamento” cresc.'),'q'=>'Instances.FirstSeen ASC'),
  309. // 'fseend'=>array('t'=>_('Data di “avvistamento” decr.'),'q'=>'Instances.FirstSeen DESC'),
  310. );
  311. if (!(array_key_exists('ord',$_GET) && array_key_exists($_GET['ord'],$order)))
  312. $_GET['ord']='rand';
  313. if ($_GET['lang']==0) $order['rand']=array('t'=>_('Random'),'q'=>'Instances.RPos ASC');
  314. $p=1;
  315. if (array_key_exists('p',$_GET) && preg_match('#^[0-9]+$#',$_GET['p'])===1) $p=$_GET['p']+0;
  316. echo('<form method="get" id="curvf" name="curvf">
  317. <input name="advc" type="hidden" value="'.$_GET['advc'].'">
  318. <input name="noxious" type="hidden" value="'.$_GET['noxious'].'">
  319. <input name="creg" type="hidden" value="'.$_GET['creg'].'">
  320. <input name="appr" type="hidden" value="'.$_GET['appr'].'">
  321. <input name="lcok" type="hidden" value="'.$_GET['lcok'].'">
  322. <input name="lang" type="hidden" value="'.$_GET['lang'].'">
  323. <input name="desc" type="hidden" value="'.htmlentities($_GET['desc']).'">
  324. <input name="minu" type="hidden" value="'.$_GET['minu'].'">
  325. <input name="maxu" type="hidden" value="'.$_GET['maxu'].'">
  326. <input name="minau" type="hidden" value="'.$_GET['minau'].'">
  327. <input name="minki" type="hidden" value="'.$_GET['minki'].'">
  328. <input name="ord" type="hidden" value="'.$_GET['ord'].'">
  329. <input name="p" type="hidden" value="'.$p.'">
  330. </form>'.N);
  331. ($_GET['lang']==0) ? $selected=' selected' : $selected='';
  332. echo('<form method="get" id="searchf" class="sdbox" onsubmit="document.getElementById(\'p\').value=1;">
  333. <div class="sdtit">'._('Search criteria').'</div>
  334. <div class="sdrow">
  335. <div class="sdlabel"><label for="display_name" title="'._('Include only users whose “display name” contains this string').'">'._('“Display name” contains').'</label></div>
  336. <div class="sdinput"><input type="text" id="display_name" name="display_name" class="sinput" maxlength="'.$tables['Users']['display_name'].'" value="'.hspech($_GET['display_name']).'"></div>
  337. </div>
  338. <div class="sdrow">
  339. <div class="sdlabel"><label for="username" title="'._('Include only users whose username contains this string').'">'._('Username contains').'</label></div>
  340. <div class="sdinput"><input type="text" id="username" name="username" class="sinput" maxlength="'.$tables['Users']['username'].'" value="'.hspech($_GET['username']).'"></div>
  341. </div>
  342. <div id="mctrl">
  343. <div class="sdrow">
  344. <input type="button" class="litbut" id="disadvcrib" value="'._('Disable all advanced criteria').'" onclick="endisadvcri();">
  345. </div>
  346. <div class="sdrow">
  347. <div class="sdlabel"><label for="minu" title="'._('Include only instances which have at least this number of users (set to empty to disable this criterion)').'">'._('Minimum number of users is').'</label></div>
  348. <div class="sdinput"><input type="number" id="minu" name="minu" min="0" max="'.$minumax.'" class="sinput" value="'.$_GET['minu'].'" onchange="ckadvcri();"></div>
  349. </div>
  350. <div class="sdrow">
  351. <div class="sdlabel"><label for="maxu" title="'._('Include only instances which have at most this number of users (set to empty to disable this criterion)').'">'._('Maximum number of users is').'</label></div>
  352. <div class="sdinput"><input type="number" id="maxu" name="maxu" min="0" max="'.$maxumax.'" class="sinput" value="'.$_GET['maxu'].'" onchange="ckadvcri();"></div>
  353. </div>
  354. <div class="sdrow">
  355. <div class="sdlabel"><label for="minau" title="'._('Include only instances which had at least this number of active users during the last 30 days (set to empty to disable this criterion)').'">'._('Minimum number of active users is').'</label></div>
  356. <div class="sdinput"><input type="number" id="minau" name="minau" min="0" max="'.$minaumax.'" class="sinput" value="'.$_GET['minau'].'" onchange="ckadvcri();"></div>
  357. </div>
  358. <div class="sdrow">
  359. <div class="sdlabel"><label for="minki" title="'._('Include only instances which know at least this number of other instances (set to empty to disable this criterion)').'">'._('Minimum number of known instances is').'</label></div>
  360. <div class="sdinput"><input type="number" id="minki" name="minki" min="0" max="'.$minkimax.'" class="sinput" value="'.$_GET['minki'].'" onchange="ckadvcri();"></div>
  361. </div>
  362. <div class="sdrow">
  363. <div class="sdlabel"><label for="cbnoxious" title="'._('Exclude noxious instances').'">'._('Exclude noxious').'</label></div>
  364. <div class="sdinput">
  365. <input type="checkbox" class="sckbox" id="cbnoxious" value="1"'.$_GET['cbnoxious'].' onchange="sethid(\'noxious\');">
  366. <input type="hidden" id="noxious" name="noxious" value="'.$_GET['noxious'].'">
  367. </div>
  368. </div>
  369. <div class="sdrow">
  370. <div class="sdlabel"><label for="cbcreg" title="'._('Exclude instances which don’t accept new registrations').'">'._('Exclude if registrations are closed').'</label></div>
  371. <div class="sdinput">
  372. <input type="checkbox" class="sckbox" id="cbcreg" value="1"'.$_GET['cbcreg'].' onchange="sethid(\'creg\');">
  373. <input type="hidden" id="creg" name="creg" value="'.$_GET['creg'].'">
  374. </div>
  375. </div>
  376. <div class="sdrow">
  377. <div class="sdlabel"><label for="cbappr" title="'._('Exclude instances on which admin approval is required for registration').'">'._('Exclude if registration requires approval').'</label></div>
  378. <div class="sdinput">
  379. <input type="checkbox" class="sckbox" id="cbappr" value="1"'.$_GET['cbappr'].' onchange="sethid(\'appr\');">
  380. <input type="hidden" id="appr" name="appr" value="'.$_GET['appr'].'">
  381. </div>
  382. </div>
  383. <div class="sdrow">
  384. <div class="sdlabel"><label for="cblcok" title="'._('Exclude instances which didn’t respond to last check').'">'._('Exclude if offline on last check').'</label></div>
  385. <div class="sdinput">
  386. <input type="checkbox" class="sckbox" id="cblcok" value="1"'.$_GET['cblcok'].' onchange="sethid(\'lcok\');">
  387. <input type="hidden" id="lcok" name="lcok" value="'.$_GET['lcok'].'">
  388. </div>
  389. </div>
  390. </div>
  391. <script language="JavaScript">
  392. ckadvcri();
  393. </script>
  394. <div class="sdcrow">
  395. <input type="button" class="litbut" id="mctrlb" value="'._('Advanced criteria').'" onclick="shmctrl()">
  396. </div>
  397. <div class="sdtitb">'._('Order of results').'</div>
  398. <div class="sdcrow">
  399. <select id="ord" name="ord" class="sselect100">'.N);
  400. foreach ($order as $key=>$buf) {
  401. ($key!=$_GET['ord']) ? $selected='' : $selected=' selected';
  402. echo('<option value="'.$key.'"'.$selected.'>'.$buf['t'].'</option>'.N);
  403. }
  404. echo('</select>
  405. </div>
  406. <div class="sdlrow">
  407. <input type="submit" value="'._('Search').'" class="ssubmit">
  408. </div>
  409. <div class="sdlcrow">
  410. <input type="button" class="litbut" value="'._('Reset search').'" onclick="document.location.href=document.location.href.replace(/\\?.*$/,\'\')">
  411. </div>
  412. <input type="hidden" id="advc" name="advc" value="'.$_GET['advc'].'">
  413. <input type="hidden" id="p" name="p" value="'.$p.'">
  414. </form>
  415. <script language="JavaScript">
  416. mctrlsh='.(($_GET['advc']==1) ? 'false' : 'true').';
  417. shmctrl();
  418. swhelp();
  419. </script>'.N);
  420. $joins=array();
  421. $wheres=array();
  422. $wheres[]='Instances.IsMastodon=1 AND Instances.FirstSeen IS NOT NULL AND Instances.LastOkCheckTS>='.$graceline;
  423. if ($_GET['noxious']==1) $wheres[]='Instances.Noxious=0';
  424. if ($_GET['creg']==1) $wheres[]='Instances.RegOpen=1';
  425. if ($_GET['appr']==1) $wheres[]='Instances.RegReqApproval=0';
  426. if ($_GET['lcok']==1) $wheres[]='Instances.WasLastCheckOk=1';
  427. /*if ($_GET['lcok']==1) {
  428. $joins[]='LEFT JOIN InstChecks AS InstChecks ON InstChecks.InstID=Instances.ID AND InstChecks.Time=(SELECT MAX(InstChecks.Time) AS MaxTime FROM InstChecks WHERE InstChecks.InstID=Instances.ID)';
  429. $wheres[]='InstChecks.Status=1';
  430. }*/
  431. if ($_GET['lang']>0) {
  432. $joins[]='LEFT JOIN InstOurLangs ON InstOurLangs.InstID=Instances.ID';
  433. $wheres[]='(InstOurLangs.OurLangID='.$_GET['lang'].' AND InstOurLangs.Pos=1)';
  434. }
  435. $buf=preg_replace('#%#','\%',myesc($link,$_GET['desc']));
  436. if ($_GET['desc']!='') $wheres[]='(Instances.URI LIKE "%'.$buf.'%" OR Instances.Title LIKE "%'.$buf.'%" OR Instances.ShortDesc LIKE "%'.$buf.'%" OR Instances.LongDesc LIKE "%'.$buf.'%")';
  437. if ($_GET['minu']!='') $wheres[]='Instances.UserCount>='.$_GET['minu'];
  438. if ($_GET['maxu']!='') $wheres[]='Instances.UserCount<='.$_GET['maxu'];
  439. if ($_GET['minau']!='') $wheres[]='Instances.ActiveUsersMonth>='.$_GET['minau'];
  440. if ($_GET['minki']!='') $wheres[]='Instances.DomainCount>='.$_GET['minki'];
  441. $joins=implode(' ',$joins);
  442. $wheres='WHERE '.implode(' AND ',$wheres);
  443. if (!$single)
  444. $que='SELECT * FROM Instances '.$joins.' '.$wheres.' ORDER BY '.$order[$_GET['ord']]['q'];
  445. else
  446. $que='SELECT * FROM Instances WHERE ID='.$_GET['id'];
  447. $debug.='QUERY: «'.$que.'»'.N;
  448. $qbt=microtime(true);
  449. $res=mysqli_query($link,$que) or muorimeglio(__LINE__.': '.mysqli_error($link),true);
  450. $debug.='MAIN QUERY EXEC TIME: '.(microtime(true)-$qbt).' sec.'.N;
  451. $itot=mysqli_num_rows($res);
  452. $debug.='RESULTS: '.$itot.N;
  453. $ipp=10;// istanze per pagina
  454. $if=$ipp*($p-1);
  455. if ($if>=$itot) {
  456. $if=0;
  457. $p=1;
  458. }
  459. $il=$if+$ipp;
  460. function tquery($query,$line) {
  461. global $link, $debug;
  462. $bt=microtime(true);
  463. $res=mysqli_query($link,$query) or muorimeglio($line.': '.mysqli_error($link),true);
  464. $debug.=(microtime(true)-$bt).' secs. for query «'.$query.'»'.N;
  465. return($res);
  466. }
  467. mysqli_data_seek($res,$if);
  468. while ($if<$il && $row=mysqli_fetch_assoc($res)) {
  469. $if++;
  470. $out='<div class="ihead"><a href="https://'.hspech($row['URI']).'" title="'._('Go to instance').'">'.hspech($row['URI']).'</a>';
  471. if (!$single) $out.=' <a href="'.$conf['instpath'].'/instances?id='.$row['ID'].'" title="'._('Direct link to this instance’s card').'">('.$if.'/'.$itot.')</a>';
  472. $out.='</div>'.N.'<div class="ibody">'.N;
  473. $qbt=microtime(true);
  474. $rres=tquery('SELECT CONCAT(Languages.Name'.$dlanguc.'," (",Languages.Code,")") AS Lang FROM InstOurLangs LEFT JOIN Languages ON Languages.ID=InstOurLangs.OurLangID WHERE InstOurLangs.InstID='.$row['ID'].' ORDER BY InstOurLangs.Pos ASC',__LINE__);
  475. $buf=array();
  476. while ($rrow=mysqli_fetch_assoc($rres))
  477. $buf[]=hspech($rrow['Lang']);
  478. $out.='<a href="https://'.hspech($row['URI']).'" title="'._('Go to instance').'"><div class="iimgc"><img class="iimg" src="'.$row['Thumb'].'">';
  479. // if (!is_null($row['Priority'])) $out.='<img src="'.$prepath.'imgs/featured-it.svg" class="ifeat">';
  480. if (!is_null($row['Priority'])) $out.='<div class="dfeat">'._('Recommended').'</div>';
  481. $out.='</div></a>'.N;
  482. $out.='<div class="icol">'.N;
  483. $out.='<div><span class="ilab">'._('Name').'</span> <a href="https://'.hspech($row['URI']).'" title="'._('Go to instance').'">'.nully(hspech($row['Title'])).'</a></div>'.N;
  484. /*$out.='<div><span class="ilab">'._('Consigliata').'</span> ';
  485. (!is_null($row['Priority'])) ? $out.='<span class="ivgood">'._('Si!').'</span>' : $out.=_('No');
  486. $out.='</div>'.N;*/
  487. $out.='<div><span class="ilab">'._('Languages').'</span> '.nully(implode(', ',$buf)).'</div>'.N;
  488. $out.='<div><span class="ilab">'._('Users').'</span> '.nully(fnum($row['UserCount'],$lc,0)).'</div>'.N;
  489. $out.='<div><span class="ilab">'._('Active users (last month)').'</span> '.nully(fnum($row['ActiveUsersMonth'],$lc,0)).'</div>'.N;
  490. $out.='<div><span class="ilab">'._('Active users (last six months)').'</span> '.nully(fnum($row['ActiveUsersHalfYear'],$lc,0)).'</div>'.N;
  491. $out.='<div><span class="ilab">'._('Known instances').'</span> '.nully(fnum($row['DomainCount'],$lc,0)).'</div>'.N;
  492. $out.='</div>'.N;
  493. $out.='<div class="icol">'.N;
  494. $out.='<div><span class="ilab">'._('Characters per toot (max)').'</span> ';
  495. if (nullemp(fnum($row['MaxTootChars'],$lc,0)))
  496. $out.='<span class="null">500</span>';
  497. else
  498. $out.=$row['MaxTootChars'];
  499. $out.='</div>'.N;
  500. $out.='<div><span class="ilab">'._('Noxious').'</span> ';
  501. ($row['Noxious']==1) ? $out.='<span class="ibad">'._('Yes (see why below)').'</span>' : $out.='<span class="igood">'._('No').'</span>';
  502. $out.='</div>'.N;
  503. $out.='<div><span class="ilab">'._('Software').'</span> '.nully(hspech(ucfirst($row['Software']))).' '.nully(hspech($row['Version'])).'</div>'.N;
  504. $out.='<div><span class="ilab">'._('Registrations').'</span> ';
  505. ($row['RegReqApproval']==1) ? $buf=' <span class="iwarn">('._('by admin approval').')</span>' : $buf='';
  506. if (nullemp($row['RegOpen']))
  507. $out.='<span class="null">'._('Not available{singular}').'</span>';
  508. elseif ($row['RegOpen']==1)
  509. $out.='<span class="igood">'._('Open').'</span>'.$buf;
  510. else
  511. $out.='<span class="iwarn">'._('Closed').'</span>';
  512. $out.='</div>'.N;
  513. $out.='<div><span class="ilab">'._('E-mail').'</span> ';
  514. if (nullemp($row['Email']))
  515. $out.='<span class="null">'._('Not available{singular}').'</span>';
  516. else
  517. $out.='<a href="mailto:'.$row['Email'].'">'.$row['Email'].'</a>';
  518. $out.='</div>'.N;
  519. $out.='</div>'.N;
  520. $out.='<div><span class="ilab">'._('Most used hashtags (last week)').'</span> ';
  521. $rres=tquery('SELECT * FROM InstTrends WHERE InstID='.$row['ID'].' ORDER BY Pos ASC',__LINE__);
  522. if (mysqli_num_rows($rres)>0) {
  523. $buf=array();
  524. while ($rrow=mysqli_fetch_assoc($rres))
  525. $buf[]='<a href="'.hspech($rrow['URL']).'">'.hspech($rrow['Name']).'</a>';
  526. $out.=implode(', ',$buf);
  527. } else {
  528. $out.='<span class="null">'._('Not available{plural}').'</span>';
  529. }
  530. $out.='</div>'.N;
  531. if ($row['Noxious']) {
  532. $out.='<div><div class="noxlab">'._('Why we consider this instance noxious').'</div><div class="noxreas">'.nully(strip(nl2br(trim(n2es($row['NoxReason'])),false),$row['URI'])).'</div></div>'.N;
  533. }
  534. $out.='<div><div class="idlab">'._('Short description').'</div><div class="idesc">'.nully(strip(nl2br(trim(n2es($row['ShortDesc'])),false),$row['URI'])).'</div></div>'.N;
  535. $out.='<div><div class="idlab">'._('Long description').'</div><div class="idesc">'.nully(strip(trim(n2es($row['LongDesc'])),$row['URI'])).'</div></div>'.N;
  536. $out.='<div class="abox"><img class="aimg" src="'.$row['AdmAvatar'].'"><div><span class="ilab">'._('Admin account').'</span> '.nully(hspech($row['AdmAccount'])).'</div><div><span class="ilab">'._('Date of creation').'</span> '.nully(ldate($row['AdmCreatedAt'],true)).'</div><div><span class="ilab">'._('Admin name').'</span> '.nully(hspech($row['AdmDisplayName'])).'</div><div><div class="idlab">'._('Admin notes').'</div><div class="inote">'.nullyp(strip(trim(n2es($row['AdmNote'])),$row['URI'])).'</div>'.N;
  537. $out.='</div></div>';
  538. $out.='<div class="ghost"><div class="idlab">'._('Stats').'</div><div class="istat">';
  539. $rres=tquery('SELECT COUNT(InstID) AS cnt, SUM(Statuses) AS tstatuses, SUM(Logins) AS tlogins, SUM(Registrations) AS tregs FROM InstActivity WHERE InstID='.$row['ID'],__LINE__);
  540. $out.='<div class="dida">'._('Last 12 weeks activity');
  541. if (mysqli_num_rows($rres)>0) {
  542. $rrow=mysqli_fetch_assoc($rres);
  543. if ($rrow['cnt']>0)
  544. $out.=' ('._('totals:').' '.$rrow['tstatuses'].' '._('statuses').', '.$rrow['tlogins'].' '._('logins').', '.$rrow['tregs'].' '._('registrations').')';
  545. }
  546. $out.='</div>'.N;
  547. $rres=tquery('SELECT * FROM InstActivity WHERE InstID='.$row['ID'].' ORDER BY Week ASC',__LINE__);
  548. $out.='<table class="abar"><tr>';
  549. $tot=mysqli_num_rows($rres);
  550. if ($tot>0) {
  551. while ($rrow=mysqli_fetch_assoc($rres))
  552. // initials for Statuses, Logins, Registrations
  553. $out.='<td width="'.(100/$tot).'%">'._('S').': '.$rrow['Statuses'].'<br>'._('L').': '.$rrow['Logins'].'<br>'._('R').': '.$rrow['Registrations'].'</td>';
  554. } else {
  555. $out.='<td><span class="null">'._('Not available{singular}').'</span></td>';
  556. }
  557. $out.='</tr></table>'.N;
  558. $rres=tquery('SELECT * FROM InstChecks WHERE InstID='.$row['ID'].' ORDER BY Time DESC LIMIT 0,8',__LINE__);
  559. $tot=mysqli_num_rows($rres);
  560. $buf=array();
  561. while ($rrow=mysqli_fetch_assoc($rres)) $buf[]=$rrow;
  562. $out.='<div class="dida">'._('Last checks (green: OK; red: KO)').'</div><table class="cbar"><tr>';
  563. for ($i=$tot-1; $i>=0; $i--) {
  564. $out.='<td width="'.(100/$tot).'%"';
  565. if ($buf[$i]['Status']==1) $out.=' class="cbarok"';
  566. $out.='>'.ldate($buf[$i]['Time']).'</td>';
  567. }
  568. $out.='</tr></table>'.N;
  569. $out.='</div></div>'.N;
  570. $out.='</div>'.N;
  571. echo($out);
  572. }
  573. mysqli_close($link);
  574. echo('</section>'.N);
  575. $ptot=ceil($itot/$ipp);
  576. if ($ptot>1) {
  577. echo('<div id="footmarg"></div>'.N);
  578. echo('<div id="bmenu">'.N);
  579. $pnav='<table id="pnav"><tr>';
  580. if ($p>1)
  581. $pnav.='<td><img src="'.$prepath.'imgs/nav_first.svg" onclick="swp(1);" class="hov" title="'._('Go to first page').'"></td><td><img src="'.$prepath.'imgs/nav_prev.svg" onclick="swp('.($p-1).');" class="hov" title="'._('Go to previous page').'"></td>';
  582. else
  583. $pnav.='<td><img src="'.$prepath.'imgs/nav_first_off.svg"></td><td><img src="'.$prepath.'imgs/nav_prev_off.svg"></td>';
  584. //$pnav.='<td>Page '.$p.'/'.$ptot.'</td>';
  585. $pnav.='<td><select id="pagesel" onchange="swp(this.value);" title="'._('Select page').'">'.N;
  586. for ($i=1; $i<=$ptot; $i++) {
  587. ($i!=$p) ? $selected='' : $selected=' selected';
  588. $li=$i*$ipp;
  589. if ($li>$itot) $li=$itot;
  590. //page number prefix
  591. $pnav.='<option value="'.$i.'"'.$selected.'>'._('Page').' '.$i.' '._('of').' '.$ptot.' ('._('instances').': '.(($i-1)*$ipp+1).'-'.$li.'/'.$itot.')</option>'.N;
  592. }
  593. $pnav.='</select></td>'.N;
  594. if ($p<$ptot)
  595. $pnav.='<td><img src="'.$prepath.'imgs/nav_next.svg" onclick="swp('.($p+1).');" class="hov" title="'._('Go to next page').'"></td><td><img src="'.$prepath.'imgs/nav_last.svg" onclick="swp('.($ptot).');" class="hov" title="'._('Go to last page').'"></td>';
  596. else
  597. $pnav.='<td><img src="'.$prepath.'imgs/nav_next_off.svg"></td><td><img src="'.$prepath.'imgs/nav_last_off.svg"></td>';
  598. $pnav.='</tr></table>'.N;
  599. echo($pnav);
  600. echo('</div>'.N);
  601. }
  602. echo('</div>'.N);
  603. echo('</div>'.N);
  604. $debug.='TOTAL RENDERING TIME: '.(microtime(true)-$bt).N;
  605. if (array_key_exists('debug',$_GET) && $_GET['debug']=='1') echo('<!--'.N.'--- DEBUG INFO ---'.N.$debug.'//-->'.N);
  606. ?>