The system currently:

  1. Detects whenever a page mentions its name
  1. Detects whenever a page stops mentioning its name
  1. Allows admins to create "link groups"
  1. Allows managers to move links between "link groups" with ease
  1. Allows managers to assign weights to individual links
  1. Renders "link groups" in a variety of styles
  1. Allows content of linked pages to be embedded within the calling page

The Data Model


you may have to replace wikka_ with your used prefix --NilsLindenberg

CREATE TABLE `wikka_link_manager_groups` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL default '',
  `description` mediumtext,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `name` (`name`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;

CREATE TABLE `wikka_link_manager_links` (
  `link_id` int(11) NOT NULL auto_increment,
  `this_tag` varchar(75) NOT NULL default '',
  `page_tag` varchar(75) NOT NULL default '',
  `link_group_id` int(11) default NULL,
  `weight` int(11) default NULL,
  PRIMARY KEY  (`link_id`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;


The PHP Code


I've found that it's convenient to keep a "common settings" file in the actions directory to store variables shared between actions and handlers. In my setup, I call it "common.ini.php". Here is the code:

<?php
// all
$base_url = 'http://localhost/wikka/wikka.php';
$page_var = 'wakka';

// linkmanager.php
$table_link_groups = $this->config['table_prefix'] . 'link_manager_groups';
$table_links = $this->config['table_prefix'] . 'link_manager_links';
$table_pages = $this->config['table_prefix'] . 'pages';
?>


Next up is the "linkmanager.php" file, which should also be saved in the actions directory...

<?php

/**
* admin interface
* {{linkmanager}}
*
* display options
* {{lmshow}} -- (default) returns all groups as definition list (dl) of links (using the default "box" style)
* {{lmshow style="CSS STYLE"}} -- replace CSS STYLE with box, event, or table for different looks
* {{lmshow group="Group One"}} -- show the group labeled "Group One" as dl of links
* {{lmshow group="Group One" embed="all"}} -- embed the entire body of every link in this page
* {{lmshow group="Group One" embed="Overview"}} -- embed section with heading "Overview" of every link in this page
*/


include('actions/common.ini.php');

$is_admin = $this->IsAdmin();
$has_access = $this->HasAccess('write');

if ($has_access)
{
    if (isset($_POST['update_links']))
    {
        mysql_query("DELETE FROM $table_links WHERE this_tag = '$this->tag'");
        $links_to_move = isset($_POST['selected_links']) ? $_POST['selected_links'] : array();
        if (isset($_POST['link_weights']))
        {
            foreach ($_POST['link_weights'] as $page_tag => $link_weight)
            {
                if (empty($link_weight)) $link_weight = 'NULL';
                if (isset($links_to_move[$page_tag]))
                {
                    $link_group_id =  $_POST['group_select'];
                    unset($links_to_move[$page_tag]);
                }
                else
                {
                    $link_group_id = isset($_POST['link_group_ids']) ? $_POST['link_group_ids'][$page_tag] : '';
                }
                mysql_query("INSERT INTO $table_links (this_tag, page_tag, link_group_id, weight) VALUES ('$this->tag', '$page_tag', $link_group_id, $link_weight)");
            }
        }
        if (count($links_to_move) && $_POST['group_select'] != 'None')
        {
            foreach ($links_to_move as $page_tag => $junk)
            {
                mysql_query("INSERT INTO $table_links (this_tag, page_tag, link_group_id) VALUES ('$this->tag', '$page_tag', $_POST[group_select])");
            }
        }
    }
}

if ($is_admin)
{
    if (isset($_GET['delete_group']))
    {
        mysql_query("DELETE FROM $table_link_groups WHERE id = $_GET[group_id]");
    }

    if (isset($_POST['add_new_group']))
    {
        $new_group_name = mysql_real_escape_string($_POST['group_name']);
        $new_group_description = mysql_real_escape_string($_POST['group_description']);
        mysql_query("INSERT INTO $table_link_groups (name, description) VALUES ('$new_group_name', '$new_group_description')");
    }

    if (isset($_POST['update_groups']))
    {
        $group_names = $_POST['group_names'];
        $group_descriptions = $_POST['group_descriptions'];
        foreach ($group_names as $group_id => $group_name)
        {
            $group_description = mysql_real_escape_string($group_descriptions[$group_id]);
            mysql_query("UPDATE $table_link_groups SET name = '$group_name', description = '$group_description' WHERE id = $group_id");
        }
    }
}

if ($has_access)
{
    echo "<form id=\"add_link_group\" action=\"$base_url\" method=\"post\">";
    echo "<input type=\"hidden\" name=\"$page_var\" value=\"$this->tag\">";
    if ($is_admin)
    {
?>
<h3 style="border-bottom: 1px solid #aaa;">Manage Link Groups</h3>
<div style="background: #fafafa">
<div style="background: #eef"><table cellpadding="5" id="add_link_group">
<tr><th>Name</th><th>Description</th></tr>
<tr>
<td valign="top"><input type="text" name="group_name" value=""></td>
<td><textarea cols="40" rows="2" name="group_description"></textarea></td>
</tr>
<tr><td colspan="3" align="right"><input type="submit" name="add_new_group" value="Add Group"></td></tr>
</table></div>
<?php
    }
    $sql = "SELECT id, name, description FROM $table_link_groups ORDER BY id DESC";
    $result = mysql_query($sql);
    if ($result && mysql_num_rows($result))
    {
        $group_select = '<select name="group_select"><option value="none">None</option>';
        $manage_groups = '<table cellpadding="5" id="edit_link_groups"><tr><th>Name</th><th>Description</th><th align="center">Actions</th></tr>';
        while ($row = mysql_fetch_array($result))
        {
            $groups[$row['id']] = $row['name'];
            $group_select .= "<option value=\"$row[id]\">$row[name]</option>";
            $delete = "<a href=\"$base_url?$page_var=$this->tag&delete_group=1&group_id=$row[id]\">Delete</a>";
            $manage_groups .= "<tr><td valign=\"top\"><input type=\"text\" name=\"group_names[$row[id]]\" value=\"$row[name]\"></td>";
            $manage_groups .= "<td><textarea name=\"group_descriptions[$row[id]]\" cols=\"40\" rows=\"2\">$row[description]</textarea></td><td align=\"center\" valign=\"top\">$delete</td></tr>";
        }
        $manage_groups .= '<tr><td colspan="2" align="right"><input type="submit" name="update_groups" value="Update Groups"></td><td>&nbsp;</td></tr>';
        $manage_groups .= '</table></div>';
        $group_select .= '</select>';
    }
    if ($is_admin) echo $manage_groups;
?>
<h3 style="border-bottom: 1px solid #aaa;">Manage Links</h3>
<?php
    $sql = "SELECT link_id, tag, link_group_id, weight FROM $table_pages LEFT JOIN $table_links ON tag = page_tag WHERE MATCH (body) AGAINST ('$this->tag') AND latest = 'Y' AND tag != '$this->tag' ORDER BY link_group_id DESC, weight DESC";
    $result = mysql_query($sql);
    if ($result && mysql_num_rows($result))
    {
        echo '<table width="500" cellpadding="5" id="edit_links"><tr><th>&nbsp;</th><th>Page Tag</th><th align="center">Group</th><th align="center">Weight</th></tr>';
        while ($row = mysql_fetch_array($result))
        {
            $group_valid = isset($groups[$row['link_group_id']]);
            if ($group_valid) $valid_links[] = $row['link_id'];
            $color = (++$i % 2 != 0) ? 'bgcolor="#f6f6f6"' : '';
            $group_name = $group_valid && $row['link_group_id'] ? $groups[$row['link_group_id']] . "<input type=\"hidden\" name=\"link_group_ids[$row[tag]]\" value=\"$row[link_group_id]\">" : 'None';
            $group_weight = $group_valid && $row['link_id'] ? "<input size=\"3\" type=\"text\" name=\"link_weights[$row[tag]]\" value=\"$row[weight]\">" : 'None';
            echo "<tr $color><td><input type=\"checkbox\" name=\"selected_links[$row[tag]]\"></td>";
            echo "<td><a href=\"$base_url?$page_var=$row[tag]\">$row[tag]</a></td>";
            echo "<td align=\"center\">$group_name</td>";
            echo "<td align=\"center\">$group_weight</td></tr>";
        }
        echo "<tr><td align=\"right\" colspan=\"4\"><b>move selected links to:</b>&nbsp;$group_select&nbsp;";
        echo '<input type="submit" name="update_links" value="Update Links"></td></tr>';
        echo '</table>';
        // remove links that have been unlinked in the source document
        $valid_links = join(',', $valid_links);
        mysql_query("DELETE FROM $table_links WHERE this_tag = '$this->tag' AND link_id NOT IN ($valid_links)");
    }
    else
    {
        echo '<p>There are no pages linking to this one.</p>';
    }
    echo '</form>';
}
?>


Now, save the following code as "lmshow.php" in the same directory...

<?php

include('actions/common.ini.php');

if (!function_exists('smart_title'))
{
    function smart_title($wikka_body)
    {
        return preg_match('/(=){2,5}([^=]*)(=){2,5}/', $wikka_body, $matches) ? $matches[2] : '';
    }
}
if (!function_exists('fetch_section'))
{
    function fetch_section($wikka_body, $section)
    {
        return preg_match("/(=){2,5}$section(=){2,5}([^=]*)/ism", $wikka_body, $matches) ? $matches[3] : false;
    }
}

$group = isset($vars['group']) ? $vars['group'] : '__ALL__';
$embed = isset($vars['embed']) ? $vars['embed'] : false;
$css_class = isset($vars['style']) ? $vars['style'] : 'box';

$group_where = $group == '__ALL__' ? '' : "WHERE name = '$group'";
$link_where = '';

$sql = "SELECT id, name, description FROM $table_link_groups $group_where";
$result = mysql_query($sql);
if ($result && mysql_num_rows($result))
{
    while ($row = mysql_fetch_array($result))
    {
        if (strtolower($row['name']) == strtolower($group)) $link_where =  "AND link_group_id = $row[id]";
        $groups[$row['id']]['name'] = $row['name'];
        $groups[$row['id']]['description'] = $row['description'];
        $count[$row['id']] = ceil(strlen($row['description']) / 25);
    }
}
else
{
    return false;
}

$sql = "SELECT link_group_id, page_tag, body  FROM $table_links l, $table_pages p WHERE l.page_tag = p.tag AND p.latest ='Y' AND this_tag = '$this->tag' $link_where ORDER BY weight DESC";
$result = mysql_query($sql);
if ($result && mysql_num_rows($result))
{
    while ($row = mysql_fetch_array($result))
    {
        $groups[$row['link_group_id']]['links'][$row['page_tag']] = $row['body'];
        ++$count[$row['link_group_id']];
    }
    arsort($count);
    foreach ($count as $id => $n)
    {
        if (is_array($groups[$id]['links']))
        {
            $name = $groups[$id]['name'];
            $css_id = str_replace(' ', '_', $name);
            if ($embed)
            {
                foreach ($groups[$id]['links'] as $page_tag => $body)
                {
                    $body = preg_replace('/{{.*linkmanager.*}}/U', '', $body);
                    $body = preg_replace('/{{.*lmshow.*}}/U', '', $body);
                    $output .= ($embed == 'all') ? trim($body) : fetch_section($body, $embed);
                    $output .= "\n\n";
                }
                echo $this->Format($output);
            }
            else
            {
                echo "<dl class=\"lm_$css_class\" id=\"lm_$css_id\">";
                echo "<dt>$name</dt>";
                if ($summary = $groups[$id]['description']) echo "<dd class=\"summary\">$summary</dd>";
                foreach ($groups[$id]['links'] as $page_tag => $body)
                {
                    $title = empty($body) ? '' : 'title="' . smart_title($body) . '"';
                    echo "<dd><a href=\"$base_url?$page_var=$page_tag\" $title>$page_tag</a></dd>";
                }
                echo '</dl>';
            }
        }
    }
}
?>


Required CSS Definitions


Add this to the end of your wikka.css file...

dl.lm_box
{
    float: left;
    width: 176px;
    padding: 4px 0px 4px 2px;
    background: #F1F1F1;
    border: 1px solid #999;
    border-left: 1px solid #999;
    margin: 10px;
    margin-bottom: 20px;
    text-align: left;
}

dl.lm_box dt {
    border: solid 1px #ccc;
    background: #e6e6e6;
    font-weight: bold;
    padding: 2px;
}

dl.lm_box dd.summary {
    padding: 5px;
    margin: 2px 2px 0px 0px;
    background: #fafafa;
}

dl.lm_box dd {
    padding: 0px;
    margin: 2px 2px 0px 0px;
}

dl.lm_box dd a
{
    display: block;
    border: solid 1px #e6e6e6;
    padding: 2px 6px 2px 6px;
    margin: 0px 2px;
    background: #e6e6e6;
    height: 1%;
    line-height: 1em;
    color: #000;
}

dl.lm_box dd a:hover
{
    border: solid 1px #999;
    background: #CCC;
}

dl.lm_box dd a:hover, dl.lm_box dd a:visited, dl.lm_box dd a:active, dl.lm_box dd a:link
{
    text-decoration: none ! important;
}

dl.lm_event
{
margin: 0;
padding: 0;
font-family: georgia, times, serif;
}

.lm_event dt
{
position: relative;
left: 0;
top: 1.5em;
width: 15em;
font-weight: bold;
}

.lm_event dd
{
border-left: 1px solid #000;
margin: 0 0 0 12em;
padding: 0 0 .5em 1.5em;
}

dl.lm_table { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd;}

.lm_table dt
{
width: 15em;
padding: .5em;
float: left;
margin: 0;
font-weight: bold;
}

.lm_table dd
{
margin-left: 16em;
padding: .5em;
}


Lastly, you may want to save the following code as "clearfloats.php" in the actions directory.

<?php
    echo '<div style="margin-bottom:-4em;clear:both;">&nbsp;</div>';
?>


The Much Needed Example


This is taken directly from my test setup, which can be seen in the screenshot below.

{{linkmanager}}

====Using the lmshow Action====

{{lmshow}}
{{clearfloats}}

And some more text goes here...


The Screenshot


Screenshot of the LinkManager action

I actually moused over the link at the bottom to show that link titles are automatically extracted from the linked pages and inserted into each anchor tag's title attribute, but I guess the old PrtScrn button didn't like that idea too much!


But Wait... There's More!


The action can do a lot more than display links. All of the display options are given at the top of linkmanager.php, but I'll repeat them here for easy reference.

{{lmshow}} -- (default) returns all groups as definition list (dl) of links (using the default "box" style)
{{lmshow style="CSS STYLE"}} -- replace CSS STYLE with box, event, or table for different looks
{{lmshow group="Group One"}} -- show the group labeled "Group One" as dl of links
{{lmshow group="Group One" embed="all"}} -- embed the entire body of every link in this page
{{lmshow group="Group One" embed="Overview"}} -- embed section with heading "Overview" of every link in this page


References and Places I Stole From



Todo List/Discussion Topics



Authors


DennyShimkoski


CategoryUserContributions
Comments
Comment by NilsLindenberg
2005-08-06 11:47:37
I haven't tested your contribution yet, but I don't thing it is a good idea to have another config-file beside wikka.config.php (and even if {{common.ini}} would have no effect - it is no action and therefore shouldn't be placed in the actions directory).

My solution:
$base_url -> you get it with $this->config['base_url'].
$page_var (I have to see for what this variable is used)

for the table-names:
-save them into wikka.config.php and you get the vars with $table_pages = $this->config['table_prefix'].$this->config['pages_table_name'] etc.
Comment by DennyShimkoski
2005-08-06 17:33:48
Thanks, Nils. The only thing about the default base_url setting in the config file is it typically looks something like this -- "http://localhost/wikka/wikka.php?wakka=" ($page_var is the "wakka" part). This is rather inconvenient for building POST forms. I suppose I could use PHP_SELF... have to give it a try. Thanks again for the tips.
Comment by DarTar
2005-08-06 19:10:43
Denny, there is a Wikka core method for creating forms: FormOpen()
Comment by JavaWoman
2005-08-06 19:58:19
... as well as the counterpart FormClose() of course ;-)

You may also want to look at the AdvancedFormOpen page to see how you can automatically generate id and class for a form -- at the same time as ensuring the id is actually unique on a mage (see also GenerateUniqueId). This is beta code - but implemented on this server.
Comment by 62.47.151.157
2006-02-27 17:42:58
If I include {{linkmanager}} a warning is displayed like that:

Warning: join(): Bad arguments. in /home/php/Wikka/actions/linkmanager.php on line 141

What could be the reason?
JohSto
Comment by NilsLindenberg
2006-02-28 17:17:31
JohSto, which version of php do you use?
Comment by 193.170.71.18
2006-03-02 09:45:59
PHP version 4.3.10
Comment by KairoMiami
2007-11-21 08:11:44
Hi Denny

I owe you one... I just completely succesfully installed your script Linkmanager, and I need some explanation... :-)

Do you have a working "demo" of it somewhere? I thought the script would show me whenever a page somewhere in the net i slinking to me a refernce to that, but it seems, that it's different? I want some live action on this? Thank you, Denny.

Tobias K. Aellig / http://www.genfusion.net
Check it out: http://wikkawiki.org/KairoMiami

///
(here a test of mine <a href="http://wikkawiki.org/KairoMiami">KairoMiami</a>
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki