CMS Made Simple™ Developer Resources
Tutorial: Admin CRUD
Now we build the admin interface: a list of holidays with add, edit, and delete functionality. This involves creating action files, Smarty templates, a query class, and adding lang strings.
Step 1: The Query Class
Create lib/class.HolidayQuery.php to handle listing holidays with pagination:
<?php
if (!defined('CMS_VERSION')) exit;
class HolidayQuery extends CmsDbQueryBase
{
public function __construct($args = '')
{
parent::__construct($args);
if (isset($this->_args['limit'])) {
$this->_limit = (int) $this->_args['limit'];
}
}
public function execute()
{
if (!is_null($this->_rs)) return;
$sql = 'SELECT SQL_CALC_FOUND_ROWS H.*
FROM ' . CMS_DB_PREFIX . 'mod_holidays H';
if (isset($this->_args['published'])) {
$tmp = $this->_args['published'];
if ($tmp === 0) {
$sql .= ' WHERE published = 0';
} else if ($tmp === 1) {
$sql .= ' WHERE published = 1';
}
}
$sql .= ' ORDER BY the_date DESC';
$db = \cms_utils::get_db();
$this->_rs = $db->SelectLimit($sql, $this->_limit, $this->_offset);
if ($db->ErrorMsg()) {
throw new \CmsSQLErrorException($db->sql . ' -- ' . $db->ErrorMsg());
}
$this->_totalmatchingrows = $db->GetOne('SELECT FOUND_ROWS()');
}
public function &GetObject()
{
$obj = new HolidayItem();
$obj->fill_from_array($this->fields);
return $obj;
}
}
This class extends CmsDbQueryBase, which handles pagination and result iteration. The GetMatches() method (inherited) returns an array of HolidayItem objects.
Step 2: The Default Admin Action
Create action.defaultadmin.php — the entry point for the admin panel:
<?php
if (!defined('CMS_VERSION')) exit;
if (!$this->CheckPermission(Holidays::MANAGE_PERM)) return;
$query = new HolidayQuery();
$holidays = $query->GetMatches();
$tpl = $smarty->CreateTemplate(
$this->GetTemplateResource('defaultadmin.tpl'), null, null, $smarty
);
$tpl->assign('holidays', $holidays);
$tpl->display();
Step 3: The Admin List Template
Create templates/defaultadmin.tpl:
<script type="text/javascript">
$(document).ready(function(){
$('a.del_holiday').click(function(){
return confirm('{$mod->Lang('confirm_delete')}');
});
});
</script>
<div class="pageoptions">
<a href="{cms_action_url action=edit_holiday}">
{admin_icon icon='newobject.gif'} {$mod->Lang('add_holiday')}
</a>
</div>
{if !empty($holidays)}
<table class="pagetable">
<thead>
<tr>
<th>{$mod->Lang('name')}</th>
<th>{$mod->Lang('date')}</th>
<th class="pageicon"></th>
<th class="pageicon"></th>
</tr>
</thead>
<tbody>
{foreach $holidays as $holiday}
{cms_action_url action=edit_holiday hid=$holiday->id assign='edit_url'}
<tr>
<td><a href="{$edit_url}" title="{$mod->Lang('edit')}">{$holiday->name|escape}</a></td>
<td>{$holiday->the_date|date_format:'%x'}</td>
<td><a href="{$edit_url}" title="{$mod->Lang('edit')}">
{admin_icon icon='edit.gif'}</a></td>
<td><a class="del_holiday"
href="{cms_action_url action=delete_holiday hid=$holiday->id}"
title="{$mod->Lang('delete')}">
{admin_icon icon='delete.gif'}</a></td>
</tr>
{/foreach}
</tbody>
</table>
{/if}
Step 4: The Edit/Add Action
Create action.edit_holiday.php — handles both adding new holidays and editing existing ones:
<?php
if (!defined('CMS_VERSION')) exit;
if (!$this->CheckPermission(Holidays::MANAGE_PERM)) return;
$holiday = new HolidayItem();
// Load existing record if editing
if (isset($params['hid']) && $params['hid'] > 0) {
$holiday = HolidayItem::load_by_id((int) $params['hid']);
}
// Handle cancel
if (isset($params['cancel'])) {
$this->RedirectToAdminTab();
}
// Handle form submission
if (isset($params['submit'])) {
$holiday->name = trim($params['name']);
$holiday->published = cms_to_bool($params['published']);
$holiday->the_date = strtotime($params['the_date']);
$holiday->description = $params['description'];
$holiday->save();
$this->SetMessage($this->Lang('holiday_saved'));
$this->RedirectToAdminTab();
}
// Display the form
$tpl = $smarty->CreateTemplate(
$this->GetTemplateResource('edit_holiday.tpl'), null, null, $smarty
);
$tpl->assign('holiday', $holiday);
$tpl->display();
Step 5: The Edit Form Template
Create templates/edit_holiday.tpl:
<h3>{$mod->Lang('add_holiday')}</h3>
{form_start hid=$holiday->id}
<div class="pageoverflow">
<p class="pageinput">
<input type="submit" name="{$actionid}submit" value="{$mod->Lang('submit')}" />
<input type="submit" name="{$actionid}cancel" value="{$mod->Lang('cancel')}" />
</p>
</div>
<div class="pageoverflow">
<p class="pagetext">{$mod->Lang('name')}:</p>
<p class="pageinput">
<input type="text" name="{$actionid}name" value="{$holiday->name|escape}" />
</p>
</div>
<div class="pageoverflow">
<p class="pagetext">{$mod->Lang('date')}:</p>
<p class="pageinput">
<input type="date" name="{$actionid}the_date"
value="{$holiday->the_date|date_format:'%Y-%m-%d'}" />
</p>
</div>
<div class="pageoverflow">
<p class="pagetext">{$mod->Lang('published')}:</p>
<p class="pageinput">
<select name="{$actionid}published">
{cms_yesno selected=$holiday->published}
</select>
</p>
</div>
<div class="pageoverflow">
<p class="pagetext">{$mod->Lang('description')}:</p>
<p class="pageinput">
{cms_textarea prefix=$actionid name=description
value=$holiday->description enablewysiwyg=true}
</p>
</div>
{form_end}
Step 6: The Delete Action
Create action.delete_holiday.php:
<?php
if (!defined('CMS_VERSION')) exit;
if (!$this->CheckPermission(Holidays::MANAGE_PERM)) return;
if (isset($params['hid']) && $params['hid'] > 0) {
$holiday = HolidayItem::load_by_id((int) $params['hid']);
if ($holiday) {
$holiday->delete();
$this->SetMessage($this->Lang('holiday_deleted'));
}
}
$this->RedirectToAdminTab();
Step 7: Add Lang Strings
Add these to lang/en_US.php:
$lang['add_holiday'] = 'Create a New Holiday';
$lang['edit'] = 'Edit this';
$lang['delete'] = 'Delete this';
$lang['submit'] = 'Submit';
$lang['cancel'] = 'Cancel';
$lang['name'] = 'Name';
$lang['date'] = 'Date';
$lang['published'] = 'Published';
$lang['description'] = 'Description';
$lang['holiday_saved'] = 'This holiday is now saved';
$lang['holiday_deleted'] = 'This holiday is now deleted';
$lang['confirm_delete'] = 'Are you sure that you want to delete this holiday record?';
Status Check
Your module now has a complete admin CRUD interface. Navigate to Extensions > Holidays to:
- Add new holidays with a name, date, published flag, and WYSIWYG description.
- See all holidays in a list table.
- Click a holiday name or the edit icon to edit it.
- Click the delete icon (with confirmation) to remove it.
modules/Holidays/
├── Holidays.module.php
├── action.defaultadmin.php
├── action.edit_holiday.php
├── action.delete_holiday.php
├── method.install.php
├── method.uninstall.php
├── lang/
│ └── en_US.php
├── lib/
│ ├── class.HolidayItem.php
│ └── class.HolidayQuery.php
└── templates/
├── defaultadmin.tpl
└── edit_holiday.tpl
Next, we'll create the frontend views so visitors can see holidays on the website. Continue to {cms_selflink dir='next' text='Frontend Views'}.
