1. Go to this page and download the library: Download pagemill/mvc library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
pagemill / mvc example snippets
namespace MyApp;
use PageMill\MVC\ControllerAbstract;
class HomeController extends ControllerAbstract {
protected function getRequestActions(): array {
return []; // No actions needed for this simple example
}
protected function getDataActions(): array {
return []; // No data actions needed
}
protected function buildModels(): array {
// Return data to be passed to the view
return [
'title' => 'Welcome to PageMill MVC',
'message' => 'Hello, World!'
];
}
}
namespace MyApp;
use PageMill\MVC\Template\HTMLAbstract;
class HomeView extends HTMLAbstract {
public string $title = '';
public string $message = '';
protected function prepareDocument(): void {
$this->document->title = $this->title;
}
protected function generateHeader(): void {
echo '<!DOCTYPE html><html><head>';
echo $this->document->generateHead();
echo '</head><body>';
}
protected function generateBody(): void {
echo '<h1>' . htmlspecialchars($this->title) . '</h1>';
echo '<p>' . htmlspecialchars($this->message) . '</p>';
}
protected function generateFooter(): void {
echo '</body></html>';
}
}
namespace MyApp;
use PageMill\MVC\ResponderAbstract;
class HomeResponder extends ResponderAbstract {
protected function getView(string $content_type): string {
return HomeView::class;
}
}
PageMill\HTTP\Request;
use PageMill\HTTP\Response;
use MyApp\HomeController;
use MyApp\HomeResponder;
$request = new Request();
$response = new Response();
$controller = new HomeController('/', [], $request);
[$data, $inputs] = $controller->handleRequest();
$responder = new HomeResponder($response);
$responder->respond($data, $inputs);
class ProductController extends ControllerAbstract {
// Filters clean/validate input
protected function getFilters(): array {
return [
'id' => ['type' => 'int', 'min' => 1]
];
}
// Request actions run first (validation)
protected function getRequestActions(): array {
return [
new ValidateProductExists()
];
}
// Data actions transform data
protected function getDataActions(): array {
return [
new LoadProductReviews()
];
}
// Models provide data
protected function buildModels(): array {
return [
new ProductModel($this->inputs['id']),
new CategoryModel()
];
}
}
class ValidateProductExists extends ActionAbstract {
public int $id = 0;
protected function doAction(array $data): mixed {
$product = Product::findById($this->id);
if (!$product) {
$this->errors[] = 'Product not found';
return null;
}
return ['product' => $product];
}
}
class ProductModel extends ModelAbstract {
public int $id = 0;
protected function getData(): array {
return [
'product' => $this->loadProductFromDatabase($this->id),
'related' => $this->loadRelatedProducts($this->id)
];
}
}
use PageMill\MVC\HTML\Assets\Combine;
$combine = new Combine($assets, $request, $response);
$combine->combine('css'); // Combines all requested CSS files
class ButtonElement extends ElementAbstract {
public static function getAssets(?string $class = null): array {
return [
'css' => ['button'],
'js' => ['button-handler']
];
}
}
// In your view:
$this->element_assets->add([ButtonElement::class]);
// Automatically loads button.css and button-handler.js
protected function prepareDocument(): void {
// Page title
$this->document->title = 'My Page Title';
// Canonical URL
$this->document->canonical = 'https://example.com/page';
// Robots directives
$this->document->robots_index = false; // noindex
$this->document->robots_follow = true; // follow
$this->document->robots_archive = false; // noarchive
// Meta tags
$this->document->addMeta([
'name' => 'description',
'content' => 'Page description'
]);
$this->document->addMeta([
'property' => 'og:title',
'content' => 'My Page Title'
]);
// Custom variables for templates
$this->document->custom_var = 'Some value';
}
// In generateHeader():
echo $this->document->generateHead();
// Outputs: <title>, <meta>, <link rel="canonical">, etc.
// HTTP headers are sent automatically:
$this->document->generateHeaders();
// Sends: X-Robots-Tag, Link rel=canonical, etc.
class AlertElement extends ElementAbstract {
public string $message = '';
public string $type = 'info';
public static function getAssets(?string $class = null): array {
return [
'css' => ['alert'],
'js' => ['alert-dismiss']
];
}
public function generateElement(): void {
echo '<div class="alert alert-' . htmlspecialchars($this->type) . '">';
echo htmlspecialchars($this->message);
echo '<button class="close">×</button>';
echo '</div>';
}
}
// Usage:
$alert = new AlertElement(['message' => 'Success!', 'type' => 'success']);
$alert->generateElement();
// Auto-load element assets:
$this->element_assets->add([AlertElement::class]);
use PageMill\MVC\Environment;
// Enable debug mode
Environment::debug(true);
// Check debug state
if (Environment::debug()) {
// Show detailed errors
}
// Disable debug mode
Environment::debug(false);
use PageMill\MVC\Traits\PropertyMap;
class MyClass {
use PropertyMap;
public string $name = '';
public int $age = 0;
// Optional: Define type constraints
protected static array $constraints = [
'email' => ['type' => 'string'],
'created_at' => ['type' => \DateTime::class]
];
public function __construct(array $data) {
// Maps array keys to properties with type checking
$this->mapProperties($data);
// Ignore unknown properties
$this->mapProperties($data, ignore: true);
}
}