Extending CMS Made Simple
Upcoming SlideShare
Loading in...5

Extending CMS Made Simple



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

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



Total Views
Views on SlideShare
Embed Views



3 Embeds 6

https://tasks.crowdflower.com 3
http://www.techgig.com 2
http://www.slashdocs.com 1



Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • Very nice and clear tutorials...
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

Extending CMS Made Simple Extending CMS Made Simple Presentation Transcript

  • Extending CMS Made Simple Presented by Jeff Bosch and Samuel Goldstein
  • Jeff Bosch ● Core Development Team member ● B.S. in Computer Science ● Started A & J Progamming in 2007 for custom web programming and implementation
  • 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
  • OK, enough of that ● Why extend CMS Made Simple? ● Add functionality ● Make things easier for your clients ● More money for you ● Fame, fortune, glory
  • Ways to Extend CMSMS ● Core, core modules, and Smarty ● User-Defined Tags ● Tags (a.k.a. Plugins) ● Modules
  • 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
  • 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 √
  • 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
  • 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>
  • 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'}
  • Add an .htaccess file <IfModule  mod_rewrite.c> RewriteEngine  on #Sub-­‐dir  e.g:  /cmsms RewriteBase  / RewriteCond  %{REQUEST_FILENAME}  !-­‐f  [NC] RewriteCond  %{REQUEST_FILENAME}  !-­‐d  [NC] RewriteRule  ^sitemap.xml$  index.php?page=sitemap&showtemplate=false  [L] </IfModule>
  • 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>
  • 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.
  • postfilter.registeredtrademarker.php <?php funcQon  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; } ?>
  • Using the Filter ● Save your filter in the plugins directory ● In the Admin, be sure to clear your cache! ● View your site.
  • You® filte®ed ®esults
  • 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!
  • UDT “pagecounter” global  $gCms; $db  =  $gCms-­‐>GetDb(); $count  =  $db-­‐>GetOne('select  count(*)  from  '.cms_db_prefi x().'content  where  acQve=1'); $smarty  =  $gCms-­‐>GetSmarty(); $smarty-­‐>assign('page_count','Total  pages:  '.$count);
  • 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}
  • Viewing your page
  • 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
  • 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
  • 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.”
  • Exercise II, cont. UDT global  $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);
  • Exercise II, cont. Template. {process_pagedata} <!DOCTYPE  html  PUBLIC  "-­‐//W3C//DTD  XHTML  1.0  TransiQ onal//EN"   "hRp://www.w3.org/TR/xhtml1/DTD/xhtml1-­‐transiQ onal.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>
  • 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);}
  • Hour II How's my timing?
  • Getting Started with Modules ● For the 1.x series, several ways to get started ● From scratch ● Skeleton module ● Module Maker ● MCFactory ● etc
  • Skeleton Module ● Download from Forge or Module Manager ● Has simple functionality ● install/upgrade ● admin panel ● database routines ● form API calls
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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.
  • 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
  • Layout on filesystem
  • 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
  • Step 1. Preparation ● Create directories ● $CMS_ROOT/modules/Quotations ● Quotations/templates ● Quotations/lang ● Create base files: ● Quotations.module.php ● lang/en_US.php
  • Quotations.module.php <?php class  QuotaQons  extends  CMSModule { funcQon  GetName() { return  'QuotaQons'; } funcQon  GetFriendlyName() { return  $this-­‐>Lang('friendlyname'); } funcQon  IsPluginModule() { return  true; } funcQon  GetVersion() { return  '0.1'; } } ?>
  • lang/en_US.php <?php $lang['friendlyname']='QuotaQon  Module'; ?>
  • Database Schema ● We'll probably need ● Unique ID ● Quotation text ● Quotation author ● Submission date
  • method.install.php <?php if  (!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"); ?>
  • Install it
  • 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
  • SetParameters() funcQon  SetParameters() { $this-­‐>RegisterModulePlugin(); $this-­‐>RestrictUnknownParams(); $this-­‐>CreateParameter('quotaQon_id','null',$this-­‐>Lang('help_quotaQ on_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'); }
  • Viewing Module Help
  • 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
  • action.default.php <?php if  (!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'); ?>
  • 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>
  • Add the tag to a page
  • View the page
  • 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.'; ?>
  • And check again
  • Input validation Added to top of action.default.php if  (isset($params['submit'])) { if  (empty($params['author'])  ||  empty($params['quotaQ on'])) { $smarty-­‐>assign('message',$this-­‐>Lang('error_empty_fi elds')); } } Added to user_form.tpl {if  isset($message)  &&  $message!=''}<div  class="error">{$message}</div>{/if}
  • Try an empty submit
  • Store to database if  (isset($params['submit'])) { if  (empty($params['author'])  ||  empty($params['quotaQ on'])) { $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')); } } }
  • Test it – add a quotation
  • action.display.php <?php if  (!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_quotaQ on.tpl'); ?>
  • display_quotation.tpl <dl> <dd>{$quotaQon.quotaQon}</dd> <dt>{$quotaQon.author}</dt> </dl>
  • Add the tag to page template ● Find a convenient spot ● Add the tag: {QuotaQons  acQon='display'}
  • Try it!
  • 2.0 Module API 2.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  =  '',  $designaQ on  =  '',  $cache_id  =  '')
  • method.install.php <?php if  (!isset($gCms))  exit; $this-­‐>Database-­‐>create_table('module_quotaQ ons',  " quotaQon_id  I  KEY  AUTO, language  C(8), quotaQon  X, author  C(80), submiRer  C(80), submit_date  DT "); $this-­‐>Database-­‐>create_index('module_quotaQ ons','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'  ); ?>
  • 2.0 Module API 2.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_submit input_select input_options input_textarea Redirect: module_url Url: link content_linkreturn_link
  • action.default.php <?php if  (!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'); ?>
  • 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}
  • Blocks: 2.0 Module Smarty Tags {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}
  • 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}
  • 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_Q me  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}
  • 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
  • method.install.php <?php if  (!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'); ?>
  • method.upgrade.php <?php if  (!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';
  • Perform the upgrade
  • Now implement admin panel 1.x ● Add method to main module: function HasAdmin() { return ($this->CheckPermission('Manage Quotations')); }
  • action.defaultadmin.php <?php if  (!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'); ?>
  • 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>
  • Admin View
  • action.admin_delete.php <?php if  (!isset($gCms))  exit; if  (!$this-­‐>CheckPermission('Manage  QuotaQons'))  exit; if  (isset($params['quotaQon_id'])) { $db  =  $this-­‐>GetDb(); $res  =  $db-­‐>Execute('delete  from  '.cms_db_prefi x(). 'module_quotaQons  where  quotaQon_id=?', array($params['quotaQon_id'])); $smarty-­‐>assign('message',$this-­‐>Lang('quotaQ on_deleted')); } echo  $this-­‐>DoAcQon('defaultadmin',  $id,  $params,  $returnid); ?>
  • Delete Quotation
  • Be kind to users ● Add some safety – modify default admin link to delete $row['delete']  =  $this-­‐>CreateLink($id,  'admin_delete',  '', $this-­‐>Lang('delete'),  array('quotaQon_id'=>$row['quotaQon_id']), $this-­‐>Lang('really_delete',$row['author'])); ● And add to language file $lang['really_delete']='Really  delete  this  quotaQon  by  %s?';
  • That's better
  • 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
  • action.admin_edit.php <?php if  (!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
  • 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_quotaQ on',$this-­‐>CreateTextArea(false,  $id, isset($params['quotaQon'])?html_enQty_decode($params['quotaQ on'],ENT_QUOTES):'',  'quotaQ on')); $smarty-­‐>assign('submit', $this-­‐>CreateInputHidden($id,'quotaQ on_id',$params['quotaQ on_id']). $this-­‐>CreateInputSubmit($id,  'submit',  $this-­‐>Lang('submit'))); echo  $this-­‐>ProcessTemplate('user_form.tpl'); ?>
  • Editing
  • And edited
  • action.defaultadmin.php 2.0 if  (!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')-­‐>fi nd_all()); $smarty-­‐>assign('users',cms_orm('CmsUser')-­‐>fi nd_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);
  • 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}