# **Chapter 11: Putting It All Together - Complete Example** > **File Extension Reference:** > - Gate Files: `*.gate.php` (e.g., `Index.gate.php`) > - Front Files: `*.front` (e.g., `index_main.front`) > - Master Files: `*.mast.php` (e.g., `default/master.mast.php`) > - Front Places: `*.place.front` or `*.place.php` --- ## **11.1 The Complete Project** In this chapter, we'll build a complete **Task Manager** application that demonstrates: - Gate registration and URL mapping - Lifecycle events (onstart, onready, onrender) - Page Events (list, create, edit, view, delete) - FrontFile Events (onfrontinit) - Two Front Files pattern (list + edit) - Master File with navigation - Holders and Code Blocks ## **11.2 Project Structure** ``` myproject/ ├── reg.php # Gate registration ├── comp.php # Configuration ├── start.php # Entry point │ ├── apps/ │ ├── Task.gate.php # Main Gate │ │ │ └── fronts/ │ ├── task_list.front # List view with pagination │ └── task_edit.front # Add/Edit form │ └── masters/ └── default/ ├── master.mast.php # Layout ├── menu.place.front # Navigation └── sphpcodeblock.php # Code blocks ``` ## **11.3 Step 1: Register the Gate** ```php <?php // reg.php registerGate("task", __DIR__ . "/apps/Task.gate.php"); ``` ## **11.4 Step 2: Create the Gate Class** ```php <?php // apps/Task.gate.php use Sphp\tools\BasicGate; class Task extends BasicGate { private $frtList; // List view with pagination private $frtEdit; // Add/Edit form public function onstart() { // Authentication - guests can view, members can edit $this->getAuthenticate("GUEST,MEMBER,ADMIN"); // Create FrontFile objects $this->frtList = new \Sphp\tools\FrontFile($this->mypath . "/fronts/task_list.front"); $this->frtEdit = new \Sphp\tools\FrontFile($this->mypath . "/fronts/task_edit.front"); } /** * FrontFile Event: Set metadata when loaded */ public function onfrontinit($frontobj) { $frontobj->addMetaData("title", "Task Manager"); } /** * Lifecycle Event: Prepare components */ public function onready() { // Pre-populate category options $sltCategory = $this->frtEdit->getComponent("sltPriority"); $sltCategory->setOptions("Low,Medium,High,Urgent"); } /** * Page Event: task.html - Show task list */ public function page_new() { // Pagination Component handles the list // Just set the FrontFile $this->setFrontFile($this->frtList); } /** * Page Event: task-create.html - Show empty form */ public function page_event_create($evtp) { // Clear form for new record $this->clearForm(); $this->frtEdit->addProp("formTitle", "Create New Task"); $this->frtEdit->addProp("isEditMode", false); $this->setFrontFile($this->frtEdit); } /** * Page Event: task-view-5.html - View task (read-only) */ public function page_view() { $taskId = (int)$this->page->evtp; $this->loadTaskToForm($taskId, false); $this->setFrontFile($this->frtEdit); } /** * Page Event: task-edit-5.html - Edit task */ public function page_event_edit($evtp) { $taskId = (int)$evtp; $this->loadTaskToForm($taskId, true); $this->setFrontFile($this->frtEdit); } /** * Page Event: task.html (POST) - Handle form submission */ public function page_submit() { // Check validation if (getCheckErr()) { $this->frtEdit->addProp("formTitle", "Please Fix Errors"); $this->setFrontFile($this->frtEdit); return; } // Get form component $form = $this->frtEdit->getComponent("taskForm"); // Check if insert or update if ($form->getRecID() == "") { // Insert new $this->page->insertData($form); } else { // Update existing $this->page->updateData($form); } // Redirect to list $this->page->forward(getGateURL("task")); } /** * Page Event: task-delete-5.html - Delete task */ public function page_event_delete($evtp) { $taskId = (int)$evtp; // Delete from database $this->dbEngine->executeQuery("DELETE FROM tasks WHERE id = $taskId"); // Redirect to list $this->page->forward(getGateURL("task")); } /** * Page Event: task-search-keyword.html - Search tasks */ public function page_event_search($evtp) { // Pass search to FrontFile holder $this->frtList->addProp("searchTerm", $evtp); // Could modify the Pagination Component's query here // For now, just show list $this->setFrontFile($this->frtList); } /** * Lifecycle Event: Add final touches */ public function onrender() { // Add page-specific CSS/JS if needed // addFileLink("task-styles.css"); } // ===== Helper Methods ===== private function clearForm() { $this->frtEdit->getComponent("txtId")->fi_setDefaultValue(""); $this->frtEdit->getComponent("txtTitle")->fi_setDefaultValue(""); $this->frtEdit->getComponent("txaDescription")->fi_setDefaultValue(""); $this->frtEdit->getComponent("sltPriority")->fi_setDefaultValue(""); } private function loadTaskToForm($taskId, $isEditMode) { $this->dbEngine->connect(); $result = $this->dbEngine->executeQuery( "SELECT * FROM tasks WHERE id = $taskId" ); $row = $this->dbEngine->row_fetch_assoc($result); $this->dbEngine->disconnect(); if (!$row) { $this->page->forward(getGateURL("task")); return; } // Populate form $this->frtEdit->getComponent("txtId")->fi_setDefaultValue($row['id']); $this->frtEdit->getComponent("txtTitle")->fi_setDefaultValue($row['title']); $this->frtEdit->getComponent("txaDescription")->fi_setDefaultValue($row['description']); $this->frtEdit->getComponent("sltPriority")->fi_setDefaultValue($row['priority']); // Set mode $this->frtEdit->addProp("formTitle", $isEditMode ? "Edit Task" : "View Task"); $this->frtEdit->addProp("isEditMode", $isEditMode); } } ``` ## **11.5 Step 3: Create List Front File** ```html <!-- apps/fronts/task_list.front --> <title id="pageTitle" runat="server">My Tasks</title> <div class="container-fluid"> <div class="row mb-4"> <div class="col"> <h1>Task Manager</h1> </div> <div class="col-auto"> <a href="task-create.html" class="btn btn-primary"> + New Task </a> </div> </div> <!-- Search Form --> <form action="task-search-.html" method="GET" class="mb-4"> <div class="input-group"> <input type="text" name="search" class="form-control" placeholder="Search tasks..."> <button type="submit" class="btn btn-outline-secondary"> Search </button> </div> </form> <!-- Task List with Pagination --> <div id="taskGrid" runat="server" path="uikit/data/Pagination.php" dtable="tasks" fun-setFieldNames="title,priority,status,due_date" fun-setPerPageRows="5" fun-setAJAX="" on-init="true"> <!-- Template for each row --> <div class="card mb-2"> <div class="card-body"> <div class="row align-items-center"> <div class="col-md-4"> <strong>##{$taskGrid->getRow('title')}#</strong> </div> <div class="col-md-2"> <span class="badge bg-##{$taskGrid->getRow('priority') === 'High' ? 'danger' : 'secondary'}#"> ##{$taskGrid->getRow('priority')}# </span> </div> <div class="col-md-2"> ##{$taskGrid->getRow('status')}# </div> <div class="col-md-2"> ##{$taskGrid->getRow('due_date')}# </div> <div class="col-md-2"> <a href="task-view-##{$taskGrid->getRow('id')}#.html" class="btn btn-sm btn-info">View</a> <a href="task-edit-##{$taskGrid->getRow('id')}#.html" class="btn btn-sm btn-warning">Edit</a> </div> </div> </div> </div> </div> <!-- Pagination Links --> <div runas="holder" sphp-comp="taskGrid" sphp-comp-prop="page_links"></div> </div> ``` ## **11.6 Step 4: Create Edit Front File** ```html <!-- apps/fronts/task_edit.front --> <title id="pageTitle" runat="server">Task Form</title> <div class="container"> <div class="row"> <div class="col-md-8 mx-auto"> <div class="card"> <div class="card-header"> <h3>##{$formTitle}#</h3> </div> <div class="card-body"> <!-- Task Form --> <form id="taskForm" runat="server" action="task.html" method="POST"> <!-- Hidden ID field --> <input id="txtId" runat="server" type="hidden" dtable="tasks" dfield="id"> <!-- Title --> <div class="mb-3"> <label class="form-label">Task Title *</label> <input id="txtTitle" runat="server" type="text" class="form-control" dtable="tasks" dfield="title" fui-setRequired="" fui-setMinLen="3" fui-setMaxLen="100" fui-setForm="taskForm"> </div> <!-- Description --> <div class="mb-3"> <label class="form-label">Description</label> <textarea id="txaDescription" runat="server" class="form-control" rows="4" dtable="tasks" dfield="description" fui-setForm="taskForm"></textarea> </div> <!-- Priority --> <div class="mb-3"> <label class="form-label">Priority</label> <select id="sltPriority" runat="server" class="form-select" dtable="tasks" dfield="priority" fui-setForm="taskForm"> <option value="">Select Priority</option> </select> </div> <!-- Status --> <div class="mb-3"> <label class="form-label">Status</label> <select id="sltStatus" runat="server" class="form-select" dtable="tasks" dfield="status" fui-setForm="taskForm"> <option value="Pending">Pending</option> <option value="In Progress">In Progress</option> <option value="Completed">Completed</option> </select> </div> <!-- Due Date --> <div class="mb-3"> <label class="form-label">Due Date</label> <input id="datDueDate" runat="server" type="date" class="form-control" dtable="tasks" dfield="due_date" fui-setForm="taskForm"> </div> <!-- Error Display --> <alert id="formErrors" runat="server" fun-setShowAll=""></alert> <!-- Buttons --> <div class="d-flex justify-content-between"> <a href="task.html" class="btn btn-secondary">Cancel</a> #{if $isEditMode}# <div> <button type="submit" class="btn btn-primary">Update</button> <a href="task-delete-##{$txtId->getValue()}#.html" class="btn btn-danger" onclick="return confirm('Delete this task?')">Delete</a> </div> #{else}# <button type="submit" class="btn btn-success">Create Task</button> #{endif}# </div> </form> </div> </div> </div> </div> </div> ``` ## **11.7 Step 5: Create Master File** ```php <?php // masters/default/master.mast.php addFrontPlace("menu", __DIR__ . "/menu.place.front", "main"); runFrontPlace("menu", "main"); ?><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <?php SphpBase::SphpJsM()::addBootStrap(); echo SphpBase::sphp_api()->getHeaderHTML(); ?> <title>Task Manager</title> </head> <body> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div class="container-fluid"> <a class="navbar-brand" href="index.html">MyApp</a> <?php renderFrontPlace("menu", "main"); ?> </div> </nav> <main class="container my-4"> <?php SphpBase::getAppOutput(); ?> </main> <footer class="bg-light text-center py-3 mt-4"> <small>&copy; 2024 Task Manager</small> </footer> <?php echo SphpBase::sphp_api()->getFooterHTML(); ?> </body> </html> ``` ## **11.8 Step 6: Create Menu Front Place** ```html <!-- masters/default/menu.place.front --> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav me-auto"> <li class="nav-item"> <a class="nav-link" href="index.html">Home</a> </li> <li class="nav-item"> <a class="nav-link" href="task.html">Tasks</a> </li> </ul> </div> ``` ## **11.9 Step 7: Create Code Blocks (Optional Enhancement)** ```php <?php // masters/default/sphpcodeblock.php SphpCodeBlock::addCodeBlock('card', function($element, $args) { $element->wrapTag('<div class="card"></div>'); $element->wrapInnerTags('<div class="card-body"></div>'); if (!empty($args[0])) { $element->setPreTag('<div class="card-header">' . $args[0] . '</div>'); } }); ``` ## **11.10 URL Mapping Summary** | URL | Gate | Event | Parameter | Result | |-----|------|-------|------------|--------| | `task.html` | task | new | - | Show list with pagination | | `task.html` (POST) | task | submit | - | Save form (insert/update) | | `task-create.html` | task | create | - | Show empty form | | `task-view-5.html` | task | view | 5 | Show task (read-only) | | `task-edit-5.html` | task | edit | 5 | Show populated form | | `task-delete-5.html` | task | delete | 5 | Delete task | | `task-search-work.html` | task | search | work | Search results | ## **11.11 Complete Flow Summary** 1. **Browser requests** `task.html` 2. **Framework** finds "task" in reg.php, loads Task.gate.php 3. **onstart()** creates FrontFile objects, checks authentication 4. **onfrontinit()** sets metadata 5. **onready()** prepares components (sets dropdown options) 6. **page_new()** sets FrontFile, renders with Master File 7. **Pagination Component** displays tasks from database 8. **onrender()** adds final touches 9. **Browser receives** complete HTML page ## **11.12 Chapter Summary** This chapter demonstrated the complete development flow: 1. **Registration** - `registerGate()` in reg.php 2. **Gate Class** - Extends BasicGate, handles events 3. **Lifecycle Events** - onstart, onready, onrender 4. **Page Events** - page_new, page_submit, page_event_* 5. **Two Front Files** - List view + Edit form 6. **Master File** - Layout with menu 7. **Front Place** - Reusable navigation ## **What You've Learned** - How URL maps to Gate + Event - Gate lifecycle events and when to use each - Page events for different request types - FrontFile events for template interaction - Building pages with FrontFiles and Master Files - Two Front Files pattern for list/edit - Holders and Code Blocks for design enhancement **You are now ready to build web applications with SartajPhp!** --- **End of Book**