1 # mix-in (or close) for classes that keep tags
2 # currently just articles
3 # the owner class should implement a tag_owner_type method
4 package BSE::TB::TagOwner;
7 use BSE::TB::TagMembers;
9 our $VERSION = "1.002";
13 BSE::TB::TagOwner - mixin for objects with tags
19 $article->set_tags([ qw/tag1 tag2/ ], \$error);
20 $article->remove_tags;
22 my @tags = $article->tag_objects;
23 my @tag_names = $article->tags;
24 my @tag_ids = $article->tag_ids;
26 if ($article->has_tags([ "tag1", "tag2" ])) {
32 This class is a mix-in that implements tags for the mixed-into object.
34 =head1 METHODS PROVIDED
38 =item set_tags(\@tags, \$error)
40 Set the specified tags on the object, replacing all existing tags.
45 my ($self, $rtags, $rerror) = @_;
47 my @current_tags = $self->tag_objects;
48 my %current = map { $_->canon_name => $_ } @current_tags;
49 my %remove = %current;
52 for my $name (@$rtags) {
53 my $work = BSE::TB::Tags->name($name, $rerror);
54 defined $work or return;
57 if ($current{$lower}) {
58 delete $remove{$lower};
59 if (!$save{$lower} && $name ne $current{$lower}->name) {
60 $save{$lower} = $name;
68 for my $add (values %add) {
69 # look for or make the tag
70 my $tag = BSE::TB::Tags->getByName($self->tag_owner_type, $add);
72 if ($tag->name ne $add && !$save{lc $add}) {
73 $current{lc $add} = $tag;
74 $save{lc $add} = $add;
78 $tag = BSE::TB::Tags->make_with_name($self->tag_owner_type, $add);
82 BSE::TB::TagMembers->make
84 owner_type => $self->tag_owner_type,
85 owner_id => $self->id,
90 for my $save (keys %save) {
91 my $new_name = $save{$save};
92 my $tag = $current{$save};
93 $tag->set_name($new_name);
97 # remove any leftovers
98 for my $remove (values %remove) {
99 BSE::TB::TagMembers->remove_by_tag($self, $remove);
107 Remove all tags from the object.
114 BSE::TB::TagMembers->remove_owned_by($self);
119 Return all existing tags on the object as tag objects.
126 return BSE::TB::Tags->getSpecial(object_tags => $self->tag_owner_type, $self->id);
131 Returns all existing tags on the object as tag names.
138 return map $_->name, $self->tag_objects;
143 Returns all existing tags on the object as tag ids.
150 return map $_->{id}, BSE::DB->single->run("Tag_ids.by_owner", $self->tag_owner_type, $self->id);
153 =item has_tags(\@tags)
155 Check that all of the specified tags are on the object.
160 my ($self, $rtags) = @_;
162 my %my_tag_ids = map { $_ => 1 } $self->tag_ids;
164 # make sure we have objects, if there's no tag, we don't have that
165 # tage and can immediately return false
166 for my $tag (@$rtags) {
169 $work = BSE::TB::Tags->getByName($self->tag_owner_type, $tag)
173 $my_tag_ids{$tag->id}
186 =head1 REQUIRED METHODS
188 These need to be implemented by the class that wants tags.
194 Return a short constant string identifying owner class of the tags.
198 The numeric id of the specific owner object of the tags.
204 Tony Cook <tony@develop-help.com>