Below is an updated version of the required management module:
@MODULE
The module will automatically create the needed database table when it is first run. The default table name is: prefix_favorite_links
Module name: Favorite Links
Description: Management for favorite links snippet
//<?php
/**
* Favorite Links Module
* Brian Stanback
* 2007/04/12
* Version 0.0.5
* Compatible with MODx 0.9.5
*
* Loosely Based off of Friends List Module by Garry Nutting
*/
$_lang['action_title'] = 'Links Listing';
$_lang['add_link'] = 'Add Link';
$_lang['cancel'] = 'Cancel';
$_lang['delete'] = 'Delete';
$_lang['edit'] = 'Edit';
$_lang['error_unfilled'] = 'Please fill all required fields';
$_lang['form_message'] = '<p>To add a new link, enter link details in the form on the left and click the "Add Link" button. Tags should be separated by a comma and a space, eg. tag1, tag2, tag3. For an explanation and more information on XFN, please visit <a href="http://gmpg.org/xfn/">http://gmpg.org/xfn/</a></p><br /><p>To update a link select the link from the list, click the \'Edit\' button, and update the details in the form on the left.</p><br /><p>To remove a link select the link from the list and click the \'Delete\' button.</p>';
$_lang['form_title'] = 'Add/Update a Link';
$_lang['favlinks_title'] = 'Title';
$_lang['favlinks_url'] = 'URL';
$_lang['favlinks_summ'] = 'Summary';
$_lang['favlinks_rating'] = 'Rating';
$_lang['favlinks_tags'] = 'Tags';
$_lang['favlinks_xfn'] = 'XFN';
$_lang['filter'] = 'Filter';
$_lang['go'] = 'Go';
$_lang['link_added'] = 'The link has been added.';
$_lang['link_deleted'] = 'The link has been deleted.';
$_lang['link_updated'] = 'The link has been updated.';
$_lang['module_title'] = 'Favorite Links';
$_lang['no_records'] = 'No links have been added.';
$_lang['update_link'] = 'Update Link';
$basePath = $modx->config['base_path'];
$siteURL = $modx->config['site_url'];
$tb_prefix = $modx->db->config['table_prefix'];
// Include grid control class
include_once($basePath . 'manager/includes/controls/datagrid.class.php');
// Get configuration values
global $manager_theme;
$table = $modx->getFullTableName('favorite_links');
// Handle request data
$link_id = (isset($_POST['link_id'])) ? intval($_POST['link_id']) : '';
$title = (isset($_POST['title'])) ? $_POST['title'] : '';
$url = (isset($_POST['url']) && $_POST['url'] != 'http://') ? $_POST['url'] : 'http://';
$summ = (isset($_POST['summ'])) ? $_POST['summ'] : '';
$tags = (isset($_POST['tags'])) ? $_POST['tags'] : '';
$xfn = (isset($_POST['xfn'])) ? $_POST['xfn'] : '';
$rating = (isset($_POST['rating'])) ? $_POST['rating'] : '';
// Determine what action to take
if (isset($_POST['edit']) && $link_id > 0)
{
$action = 'edit';
}
elseif (isset($_POST['delete']) && $link_id > 0)
{
$action = 'delete';
}
elseif (isset($_POST['action']))
{
$action = $_POST['action'];
}
// Check for required fields
if (($action == 'add' || $action == 'update') && (!$title || !$url))
$error = $_lang['error_unfilled'] . ' (*)';
if ($action == 'update' && !isset($error))
{
$tags = ':' . str_replace(', ', ':', $tags) . ':';
$fields = array(
'title' => $modx->db->escape($title),
'url' => $modx->db->escape($url),
'summ' => $modx->db->escape($summ),
'tags' => $modx->db->escape($tags),
'xfn' => $modx->db->escape($xfn),
'rating' => $modx->db->escape($rating)
);
$modx->db->update($fields, $table, 'id=' . $link_id);
$msg .= $_lang['link_updated'];
$link_id = ''; $title = ''; $url = 'http://'; $summ = ''; $tags = ''; $xfn = ''; $rating = '';
}
elseif ($action == 'delete')
{
$modx->db->delete($table, 'id=' . $link_id);
$msg .= $_lang['link_deleted'];
$link_id = '';
}
elseif ($action == 'add' && !isset($error))
{
$tags = ':' . str_replace(', ', ':', $tags) . ':';
$fields = array(
'title' => $modx->db->escape($title),
'url' => $modx->db->escape($url),
'summ' => $modx->db->escape($summ),
'tags' => $modx->db->escape($tags),
'xfn' => $modx->db->escape($xfn),
'rating' => $modx->db->escape($rating),
'added' => time()
);
$modx->db->insert($fields, $table);
$msg .= $_lang['link_added'];
$link_id = ''; $title = ''; $url = 'http://'; $summ = ''; $tags = ''; $xfn = ''; $rating = '';
}
if ($action == 'edit')
{
$result = $modx->db->select('*', $table, 'id="' . $link_id . '"');
$row = $modx->db->getRow($result);
$title = $row['title'];
$url = $row['url'];
$summ = $row['summ'];
$tags = str_replace(':', ', ', trim($row['tags'], ':'));
$xfn = $row['xfn'];
$rating = $row['rating'];
}
if (!function_exists('checkLinksTable'))
{
/**
* Create the table if it does not exist
*/
function checkLinksTable($table, &$errorMsg)
{
global $modx;
$sql = "CREATE TABLE IF NOT EXISTS " . $table . " (" .
"`id` int(11) NOT NULL auto_increment PRIMARY KEY, " .
"`title` varchar(255) NOT NULL, " .
"`url` varchar(255) NOT NULL, " .
"`summ` text, " .
"`tags` varchar(255), " .
"`rating` float(2), " .
"`xfn` varchar(64), " .
"`added` char(10)" .
")";
if (!$modx->db->query($sql))
$errorMsg .= "<p class=\"error\">Error creating table {$table}!</p>\n";
}
}
checkLinksTable($table, $errorMsg);
$filter = "";
if ($_POST['filter'])
{
$q = $modx->db->escape($_POST['filter']);
$filter .= "(url LIKE '%$q%' OR title LIKE '%$q%' OR summ LIKE '%$q%')";
}
if ($_POST['tag'])
{
$q = $modx->db->escape($_POST['tag']);
if ($filter != "") $filter .= " AND ";
$filter .= "(tags LIKE '%:$q:%')";
}
$linksQuery = $modx->db->select('*', $table, $filter, 'added DESC');
// Page header
$output .= '
<html>
<head>
<link rel="stylesheet" type="text/css" href="media/style/' . $manager_theme . '/style.css" />
<style type="text/css">
.topdiv {
border: 0;
}
.subdiv {
border: 0;
}
li {
list-style:none;
}
.tplbutton {
text-align: right;
}
#bttn .bttnheight {
height: 25px !important;
padding: 0px;
padding-top: 6px;
float: left;
vertical-align: middle !important;
}
ul.sortableList {
padding-left: 20px;
margin: 0px;
width: 300px;
font-family: Arial, sans-serif;
}
ul.sortableList li {
font-weight: bold;
cursor: move;
color: grey;
padding: 2px 2px;
margin: 2px 0px;
border: 1px solid #000000;
background-image: url("media/style/' . $manager_theme . '/images/bg/grid_hdr.gif");
background-repeat: repeat-x;
}
#bttn .bttnheight {
height: 25px !important;
padding: 0px;
padding-top: 6px;
float: left;
vertical-align: middle !important;
}
#bttn a{
cursor: default !important;
font: icon !important;
color: black !important;
border: 0px !important;
padding: 5px 5px 7px 5px!important;
white-space: nowrap !important;
vertical-align: middle !important;
background: transparent !important;
text-decoration: none;
}
#bttn a:hover {
border: 1px solid darkgreen !important;
padding: 4px 4px 6px 4px !important;
background-image: url("media/style/' . $manager_theme . '/images/bg/button_dn.gif") !important;
text-decoration: none;
}
#bttn a img {
vertical-align: middle !important;
}
.go a {
cursor: default !important;
font: icon !important;
color: black !important;
border: 0px !important;
padding: 5px 5px 7px 5px !important;
white-space: nowrap !important;
vertical-align: middle !important;
background: transparent;
text-decoration: none;
}
.go a:hover {
border: 1px solid darkgreen !important;
padding: 4px 4px 6px 4px !important;
background: url("media/style/' . $manager_theme . '/images/bg/button_dn.gif");
text-decoration: none;
}
.go a img {
vertical-align: middle !important;
}
.form_message {
font-size: 85%;
}
.gridItem, .gridAltItem {
font-sizE: 95%;
}
td {
font-size: 90%;
}
</style>
</head>
<body>
<div class="subTitle" id="bttn">
<span class="right"><img src="media/style/' . $manager_theme . '/images/_tx_.gif" width="1" height="5"><br />' . $_lang['module_title'] . '</span>
<div class="bttnheight"><a id="Button5" onclick="document.location.href=\'index.php?a=106\';">
<img src="media/style/' . $manager_theme . '/images/icons/close.gif" alt="" /> Close Favorite Links Manager</a>
</div>
<div class="bttnheight"><a id="Button5" onclick="document.location.href=\'index.php?a=106\';">
<img src="media/style' . $manager_theme . '/images/icons/link_add.png" alt="" /> Import / Export</a>
</div>
<div class="stay"></div>
</div>
<div class="sectionHeader">' . $_lang['form_title'] . '</div>
<div class="sectionBody">
';
$output .= '
<table><tr><td style="width: 60%;" valign="top">
<form name="details" method="post" action="">
<input type="hidden" name="action" value="' . (($action == 'edit') ? 'update' : 'add') . '" />
<input type="hidden" name="link_id" value="' . $link_id . '" />
<table border="0" cellspacing="0" cellpadding="1" width="95%">
<tr><td>' . $_lang['favlinks_title'] . ': * </td><td><input type="text" name="title" value="' . $title . '" style="width: 100%;" /></td></tr>
<tr><td>' . $_lang['favlinks_url'] . ': * </td><td><input type="text" name="url" value="' . $url . '" style="width: 100%;" /></td></tr>
<tr><td valign="top">' . $_lang['favlinks_summ'] . ': </td><td><textarea name="summ" rows="2" style="width: 100%; height: auto;">' . $summ . '</textarea></td></tr>
<tr><td>' . $_lang['favlinks_tags'] . ': </td><td><input type="text" name="tags" value="' . $tags . '" style="width: 100%;" /></td></tr>
<tr><td>' . $_lang['favlinks_xfn'] . ': </td><td><input type="text" name="xfn" value="' . $xfn . '" style="width: 100%;" /></td></tr>
<tr><td>' . $_lang['favlinks_rating'] . ': </td><td><input type="text" name="rating" value="' . $rating . '" style="width: 100%;" /></td></tr>
<tr><td> </td><td><br /><input type="submit" name="postform" value="' . (($action == 'edit') ? $_lang['update_link'] : $_lang['add_link']) . '" /></td></tr>
</table>
</form>
</td><td valign="top" class="form_message">' . $_lang['form_message'] . '</td></tr></table>';
// Output any messages or errors
$output .= '<div>';
$output .= '<p class="warning">' . $msg . '</p>';
if (isset($error)) {
$output .= '<p class="warning">' . $error . '</p>';
}
$output .= '</div>';
$output .= '</div>
<div class="sectionHeader">' . $_lang['action_title'] . '</div>
<div class="sectionBody">
<form name="links" method="post" action="">
<div style="float: right;">' . $_lang['filter'] . ': <select name="tag" onchange="links.submit()"><option value="">-</option>';
// Get tags from database, populating array
$result = $modx->db->select('DISTINCT tags', $table);
$tags = array();
while ($row = $modx->db->getRow($result))
{
foreach (explode(':', trim($row['tags'], ':')) as $tag) $tags[$tag]++;
}
ksort($tags);
foreach ($tags as $tag => $occurances)
{
// Output tags
if ($tag == $_POST['tag'])
$output .= "<option selected=\"selected\" value=\"$tag\">$tag</option>";
else
$output .= "<option value=\"$tag\">$tag</option>";
}
$output .= '
</select> <input type="text" name="filter" size="20" value="' . $_POST['filter'] . '" /> <input type="submit" value="' . $_lang['go'] . '" /></div>
<input type="submit" value="' . $_lang['edit'] . '" name="edit" />
<input type="submit" value="' . $_lang['delete'] . '" name="delete" /><br /><br />';
// Render links grid
$grid = new DataGrid('', $linksQuery);
$grid->noRecordMsg = $_lang['no_records'];
$grid->cssClass = "grid";
$grid->columnHeaderClass = "gridHeader";
$grid->itemClass = "gridItem";
$grid->altItemClass = "gridAltItem";
$grid->columns = " ," . $_lang['favlinks_title'] . "," . $_lang['favlinks_url'] . "," . $_lang['favlinks_rating'];
$grid->colTypes = "template:<input type='radio' value='[+id+]' name='link_id' />";
$grid->colWidths = "5%,35%,35%,15%";
$grid->fields = "template,title,url,rating";
$output .= $grid->render();
$output .= '</form>';
$output .= '</div></body></html>';
return $output;
The
FavoriteLinksForm snippet (which implements bookmarklet and frontend link posting) should be fully compatible with this updated version.