MastodonHelp/web/site/users.php
2023-12-28 14:56:23 +01:00

667 lines
28 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
if (!defined('N')) {
echo('You probably meant <a href="'.preg_replace('/\.php$/','',$_SERVER['REQUEST_URI']).'">this</a>.');
exit(0);
}
echo('</nav>
<div class="scrwide">
<div class="scrwidein">
<section class="sectcontm">
<h3>Under construction.</h3>
</section>
</div>
</div>'.N);
exit(0);
$bt=microtime(true);
$dlanguc=strtoupper($dlang);
$lc=localeconv();
require '../lib/n2es.php';
require '../lib/tables.php';
require '../lib/gracetime.php';
require '../lib/fnum.php';
$graceline=time()-$gracetime;
use function mysqli_real_escape_string as myesc;
/*$dlang='fr';
$dtzbl=array('ca'=>'Europe/Madrid','en'=>'Europe/London','es'=>'Europe/Madrid','fr'=>'Europe/Paris','it'=>'Europe/Rome');
date_default_timezone_set($dtzbl[$dlang]);*/
$debug='';
$debug.='REQUEST_URI: '.$_SERVER['REQUEST_URI'].N;
$debug.='$_GET: '.print_r($_GET,1);
$debug.='LOCALE: '.$locale.N;
if (array_key_exists('id',$_GET) && preg_match('/^\d+$/',$_GET['id'])) {
$_GET['id']+=0;
$single=true;
} else {
$single=false;
}
//$getc=count($_GET);
//forzo $getc a 1 per non mostrare mai la spiega di come funziona il motore di ricerca
$getc=1;
if (array_key_exists('advc',$_GET)) {
($_GET['advc']=='1') ? $_GET['advc']=1 : $_GET['advc']=0;
} else {
$_GET['advc']=0;
}
$minudef=10;
$minumax=10000000000;
$maxudef=30000;
$maxumax=10000000000;
$minaudef=10;
$minaumax=10000000;
$minkidef=500;
$minkimax=100000;
echo('</nav>
<div class="scrwide">
<div class="scrwidein">
<section class="sectcontm">
<img src="'.$prepath.'imgs/helpbutti.svg" id="helpbutt" class="helpb" onmouseover="swhelpi(true);" onmouseout="swhelpi(false);" onclick="swhelp();">
<h3>'._('Users').'</h3>
<script language="JavaScript">
let mctrlsh=false;
function shmctrl() {
let mctrl=document.getElementById("mctrl");
let mctrlb=document.getElementById("mctrlb");
let advc=document.getElementById("advc");
if (mctrlsh) {
//mctrl.style.display="none";
mctrl.style.height="0px";
//mctrlb.className="litbut";
mctrlb.value="'._('Show advanced criteria').'";
advc.value=0;
mctrlsh=false;
} else {
//mctrl.style.display="block";
mctrl.style.height=mctrl.scrollHeight+"px";
//mctrlb.className="litbuta";
mctrlb.value="'._('Hide advanced criteria').'";
advc.value=1;
mctrlsh=true;
}
}
let helpsh='.(($getc==0) ? 'false' : 'true').';
function swhelp() {
let hdiv=document.getElementById("help");
let himg=document.getElementById("helpbutt");
if (helpsh) {
//hdiv.style.display="none";
hdiv.style.height="0px";
himg.title="'._('Show introduction').'";
himg.src="'.$prepath.'imgs/helpbutti.svg";
helpsh=false;
} else {
//hdiv.style.display="block";
hdiv.style.height=hdiv.scrollHeight+"px";
himg.title="'._('Hide introduction').'";
himg.src="'.$prepath.'imgs/helpbutta.svg";
helpsh=true;
}
}
function swhelpi(over) {
let himg=document.getElementById("helpbutt"), ia;
if (helpsh) {
(over) ? ia="i" : ia="a";
} else {
(over) ? ia="a" : ia="i";
}
himg.src="'.$prepath.'imgs/helpbutt"+ia+".svg";
}
function swp(pn) {
document.curvf.p.value=pn;
document.curvf.submit();
}
function sethid(obj) {
if (document.getElementById("cb"+obj).checked)
document.getElementById(obj).value=1;
else
document.getElementById(obj).value=0;
ckadvcri();
}
let advcri=true;
function ckadvcri() {
if (document.getElementById("minu").value!='.$minudef.' ||
document.getElementById("maxu").value!='.$maxudef.' ||
document.getElementById("minau").value!='.$minaudef.' ||
document.getElementById("minki").value!='.$minkidef.' ||
document.getElementById("cbnoxious").checked==false ||
document.getElementById("cbcreg").checked==false ||
document.getElementById("cbappr").checked==true ||
document.getElementById("cblcok").checked==true) {
document.getElementById("disadvcrib").value="'._('Reset all advanced criteria to default').'";
advcri=false;
} else {
document.getElementById("disadvcrib").value="'._('Disable all advanced criteria').'";
advcri=true;
}
}
function endisadvcri() {
if (advcri) {
document.getElementById("minu").value="";
document.getElementById("maxu").value="";
document.getElementById("minau").value="";
document.getElementById("minki").value="";
document.getElementById("cbnoxious").checked=false;
document.getElementById("noxious").value=0;
document.getElementById("cbcreg").checked=false;
document.getElementById("creg").value=0;
document.getElementById("cbappr").checked=false;
document.getElementById("appr").value=0;
document.getElementById("cblcok").checked=false;
document.getElementById("lcok").value=0;
} else {
document.getElementById("minu").value='.$minudef.';
document.getElementById("maxu").value='.$maxudef.';
document.getElementById("minau").value='.$minaudef.';
document.getElementById("minki").value='.$minkidef.';
document.getElementById("cbnoxious").checked=true;
document.getElementById("noxious").value=1;
document.getElementById("cbcreg").checked=true;
document.getElementById("creg").value=1;
document.getElementById("cbappr").checked=false;
document.getElementById("appr").value=0;
document.getElementById("cblcok").checked=false;
document.getElementById("lcok").value=0;
}
ckadvcri();
}
</script>
'.N);
function nullemp($inp) {
if (is_null($inp) || preg_match('/^\s*$/',$inp)===1) return(true);
return(false);
}
function ldate($ts,$dateonly=false) {
if (nullemp($ts)) return(null);
$ts=round($ts);
if (!$dateonly)
return(gmdate('d/m/Y H:i:s e',$ts));
else
return(gmdate('d/m/Y',$ts));
}
function hspech($str) {
if (nullemp($str)) return(null);
return(htmlspecialchars($str,ENT_QUOTES|ENT_HTML5,'UTF-8'));
}
function muorimeglio($msg,$close) {
global $link;
if ($close)
mysqli_close($link);
echo('<p>'.$msg.'</p>'.N.'</section>'.N.'</div>'.N.'</div>'.N.'</body>'.N);
exit(2);
}
function nully($str) {
// "Not available" in singular form - translators, please omit "{singular}" from translation,
// it's there just to diversify this "Not available" from the next one
if (nullemp($str)) return('<span class="null">'._('Not available{singular}').'</span>');
return($str);
}
function nullyp($str) {
// "Not available" in plural form - translators, please omit "{plural}" from translation,
// it's there just to diversify this "Not available" from the previous one
if (nullemp($str)) return('<span class="null">'._('Not available{plural}').'</span>');
return($str);
}
function strip($str,$uri) {
if (nullemp($str)) return(null);
while (preg_match('#^\s*<br\s*[\\\/]?>#',$str)===1) $str=preg_replace('#^\s*<br\s*[\\\/]?>#','',$str);
while (preg_match('#<br\s*[\\\/]?>\s*$#',$str)===1) $str=preg_replace('#<br\s*[\\\/]?>\s*$#','',$str);
while (preg_match('#<br\s*[\\\/]?>\s*<br\s*[\\\/]?>#s',$str)===1)
$str=preg_replace('#<br\s*[\\\/]?>\s*<br\s*[\\\/]?>#s','<br>',$str);
$str=preg_replace('#<style( [^>]*)?>.*</style>#s','',$str);
$str=preg_replace('#<a href="(?![a-zA-Z]+://)([^"]+)#','<a href="https://'.$uri.'$1>',$str);
$str=preg_replace('#<h[1-9][^>]*>#','<p><strong>',$str);
$str=preg_replace('#</h[1-9]>#','</strong></p>',$str);
$str=preg_replace(array('#</p><br>#','#</li><br>#','#</ul><br>#','#<ul><br>#'),array('</p>','</li>','</ul>','<ul>'),$str);
$str=preg_replace('#<b>#','<strong>',$str);
$str=preg_replace('#</b>#','</strong>',$str);
$str=preg_replace('#<p></p>#','',$str);
$str=strip_tags($str,'<a><br><ol><ul><li><p><div><i><b><strong><em><small><img>');
return($str);
}
$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(_('Couldnt connect to database: ').mysqli_connect_error().' ['.mysqli_connect_errno().']',false);
mysqli_set_charset($link,'utf8mb4');
$tables=tables($link);
$res=mysqli_query($link,'SELECT COUNT(ID) AS totusers FROM Users') or muorimeglio(__LINE__.': '.mysqli_error($link),true);
$row=mysqli_fetch_assoc($res);
echo(_('<div id="help" class="helpd"><p class="intro">This is our search engine for Mastodon users. It works this way...</p></div>').N);
printf(_('<p class="introe">We currently count <span class="statd">%s</span> Mastodon users.</p>').N, fnum($row['totusers'],$lc,0));
if ((array_key_exists('noxious',$_GET) && $_GET['noxious']=='1') || !array_key_exists('noxious',$_GET)) {
$_GET['cbnoxious']=' checked';
$_GET['noxious']=1;
} else {
$_GET['cbnoxious']='';
$_GET['noxious']=0;
}
//echo('<p>noxious: '.$_GET['noxious'].'</p>');
if ((array_key_exists('creg',$_GET) && $_GET['creg']=='1') || !array_key_exists('creg',$_GET)) {
$_GET['cbcreg']=' checked';
$_GET['creg']=1;
} else {
$_GET['cbcreg']='';
$_GET['creg']=0;
}
if (array_key_exists('appr',$_GET) && $_GET['appr']=='1') {
$_GET['cbappr']=' checked';
$_GET['appr']=1;
} else {
$_GET['cbappr']='';
$_GET['appr']=0;
}
if (array_key_exists('lcok',$_GET) && $_GET['lcok']=='1') {
$_GET['cblcok']=' checked';
$_GET['lcok']=1;
} else {
$_GET['cblcok']='';
$_GET['lcok']=0;
}
if (array_key_exists('lang',$_GET)) {
if (preg_match('#^[0-9]+$#',$_GET['lang'])===1)
$_GET['lang']=$_GET['lang']+0;
else
$_GET['lang']=0;
} else {
$res=mysqli_query($link,'SELECT ID FROM Languages WHERE Code="'.$dlang.'"') or muorimeglio(__LINE__.': '.mysqli_error($link),true);
if (mysqli_num_rows($res)>0) {
$row=mysqli_fetch_assoc($res);
$_GET['lang']=$row['ID'];
} else {
$_GET['lang']=0;
}
}
if ($_GET['lang']>5000000000) $_GET['lang']=0;
if (array_key_exists('desc',$_GET) && preg_match('#^.+$#',$_GET['lang'])===1)
$_GET['desc']=trim(n2es($_GET['desc']));
else
$_GET['desc']='';
if (mb_strlen($_GET['desc'])>64) $_GET['desc']='';
function ckgnum($key,$def,$max) {
if (array_key_exists($key,$_GET)) {
$_GET[$key]=trim($_GET[$key]);
if (preg_match('#^[0-9]+$#',$_GET[$key])===1) {
$_GET[$key]=$_GET[$key]+0;
if ($_GET[$key]>$max) $_GET[$key]=$max;
} elseif ($_GET[$key]!='') {
$_GET[$key]=$def;
}
} else {
$_GET[$key]=$def;
}
}
ckgnum('minu',$minudef,$minumax);
ckgnum('maxu',$maxudef,$maxumax);
if (is_int($_GET['maxu']) && is_int($_GET['minu']) && $_GET['maxu']<$_GET['minu']) $_GET['maxu']=$_GET['minu'];
ckgnum('minau',$minaudef,$minaumax);
ckgnum('minki',$minkidef,$minkimax);
$order=array(
'rand'=>array('t'=>_('Random, recommended first'),'q'=>'Instances.Priority DESC, Instances.RPos ASC'),
// 'feat'=>array('t'=>_('Prima le consigliate'),'q'=>'Instances.Priority DESC'),
// partecipazione: totusers/activeusers
// 'part'=>array('t'=>_('Partecipazione (decr.)'),'q'=>'(Instances.UserCount / Instances.ActiveUsersMonth) ASC'),
'tusersa'=>array('t'=>_('By number of users, ascending'),'q'=>'Instances.UserCount ASC'),
'tusersd'=>array('t'=>_('By number of users, descending'),'q'=>'Instances.UserCount DESC'),
'ausersd'=>array('t'=>_('By number of active users, descending'),'q'=>'Instances.ActiveUsersMonth DESC'),
'kinstsd'=>array('t'=>_('By number of known instances, descending'),'q'=>'Instances.DomainCount DESC'),
'charsd'=>array('t'=>_('By maximum number of characters per toot, descending'),'q'=>'Instances.MaxTootChars DESC'),
// 'open'=>array('t'=>_('Prima quelle con iscriz. aperte'),'q'=>'Instances.RegOpen DESC, Instances.RegReqApproval ASC'),
// 'alph'=>array('t'=>_('Alfabetico'),'q'=>'Instances.URI ASC'),
// new non ha senso di esistere visto che c'è firstseen
// 'name'=>array('t'=>_('Nome (crescente)'),'q'=>'Instances.Title ASC'),
// 'admc'=>array('t'=>_('Data creazione account admin'),'q'=>'IF (Instances.AdmCreatedAt IS NULL, 9999999999, Instances.AdmCreatedAt) ASC'),
// 'fseena'=>array('t'=>_('Data di “avvistamento” cresc.'),'q'=>'Instances.FirstSeen ASC'),
// 'fseend'=>array('t'=>_('Data di “avvistamento” decr.'),'q'=>'Instances.FirstSeen DESC'),
);
if (!(array_key_exists('ord',$_GET) && array_key_exists($_GET['ord'],$order)))
$_GET['ord']='rand';
if ($_GET['lang']==0) $order['rand']=array('t'=>_('Random'),'q'=>'Instances.RPos ASC');
$p=1;
if (array_key_exists('p',$_GET) && preg_match('#^[0-9]+$#',$_GET['p'])===1) $p=$_GET['p']+0;
echo('<form method="get" id="curvf" name="curvf">
<input name="advc" type="hidden" value="'.$_GET['advc'].'">
<input name="noxious" type="hidden" value="'.$_GET['noxious'].'">
<input name="creg" type="hidden" value="'.$_GET['creg'].'">
<input name="appr" type="hidden" value="'.$_GET['appr'].'">
<input name="lcok" type="hidden" value="'.$_GET['lcok'].'">
<input name="lang" type="hidden" value="'.$_GET['lang'].'">
<input name="desc" type="hidden" value="'.htmlentities($_GET['desc']).'">
<input name="minu" type="hidden" value="'.$_GET['minu'].'">
<input name="maxu" type="hidden" value="'.$_GET['maxu'].'">
<input name="minau" type="hidden" value="'.$_GET['minau'].'">
<input name="minki" type="hidden" value="'.$_GET['minki'].'">
<input name="ord" type="hidden" value="'.$_GET['ord'].'">
<input name="p" type="hidden" value="'.$p.'">
</form>'.N);
($_GET['lang']==0) ? $selected=' selected' : $selected='';
echo('<form method="get" id="searchf" class="sdbox" onsubmit="document.getElementById(\'p\').value=1;">
<div class="sdtit">'._('Search criteria').'</div>
<div class="sdrow">
<div class="sdlabel"><label for="display_name" title="'._('Include only users whose “display name” contains this string').'">'._('“Display name” contains').'</label></div>
<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>
</div>
<div class="sdrow">
<div class="sdlabel"><label for="username" title="'._('Include only users whose username contains this string').'">'._('Username contains').'</label></div>
<div class="sdinput"><input type="text" id="username" name="username" class="sinput" maxlength="'.$tables['Users']['username'].'" value="'.hspech($_GET['username']).'"></div>
</div>
<div id="mctrl">
<div class="sdrow">
<input type="button" class="litbut" id="disadvcrib" value="'._('Disable all advanced criteria').'" onclick="endisadvcri();">
</div>
<div class="sdrow">
<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>
<div class="sdinput"><input type="number" id="minu" name="minu" min="0" max="'.$minumax.'" class="sinput" value="'.$_GET['minu'].'" onchange="ckadvcri();"></div>
</div>
<div class="sdrow">
<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>
<div class="sdinput"><input type="number" id="maxu" name="maxu" min="0" max="'.$maxumax.'" class="sinput" value="'.$_GET['maxu'].'" onchange="ckadvcri();"></div>
</div>
<div class="sdrow">
<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>
<div class="sdinput"><input type="number" id="minau" name="minau" min="0" max="'.$minaumax.'" class="sinput" value="'.$_GET['minau'].'" onchange="ckadvcri();"></div>
</div>
<div class="sdrow">
<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>
<div class="sdinput"><input type="number" id="minki" name="minki" min="0" max="'.$minkimax.'" class="sinput" value="'.$_GET['minki'].'" onchange="ckadvcri();"></div>
</div>
<div class="sdrow">
<div class="sdlabel"><label for="cbnoxious" title="'._('Exclude noxious instances').'">'._('Exclude noxious').'</label></div>
<div class="sdinput">
<input type="checkbox" class="sckbox" id="cbnoxious" value="1"'.$_GET['cbnoxious'].' onchange="sethid(\'noxious\');">
<input type="hidden" id="noxious" name="noxious" value="'.$_GET['noxious'].'">
</div>
</div>
<div class="sdrow">
<div class="sdlabel"><label for="cbcreg" title="'._('Exclude instances which dont accept new registrations').'">'._('Exclude if registrations are closed').'</label></div>
<div class="sdinput">
<input type="checkbox" class="sckbox" id="cbcreg" value="1"'.$_GET['cbcreg'].' onchange="sethid(\'creg\');">
<input type="hidden" id="creg" name="creg" value="'.$_GET['creg'].'">
</div>
</div>
<div class="sdrow">
<div class="sdlabel"><label for="cbappr" title="'._('Exclude instances on which admin approval is required for registration').'">'._('Exclude if registration requires approval').'</label></div>
<div class="sdinput">
<input type="checkbox" class="sckbox" id="cbappr" value="1"'.$_GET['cbappr'].' onchange="sethid(\'appr\');">
<input type="hidden" id="appr" name="appr" value="'.$_GET['appr'].'">
</div>
</div>
<div class="sdrow">
<div class="sdlabel"><label for="cblcok" title="'._('Exclude instances which didnt respond to last check').'">'._('Exclude if offline on last check').'</label></div>
<div class="sdinput">
<input type="checkbox" class="sckbox" id="cblcok" value="1"'.$_GET['cblcok'].' onchange="sethid(\'lcok\');">
<input type="hidden" id="lcok" name="lcok" value="'.$_GET['lcok'].'">
</div>
</div>
</div>
<script language="JavaScript">
ckadvcri();
</script>
<div class="sdcrow">
<input type="button" class="litbut" id="mctrlb" value="'._('Advanced criteria').'" onclick="shmctrl()">
</div>
<div class="sdtitb">'._('Order of results').'</div>
<div class="sdcrow">
<select id="ord" name="ord" class="sselect100">'.N);
foreach ($order as $key=>$buf) {
($key!=$_GET['ord']) ? $selected='' : $selected=' selected';
echo('<option value="'.$key.'"'.$selected.'>'.$buf['t'].'</option>'.N);
}
echo('</select>
</div>
<div class="sdlrow">
<input type="submit" value="'._('Search').'" class="ssubmit">
</div>
<div class="sdlcrow">
<input type="button" class="litbut" value="'._('Reset search').'" onclick="document.location.href=document.location.href.replace(/\\?.*$/,\'\')">
</div>
<input type="hidden" id="advc" name="advc" value="'.$_GET['advc'].'">
<input type="hidden" id="p" name="p" value="'.$p.'">
</form>
<script language="JavaScript">
mctrlsh='.(($_GET['advc']==1) ? 'false' : 'true').';
shmctrl();
swhelp();
</script>'.N);
$joins=array();
$wheres=array();
$wheres[]='Instances.IsMastodon=1 AND Instances.FirstSeen IS NOT NULL AND Instances.LastOkCheckTS>='.$graceline;
if ($_GET['noxious']==1) $wheres[]='Instances.Noxious=0';
if ($_GET['creg']==1) $wheres[]='Instances.RegOpen=1';
if ($_GET['appr']==1) $wheres[]='Instances.RegReqApproval=0';
if ($_GET['lcok']==1) $wheres[]='Instances.WasLastCheckOk=1';
/*if ($_GET['lcok']==1) {
$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)';
$wheres[]='InstChecks.Status=1';
}*/
if ($_GET['lang']>0) {
$joins[]='LEFT JOIN InstOurLangs ON InstOurLangs.InstID=Instances.ID';
$wheres[]='(InstOurLangs.OurLangID='.$_GET['lang'].' AND InstOurLangs.Pos=1)';
}
$buf=preg_replace('#%#','\%',myesc($link,$_GET['desc']));
if ($_GET['desc']!='') $wheres[]='(Instances.URI LIKE "%'.$buf.'%" OR Instances.Title LIKE "%'.$buf.'%" OR Instances.ShortDesc LIKE "%'.$buf.'%" OR Instances.LongDesc LIKE "%'.$buf.'%")';
if ($_GET['minu']!='') $wheres[]='Instances.UserCount>='.$_GET['minu'];
if ($_GET['maxu']!='') $wheres[]='Instances.UserCount<='.$_GET['maxu'];
if ($_GET['minau']!='') $wheres[]='Instances.ActiveUsersMonth>='.$_GET['minau'];
if ($_GET['minki']!='') $wheres[]='Instances.DomainCount>='.$_GET['minki'];
$joins=implode(' ',$joins);
$wheres='WHERE '.implode(' AND ',$wheres);
if (!$single)
$que='SELECT * FROM Instances '.$joins.' '.$wheres.' ORDER BY '.$order[$_GET['ord']]['q'];
else
$que='SELECT * FROM Instances WHERE ID='.$_GET['id'];
$debug.='QUERY: «'.$que.'»'.N;
$qbt=microtime(true);
$res=mysqli_query($link,$que) or muorimeglio(__LINE__.': '.mysqli_error($link),true);
$debug.='MAIN QUERY EXEC TIME: '.(microtime(true)-$qbt).' sec.'.N;
$itot=mysqli_num_rows($res);
$debug.='RESULTS: '.$itot.N;
$ipp=10;// istanze per pagina
$if=$ipp*($p-1);
if ($if>=$itot) {
$if=0;
$p=1;
}
$il=$if+$ipp;
function tquery($query,$line) {
global $link, $debug;
$bt=microtime(true);
$res=mysqli_query($link,$query) or muorimeglio($line.': '.mysqli_error($link),true);
$debug.=(microtime(true)-$bt).' secs. for query «'.$query.'»'.N;
return($res);
}
mysqli_data_seek($res,$if);
while ($if<$il && $row=mysqli_fetch_assoc($res)) {
$if++;
$out='<div class="ihead"><a href="https://'.hspech($row['URI']).'" title="'._('Go to instance').'">'.hspech($row['URI']).'</a>';
if (!$single) $out.=' <a href="'.$conf['instpath'].'/instances?id='.$row['ID'].'" title="'._('Direct link to this instances card').'">('.$if.'/'.$itot.')</a>';
$out.='</div>'.N.'<div class="ibody">'.N;
$qbt=microtime(true);
$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__);
$buf=array();
while ($rrow=mysqli_fetch_assoc($rres))
$buf[]=hspech($rrow['Lang']);
$out.='<a href="https://'.hspech($row['URI']).'" title="'._('Go to instance').'"><div class="iimgc"><img class="iimg" src="'.$row['Thumb'].'">';
// if (!is_null($row['Priority'])) $out.='<img src="'.$prepath.'imgs/featured-it.svg" class="ifeat">';
if (!is_null($row['Priority'])) $out.='<div class="dfeat">'._('Recommended').'</div>';
$out.='</div></a>'.N;
$out.='<div class="icol">'.N;
$out.='<div><span class="ilab">'._('Name').'</span> <a href="https://'.hspech($row['URI']).'" title="'._('Go to instance').'">'.nully(hspech($row['Title'])).'</a></div>'.N;
/*$out.='<div><span class="ilab">'._('Consigliata').'</span> ';
(!is_null($row['Priority'])) ? $out.='<span class="ivgood">'._('Si!').'</span>' : $out.=_('No');
$out.='</div>'.N;*/
$out.='<div><span class="ilab">'._('Languages').'</span> '.nully(implode(', ',$buf)).'</div>'.N;
$out.='<div><span class="ilab">'._('Users').'</span> '.nully(fnum($row['UserCount'],$lc,0)).'</div>'.N;
$out.='<div><span class="ilab">'._('Active users (last month)').'</span> '.nully(fnum($row['ActiveUsersMonth'],$lc,0)).'</div>'.N;
$out.='<div><span class="ilab">'._('Active users (last six months)').'</span> '.nully(fnum($row['ActiveUsersHalfYear'],$lc,0)).'</div>'.N;
$out.='<div><span class="ilab">'._('Known instances').'</span> '.nully(fnum($row['DomainCount'],$lc,0)).'</div>'.N;
$out.='</div>'.N;
$out.='<div class="icol">'.N;
$out.='<div><span class="ilab">'._('Characters per toot (max)').'</span> ';
if (nullemp(fnum($row['MaxTootChars'],$lc,0)))
$out.='<span class="null">500</span>';
else
$out.=$row['MaxTootChars'];
$out.='</div>'.N;
$out.='<div><span class="ilab">'._('Noxious').'</span> ';
($row['Noxious']==1) ? $out.='<span class="ibad">'._('Yes (see why below)').'</span>' : $out.='<span class="igood">'._('No').'</span>';
$out.='</div>'.N;
$out.='<div><span class="ilab">'._('Software').'</span> '.nully(hspech(ucfirst($row['Software']))).' '.nully(hspech($row['Version'])).'</div>'.N;
$out.='<div><span class="ilab">'._('Registrations').'</span> ';
($row['RegReqApproval']==1) ? $buf=' <span class="iwarn">('._('by admin approval').')</span>' : $buf='';
if (nullemp($row['RegOpen']))
$out.='<span class="null">'._('Not available{singular}').'</span>';
elseif ($row['RegOpen']==1)
$out.='<span class="igood">'._('Open').'</span>'.$buf;
else
$out.='<span class="iwarn">'._('Closed').'</span>';
$out.='</div>'.N;
$out.='<div><span class="ilab">'._('E-mail').'</span> ';
if (nullemp($row['Email']))
$out.='<span class="null">'._('Not available{singular}').'</span>';
else
$out.='<a href="mailto:'.$row['Email'].'">'.$row['Email'].'</a>';
$out.='</div>'.N;
$out.='</div>'.N;
$out.='<div><span class="ilab">'._('Most used hashtags (last week)').'</span> ';
$rres=tquery('SELECT * FROM InstTrends WHERE InstID='.$row['ID'].' ORDER BY Pos ASC',__LINE__);
if (mysqli_num_rows($rres)>0) {
$buf=array();
while ($rrow=mysqli_fetch_assoc($rres))
$buf[]='<a href="'.hspech($rrow['URL']).'">'.hspech($rrow['Name']).'</a>';
$out.=implode(', ',$buf);
} else {
$out.='<span class="null">'._('Not available{plural}').'</span>';
}
$out.='</div>'.N;
if ($row['Noxious']) {
$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;
}
$out.='<div><div class="idlab">'._('Short description').'</div><div class="idesc">'.nully(strip(nl2br(trim(n2es($row['ShortDesc'])),false),$row['URI'])).'</div></div>'.N;
$out.='<div><div class="idlab">'._('Long description').'</div><div class="idesc">'.nully(strip(trim(n2es($row['LongDesc'])),$row['URI'])).'</div></div>'.N;
$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;
$out.='</div></div>';
$out.='<div class="ghost"><div class="idlab">'._('Stats').'</div><div class="istat">';
$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__);
$out.='<div class="dida">'._('Last 12 weeks activity');
if (mysqli_num_rows($rres)>0) {
$rrow=mysqli_fetch_assoc($rres);
if ($rrow['cnt']>0)
$out.=' ('._('totals:').' '.$rrow['tstatuses'].' '._('statuses').', '.$rrow['tlogins'].' '._('logins').', '.$rrow['tregs'].' '._('registrations').')';
}
$out.='</div>'.N;
$rres=tquery('SELECT * FROM InstActivity WHERE InstID='.$row['ID'].' ORDER BY Week ASC',__LINE__);
$out.='<table class="abar"><tr>';
$tot=mysqli_num_rows($rres);
if ($tot>0) {
while ($rrow=mysqli_fetch_assoc($rres))
// initials for Statuses, Logins, Registrations
$out.='<td width="'.(100/$tot).'%">'._('S').': '.$rrow['Statuses'].'<br>'._('L').': '.$rrow['Logins'].'<br>'._('R').': '.$rrow['Registrations'].'</td>';
} else {
$out.='<td><span class="null">'._('Not available{singular}').'</span></td>';
}
$out.='</tr></table>'.N;
$rres=tquery('SELECT * FROM InstChecks WHERE InstID='.$row['ID'].' ORDER BY Time DESC LIMIT 0,8',__LINE__);
$tot=mysqli_num_rows($rres);
$buf=array();
while ($rrow=mysqli_fetch_assoc($rres)) $buf[]=$rrow;
$out.='<div class="dida">'._('Last checks (green: OK; red: KO)').'</div><table class="cbar"><tr>';
for ($i=$tot-1; $i>=0; $i--) {
$out.='<td width="'.(100/$tot).'%"';
if ($buf[$i]['Status']==1) $out.=' class="cbarok"';
$out.='>'.ldate($buf[$i]['Time']).'</td>';
}
$out.='</tr></table>'.N;
$out.='</div></div>'.N;
$out.='</div>'.N;
echo($out);
}
mysqli_close($link);
echo('</section>'.N);
$ptot=ceil($itot/$ipp);
if ($ptot>1) {
echo('<div id="footmarg"></div>'.N);
echo('<div id="bmenu">'.N);
$pnav='<table id="pnav"><tr>';
if ($p>1)
$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>';
else
$pnav.='<td><img src="'.$prepath.'imgs/nav_first_off.svg"></td><td><img src="'.$prepath.'imgs/nav_prev_off.svg"></td>';
//$pnav.='<td>Page '.$p.'/'.$ptot.'</td>';
$pnav.='<td><select id="pagesel" onchange="swp(this.value);" title="'._('Select page').'">'.N;
for ($i=1; $i<=$ptot; $i++) {
($i!=$p) ? $selected='' : $selected=' selected';
$li=$i*$ipp;
if ($li>$itot) $li=$itot;
//page number prefix
$pnav.='<option value="'.$i.'"'.$selected.'>'._('Page').' '.$i.' '._('of').' '.$ptot.' ('._('instances').': '.(($i-1)*$ipp+1).'-'.$li.'/'.$itot.')</option>'.N;
}
$pnav.='</select></td>'.N;
if ($p<$ptot)
$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>';
else
$pnav.='<td><img src="'.$prepath.'imgs/nav_next_off.svg"></td><td><img src="'.$prepath.'imgs/nav_last_off.svg"></td>';
$pnav.='</tr></table>'.N;
echo($pnav);
echo('</div>'.N);
}
echo('</div>'.N);
echo('</div>'.N);
$debug.='TOTAL RENDERING TIME: '.(microtime(true)-$bt).N;
if (array_key_exists('debug',$_GET) && $_GET['debug']=='1') echo('<!--'.N.'--- DEBUG INFO ---'.N.$debug.'//-->'.N);
?>