diff --git a/cp/app/Controllers/SystemController.php b/cp/app/Controllers/SystemController.php index d9feda1..f47336d 100644 --- a/cp/app/Controllers/SystemController.php +++ b/cp/app/Controllers/SystemController.php @@ -976,8 +976,6 @@ class SystemController extends Controller $premium_pricing = $db->selectRow('SELECT * FROM premium_domain_pricing WHERE tld_id = ?', [ $tld['id'] ]); $premium_categories = $db->select('SELECT * FROM premium_domain_categories'); - $launch_phases = $db->select('SELECT * FROM launch_phases WHERE tld_id = ?', - [ $tld['id'] ]); // Mapping of regex patterns to script names $regexToScriptName = [ @@ -1167,7 +1165,6 @@ class SystemController extends Controller 'tld_restore' => $tld_restore, 'premium_pricing' => $premium_pricing, 'premium_categories' => $premium_categories, - 'launch_phases' => $launch_phases, 'secureTld' => $secureTld, 'dnssecData' => $dnssecData, 'currentUri' => $uri @@ -1632,7 +1629,61 @@ class SystemController extends Controller } } - + + public function viewPhases(Request $request, Response $response, $args) + { + if ($_SESSION["auth_roles"] != 0) { + return $response->withHeader('Location', '/dashboard')->withStatus(302); + } + + $db = $this->container->get('db'); + // Get the current URI + $uri = $request->getUri()->getPath(); + + if ($args) { + $args = trim($args); + + if (!preg_match('/^\.(xn--[a-zA-Z0-9-]+|[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)?)$/', $args)) { + $this->container->get('flash')->addMessage('error', 'Invalid TLD format'); + return $response->withHeader('Location', '/registry/tlds')->withStatus(302); + } + + $tld = $db->selectRow('SELECT id, tld, idn_table, secure FROM domain_tld WHERE tld = ?', + [ $args ]); + + if ($tld) { + $launch_phases = $db->select('SELECT * FROM launch_phases WHERE tld_id = ?', + [ $tld['id'] ]); + + if (strpos(strtolower($tld['tld']), '.xn--') === 0) { + $tld['tld'] = ltrim($tld['tld'], '.'); + $tld_u = '.'.idn_to_utf8($tld['tld'], 0, INTL_IDNA_VARIANT_UTS46); + $tld['tld'] = '.'.$tld['tld']; + } else { + $tld_u = $tld['tld']; + } + + $_SESSION['u_tld_id'] = [$tld['id']]; + $_SESSION['u_tld_extension'] = [$tld['tld']]; + + return view($response,'admin/system/viewPhase.twig', [ + 'tld' => $tld, + 'tld_u' => $tld_u, + 'launch_phases' => $launch_phases, + 'currentUri' => $uri + ]); + } else { + // TLD does not exist, redirect to the tlds view + return $response->withHeader('Location', '/registry/tlds')->withStatus(302); + } + + } else { + // Redirect to the tlds view + return $response->withHeader('Location', '/registry/tlds')->withStatus(302); + } + + } + public function managePhases(Request $request, Response $response) { if ($_SESSION["auth_roles"] != 0) { @@ -1647,14 +1698,14 @@ class SystemController extends Controller if (!empty($_SESSION['u_tld_id'])) { $tld_id = $_SESSION['u_tld_id'][0]; } else { - $this->container->get('flash')->addMessage('error', 'No TLD specified for promotions'); + $this->container->get('flash')->addMessage('error', 'No TLD specified for launch phases'); return $response->withHeader('Location', '/registry/tlds')->withStatus(302); } if (!empty($_SESSION['u_tld_extension'])) { $tld_extension = $_SESSION['u_tld_extension'][0]; } else { - $this->container->get('flash')->addMessage('error', 'No TLD specified for promotions'); + $this->container->get('flash')->addMessage('error', 'No TLD specified for launch phases'); return $response->withHeader('Location', '/registry/tlds')->withStatus(302); } @@ -1673,7 +1724,7 @@ class SystemController extends Controller $sData['phaseEnd'] = str_replace('T', ' ', $data['phaseEnd']) . ':00'; } elseif (!in_array($sData['phaseType'], ['open', 'custom'])) { $this->container->get('flash')->addMessage('error', "Error: phaseEnd is required for phaseType '{$sData['phaseType']}'"); - return $response->withHeader('Location', '/registry/tld/'.$sData['extension'])->withStatus(302); + return $response->withHeader('Location', '/registry/phases/'.$sData['extension'])->withStatus(302); } try { @@ -1686,7 +1737,7 @@ class SystemController extends Controller if ($sData['phaseType'] === 'custom' && (empty($sData['phaseName']) || is_null($sData['phaseName']))) { // Handle the error scenario $this->container->get('flash')->addMessage('error', 'Phase name is required when the type is Custom.'); - return $response->withHeader('Location', '/registry/tld/'.$sData['extension'])->withStatus(302); + return $response->withHeader('Location', '/registry/phases/'.$sData['extension'])->withStatus(302); } // Check for existing phase_type (excluding 'custom' with different phase_name) or date overlap (excluding 'custom' and 'open' types) @@ -1731,20 +1782,20 @@ class SystemController extends Controller // phase_type already exists for the tldid $db->rollBack(); $this->container->get('flash')->addMessage('error', 'The phase type already exists for this TLD.'); - return $response->withHeader('Location', '/registry/tld/'.$sData['extension'])->withStatus(302); + return $response->withHeader('Location', '/registry/phases/'.$sData['extension'])->withStatus(302); } if ($result['duplicatePhaseNameExists'] > 0) { $db->rollBack(); $this->container->get('flash')->addMessage('error', 'A phase with this name already exists for this TLD.'); - return $response->withHeader('Location', '/registry/tld/'.$sData['extension'])->withStatus(302); + return $response->withHeader('Location', '/registry/phases/'.$sData['extension'])->withStatus(302); } if ($result['dateOverlapExists'] > 0) { // Date range overlaps with an existing entry $db->rollBack(); $this->container->get('flash')->addMessage('error', 'Date range overlaps with an existing phase for this TLD.'); - return $response->withHeader('Location', '/registry/tld/'.$sData['extension'])->withStatus(302); + return $response->withHeader('Location', '/registry/phases/'.$sData['extension'])->withStatus(302); } $db->insert( @@ -1767,11 +1818,11 @@ class SystemController extends Controller unset($_SESSION['u_tld_extension']); $this->container->get('flash')->addMessage('success', 'Launch phase updates for the ' . $sData['extension'] . ' TLD have been successfully applied'); - return $response->withHeader('Location', '/registry/tld/'.$sData['extension'])->withStatus(302); + return $response->withHeader('Location', '/registry/phases/'.$sData['extension'])->withStatus(302); } catch (Exception $e) { $db->rollBack(); $this->container->get('flash')->addMessage('error', 'Database failure: ' . $e->getMessage()); - return $response->withHeader('Location', '/registry/tld/'.$sData['extension'])->withStatus(302); + return $response->withHeader('Location', '/registry/phases/'.$sData['extension'])->withStatus(302); } } else { diff --git a/cp/resources/views/admin/system/manageTld.twig b/cp/resources/views/admin/system/manageTld.twig index 495e902..93e5751 100644 --- a/cp/resources/views/admin/system/manageTld.twig +++ b/cp/resources/views/admin/system/manageTld.twig @@ -320,104 +320,6 @@ -
-
-
{{ __('Manage Launch Phases') }}
-
-
-
- - - - - - - - - - - - - {% for phase in launch_phases %} - - - - - - - - - {% else %} - - - - {% endfor %} - -
{{ __('Phase Type') }}{{ __('Phase Name') }}{{ __('Phase Category') }}{{ __('Phase Description') }}{{ __('Start Date') }}{{ __('End Date') }}
{{ phase.phase_type|capitalize }}{{ phase.phase_name|default('N/A') }}{{ phase.phase_category }}{{ phase.phase_description }}{{ phase.start_date }}{{ phase.end_date|default('N/A') }}
{{ __('No launch phases found.') }}
-
-
{{ __('Create New Phase') }}
-
- {{ csrf.field | raw }} -
- - -
-
- - - The "Phase Name" field is required only if the "Type" is set to "Custom". -
-
-
{{ __('Phase Category') }}
-
- - -
-
-
- - -
-
-
-
- - - {{ __('Please Note:') }} {{ __('All times displayed are in') }} Coordinated Universal Time (UTC) -
-
-
-
- - -
-
-
-
- -
- {% include 'partials/footer.twig' %} diff --git a/cp/resources/views/admin/system/viewPhase.twig b/cp/resources/views/admin/system/viewPhase.twig new file mode 100644 index 0000000..78f7cf5 --- /dev/null +++ b/cp/resources/views/admin/system/viewPhase.twig @@ -0,0 +1,131 @@ +{% extends "layouts/app.twig" %} + +{% block title %}{{ __('Manage Launch Phases') }} {{ __('for') }} {{ tld_u }}{% endblock %} + +{% block content %} +
+ + + +
+
+
+ {% include 'partials/flash.twig' %} + +
+
+
{{ __('Manage Launch Phases') }}
+
+
+
+ + + + + + + + + + + + + {% for phase in launch_phases %} + + + + + + + + + {% else %} + + + + {% endfor %} + +
{{ __('Phase Type') }}{{ __('Phase Name') }}{{ __('Phase Category') }}{{ __('Phase Description') }}{{ __('Start Date') }}{{ __('End Date') }}
{{ phase.phase_type|capitalize }}{{ phase.phase_name|default('N/A') }}{{ phase.phase_category }}{{ phase.phase_description }}{{ phase.start_date }}{{ phase.end_date|default('N/A') }}
{{ __('No launch phases found.') }}
+
+
{{ __('Create New Phase') }}
+
+ {{ csrf.field | raw }} +
+ + +
+
+ + + The "Phase Name" field is required only if the "Type" is set to "Custom". +
+
+
{{ __('Phase Category') }}
+
+ + +
+
+
+ + +
+
+
+
+ + + {{ __('Please Note:') }} {{ __('All times displayed are in') }} Coordinated Universal Time (UTC) +
+
+
+
+ + +
+
+
+
+ +
+ +
+
+ {% include 'partials/footer.twig' %} +
+{% endblock %} \ No newline at end of file diff --git a/cp/resources/views/admin/system/viewPromo.twig b/cp/resources/views/admin/system/viewPromo.twig index bfb97fe..fbba56c 100644 --- a/cp/resources/views/admin/system/viewPromo.twig +++ b/cp/resources/views/admin/system/viewPromo.twig @@ -26,7 +26,7 @@
{% include 'partials/flash.twig' %} -
+
{{ __('Manage Promotions') }} {{ __('for') }} {{ tld_u }}
diff --git a/cp/resources/views/partials/js-tlds.twig b/cp/resources/views/partials/js-tlds.twig index 12819fa..cef89a3 100644 --- a/cp/resources/views/partials/js-tlds.twig +++ b/cp/resources/views/partials/js-tlds.twig @@ -24,7 +24,7 @@ } function actionsFormatter(cell, formatterParams, onRendered) { - return ` `; + return ` `; } // Mapping of database string values to script names @@ -76,7 +76,7 @@ {title:"TLD", field:"tld", minWidth:50, headerSort:true, resizable:false, formatter: tldLinkFormatter, responsive:0}, { title: "{{ __('Script') }}", field: "idn_table", width:300, minWidth:80, headerSort:true, resizable:false, formatter: scriptNameFormatter, responsive:2}, {title:"DNSSEC", field:"secure", width:250, minWidth:80, headerSort:true, resizable:false, formatter: secureFormatter, responsive:2}, - {title: "{{ __('Actions') }}", formatter: actionsFormatter, headerSort: false, resizable:false, download:false, hozAlign: "center", responsive:0, cellClick:function(e, cell){ e.stopPropagation(); }}, + {title: "{{ __('Actions') }}", formatter: actionsFormatter, minWidth:200, headerSort: false, resizable:false, download:false, hozAlign: "center", responsive:0, cellClick:function(e, cell){ e.stopPropagation(); }}, ] }); var searchInput = document.getElementById("search-input"); diff --git a/cp/routes/web.php b/cp/routes/web.php index 7c34d4f..4065cc6 100644 --- a/cp/routes/web.php +++ b/cp/routes/web.php @@ -147,6 +147,7 @@ $app->group('', function ($route) { $route->map(['GET', 'POST'], '/registry/tokens/delete/{token}', SystemController::class . ':deleteToken')->setName('deleteToken'); $route->get('/registry/promotion/{tld}', SystemController::class . ':viewPromo')->setName('viewPromo'); $route->post('/registry/promotions', SystemController::class . ':managePromo')->setName('managePromo'); + $route->get('/registry/phases/{tld}', SystemController::class . ':viewPhases')->setName('viewPhases'); $route->post('/registry/phases', SystemController::class . ':managePhases')->setName('managePhases'); $route->get('/registry/idnexport/{script}', SystemController::class .':idnexport')->setName('idnexport');