//////////////////////////// common.php ////////////////////////////
= e($title) ?> | ICT3612 Assessment 3
Source code used for this task
PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
initialise_database($pdo);
return $pdo;
}
function initialise_database(PDO $pdo)
{
$statements = [
"CREATE TABLE IF NOT EXISTS Modules (
ModuleCode VARCHAR(10) PRIMARY KEY,
ModuleName VARCHAR(120) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
"CREATE TABLE IF NOT EXISTS Lecturers (
LecturerID INT AUTO_INCREMENT PRIMARY KEY,
LecturerName VARCHAR(120) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
"CREATE TABLE IF NOT EXISTS Roles (
RoleID INT AUTO_INCREMENT PRIMARY KEY,
RoleName VARCHAR(80) NOT NULL UNIQUE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
"CREATE TABLE IF NOT EXISTS ModuleLecturerRole (
ModuleCode VARCHAR(10) NOT NULL,
LecturerID INT NOT NULL,
RoleID INT NOT NULL,
Year SMALLINT NOT NULL,
PRIMARY KEY (ModuleCode, LecturerID, RoleID, Year),
CONSTRAINT fk_mlr_module FOREIGN KEY (ModuleCode)
REFERENCES Modules(ModuleCode) ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_mlr_lecturer FOREIGN KEY (LecturerID)
REFERENCES Lecturers(LecturerID) ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_mlr_role FOREIGN KEY (RoleID)
REFERENCES Roles(RoleID) ON UPDATE CASCADE ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
"CREATE TABLE IF NOT EXISTS organisations (
organisation_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(140) NOT NULL,
registration_number VARCHAR(60) NOT NULL UNIQUE,
contact_email VARCHAR(160) NOT NULL,
phone VARCHAR(40) NOT NULL,
address VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
"CREATE TABLE IF NOT EXISTS users (
user_id INT AUTO_INCREMENT PRIMARY KEY,
organisation_id INT NULL,
username VARCHAR(60) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
role ENUM('admin','organisation') NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_user_organisation FOREIGN KEY (organisation_id)
REFERENCES organisations(organisation_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
"CREATE TABLE IF NOT EXISTS trainings (
training_id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(140) NOT NULL,
description VARCHAR(255) NOT NULL,
training_date DATE NOT NULL,
venue VARCHAR(140) NOT NULL,
cost DECIMAL(10,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
"CREATE TABLE IF NOT EXISTS employees (
employee_id INT AUTO_INCREMENT PRIMARY KEY,
organisation_id INT NOT NULL,
employee_number VARCHAR(40) NOT NULL,
first_name VARCHAR(80) NOT NULL,
last_name VARCHAR(80) NOT NULL,
email VARCHAR(160) NOT NULL,
UNIQUE KEY uq_employee_number_org (organisation_id, employee_number),
CONSTRAINT fk_employee_organisation FOREIGN KEY (organisation_id)
REFERENCES organisations(organisation_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
"CREATE TABLE IF NOT EXISTS registrations (
registration_id INT AUTO_INCREMENT PRIMARY KEY,
employee_id INT NOT NULL,
training_id INT NOT NULL,
status ENUM('Registered','Completed','Cancelled') NOT NULL DEFAULT 'Registered',
registered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uq_employee_training (employee_id, training_id),
CONSTRAINT fk_registration_employee FOREIGN KEY (employee_id)
REFERENCES employees(employee_id) ON DELETE CASCADE,
CONSTRAINT fk_registration_training FOREIGN KEY (training_id)
REFERENCES trainings(training_id) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
];
foreach ($statements as $statement) {
$pdo->exec($statement);
}
seed_task2($pdo);
seed_task4($pdo);
}
function seed_task2(PDO $pdo)
{
if ((int) $pdo->query('SELECT COUNT(*) FROM Modules')->fetchColumn() === 0) {
$pdo->exec("INSERT INTO Modules (ModuleCode, ModuleName) VALUES
('ICT2613', 'Internet Programming'),
('ICT3611', 'Advanced Databases'),
('ICT3612', 'Advanced Internet Programming'),
('ICT3715', 'Information Security'),
('ICT3722', 'Human-Computer Interaction')");
}
if ((int) $pdo->query('SELECT COUNT(*) FROM Lecturers')->fetchColumn() === 0) {
$pdo->exec("INSERT INTO Lecturers (LecturerName) VALUES
('Dr Amina Jacobs'),
('Prof Kabelo Mokoena'),
('Dr Naledi Khumalo'),
('Ms Lerato Molefe'),
('Prof Sipho Dlamini'),
('Ms Thandi Ndlovu')");
}
if ((int) $pdo->query('SELECT COUNT(*) FROM Roles')->fetchColumn() === 0) {
$pdo->exec("INSERT INTO Roles (RoleName) VALUES
('Primary lecturer'),
('Secondary lecturer'),
('Internal moderator'),
('External moderator'),
('Critical reader')");
}
if ((int) $pdo->query('SELECT COUNT(*) FROM ModuleLecturerRole')->fetchColumn() === 0) {
$pdo->exec("INSERT INTO ModuleLecturerRole (ModuleCode, LecturerID, RoleID, Year) VALUES
('ICT2613', 1, 1, 2026),
('ICT3611', 2, 1, 2026),
('ICT3612', 3, 1, 2026),
('ICT3715', 4, 2, 2026),
('ICT3722', 5, 3, 2026),
('ICT3612', 2, 4, 2026)");
}
}
function seed_task4(PDO $pdo)
{
if ((int) $pdo->query('SELECT COUNT(*) FROM organisations')->fetchColumn() === 0) {
$pdo->exec("INSERT INTO organisations
(name, registration_number, contact_email, phone, address) VALUES
('Ubuntu Digital Solutions', '2020/145821/07', 'learning@ubuntudigital.co.za', '011 555 0182', '45 Rivonia Road, Sandton'),
('Cape Horizon Logistics', '2018/278411/07', 'hr@capehorizon.co.za', '021 555 0134', '12 Dock Road, Cape Town'),
('Mahlangu Health Group', '2019/304567/07', 'people@mahlanguhealth.co.za', '012 555 0199', '88 Francis Baard Street, Pretoria')");
}
if ((int) $pdo->query('SELECT COUNT(*) FROM users')->fetchColumn() === 0) {
$insert = $pdo->prepare(
'INSERT INTO users (organisation_id, username, password_hash, role) VALUES (?, ?, ?, ?)'
);
$insert->execute([null, 'admin21194440', password_hash('Admin@2026', PASSWORD_DEFAULT), 'admin']);
$insert->execute([1, 'ubuntu_org', password_hash('Ubuntu@2026', PASSWORD_DEFAULT), 'organisation']);
$insert->execute([2, 'cape_org', password_hash('Cape@2026', PASSWORD_DEFAULT), 'organisation']);
$insert->execute([3, 'mahlangu_org', password_hash('Health@2026', PASSWORD_DEFAULT), 'organisation']);
}
if ((int) $pdo->query('SELECT COUNT(*) FROM trainings')->fetchColumn() === 0) {
$pdo->exec("INSERT INTO trainings
(title, description, training_date, venue, cost) VALUES
('Cybersecurity Essentials', 'Practical cyber hygiene, phishing prevention and incident reporting.', '2026-08-18', 'Johannesburg Learning Hub', 2850.00),
('Data Analytics with Power BI', 'From data preparation to interactive business dashboards.', '2026-09-03', 'Cape Town Learning Hub', 3400.00),
('People Leadership', 'Coaching, feedback and performance conversations for new managers.', '2026-09-16', 'Virtual classroom', 2200.00),
('Project Management Foundations', 'Planning, risk, quality and stakeholder communication.', '2026-10-07', 'Pretoria Learning Hub', 3150.00)");
}
if ((int) $pdo->query('SELECT COUNT(*) FROM employees')->fetchColumn() === 0) {
$pdo->exec("INSERT INTO employees
(organisation_id, employee_number, first_name, last_name, email) VALUES
(1, 'UDS-104', 'Ayanda', 'Maseko', 'ayanda.maseko@ubuntudigital.co.za'),
(1, 'UDS-117', 'Jason', 'Pillay', 'jason.pillay@ubuntudigital.co.za'),
(2, 'CHL-088', 'Zanele', 'Radebe', 'zanele.radebe@capehorizon.co.za'),
(2, 'CHL-093', 'Megan', 'Adams', 'megan.adams@capehorizon.co.za'),
(3, 'MHG-221', 'Thabo', 'Mahlangu', 'thabo.mahlangu@mahlanguhealth.co.za'),
(3, 'MHG-236', 'Fatima', 'Ismail', 'fatima.ismail@mahlanguhealth.co.za')");
}
if ((int) $pdo->query('SELECT COUNT(*) FROM registrations')->fetchColumn() === 0) {
$pdo->exec("INSERT INTO registrations (employee_id, training_id, status) VALUES
(1, 1, 'Registered'),
(2, 2, 'Registered'),
(3, 3, 'Registered'),
(4, 1, 'Completed'),
(5, 4, 'Registered'),
(6, 3, 'Registered')");
}
}
//////////////////////////// task4_models.php ////////////////////////////
pdo = $pdo;
}
public function findUserByUsername($username)
{
$statement = $this->pdo->prepare(
'SELECT u.*, o.name AS organisation_name
FROM users u LEFT JOIN organisations o ON o.organisation_id = u.organisation_id
WHERE u.username = ?'
);
$statement->execute([$username]);
return $statement->fetch();
}
public function registerOrganisation(array $data)
{
$this->pdo->beginTransaction();
try {
$organisation = $this->pdo->prepare(
'INSERT INTO organisations
(name, registration_number, contact_email, phone, address)
VALUES (?, ?, ?, ?, ?)'
);
$organisation->execute([
$data['name'],
$data['registration_number'],
$data['contact_email'],
$data['phone'],
$data['address'],
]);
$organisationId = (int) $this->pdo->lastInsertId();
$user = $this->pdo->prepare(
"INSERT INTO users (organisation_id, username, password_hash, role)
VALUES (?, ?, ?, 'organisation')"
);
$user->execute([
$organisationId,
$data['username'],
password_hash($data['password'], PASSWORD_DEFAULT),
]);
$this->pdo->commit();
return $organisationId;
} catch (Throwable $error) {
$this->pdo->rollBack();
throw $error;
}
}
}
class TrainingModel
{
private $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function all()
{
return $this->pdo->query(
'SELECT * FROM trainings ORDER BY training_date, title'
)->fetchAll();
}
public function exists($trainingId)
{
$statement = $this->pdo->prepare('SELECT COUNT(*) FROM trainings WHERE training_id = ?');
$statement->execute([$trainingId]);
return (int) $statement->fetchColumn() === 1;
}
}
class OrganisationModel
{
private $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function createEmployeeRegistration($organisationId, array $data)
{
$this->pdo->beginTransaction();
try {
$lookup = $this->pdo->prepare(
'SELECT employee_id FROM employees
WHERE organisation_id = ? AND employee_number = ?'
);
$lookup->execute([$organisationId, $data['employee_number']]);
$employeeId = $lookup->fetchColumn();
if ($employeeId) {
$update = $this->pdo->prepare(
'UPDATE employees SET first_name = ?, last_name = ?, email = ?
WHERE employee_id = ? AND organisation_id = ?'
);
$update->execute([
$data['first_name'],
$data['last_name'],
$data['email'],
$employeeId,
$organisationId,
]);
} else {
$insert = $this->pdo->prepare(
'INSERT INTO employees
(organisation_id, employee_number, first_name, last_name, email)
VALUES (?, ?, ?, ?, ?)'
);
$insert->execute([
$organisationId,
$data['employee_number'],
$data['first_name'],
$data['last_name'],
$data['email'],
]);
$employeeId = (int) $this->pdo->lastInsertId();
}
$registration = $this->pdo->prepare(
"INSERT INTO registrations (employee_id, training_id, status)
VALUES (?, ?, 'Registered')"
);
$registration->execute([$employeeId, $data['training_id']]);
$this->pdo->commit();
} catch (Throwable $error) {
$this->pdo->rollBack();
throw $error;
}
}
public function registrations($organisationId)
{
$statement = $this->pdo->prepare(
'SELECT r.registration_id, e.employee_number, e.first_name, e.last_name,
e.email, t.training_id, t.title, t.training_date, t.venue, t.cost,
r.status, r.registered_at
FROM registrations r
INNER JOIN employees e ON e.employee_id = r.employee_id
INNER JOIN trainings t ON t.training_id = r.training_id
WHERE e.organisation_id = ?
ORDER BY t.training_date, e.last_name, e.first_name'
);
$statement->execute([$organisationId]);
return $statement->fetchAll();
}
public function summary($organisationId)
{
$statement = $this->pdo->prepare(
"SELECT COUNT(r.registration_id) AS registration_count,
COUNT(DISTINCT e.employee_id) AS employee_count,
COALESCE(SUM(CASE WHEN r.status <> 'Cancelled' THEN t.cost ELSE 0 END), 0) AS total_cost
FROM employees e
LEFT JOIN registrations r ON r.employee_id = e.employee_id
LEFT JOIN trainings t ON t.training_id = r.training_id
WHERE e.organisation_id = ?"
);
$statement->execute([$organisationId]);
return $statement->fetch();
}
public function updateRegistration($organisationId, $registrationId, $trainingId, $status)
{
$statement = $this->pdo->prepare(
'UPDATE registrations r
INNER JOIN employees e ON e.employee_id = r.employee_id
SET r.training_id = ?, r.status = ?
WHERE r.registration_id = ? AND e.organisation_id = ?'
);
$statement->execute([$trainingId, $status, $registrationId, $organisationId]);
if ($statement->rowCount() === 0) {
$check = $this->pdo->prepare(
'SELECT COUNT(*) FROM registrations r
JOIN employees e ON e.employee_id = r.employee_id
WHERE r.registration_id = ? AND e.organisation_id = ?'
);
$check->execute([$registrationId, $organisationId]);
if ((int) $check->fetchColumn() === 0) {
throw new RuntimeException('Registration not found for this organisation.');
}
}
}
public function deleteRegistration($organisationId, $registrationId)
{
$statement = $this->pdo->prepare(
'DELETE r FROM registrations r
INNER JOIN employees e ON e.employee_id = r.employee_id
WHERE r.registration_id = ? AND e.organisation_id = ?'
);
$statement->execute([$registrationId, $organisationId]);
if ($statement->rowCount() !== 1) {
throw new RuntimeException('Registration not found for this organisation.');
}
}
}
class AdminModel
{
private $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function organisations()
{
return $this->pdo->query(
'SELECT organisation_id, name FROM organisations ORDER BY name'
)->fetchAll();
}
public function overview()
{
return $this->pdo->query(
"SELECT
(SELECT COUNT(*) FROM organisations) AS organisations,
(SELECT COUNT(*) FROM employees) AS employees,
(SELECT COUNT(*) FROM registrations) AS registrations,
(SELECT COALESCE(SUM(t.cost), 0)
FROM registrations r JOIN trainings t ON t.training_id = r.training_id
WHERE r.status <> 'Cancelled') AS revenue"
)->fetch();
}
public function report($trainingId = 0, $organisationId = 0)
{
$sql = 'SELECT r.registration_id, o.name AS organisation, e.employee_number,
CONCAT(e.first_name, " ", e.last_name) AS participant,
e.email, t.title AS training, t.training_date, t.cost, r.status
FROM registrations r
INNER JOIN employees e ON e.employee_id = r.employee_id
INNER JOIN organisations o ON o.organisation_id = e.organisation_id
INNER JOIN trainings t ON t.training_id = r.training_id
WHERE 1 = 1';
$parameters = [];
if ($trainingId > 0) {
$sql .= ' AND t.training_id = ?';
$parameters[] = $trainingId;
}
if ($organisationId > 0) {
$sql .= ' AND o.organisation_id = ?';
$parameters[] = $organisationId;
}
$sql .= ' ORDER BY t.training_date, o.name, e.last_name';
$statement = $this->pdo->prepare($sql);
$statement->execute($parameters);
return $statement->fetchAll();
}
}
//////////////////////////// task4_controllers.php ////////////////////////////
$message, 'type' => $type];
}
function take_flash_message()
{
$flash = $_SESSION['flash'] ?? null;
unset($_SESSION['flash']);
return $flash;
}
function safe_error_message(Throwable $error)
{
if ($error instanceof PDOException) {
if ((string) $error->getCode() === '23000') {
return 'That record already exists or is still referenced by another record.';
}
return 'The database operation could not be completed. Please try again.';
}
return $error->getMessage();
}
function redirect_task4($query = '')
{
header('Location: task4.php' . ($query ? '?' . $query : ''));
exit;
}
function logged_in_user()
{
return $_SESSION['task4_user'] ?? null;
}
class AuthController
{
private $model;
public function __construct(AuthModel $model)
{
$this->model = $model;
}
public function login()
{
require_valid_post();
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
$user = $this->model->findUserByUsername($username);
if (!$user || !password_verify($password, $user['password_hash'])) {
throw new RuntimeException('The username or password is incorrect.');
}
session_regenerate_id(true);
$_SESSION['task4_user'] = [
'user_id' => (int) $user['user_id'],
'organisation_id' => $user['organisation_id'] === null ? null : (int) $user['organisation_id'],
'username' => $user['username'],
'role' => $user['role'],
'organisation_name' => $user['organisation_name'],
];
flash_message('Welcome back, ' . $user['username'] . '.');
redirect_task4();
}
public function logout()
{
require_valid_post();
unset($_SESSION['task4_user']);
session_regenerate_id(true);
flash_message('You have been logged out.');
redirect_task4();
}
public function register()
{
require_valid_post();
$data = [
'name' => trim($_POST['name'] ?? ''),
'registration_number' => trim($_POST['registration_number'] ?? ''),
'contact_email' => trim($_POST['contact_email'] ?? ''),
'phone' => trim($_POST['phone'] ?? ''),
'address' => trim($_POST['address'] ?? ''),
'username' => trim($_POST['username'] ?? ''),
'password' => $_POST['password'] ?? '',
];
foreach ($data as $field => $value) {
if ($value === '') {
throw new InvalidArgumentException('All organisation and account fields are required.');
}
}
if (!filter_var($data['contact_email'], FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Enter a valid organisation email address.');
}
if (!preg_match('/^[A-Za-z0-9_]{4,60}$/', $data['username'])) {
throw new InvalidArgumentException('Username must be 4-60 letters, numbers or underscores.');
}
if (strlen($data['password']) < 8) {
throw new InvalidArgumentException('Password must contain at least 8 characters.');
}
$this->model->registerOrganisation($data);
flash_message('Organisation registered. You can now log in.');
redirect_task4('page=login');
}
}
class OrganisationController
{
private $model;
private $trainings;
public function __construct(OrganisationModel $model, TrainingModel $trainings)
{
$this->model = $model;
$this->trainings = $trainings;
}
private function organisationId()
{
$user = logged_in_user();
if (!$user || $user['role'] !== 'organisation' || !$user['organisation_id']) {
throw new RuntimeException('Organisation login required.');
}
return (int) $user['organisation_id'];
}
public function createRegistration()
{
require_valid_post();
$organisationId = $this->organisationId();
$data = [
'employee_number' => trim($_POST['employee_number'] ?? ''),
'first_name' => trim($_POST['first_name'] ?? ''),
'last_name' => trim($_POST['last_name'] ?? ''),
'email' => trim($_POST['email'] ?? ''),
'training_id' => filter_input(INPUT_POST, 'training_id', FILTER_VALIDATE_INT),
];
if (
$data['employee_number'] === '' ||
$data['first_name'] === '' ||
$data['last_name'] === '' ||
!filter_var($data['email'], FILTER_VALIDATE_EMAIL) ||
!$data['training_id']
) {
throw new InvalidArgumentException('Complete all employee fields with a valid email and training.');
}
if (!$this->trainings->exists($data['training_id'])) {
throw new InvalidArgumentException('The selected training does not exist.');
}
$this->model->createEmployeeRegistration($organisationId, $data);
flash_message('Employee training registration added.');
redirect_task4();
}
public function updateRegistration()
{
require_valid_post();
$organisationId = $this->organisationId();
$registrationId = filter_input(INPUT_POST, 'registration_id', FILTER_VALIDATE_INT);
$trainingId = filter_input(INPUT_POST, 'training_id', FILTER_VALIDATE_INT);
$status = $_POST['status'] ?? '';
if (!$registrationId || !$trainingId || !in_array($status, ['Registered', 'Completed', 'Cancelled'], true)) {
throw new InvalidArgumentException('Choose a valid training and registration status.');
}
if (!$this->trainings->exists($trainingId)) {
throw new InvalidArgumentException('The selected training does not exist.');
}
$this->model->updateRegistration($organisationId, $registrationId, $trainingId, $status);
flash_message('Training registration updated.');
redirect_task4();
}
public function deleteRegistration()
{
require_valid_post();
$registrationId = filter_input(INPUT_POST, 'registration_id', FILTER_VALIDATE_INT);
if (!$registrationId) {
throw new InvalidArgumentException('Choose a valid registration.');
}
$this->model->deleteRegistration($this->organisationId(), $registrationId);
flash_message('Training registration deleted.');
redirect_task4();
}
}
class AdminController
{
public function requireAdmin()
{
$user = logged_in_user();
if (!$user || $user['role'] !== 'admin') {
throw new RuntimeException('Administrator login required.');
}
}
}
//////////////////////////// task4_views.php ////////////////////////////
= e($flash['message']) ?>
Task 4 · SkillSpring Training Services
Develop people. Strengthen organisations.
Companies can create an account, register employees for professional training and manage their complete training cost from one portal.
Log in
Register organisation
Account login
Marker credentials are available in users.txt.
Upcoming training
Training catalogue
= e($training['title']) ?>
= e($training['description']) ?>
= e(date('d M Y', strtotime($training['training_date']))) ?>
= e($training['venue']) ?>
R= e(number_format($training['cost'], 2)) ?>
Organisation dashboard
= e($user['organisation_name']) ?>
Register employees independently, review the training summary and update or remove registrations below.
Employees enrolled= e($summary['employee_count']) ?>
Training registrations= e($summary['registration_count']) ?>
Current costR= e(number_format($summary['total_cost'], 2)) ?>
Employee training summary
No training registrations have been added yet.
| Employee | Training | Date / venue | Cost | Modify | Delete |
= e($registration['first_name'] . ' ' . $registration['last_name']) ?> = e($registration['employee_number']) ?> = e($registration['email']) ?> |
= e($registration['title']) ?> = e($registration['status']) ?> |
= e(date('d M Y', strtotime($registration['training_date']))) ?> = e($registration['venue']) ?> |
R= e(number_format($registration['cost'], 2)) ?> |
|
|
Administrator dashboard
Overall training registration
Use either filter independently or combine them to inspect registrations for a chosen training and organisation.
Organisations= e($overview['organisations']) ?>
Employees= e($overview['employees']) ?>
Registrations= e($overview['registrations']) ?>
Active registration valueR= e(number_format($overview['revenue'], 2)) ?>
Administrative report filters
Registration report
No registrations match these filters.
| Participant | Organisation | Training | Date | Status | Cost |
= e($row['participant']) ?> = e($row['employee_number']) ?> = e($row['email']) ?> |
= e($row['organisation']) ?> |
= e($row['training']) ?> |
= e(date('d M Y', strtotime($row['training_date']))) ?> |
= e($row['status']) ?> |
R= e(number_format($row['cost'], 2)) ?> |
Database design
Task 4 entity relationship diagram
controller -> model -> view
*/
session_start();
require_once 'common.php';
require_once 'database.php';
require_once 'task4_models.php';
require_once 'task4_controllers.php';
require_once 'task4_views.php';
$pdo = null;
$fatalError = '';
try {
$pdo = database();
$authModel = new AuthModel($pdo);
$trainingModel = new TrainingModel($pdo);
$organisationModel = new OrganisationModel($pdo);
$adminModel = new AdminModel($pdo);
$authController = new AuthController($authModel);
$organisationController = new OrganisationController($organisationModel, $trainingModel);
$adminController = new AdminController();
$action = $_GET['action'] ?? '';
if ($action !== '') {
try {
switch ($action) {
case 'login':
$authController->login();
break;
case 'logout':
$authController->logout();
break;
case 'register':
$authController->register();
break;
case 'create_registration':
$organisationController->createRegistration();
break;
case 'update_registration':
$organisationController->updateRegistration();
break;
case 'delete_registration':
$organisationController->deleteRegistration();
break;
default:
throw new RuntimeException('Unknown application action.');
}
} catch (Throwable $error) {
flash_message(safe_error_message($error), 'error');
redirect_task4();
}
}
} catch (Throwable $error) {
$fatalError = $error->getMessage();
}
render_page_start('Task 4 · Employee Training Portal');
include 'menu.inc';
?>
Task 4
Database connection required
= e($fatalError) ?>
Enter the Eduquest MySQL details in config.php. The MVC database tables and three or more seed rows per table will then be created automatically.
all()); ?>
registrations($user['organisation_id']);
$summary = $organisationModel->summary($user['organisation_id']);
render_organisation_dashboard($user, $trainingModel->all(), $registrations, $summary);
render_task4_logout();
?>
requireAdmin();
$trainingId = filter_input(INPUT_GET, 'training_id', FILTER_VALIDATE_INT) ?: 0;
$organisationId = filter_input(INPUT_GET, 'organisation_id', FILTER_VALIDATE_INT) ?: 0;
render_admin_dashboard(
$adminModel->overview(),
$trainingModel->all(),
$adminModel->organisations(),
$adminModel->report($trainingId, $organisationId),
$trainingId,
$organisationId
);
render_task4_logout();
?>