Let's build an ExpressionEngine Module!
Control Panel Page (mcp file) and model. Part One
Filed in: PHP, ExpressionEngine, tutorial
March 16, 2011
- Project Setup and Module Installation
- Control Panel Page (mcp file) and model. Part One
- Control Panel Page (mcp file) and model. Part Two
- Front End Template Tag
I decided to break the control panel portion into two parts, so this will now be a four part series. First, we're going to build the form to submit a short link. This will include a model, view and controller (mcp file).
So, let's start by setting up the base for the module control panel file (mcp.shortee.php). Open that up in your editor, and let's get to work!
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Shortee_mcp { private $_base_url; private $_form_base; private $EE; public function __construct() { } public function index() { } public function add_edit_link() { } public function view_link() { } }
As part of sketching out what the file is going to look like, I find it helpful to first decide on all of the public methods I'll need. On Control Panel files like this, I usually find it helpful to setup a couple of private variables to cut down on typing…more on that later.
The functions map to URLs in the control panel, eg: /index.php?S=0&D=cp&C=addons_modules&M=show_module_cp&module=shortee maps to the index() method. In a CP file, if you want to access add_edit_link, tack on method=add_edit_link to the URL.
Let's start in the constructor and add some things we want available in the entire class.
<?php public function __construct() { $this->EE =& get_instance(); // Set base URL to the module so there's less typing // elsewhere in this class. $this->_base_url = BASE.AMP.'C=addons_modules'.AMP.'M=show_module_cp'; $this->_base_url .= AMP.'module=shortee'; $this->_form_base = 'C=addons_modules'.AMP.'M=show_module_cp'.AMP.'module=shortee'; $this->EE->cp->set_right_nav(array( 'shortlink_home' => $this->_base_url, 'add_link' => $this->_base_url.AMP.'method=add_edit_link', )); $this->EE->load->helper('text'); }
First off, we assign the EE Super Object to the private $EE class variable. To keep our typing low, we'll setup $_base_url and $_form_base as well. Additionally, we're using the set_right_nav() function in the CP class to set the righthand navigation in our module's CP.
<?php public function add_edit_link() { // Set page title $this->EE->cp->set_variable('cp_page_title', lang('add_link')); // Load libs $this->EE->load->library('form_validation'); // Helpers $this->EE->load->helper('form'); $this->EE->form_validation->set_rules( 'url', 'lang:url', 'required|prep_url') ->set_error_delimiters( '<div class="notice">', '</div>'); if ($this->EE->form_validation->run()) { // We passed the test, onward! $data = array( 'link' => $this->EE->input->post('url'), 'created_by_member_id' => $this->EE->session->userdata('member_id'), 'entry_date' => $this->EE->localize->now ); $this->EE->db->insert('shortee_links', $data); $id = $this->EE->db->insert_id(); $this->EE->session->set_flashdata('message_success', lang('link_added')); $this->EE->functions->redirect($this->_base_url.AMP.'method=view_link'.AMP.'id='.$id); } $form_hidden = (($id = $this->EE->input->get('id')) ? array('id' => $id) : ''); $data = array( 'form_action' => $this->_form_base.AMP.'method=add_edit_link', 'form_hidden' => $form_hidden, ); return $this->EE->load->view('add_link', $data, TRUE); } // ----------------------------------------------------------------
In this method the first thing to do is to call $this->EE->cp->set_variable('cp_page_title', lang('add_link')) to set the page title. Next, we load up CodeIgniter form_validation library and Form Helper.
We set form validation rules to require the URL field, and load up the form, as $this->EE->form_validation->run() returns a boolean FALSE on the first page load. Looking to the future, I want the ability to edit links on this same page, so I'm setting a hidden form element of id if we have id=n in the query string. If form validation passes, we're dropping in the link, the entry_date and member_id of the logged in user who created it in the database.
This method is a bit long, so we should refactor a bit to make it look more readable.
<?php public function add_edit_link() { // Set page title $this->EE->cp->set_variable('cp_page_title', lang('add_link')); // Load libs $this->EE->load->library('form_validation'); // Helpers $this->EE->load->helper('form'); $this->EE->form_validation->set_rules( 'url', 'lang:url', 'required|prep_url') ->set_error_delimiters( '<div class="notice">', '</div>'); if ($this->EE->form_validation->run()) { // We passed the test, onward! $this->_do_add_shortlink(); } $form_hidden = (($id = $this->EE->input->get('id')) ? array('id' => $id) : ''); $data = array( 'form_action' => $this->_form_base.AMP.'method=add_edit_link', 'form_hidden' => $form_hidden, ); return $this->EE->load->view('add_link', $data, TRUE); } // ---------------------------------------------------------------- private function _do_add_shortlink() { $data = array( 'link' => $this->EE->input->post('url'), 'created_by_member_id' => $this->EE->session->userdata('member_id'), 'entry_date' => $this->EE->localize->now ); $this->EE->db->insert('shortee_links', $data); $id = $this->EE->db->insert_id(); $this->EE->session->set_flashdata('message_success', lang('link_added')); $this->EE->functions->redirect($this->_base_url.AMP.'method=view_link'.AMP.'id='.$id); }
So that's a bit more like it. All of the form processing data is now contained in its own function that's called when form validation passes. Some MVC die-hards might be mad at the way I'm handling the database insert. Honestly, I don't really care. I think the code is still highly readable, and it seems silly to me to include a file and instantiate a class only to call one 5 line method. So this works for me. :)
View File
<?=form_open($form_action, '', $form_hidden);?> <?=validation_errors()?> <table class="mainTable" border="0" cellspacing="0" cellpadding="0"> <thead> <tr> <th style="width:20%"><?=lang('setting')?></th> <th><?=lang('value')?></th> </tr> </thead> <tbody> <tr class="even"> <td><?=lang('url', 'url')?></td> <td><?=form_input('url')?></td> </tr> </tbody> </table> <?=form_submit('submit', lang('submit'), 'class="submit"')?> <?=form_close()?>
Here, we build up the form. You can either choose to code the table yourself, or use the CodeIgniter HTML Table class. There isn't a right or wrong way. Do what you're comfortable with. The main thing to pay attention to is the classes used. table.mainTable will give you the EE default table 'look,' and the submit class on the submit button is the proper style for the cherry red submit button. Lastly, you can 'stripe' your html tables alternating between tr.even/odd. See the EE Dev Docs for more information on control panel styles.
At this point, we should be able to submit the form and add a new short link. In the next post, we'll work on the page we return to after submission, and the fun with models will begin! I tagged where code should be at this point over at BitBucket.
Until next time…