File Coverage

blib/lib/Wiki/Toolkit/Plugin/Categoriser.pm
Criterion Covered Total %
statement 9 36 25.0
branch 0 2 0.0
condition n/a
subroutine 3 7 42.8
pod 4 4 100.0
total 16 49 32.6


line stmt bran cond sub pod time code
1             package Wiki::Toolkit::Plugin::Categoriser;
2 2     2   2662 use strict;
  2         4  
  2         72  
3 2     2   2214 use Wiki::Toolkit::Plugin;
  2         833  
  2         69  
4              
5 2     2   24 use vars qw( $VERSION @ISA );
  2         3  
  2         980  
6             $VERSION = '0.08';
7             @ISA = qw( Wiki::Toolkit::Plugin );
8              
9             =head1 NAME
10              
11             Wiki::Toolkit::Plugin::Categoriser - Category management for Wiki::Toolkit.
12              
13             =head1 DESCRIPTION
14              
15             Uses node metadata to build a model of how nodes are related to each
16             other in terms of categories.
17              
18             =head1 SYNOPSIS
19              
20             use Wiki::Toolkit;
21             use Wiki::Toolkit::Plugin::Categoriser;
22              
23             my $wiki = Wiki::Toolkit->new( ... );
24             $wiki->write_node( "Red Lion", "nice beer", $checksum,
25             { category => [ "Pubs", "Pub Food" ] }
26             ) or die "Can't write node";
27             $wiki->write_node( "Holborn Station", "busy at peak times", $checksum,
28             { category => "Tube Station" }
29             ) or die "Can't write node";
30              
31             my $categoriser = Wiki::Toolkit::Plugin::Categoriser->new;
32             $wiki->register_plugin( plugin => $categoriser );
33              
34             my $isa_pub = $categoriser->in_category( category => "Pubs",
35             node => "Red Lion" );
36             my @categories = $categoriser->categories( node => "Holborn Station" );
37              
38             =head1 METHODS
39              
40             =over 4
41              
42             =item B
43              
44             my $categoriser = Wiki::Toolkit::Plugin::Categoriser->new;
45             $wiki->register_plugin( plugin => $categoriser );
46              
47             =cut
48              
49             sub new {
50 0     0 1   my $class = shift;
51 0           my $self = {};
52 0           bless $self, $class;
53 0           return $self;
54             }
55              
56             =item B
57              
58             my $isa_pub = $categoriser->in_category( category => "Pubs",
59             node => "Red Lion" );
60              
61             Returns true if the node is in the category, and false otherwise. Note
62             that this is B, so C is the same category as
63             C. I might do something to make it plural-insensitive at some
64             point too.
65              
66             =cut
67              
68             sub in_category {
69 0     0 1   my ($self, %args) = @_;
70 0           my @catarr = $self->categories( node => $args{node} );
71 0           my %categories = map { lc($_) => 1 } @catarr;
  0            
72 0           return $categories{lc($args{category})};
73             }
74              
75             =item B
76              
77             $wiki->write_node( "Category Pub Food", "mmm food", $checksum,
78             { category => [ "Pubs", "Food", "Category" ] }
79             ) or die "Can't write node";
80             my @subcats = $categoriser->subcategories( category => "Pubs" );
81             # will return ( "Pub Food" )
82              
83             # Or if you prefer CamelCase node names:
84             $wiki->write_node( "CategoryPubFood", "mmm food", $checksum,
85             { category => [ "Pubs", "Food", "Category" ] }
86             ) or die "Can't write node";
87             my @subcats = $categoriser->subcategories( category => "Pubs" );
88             # will return ( "PubFood" )
89              
90             To add a subcategory C to a given category C, write a node
91             called any one of C, C, or C with
92             metadata indicating that it's in categories C and C.
93              
94             Yes, this pays specific attention to the Wiki convention of defining
95             categories by prefacing the category name with C and
96             creating a node by that name. If different behaviour is required we
97             should probably implement it using an optional argument in the
98             constructor.
99              
100             =cut
101              
102             sub subcategories {
103 0     0 1   my ($self, %args) = @_;
104 0 0         return () unless $args{category};
105 0           my $datastore = $self->datastore;
106 0           my %cats = map { $_ => 1 }
  0            
107             $datastore->list_nodes_by_metadata(
108             metadata_type => "category",
109             metadata_value => "Category" );
110 0           my @in_cat = $datastore->list_nodes_by_metadata(
111             metadata_type => "category",
112             metadata_value => $args{category} );
113 0           return map { s/^Category\s+//; $_ } grep { $cats{$_} } @in_cat;
  0            
  0            
  0            
114             }
115              
116             =item B
117              
118             my @cats = $categoriser->categories( node => "Holborn Station" );
119              
120             Returns an array of category names in no particular order.
121              
122             =cut
123              
124             sub categories {
125 0     0 1   my ($self, %args) = @_;
126 0           my $dbh = $self->datastore->dbh;
127 0           my $sth = $dbh->prepare( "SELECT metadata_value
128             FROM node
129             INNER JOIN metadata
130             ON ( node.id = metadata.node_id
131             AND node.version = metadata.version )
132             WHERE name = ? AND metadata_type = 'category'" );
133 0           $sth->execute( $args{node} );
134 0           my @categories;
135 0           while ( my ($cat) = $sth->fetchrow_array ) {
136 0           push @categories, $cat;
137             }
138 0           return @categories;
139             }
140              
141             =back
142              
143             =head1 SEE ALSO
144              
145             =over 4
146              
147             =item * L
148              
149             =item * L
150              
151             =back
152              
153             =head1 AUTHOR
154              
155             Kake Pugh (kake@earth.li).
156             The Wiki::Toolkit team (http://www.wiki-toolkit.org/)
157              
158             =head1 COPYRIGHT
159              
160             Copyright (C) 2003-4 Kake Pugh. All Rights Reserved.
161             Copyright (C) 2006-2009 the Wiki::Toolkit team. All Rights Reserved.
162              
163             This module is free software; you can redistribute it and/or modify it
164             under the same terms as Perl itself.
165              
166             =cut
167              
168             1;