Revision 480 (by ahitrov, 2015/03/03 12:14:40) |
Tags plugin: initial import
|
package tag::Cloud;
use base 'Contenido::Link';
use Contenido::Globals;
use Data::Recursive::Encode;
use Data::Dumper;
use JSON::XS;
sub class_name
{
return 'Тег к объекту';
}
sub class_description
{
return 'Организация облака тегов';
}
sub extra_properties
{
return (
);
}
sub available_sources
{
return [ qw(tag::Tag) ];
}
sub available_destinations
{
return $state->{tag}->tag_destinations;
}
sub class_table
{
return 'tag::SQL::TagsCloudTable';
}
sub pre_store
{
my $self = shift;
return 1;
}
sub post_store
{
my $self = shift;
warn "Store tag cloud element\n" if $DEBUG;
my $object = $keeper->get_document_by_id($self->dest_id, class => $self->dest_class ) if $self->dest_id && $self->dest_class;
my $tag = $self->keeper->get_document_by_id($self->source_id, class => $self->source_class ) if $self->source_id && $self->source_class;
if ( ref $object && ref $tag ) {
my ($prop) = grep { $_->{type} eq 'tagset' } $object->structure;
my $class = $object->class;
my $is_extra = grep { ref $_ && $_->{attr} eq $name } $class->extra_properties ? 1 : 0;
if ( ref $prop && !(exists $prop->{virtual} && $prop->{virtual}) ) {
my $name = $prop->{attr};
my $struct;
if ( ref $object->$name ) {
$struct = $object->$name;
} elsif ( $object->$name ) {
$struct = JSON::XS->new->utf8->decode( $object->$name );
}
if ( ref $struct eq 'ARRAY' && @$struct && !(grep { $_->{id} == $tag->id } @$struct) ) {
push @$struct, { id => $tag->id, name => Encode::decode('utf-8', $tag->name) };
unless ( $is_extra ) {
$struct = Encode::encode('utf-8', JSON::XS->new->encode( $struct ));
}
$object->$name( $struct );
$object->store;
}
}
} else {
warn "Tag Cloud update error: cloud_element_id=".$self->id.", no source or destination available\n";
}
}
sub post_delete
{
my $self = shift;
my $object = $keeper->get_document_by_id($self->dest_id, class => $self->dest_class ) if $self->dest_id && $self->dest_class;
my $tag = $self->keeper->get_document_by_id($self->source_id, class => $self->source_class ) if $self->source_id && $self->source_class;
if ( ref $object && ref $tag ) {
my ($prop) = grep { $_->{type} eq 'tagset' } $object->structure;
my $class = $object->class;
my $is_extra = grep { ref $_ && $_->{attr} eq $name } $class->extra_properties ? 1 : 0;
if ( ref $prop && !(exists $prop->{virtual} && $prop->{virtual}) ) {
my $name = $prop->{attr};
my $struct;
if ( ref $object->$name ) {
$struct = $object->$name;
} elsif ( $object->$name ) {
$struct = JSON::XS->new->utf8->decode( $object->$name );
}
if ( ref $struct eq 'ARRAY' && @$struct && (grep { $_->{id} == $tag->id } @$struct) ) {
@$struct = grep { $_->{id} != $tag->id } @$struct;
unless ( $is_extra ) {
$struct = Encode::encode('utf-8', JSON::XS->new->encode( $struct ));
}
$object->$name( $struct );
$object->store;
}
}
} else {
warn "Tag Cloud delete error: cloud_element_id=".$self->id.", no source or destination available\n";
}
}
1;