Examples
Practical code examples for building with WPZylos Scaffold.
Basic Controller
<?php
// app/Http/Controllers/DashboardController.php
namespace MyPlugin\Http\Controllers;
use WPZylos\Framework\Views\ViewFactory;
use WPZylos\Framework\Core\Contracts\ContextInterface;
class DashboardController
{
public function __construct(
private ViewFactory $view,
private ContextInterface $context
) {}
public function index(): void
{
echo $this->view->render('admin/dashboard', [
'title' => __('Dashboard', $this->context->textDomain()),
'stats' => $this->getStats(),
]);
}
private function getStats(): array
{
return [
'total_items' => 150,
'active_items' => 42,
];
}
}
Service with Database
<?php
// app/Services/ItemService.php
namespace MyPlugin\Services;
use WPZylos\Framework\Database\Connection;
use WPZylos\Framework\Core\Contracts\ContextInterface;
class ItemService
{
private string $table;
public function __construct(
private Connection $db,
private ContextInterface $context
) {
$this->table = $context->tableName('items');
}
public function all(): array
{
return $this->db->getResults(
"SELECT * FROM {$this->table} ORDER BY created_at DESC"
);
}
public function find(int $id): ?object
{
return $this->db->getRow(
$this->db->prepare(
"SELECT * FROM {$this->table} WHERE id = %d",
$id
)
);
}
public function create(array $data): int
{
return $this->db->insert($this->table, $data);
}
public function update(int $id, array $data): int
{
return $this->db->update($this->table, $data, ['id' => $id]);
}
public function delete(int $id): int
{
return $this->db->delete($this->table, ['id' => $id]);
}
}
Migration
<?php
// database/migrations/2024_01_01_000000_create_items_table.php
use WPZylos\Framework\Migrations\Migration;
return new class extends Migration
{
public function up(): void
{
$table = $this->context->tableName('items');
$sql = "CREATE TABLE {$table} (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
description text,
status varchar(50) NOT NULL DEFAULT 'active',
user_id bigint(20) unsigned NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY user_id (user_id),
KEY status (status)
) {$this->charset};";
$this->dbDelta($sql);
}
public function down(): void
{
$this->dropTable('items');
}
};
Admin Form with Nonce
<?php
// app/Http/Controllers/SettingsController.php
namespace MyPlugin\Http\Controllers;
use WPZylos\Framework\Views\ViewFactory;
use WPZylos\Framework\Security\Nonce;
use WPZylos\Framework\Security\Gate;
use WPZylos\Framework\Security\Sanitizer;
use WPZylos\Framework\Core\Contracts\ContextInterface;
class SettingsController
{
public function __construct(
private ViewFactory $view,
private Nonce $nonce,
private Gate $gate,
private Sanitizer $sanitizer,
private ContextInterface $context
) {}
public function index(): void
{
echo $this->view->render('admin/settings', [
'title' => __('Settings', $this->context->textDomain()),
'nonce' => $this->nonce->create('save_settings'),
'options' => get_option($this->context->optionKey('settings'), []),
]);
}
public function save(): void
{
// 1. Verify nonce
if (!$this->nonce->verify($_POST['_nonce'] ?? '', 'save_settings')) {
wp_die(__('Invalid request', $this->context->textDomain()));
}
// 2. Check capability
if (!$this->gate->can('manage_options')) {
wp_die(__('Unauthorized', $this->context->textDomain()));
}
// 3. Sanitize and save
$settings = [
'enabled' => isset($_POST['enabled']),
'api_key' => $this->sanitizer->text($_POST['api_key'] ?? ''),
'limit' => absint($_POST['limit'] ?? 10),
];
update_option($this->context->optionKey('settings'), $settings);
wp_redirect(admin_url('admin.php?page=' . $this->context->slug() . '-settings&saved=1'));
exit;
}
}
View Template
<?php
// resources/views/admin/settings.php
/** @var string $title */
/** @var string $nonce */
/** @var array $options */
/** @var \WPZylos\Framework\Core\Contracts\ContextInterface $context */
?>
<div class="wrap">
<h1><?php echo esc_html($title); ?></h1>
<?php if (isset($_GET['saved'])): ?>
<div class="notice notice-success is-dismissible">
<p><?php esc_html_e('Settings saved!', $context->textDomain()); ?></p>
</div>
<?php endif; ?>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
<input type="hidden" name="action" value="<?php echo esc_attr($context->slug()); ?>_save_settings">
<input type="hidden" name="_nonce" value="<?php echo esc_attr($nonce); ?>">
<table class="form-table">
<tr>
<th><?php esc_html_e('Enable Feature', $context->textDomain()); ?></th>
<td>
<label>
<input type="checkbox" name="enabled" <?php checked($options['enabled'] ?? false); ?>>
<?php esc_html_e('Enable', $context->textDomain()); ?>
</label>
</td>
</tr>
<tr>
<th><?php esc_html_e('API Key', $context->textDomain()); ?></th>
<td>
<input type="text" name="api_key" value="<?php echo esc_attr($options['api_key'] ?? ''); ?>" class="regular-text">
</td>
</tr>
<tr>
<th><?php esc_html_e('Limit', $context->textDomain()); ?></th>
<td>
<input type="number" name="limit" value="<?php echo esc_attr($options['limit'] ?? 10); ?>" min="1" max="100">
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
Service Provider
<?php
// app/Providers/AppServiceProvider.php
namespace MyPlugin\Providers;
use WPZylos\Framework\Core\ServiceProvider;
use MyPlugin\Services\ItemService;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->container->singleton(ItemService::class, function ($container) {
return new ItemService(
$container->get('database'),
$container->get('context')
);
});
}
public function boot(): void
{
// Register hooks, shortcodes, etc.
add_action('admin_menu', [$this, 'registerMenus']);
}
public function registerMenus(): void
{
add_menu_page(
__('My Plugin', $this->context->textDomain()),
__('My Plugin', $this->context->textDomain()),
'manage_options',
$this->context->slug(),
[$this, 'renderDashboard'],
'dashicons-admin-generic'
);
}
public function renderDashboard(): void
{
$controller = $this->container->get(DashboardController::class);
$controller->index();
}
}
Routes File
<?php
// routes/web.php
use WPZylos\Framework\Routing\Router;
use MyPlugin\Http\Controllers\ItemController;
use MyPlugin\Http\Controllers\SettingsController;
return static function (Router $router): void {
// Admin routes
$router->admin('', [ItemController::class, 'index']);
$router->admin('add', [ItemController::class, 'create']);
$router->admin('edit/{id}', [ItemController::class, 'edit']);
$router->admin('settings', [SettingsController::class, 'index']);
// POST routes
$router->post('store', [ItemController::class, 'store']);
$router->post('update/{id}', [ItemController::class, 'update']);
$router->post('delete/{id}', [ItemController::class, 'destroy']);
$router->post('save-settings', [SettingsController::class, 'save']);
};
Related Resources
- Walkthrough — Complete step-by-step tutorial
- API Reference — Full method documentation
- wpzylos.com — Framework documentation