summaryrefslogtreecommitdiff
path: root/lib/VNDB/Handler/Producers.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VNDB/Handler/Producers.pm')
-rw-r--r--lib/VNDB/Handler/Producers.pm160
1 files changed, 144 insertions, 16 deletions
diff --git a/lib/VNDB/Handler/Producers.pm b/lib/VNDB/Handler/Producers.pm
index e6477567..4e75962b 100644
--- a/lib/VNDB/Handler/Producers.pm
+++ b/lib/VNDB/Handler/Producers.pm
@@ -3,11 +3,12 @@ package VNDB::Handler::Producers;
use strict;
use warnings;
-use YAWF ':html', ':xml';
+use YAWF ':html', ':xml', 'xml_escape';
use VNDB::Func;
YAWF::register(
+ qr{p([1-9]\d*)/rg} => \&rg,
qr{p([1-9]\d*)(?:\.([1-9]\d*))?} => \&page,
qr{p(?:([1-9]\d*)(?:\.([1-9]\d*))?/edit|/new)}
=> \&edit,
@@ -16,12 +17,34 @@ YAWF::register(
);
+sub rg {
+ my($self, $pid) = @_;
+
+ my $p = $self->dbProducerGet(id => $pid, what => 'relgraph')->[0];
+ return 404 if !$p->{id} || !$p->{rgraph};
+
+ my $title = mt '_prodrg_title', $p->{name};
+ return if $self->htmlRGHeader($title, 'p', $p);
+
+ $p->{svg} =~ s/\$___(_prodrel_[a-z]+)____\$/mt $1/eg;
+ $p->{svg} =~ s/\$(_lang_[a-z]+)_\$/mt $1/eg;
+ $p->{svg} =~ s/\$(_ptype_[a-z]+)_\$/mt $1/eg;
+
+ div class => 'mainbox';
+ h1 $title;
+ p class => 'center';
+ lit $p->{svg};
+ end;
+ end;
+ $self->htmlFooter;
+}
+
sub page {
my($self, $pid, $rev) = @_;
my $p = $self->dbProducerGet(
id => $pid,
- what => 'vn extended'.($rev ? ' changes' : ''),
+ what => 'vn extended relations'.($rev ? ' changes' : ''),
$rev ? ( rev => $rev ) : ()
)->[0];
return 404 if !$p->{id};
@@ -31,7 +54,7 @@ sub page {
return if $self->htmlHiddenMessage('p', $p);
if($rev) {
- my $prev = $rev && $rev > 1 && $self->dbProducerGet(id => $pid, rev => $rev-1, what => 'changes extended')->[0];
+ my $prev = $rev && $rev > 1 && $self->dbProducerGet(id => $pid, rev => $rev-1, what => 'changes extended relations')->[0];
$self->htmlRevision('p', $prev, $p,
[ type => serialize => sub { mt "_ptype_$_[0]" } ],
[ name => diff => 1 ],
@@ -40,6 +63,12 @@ sub page {
[ lang => serialize => sub { "$_[0] (".mt("_lang_$_[0]").')' } ],
[ website => diff => 1 ],
[ desc => diff => 1 ],
+ [ relations => join => '<br />', split => sub {
+ my @r = map sprintf('%s: <a href="/p%d" title="%s">%s</a>',
+ mt("_prodrel_$_->{relation}"), $_->{id}, xml_escape($_->{original}||$_->{name}), xml_escape shorten $_->{name}, 40
+ ), sort { $a->{id} <=> $b->{id} } @{$_[0]};
+ return @r ? @r : (mt '_proddiff_none');
+ }],
);
}
@@ -56,6 +85,23 @@ sub page {
}
end;
+ if(@{$p->{relations}}) {
+ my %rel;
+ push @{$rel{$_->{relation}}}, $_
+ for (sort { $a->{name} cmp $b->{name} } @{$p->{relations}});
+ p class => 'center';
+ txt "\n";
+ for my $r (sort keys %rel) {
+ txt mt("_prodrel_$r").': ';
+ for (@{$rel{$r}}) {
+ a href => "/p$_->{id}", title => $_->{original}||$_->{name}, shorten $_->{name}, 40;
+ txt ', ' if $_ ne $rel{$r}[$#{$rel{$r}}];
+ }
+ txt "\n";
+ }
+ end;
+ }
+
if($p->{desc}) {
p class => 'description';
lit bb2html $p->{desc};
@@ -75,6 +121,8 @@ sub page {
lit $self->{l10n}->datestr($_->{date});
end;
a href => "/v$_->{id}", title => $_->{original}, $_->{title};
+ b class => 'grayedout', ' ('.join(', ',
+ $_->{developer} ? mt '_prodpage_dev' : (), $_->{publisher} ? mt '_prodpage_pub' : ()).')';
end;
}
end;
@@ -89,36 +137,55 @@ sub page {
sub edit {
my($self, $pid, $rev) = @_;
- my $p = $pid && $self->dbProducerGet(id => $pid, what => 'changes extended', $rev ? (rev => $rev) : ())->[0];
+ my $p = $pid && $self->dbProducerGet(id => $pid, what => 'changes extended relations', $rev ? (rev => $rev) : ())->[0];
return 404 if $pid && !$p->{id};
$rev = undef if !$p || $p->{cid} == $p->{latest};
return $self->htmlDenied if !$self->authCan('edit')
|| $pid && ($p->{locked} && !$self->authCan('lock') || $p->{hidden} && !$self->authCan('del'));
- my %b4 = !$pid ? () : map { $_ => $p->{$_} } qw|type name original lang website desc alias|;
+ my %b4 = !$pid ? () : (
+ (map { $_ => $p->{$_} } qw|type name original lang website desc alias|),
+ prodrelations => join('|||', map $_->{relation}.','.$_->{id}.','.$_->{name}, sort { $a->{id} <=> $b->{id} } @{$p->{relations}}),
+ );
my $frm;
if($self->reqMethod eq 'POST') {
$frm = $self->formValidate(
- { name => 'type', enum => $self->{producer_types} },
- { name => 'name', maxlength => 200 },
- { name => 'original', required => 0, maxlength => 200, default => '' },
- { name => 'alias', required => 0, maxlength => 500, default => '' },
- { name => 'lang', enum => $self->{languages} },
- { name => 'website', required => 0, template => 'url', default => '' },
- { name => 'desc', required => 0, maxlength => 5000, default => '' },
- { name => 'editsum', maxlength => 5000 },
+ { name => 'type', enum => $self->{producer_types} },
+ { name => 'name', maxlength => 200 },
+ { name => 'original', required => 0, maxlength => 200, default => '' },
+ { name => 'alias', required => 0, maxlength => 500, default => '' },
+ { name => 'lang', enum => $self->{languages} },
+ { name => 'website', required => 0, template => 'url', default => '' },
+ { name => 'desc', required => 0, maxlength => 5000, default => '' },
+ { name => 'prodrelations', required => 0, maxlength => 5000, default => '' },
+ { name => 'editsum', maxlength => 5000 },
);
if(!$frm->{_err}) {
+ # parse
+ my $relations = [ map { /^([a-z]+),([0-9]+),(.+)$/ && (!$pid || $2 != $pid) ? [ $1, $2, $3 ] : () } split /\|\|\|/, $frm->{prodrelations} ];
+
+ # normalize
+ $frm->{prodrelations} = join '|||', map $_->[0].','.$_->[1].','.$_->[2], sort { $a->[1] <=> $b->[1]} @{$relations};
+
return $self->resRedirect("/p$pid", 'post')
if $pid && !grep $frm->{$_} ne $b4{$_}, keys %b4;
+ $frm->{relations} = $relations;
$rev = 1;
+ my $cid;
if($pid) {
- ($rev) = $self->dbProducerEdit($pid, %$frm);
+ ($rev, $cid) = $self->dbProducerEdit($pid, %$frm);
} else {
- ($pid) = $self->dbProducerAdd(%$frm);
+ ($pid, $cid) = $self->dbProducerAdd(%$frm);
+ }
+
+ # update reverse relations
+ if(!$pid && $#$relations >= 0 || $pid && $frm->{prodrelations} ne $b4{prodrelations}) {
+ my %old = $pid ? (map { $_->{id} => $_->{relation} } @{$p->{relations}}) : ();
+ my %new = map { $_->[1] => $_->[0] } @$relations;
+ _updreverse($self, \%old, \%new, $pid, $cid, $rev);
}
return $self->resRedirect("/p$pid.$rev", 'post');
@@ -133,7 +200,8 @@ sub edit {
$self->htmlHeader(title => $title, noindex => 1);
$self->htmlMainTabs('p', $p, 'edit') if $pid;
$self->htmlEditMessage('p', $p, $title);
- $self->htmlForm({ frm => $frm, action => $pid ? "/p$pid/edit" : '/p/new', editsum => 1 }, 'pedit_geninfo' => [mt('_pedit_form_generalinfo'),
+ $self->htmlForm({ frm => $frm, action => $pid ? "/p$pid/edit" : '/p/new', editsum => 1 },
+ 'pedit_geninfo' => [ mt('_pedit_form_generalinfo'),
[ select => name => mt('_pedit_form_type'), short => 'type',
options => [ map [ $_, mt "_ptype_$_" ], sort @{$self->{producer_types}} ] ],
[ input => name => mt('_pedit_form_name'), short => 'name' ],
@@ -145,10 +213,70 @@ sub edit {
options => [ map [ $_, "$_ (".mt("_lang_$_").')' ], sort @{$self->{languages}} ] ],
[ input => name => mt('_pedit_form_website'), short => 'website' ],
[ text => name => mt('_pedit_form_desc').'<br /><b class="standout">'.mt('_inenglish').'</b>', short => 'desc', rows => 6 ],
+ ], 'pedit_rel' => [ mt('_pedit_form_rel'),
+ [ hidden => short => 'prodrelations' ],
+ [ static => nolabel => 1, content => sub {
+ h2 mt '_pedit_rel_sel';
+ table;
+ tbody id => 'relation_tbl';
+ # to be filled using javascript
+ end;
+ end;
+
+ h2 mt '_pedit_rel_add';
+ table;
+ Tr id => 'relation_new';
+ td class => 'tc_prod';
+ input type => 'text', class => 'text';
+ end;
+ td class => 'tc_rel';
+ Select;
+ option value => $_, mt "_prodrel_$_"
+ for (sort { $self->{prod_relations}{$a}[0] <=> $self->{prod_relations}{$b}[0] } keys %{$self->{prod_relations}});
+ end;
+ end;
+ td class => 'tc_add';
+ a href => '#', mt '_pedit_rel_addbut';
+ end;
+ end;
+ end;
+ }],
]);
$self->htmlFooter;
}
+# !IMPORTANT!: Don't forget to update this function when
+# adding/removing fields to/from producer entries!
+sub _updreverse {
+ my($self, $old, $new, $pid, $cid, $rev) = @_;
+ my %upd;
+
+ # compare %old and %new
+ for (keys %$old, keys %$new) {
+ if(exists $$old{$_} and !exists $$new{$_}) {
+ $upd{$_} = undef;
+ } elsif((!exists $$old{$_} and exists $$new{$_}) || ($$old{$_} ne $$new{$_})) {
+ $upd{$_} = $self->{prod_relations}{$$new{$_}}[1];
+ }
+ }
+
+ return if !keys %upd;
+
+ # edit all related producers
+ for my $i (keys %upd) {
+ my $r = $self->dbProducerGet(id => $i, what => 'extended relations')->[0];
+ my @newrel = map $_->{id} != $pid ? [ $_->{relation}, $_->{id} ] : (), @{$r->{relations}};
+ push @newrel, [ $upd{$i}, $pid ] if $upd{$i};
+ $self->dbProducerEdit($i,
+ relations => \@newrel,
+ editsum => "Reverse relation update caused by revision p$pid.$rev",
+ causedby => $cid,
+ uid => 1, # Multi - hardcoded
+ ( map { $_ => $r->{$_} } qw|type name original lang website desc alias| )
+ );
+ }
+}
+
sub list {
my($self, $char) = @_;