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;