Extending CMS Made Simple

89
Extending CMS Made Simple Presented by Jeff Bosch and Samuel Goldstein

description

How to add functionality to CMS Made Simple using Tags, User-Defined Tags, and Modules. Also includes some previews of how the module API will change with version 2.0

Transcript of Extending CMS Made Simple

Page 1: Extending CMS Made Simple

Extending CMS Made SimplePresented by

Jeff Bosch and Samuel Goldstein

Page 2: Extending CMS Made Simple

Jeff Bosch

● Core Development Team member● B.S. in Computer Science● Started A & J Progamming in 2007 for

custom web programming and implementation

Page 3: Extending CMS Made Simple

Samuel Goldstein

● Core Development Team member since 2004

● Principal at 1969 Communications

● Background● Programming since 1980, starting with TRS-80● Aerospace in the '90s● Dot-com roller coaster

● Hey! Buy my book!● CMS Made Simple Developer's Cookbook from Packt Publishing

Page 4: Extending CMS Made Simple

OK, enough of that

● Why extend CMS Made Simple?● Add functionality● Make things easier for your clients● More money for you● Fame, fortune, glory

Page 5: Extending CMS Made Simple

Ways to Extend CMSMS

● Core, core modules, and Smarty● User-Defined Tags● Tags (a.k.a. Plugins)● Modules

Page 6: Extending CMS Made Simple

How do I decide on an approach?

● There is not always an “absolute best” approach

● Don't neglect non-technical considerations (e.g., your specific users)

● The following chart may also help

Page 7: Extending CMS Made Simple

Approaches

Smarty Tag UDT Module

No installation required √ √

Multiple actions √* √

Create databases / preferences √* √

Act as Smarty modifier √

Help displayed in Admin area √ √

Admin panel √

Post on Developer's Forge, share via Module Manager

Localization/Translation √

Page 8: Extending CMS Made Simple

Let's get started!

● Build a Google Site Map using Core and Core Modules● We'll use Menu Manager in a hidden page● We'll create a custom Menu Manager

template● And a mod_rewrite trick

Page 9: Extending CMS Made Simple

Menu Manager Template

<?xml  version="1.0"  encoding="UTF-­‐8"?><urlset  xmlns="hRp://www.sitemaps.org/schemas/sitemap/0.9">{if  $count  >  0}{foreach  from=$nodelist  item=node}  <url>        <loc>{$node-­‐>url|escape:'html'}</loc>        <lastmod>{$node-­‐>modified|date_format:'%Y-­‐%m-­‐%dT%T-­‐08:00'}</lastmod>    </url>{/foreach}{/if}</urlset>

Page 10: Extending CMS Made Simple

Calling the Template

● Create page named “sitemap”● Set alias to “sitemap” too● Uncheck “Show in Menu”● Insert tag into your page content:{menu  template='sitemap'  show_all='1'  collapse='0'}

Page 11: Extending CMS Made Simple

<IfModule  mod_rewrite.c>RewriteEngine  on#Sub-­‐dir  e.g:  /cmsmsRewriteBase  /RewriteCond  %{REQUEST_FILENAME}  !-­‐f  [NC]RewriteCond  %{REQUEST_FILENAME}  !-­‐d  [NC]RewriteRule  ^sitemap.xml$  index.php?page=sitemap&showtemplate=false  [L]</IfModule>

Add an .htaccess file

Page 12: Extending CMS Made Simple

Test it!

● Go to http://yoursite.com/sitemap.xml<?xml  version="1.0"  encoding="UTF-­‐8"?><urlset  xmlns="hRp://www.sitemaps.org/schemas/sitemap/0.9">    <url>        <loc>hRp://cms_book.viajante/</loc>        <lastmod>2009-­‐05-­‐13T10:12:18-­‐08:00</lastmod>    </url>    <url>        <loc>hRp://cms_book.viajante/index.php?page=how-­‐cmsms-­‐works</loc>        <lastmod>2009-­‐05-­‐12T20:11:52-­‐08:00</lastmod>    </url>  …</urlset>

Page 13: Extending CMS Made Simple

OK, how about a Tag?

● Only tags can serve as Smarty modifiers● Here's a tag that vigorously defends our

intellectual property!● Appends a ® symbol to every instance of

“CMS Made Simple” in page content.

Page 14: Extending CMS Made Simple

postfilter.registeredtrademarker.php

<?phpfuncQon  smarty_cms_posPilter_registeredtrademarker($tpl_output,  &$smarty){

global  $gCms;$result  =  explode(':',  $smarty-­‐>_current_file);

if  (count($result)  >  0){

if  ($result[0]  ==  'content'){$tpl_output  =  str_replace('CMS  Made  Simple','CMS  Made  Simple®',  $tpl_output);}

}return  $tpl_output;

}?>

Page 15: Extending CMS Made Simple

Using the Filter

● Save your filter in the plugins directory● In the Admin, be sure to clear your

cache!● View your site.

Page 16: Extending CMS Made Simple

You® filte®ed ®esults

Page 17: Extending CMS Made Simple

OK, how about a UDT?

● UDTs can do all sorts of things:● Talk to the database● Talk to modules● Deal with events● Interact with Smarty

● Let's try a few of those things!

Page 18: Extending CMS Made Simple

UDT “pagecounter”

global  $gCms;

$db  =  $gCms-­‐>GetDb();

$count  =  $db-­‐>GetOne('select  count(*)  from  '.cms_db_prefix().'content  where  acQve=1');

$smarty  =  $gCms-­‐>GetSmarty();$smarty-­‐>assign('page_count','Total  pages:  '.$count);

Page 19: Extending CMS Made Simple

Then, add a content page

● Set the title and menu text● In the content, call the UDT with{pagecounter}

● And output the Smarty variable with{$page_count}

Page 20: Extending CMS Made Simple

Viewing your page

Page 21: Extending CMS Made Simple

Exercise I

● What approach would you use to implement each of the following?● Convert your page content into Pirate Speak● A form for users to submit movie reviews, with an

Admin panel allowing the site maintainer to approve or reject reviews for display

● Putting the title of the most-recently added page into a Smarty variable

Page 22: Extending CMS Made Simple

Exercise I, cont.

● Display a special image file only on the site's home page

● Display the Admin account email address on a page (but obscured to prevent spammers from harvesting it)

● Display a poll, and show the results after the user votes

● Display links to all pages that are below the current page in the site hierarchy

Page 23: Extending CMS Made Simple

Exercise II

● Create a UDT for changing site layout seasonally.● Set a variable which can be used to change

the stylesheet classes of the site.● For simplicity, call January-March “winter,”

April-June “spring,” July-September “summer,” and October-December “autumn.”

Page 24: Extending CMS Made Simple

Exercise II, cont. UDTglobal  $gCms;

$month  =  date('n');  //  returns  month  as  number  between  1  and  12,  inclusive$smarty  =  $gCms-­‐>GetSmarty();

if  ($month  <  4)$season  =  'winter';

else  if  ($month  <  7)$season  =  'spring';

else  if  ($month  <  10)$season  =  'summer';

else$season  =  'autumn';

$smarty-­‐>assign('season',  $season);

Page 25: Extending CMS Made Simple

Exercise II, cont. Template.{process_pagedata}<!DOCTYPE  html  PUBLIC  "-­‐//W3C//DTD  XHTML  1.0  TransiQonal//EN"  "hRp://www.w3.org/TR/xhtml1/DTD/xhtml1-­‐transiQonal.dtd"><html  xmlns="hRp://www.w3.org/1999/xhtml"  xml:lang="en"  ><head><Qtle>{sitename}  -­‐  {Qtle}</Qtle>{metadata}{cms_stylesheet}{season}</head><body><div  id="header"><h1  class=”{$season}”>{sitename}</h1></div><div  id="menu">{menu}</div><div  id="content"  class=”{$season}”>    <h1>{Qtle}</h1>    {content}</div></body></html>

Page 26: Extending CMS Made Simple

Exercise II, cont. CSS

.winter  {background-­‐color:  #bfc4ff;}

.spring  {background-­‐color:  #bfffce;}

.summer  {background-­‐color:  #fffabf;}

.autumn  {background-­‐color:  #ffcabf;}

#header  h1.summer  {background:  url(/uploads/images/beach.jpg);}

Page 27: Extending CMS Made Simple

Hour IIHow's my timing?

Page 28: Extending CMS Made Simple

Getting Started with Modules

● For the 1.x series, several ways to get started● From scratch● Skeleton module● Module Maker● MCFactory● etc

Page 29: Extending CMS Made Simple

Skeleton Module

● Download from Forge or Module Manager

● Has simple functionality● install/upgrade● admin panel● database routines● form API calls

Page 30: Extending CMS Made Simple

Skeleton Module, cont.

● Once you've installed, edit the files to adapt to your own purposes

● Well commented● Somewhat dated: last updated for CMS

MS 1.6.5● Still has correct structure, but may lack

more recent improvements and features

Page 31: Extending CMS Made Simple

Structure of a 1.x module

● Modules extend the CMSModule class● Magic of OO:

● Automatically inherits a lot of functionality (e.g., Database and Form APIs, Smarty, Translation, etc)

● Most methods already inherit acceptable defaults

Page 32: Extending CMS Made Simple

Minimal 1.x Module

● File lives in $CMS_ROOT/modules/module_name

● Filename is module_name.module.php● Module class must match file name● Need to implement 3 methods:

● GetName● DoAction● IsPluginModule

Page 33: Extending CMS Made Simple

Minimal 1.x module, cont.

● GetName simply returns module name; must match class and filename

● IsPluginModule returns boolean.● DoAction is, unsurprisingly, where the

real action takes place

Page 34: Extending CMS Made Simple

DoAction

● Called with a few parameters:● $action, “reason for calling.” Two built-in:

“default” and “defaultadmin”● $id, a prefix for use in forms● $params, a hash of parameters● $returnid, reference to the page containing

the tag

Page 35: Extending CMS Made Simple

Other important methods

● Install, upgrade, uninstall. These methods called as expected, and allow for housekeeping

● SetParameters. Sets up parameter filtering, URL routes,

● Lang. Translates strings.

Page 36: Extending CMS Made Simple

Minimal 1.x module, cont.

● For performance reasons, methods are split out into multiple files

● String translations are stored in external files

● Templates may be stored as files or in the database

Page 37: Extending CMS Made Simple

Layout on filesystem

Page 38: Extending CMS Made Simple

Enough Abstraction!

● We will create a basic module that demonstrates core APIs

● “Quotations Module” requirements:● Presents form to user, handles input safely● Displays random quotation to user● Allows admin to delete records

Page 39: Extending CMS Made Simple

Step 1. Preparation

● Create directories● $CMS_ROOT/modules/Quotations● Quotations/templates● Quotations/lang

● Create base files:● Quotations.module.php● lang/en_US.php

Page 40: Extending CMS Made Simple

Quotations.module.php<?phpclass  QuotaQons  extends  CMSModule

{funcQon  GetName()

{return  'QuotaQons';}

funcQon  GetFriendlyName(){return  $this-­‐>Lang('friendlyname');}

funcQon  IsPluginModule(){return  true;}

funcQon  GetVersion(){return  '0.1';}

}?>

Page 41: Extending CMS Made Simple

lang/en_US.php<?php$lang['friendlyname']='QuotaQon  Module';?>

Page 42: Extending CMS Made Simple

Database Schema

● We'll probably need● Unique ID● Quotation text● Quotation author● Submission date

Page 43: Extending CMS Made Simple

method.install.php<?phpif  (!isset($gCms))  exit;

$db  =  $this-­‐>GetDb();$dict  =  NewDataDicQonary(  $db  );

$fields="quotaQon_id  I  KEY,quotaQon  X,author  C(80),submit_date  DT

";

$sqlarray  =  $dict-­‐>CreateTableSQL(  cms_db_prefix()."module_quotaQons",$fields);$dict-­‐>ExecuteSQLArray($sqlarray);

$db-­‐>CreateSequence(cms_db_prefix()."module_quotaQon_seq");?>

Page 44: Extending CMS Made Simple

Install it

Page 45: Extending CMS Made Simple

Consider parameters

● Form will submit quotation and author● Viewing will require quotation_id● Module will also be a plugin module, so

we want to give it its own tag {quotation}● Let's create SetParameters method

Page 46: Extending CMS Made Simple

SetParameters()funcQon  SetParameters()

{$this-­‐>RegisterModulePlugin();$this-­‐>RestrictUnknownParams();$this-­‐>CreateParameter('quotaQon_id','null',$this-­‐>Lang('help_quotaQon_id'));$this-­‐>SetParameterType('quotaQon_id',  CLEAN_INT);$this-­‐>CreateParameter('author','anonymous',$this-­‐>Lang('help_author'));$this-­‐>SetParameterType('author',CLEAN_STRING);$this-­‐>CreateParameter('quotaQon','',$this-­‐>Lang('help_quotaQon'));$this-­‐>SetParameterType('quotaQon',CLEAN_STRING);$this-­‐>CreateParameter('submit');$this-­‐>SetParameterType('submit',CLEAN_STRING);}

funcQon  GetHelp(){return  $this-­‐>Lang('help');}

Page 47: Extending CMS Made Simple

Viewing Module Help

Page 48: Extending CMS Made Simple

OK, let's get serious.

● Need to create the form● Need to handle the inputs● This will be the module's default action● Create action.default.php

Page 49: Extending CMS Made Simple

action.default.php<?phpif  (!isset($gCms))  exit;

$smarty-­‐>assign('form_start',$this-­‐>CreateFormStart($id,  'default',  $returnid));

$smarty-­‐>assign('input_author',$this-­‐>CreateInputTextWithLabel($id,  'author',isset($params['author'])?$params['author']:'',  10,  80,  '',$this-­‐>Lang('Qtle_author')));

$smarty-­‐>assign('Qtle_quotaQon',$this-­‐>Lang('Qtle_quotaQon'));

$smarty-­‐>assign('input_quotaQon',$this-­‐>CreateTextArea(false,  $id,isset($params['quotaQon'])?html_enQty_decode($params['quotaQon'],ENT_QUOTES):'',  

'quotaQon'));

$smarty-­‐>assign('submit',$this-­‐>CreateInputSubmit($id,  'submit',  $this-­‐>Lang('submit')));

echo  $this-­‐>ProcessTemplate('user_form.tpl');?>

Page 50: Extending CMS Made Simple

user_form.tpl<div  class="quotaQon_form">

{$form_start}<div>{$input_author}</div><div>{$Qtle_quotaQon}<br  />{$input_quotaQon}</div><div>{$submit}</div></form>

</div>

Page 51: Extending CMS Made Simple

Add the tag to a page

Page 52: Extending CMS Made Simple

View the page

Page 53: Extending CMS Made Simple

Update our lang file

<?php$lang['friendlyname']='QuotaQon  Module';

$lang['Qtle_author']='QuotaQon  Author';$lang['Qtle_quotaQon']='QuotaQon';$lang['submit']='Submit';

$lang['help_quotaQon_id']='ID  for  a  specific  quotaQon';$lang['help_author']='QuotaQon  author';$lang['help_quotaQon']='QuotaQon  text';$lang['help']='This  module  is  for  the  presentaQon  of  quotaQons.';?>

Page 54: Extending CMS Made Simple

And check again

Page 55: Extending CMS Made Simple

Input validation

if  (isset($params['submit'])){if  (empty($params['author'])  ||  empty($params['quotaQon']))

{$smarty-­‐>assign('message',$this-­‐>Lang('error_empty_fields'));}

}

Added to top of action.default.php

Added to user_form.tpl

{if  isset($message)  &&  $message!=''}<div  class="error">{$message}</div>{/if}

Page 56: Extending CMS Made Simple

Try an empty submit

Page 57: Extending CMS Made Simple

Store to databaseif  (isset($params['submit']))

{if  (empty($params['author'])  ||  empty($params['quotaQon']))

{$smarty-­‐>assign('message',$this-­‐>Lang('error_empty_fi elds'));}

else{$db  =  $this-­‐>GetDb();$quotaQon_id  =  $db-­‐>GenID(cms_db_prefix().  'module_quotaQon_seq');$res  =  $db-­‐>Execute('insert  into  '.cms_db_prefi x().

'module_quotaQons  (quotaQon_id,author,quotaQon,submiRed_date)  values  (?,?,?,NOW())',array($quotaQon_id,$params['author'],$params['quotaQon']));

if  ($res  ===  false){$smarty-­‐>assign('message',$this-­‐>Lang('db_error',$db-­‐>ErrorMsg()));}

else{$smarty-­‐>assign('message',$this-­‐>Lang('added'));}

}}

Page 58: Extending CMS Made Simple

Test it – add a quotation

Page 59: Extending CMS Made Simple

action.display.php<?phpif  (!isset($gCms))  exit;

$db=$this-­‐>GetDb();$row  =  array();$res  =  $db-­‐>Execute('select  *  from  '.cms_db_prefix().

'module_quotaQons  order  by  rand()  limit  1');

if  ($res  &&  $row=$res-­‐>FetchRow()){$smarty-­‐>assign('quotaQon',$row);}

echo  $this-­‐>ProcessTemplate('display_quotaQon.tpl');?>

Page 60: Extending CMS Made Simple

display_quotation.tpl<dl>

<dd>{$quotaQon.quotaQon}</dd><dt>{$quotaQon.author}</dt>

</dl>

Page 61: Extending CMS Made Simple

Add the tag to page template

● Find a convenient spot● Add the tag:{QuotaQons  acQon='display'}

Page 62: Extending CMS Made Simple

Try it!

Page 63: Extending CMS Made Simple

2.0 Module API2.0  Module  Extensions:

Database:create_table($table,  $fields)create_index($table,  $name,  $field)drop_table($table)

Preference:  get($preference_name,  $default_value  =  '')set($preference_name,  $value)remove($preference_name  =  '')

Template:  get_list($template_type  =  '')get($template_type,  $template_name)get_from_file($template_name)set($template_type,  $template_name,  $content,  $default  =  null)delete($template_type  =  '',  $template_name  =  '')process_from_data(  $data  )process_from_database($template_type,  $template_name  =  '',  $id  =  '',  $return_id  =  '',  

$designaQon  =  '',  $cache_id  =  '')process($template_name,  $id  =  '',  $return_id  =  '',  $designaQon  =  '',  $cache_id  =  '')

Page 64: Extending CMS Made Simple

method.install.php<?phpif  (!isset($gCms))  exit;

$this-­‐>Database-­‐>create_table('module_quotaQons',  "quotaQon_id  I  KEY  AUTO,language  C(8),quotaQon  X,author  C(80),submiRer  C(80),submit_date  DT

");

$this-­‐>Database-­‐>create_index('module_quotaQons','Author',  'author');

$this-­‐>Template-­‐>set('summary',  'Default  Template',  $this-­‐>Template-­‐>get_from_file('orig_default_summary'));

$this-­‐>Preference-­‐>set('sort_by','author');

$this-­‐>Permission-­‐>create('Manage  QuotaQons'  );

?>

Page 65: Extending CMS Made Simple

2.0 Module API2.0 Module Extensions (Group 2)

Permission:create($permission_name, $extra_attr = '', $hierarchical = false, $table = '')check($permission_name, $extra_attr = '', $hierarchical = false, $table = '')remove($permission_name, $extra_attr = '')

Form:form_start($params = array(), $check_keys = false)form_end input_text input_hidden input_checkbox input_submitinput_select input_options input_textarea

Redirect:module_url

Url:link content_linkreturn_link

Page 66: Extending CMS Made Simple

action.default.php<?phpif  (!isset($gCms))  exit;

$smarty-­‐>assign('form_start',$this-­‐>Form-­‐>form_start(array('acQon'=>'default','return_id'=>$returnid))  );

$smarty-­‐>assign('input_author',$this-­‐>Form-­‐>input_text(array('id'=>$id,'name'=>  'author','value'=>

isset($params['author'])?$params['author']:'',  'size'=>10,'maxlength=>80,  'lable'=>'Qtle_author'))  );

$smarty-­‐>assign('Qtle_quotaQon',$this-­‐>Lang('Qtle_quotaQon'));

$smarty-­‐>assign('submit',$this-­‐>Form-­‐>input_submit('name'=>  'submit',  'value'=>'submit')));

echo  $this-­‐>Template-­‐>process_from_database('summary');?>

Page 67: Extending CMS Made Simple

2.0 Smarty Tags{has_permission  perm="Modify  Templates"}{/has_permission}

{tabs}{tab_content  name='users'}

{tab_header  name='users'}{/tab_header}

{/tab_content}{/tabs}

{tr}users{/tr}

Page 68: Extending CMS Made Simple

2.0 Module Smarty TagsBlocks:{mod_form}{/mod_form}{mod_formrow}{/mod_formrow}{mod_label}{/mod_label}{mod_select}{/mod_select}

FuncQons:{mod_checkbox}{mod_dropdown}{mod_helptext}{mod_hidden}{mod_lang}{mod_link}{mod_opQons}{mod_password}{mod_submit}{mod_template}{mod_textarea}{mod_textbox}{mod_validaQon_errors}

Page 69: Extending CMS Made Simple

2.0 Module Form{mod_validaQon_errors  for=$blog_post}

{mod_form  acQon=$form_acQon}{mod_label  name="blog_post[Qtle]"}Title{/mod_label}:<br  />{mod_textbox  name="blog_post[Qtle]"  value=$blog_post-­‐>Qtle  size="40"}{mod_label  name="blog_post[content]"}Post{/mod_label}:<br  />{mod_textarea  name="blog_post[content]"  value=$blog_post-­‐>content  cols="40"  

rows="10"  wysiwyg=true}<legend>{tr}Categories{/tr}</legend>{foreach  from=$categories  item='one_category'}

{assign  var=category_id  value=$one_category-­‐>id}{assign  var=category_name  value=$one_category-­‐>name}{mod_checkbox  name="blog_post[category][$category_id]"  

selected=$blog_post-­‐>in_category($category_id)}  {$category_name}<br  />{/foreach}

{mod_label  name="blog_post[status]"}{tr}Status{/tr}{/mod_label}:<br  />{mod_dropdown  name="blog_post[status]"  items=$cms_mapi_module-­‐>get_statuses()  

selected_value=$blog_post-­‐>status}

Page 70: Extending CMS Made Simple

2.0 Module Form (Part 2){mod_label  name='post_date_Month'}{tr}Post  Date{/tr}{/mod_label}:<br  />{html_select_date  prefix=$post_date_prefix  Qme=$blog_post-­‐>post_date-­‐

>Qmestamp()  start_year=2000  end_year=2020}  {html_select_Qme  prefix=$post_date_prefix  Qme=$blog_post-­‐>post_date-­‐>Qmestamp()}

{mod_hidden  name="blog_post[author_id]"  value=$blog_post-­‐>author_id}{mod_submit  name="submitpost"  value='Submit'  translate=true}  {if  $blog_post-­‐>id  gt  0}

{mod_hidden  name="blog_post_id"  value=$blog_post-­‐>id}{mod_submit  name="cancelpost"  value='Cancel'  translate=true}  

{/if}{mod_submit  name="submitpublish"  value='Publish'  translate=true}

{/mod_form}

Page 71: Extending CMS Made Simple

OK, let's add an admin panel

● First, we need to add a permission to control access

● This should be done in the installer● Steps:

● Change installer● Bump the module version number● Create the upgrade method

Page 72: Extending CMS Made Simple

method.install.php<?phpif  (!isset($gCms))  exit;$db  =  $this-­‐>GetDb();$dict  =  NewDataDicQonary(  $db  );

$fields="quotaQon_id  I  KEY,language  C(8),quotaQon  X,author  C(80),submiRer  C(80),submit_date  DT

";

$sqlarray  =  $dict-­‐>CreateTableSQL(  cms_db_prefix()."module_quotaQons",$fields);$dict-­‐>ExecuteSQLArray($sqlarray);

$db-­‐>CreateSequence(cms_db_prefix()."module_quotaQon_seq");$this-­‐>CreatePermission('Manage  QuotaQons',  'Manage  QuotaQons');?>

Page 73: Extending CMS Made Simple

method.upgrade.php<?phpif  (!isset($gCms))  exit;

switch($old_version){case  "0.1":

$this-­‐>CreatePermission('Manage  QuotaQons',  'Manage  QuotaQons');}

$this-­‐>Audit(  0,  $this-­‐>Lang('friendlyname'),  $this-­‐>Lang('upgraded',$this-­‐>GetVersion()));?>

Added to lang file:

$lang['upgraded']='Upgraded  to  version  %s';

Page 74: Extending CMS Made Simple

Perform the upgrade

Page 75: Extending CMS Made Simple

Now implement admin panel 1.x

● Add method to main module:

function HasAdmin(){return ($this->CheckPermission('Manage Quotations'));}

Page 76: Extending CMS Made Simple

action.defaultadmin.php<?phpif  (!isset($gCms))  exit;if  (!$this-­‐>CheckPermission('Manage  QuotaQons'))  exit;

$db=$this-­‐>GetDb();$rows  =  array();$res  =  $db-­‐>Execute('select  *  from  '.cms_db_prefix().'module_quotaQons  order  by  submit_date  desc');while  ($res  &&  $row=$res-­‐>FetchRow())

{$row['edit']  =  $this-­‐>CreateLink($id,  'admin_edit',  '',

$this-­‐>Lang('edit'),  array('quotaQon_id'=>$row['quotaQon_id']));$row['delete']  =  $this-­‐>CreateLink($id,  'admin_delete',  '',

$this-­‐>Lang('delete'),  array('quotaQon_id'=>$row['quotaQon_id']));array_push($rows,$row);}

$smarty-­‐>assign('quotaQons',$rows);echo  $this-­‐>ProcessTemplate('admin_display_list.tpl');?>

Page 77: Extending CMS Made Simple

admin_display_list.tpl{if  isset($message)  &&  $message!=''}<div  class="pagewarning">{$message}</div>{/if}<table>{foreach  from=$quotaQons  item=q}

<tr><td>{$q.quotaQon_id}</td><td>{$q.quotaQon|truncate:80}</td><td>{$q.author}</td><td>{$q.edit}</td><td>{$q.delete}</td>

</tr>{/foreach}</table>

Page 78: Extending CMS Made Simple

Admin View

Page 79: Extending CMS Made Simple

action.admin_delete.php<?phpif  (!isset($gCms))  exit;if  (!$this-­‐>CheckPermission('Manage  QuotaQons'))  exit;

if  (isset($params['quotaQon_id'])){$db  =  $this-­‐>GetDb();$res  =  $db-­‐>Execute('delete  from  '.cms_db_prefix().

'module_quotaQons  where  quotaQon_id=?',array($params['quotaQon_id']));

$smarty-­‐>assign('message',$this-­‐>Lang('quotaQon_deleted'));}

echo  $this-­‐>DoAcQon('defaultadmin',  $id,  $params,  $returnid);?>

Page 80: Extending CMS Made Simple

Delete Quotation

Page 81: Extending CMS Made Simple

Be kind to users

● Add some safety – modify default admin link to delete

● And add to language file$lang['really_delete']='Really  delete  this  quotaQon  by  %s?';

$row['delete']  =  $this-­‐>CreateLink($id,  'admin_delete',  '',$this-­‐>Lang('delete'),  array('quotaQon_id'=>$row['quotaQon_id']),$this-­‐>Lang('really_delete',$row['author']));

Page 82: Extending CMS Made Simple

That's better

Page 83: Extending CMS Made Simple

Let admin edit quotations

● We can re-use the form template● Just need to create the admin-side logic● Note that the logic is not identical, since

we'll be updating the database rather than adding a new record

Page 84: Extending CMS Made Simple

action.admin_edit.php<?phpif  (!isset($gCms))  exit;if  (!$this-­‐>CheckPermission('Manage  QuotaQ ons'))  exit;$db  =  $this-­‐>GetDb();

if  (isset($params['submit'])){if  (empty($params['author'])  ||  empty($params['quotaQ on']))

{$smarty-­‐>assign('message',$this-­‐>Lang('error_empty_fi elds'));}

else{$res  =  $db-­‐>Execute('update  '.cms_db_prefi x().'module_quotaQons  set  author=?,quotaQon=?  where  quotaQon_id=?',

array($params['author'],$params['quotaQ on'],$params['quotaQon_id']));if  ($res  ===  false)

{$smarty-­‐>assign('message',$this-­‐>Lang('db_error',$db-­‐>ErrorMsg()));}

else{$smarty-­‐>assign('message',$this-­‐>Lang('quotaQ on_edited'));}

return  $this-­‐>DoAcQon('defaultadmin',  $id,  $params,  $returnid);}

}else

Page 85: Extending CMS Made Simple

action.admin_edit.php, cont{$res  =  $db-­‐>Execute('select  *  from  '.cms_db_prefi x().'module_quotaQons  where  quotaQon_id=?',

array($params['quotaQon_id']));if  ($res  &&  $row=$res-­‐>FetchRow())

{$params['author']=$row['author'];$params['quotaQon']=$row['quotaQon'];}

}$smarty-­‐>assign('form_start',$this-­‐>CreateFormStart($id,  'admin_edit',  $returnid));

$smarty-­‐>assign('input_author',$this-­‐>CreateInputTextWithLabel($id,  'author',isset($params['author'])?$params['author']:'',  10,  80,  '',$this-­‐>Lang('Qtle_author')));

$smarty-­‐>assign('Qtle_quotaQon',$this-­‐>Lang('Qtle_quotaQon'));

$smarty-­‐>assign('input_quotaQon',$this-­‐>CreateTextArea(false,  $id,isset($params['quotaQon'])?html_enQty_decode($params['quotaQon'],ENT_QUOTES):'',  'quotaQon'));

$smarty-­‐>assign('submit',$this-­‐>CreateInputHidden($id,'quotaQ on_id',$params['quotaQon_id']).$this-­‐>CreateInputSubmit($id,  'submit',  $this-­‐>Lang('submit')));

echo  $this-­‐>ProcessTemplate('user_form.tpl');?>

Page 86: Extending CMS Made Simple

Editing

Page 87: Extending CMS Made Simple

And edited

Page 88: Extending CMS Made Simple

action.defaultadmin.php 2.0if  (!isset($gCms))  die("Can't  call  acQons  directly!");

if  (  !$this-­‐>Permission-­‐>check('Modify  Site  Preferences')  )CmsResponse::redirect('index.php?'.CMS_SECURE_PARAM_NAME.'='.

$_SESSION[CMS_USER_KEY]);

if  (isset($params['submitprefs'])  ){

if(  !CmsAcl::check_core_permission('Modify  Site  Preferences',  $user)  )die('permission  denied');

$password_minlength  =  (int)coalesce_key($params,'password_minlength',6);$this-­‐>Preference-­‐>set('password_minlength',$password_minlength);

}$smarty-­‐>assign('groups',cms_orm('CmsGroup')-­‐>find_all());$smarty-­‐>assign('users',cms_orm('CmsUser')-­‐>find_all());

$smarty-­‐>assign('acQve_tab_for_modules',    coalesce_key($params,'selected_tab','users'));$smarty-­‐>assign('form_acQon','defaultadmin');

echo  $this-­‐>Template-­‐>process('defaultadmin.tpl',$id,$return_id);

Page 89: Extending CMS Made Simple

defaultadmin.tpl 2.0{has_permission  perm="Modify  Templates"}

<div  style="text-­‐align:  right;  width:  80%;"><a  href="listmodtemplates.php"  Qtle="{tr}modify_templates{/tr}">{tr}modify_templates{/tr}</a></div><br/>{/has_permission}

{tabs}{has_permission  perm='Modify  Users'}

{tab_content  name='users'}{tab_header  name='users'}{tr}users{/tr}{/tab_header}{mod_template  template='users_tab.tpl'}

{/tab_content}{/has_permission}

{has_permission  perm='Modify  Site  Preferences'}{tab_content  name='prefs'}

{tab_header  name='prefs'}{tr}preferences{/tr}{/tab_header}{mod_template  template='prefs_tab.tpl'}

{/tab_content}{/has_permission}

{/tabs}