# Teacher Module: Complete Migration Process (CI3 → CI4, PHP 7.4 → 8.5)

## 1. Overview

This document describes the **complete migration process** for the **Teacher module** from:

- **CodeIgniter 3 (CI3)** → **CodeIgniter 4 (CI4)**
- **PHP 7.4** → **PHP 8.5**

**Scope of the Teacher module:**

| Area | Description |
|------|-------------|
| **TP Teacher auth** | Teacher login, logout, forgot password, new password (`tp/te/*`) |
| **TP Unified role (Ur)** | School/class selection, dashboard, dashboard JSON feeds, view events (shared teacher + parent) |
| **TP Rosters** | Check In / Check Out, student list, notes, in/out/absent, daily activity |
| **TP Quests** | Lesson planning: create lesson, planned lesson, status, cancel, confirmation |
| **TP Teacher Message** | Teacher messaging: student list, send/view messages, admin report |
| **TP Internal Message** | Inbox, compose, sent, reply, forward (teacher + parent) |
| **TP Reports** | Daily reports (teacher/parent) |
| **TP Incoming** | Incoming items (teacher/parent) |
| **Admin Teachers** | Admin CRUD: teacher list (Super Admin / Franchisee), add/edit, reset password, teacher classroom, delete |

**Source (CI3):** Controllers under `application/controllers/` (tp/te.php, tp/ur.php, tp/rosters.php, tp/quests.php, tp/teacherMessage.php, tp/internalMessage.php, tp/reports.php, tp/incoming.php) and `application/controllers/admin/teachers.php`; models under `application/models/`; views under `application/views/tp/` and `application/views/admin/`.

**Target (CI4):** `app/Controllers/Tp\*`, `app/Controllers/Admin/Teachers.php`; `app/Models\*`; `app/Views/tp/`, `app/Views/admin/`; routes in `app/Config/Routes.php`.

---

## 2. Files Migrated (Teacher Module)

### 2.1 Controllers

| CI3 (conceptual) | CI4 | Description |
|------------------|-----|-------------|
| tp/te.php | `App\Controllers\Tp\Te` | Teacher login, logout, forgotPassword, newPassword |
| tp/ur.php | `App\Controllers\Tp\Ur` | index, chooseSchool, getClass, signin_out, dashboard, changePassword, changeProfile; all dashboard JSON endpoints; viewEvents |
| tp/rosters.php | `App\Controllers\Tp\Rosters` | index (roster AJAX), addNotes, getStudentDetails, addInOutAbs, addStudentDailyActivity |
| tp/quests.php | `App\Controllers\Tp\Quests` | createLesson, plannedLesson, lessonPlannedStatus, ajaxPlannedLesson, cancelLessonPlan, confirmation, getMaterialsByArea, getConceptsByAreaMaterial, ajaxCreateLesson |
| tp/teacherMessage.php | `App\Controllers\Tp\TeacherMessage` | index, getStudentlist, sendMessage, viewData, deleteTeacherMessage, teacherAdminReport, ajaxTeacheradminReport, webcam |
| tp/internalMessage.php | `App\Controllers\Tp\InternalMessage` | index, compose, sent_items, description, reply, forward, delete_inbox_items, delete_sent_items |
| tp/reports.php | `App\Controllers\Tp\Reports` | index, getStudentReports, addComments, addAttachments, onClickItem, getdata, checkSubmitButtonStatus |
| tp/incoming.php | `App\Controllers\Tp\Incoming` | index |
| admin/teachers.php | `App\Controllers\Admin\Teachers` | index, addEdit, teacherClassRoom, ajaxGetTeacherClass, ajaxTeachersSuperAdminListing, ajaxTeachersFranchiseeListing, deleteTeacher |

### 2.2 Models (teacher-related)

| CI3 | CI4 | Purpose |
|-----|-----|---------|
| teacher | TeacherModel | teachers table; loginRules(), changePasswordRules() |
| securities | SecuritiesModel | authenticateLogin(), getLoginUserDetail('tp'), sessionExistRedirect(), teLogout(), allowedRoles() |
| utility | UtilityModel | fronEndChooseSchool(), setUserTimeZone(), getRowsByField(), GmDateTime(), forgotPasswordRules(), authenticateForgotPassword(), updatePasswordResetToken(), updatePassword(), insert_user_login_detail(), update_user_login_detail() |
| quest | QuestModel | Lesson plan / assignments |
| teacher_message | TeacherMessageModel | Teacher messaging |
| internal_message | InternalMessageModel | Internal messages |

### 2.3 Views (teacher / TP shared)

| View | Description |
|------|-------------|
| tp/teLogin.php | Teacher login form |
| tp/forgotPassword.php | Forgot password (formAction = te/pa) |
| tp/newPassword.php | New password from token |
| tp/urChoose.php | Role selection (teacher/parent) |
| tp/urChooseSchool.php | School/class selection |
| tp/urDashboard.php | Dashboard wrapper |
| tp/urRoster.php, tp/urRosternew.php | Roster page (check in/out) |
| tp/urReport.php | Reports page |
| tp/urIncoming.php | Incoming page |
| tp/changePassword.php, tp/changePasswordNew.php | Change password/profile |
| tp/viewEvent.php | Event detail modal |
| tp/questCreateLesson.php, tp/questPlannedLesson.php, tp/questLessonPlanStatus.php, tp/questAjaxCreateLesson.php, tp/ajaxQuestPlannedLesson.php, tp/ajaxQuestPlannedLessonStatus.php | Quest (lesson plan) |
| tp/teachermessage/index.php, sendmessage.php, studentAjaxList.php, webcam.php | Teacher message |
| tp/internalmessage/inbox.php, compose.php, sent_items.php | Internal message |
| tp/include/headScripts.php, header.php, sidebar.php, sub_header_msg.php | TP layout |
| tp/popup/addNotes.php, studentInfo.php, addComments.php, addAttachments.php, confirmation.php | Popups |
| admin/teacherSuperAdminList.php, admin/teacherFranchiseeList.php | Admin teacher lists |
| admin/teachersAddEdit.php (and related) | Admin add/edit teacher |

### 2.4 Routes (teacher-related)

All under the `tp` group (`app/Config/Routes.php`), namespace `App\Controllers\Tp`:

- **te:** `te/login` (GET/POST), `te/logout`, `te/forgotPassword` (GET/POST), `te/newPassword/(:segment)` (GET/POST)
- **ur:** `ur`, `ur/chooseSchool`, `ur/getClass/(:num)`, `ur/signin_out` (GET/POST), `ur/dashboard` (GET/POST), `ur/changePassword`, `ur/changeProfile`, plus all dashboard JSON and `ur/viewEvents`
- **rosters:** `rosters/index` (POST), `rosters/addNotes/(:num)` etc.
- **quests:** `quests/createLesson`, `quests/plannedLesson`, `quests/ajaxPlannedLesson`, etc.
- **teacherMessage:** `teacherMessage/index`, `teacherMessage/getStudentlist`, etc.
- **internalMessage:** `internalMessage/index`, `internalMessage/compose`, etc.
- **reports:** (under tp group)
- **incoming:** `incoming`, `incoming/index`

Admin group:

- `teachers/index`, `teachers`, `teachers/addEdit`, `teachers/addEdit/(:segment)`, `teachers/teacherClassRoom`, `teachers/ajaxGetTeacherClass`, `teachers/ajaxTeachersSuperAdminListing`, `teachers/ajaxTeachersFranchiseeListing`, `teachers/deleteTeacher`

---

## 3. CI3 → CI4 Migration Process (Step-by-Step)

### 3.1 Project layout

| CI3 | CI4 |
|-----|-----|
| application/controllers/ | app/Controllers/ |
| application/models/ | app/Models/ |
| application/views/ | app/Views/ |
| application/config/ | app/Config/ |
| index.php at project root | public/index.php (optional) |

### 3.2 Controllers

1. **Namespace and base class**
   - Add `namespace App\Controllers\Tp;` (or `App\Controllers\Admin` for Teachers).
   - Extend `BaseController` (or `AdminController` for admin).
   - Use `declare(strict_types=1);` where applicable.

2. **Model loading**
   - **CI3:** `$this->load->model('securities');` then `$this->securities->method()`.
   - **CI4:** In constructor: `$this->securitiesModel = model(SecuritiesModel::class);` (or inject). Use `model(ClassName::class)`; no `load->model`.

3. **Request**
   - **CI3:** `$this->input->post('key')`, `$this->input->get()`, `$this->uri->segment(4)`.
   - **CI4:** `$this->request->getPost('key')`, `$this->request->getGet()`, `$this->request->getUri()->getSegment(4)` or method parameter e.g. `newPassword(string $tokenSegment)`.

4. **Response**
   - **CI3:** `redirect(base_url().'tp/te/login');`, `echo json_encode($arr);`.
   - **CI4:** `return redirect()->to(base_url('tp/te/login'));`, `return $this->response->setJSON($arr);`, `return $this->response->setBody($html)->setHeader('Content-Type','text/html');`.

5. **Session**
   - **CI3:** `$this->session->set_userdata('teacher_user_id', $id);`, `$this->session->flashdata('login_fail');`, `$this->session->sess_destroy();`.
   - **CI4:** `session()->set('teacher_user_id', $id);`, `session()->getFlashdata('login_fail');`, `session()->setFlashdata('login_fail', 'msg');`, `session()->remove('teacher_user_id');`, `session()->destroy();`.

6. **Views**
   - **CI3:** `$this->load->view('tp/teLogin', $this->data);`.
   - **CI4:** `return view('tp/teLogin', $this->data);` or `return $this->layoutView('admin/teacherSuperAdminList');` for admin layout.

7. **Validation**
   - **CI3:** `$this->form_validation->set_rules(...);`, `$this->form_validation->run()`.
   - **CI4:** `$this->validate($rules)` with rules array (e.g. from `TeacherModel::loginRules()`); errors: `$this->validator->getErrors()`.

8. **Config / helpers**
   - **CI3:** `$this->config->item('base_url')`, global helpers.
   - **CI4:** `base_url()`, helpers loaded in BaseController (e.g. `form`, `url`) or in `Config\App`.

### 3.3 Models

1. **Namespace and base**
   - `namespace App\Models;`, extend `CodeIgniter\Model` or project `BaseModel`.
   - **CI3:** `$this->db->get()`, `$query->result()`, `$query->row()`.
   - **CI4:** Use Query Builder: `$this->db->table('teachers')->where(...)->get()->getResult()` / `getRow()`; or `Database::connect()->table(...)` in controllers when needed.

2. **Constants**
   - **CI3:** `TEACHER_ROLE_ID` from constants.php.
   - **CI4:** `Config\CmmConstants::TEACHER_ROLE_ID`.

3. **Return types**
   - Prefer typed returns for new/refactored methods, e.g. `: array`, `: ?object`, for PHP 8.x.

### 3.4 Views

1. **Loading**
   - **CI3:** `$this->load->view('tp/teLogin', $data);` (from controller).
   - **CI4:** Controller uses `return view('tp/teLogin', $this->data);`; in views sub-views: `<?= view('tp/include/headScripts'); ?>`.

2. **Flash and old input**
   - **CI3:** `$this->session->flashdata('login_fail')`, `set_value('username')`.
   - **CI4:** `session()->getFlashdata('login_fail')`, `old('username')`.

3. **Validation errors**
   - **CI3:** `form_error('username')`.
   - **CI4:** Pass `$errors` from controller (`$this->validator->getErrors()`) and use `<?php if (!empty($errors['username'])) : ?><?= esc($errors['username']); ?><?php endif; ?>`.

4. **URLs and escaping**
   - **CI3:** `base_url().'tp/te/login'`, often unescaped in attributes.
   - **CI4:** `base_url('tp/te/login')`, use `esc()` in HTML attributes and user-derived output: `<?= esc(base_url('tp/te/login')); ?>`.

5. **CSRF**
   - **CI4:** Add `<?= csrf_field() ?>` in forms; CSRF filter enabled in Config.

### 3.5 Routing

- **CI3:** Convention: `controller/method/segment3/segment4`.
- **CI4:** Explicit routes in `app/Config/Routes.php`. Use groups:
  - `$routes->group('tp', ['namespace' => 'App\Controllers\Tp'], function ($routes) { ... });`
  - Define each verb: `$routes->get('te/login', 'Te::login');`, `$routes->post('te/login', 'Te::login');`
  - Placeholder: `(:segment)`, `(:num)` for parameters; pass to method: `Te::newPassword/$1`.

### 3.6 Security / auth (teacher)

- **Session check:** Use `SecuritiesModel::sessionExistRedirect('tp')`; if not null, return that redirect (e.g. to dashboard or login).
- **Role check:** Use `SecuritiesModel::allowedRoles('tp', ['UserTypes' => [CmmConstants::TEACHER_ROLE_ID]])`; if not `true`, return the redirect or 403 response.
- **Teacher session keys:** `teacher_user_id`, `teacher_time_zone`; clear on logout via `teLogout()` plus removal of `tp_*` and optional `session()->destroy()`.
- **Logout:** Call `$this->securitiesModel->teLogout();` then remove tp session vars and optionally `session()->destroy()`, then `redirect()->to(base_url('tp/te/login'))`.

### 3.7 Pattern reference (quick table)

| CI3 | CI4 |
|-----|-----|
| `$this->load->model('securities')` | `model(SecuritiesModel::class)` in constructor |
| `$this->load->view('x', $data)` | `return view('x', $data)` |
| `$this->input->post('x')` | `$this->request->getPost('x')` |
| `$this->config->item('base_url')` | `base_url()` |
| `$this->session->set_userdata('k','v')` | `session()->set('k','v')` |
| `$this->session->flashdata('k')` | `session()->getFlashdata('k')` |
| `$this->session->set_flashdata('k','v')` | `session()->setFlashdata('k','v')` |
| `redirect(base_url().'path')` | `return redirect()->to(base_url('path'))` |
| `$this->form_validation->run()` | `$this->validate($rules)` |
| `form_error('field')` | Pass `$errors` and use in view |
| `set_value('field')` | `old('field')` |
| TEACHER_ROLE_ID (constant) | `CmmConstants::TEACHER_ROLE_ID` |
| `$this->securities->session_exist_redirect('tp')` | `$this->securitiesModel->sessionExistRedirect('tp')` (returns RedirectResponse or null) |
| `$this->securities->AllowedRoles(...)` | `$this->securitiesModel->allowedRoles(...)` (returns true or RedirectResponse) |

---

## 4. PHP 7.4 → 8.5 Migration (Teacher Module)

### 4.1 Compatibility baseline

- **Composer:** Set `"php": "^8.1"` or `"php": ">=8.1"` in `composer.json` (8.5 is backward compatible with 8.1 for typical code). Optionally `config.platform.php: "8.5"` for lockfile.
- **CI4:** Use a CI4 version that supports PHP 8.1+ (and 8.5 when released); check release notes.

### 4.2 Deprecations and removals (PHP 8.x)

- **Nullable and type declarations:** Prefer method signatures with types; use `?Type` for nullable. CI4 and models already use mixed/array/object where appropriate.
- **Implicit nullable:** PHP 8.4+ deprecates implicit nullable (e.g. `function f(string $x = null)`). Use `?string $x = null` or `string $x = null` only where PHP allows.
- **Dynamic properties:** PHP 8.2+ deprecates/restricts undefined object properties. Controllers use `$this->data` array; models use `$allowedFields`, `$table`, etc. Avoid setting arbitrary `$this->newProp` on controllers/models; use `$this->data['key']` or declared properties.
- **Curly brace for string offset:** `$str{0}` removed in 8.0; use `$str[0]`.
- **Required parameter after optional:** Not allowed in 8.0+. Ensure no method has optional parameter followed by required one.

### 4.3 Practices for PHP 8.5 (and 8.x)

- **Typed properties:** Use in new code where it helps (e.g. `protected SecuritiesModel $securitiesModel;`). Existing `protected $data = [];` can stay as-is or be typed `protected array $data = [];`.
- **Constructor property promotion:** Optional for new constructors, e.g. `public function __construct(protected SecuritiesModel $securitiesModel) {}`.
- **Match expression:** Can replace some switch blocks for cleaner code.
- **Nullsafe operator:** Use `$obj?->prop` where the object may be null to avoid notices.
- **Named arguments:** Use where it improves readability when calling CI4 or project APIs.
- **Strict types:** Add `declare(strict_types=1);` at top of new/modified controller and model files to avoid accidental type coercion (already used in Admin\Teachers, TeacherModel, TeacherMessage, etc.).

### 4.4 Teacher-module-specific checks

- **Session keys:** Ensure all session keys used for teacher (e.g. `teacher_user_id`, `teacher_time_zone`, `tp_school_id`, `tp_program_class_type_id`) are set/removed consistently; no reliance on undefined indexes. Use null coalescing in reads: `session()->get('teacher_user_id') ?? 0`.
- **Request getPost/getGet:** CI4 returns `null` for missing keys; avoid passing null to functions expecting string. Use `(string) ($this->request->getPost('key') ?? '')` or validate first.
- **Validation rules:** CI4 validation rule names and behavior match CI3 conceptually; ensure rule arrays use string keys and valid rule names for PHP 8.
- **JSON responses:** Use `$this->response->setJSON($data)`; ensure $data is serializable (no resources or illegal types) for PHP 8.

### 4.5 Testing on PHP 8.5

- Run unit/integration tests (if any) under PHP 8.5.
- Manually test: teacher login, logout, forgot/new password, dashboard, roster, quests, teacher message, internal message, reports; admin teachers list and add/edit (including reset password).
- Check error logs and deprecation notices (e.g. `display_errors` and log level in env).

---

## 5. Checklist Summary

### CI3 → CI4

- [ ] All teacher-related controllers namespaced under `App\Controllers\Tp` (or `Admin`); extend BaseController/AdminController.
- [ ] Models loaded with `model(ClassName::class)`; no `load->model`.
- [ ] Request: `getPost()`, `getUri()->getSegment()` or method params.
- [ ] Session: `session()->set/get/remove/setFlashdata/getFlashdata/destroy`.
- [ ] Redirect: `return redirect()->to(base_url('...'));`.
- [ ] Views: `return view('...', $data)`; sub-views with `view('...')`; `old()`, `esc()`, CSRF in forms.
- [ ] Validation: `$this->validate($rules)`; errors passed to views.
- [ ] Routes: all `tp/te/*`, `tp/ur/*`, `tp/rosters/*`, `tp/quests/*`, `tp/teacherMessage/*`, `tp/internalMessage/*`, `tp/reports/*`, `tp/incoming/*`, and admin `teachers/*` defined in Routes.php.
- [ ] Auth: `sessionExistRedirect('tp')`, `allowedRoles('tp', ['UserTypes' => [TEACHER_ROLE_ID]])`, `teLogout()` used correctly.
- [ ] Config/constants: `base_url()`, `CmmConstants::TEACHER_ROLE_ID`.

### PHP 7.4 → 8.5

- [ ] `composer.json` PHP requirement `^8.1` or equivalent; CI4 version supports PHP 8.x.
- [ ] No dynamic properties on controllers/models; use `$this->data` or declared properties.
- [ ] No implicit nullable in new method signatures; use `?Type` where needed.
- [ ] No required parameter after optional; no `$str{0}`.
- [ ] Optional: add `declare(strict_types=1);` and typed properties in new/refactored files.
- [ ] Manual and automated tests run on PHP 8.5 (or target 8.x).

---

## 6. References

- **Project:** `MIGRATION.md` (project-wide CI3→CI4 summary), `docs/UPGRADATION.md` (routes/controllers/views counts), `migration_report.md` (example: Admin Students migration).
- **CI4:** [CodeIgniter 4 User Guide](https://codeigniter.com/user_guide/) (controllers, models, views, routing, validation, security).
- **PHP:** [PHP 8.x migration guides](https://www.php.net/manual/en/appendices.php) and release notes for 8.0–8.4 (8.5 when available).
