<?php
// $Id: pnadmin.php,v 1.1.1.1 2002/09/15 22:26:15 root Exp $
// ----------------------------------------------------------------------
// POST-NUKE Content Management System
// Copyright (C) 2002 by the PostNuke Development Team.
// http://www.postnuke.com/
// ----------------------------------------------------------------------
// Based on:
// PHP-NUKE Web Portal System - http://phpnuke.org/
// Thatware - http://thatware.org/
// ----------------------------------------------------------------------
// LICENSE
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License (GPL)
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WIthOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// To read the license please visit http://www.gnu.org/copyleft/gpl.html
// ----------------------------------------------------------------------
// Original Author of file: Jim McDonald
// Purpose of file:  Template administration display functions
// ----------------------------------------------------------------------

/**
 * the main administration function
 * This function is the default function, and is called whenever the
 * module is initiated without defining arguments.  As such it can
 * be used for a number of things, but most commonly it either just
 * shows the module menu and returns or calls whatever the module
 * designer feels should be the default function (often this is the
 * view() function)
 */
function template_admin_main()
{
    // Create output object - this object will store all of our output so that
    // we can return it easily when required
    $output = new pnHTML();

    // Security check - important to do this as early as possible to avoid
    // potential security holes or just too much wasted processing.  For the
    // main function we want to check that the user has at least edit privilege
    // for some item within this component, or else they won't be able to do
    // anything and so we refuse access altogether.  The lowest level of access
    // for administration depends on the particular module, but it is generally
    // either 'edit' or 'delete'
    if (!pnSecAuthAction(0, 'Template::Item', '::', ACCESS_EDIT)) {
        $output->Text(_TEMPLATENOAUTH);
        return $output->GetOutput();
    }

    // Add menu to output - it helps if all of the module pages have a standard
    // menu at their head to aid in navigation
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->Text(template_adminmenu());
    $output->SetInputMode(_PNH_PARSEINPUT);

    // Return the output that has been generated by this function
    return $output->GetOutput();
}

/**
 * add new item
 * This is a standard function that is called whenever an administrator
 * wishes to create a new module item
 */
function template_admin_new()
{
    // Create output object - this object will store all of our output so that
    // we can return it easily when required
    $output = new pnHTML();

    // Security check - important to do this as early as possible to avoid
    // potential security holes or just too much wasted processing
    if (!pnSecAuthAction(0, 'Template::Item', '::', ACCESS_ADD)) {
        $output->Text(_TEMPLATENOAUTH);
        return $output->GetOutput();
    }

    // Add menu to output - it helps if all of the module pages have a standard
    // menu at their head to aid in navigation
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->Text(template_adminmenu());
    $output->SetInputMode(_PNH_PARSEINPUT);

    // Title - putting a title ad the head of each page reminds the user what
    // they are doing
    $output->Title(_ADDTEMPLATE);

    // Start form - note the use of pnModURL() to create the recipient URL of
    // this form.  All URLs should be generated through pnModURL() to ensure
    // compatibility with future versions of PostNuke
    $output->FormStart(pnModURL('Template', 'admin', 'create'));

    // Add an authorisation ID - this adds a hidden field in the form that
    // contains an authorisation ID.  The authorisation ID is very important in
    // preventing certain attacks on the website
    $output->FormHidden('authid', pnSecGenAuthKey());

    // Start the table that holds the information to be input.  Note how each
    // item in the form is kept logically separate in the code; this helps to
    // see which part of the code is responsible for the display of each item,
    // and helps with future modifications
    $output->TableStart();

    // Name
    $row = array();
    $output->SetOutputMode(_PNH_RETURNOUTPUT);
    $row[] = $output->Text(pnVarPrepForDisplay(_TEMPLATENAME));
    $row[] = $output->FormText('name', '', 32, 32);
    $output->SetOutputMode(_PNH_KEEPOUTPUT);
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->TableAddrow($row, 'left');
    $output->SetInputMode(_PNH_PARSEINPUT);
    $output->Linebreak(2);

    // Number
    $row = array();
    $output->SetOutputMode(_PNH_RETURNOUTPUT);
    $row[] = $output->Text(pnVarPrepForDisplay(_TEMPLATENUMBER));
    $row[] = $output->FormText('number', '', 5, 5);
    $output->SetOutputMode(_PNH_KEEPOUTPUT);
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->TableAddrow($row, 'left');
    $output->SetInputMode(_PNH_PARSEINPUT);
    $output->Linebreak(2);

    $output->TableEnd();

    // End form
    $output->Linebreak(2);
    $output->FormSubmit(_TEMPLATEADD);
    $output->FormEnd();

    // Return the output that has been generated by this function
    return $output->GetOutput();
}

/**
 * This is a standard function that is called with the results of the
 * form supplied by template_admin_new() to create a new item
 * @param 'name' the name of the item to be created
 * @param 'number' the number of the item to be created
 */
function template_admin_create($args)
{
    // Get parameters from whatever input we need.  All arguments to this
    // function should be obtained from pnVarCleanFromInput(), getting them
    // from other places such as the environment is not allowed, as that makes
    // assumptions that will not hold in future versions of PostNuke
    list($name,
         $number) = pnVarCleanFromInput('name',
                                        'number');

    // Admin functions of this type can be called by other modules.  If this
    // happens then the calling module will be able to pass in arguments to
    // this function through the $args parameter.  Hence we extract these
    // arguments *after* we have obtained any form-based input through
    // pnVarCleanFromInput().
    extract($args);

    // Confirm authorisation code.  This checks that the form had a valid
    // authorisation code attached to it.  If it did not then the function will
    // proceed no further as it is possible that this is an attempt at sending
    // in false data to the system
    if (!pnSecConfirmAuthKey()) {
        pnSessionSetVar('errormsg', _BADAUTHKEY);
        pnRedirect(pnModURL('Template', 'admin', 'view'));
        return true;
    }

    // Notable by its absence there is no security check here.  This is because
    // the security check is carried out within the API function and as such we
    // do not duplicate the work here

    // Load API.  All of the actual work for the creation of the new item is
    // done within the API, so we need to load that in before we can do
    // anything.  If the API fails to load an appropriate error message is
    // posted and the function returns
    if (!pnModAPILoad('Template', 'admin')) {
        pnSessionSetVar('errormsg', _LOADFAILED);
        return $output->GetOutput();
    }

    // The API function is called.  Note that the name of the API function and
    // the name of this function are identical, this helps a lot when
    // programming more complex modules.  The arguments to the function are
    // passed in as their own arguments array
    $tid = pnModAPIFunc('Template',
                        'admin',
                        'create',
                        array('name' => $name,
                              'number' => $number));

    // The return value of the function is checked here, and if the function
    // suceeded then an appropriate message is posted.  Note that if the
    // function did not succeed then the API function should have already
    // posted a failure message so no action is required
    if ($tid != false) {
        // Success
        pnSessionSetVar('statusmsg', _TEMPLATECREATED);
    }

    // This function generated no output, and so now it is complete we redirect
    // the user to an appropriate page for them to carry on their work
    pnRedirect(pnModURL('Template', 'admin', 'view'));

    // Return
    return true;
}

/**
 * modify an item
 * This is a standard function that is called whenever an administrator
 * wishes to modify a current module item
 * @param 'tid' the id of the item to be modified
 */
function template_admin_modify($args)
{
    // Get parameters from whatever input we need.  All arguments to this
    // function should be obtained from pnVarCleanFromInput(), getting them
    // from other places such as the environment is not allowed, as that makes
    // assumptions that will not hold in future versions of PostNuke
    list($tid,
         $objectid)= pnVarCleanFromInput('tid',
                                         'objectid');

                           
    // Admin functions of this type can be called by other modules.  If this
    // happens then the calling module will be able to pass in arguments to
    // this function through the $args parameter.  Hence we extract these
    // arguments *after* we have obtained any form-based input through
    // pnVarCleanFromInput().
    extract($args);

    // At this stage we check to see if we have been passed $objectid, the
    // generic item identifier.  This could have been passed in by a hook or
    // through some other function calling this as part of a larger module, but
    // if it exists it overrides $tid
    //
    // Note that this module couuld just use $objectid everywhere to avoid all
    // of this munging of variables, but then the resultant code is less
    // descriptive, especially where multiple objects are being used.  The
    // decision of which of these ways to go is up to the module developer
    if (!empty($objectid)) {
        $tid = $objectid;
    }                       

    // Create output object - this object will store all of our output so that
    // we can return it easily when required
    $output = new pnHTML();

    // Load API.  Note that this is loading the user API, that is because the
    // user API contains the function to obtain item information which is the
    // first thing that we need to do.  If the API fails to load an appropriate
    // error message is posted and the function returns
    if (!pnModAPILoad('Template', 'user')) {
        $output->Text(_LOADFAILED);
        return $output->GetOutput();
    }

    // The user API function is called.  This takes the item ID which we
    // obtained from the input and gets us the information on the appropriate
    // item.  If the item does not exist we post an appropriate message and
    // return
    $item = pnModAPIFunc('Template',
                         'user',
                         'get',
                         array('tid' => $tid));

    if ($item == false) {
        $output->Text(_TEMPLATENOSUCHITEM);
        return $output->GetOutput();
    }

    // Security check - important to do this as early as possible to avoid
    // potential security holes or just too much wasted processing.  However,
    // in this case we had to wait until we could obtain the item name to
    // complete the instance information so this is the first chance we get to
    // do the check
    if (!pnSecAuthAction(0, 'Template::Item', "$item[name]::$tid", ACCESS_EDIT)) {
        $output->Text(_TEMPLATENOAUTH);
        return $output->GetOutput();
    }

    // Add menu to output - it helps if all of the module pages have a standard
    // menu at their head to aid in navigation
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->Text(template_adminmenu());
    $output->SetInputMode(_PNH_PARSEINPUT);

    // Title - putting a title ad the head of each page reminds the user what
    // they are doing
    $output->Title(_EDITTEMPLATE);

    // Start form - note the use of pnModURL() to create the recipient URL of
    // this form.  All URLs should be generated through pnModURL() to ensure
    // compatibility with future versions of PostNuke
    $output->FormStart(pnModURL('Template', 'admin', 'update'));

    // Add an authorisation ID - this adds a hidden field in the form that
    // contains an authorisation ID.  The authorisation ID is very important in
    // preventing certain attacks on the website
    $output->FormHidden('authid', pnSecGenAuthKey());

    // Add a hidden variable for the item id.  This needs to be passed on to
    // the update function so that it knows which item for which item to carry
    // out the update
    $output->FormHidden('tid', pnVarPrepForDisplay($tid));

    // Start the table that holds the information to be input.  Note how each
    // item in the form is kept logically separate in the code; this helps to
    // see which part of the code is responsible for the display of each item,
    // and helps with future modifications
    $output->TableStart();

    // Name
    $row = array();
    $output->SetOutputMode(_PNH_RETURNOUTPUT);
    $row[] = $output->Text(pnVarPrepForDisplay(_TEMPLATENAME));
    $row[] = $output->FormText('name', pnVarPrepForDisplay($item['name']), 32, 32);
    $output->SetOutputMode(_PNH_KEEPOUTPUT);
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->TableAddrow($row, 'left');
    $output->SetInputMode(_PNH_PARSEINPUT);
    $output->Linebreak(2);

    // Number
    $row = array();
    $output->SetOutputMode(_PNH_RETURNOUTPUT);
    $row[] = $output->Text(pnVarPrepForDisplay(_TEMPLATENUMBER));
    $row[] = $output->FormText('number', pnVarPrepForDisplay($item['number']), 5, 5);
    $output->SetOutputMode(_PNH_KEEPOUTPUT);
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->TableAddrow($row, 'left');
    $output->SetInputMode(_PNH_PARSEINPUT);
    $output->Linebreak(2);

    $output->TableEnd();

    // End form
    $output->Linebreak(2);
    $output->FormSubmit(_TEMPLATEUPDATE);
    $output->FormEnd();
    
    // Return the output that has been generated by this function
    return $output->GetOutput();
}


/**
 * This is a standard function that is called with the results of the
 * form supplied by template_admin_modify() to update a current item
 * @param 'tid' the id of the item to be updated
 * @param 'name' the name of the item to be updated
 * @param 'number' the number of the item to be updated
 */
function template_admin_update($args)
{
    // Get parameters from whatever input we need.  All arguments to this
    // function should be obtained from pnVarCleanFromInput(), getting them
    // from other places such as the environment is not allowed, as that makes
    // assumptions that will not hold in future versions of PostNuke
    list($tid,
         $objectid,
         $name,
         $number) = pnVarCleanFromInput('tid',
                                        'objectid',
                                        'name',
                                        'number');

    // User functions of this type can be called by other modules.  If this
    // happens then the calling module will be able to pass in arguments to
    // this function through the $args parameter.  Hence we extract these
    // arguments *after* we have obtained any form-based input through
    // pnVarCleanFromInput().
    extract($args);
                            
    // At this stage we check to see if we have been passed $objectid, the
    // generic item identifier.  This could have been passed in by a hook or
    // through some other function calling this as part of a larger module, but
    // if it exists it overrides $tid
    //
    // Note that this module couuld just use $objectid everywhere to avoid all
    // of this munging of variables, but then the resultant code is less
    // descriptive, especially where multiple objects are being used.  The
    // decision of which of these ways to go is up to the module developer
    if (!empty($objectid)) {
        $tid = $objectid;
    }                       

    // Confirm authorisation code.  This checks that the form had a valid
    // authorisation code attached to it.  If it did not then the function will
    // proceed no further as it is possible that this is an attempt at sending
    // in false data to the system
    if (!pnSecConfirmAuthKey()) {
        pnSessionSetVar('errormsg', _BADAUTHKEY);
        pnRedirect(pnModURL('Template', 'admin', 'view'));
        return true;
    }

    // Notable by its absence there is no security check here.  This is because
    // the security check is carried out within the API function and as such we
    // do not duplicate the work here

    // Load API.  All of the actual work for the update of the new item is done
    // within the API, so we need to load that in before we can do anything.
    // If the API fails to load an appropriate error message is posted and the
    // function returns
    if (!pnModAPILoad('Template', 'admin')) {
        pnSessionSetVar('errormsg', _LOADFAILED);
        return $output->GetOutput();
    }

    // The API function is called.  Note that the name of the API function and
    // the name of this function are identical, this helps a lot when
    // programming more complex modules.  The arguments to the function are
    // passed in as their own arguments array.
    //
    // The return value of the function is checked here, and if the function
    // suceeded then an appropriate message is posted.  Note that if the
    // function did not succeed then the API function should have already
    // posted a failure message so no action is required
    if(pnModAPIFunc('Template',
                    'admin',
                    'update',
                    array('tid' => $tid,
                          'name' => $name,
                          'number' => $number))) {
        // Success
        pnSessionSetVar('statusmsg', _TEMPLATEUPDATED);
    }

    // This function generated no output, and so now it is complete we redirect
    // the user to an appropriate page for them to carry on their work
    pnRedirect(pnModURL('Template', 'admin', 'view'));

    // Return
    return true;
}

/**
 * delete item
 * This is a standard function that is called whenever an administrator
 * wishes to delete a current module item.  Note that this function is
 * the equivalent of both of the modify() and update() functions above as
 * it both creates a form and processes its output.  This is fine for
 * simpler functions, but for more complex operations such as creation and
 * modification it is generally easier to separate them into separate
 * functions.  There is no requirement in the PostNuke MDG to do one or the
 * other, so either or both can be used as seen appropriate by the module
 * developer
 * @param 'tid' the id of the item to be deleted
 * @param 'confirmation' confirmation that this item can be deleted
 */
function template_admin_delete($args)
{
    // Get parameters from whatever input we need.  All arguments to this
    // function should be obtained from pnVarCleanFromInput(), getting them
    // from other places such as the environment is not allowed, as that makes
    // assumptions that will not hold in future versions of PostNuke
    list($tid,
         $objectid,
         $confirmation) = pnVarCleanFromInput('tid',
                                              'objectid',
                                              'confirmation');


    // User functions of this type can be called by other modules.  If this
    // happens then the calling module will be able to pass in arguments to
    // this function through the $args parameter.  Hence we extract these
    // arguments *after* we have obtained any form-based input through
    // pnVarCleanFromInput().
    extract($args);

     // At this stage we check to see if we have been passed $objectid, the
     // generic item identifier.  This could have been passed in by a hook or
     // through some other function calling this as part of a larger module, but
     // if it exists it overrides $tid
     //
     // Note that this module couuld just use $objectid everywhere to avoid all
     // of this munging of variables, but then the resultant code is less
     // descriptive, especially where multiple objects are being used.  The
     // decision of which of these ways to go is up to the module developer
     if (!empty($objectid)) {
         $tid = $objectid;
     }                     

    // Load API.  Note that this is loading the user API, that is because the
    // user API contains the function to obtain item information which is the
    // first thing that we need to do.  If the API fails to load an appropriate
    // error message is posted and the function returns
    if (!pnModAPILoad('Template', 'user')) {
        $output->Text(_LOADFAILED);
        return $output->GetOutput();
    }

    // The user API function is called.  This takes the item ID which we
    // obtained from the input and gets us the information on the appropriate
    // item.  If the item does not exist we post an appropriate message and
    // return
    $item = pnModAPIFunc('Template',
                         'user',
                         'get',
                         array('tid' => $tid));

    if ($item == false) {
        $output->Text(_TEMPLATENOSUCHITEM);
        return $output->GetOutput();
    }

    // Security check - important to do this as early as possible to avoid
    // potential security holes or just too much wasted processing.  However,
    // in this case we had to wait until we could obtain the item name to
    // complete the instance information so this is the first chance we get to
    // do the check
    if (!pnSecAuthAction(0, 'Template::Item', "$item[name]::$tid", ACCESS_DELETE)) {
        $output->Text(_TEMPLATENOAUTH);
        return $output->GetOutput();
    }

    // Check for confirmation. 
    if (empty($confirmation)) {
        // No confirmation yet - display a suitable form to obtain confirmation
        // of this action from the user

        // Create output object - this object will store all of our output so
        // that we can return it easily when required
        $output = new pnHTML();

        // Add menu to output - it helps if all of the module pages have a
        // standard menu at their head to aid in navigation
        $output->SetInputMode(_PNH_VERBATIMINPUT);
        $output->Text(template_adminmenu());
        $output->SetInputMode(_PNH_PARSEINPUT);

        // Title - putting a title ad the head of each page reminds the user
        // what they are doing
        $output->Title(_DELETETEMPLATE);

        // Add confirmation to output.  Note that this uses a pnHTML helper
        // function to produce the requested confirmation in a standard
        // fashion.  This not only cuts down on code within the module but
        // allows it to be altered in future without the module developer
        // having to worry about it
        $output->ConfirmAction(_CONFIRMTEMPLATEDELETE,
                               pnModURL('Template',
                                        'admin',
                                        'delete'),
                               _CANCELTEMPLATEDELETE,
                               pnModURL('Template',
                                        'admin',
                                        'view'),
                               array('tid' => $tid));

        // Return the output that has been generated by this function
        return $output->GetOutput();
    }

    // If we get here it means that the user has confirmed the action

    // Confirm authorisation code.  This checks that the form had a valid
    // authorisation code attached to it.  If it did not then the function will
    // proceed no further as it is possible that this is an attempt at sending
    // in false data to the system
    if (!pnSecConfirmAuthKey()) {
        pnSessionSetVar('errormsg', _BADAUTHKEY);
        pnRedirect(pnModURL('Template', 'admin', 'view'));
        return true;
    }

    // Load API.  All of the actual work for the deletion of the item is done
    // within the API, so we need to load that in before before we can do
    // anything.  If the API fails to load an appropriate error message is
    // posted and the function returns
    if (!pnModAPILoad('Template', 'admin')) {
        $output->Text(_LOADFAILED);
        return $output->GetOutput();
    }

    // The API function is called.  Note that the name of the API function and
    // the name of this function are identical, this helps a lot when
    // programming more complex modules.  The arguments to the function are
    // passed in as their own arguments array.
    //
    // The return value of the function is checked here, and if the function
    // suceeded then an appropriate message is posted.  Note that if the
    // function did not succeed then the API function should have already
    // posted a failure message so no action is required
    if (pnModAPIFunc('Template',
                     'admin',
                     'delete',
                     array('tid' => $tid))) {
        // Success
        pnSessionSetVar('statusmsg', _TEMPLATEDELETED);
    }

    // This function generated no output, and so now it is complete we redirect
    // the user to an appropriate page for them to carry on their work
    pnRedirect(pnModURL('Template', 'admin', 'view'));
    
    // Return
    return true;
}

/**
 * view items
 */
function template_admin_view()
{
    // Get parameters from whatever input we need.  All arguments to this
    // function should be obtained from pnVarCleanFromInput(), getting them
    // from other places such as the environment is not allowed, as that makes
    // assumptions that will not hold in future versions of PostNuke
    $startnum = pnVarCleanFromInput('startnum');

    // Create output object - this object will store all of our output so that
    // we can return it easily when required
    $output = new pnHTML();

    if (!pnSecAuthAction(0, 'Template::', '::', ACCESS_EDIT)) {
        $output->Text(_TEMPLATENOAUTH);
        return $output->GetOutput();
    }

    // Add menu to output - it helps if all of the module pages have a standard
    // menu at their head to aid in navigation
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->Text(template_adminmenu());
    $output->SetInputMode(_PNH_PARSEINPUT);

    // Title - putting a title ad the head of each page reminds the user what
    // they are doing
    $output->Title(_VIEWTEMPLATE);

    // Load API.  Note that this is loading the user API, that is because the
    // user API contains the function to obtain item information which is the
    // first thing that we need to do.  If the API fails to load an appropriate
    // error message is posted and the function returns
    if (!pnModAPILoad('Template', 'user')) {
        $output->Text(_LOADFAILED);
        return $output->GetOutput();
    }

    // The user API function is called.  This takes the number of items
    // required and the first number in the list of all items, which we
    // obtained from the input and gets us the information on the appropriate
    // items.
    $items = pnModAPIFunc('Template',
                          'user',
                          'getall',
                          array('startnum' => $startnum,
                                'numitems' => pnModGetVar('Template',
                                                          'itemsperpage')));

    // Start output table
    $output->TableStart('',
                        array(_TEMPLATENAME,
                              _TEMPLATENUMBER,
                              _TEMPLATEOPTIONS),
                        3);

    foreach ($items as $item) {

        $row = array();

        if (pnSecAuthAction(0, 'Template::', "$item[name]::$item[tid]", ACCESS_READ)) {
    
            // Name and number.  Note that unlike the user function we do not
            // censor the text that is being displayed.  This is so the
            // administrator can see the text as exists in the database rather
            // than the munged output version
            $row[] = $item['name'];
            $row[] = $item['number'];

            // Options for the item.  Note that each item has the appropriate
            // levels of authentication checked to ensure that it is suitable
            // for display

            $options = array();
            $output->SetOutputMode(_PNH_RETURNOUTPUT);
            if (pnSecAuthAction(0, 'Template::', "$item[name]::$item[tid]", ACCESS_EDIT)) {
                $options[] = $output->URL(pnModURL('Template',
                                                   'admin',
                                                   'modify',
                                                   array('tid' => $item['tid'])),
                                          _EDIT);
                if (pnSecAuthAction(0, 'Template::', "$item[name]::$item[tid]", ACCESS_DELETE)) {
                    $options[] = $output->URL(pnModURL('Template',
                                                       'admin',
                                                       'delete',
                                                       array('tid' => $item['tid'])),
                                              _DELETE);
                }
            }

            $options = join(' | ', $options);
            $output->SetInputMode(_PNH_VERBATIMINPUT);
            $row[] = $output->Text($options);
            $output->SetOutputMode(_PNH_KEEPOUTPUT);
            $output->TableAddRow($row);
            $output->SetInputMode(_PNH_PARSEINPUT);
        }
    }
    $output->TableEnd();

    // Call the pnHTML helper function to produce a pager in case of there
    // being many items to display.
    //
    // Note that this function includes another user API function.  The
    // function returns a simple count of the total number of items in the item
    // table so that the pager function can do its job properly
    $output->Pager($startnum,
                    pnModAPIFunc('Template', 'user', 'countitems'),
                    pnModURL('Template',
                             'admin',
                             'view',
                            array('startnum' => '%%')),
                    pnModGetVar('Template', 'itemsperpage'));


    // Return the output that has been generated by this function
    return $output->GetOutput();
}


/**
 * This is a standard function to modify the configuration parameters of the
 * module
 */
function template_admin_modifyconfig()
{
    // Create output object - this object will store all of our output so that
    // we can return it easily when required
    $output = new pnHTML();

    // Security check - important to do this as early as possible to avoid
    // potential security holes or just too much wasted processing

    if (!pnSecAuthAction(0, 'Template::', '::', ACCESS_ADMIN)) {
        $output->Text(_TEMPLATENOAUTH);
        return $output->GetOutput();
    }

    // Add menu to output - it helps if all of the module pages have a standard
    // menu at their head to aid in navigation
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->Text(template_adminmenu());
    $output->SetInputMode(_PNH_PARSEINPUT);

    // Title - putting a title ad the head of each page reminds the user what
    // they are doing
    $output->Title(_TEMPLATEMODIFYCONFIG);

    // Start form - note the use of pnModURL() to create the recipient URL of
    // this form.  All URLs should be generated through pnModURL() to ensure
    // compatibility with future versions of PostNuke
    $output->FormStart(pnModURL('Template', 'admin', 'updateconfig'));


    // Add an authorisation ID - this adds a hidden field in the form that
    // contains an authorisation ID.  The authorisation ID is very important in
    // preventing certain attacks on the website
    $output->FormHidden('authid', pnSecGenAuthKey());

    // Start the table that holds the information to be modified.  Note how
    // each item in the form is kept logically separate in the code; this helps
    // to see which part of the code is responsible for the display of each
    // item, and helps with future modifications
    $output->TableStart();

    // Bold
    $row = array();
    $output->SetOutputMode(_PNH_RETURNOUTPUT);
    $row[] = $output->Text(pnVarPrepForDisplay(_TEMPLATEDISPLAYBOLD));
    $row[] = $output->FormCheckbox('bold', pnModGetVar('Template', 'bold'));
    $output->SetOutputMode(_PNH_KEEPOUTPUT);
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->TableAddrow($row, 'left');
    $output->SetInputMode(_PNH_PARSEINPUT);
    $output->Linebreak(2);

    // Number of items to display per page
    $row = array();
    $output->SetOutputMode(_PNH_RETURNOUTPUT);
    $row[] = $output->Text(pnVarPrepForDisplay(_TEMPLATEITEMSPERPAGE));
    $row[] = $output->FormText('itemsperpage', pnModGetVar('Template', 'itemsperpage'), 3, 3);
    $output->SetOutputMode(_PNH_KEEPOUTPUT);
    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->TableAddrow($row, 'left');
    $output->SetInputMode(_PNH_PARSEINPUT);
    $output->Linebreak(2);

    $output->TableEnd();

    // End form
    $output->Linebreak(2);
    $output->FormSubmit(_TEMPLATEUPDATE);
    $output->FormEnd();
    
    // Return the output that has been generated by this function
    return $output->GetOutput();
}

/**
 * This is a standard function to update the configuration parameters of the
 * module given the information passed back by the modification form
 */
function template_admin_updateconfig()
{
    // Get parameters from whatever input we need.  All arguments to this
    // function should be obtained from pnVarCleanFromInput(), getting them
    // from other places such as the environment is not allowed, as that makes
    // assumptions that will not hold in future versions of PostNuke
    $bold = pnVarCleanFromInput('bold');

    // Confirm authorisation code.  This checks that the form had a valid
    // authorisation code attached to it.  If it did not then the function will
    // proceed no further as it is possible that this is an attempt at sending
    // in false data to the system
    if (!pnSecConfirmAuthKey()) {
        pnSessionSetVar('errormsg', _BADAUTHKEY);
        pnRedirect(pnModURL('Template', 'admin', 'view'));
        return true;
    }

    // Update module variables.  Note that depending on the HTML structure used
    // to obtain the information from the user it is possible that the values
    // might be unset, so it is important to check them all and assign them
    // default values if required
    if (!isset($bold)) {
        $bold = 0;
    }
    pnModSetVar('template', 'bold', $bold);

    if (!isset($itemsperpage)) {
        $itemsperpage = 10;
    }
    pnModSetVar('template', 'itemsperpage', $itemsperpage);

    // This function generated no output, and so now it is complete we redirect
    // the user to an appropriate page for them to carry on their work
    pnRedirect(pnModURL('Template', 'admin', 'view'));

    // Return
    return true;
}
/**
 * Main administration menu
 */
function template_adminmenu()
{
    // Create output object - this object will store all of our output so that
    // we can return it easily when required
    $output = new pnHTML();

    // Display status message if any.  Note that in future this functionality
    // will probably be in the theme rather than in this menu, but this is the
    // best place to keep it for now
    $output->Text(pnGetStatusMsg());
    $output->Linebreak(2);

    // Start options menu
    $output->TableStart(_TEMPLATE);
    $output->SetOutputMode(_PNH_RETURNOUTPUT);

    // Menu options.  These options are all added in a single row, to add
    // multiple rows of options the code below would just be repeated
    $columns = array();
    $columns[] = $output->URL(pnModURL('Template',
                                        'admin',
                                        'new'),
                              _NEWTEMPLATE); 
    $columns[] = $output->URL(pnModURL('Template',
                                        'admin',
                                        'view'),
                              _VIEWTEMPLATE); 
    $columns[] = $output->URL(pnModURL('Template',
                                        'admin',
                                        'modifyconfig'),
                              _EDITTEMPLATECONFIG); 
    $output->SetOutputMode(_PNH_KEEPOUTPUT);

    $output->SetInputMode(_PNH_VERBATIMINPUT);
    $output->TableAddRow($columns);
    $output->SetInputMode(_PNH_PARSEINPUT);

    $output->TableEnd();

    // Return the output that has been generated by this function
    return $output->GetOutput();
}

?>