Add an extra field to the Gallery module

The Gallery module for CMS Made Simple has two fields where you can enter a title and comment for any image. You can place these in your template using {$image->title} and {$image->comment}. Ideally, you should be able to add field definitions, like in the News module. This would make it much more flexible, giving you more Smarty variables to work with, but this would require some hefty module modification. Instead, I will show you how to add a single extra field to the Gallery module, and if you require more, you have something to work off.

Download the Gallery module (1.2.1 at the time of writing) from:
http://dev.cmsmadesimple.org/projects/gallery

The files we will be making modifications to are:

Gallery/method.install.php
Gallery/action.default.php
Gallery/action.do_editgallery.php
Gallery/action.editgallery.php
Gallery/lang/en_US.php
Gallery/templates/editgallery.tpl

Making the modifications

Lines that need to be added or modified are highlighted.

Gallery/method.install.php

If you would like to make a re-packaged version of the Gallery module that you can freshly install with the modifications in place, you will need to edit this file. Here, we add another field to the database table called “extra” set to VARCHAR(255).

$flds = "
    fileid I KEY AUTO,
    filename C(255),
    filepath C(255),
    filedate " . CMS_ADODB_DT . ",
    fileorder I,
    active I,
    defaultfile I,
    galleryid I KEY,
    title C(255),
    comment X,
    extra C(255)
";

If you have already installed the Gallery module, you can alter the table in the database directly, for example:

ALTER TABLE cms_module_gallery ADD extra VARCHAR(255) NOT NULL;

Make sure the prefix matches your CMSMS installation.

Gallery/lang/en_US.php

Add the name of the field to the language file. If you ever decide to change the name of the field that is viewable to the administrator, you can just change this line and you won’t have to make any other code changes.

$lang['comment'] = 'Comment';
$lang['extra'] = 'Extra';

Gallery/action.default.php

                $rec->comment = ($galeryfiles && array_key_exists($key, $galeryfiles)) ? $galeryfiles[$key]['comment'] : '';
                $rec->extra = ($galeryfiles && array_key_exists($key, $galeryfiles)) ? $galeryfiles[$key]['extra'] : '';

Gallery/action.do_editgallery.php

                else
                {
                    $searchwords .= ' ' . $filetitle . ' ' . $params['filecomment'][$key];
                    $query = "UPDATE " . cms_db_prefix() . "module_gallery SET title=?, comment=?, extra=?, fileorder=? WHERE fileid = ?";
                    $result = $db->Execute($query, array($filetitle, $params['filecomment'][$key], $params['fileextra'][$key], $sortkey, $key));
                }
            }
            elseif ( $filetitle != "#dir" )
            {
                $searchwords .= ' ' . $filetitle . ' ' . $params['filecomment'][$key];
                $query = "UPDATE " . cms_db_prefix() . "module_gallery SET title=?, comment=?, extra=? WHERE fileid = ?";
                $result = $db->Execute($query, array($filetitle, $params['filecomment'][$key], $params['fileextra'][$key], $key));
            }

Gallery/action.editgallery.php

            $onerow->comment = $this->CreateTextArea(0, $id, $file['comment'], 'filecomment[' . $file['fileid'] . ']', 'fake" style="width:400px; height:4em;', '', '', '', '40', '4');  // class filled with fake and style-info to overrule the theme-css
            $onerow->extra = $this->CreateInputText($id, 'fileextra[' . $file['fileid'] . ']', $file['extra'], 30, 100);

Adding an extra field will increase the width of the Gallery module administration interface. Depending on your administration theme, this might be too wide. To accommodate for this, you can change the width style of the Comment textarea, for example, width:200px;.

Gallery/templates/editgallery.tpl

    <table id="gtable" cellspacing="0" class="pagetable">
        <thead>
        <tr>
            <th class="pageicon">&nbsp;</th>
            <th>{$item}</th>
            <th>{$title}</th>
            <th>{$comment}</th>
            <th>{$extra}</th>
            <th>{$filedate}</th>
            <th class="pageicon">{$cover}</th>
            <th class="pageicon">{$active}</th>
        </tr>
        </thead>
        <tbody>
    {foreach from=$items item=entry}
        {cycle values="row1,row2" assign=rowclass}
        <tr id="{$entry->fileid}" class="{$rowclass}">
            <td>&nbsp;</td>
            <td><div style="width:96px; height:72px; background: url({$entry->thumburl}) no-repeat center; overflow:hidden; cursor:default;">&nbsp;</div></td>
            <td{if $entry->isdir} colspan="2"{/if}>{$entry->filename}<br />{$entry->title}</td>
            {if !$entry->isdir}<td>{$entry->comment}</td>{/if}
            <td>{$entry->extra}</td>
            <td>{$entry->filedate}</td>
            <td class="pagepos" style="text-align:center">{$entry->defaultlink}</td>
            <td class="pagepos" style="text-align:center">{$entry->activelink}</td>
        </tr>
    {/foreach}
        </tbody>
    </table>

Further down in the same file:

    $this->smarty->assign('comment', $this->Lang('comment'));
    $this->smarty->assign('extra', $this->Lang('extra'));

Download

For your convenience, I have re-packaged the Gallery module (1.2.1) with an extra field. You can download it here:

Download: Gallery module with extra field 1.2.1 (zip, 320.24 kB)
Posted in Web development | Tagged , , , , | Leave a comment

HTTP Front-end

HTTP Front-end is quite an old project of mine (started in 2005). It allows you to go behind the scenes, to see exactly what is happening in a HTTP transaction.

By sending a customised HTTP request, you can see how a certain web application will behave. This makes HTTP Front-end a great tool for debugging and finding weak spots or vulnerabilities in web applications.

Take the following code for example:

<?php
if (isset($_POST['foo'])) {
    echo htmlspecialchars($_POST['foo']);
}
?>

<form action="test.php" method="post">
<input type="text" name="foo" />
<input type="submit" name="submit" value="Submit" />
</form>

You may think this is a pretty securely typed snippet of code. isset() is used to check if the variable is set, and htmlspecialchars() makes sure any special characters are converted to HTML entities.

If you typed “bar” into the text box and hit Submit, your web browser (client) would send a HTTP request to the server that looks something like this:

POST /test.php HTTP/1.0
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
Connection: close

foo=bar

The response body contains:

bar
...

Everything is fine, right? Let’s take a look at a specially crafted HTTP request sent with HTTP Front-end.

POST /test.php HTTP/1.0
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 9
Connection: close

foo[]=bar

Now we get the following response body:

<br />
<b>Warning</b>: htmlspecialchars() expects parameter 1 to be string, array given in <b>/var/www/html/test.php</b> on line <b>4</b><br />
...

By sending an array instead of a string, this has resulted in full path disclosure. Full path disclosure by itself is not a big worry, but it is good coding practice to make sure this cannot occur, even if the display_errors directive is enabled. Let’s secure the code:

<?php
if (isset($_POST['foo']) && is_string($_POST['foo'])) {
    echo htmlspecialchars($_POST['foo']);
}
?>

<form action="test.php" method="post">
<input type="text" name="foo" />
<input type="submit" name="submit" value="Submit" />
</form>

is_string() is added to make sure the variable is of the correct type.

You may access HTTP Front-end here:

http://www.benmalen.com/projects/http-front-end/

Posted in Web development | Tagged , , | 1 Comment

Additional Smarty variables for CMSMS CGBlog

I have released a plugin for CMS Made Simple, for use with with the CGBlog module.

What does this do?

CGBlog (1.3.2) is a great module, but unfortunately, it does not provide a great deal of Smarty variables to use. This plugin will retrieve information from the summary, detail, or archive view, and place that information into easy-to-access Smarty variables. You can then use these variables anywhere in the page template or the module templates themselves.

How do I use it?

Call this plugin at the very top of your page template using:

{blog_info}

The following Smarty variables will be set if the information is found:

$blog_category_id (for example, 1)
$blog_category_name (for example, Animals)
$blog_archive_year (for example, 2010)
$blog_archive_month (for example, 04)
$blog_archive_month_full (for example, April)

Note: These Smarty variables are not escaped so they can be used for string comparison logic. $blog_category_name may contain special HTML characters, which would cause invalid markup, so be sure to escape it when outputting, for example, {$blog_category_name|cms_escape}.

What about the article name? This is already available in the CGBlog detail template. This also applies to the News module. To place this variable into your page template, add the following code to the top of the CGBlog detail template:

{assign var='blog_article_name' value=$entry->title|cms_escape}

The very first line of your page template should contain:

{process_pagedata}

This assumes $config['process_whole_template'] = false; in config.php (this is the default value in CMSMS 1.7.1).

You can now access $blog_article_name in the <head> section of your page template.

Because of the way CMSMS processes the page template, if you wish to access $blog_article_name in the <body> section of your page template, you will need to do a little extra.

Add this to the first line of your page template:
{content assign='mycontent'}

Then replace your original {content} tag with {$mycontent}.

You should now be able to access $blog_article_name in the <body> section of your page template.

Further reading:
http://calguy1000.com/Blogs/4/60.html
http://forum.cmsmadesimple.org/index.php/topic,30475.45.html

What parameters does it take?

  • (optional) match – String in CSV format, containing other CGBlog modules to check for (case-insensitive). This is useful if you are running multiple instances of the CGBlog module under different names (i.e. you have duplicated/renamed the CGBlog module). If not specified, it will default to ‘CGBlog’. For example: {blog_info match='CGBlog, RGuide, FGuide'}

Download

Download: Blog Info 1.1 (zip, 2.5 kB)
Posted in Web development | Tagged , , | 1 Comment