]>
Commit | Line | Data |
---|---|---|
41b9d8ec | 1 | package Article; |
9d29b58f | 2 | use strict; |
41b9d8ec TC |
3 | # represents an article from the database |
4 | use Squirrel::Row; | |
7646d96e | 5 | use BSE::TB::SiteCommon; |
41b9d8ec | 6 | use vars qw/@ISA/; |
7646d96e | 7 | @ISA = qw/Squirrel::Row BSE::TB::SiteCommon/; |
efcc5a30 | 8 | use Carp 'confess'; |
41b9d8ec | 9 | |
a739c25d | 10 | our $VERSION = "1.001"; |
cb7fd78d | 11 | |
41b9d8ec TC |
12 | sub columns { |
13 | return qw/id parentid displayOrder title titleImage body | |
14 | thumbImage thumbWidth thumbHeight imagePos | |
15 | release expire keyword template link admin threshold | |
331fd099 | 16 | summaryLength generator level listed lastModified flags |
9063386f | 17 | customDate1 customDate2 customStr1 customStr2 |
9604a90c | 18 | customInt1 customInt2 customInt3 customInt4 |
efcc5a30 | 19 | lastModifiedBy created createdBy author pageTitle |
12bcb7ac | 20 | force_dynamic cached_dynamic inherit_siteuser_rights |
c76e86ea | 21 | metaDescription metaKeywords summary menu titleAlias linkAlias/; |
41b9d8ec TC |
22 | } |
23 | ||
58baa27b TC |
24 | sub table { |
25 | 'article'; | |
26 | } | |
27 | ||
41f10371 TC |
28 | sub numeric { |
29 | qw(id listed parentid threshold summaryLength level | |
0a66f55c | 30 | customInt1 customInt2 customInt3 customInt4 menu); |
41f10371 TC |
31 | } |
32 | ||
ff9130e4 TC |
33 | sub section { |
34 | my ($self) = @_; | |
35 | ||
36 | my $section = $self; | |
37 | while ($section->{parentid} > 0 | |
38 | and my $parent = Articles->getByPkey($section->{parentid})) { | |
39 | $section = $parent; | |
40 | } | |
41 | ||
42 | return $section; | |
43 | } | |
44 | ||
08123550 TC |
45 | sub parent { |
46 | my ($self) = @_; | |
47 | $self->{parentid} == -1 and return; | |
48 | return Articles->getByPkey($self->{parentid}); | |
49 | } | |
50 | ||
efcc5a30 TC |
51 | sub update_dynamic { |
52 | my ($self, $cfg) = @_; | |
53 | ||
54 | $cfg && $cfg->can('entry') | |
55 | or confess 'update_dynamic called without $cfg'; | |
56 | ||
57 | # conditional in case something strange is in the config file | |
58 | my $dynamic = $cfg->entry('basic', 'all_dynamic', 0) ? 1 : 0; | |
59 | ||
60 | $dynamic or $dynamic = $self->{force_dynamic}; | |
61 | ||
63e99d77 | 62 | $dynamic or $dynamic = $self->is_access_controlled; |
c2096d67 | 63 | |
63e99d77 | 64 | $dynamic or $dynamic = $self->force_dynamic_inherited; |
efcc5a30 TC |
65 | |
66 | $self->{cached_dynamic} = $dynamic; | |
67 | } | |
68 | ||
69 | sub is_dynamic { | |
70 | $_[0]{cached_dynamic}; | |
71 | } | |
72 | ||
c2096d67 TC |
73 | sub is_accessible_to { |
74 | my ($self, $group) = @_; | |
75 | ||
76 | my $groupid = ref $group ? $group->{id} : $group; | |
77 | ||
78 | my @rows = BSE::DB->query(articleAccessibleToGroup => $self->{id}, $groupid); | |
79 | ||
80 | scalar @rows; | |
81 | } | |
82 | ||
83 | sub group_ids { | |
84 | my ($self) = @_; | |
85 | ||
86 | map $_->{id}, BSE::DB->query(siteuserGroupsForArticle => $self->{id}); | |
87 | } | |
88 | ||
89 | sub add_group_id { | |
90 | my ($self, $id) = @_; | |
91 | ||
92 | eval { | |
93 | BSE::DB->single->run(articleAddSiteUserGroup => $self->{id}, $id); | |
94 | }; | |
95 | } | |
96 | ||
97 | sub remove_group_id { | |
98 | my ($self, $id) = @_; | |
99 | ||
100 | BSE::DB->single->run(articleDeleteSiteUserGroup => $self->{id}, $id); | |
101 | } | |
102 | ||
b873a8fa TC |
103 | sub is_access_controlled { |
104 | my ($self) = @_; | |
105 | ||
106 | my @group_ids = $self->group_ids; | |
107 | return 1 if @group_ids; | |
108 | ||
109 | return 0 | |
110 | unless $self->{inherit_siteuser_rights}; | |
111 | ||
112 | my $parent = $self->parent | |
113 | or return 0; | |
114 | ||
115 | return $parent->is_access_controlled; | |
116 | } | |
117 | ||
63e99d77 TC |
118 | sub force_dynamic_inherited { |
119 | my ($self) = @_; | |
120 | ||
121 | my $parent = $self->parent | |
122 | or return 0; | |
123 | ||
124 | $parent->{force_dynamic} && $parent->{flags} =~ /F/ | |
125 | and return 1; | |
126 | ||
127 | return $parent->force_dynamic_inherited; | |
128 | } | |
129 | ||
130 | sub link_to_filename { | |
131 | my ($self, $cfg, $link) = @_; | |
132 | ||
a739c25d | 133 | $cfg ||= BSE::Cfg->single; |
16901a2a | 134 | |
63e99d77 TC |
135 | defined $link or $link = $self->{link}; |
136 | ||
8f84f3f1 TC |
137 | length $link or return; |
138 | ||
63e99d77 TC |
139 | my $filename = $link; |
140 | $filename =~ s!/\w*$!!; | |
141 | $filename =~ s{^\w+://[\w.-]+(?::\d+)?}{}; | |
142 | $filename = $Constants::CONTENTBASE . $filename; | |
143 | $filename =~ s!//+!/!; | |
144 | ||
145 | return $filename; | |
146 | } | |
147 | ||
16901a2a TC |
148 | sub cached_filename { |
149 | my ($self, $cfg) = @_; | |
150 | ||
a739c25d | 151 | $cfg ||= BSE::Cfg->single; |
16901a2a TC |
152 | |
153 | my $dynamic_path = $cfg->entryVar('paths', 'dynamic_cache'); | |
154 | return $dynamic_path . "/" . $self->{id} . ".html"; | |
155 | } | |
156 | ||
a739c25d TC |
157 | sub html_filename { |
158 | my ($self, $cfg) = @_; | |
159 | ||
160 | $cfg ||= BSE::Cfg->single; | |
161 | ||
162 | return $self->is_dynamic | |
163 | ? $self->cached_filename($cfg) | |
164 | : $self->link_to_filename($cfg); | |
165 | } | |
166 | ||
167 | sub remove_html { | |
168 | my ($self, $cfg) = @_; | |
169 | ||
170 | my $filename = $self->html_filename($cfg) | |
171 | or return 1; | |
172 | ||
173 | unlink $filename | |
174 | or return; | |
175 | ||
176 | return 1; | |
177 | } | |
178 | ||
bf87e97c TC |
179 | sub remove { |
180 | my ($self, $cfg) = @_; | |
181 | ||
182 | $cfg or confess "No \$cfg supplied to ", ref $self, "->remove"; | |
183 | ||
184 | $self->remove_images($cfg); | |
16901a2a TC |
185 | |
186 | for my $file ($self->files) { | |
187 | $file->remove($cfg); | |
188 | } | |
189 | ||
190 | # remove any step(child|parent) links | |
191 | require OtherParents; | |
192 | my @steprels = OtherParents->anylinks($self->{id}); | |
193 | for my $link (@steprels) { | |
194 | $link->remove(); | |
195 | } | |
196 | ||
197 | # remove the static page | |
a739c25d | 198 | $self->remove_html($cfg); |
16901a2a TC |
199 | |
200 | $self->SUPER::remove(); | |
201 | } | |
202 | ||
201e926c TC |
203 | sub all_parents { |
204 | my ($self) = @_; | |
205 | ||
206 | my @result = $self->step_parents; | |
207 | if ($self->{parentid} > 0 && !grep $_->{id} eq $self->{parentid}, @result) { | |
208 | push @result, $self->parent; | |
209 | } | |
210 | ||
211 | return @result; | |
212 | } | |
213 | ||
214 | sub is_step_ancestor { | |
215 | my ($self, $other, $max) = @_; | |
216 | ||
217 | my $other_id = ref $other ? $other->{id} : $other; | |
218 | my %seen; | |
219 | ||
220 | $max ||= 10; | |
221 | ||
222 | # early exit if possible | |
223 | return 1 if $self->{parentid} == $other_id; | |
224 | ||
225 | my @all_parents = $self->all_parents; | |
226 | return 1 if grep $_->{id} == $other_id, @all_parents; | |
227 | my @work = map [ 0, $_], grep !$seen{$_}++, @all_parents; | |
228 | while (@work) { | |
229 | my $entry = shift @work; | |
230 | my ($level, $workart) = @$entry; | |
231 | ||
232 | $level++; | |
233 | if ($level < $max) { | |
234 | @all_parents = $workart->all_parents; | |
235 | return 1 if grep $_->{id} == $other_id, @all_parents; | |
236 | push @work, map [ $level, $_ ], grep !$seen{$_}++, @all_parents; | |
237 | } | |
238 | } | |
239 | ||
240 | return 0; | |
241 | } | |
242 | ||
147e99e8 TC |
243 | sub possible_stepparents { |
244 | my $self = shift; | |
245 | ||
246 | return BSE::DB->query(articlePossibleStepparents => $self->{id}, $self->{id}); | |
247 | } | |
248 | ||
249 | sub possible_stepchildren { | |
250 | my $self = shift; | |
251 | ||
252 | return BSE::DB->query(articlePossibleStepchildren => $self->{id}, $self->{id}); | |
253 | } | |
254 | ||
c76e86ea TC |
255 | sub link { |
256 | my ($self, $cfg) = @_; | |
257 | ||
538b7aee TC |
258 | if ($self->flags =~ /P/) { |
259 | my $parent = $self->parent; | |
260 | $parent and return $parent->link($cfg); | |
261 | } | |
262 | ||
a739c25d TC |
263 | $self->is_linked |
264 | or return ""; | |
265 | ||
538b7aee | 266 | $cfg ||= BSE::Cfg->single; |
089bef32 | 267 | |
c76e86ea TC |
268 | if ($self->{linkAlias} && $cfg->entry('basic', 'use_alias', 1)) { |
269 | my $prefix = $cfg->entry('basic', 'alias_prefix', ''); | |
73e6b73a TC |
270 | my $link = $prefix . '/' . $self->{linkAlias}; |
271 | if ($cfg->entry('basic', 'alias_suffix', 1)) { | |
272 | my $title = $self->{title}; | |
273 | $title =~ tr/a-zA-Z0-9/_/cs; | |
274 | $link .= '/' . $title; | |
275 | } | |
276 | return $link; | |
c76e86ea TC |
277 | } |
278 | else { | |
279 | return $self->{link}; | |
280 | } | |
281 | } | |
282 | ||
a739c25d TC |
283 | sub is_linked { |
284 | my ($self) = @_; | |
285 | ||
286 | return $self->flags !~ /L/; | |
287 | } | |
288 | ||
41b9d8ec | 289 | 1; |