| blib/lib/Labyrinth/Plugin/Review.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 12 | 12 | 100.0 |
| branch | n/a | ||
| condition | n/a | ||
| subroutine | 4 | 4 | 100.0 |
| pod | n/a | ||
| total | 16 | 16 | 100.0 |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package Labyrinth::Plugin::Review; | ||||||
| 2 | |||||||
| 3 | 5 | 5 | 76811 | use warnings; | |||
| 5 | 9 | ||||||
| 5 | 205 | ||||||
| 4 | 5 | 5 | 21 | use strict; | |||
| 5 | 6 | ||||||
| 5 | 135 | ||||||
| 5 | |||||||
| 6 | 5 | 5 | 17 | use vars qw($VERSION); | |||
| 5 | 9 | ||||||
| 5 | 305 | ||||||
| 7 | $VERSION = '1.01'; | ||||||
| 8 | |||||||
| 9 | =head1 NAME | ||||||
| 10 | |||||||
| 11 | Labyrinth::Plugin::Review - Reviews plugin for the Labyrinth framework | ||||||
| 12 | |||||||
| 13 | =head1 DESCRIPTION | ||||||
| 14 | |||||||
| 15 | Contains all the functionality for book reviews. | ||||||
| 16 | |||||||
| 17 | =cut | ||||||
| 18 | |||||||
| 19 | # ------------------------------------- | ||||||
| 20 | # Library Modules | ||||||
| 21 | |||||||
| 22 | 5 | 5 | 20 | use base qw(Labyrinth::Plugin::Base); | |||
| 5 | 5 | ||||||
| 5 | 4518 | ||||||
| 23 | |||||||
| 24 | use Clone qw(clone); | ||||||
| 25 | use Labyrinth::Audit; | ||||||
| 26 | use Labyrinth::DBUtils; | ||||||
| 27 | use Labyrinth::DTUtils; | ||||||
| 28 | use Labyrinth::MLUtils; | ||||||
| 29 | use Labyrinth::Media; | ||||||
| 30 | use Labyrinth::Session; | ||||||
| 31 | use Labyrinth::Support; | ||||||
| 32 | use Labyrinth::Users; | ||||||
| 33 | use Labyrinth::Variables; | ||||||
| 34 | |||||||
| 35 | use Data::Dumper; | ||||||
| 36 | |||||||
| 37 | # ------------------------------------- | ||||||
| 38 | # Constants | ||||||
| 39 | |||||||
| 40 | use constant FRONTPAGE => 10; | ||||||
| 41 | use constant COVER_WIDTH => 150; | ||||||
| 42 | use constant COVER_HEIGHT => 200; | ||||||
| 43 | |||||||
| 44 | # ------------------------------------- | ||||||
| 45 | # Variables | ||||||
| 46 | |||||||
| 47 | # type: 0 = optional, 1 = mandatory | ||||||
| 48 | # html: 0 = none, 1 = text, 2 = textarea | ||||||
| 49 | |||||||
| 50 | my %fields = ( | ||||||
| 51 | # review references | ||||||
| 52 | reviewid => { type => 0, html => 0 }, | ||||||
| 53 | title => { type => 1, html => 1 }, | ||||||
| 54 | userid => { type => 1, html => 0 }, | ||||||
| 55 | reviewtypeid => { type => 1, html => 0 }, | ||||||
| 56 | postdate => { type => 1, html => 0 }, | ||||||
| 57 | imageid => { type => 0, html => 0 }, | ||||||
| 58 | snippet => { type => 0, html => 2 }, | ||||||
| 59 | body => { type => 1, html => 2 }, | ||||||
| 60 | publish => { type => 1, html => 0 }, | ||||||
| 61 | additional => { type => 0, html => 1 }, | ||||||
| 62 | |||||||
| 63 | # item references | ||||||
| 64 | brand => { type => 1, html => 1 }, | ||||||
| 65 | retailerid => { type => 1, html => 0 }, | ||||||
| 66 | itemcode => { type => 1, html => 0 }, | ||||||
| 67 | itemlink => { type => 1, html => 0 }, | ||||||
| 68 | ); | ||||||
| 69 | |||||||
| 70 | my (@mandatory,@allfields); | ||||||
| 71 | for(keys %fields) { | ||||||
| 72 | push @mandatory, $_ if($fields{$_}->{type}); | ||||||
| 73 | push @allfields, $_; | ||||||
| 74 | } | ||||||
| 75 | |||||||
| 76 | # ------------------------------------- | ||||||
| 77 | # The Subs | ||||||
| 78 | |||||||
| 79 | =head1 PUBLIC INTERFACE METHODS | ||||||
| 80 | |||||||
| 81 | =over 4 | ||||||
| 82 | |||||||
| 83 | =item * FrontPage | ||||||
| 84 | |||||||
| 85 | Provides the an abbreviated list of the latest reviews to use on the front | ||||||
| 86 | page or a side panel of the website. | ||||||
| 87 | |||||||
| 88 | =item * List | ||||||
| 89 | |||||||
| 90 | Provides a full list, filtered based on any search criteria, of reviews for | ||||||
| 91 | the main reviews page on the website. | ||||||
| 92 | |||||||
| 93 | =item * Item | ||||||
| 94 | |||||||
| 95 | Provides all the details for a specific review. | ||||||
| 96 | |||||||
| 97 | =back | ||||||
| 98 | |||||||
| 99 | =cut | ||||||
| 100 | |||||||
| 101 | sub FrontPage { | ||||||
| 102 | my @rows; | ||||||
| 103 | my @time = split("/",formatDate(9)); | ||||||
| 104 | my $this = "$time[0]/$time[1]"; | ||||||
| 105 | $time[1]--; | ||||||
| 106 | if($time[1] < 1) { $time[0]--;$time[1]=12; } | ||||||
| 107 | my $that = "$time[0]/$time[1]"; | ||||||
| 108 | |||||||
| 109 | |||||||
| 110 | my $stop = $settings{'frontpage'} || FRONTPAGE; | ||||||
| 111 | my $next = $dbi->Iterator('hash','PubReviews'); | ||||||
| 112 | while(@rows < $stop && (my $row = $next->())) { | ||||||
| 113 | $row->{new} = ($row->{createdate} =~ m!^($this|$that)! ? 1 : 0); | ||||||
| 114 | push @rows, $row; | ||||||
| 115 | } | ||||||
| 116 | $tvars{reviews} = \@rows if(@rows); | ||||||
| 117 | } | ||||||
| 118 | |||||||
| 119 | sub List { | ||||||
| 120 | my $publish = 3 unless($tvars{command} eq 'admin'); | ||||||
| 121 | |||||||
| 122 | my @where; | ||||||
| 123 | push @where, "r.publish=$publish" if($publish); | ||||||
| 124 | push @where, "r.title LIKE '%$cgiparams{'searchtitle'}%'" if($cgiparams{'searchtitle'}); | ||||||
| 125 | push @where, "r.reviewtypeid=$cgiparams{'reviewtypeid'}" if($cgiparams{'reviewtypeid'}); | ||||||
| 126 | push @where, "r.userid=$cgiparams{'userid'}" if($cgiparams{'userid'}); | ||||||
| 127 | push @where, "r.brand=$cgiparams{'brand'}" if($cgiparams{'brand'}); | ||||||
| 128 | push @where, "r.retailerid=$cgiparams{'retailerid'}" if($cgiparams{'retailerid'}); | ||||||
| 129 | my $where = @where ? 'WHERE '.join(' AND ',@where) : ''; | ||||||
| 130 | |||||||
| 131 | my @rows = $dbi->GetQuery('hash','AllReviews',{where=>$where}); | ||||||
| 132 | foreach (@rows) { | ||||||
| 133 | $_->{publishstate} = PublishState($_->{publish}); | ||||||
| 134 | $_->{postdate} = formatDate(3,$_->{createdate}); | ||||||
| 135 | } | ||||||
| 136 | $tvars{data} = \@rows if(@rows); | ||||||
| 137 | |||||||
| 138 | $tvars{searchtitle} = $cgiparams{searchtitle}; | ||||||
| 139 | $tvars{ddreviewers} = UserSelect($cgiparams{userid},1,1,'Reviewer'); | ||||||
| 140 | $tvars{ddrevtypes} = _dropdownReviewTypes($cgiparams{reviewtypeid},1); | ||||||
| 141 | $tvars{ddretailers} = _dropdownRetailers($cgiparams{retailerid},1); | ||||||
| 142 | } | ||||||
| 143 | |||||||
| 144 | sub Item { | ||||||
| 145 | return unless($cgiparams{'reviewid'}); | ||||||
| 146 | |||||||
| 147 | my @rows = $dbi->GetQuery('hash','GetReviewByID',$cgiparams{'reviewid'}); | ||||||
| 148 | return unless(@rows); | ||||||
| 149 | |||||||
| 150 | if($rows[0]->{'imageid'}) { | ||||||
| 151 | my @img = $dbi->GetQuery('hash','GetImageByID',$rows[0]->{'imageid'}); | ||||||
| 152 | $rows[0]->{'image_link'} = $img[0]->{'link'} if(@img); | ||||||
| 153 | } | ||||||
| 154 | |||||||
| 155 | $rows[0]->{body} = ' ' . $rows[0]->{body} unless($rows[0]->{body} =~ /^ /i); |
||||||
| 156 | $tvars{data} = $rows[0]; | ||||||
| 157 | |||||||
| 158 | if($tvars{data}->{additional}) { | ||||||
| 159 | my $html = ''; | ||||||
| 160 | my @links = split ",", $tvars{data}->{additional}; | ||||||
| 161 | foreach my $link (@links) { | ||||||
| 162 | my ($name,$url) = split "=", $link; | ||||||
| 163 | $html .= qq!$name !; |
||||||
| 164 | } | ||||||
| 165 | $tvars{data}->{additional} = $html; | ||||||
| 166 | } | ||||||
| 167 | } | ||||||
| 168 | |||||||
| 169 | =head1 ADMIN INTERFACE METHODS | ||||||
| 170 | |||||||
| 171 | =over 4 | ||||||
| 172 | |||||||
| 173 | =item * Access | ||||||
| 174 | |||||||
| 175 | Check default access to the Admin methods | ||||||
| 176 | |||||||
| 177 | =item * Admin | ||||||
| 178 | |||||||
| 179 | List reviews for administration purposes. | ||||||
| 180 | |||||||
| 181 | =item * Add | ||||||
| 182 | |||||||
| 183 | Add a review. | ||||||
| 184 | |||||||
| 185 | =item * PreEdit | ||||||
| 186 | |||||||
| 187 | Following an add review page, there may be additional lookuos required to | ||||||
| 188 | check the validity of the product code given. This may be an additonal API | ||||||
| 189 | call to a 3rd party website, and is most likely to be used by sub-classed | ||||||
| 190 | modules. | ||||||
| 191 | |||||||
| 192 | Requires a call to the Edit method to display current values. | ||||||
| 193 | |||||||
| 194 | =item * Copy | ||||||
| 195 | |||||||
| 196 | Copies an existing review to a new review. Typical when you want to use the | ||||||
| 197 | same product to review, and just want to use the same product references. | ||||||
| 198 | |||||||
| 199 | Requires a call to the Edit method to display current values. | ||||||
| 200 | |||||||
| 201 | =item * Edit | ||||||
| 202 | |||||||
| 203 | Edit a review. | ||||||
| 204 | |||||||
| 205 | =item * Save | ||||||
| 206 | |||||||
| 207 | Save a review. | ||||||
| 208 | |||||||
| 209 | =item * Delete | ||||||
| 210 | |||||||
| 211 | Delete one or more reviews. | ||||||
| 212 | |||||||
| 213 | =back | ||||||
| 214 | |||||||
| 215 | =cut | ||||||
| 216 | |||||||
| 217 | sub Access { Authorised(EDITOR) } | ||||||
| 218 | |||||||
| 219 | sub Admin { | ||||||
| 220 | return unless AccessUser(EDITOR); | ||||||
| 221 | |||||||
| 222 | if($cgiparams{doaction}) { | ||||||
| 223 | if($cgiparams{doaction} eq 'Delete') { Delete(); } | ||||||
| 224 | elsif($cgiparams{doaction} eq 'Copy') { Copy(); } | ||||||
| 225 | } | ||||||
| 226 | |||||||
| 227 | List(); | ||||||
| 228 | } | ||||||
| 229 | |||||||
| 230 | sub Add { | ||||||
| 231 | AccessUser(EDITOR); | ||||||
| 232 | |||||||
| 233 | my $select; | ||||||
| 234 | if(Authorised(PUBLISHER)) { | ||||||
| 235 | $select = UserSelect(0,1); | ||||||
| 236 | } else { | ||||||
| 237 | $select = DropDownRows($tvars{user}->{userid},'userid','userid','name',{userid => $tvars{user}->{userid}, name => $tvars{user}->{name}}); | ||||||
| 238 | } | ||||||
| 239 | |||||||
| 240 | my %data = ( | ||||||
| 241 | ddreviewers => $select, | ||||||
| 242 | ddretailers => _dropdownRetailers(), | ||||||
| 243 | ddrevtypes => _dropdownReviewTypes(), | ||||||
| 244 | postdate => formatDate(3), | ||||||
| 245 | ); | ||||||
| 246 | |||||||
| 247 | $tvars{data} = \%data; | ||||||
| 248 | $tvars{preedit} = 1; | ||||||
| 249 | } | ||||||
| 250 | |||||||
| 251 | sub PreEdit { | ||||||
| 252 | my @man = qw(userid reviewtypeid postdate itemcode); | ||||||
| 253 | return if FieldCheck(\@mandatory,\@mandatory); | ||||||
| 254 | |||||||
| 255 | $tvars{data}->{realname} = UserName($tvars{data}->{userid}); | ||||||
| 256 | $tvars{data}->{createdate} = unformatDate(3,$tvars{data}->{postdate}); | ||||||
| 257 | } | ||||||
| 258 | |||||||
| 259 | sub Copy { | ||||||
| 260 | $cgiparams{'reviewid'} = $cgiparams{'LISTED'}; | ||||||
| 261 | return unless AuthorCheck('GetReviewByID','reviewid',PUBLISHER); | ||||||
| 262 | |||||||
| 263 | my @fields = ( | ||||||
| 264 | $tvars{data}->{reviewtypeid},0, | ||||||
| 265 | $tvars{data}->{title}, | ||||||
| 266 | $tvars{data}->{brand}, | ||||||
| 267 | $tvars{data}->{itemcode}, | ||||||
| 268 | $tvars{data}->{userid}, | ||||||
| 269 | $tvars{data}->{createdate}, | ||||||
| 270 | $tvars{data}->{snippet}, | ||||||
| 271 | $tvars{data}->{body}, | ||||||
| 272 | $tvars{data}->{imageid}, | ||||||
| 273 | $tvars{data}->{itemlink}, | ||||||
| 274 | $tvars{data}->{retailerid}, | ||||||
| 275 | 1 | ||||||
| 276 | ); | ||||||
| 277 | |||||||
| 278 | $cgiparams{reviewid} = $dbi->IDQuery('AddReview',@fields); | ||||||
| 279 | } | ||||||
| 280 | |||||||
| 281 | sub Edit { | ||||||
| 282 | if($cgiparams{reviewid}) { | ||||||
| 283 | return unless AuthorCheck('GetReviewByID','reviewid',PUBLISHER); | ||||||
| 284 | |||||||
| 285 | if($tvars{data}->{'imageid'}) { | ||||||
| 286 | my @img = $dbi->GetQuery('hash','GetImageByID',$tvars{data}->{'imageid'}); | ||||||
| 287 | $tvars{data}->{'image_link'} = $img[0]->{'link'} if(@img); | ||||||
| 288 | } | ||||||
| 289 | |||||||
| 290 | if($tvars{data}->{publish} == 4 && $tvars{command} ne 'view') { | ||||||
| 291 | $tvars{errcode} = 'FAILURE'; | ||||||
| 292 | return; | ||||||
| 293 | } | ||||||
| 294 | } | ||||||
| 295 | |||||||
| 296 | my $select; | ||||||
| 297 | if(Authorised(PUBLISHER)) { | ||||||
| 298 | $select = UserSelect($tvars{data}->{userid},1,1); | ||||||
| 299 | } else { | ||||||
| 300 | $select = DropDownRows($tvars{user}->{userid},'userid','userid','name',{userid => $tvars{user}->{userid}, name => $tvars{user}->{name}}); | ||||||
| 301 | } | ||||||
| 302 | |||||||
| 303 | my $promote = 0; | ||||||
| 304 | $promote = 1 if($tvars{data}->{publish} == 1 && Authorised(EDITOR)); | ||||||
| 305 | $promote = 1 if($tvars{data}->{publish} == 2 && Authorised(PUBLISHER)); | ||||||
| 306 | $promote = 1 if($tvars{data}->{publish} == 3 && Authorised(PUBLISHER)); | ||||||
| 307 | $tvars{data}->{ddpublish} = PublishAction($tvars{data}->{publish},$promote); | ||||||
| 308 | $tvars{data}->{ddpublish} = PublishSelect($tvars{data}->{publish}) if(Authorised(ADMIN)); | ||||||
| 309 | |||||||
| 310 | $tvars{data}->{ddreviewers} = $select; | ||||||
| 311 | $tvars{data}->{ddretailers} = _dropdownRetailers($tvars{data}->{retailerid}); | ||||||
| 312 | $tvars{data}->{ddrevtypes} = _dropdownReviewTypes($tvars{data}->{reviewtypeid}); | ||||||
| 313 | $tvars{data}->{postdate} = formatDate(3,$tvars{data}->{createdate}); | ||||||
| 314 | |||||||
| 315 | $tvars{preview} = clone($tvars{data}); # data fields need to be editable | ||||||
| 316 | |||||||
| 317 | for(keys %fields) { | ||||||
| 318 | if($fields{$_}->{html} == 1) { $tvars{data}->{$_} = CleanHTML($tvars{data}->{$_}); | ||||||
| 319 | $tvars{preview}->{$_} = CleanHTML($tvars{preview}->{$_}); } | ||||||
| 320 | elsif($fields{$_}->{html} == 2) { $tvars{data}->{$_} = SafeHTML($tvars{data}->{$_}); } | ||||||
| 321 | } | ||||||
| 322 | |||||||
| 323 | if($tvars{data}->{additional}) { | ||||||
| 324 | my $html = ''; | ||||||
| 325 | my @links = split ",", $tvars{data}->{additional}; | ||||||
| 326 | foreach my $link (@links) { | ||||||
| 327 | my ($name,$url) = split "=", $link; | ||||||
| 328 | $html .= qq!$name !; |
||||||
| 329 | } | ||||||
| 330 | $tvars{preview}->{additional} = $html; | ||||||
| 331 | } | ||||||
| 332 | } | ||||||
| 333 | |||||||
| 334 | sub Save { | ||||||
| 335 | return unless AuthorCheck('GetReviewByID','reviewid',PUBLISHER); | ||||||
| 336 | return if FieldCheck(\@allfields,\@mandatory); | ||||||
| 337 | |||||||
| 338 | for(keys %fields) { | ||||||
| 339 | if($fields{$_}->{html} == 1) { $tvars{data}->{$_} = CleanHTML($tvars{data}->{$_}) } | ||||||
| 340 | elsif($fields{$_}->{html} == 2) { $tvars{data}->{$_} = CleanTags($tvars{data}->{$_}) } | ||||||
| 341 | } | ||||||
| 342 | |||||||
| 343 | $tvars{data}->{createdate} = unformatDate(3,$tvars{data}->{postdate}) if($tvars{data}->{postdate}); | ||||||
| 344 | ($tvars{data}->{imageid}) = SaveImageFile( | ||||||
| 345 | param => 'image_link', | ||||||
| 346 | width => $settings{review_cover_width} || COVER_WIDTH, | ||||||
| 347 | height => $settings{review_cover_height} || COVER_HEIGHT, | ||||||
| 348 | stock => 'Covers' | ||||||
| 349 | ) if($cgiparams{image_link}); | ||||||
| 350 | |||||||
| 351 | my @fields = ( | ||||||
| 352 | $tvars{data}->{reviewtypeid}, | ||||||
| 353 | 0, | ||||||
| 354 | $tvars{data}->{title}, | ||||||
| 355 | $tvars{data}->{brand}, | ||||||
| 356 | $tvars{data}->{itemcode}, | ||||||
| 357 | $tvars{data}->{userid}, | ||||||
| 358 | $tvars{data}->{createdate}, | ||||||
| 359 | $tvars{data}->{snippet}, | ||||||
| 360 | $tvars{data}->{body}, | ||||||
| 361 | $tvars{data}->{imageid}, | ||||||
| 362 | $tvars{data}->{itemlink}, | ||||||
| 363 | $tvars{data}->{retailerid}, | ||||||
| 364 | $tvars{data}->{publish} | ||||||
| 365 | ); | ||||||
| 366 | |||||||
| 367 | # store review details | ||||||
| 368 | if($tvars{data}->{reviewid}) | ||||||
| 369 | { $dbi->DoQuery('SaveReview',@fields,$tvars{data}->{reviewid}); } | ||||||
| 370 | else { $cgiparams{reviewid} = $dbi->IDQuery('AddReview',@fields); } | ||||||
| 371 | |||||||
| 372 | $tvars{thanks} = 1; | ||||||
| 373 | } | ||||||
| 374 | |||||||
| 375 | sub Delete { | ||||||
| 376 | return unless AccessUser(PUBLISHER); | ||||||
| 377 | my @ids = CGIArray('LISTED'); | ||||||
| 378 | return unless @ids; | ||||||
| 379 | |||||||
| 380 | for my $id (@ids) { | ||||||
| 381 | $cgiparams{'reviewid'} = $id; | ||||||
| 382 | next unless AuthorCheck('GetReviewByID','reviewid',PUBLISHER); | ||||||
| 383 | $dbi->DoQuery('DeleteReview',$cgiparams{'reviewid'}); | ||||||
| 384 | } | ||||||
| 385 | } | ||||||
| 386 | |||||||
| 387 | # ------------------------------------- | ||||||
| 388 | # Private Methods | ||||||
| 389 | |||||||
| 390 | sub _dropdownRetailers { | ||||||
| 391 | my ($select,$blank) = @_; | ||||||
| 392 | my @rows = $dbi->GetQuery('hash','AllRetailers'); | ||||||
| 393 | unshift @rows, {retailerid=>0,retailer=>'Select Retailer'} if(defined $blank && $blank == 1); | ||||||
| 394 | return DropDownRows($select,'retailerid','retailerid','retailer',@rows); | ||||||
| 395 | } | ||||||
| 396 | |||||||
| 397 | sub _dropdownReviewTypes { | ||||||
| 398 | my ($select,$blank) = @_; | ||||||
| 399 | my @rows = $dbi->GetQuery('hash','AllReviewTypes'); | ||||||
| 400 | unshift @rows, {reviewtypeid=>0,typename=>'Select Review Type'} if(defined $blank && $blank == 1); | ||||||
| 401 | return DropDownRows($select,'reviewtypeid','reviewtypeid','typename',@rows); | ||||||
| 402 | } | ||||||
| 403 | |||||||
| 404 | 1; | ||||||
| 405 | |||||||
| 406 | __END__ |