mirror of
https://github.com/getnamingo/registry.git
synced 2025-07-20 17:46:03 +02:00
Added registrar statistics in CP reports menu
Also fixed small bug in view registrar
This commit is contained in:
parent
fca7e93306
commit
b5e607fdb8
3 changed files with 95 additions and 5 deletions
|
@ -313,11 +313,11 @@ class RegistrarsController extends Controller
|
||||||
if ($args) {
|
if ($args) {
|
||||||
$args = trim(preg_replace('/\s+/', ' ', $args));
|
$args = trim(preg_replace('/\s+/', ' ', $args));
|
||||||
|
|
||||||
if (!preg_match('/^[a-zA-Z0-9\s]+$/', $args)) {
|
if (!preg_match('/^[a-zA-Z0-9\s.\-]+$/', $args)) {
|
||||||
$this->container->get('flash')->addMessage('error', 'Invalid registrar');
|
$this->container->get('flash')->addMessage('error', 'Invalid registrar');
|
||||||
return $response->withHeader('Location', '/registrars')->withStatus(302);
|
return $response->withHeader('Location', '/registrars')->withStatus(302);
|
||||||
}
|
}
|
||||||
|
|
||||||
$registrar = $db->selectRow('SELECT * FROM registrar WHERE name = ?',
|
$registrar = $db->selectRow('SELECT * FROM registrar WHERE name = ?',
|
||||||
[ $args ]);
|
[ $args ]);
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,42 @@ class ReportsController extends Controller
|
||||||
if ($_SESSION["auth_roles"] != 0) {
|
if ($_SESSION["auth_roles"] != 0) {
|
||||||
return $response->withHeader('Location', '/dashboard')->withStatus(302);
|
return $response->withHeader('Location', '/dashboard')->withStatus(302);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$stats = [];
|
||||||
|
$currency = $_SESSION['_currency'] ?? 'USD';
|
||||||
|
$db = $this->container->get('db');
|
||||||
|
$totalDomains = $db->select('SELECT COUNT(name) as total FROM domain');
|
||||||
|
$numT = $totalDomains[0]['total'] ?? 1;
|
||||||
|
|
||||||
return view($response,'admin/reports/index.twig');
|
$registrars = $db->select('SELECT id, name FROM registrar');
|
||||||
|
foreach ($registrars as $registrar) {
|
||||||
|
$domainCount = $db->select(
|
||||||
|
'SELECT COUNT(name) as count FROM domain WHERE clid = ?',
|
||||||
|
[$registrar['id']]
|
||||||
|
);
|
||||||
|
|
||||||
|
$earnings = $db->select(
|
||||||
|
'SELECT SUM(amount) as amt FROM statement WHERE registrar_id = ? AND command <> "deposit"',
|
||||||
|
[$registrar['id']]
|
||||||
|
);
|
||||||
|
|
||||||
|
$stats[] = [
|
||||||
|
'id' => $registrar['id'],
|
||||||
|
'registrar' => $registrar['name'],
|
||||||
|
'currency' => $currency,
|
||||||
|
'number' => $domainCount[0]['count'] ?? 0,
|
||||||
|
'share' => number_format(($domainCount[0]['count'] ?? 0) / $numT * 100, 2),
|
||||||
|
'earnings' => $earnings[0]['amt'] ?? 0
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($stats, function ($a, $b) {
|
||||||
|
return $b['share'] <=> $a['share'];
|
||||||
|
});
|
||||||
|
|
||||||
|
return view($response,'admin/reports/index.twig', [
|
||||||
|
'stats' => $stats
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function exportDomains(Request $request, Response $response)
|
public function exportDomains(Request $request, Response $response)
|
||||||
|
|
|
@ -20,11 +20,18 @@
|
||||||
<!-- Page title actions -->
|
<!-- Page title actions -->
|
||||||
<div class="col-auto ms-auto d-print-none">
|
<div class="col-auto ms-auto d-print-none">
|
||||||
<div class="btn-list">
|
<div class="btn-list">
|
||||||
<a href="{{route('exportDomains')}}" class="btn btn-info d-none d-sm-inline-block">
|
<a href="#" class="btn btn-indigo d-none d-sm-inline-block" data-bs-toggle="modal" data-bs-target="#statsModal">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 3v18h18" /><path d="M9 9m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /><path d="M19 7m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /><path d="M14 15m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /><path d="M10.16 10.62l2.34 2.88" /><path d="M15.088 13.328l2.837 -4.586" /></svg>
|
||||||
|
{{ __('Registrar Statistics') }}
|
||||||
|
</a>
|
||||||
|
<a href="{{route('exportDomains')}}" class="btn btn-lime d-none d-sm-inline-block">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 6c0 1.657 3.582 3 8 3s8 -1.343 8 -3s-3.582 -3 -8 -3s-8 1.343 -8 3" /><path d="M4 6v6c0 1.657 3.582 3 8 3c1.118 0 2.183 -.086 3.15 -.241" /><path d="M20 12v-6" /><path d="M4 12v6c0 1.657 3.582 3 8 3c.157 0 .312 -.002 .466 -.005" /><path d="M16 19h6" /><path d="M19 16l3 3l-3 3" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 6c0 1.657 3.582 3 8 3s8 -1.343 8 -3s-3.582 -3 -8 -3s-8 1.343 -8 3" /><path d="M4 6v6c0 1.657 3.582 3 8 3c1.118 0 2.183 -.086 3.15 -.241" /><path d="M20 12v-6" /><path d="M4 12v6c0 1.657 3.582 3 8 3c.157 0 .312 -.002 .466 -.005" /><path d="M16 19h6" /><path d="M19 16l3 3l-3 3" /></svg>
|
||||||
{{ __('Export Domains') }}
|
{{ __('Export Domains') }}
|
||||||
</a>
|
</a>
|
||||||
<a href="{{route('exportDomains')}}" class="btn btn-info d-sm-none btn-icon" aria-label="{{ __('Export Domains') }}">
|
<a href="#" class="btn btn-indigo d-sm-none btn-icon" aria-label="{{ __('Registrar Statistics') }}" data-bs-toggle="modal" data-bs-target="#statsModal">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 3v18h18" /><path d="M9 9m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /><path d="M19 7m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /><path d="M14 15m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /><path d="M10.16 10.62l2.34 2.88" /><path d="M15.088 13.328l2.837 -4.586" /></svg>
|
||||||
|
</a>
|
||||||
|
<a href="{{route('exportDomains')}}" class="btn btn-lime d-sm-none btn-icon" aria-label="{{ __('Export Domains') }}">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 6c0 1.657 3.582 3 8 3s8 -1.343 8 -3s-3.582 -3 -8 -3s-8 1.343 -8 3" /><path d="M4 6v6c0 1.657 3.582 3 8 3c1.118 0 2.183 -.086 3.15 -.241" /><path d="M20 12v-6" /><path d="M4 12v6c0 1.657 3.582 3 8 3c.157 0 .312 -.002 .466 -.005" /><path d="M16 19h6" /><path d="M19 16l3 3l-3 3" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 6c0 1.657 3.582 3 8 3s8 -1.343 8 -3s-3.582 -3 -8 -3s-8 1.343 -8 3" /><path d="M4 6v6c0 1.657 3.582 3 8 3c1.118 0 2.183 -.086 3.15 -.241" /><path d="M20 12v-6" /><path d="M4 12v6c0 1.657 3.582 3 8 3c.157 0 .312 -.002 .466 -.005" /><path d="M16 19h6" /><path d="M19 16l3 3l-3 3" /></svg>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -62,4 +69,53 @@
|
||||||
</div>
|
</div>
|
||||||
{% include 'partials/footer.twig' %}
|
{% include 'partials/footer.twig' %}
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div class="modal fade" id="statsModal" tabindex="-1" aria-labelledby="statsModalLabel">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="statsModalLabel">{{ __('Registrar Statistics') }}</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="table-responsive" style="max-height: 400px; overflow-y: auto;">
|
||||||
|
<table class="table table-vcenter">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{ __('Registrar') }}</th>
|
||||||
|
<th>{{ __('Number of Domains') }}</th>
|
||||||
|
<th>{{ __('Market Share') }}</th>
|
||||||
|
<th>{{ __('Earnings') }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for stat in stats %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<strong>{{ stat.registrar }}</strong>
|
||||||
|
<a href="/registrar/view/{{ stat.registrar }}" class="ms-1" aria-label="{{ __('Open website') }}" target="_blank">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M10 14a3.5 3.5 0 0 0 5 0l4 -4a3.5 3.5 0 0 0 -5 -5l-.5 .5" />
|
||||||
|
<path d="M14 10a3.5 3.5 0 0 0 -5 0l-4 4a3.5 3.5 0 0 0 5 5l.5 -.5" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="text-muted">{{ stat.number }}</td>
|
||||||
|
<td class="text-muted">{{ stat.share }}%</td>
|
||||||
|
<td>{{ stat.earnings | number_format(2, '.', ',') }} {{ currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ __('Close') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
Loading…
Add table
Add a link
Reference in a new issue