# **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>© 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**