Admin Editable Settings and Theme in CakePHP

Admin Editible Settings and Theme in CakePHP

Usually the client will request for me to give them a way to edit simple settings in their application.

I decided to read all the variables from the database in the beforeFilter to make them available in any controller.

The Tables

settings
CREATE TABLE IF NOT EXISTS `settings` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL,
  `description` text,
  `category` varchar(255) NOT NULL,
  `setting` varchar(255) NOT NULL,
  `value` text,
  `created` datetime default NULL,
  `modified` datetime default NULL,
  PRIMARY KEY  (`id`)
);
INSERT INTO `settings` (`id`, `name`, `description`, `category`, `setting`, `value`, `created`, `modified`) VALUES
(1, 'Name', 'The title of the application.', 'app', 'name', 'Your Website', NOW(), NOW()),
(3, 'Theme', 'Front end theme.', 'app', 'theme', NULL, NOW(), NOW()),
(4, 'Admin Theme', 'Admin theme.', 'app', 'admin_theme', 'cp', NOW(), NOW()),
(5, 'Email', 'The default email address.', 'app', 'email', 'noreply@yourdomain.com', NOW(), NOW()),
(6, 'Delivery', 'Delivery method.  Valid options are: mail, smtp or debug.', 'smtp', 'delivery', 'debug', NOW(), NOW()),
(7, 'Username', 'SMTP Username.', 'smtp', 'username', NULL, NOW(), NOW()),
(8, 'Password', 'SMTP Password.', 'smtp', 'password', NULL, NOW(), NOW());

The Models

Before we get started, lets setup the models.

models/setting.php
<?php
class Setting extends AppModel {
	var $name = 'Setting';
}
?>

The Controller

The app_controller will do the work of setting the Settings and the Theme.

app_controller.php
<?php
class AppController extends Controller {
	var $view = 'Theme'; // important for theming

	function beforeFilter() {
		$this->__setSettings();
		$this->__setTheme();
		parent::beforeFilter();
	}

	function __setSettings() {
		$Setting  = ClassRegistry::init('Setting');
  		$settings = $Setting->find('all');
  		foreach($settings as $_setting) {
  			if ($_setting['Setting']['value']!==null) {
	  			Configure::write('Settings.'.$_setting['Setting']['category'].'.'.$_setting['Setting']['setting'], $_setting['Setting']['value']);
  			}
  		}
  		// you can now use the following anywhere in your app
  		// $settings = Configure::read('Settings.app'); debug($settings)
	}

	function __setTheme() {
		// check if the admin is being requested
		if(isset($this->params[Configure::read('Routing.admin')])) {
			// set admin theme
			$this->theme = Configure::read('Settings.app.admin_theme');
		}
		else {
			// set front end theme
			$this->theme = Configure::read('Settings.app.theme');
		}
	}

}
?>

The settings controller handles the administration of the settings.

controllers/settings_controller.php
<?php
class SettingsController extends AppController{
	var $name = 'Settings';
	var $multiActions = array('admin_multi_delete');

	function admin_index() {
		if (isset($this->passedArgs['keywords']) && $this->passedArgs['keywords']) {
			$this->paginate['conditions'][]['Setting.name'] = 'LIKE %'.$this->passedArgs['keywords'].'%';
			$this->paginate['conditions'][]['Setting.category'] = 'LIKE %'.$this->passedArgs['keywords'].'%';
			$this->paginate['conditions'][]['Setting.setting'] = 'LIKE %'.$this->passedArgs['keywords'].'%';
			$this->data['Search']['keywords'] = $this->passedArgs['keywords'];
		}
		if (isset($this->passedArgs['category']) && $this->passedArgs['category']) {
			$this->paginate['conditions'][]['Setting.category'] = $this->passedArgs['category'];
			$this->data['Search']['category'] = $this->passedArgs['category'];
		}
		$settings = $this->paginate();
	 	$this->set('settings', $settings);
	}

	function admin_search() {
		$url['action'] = 'index';
		if (isset($this->data['Search']['keywords']) && $this->data['Search']['keywords'] && $this->data['Search']['keywords']!='keywords') {
			$url['keywords'] = $this->data['Search']['keywords'];
		}
		if (isset($this->data['Search']['category']) && $this->data['Search']['category'] && $this->data['Search']['keywords']!='category') {
			$url['category'] = $this->data['Search']['category'];
		}
		$this->redirect($url, null, true);
	}

	function admin_add() {
		$this->admin_form();
		$this->render('admin_form');
	}
	function admin_edit($id = null) {
		if (!$id && empty($this->data)) {
			$this->multiFlash(__('Invalid Setting.', true),'error');
			$this->redirect(array('action'=>'index'));
		}
		$this->admin_form($id);
		$this->render('admin_form');
	}
	
	function admin_form($id = null) {
		if (!empty($this->data)) {
			// save the data			
			if ($this->Setting->save($this->data)) {
				$this->multiFlash(__('The Setting has been saved.', true),'success');
				$this->redirect(array('action'=>'view',$this->Setting->id));
			} else {
				$this->multiFlash(__('The Setting could not be saved. Please, try again.', true),'warning');
			}
		}
		if (empty($this->data)) {
			$this->data = $this->Setting->read(null, $id);
		}
	}
	
}
?>

The Views

views/settings/admin_index.ctp
<div class="actions">
	<ul>
		<li><?php echo $html->link(__('New Setting', true), array('action'=>'add')); ?></li>
	</ul>
</div>

<div class="settings index">

	<h2><?php __('Settings');?></h2>
	
	<?php echo $form->create('Setting',array('id'=>'SettingListForm','url'=>array('controller'=>'settings','action'=>'multi')));?>
	<table cellpadding="0" cellspacing="0" class="listTable">
		<tr>
			<th><span class="select_all">a</span>|<span class="select_none">n</span></th>
			<th><?php echo $paginator->sort('id');?></th>
			<th><?php echo $paginator->sort('name');?></th>
			<th><?php echo $paginator->sort('category');?></th>
			<th><?php echo $paginator->sort('setting');?></th>
			<th><?php echo $paginator->sort('value');?></th>
			<th><?php echo $paginator->sort('modified');?></th>
			<th class="actions"><?php __('Actions');?></th>
		</tr>
		<?php
		$i = 0;
		foreach ($settings as $setting):
			$class = null;
			if ($i++ % 2 == 0) {
				$class = ' class="altrow"';
			}
		?>
			<tr<?php echo $class;?>>
				<td>
					<?php echo $form->input($setting['Setting']['id'],array(
						'type'=>'checkbox',
						'label'=>false,
						'name'=>'record['.$setting['Setting']['id'].']',
						'id'=>'listRecord_'.$setting['Setting']['id'],
					)); ?>
				</td>
				<td>
					<?php echo $setting['Setting']['id']; ?>
				</td>
				<td>
					<?php echo $setting['Setting']['name']; ?>
				</td>
				<td>
					<?php echo $setting['Setting']['category']; ?>
				</td>
				<td>
					<?php echo $setting['Setting']['setting']; ?>
				</td>
				<td>
					<?php echo $setting['Setting']['value']; ?>
				</td>
				<td>
					<?php echo $setting['Setting']['modified']; ?>
				</td>
				<td class="actions">
					<?php echo $html->link(__('Edit', true), array('action'=>'edit', $setting['Setting']['id'])); ?>
				</td>
			</tr>
		<?php endforeach; ?>
	</table>
	
	<?php echo $form->end();?>
	<?php echo $this->renderElement('paging');?>
	
</div>
views/settings/admin_form.ctp
<div class="actions">
	<ul>
		<li><?php echo $html->link(__('List Settings', true), array('action'=>'index'));?></li>
	</ul>
</div>

<div class="settings form">
	<h2><?php __('Edit Setting');?></h2>
	<?php echo $form->create('Setting');?>
		<fieldset>
	 		<legend><?php __('Setting Details');?></legend>
		<?php
			echo $form->input('id');
			echo $form->input('name');
			echo $form->input('description');
			echo $form->input('category');
			echo $form->input('setting');
			echo $form->input('value');
		?>
		</fieldset>
	<?php echo $form->end('Submit');?>
</div>

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I am a newbe in cakephp and this post is very useful for me. Post more useful tutorial in cakephp.

hey thank you this article save me..

good job

Thank you!
But action "view" is absent in the controller.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <b> <i> <strong> <cite> <em> <code> <pre> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <css>, <diff>, <drupal5>, <html>, <javascript>, <php>. The supported tag styles are: <foo>, [foo]. PHP source code can also be enclosed in <?php ... ?> or <% ... %>.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.