diff --git a/automation/audit.json b/automation/audit.json
index 312332f..940380d 100644
--- a/automation/audit.json
+++ b/automation/audit.json
@@ -56,7 +56,7 @@
"set @audit_rownum = ifnull(@audit_rownum, 0) + 1;"
],
"tables": {
- "launch_phase": {
+ "launch_phases": {
"audit": true,
"skip": null
},
@@ -76,6 +76,10 @@
"audit": true,
"skip": null
},
+ "allocation_tokens": {
+ "audit": null,
+ "skip": null
+ },
"error_log": {
"audit": null,
"skip": null
diff --git a/cp/app/Controllers/SystemController.php b/cp/app/Controllers/SystemController.php
index 592e238..6674b00 100644
--- a/cp/app/Controllers/SystemController.php
+++ b/cp/app/Controllers/SystemController.php
@@ -783,6 +783,8 @@ class SystemController extends Controller
$premium_categories = $db->select('SELECT * FROM premium_domain_categories');
$promotions = $db->select('SELECT * FROM promotion_pricing WHERE tld_id = ?',
[ $tld['id'] ]);
+ $launch_phases = $db->select('SELECT * FROM launch_phases WHERE tld_id = ?',
+ [ $tld['id'] ]);
// Mapping of regex patterns to script names
$regexToScriptName = [
@@ -812,6 +814,7 @@ class SystemController extends Controller
'premium_pricing' => $premium_pricing,
'premium_categories' => $premium_categories,
'promotions' => $promotions,
+ 'launch_phases' => $launch_phases,
'currentUri' => $uri
]);
} else {
@@ -989,5 +992,77 @@ class SystemController extends Controller
}
}
+
+ public function managePhases(Request $request, Response $response)
+ {
+ if ($_SESSION["auth_roles"] != 0) {
+ return $response->withHeader('Location', '/dashboard')->withStatus(302);
+ }
+
+ if ($request->getMethod() === 'POST') {
+ // Retrieve POST data
+ $data = $request->getParsedBody();
+ $db = $this->container->get('db');
+
+ $sData = array();
+
+ $sData['tldid'] = filter_var($data['tldid'], FILTER_SANITIZE_NUMBER_INT);
+ $sData['extension'] = substr(trim($data['extension']), 0, 10);
+ $sData['phaseName'] = substr(trim($data['phaseName']), 0, 255);
+ $sData['phaseType'] = substr(trim($data['phaseType']), 0, 255);
+ $sData['phaseDescription'] = substr(trim($data['phaseDescription']), 0, 1000);
+ $sData['phaseStart'] = date('Y-m-d', strtotime($data['phaseStart']));
+ $sData['phaseEnd'] = date('Y-m-d', strtotime($data['phaseEnd']));
+
+ try {
+ $currentDateTime = new \DateTime();
+ $update = $currentDateTime->format('Y-m-d H:i:s.v'); // Current timestamp
+
+ $db->beginTransaction();
+
+ $existingPhaseType = $db->selectValue(
+ 'SELECT COUNT(*) FROM launch_phases WHERE tld_id = ? AND phase_type = ?',
+ [
+ $sData['tldid'],
+ $sData['phaseType']
+ ]
+ );
+
+ if ($existingPhaseType > 0) {
+ // 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);
+ }
+
+ $db->insert(
+ 'launch_phases',
+ [
+ 'tld_id' => $sData['tldid'],
+ 'phase_name' => $sData['phaseName'],
+ 'phase_type' => $sData['phaseType'],
+ 'phase_description' => $sData['phaseDescription'],
+ 'start_date' => $sData['phaseStart'],
+ 'end_date' => $sData['phaseEnd'],
+ 'lastupdate' => $update
+ ]
+ );
+
+ $db->commit();
+
+ $this->container->get('flash')->addMessage('success', 'Launch phase updates for the ' . $sData['extension'] . ' TLD have been successfully applied');
+ return $response->withHeader('Location', '/registry/tlds')->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);
+ }
+
+ } else {
+ // Redirect to the tlds view
+ return $response->withHeader('Location', '/registry/tlds')->withStatus(302);
+ }
+
+ }
}
\ No newline at end of file
diff --git a/cp/resources/views/admin/system/manageTld.twig b/cp/resources/views/admin/system/manageTld.twig
index c65ca05..0985666 100644
--- a/cp/resources/views/admin/system/manageTld.twig
+++ b/cp/resources/views/admin/system/manageTld.twig
@@ -191,7 +191,7 @@
-
+
+
+
+
+
+
+
+
+ ID |
+ Phase Type |
+ Phase Name |
+ Phase Description |
+ Start Date |
+ End Date |
+
+
+
+ {% for phase in launch_phases %}
+
+ {{ phase.id }} |
+ {{ phase.phase_type }} |
+ {{ phase.phase_name }} |
+ {{ phase.phase_description }} |
+ {{ phase.start_date }} |
+ {{ phase.end_date }} |
+
+ {% else %}
+
+ No launch phases found. |
+
+ {% endfor %}
+
+
+
+
Create New Phase
+
+
+
diff --git a/cp/routes/web.php b/cp/routes/web.php
index 70ec91b..333e8b5 100644
--- a/cp/routes/web.php
+++ b/cp/routes/web.php
@@ -101,6 +101,7 @@ $app->group('', function ($route) {
$route->get('/registry/tlds', SystemController::class .':listTlds')->setName('listTlds');
$route->map(['GET', 'POST'], '/registry/reserved', SystemController::class .':manageReserved')->setName('manageReserved');
$route->post('/registry/promotions', SystemController::class . ':managePromo')->setName('managePromo');
+ $route->post('/registry/phases', SystemController::class . ':managePhases')->setName('managePhases');
$route->get('/support', SupportController::class .':view')->setName('ticketview');
$route->map(['GET', 'POST'], '/support/new', SupportController::class .':newticket')->setName('newticket');
diff --git a/database/registry.mariadb.sql b/database/registry.mariadb.sql
index 1e02f5e..1a78c2b 100644
--- a/database/registry.mariadb.sql
+++ b/database/registry.mariadb.sql
@@ -2,12 +2,17 @@ SET FOREIGN_KEY_CHECKS=0;
CREATE DATABASE IF NOT EXISTS `registry`;
-CREATE TABLE IF NOT EXISTS `registry`.`launch_phase` (
+CREATE TABLE IF NOT EXISTS `registry`.`launch_phases` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
- `phase_name` VARCHAR(255) NOT NULL,
+ `tld_id` int(10) unsigned DEFAULT NULL,
+ `phase_name` VARCHAR(75) NOT NULL,
+ `phase_type` VARCHAR(50) NOT NULL,
`phase_description` TEXT,
- `start_date` DATETIME(3),
- `end_date` DATETIME(3),
+ `start_date` DATETIME(3) NOT NULL,
+ `end_date` DATETIME(3) DEFAULT NULL,
+ `lastupdate` TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP,
+ KEY `tld_id` (`tld_id`),
+ FOREIGN KEY (`tld_id`) REFERENCES `domain_tld`(`id`),
UNIQUE(`phase_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='launch phases';
@@ -57,6 +62,21 @@ CREATE TABLE IF NOT EXISTS `registry`.`domain_restore_price` (
CONSTRAINT `domain_restore_price_ibfk_1` FOREIGN KEY (`tldid`) REFERENCES `domain_tld` (`id`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='domain restore price';
+CREATE TABLE IF NOT EXISTS `registry`.`allocation_tokens` (
+ token VARCHAR(255) NOT NULL,
+ domain_name VARCHAR(255) DEFAULT NULL,
+ tokenStatus VARCHAR(100) DEFAULT NULL,
+ tokenType VARCHAR(100) DEFAULT NULL,
+ createDateTime TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ lastUpdate DATETIME(3) DEFAULT NULL,
+ registrars JSON DEFAULT NULL,
+ tlds JSON DEFAULT NULL,
+ eppActions JSON DEFAULT NULL,
+ reducePremium TINYINT(1) NOT NULL,
+ reduceYears INT NOT NULL CHECK (reduceYears BETWEEN 0 AND 10),
+ PRIMARY KEY (token)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='allocation tokens';
+
CREATE TABLE IF NOT EXISTS `registry`.`error_log` (
`id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`registrar_id` INT(10) unsigned NOT NULL,
diff --git a/database/registry.postgres.sql b/database/registry.postgres.sql
index b38af59..7eae492 100644
--- a/database/registry.postgres.sql
+++ b/database/registry.postgres.sql
@@ -3,15 +3,29 @@ CREATE SCHEMA registryTransaction;
SET search_path TO registry, registryTransaction, public;
-CREATE TABLE registry.launch_phase (
+CREATE TABLE registry.launch_phases (
"id" SERIAL PRIMARY KEY,
- "phase_name" VARCHAR(255) NOT NULL,
+ "tld_id" INT CHECK ("tld_id" >= 0),
+ "phase_name" VARCHAR(75) NOT NULL,
+ "phase_type" VARCHAR(50) NOT NULL,
"phase_description" TEXT,
- "start_date" TIMESTAMP(3),
- "end_date" TIMESTAMP(3),
+ "start_date" TIMESTAMP(3) NOT NULL,
+ "end_date" TIMESTAMP(3) DEFAULT NULL,
+ "lastupdate" timestamp(3),
+ FOREIGN KEY ("tld_id") REFERENCES registry.domain_tld("id"),
UNIQUE(phase_name)
);
+ CREATE OR REPLACE FUNCTION update_phases() RETURNS trigger AS '
+BEGIN
+ NEW.lastupdate := CURRENT_TIMESTAMP;
+ RETURN NEW;
+END;
+' LANGUAGE 'plpgsql';
+
+CREATE TRIGGER add_current_date_to_launch_phases BEFORE UPDATE ON registry.launch_phases FOR EACH ROW EXECUTE PROCEDURE
+update_phases();
+
CREATE TABLE registry.domain_tld (
"id" SERIAL PRIMARY KEY,
"tld" varchar(32) NOT NULL,
@@ -53,6 +67,21 @@ CREATE TABLE registry.domain_restore_price (
unique ("tldid")
);
+CREATE TABLE registry.allocation_tokens (
+ "token" VARCHAR(255) NOT NULL,
+ "domain_name" VARCHAR(255),
+ "tokenStatus" VARCHAR(100),
+ "tokenType" VARCHAR(100),
+ "createDateTime" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "lastUpdate" TIMESTAMP(3),
+ "registrars" JSON,
+ "tlds" JSON,
+ "eppActions" JSON,
+ "reducePremium" BOOLEAN NOT NULL,
+ "reduceYears" INT NOT NULL CHECK (reduceYears BETWEEN 0 AND 10),
+ PRIMARY KEY (token)
+);
+
CREATE TABLE registry.error_log (
"id" INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
"registrar_id" int CHECK ("registrar_id" >= 0) NOT NULL,,