the metadata fetcher
[bse.git] / site / cgi-bin / modules / BSE / MetaOwnerBase.pm
CommitLineData
f5b7b326
TC
1package BSE::MetaOwnerBase;
2use strict;
4029e8ab 3use Carp 'confess';
f5b7b326 4
b242c5a6 5our $VERSION = "1.005";
f5b7b326 6
4029e8ab 7=head1 NAME
f5b7b326 8
4029e8ab 9BSE::MetaOwnerBase - mix-in for objects that have metadata.
f5b7b326 10
4029e8ab 11=head1 SYNOPSIS
f5b7b326 12
4029e8ab
TC
13 my $file = ...
14 my @meta = $file->metadata;
15 my @text = $file->text_metadata;
16 my $meta = $file->meta_by_name($name);
17 my @names = $file->metanames;
18 my @info = $file->metainfo;
19 my @config = $file->meta_config;
f5b7b326 20
4029e8ab 21=head1 DESCRIPTION
f5b7b326 22
4029e8ab
TC
23Provides generic metadata support methods. These can be called on any
24L<BSE::TB::ArticleFile> object, and possibly other objects in the
25future.
f5b7b326 26
4029e8ab 27=head1 PUBLIC METHODS
f5b7b326 28
4029e8ab 29These can be called from anywhere, including templates:
f5b7b326 30
4029e8ab 31=over
f5b7b326 32
4029e8ab
TC
33=item metadata
34
35Return all metadata for the object (as metadata objects).
36
37=cut
f5b7b326
TC
38
39sub metadata {
40 my ($self) = @_;
41
42 require BSE::TB::Metadata;
43 return BSE::TB::Metadata->getBy
44 (
45 file_id => $self->id,
46 owner_type => $self->meta_owner_type,
47 );
48}
49
b4c02bf9 50=item text_metadata
4029e8ab
TC
51
52Return all metadata for the object with a content type of
53C<text/plain>.
54
55=cut
56
f5b7b326
TC
57sub text_metadata {
58 my ($self) = @_;
59
60 require BSE::TB::Metadata;
61 return BSE::TB::Metadata->getBy
62 (
63 file_id => $self->id,
64 owner_type => $self->meta_owner_type,
65 content_type => "text/plain",
66 );
67}
68
4029e8ab
TC
69=item meta_by_name
70
71Retrieve metadata with a specific name.
72
73Returns nothing if there is no metadata of that name.
74
75=cut
76
f5b7b326
TC
77sub meta_by_name {
78 my ($self, $name) = @_;
79
80 require BSE::TB::Metadata;
81 my ($result) = BSE::TB::Metadata->getBy
82 (
83 file_id => $self->id,
84 owner_type => $self->meta_owner_type,
85 name => $name
86 )
87 or return;
88
89 return $result;
90}
91
b242c5a6
TC
92=item meta_json_by_name
93
94Retrieve metadata with a specific name and decode it as JSON,
95returning a data structure.
96
97Returns nothing if there is no metadata of that name, or if the
98content type isn't a JSON content type or if the metadata cannot be
99decoded as JSON.
100
101=cut
102
103sub meta_json_by_name {
104 my ($self, $name) = @_;
105
106 my $meta = $self->meta_by_name($name)
107 or return;
108
109 return $meta->retrieve_json;
110}
111
4029e8ab
TC
112=item metanames
113
114Returns the names of each metadatum defined for the file.
115
116=cut
117
118sub metanames {
119 my ($self) = @_;
120
121 require BSE::TB::Metadata;
122 return BSE::TB::Metadata->getColumnBy
123 (
124 "name",
125 [
126 [ file_id => $self->id ],
127 [ owner_type => $self->meta_owner_type ],
128 ],
129 );
130
131}
132
133=item metainfo
134
135Returns all but the value for metadata defined for the file.
136
137This is useful to avoid loading large objects if the metadata happens
138to be file content.
139
140=cut
141
142sub metainfo {
143 my ($self) = @_;
144
145 require BSE::TB::Metadata;
146 my @cols = grep $_ ne "value", BSE::TB::MetaEntry->columns;
147 return BSE::TB::Metadata->getColumnsBy
148 (
149 \@cols,
150 [
151 [ file_id => $self->id ],
152 [ owner_type => $self->meta_owner_type ],
153 ],
154 );
155}
156
157=item meta_config
158
159Returns configured metadata fields for this object.
160
161=cut
162
163sub meta_config {
164 my ($self, $cfg) = @_;
165
166 $cfg || BSE::Cfg->single;
167
168 require BSE::MetaMeta;
169 my @metafields;
170 my $prefix = $self->meta_meta_cfg_prefix;
171 my @keys = $cfg->orderCS($self->meta_meta_cfg_section);
172 for my $name (@keys) {
173 my %opts = ( name => $name );
174 my $section = "$prefix $name";
175 for my $key (BSE::MetaMeta->keys) {
176 my $value = $cfg->entry($section, $key);
177 if (defined $value) {
178 $opts{$key} = $value;
179 }
180 }
181 push @metafields, BSE::MetaMeta->new(%opts, cfg => $cfg);
182 }
183
184 return @metafields;
185
186}
187
b242c5a6
TC
188=item all_meta_by_name
189
190Retrieves all metadata for this owner type with the given name.
191
192=cut
193
194sub all_meta_by_name {
195 my ($class, $name) = @_;
196
197 require BSE::TB::Metadata;
198 return BSE::TB::Metadata->getBy
199 (
200 owner_type => $class->meta_owner_type,
201 name => $name,
202 );
203}
204
4029e8ab
TC
205=back
206
207=head1 RESTRICTED METHODS
208
209These are not accessible from templates.
210
b4c02bf9
TC
211=over
212
4029e8ab
TC
213=item clear_metadata
214
215Remove all metadata for this object. Should be called when the object
216is removed.
217
218Restricted.
219
220=cut
221
222sub clear_metadata {
223 my ($self) = @_;
224
225 BSE::DB->run(bseClearArticleFileMetadata => $self->id, $self->meta_owner_type);
226}
227
228=item clear_app_metadata
229
230Remove all application metadata for this object.
231
232Restricted.
233
234=cut
235
236sub clear_app_metadata {
237 my ($self) = @_;
238
239 BSE::DB->run(bseClearArticleFileAppMetadata => $self->id, $self->meta_owner_type);
240}
241
242=item clear_sys_metadata
243
244Remove all system metadata for this object.
245
246Restricted.
247
248=cut
249
250sub clear_sys_metadata {
251 my ($self) = @_;
252
253 BSE::DB->run(bseClearArticleFileSysMetadata => $self->id, $self->meta_owner_type);
254}
255
256=item delete_meta_by_name
257
258Remove a single piece of metadata from the object.
259
260Restricted.
261
262=cut
263
264sub delete_meta_by_name {
265 my ($self, $name) = @_;
266
4029e8ab
TC
267 BSE::DB->run(bseDeleteArticleFileMetaByName => $self->id, $name, $self->meta_owner_type);
268}
269
270=item add_meta
271
272Add metadata to the object.
273
274Restricted.
275
276=cut
277
278sub add_meta {
279 my ($self, %opts) = @_;
280
c29434c9
TC
281 my $value_text = delete $opts{value_text};
282 if ($value_text) {
283 utf8::encode($value_text);
284 $opts{value} = $value_text;
285 }
286
4029e8ab
TC
287 require BSE::TB::Metadata;
288 return BSE::TB::Metadata->make
289 (
290 file_id => $self->id,
291 owner_type => $self->meta_owner_type,
292 %opts,
293 );
294}
295
296sub restricted_method {
297 my ($self, $name) = @_;
298
299 return $name =~ /^(?:clear_|delete_|add_)/;
300}
301
f5b7b326 3021;
4029e8ab
TC
303
304=back
305
306=cut