File Coverage

blib/lib/Rubric/EntryTag.pm
Criterion Covered Total %
statement 30 37 81.0
branch 11 14 78.5
condition 3 6 50.0
subroutine 7 8 87.5
pod 3 3 100.0
total 54 68 79.4


line stmt bran cond sub pod time code
1 12     12   13058 use strict;
  12         25  
  12         490  
2 12     12   65 use warnings;
  12         23  
  12         602  
3             package Rubric::EntryTag;
4             # ABSTRACT: a tag on an entry
5             $Rubric::EntryTag::VERSION = '0.155';
6 12     12   945 use String::TagString;
  12         30133  
  12         344  
7              
8             # =head1 DESCRIPTION
9             #
10             # This class provides an interface to tags on Rubric entries. It inherits from
11             # Rubric::DBI, which is a Class::DBI class.
12             #
13             # =cut
14              
15 12     12   71 use base qw(Rubric::DBI);
  12         23  
  12         6626  
16              
17             __PACKAGE__->table('entrytags');
18              
19             # =head1 COLUMNS
20             #
21             # id - a unique identifier
22             # entry - the tagged entry
23             # tag - the tag itself
24             # tag_value - the value of the tag (for tags in "tag:value" form)
25             #
26             # =cut
27              
28             __PACKAGE__->columns(All => qw(id entry tag tag_value));
29              
30             # =head1 RELATIONSHIPS
31             #
32             # =head2 entry
33             #
34             # The entry attribute returns a Rubric::Entry.
35             #
36             # =cut
37              
38             __PACKAGE__->has_a(entry => 'Rubric::Entry');
39              
40             # =head1 TRIGGERS
41             #
42             # =cut
43              
44             __PACKAGE__->add_trigger(before_create => \&_nullify_values);
45             __PACKAGE__->add_trigger(before_update => \&_nullify_values);
46              
47             sub _nullify_values {
48 7     7   7618 my $self = shift;
49 7 100 66     93 $self->tag_value(undef)
50             unless defined $self->{tag_value} and length $self->{tag_value};
51             }
52              
53             # =head1 METHODS
54             #
55             # =head2 related_tags(\@tags)
56             #
57             # This method returns a reference to an array of tags related to all the given
58             # tags. Tags are related if they occur together on entries.
59             #
60             # =cut
61              
62             sub related_tags {
63 1     1 1 1312 my ($self, $tags) = @_;
64 1 50 33     11 return unless $tags and my @tags = @$tags;
65              
66             # or maybe we should throw an exception? -- rjbs, 2006-02-13
67 1 50       3 return [] if grep { $_ eq '@private' } @tags;
  1         9  
68              
69 0         0 my $query = q|
70             SELECT DISTINCT tag FROM entrytags
71             WHERE
72 0         0 tag NOT IN (| . join(',',map { $self->db_Main->quote($_) } @tags) . q|)
73             AND tag NOT LIKE '@%'
74             AND | .
75             join ' AND ',
76 0         0 map { "entry IN (SELECT entry FROM entrytags WHERE tag=$_)" }
77 0         0 map { $self->db_Main->quote($_) }
78             @tags;
79              
80 0         0 $self->db_Main->selectcol_arrayref($query, undef);
81             }
82              
83             # =head3 related_tags_counted(\@tags)
84             #
85             # This is the obvious conjunction of C and C. It
86             # returns an arrayref of arrayrefs, each a pair of tag/occurance values.
87             #
88             # =cut
89              
90             sub related_tags_counted {
91 23     23 1 38607 my ($self, $tags) = @_;
92 23 100       93 return unless $tags;
93 13 100       85 $tags = [ keys %$tags ] if ref $tags eq 'HASH';
94 13 50       64 return unless my @tags = @$tags;
95              
96             # or maybe we should throw an exception? -- rjbs, 2006-02-13
97 13 100       30 return [] if grep { $_ eq '@private' } @tags;
  13         69  
98              
99 12         60 my $query = q|
100             SELECT DISTINCT tag, COUNT(*) AS count
101             FROM entrytags
102             WHERE tag NOT IN (|
103 12         561 . join(',',map { $self->db_Main->quote($_) } @tags) . q|)
104             AND tag NOT LIKE '@%'
105             AND | .
106             join ' AND ',
107 12         846 map { "entry IN (SELECT entry FROM entrytags WHERE tag=$_)" }
108 12         35 map { $self->db_Main->quote($_) }
109             @tags;
110              
111 12         38 $query .= " GROUP BY tag";
112              
113 12         42 $self->db_Main->selectall_arrayref($query, undef);
114             }
115              
116             # =head2 stringify_self
117             #
118             # =cut
119              
120             sub stringify_self {
121 0     0 1   my ($self) = @_;
122 0           String::TagString->string_from_tags({
123             $self->tag => $self->tag_value
124             });
125             }
126              
127             1;
128              
129             __END__