package Bric::Biz::Asset; ############################################################################### =head1 NAME Bric::Biz::Asset - A base class of behaviours that all assets must exhibit. An asset is anything that goes through workflow =head1 VERSION $LastChangedRevision$ =cut require Bric; our $VERSION = Bric->VERSION; =head1 DATE $LastChangedDate: 2007-01-29 20:45:23 +0100 (Mon, 29 Jan 2007) $ =head1 SYNOPSIS # Class Methods $key_name = Bric::Biz::Asset->key_name() %priorities = Bric::Biz::Asset->list_priorities() $data = Bric::Biz::Asset->my_meths # looking up of objects ($asset_list || @assets) = Bric::Biz::Asset->list( $param ) # General information $asset = $asset->get_id() $asset = $asset->set_name($name) $name = $asset->get_name() $asset = $asset->set_description($description) $description = $asset->get_description() $priority = $asset->get_priority() $asset = $asset->set_priority($priority) $site_id = $asset->get_site_id() $asset = $asset->set_site_id($site_id) # User information $usr_id = $asset->get_user__id() $modifier = $asset->get_modifier() # Version information $vers = $asset->get_version(); $vers_id = $asset->get_version_id(); $current = $asset->get_current_version(); $checked_out = $asset->get_checked_out() # Publish info $needs_publish = $asset->needs_publish(); # Expire Data Information $asset = $asset->set_expire_date($date) $expire_date = $asset->get_expire_date() # Desk information $desk = $asset->get_current_desk; $asset = $asset->set_current_desk($desk); # Workflow methods. $id = $asset->get_workflow_id; $obj = $asset->get_workflow_object; $asset = $asset->set_workflow_id($id); # Access note information $asset = $asset->set_note($note); my $note = $asset->get_note; my $notes_href = $asset->get_notes() # Access active status $asset = $asset->deactivate() $asset = $asset->activate() ($asset || undef) = $asset->is_active() $asset = $asset->save() # returns all the groups this is a member of ($grps || @grps) = $asset->get_grp_ids() =head1 DESCRIPTION Asset is the Parent Class for everything that will go through Workflow. It contains data and actions that are common to all of these objects. Asset holds information on desks visited by the object, notes associated with the object, and versioning information. Actions that can be preformed are fork which prepares an object to be edited in a checked out state, cancel, which cancels the fork, merge which takes the forked object compares it to the stored main version and creates a new version and revert which is called on a forked object which returns the state of the object at a given version id. A fork will preform a copy in the database keeping the asset id, and version number the same but will associate a user with the object. =cut #==============================================================================# # Dependencies # #======================================# #--------------------------------------# # Standard Dependencies use strict; use List::Util qw(first); #--------------------------------------# # Programmatic Dependencies use Bric::Util::Fault qw(throw_gen throw_mni); use Bric::Biz::Workflow; use Bric::Util::Time qw(:all); use Bric::Util::DBI qw(:all); #==============================================================================# # Inheritance # #======================================# # The parent module should have a 'use' line if you need to import from it. # use Bric; use base qw(Bric); #=============================================================================# # Function Prototypes # #======================================# # None #==============================================================================# # Constants # #======================================# use constant DEBUG => 0; sub RO_FIELDS () { return } use constant RO_COLUMNS => ''; use constant OBJECT_SELECT_COLUMN_NUMBER => 0; use constant HAS_MULTISITE => 1; #==============================================================================# # Fields # #======================================# #--------------------------------------# # Public Class Fields # Public fields should use 'vars' #use vars qw(); #--------------------------------------# # Private Class Fields my $meths; my @ord = qw(id version_id name description priority uri cover_date version element_type needs_publish publish_status expire_date active site_id site); #--------------------------------------# # Instance Fields # None # This method of Bricolage will call 'use fields' for you and set some permissions. BEGIN { Bric::register_fields({ # Public Fields name => Bric::FIELD_RDWR, description => Bric::FIELD_RDWR, version => Bric::FIELD_READ, user__id => Bric::FIELD_READ, id => Bric::FIELD_READ, version_id => Bric::FIELD_READ, current_version => Bric::FIELD_READ, published_version => Bric::FIELD_RDWR, priority => Bric::FIELD_RDWR, modifier => Bric::FIELD_READ, expire_date => Bric::FIELD_RDWR, checked_out => Bric::FIELD_READ, workflow_id => Bric::FIELD_RDWR, desk_id => Bric::FIELD_READ, site_id => Bric::FIELD_RDWR, note => Bric::FIELD_RDWR, # Private Fields _checkin => Bric::FIELD_NONE, _checkout => Bric::FIELD_NONE, _cancel => Bric::FIELD_NONE, _active => Bric::FIELD_NONE, _delete => Bric::FIELD_NONE, _notes => Bric::FIELD_NONE, _got_notes => Bric::FIELD_NONE, _versions => Bric::FIELD_NONE, _desk => Bric::FIELD_NONE, _site => Bric::FIELD_NONE, }); } #==============================================================================# # Interface Methods # #======================================# =head1 INTERFACE =head2 Constructors =over 4 =cut #--------------------------------------# # Constructors #------------------------------------------------------------------------------# sub new { my ($pkg, $init) = @_; @{$init}{qw(workflow_id desk_id)} = (0, 0); $pkg->SUPER::new($init); } =item $asset = Bric::Biz::Asset::Business::Story->lookup({ id => $id }) =item $asset = Bric::Biz::Asset::Business::Media->lookup({ id => $id }) =item $asset = Bric::Biz::Asset::Template->lookup({ id => $id }) This will return an asset that matches the ID provided. B "Missing required parameter 'id'" B NONE B NONE =cut sub lookup { my ($pkg, $param) = @_; $pkg = ref $pkg || $pkg; throw_gen(error => "Missing Required Parameters id or uuid or version_id") unless $param->{id} || $param->{version_id} || $param->{uuid} || ($param->{alias_id} && $param->{site_id}); throw_mni(error => 'Must call list on Story, Media, or Template') unless $pkg->CAN_DO_LOOKUP; # Check the cache. my $obj = $pkg->cache_lookup($param); return $obj if $obj; $param = clean_params($pkg, $param); # Lookup can return active and inactive assets. delete $param->{active}; # we generally want the newest version. will use order to get it $param->{Order} = 'version'; $param->{OrderDirection} = 'DESC'; my $tables = tables($pkg, $param); my ($where, $args) = where_clause($pkg, $param); my $order = order_by($pkg, $param); my $grp_by = group_by($pkg, $param); my $sql = build_query($pkg, $pkg->COLUMNS . $pkg->RO_COLUMNS . join (', ', '', $pkg->GROUP_COLS), $grp_by, $tables, $where, $order, @{$param}{qw(Limit Offset)}); my $fields = [ 'id', $pkg->FIELDS, 'version_id', $pkg->VERSION_FIELDS, $pkg->RO_FIELDS, 'grp_ids' ]; my @obj = fetch_objects($pkg, $sql, $fields, scalar $pkg->GROUP_COLS, $args); return unless $obj[0]; return $obj[0]; } ################################################################################ =item (@stories || $stories) = Bric::Biz::Asset::Business::Story->list($params) =item (@media_objs || $media) = Bric::Biz::Asset::Business::Media->list($params) =item (@template_objs || $templates) = Bric::Biz::Asset::Business::Template->list($params) B =over 4 =item Bric::Biz::Asset::Business::Story->list() =item Bric::Biz::Asset::Business::Media->list() =item Bric::Biz::Asset::Business::Template->list() =back =cut sub list { my ($pkg, $param) = @_; $pkg = ref $pkg || $pkg; throw_mni(error => 'Must call list on Story, Media, or Template') unless $pkg->CAN_DO_LIST; $param = clean_params($pkg, $param); my $tables = tables($pkg, $param); my ($where, $args) = where_clause($pkg, $param); my $order = order_by($pkg, $param); my $grp_by = group_by($pkg, $param); my $sql = build_query($pkg, $pkg->COLUMNS . $pkg->RO_COLUMNS . join (', ', '', $pkg->GROUP_COLS), $grp_by, $tables, $where, $order, @{$param}{qw(Limit Offset)}); my $fields = [ 'id', $pkg->FIELDS, 'version_id', $pkg->VERSION_FIELDS, $pkg->RO_FIELDS, 'grp_ids' ]; my @objs = fetch_objects($pkg, $sql, $fields, scalar $pkg->GROUP_COLS, $args); return (wantarray ? @objs : \@objs); } =item (@ids||$ids) = Bric::Biz::Asset::Business::Story->list_ids($params) =item (@ids||$ids) = Bric::Biz::Asset::Business::Media->list_ids($params) =item (@ids||$ids) = Bric::Biz::Asset::Business::Template->list_ids($params) B =over 4 =item Bric::Biz::Asset::Business::Story->list_ids() =item Bric::Biz::Asset::Business::Media->list_ids() =item Bric::Biz::Asset::Business::Template->list_ids() =back =cut sub list_ids { my ($pkg, $param) = @_; $pkg = ref $pkg || $pkg; throw_mni(error => 'Must call list on Story, Media, or Template') unless $pkg->CAN_DO_LIST_IDS; # clean the params $param = clean_params($pkg, $param); delete $param->{Order}; my $cols = 'DISTINCT ' . $pkg->ID_COL; my $tables = tables($pkg, $param); my ($where, $args) = where_clause($pkg, $param); my $order = order_by($pkg, $param); # choose the query type, without grp_ids is faster my $sql = build_query($pkg, $cols, '', $tables, $where, $order); my $select = prepare_ca($$sql, undef); my $return = col_aref($select, @$args); return wantarray ? @{ $return } : $return; } ################################################################################ #--------------------------------------# =back =head2 Destructors =over 4 =item $self->DESTROY Dummy method to prevent wasting time trying to AUTOLOAD DESTROY. =cut sub DESTROY { # This method should be here even if its empty so that we don't waste time # making Bricolage's autoload method try to find it. } ################################################################################ =item my $key_name = Bric::Biz::Asset->key_name() Returns the key name of this class. B NONE. B NONE. B NONE. =cut sub key_name { 'asset' } ################################################################################ =item my (%priorities || $priorities_href) = $asset->list_priorities() Returns a list or anonymous array of the priority labels. Each key is the priority number, and the corresponding value is its label. B NONE. B NONE. B NONE. =cut sub list_priorities { my $p = { 1 => 'High', 2 => 'Medium High', 3 => 'Normal', 4 => 'Medium Low', 5 => 'Low' }; return wantarray ? %$p : $p; } ################################################################################ =item $meths = Bric::Biz::Asset->my_meths =item (@meths || $meths_aref) = Bric::Biz::Asset->my_meths(TRUE) =item my (@meths || $meths_aref) = Bric::Biz::Asset->my_meths(0, TRUE) Returns an anonymous hash of introspection data for this object. If called with a true argument, it will return an ordered list or anonymous array of introspection data. If a second true argument is passed instead of a first, then a list or anonymous array of introspection data will be returned for properties that uniquely identify an object (excluding C, which is assumed). Each hash key is the name of a property or attribute of the object. The value for a hash key is another anonymous hash containing the following keys: =over 4 =item * name - The name of the property or attribute. Is the same as the hash key when an anonymous hash is returned. =item * disp - The display name of the property or attribute. =item * get_meth - A reference to the method that will retrieve the value of the property or attribute. =item * get_args - An anonymous array of arguments to pass to a call to get_meth in order to retrieve the value of the property or attribute. =item * set_meth - A reference to the method that will set the value of the property or attribute. =item * set_args - An anonymous array of arguments to pass to a call to set_meth in order to set the value of the property or attribute. =item * type - The type of value the property or attribute contains. There are only three types: =over 4 =item short =item date =item blob =back =item * len - If the value is a 'short' value, this hash key contains the length of the field. =item * search - The property is searchable via the list() and list_ids() methods. =item * req - The property or attribute is required. =item * props - An anonymous hash of properties used to display the property or attribute. Possible keys include: =over 4 =item type The display field type. Possible values are =item text =item textarea =item password =item hidden =item radio =item checkbox =item select =back =item * length - The Length, in letters, to display a text or password field. =item * maxlength - The maximum length of the property or value - usually defined by the SQL DDL. =item * rows - The number of rows to format in a textarea field. =item * cols - The number of columns to format in a textarea field. =item * vals - An anonymous hash of key/value pairs representing the values and display names to use in a select list. =back B NONE. B NONE. B NONE. =cut sub my_meths { my ($pkg, $ord, $ident) = @_; # We don't got 'em. So get 'em! $meths ||= { id => { name => 'id', get_meth => sub { shift->get_id(@_) }, get_args => [], disp => 'ID', len => 10, type => 'short', }, uuid => { name => 'uuid', get_meth => sub { shift->get_uuid }, get_args => [], disp => 'UUID', len => 36, type => 'short', }, version_id => { name => 'version_id', get_meth => sub { shift->get_version_id(@_) }, get_args => [], disp => 'Version ID', len => 10, type => 'short', }, needs_publish => { name => 'needs_publish', get_meth => sub { shift->needs_publish(@_) }, get_args => [], disp => 'Needs Publish', }, name => { name => 'name', get_meth => sub { shift->get_name(@_) }, get_args => [], set_meth => sub { shift->set_name(@_) }, set_args => [], disp => 'Name', type => 'short', len => 256, req => 1, props => { type => 'text', length => 32, maxlength => 256 } }, description => { name => 'description', get_meth => sub { shift->get_description(@_) }, get_args => [], set_meth => sub { shift->set_description(@_) }, set_args => [], disp => 'Description', req => 0, type => 'short', props => { type => 'textarea', maxlength => 1024, cols => 40, rows => 4 } }, priority => { name => 'priority', get_meth => sub { shift->get_priority(@_) }, get_args => [], set_meth => sub { shift->set_priority(@_) }, set_args => [], disp => 'Priority', type => 'short', len => 1, req => 1, props => { type => 'select', vals => [[ 1 => 'High'], [ 2 => 'Medium High'], [ 3 => 'Normal'], [ 4 => 'Medium Low'], [ 5 => 'Low'], ] } }, uri => { name => 'uri', get_meth => sub { shift->get_uri(@_) }, get_args => [], disp => 'URI', len => 256, type => 'short', }, cover_date => { name => 'cover_date', get_meth => sub { shift->get_cover_date(@_) }, get_args => [], set_meth => sub { shift->set_cover_date(@_) }, set_args => [], search => 1, disp => 'Cover Date', len => 64, req => 0, type => 'short', props => { type => 'date' } }, version => { name => 'version', get_meth => sub { shift->get_version(@_) }, get_args => [], disp => 'Version', len => 10, type => 'short', }, element_type_id => { name => 'element_type_id', get_meth => sub { shift->get_element_type_id(@_) }, get_args => [], set_meth => sub { shift->set_element_type_id(@_) }, set_args => [], disp => 'Element Type ID', len => 10, req => 0, type => 'short', }, element_type => { name => 'element_type', get_meth => sub { my $a_id = shift->get_element_type_id(@_); my $a = Bric::Biz::ElementType->lookup({ id => $a_id }) or return; $a->get_name(); }, get_args => [], disp => 'Element Type', len => 256, type => 'short', props => { type => 'select' }, }, publish_status => { name => 'publish_status', get_meth => sub { shift->get_publish_status(@_) }, get_args => [], disp => 'Status', len => 1, req => 1, type => 'short', }, expire_date => { name => 'expire_date', get_meth => sub { shift->get_expire_date(@_) }, get_args => [], set_meth => sub { shift->set_expire_date(@_) }, set_args => [], disp => 'Expire Date', len => 64, req => 0, type => 'short', props => { type => 'date' } }, active => { name => 'active', get_meth => sub { shift->is_active(@_) ? 1 : 0 }, get_args => [], set_meth => sub { $_[1] ? shift->activate(@_) : shift->deactivate(@_) }, set_args => [], disp => 'Active', len => 1, req => 1, type => 'short', props => { type => 'checkbox' } }, site_id => { get_meth => sub { shift->get_site_id(@_) }, get_args => [], set_meth => sub { shift->set_site_id(@_) }, set_args => [], name => 'site_id', disp => 'Site ID', len => 10, req => 1, type => 'short', props => {} }, site => { get_meth => sub { Bric::Biz::Site->lookup({ id => shift->get_site_id(@_) })->get_name }, get_args => [], name => 'site', disp => 'Site', type => 'short', props => { type => 'text' } }, }; if ($ord) { return wantarray ? @{$meths}{@ord} : [@{$meths}{@ord}]; } elsif ($ident) { return wantarray ? $meths->{version_id} : [$meths->{version_id}]; } else { return $meths; } } #--------------------------------------# =back =head2 Public Instance Methods =over 4 =item $versions = $asset->get_versions Returns an array or array reference the previous versions of this asset in order from the first to the current. B NONE B NONE B NONE =cut sub get_versions { my ($self) = @_; my $versions = $self->_get('_versions'); unless ($versions) { my $dirty = $self->_get__dirty; $versions = $self->list({ id => $self->get_id, return_versions => 1, Order => 'version' }); $self->_set({ _versions => $versions }); $self->_set__dirty($dirty); } return wantarray ? @$versions : $versions; } ################################################################################ =item $name = $self->get_name() Returns the name field from Assets B NONE B NONE B NONE =cut ################################################################################ =item $self = $self->set_name() Sets the name field for Assets B NONE B NONE B NONE =cut ################################################################################ =item $site_id = $asset->get_site_id Returns the ID of the site this asset is a part of. B NONE. B NONE. B NONE. =cut ################################################################################ =item $site = $asset->get_site Returns the the site this asset is a part of. B NONE. B NONE. B NONE. =cut sub get_site { my $self = shift; my $site; unless ($site = $self->_get('_site')) { $self->_set( ['_site'], [ $site = Bric::Biz::Site->lookup({ id => $self->get_site_id }) ] ); } return $site; } ################################################################################ =item $description = $self->get_description() This returns the description for the asset B NONE B NONE B NONE =cut ################################################################################ =item $self = $self->set_description() This sets the description on the asset B NONE B NONE B NONE =cut ################################################################################ =item $priority = $asset->get_priority() This will return the priority that is set upon the asset B NONE B NONE B NONE =cut ################################################################################ =item $asset = $asset->set_priority($priority) This will set the priority for the asset B NONE B NONE B NONE =cut ################################################################################ =item $version = $asset->get_version() Returns the version that this asset represents. B NONE B NONE B NONE =cut ################################################################################ =item $user__id = $asset->get_user__id() Returns the user__id of the person to whom the asset is checked out to B NONE B NONE B NONE =cut ################################################################################ =item $version_id = $asset->get_version_id() Returns the database id of the version of this asset. B NONE B NONE B NONE =cut ################################################################################ =item $current_version = $asset->get_current_version() Returns the version that is the current one. B NONE B NONE B NONE =cut ################################################################################ =item $user__id = $asset->get_modifier() Returns the user id of the person who edited this version of the asset. If the asset is checked out it will be the same as the user who checked it out. B NONE B NONE B NONE =cut ################################################################################ =item $publish_status = $asset->get_publish_status() returns the publish status flag B NONE B NONE B NONE =cut ################################################################################ =item $asset = $asset->set_publish_status($status) sets the publish status flag. B NONE B NONE B NONE =cut ################################################################################ =item $needs_publish = $asset->needs_publish() Compares current_version and published_version from asset table. If the same, needs_publish returns 0. If different, returns 1. B NONE B NONE B NONE =cut sub needs_publish { my $self = shift; # Version 0 is never published. Neither is undef, of course. my $pub_version = $self->get_published_version or return 1; return $self->get_current_version == $pub_version ? 0 : 1; } ################################################################################ =item $checked_out = $asset->get_checked_out() Returns the checked out flag B NONE B NONE B NONE =cut ################################################################################ =item $self = $story->set_expire_date($expire_date) Sets the expire date. B =over 4 =item * Bric::_get() - Problems retrieving fields. =item * Unable to unpack date. =item * Unable to format date. =item * Incorrect number of args to Bric::_set(). =item * Bric::set() - Problems setting fields. =back B NONE B NONE =cut sub set_expire_date { $_[0]->_set(['expire_date'], [db_date($_[1])]) } ################################################################################ =item my $expire_date = $story->get_expire_date($format) Returns expire date. B =over 4 =item * Bric::_get() - Problems retrieving fields. =item * Unable to unpack date. =item * Unable to format date. =back B NONE B NONE =cut sub get_expire_date { local_date($_[0]->_get('expire_date'), $_[1]) } ################################################################################ =item $self = $self->set_current_desk($desk_object); This method takes a desk stamp object and adds it to the asset object B Adds the asset_grp_id of the desk to grp_ids (unless it was already there). =cut sub set_current_desk { my ($self, $desk) = @_; # grp_ids may change as a side effect my $dgid = 0; if (my $c_desk = $self->get_current_desk) { $dgid = $c_desk->get_asset_grp; } my @grp_ids = ((grep { $_ != $dgid } $self->get_grp_ids), $desk->get_asset_grp); $self->_set({grp_ids => \@grp_ids}); # now set the actual value $self->_set([qw(desk_id _desk)] => [$desk->get_id, $desk]); return $self; } ################################################################################ =item $ld = $self->get_current_desk; This returns the desk stamp of the desk that the object is currently at B NONE. B NONE. B NONE. =cut sub get_current_desk { my $self = shift; my ($id, $desk) = $self->_get(qw(desk_id _desk)); return $desk if $desk; return unless $id; # Desk ID 0 is the same as no desk. $desk = Bric::Biz::Workflow::Parts::Desk->lookup({ id => $id }); $self->_set(['_desk'] => [$desk]); return $desk; } ############################################################################## =item $self = $self->remove_from_desk Removes the asset from the current desk. B NONE. B NONE. B NONE. =cut sub remove_from_desk { shift->_set([qw(desk_id _desk)], [0]); } ############################################################################### =item $id = $asset->get_id() This returns the id that uniquely identifies this asset. B NONE B NONE B NONE =cut ################################################################################ =item $id = $asset->get_workflow_id Returns the workflow ID that this asset is a part of B NONE B NONE B NONE =cut ################################################################################ =item $asset = $asset->set_workflow_id( $w_ID ); Sets the workflow that this asset is a member of B Adds the asset group ID of the workflow to grp_ids unless it was already there. =cut sub set_workflow_id { my ($self, $workflow_id) = @_; $workflow_id ||= 0; # grp_ids may change as a side effect my $grp_ids = []; if (my $wf = $self->get_workflow_object) { my $ag_id = $wf->get_asset_grp_id; foreach my $gid ($self->get_grp_ids) { next if $gid == $ag_id; push @$grp_ids, $gid; } } else { $grp_ids = [ grep { $_ != 0 } $self->get_grp_ids ]; } if ($workflow_id) { my $wf = Bric::Biz::Workflow->lookup({ id => $workflow_id }); push @$grp_ids, $wf->get_asset_grp_id; } else { # Set workflow ID to 0 if there is no associated workflow. push @$grp_ids, 0; } # Now set the workflow ID and the group IDs. $self->_set([qw(grp_ids workflow_id)], [$grp_ids, $workflow_id]); } ################################################################################ =item $workflow_obj = $asset->get_workflow_object(); Returns the workflow object that this asset is associated with B NONE B NONE B NONE =cut sub get_workflow_object { my ($self) = @_; my $w_id = $self->get_workflow_id or return; return Bric::Biz::Workflow->lookup({'id' => $w_id}); } ################################################################################ =item $id = $asset->get_desk_id Returns the ID for the desk the asset is currently on. B NONE B NONE B NONE =cut ############################################################################## =item my @grp_ids = $asset->get_grp_ids =item my $grp_ids_aref = $asset->get_grp_ids Returns the IDs for all the groups of which the asset is an active member. B NONE. B NONE. B This method overrides C in order to add the site ID to the list of IDs. This works because the site ID corresponds to a secret group ID. =cut sub get_grp_ids { my $self = shift; return $self->INSTANCE_GROUP_ID unless ref $self; my ($gids, $site_id) = $self->_get(qw(grp_ids site_id)); unshift @$gids, $site_id if $site_id and not $gids->[0] == $site_id; return wantarray ? @$gids : $gids; } ################################################################################ =item $self = $self->cancel Reverts the actions of a fork with out committing any changes. Deletes row for the checked out asset. B NONE B Removes the Asset (version) record from the database B NONE =cut ################################################################################ =item $self->set_note($note); =item $self->add_note($note); Sets the note for this instance of the assset. B NONE. B NONE. B C is deprecated. =cut sub add_note { shift->set_note(@_) } ################################################################################ =item my $note = $asset->get_note Returns the note for this instance of the asset. B NONE. B NONE. B NONE. =cut ################################################################################ =item my $notes_href = $asset->get_notes; Returns a hash reference of the notes for the asset. The hash keys are asset version numbers, and the values are the notes. B NONE. B NONE. B NONE. =cut sub get_notes { my $self = shift; my $notes = $self->_get('_notes'); unless ($notes) { my $table = $self->VERSION_TABLE; my $col = $self->TABLE . '__id'; my $sel = prepare_c(" SELECT version, note FROM $table WHERE $col = ? ORDER BY id DESC" ); execute($sel, $self->get_id); bind_columns($sel, \my ($version, $note)); while (fetch($sel)) { $notes->{$version} = $note; } $self->_set(['_notes'] => [$notes] ); } return $notes; } ################################################################################ =item my $bool = $asset->has_notes Returns true if the asset has notes in any of its versions, and false if it does not. =cut sub has_notes { my $self = shift; if (first { $_ } $self->_get(qw(note _got_notes _notes))) { return $self; } my $table = $self->VERSION_TABLE; my $col = $self->TABLE . '__id'; my ($got_notes) = row_array(prepare_c(" SELECT 1 FROM $table WHERE $col = ? AND note IS NOT NULL LIMIT 1 "), $self->get_id); $self->_set(['_got_notes'] => [ $got_notes ]); return $got_notes ? $self : undef; } =item $asset = $asset->activate() This will activate a nonactive asset B NONE B NONE B NONE =cut sub activate { my $self = shift; $self->_set( { '_active' => 1 } ); return $self; } ################################################################################ =item $asset = $asset->deactivate() This will set the asset to a non active state B NONE B NONE B NONE =cut sub deactivate { my $self = shift; $self->_set( { '_active' => 0 } ); return $self; } ################################################################################ =item ($asset || undef) = $asset->is_active() Returns the object if it is active, undef otherwise B NONE B NONE B NONE =cut sub is_active { my $self = shift; return $self->_get('_active') ? $self : undef; } ################################################################################ =item $self = $self->cancel_checkout Cancels the checkout. Deletes the version instance record. B =over 4 =item "Cannot cancel a non checked out asset" =back B NONE. B NONE. =cut sub cancel_checkout { my $self = shift; # Make sure it's checked out. throw_gen "Cannot cancel a non checked out asset" unless $self->_get('checked_out'); return $self->_set([qw(user__id checked_out _cancel)] => [undef, 0, 1]); } ############################################################################## =item $asset = $asset->checkin Checks the asset in. B =over 4 =item * Cannot checkin non checked out versions. =back B NONE. B NONE. =cut sub checkin { my $self = shift; throw_gen(error => "Cannot checkin non checked out versions") unless $self->_get('checked_out'); my $version = $self->_get('version'); $version++; $self->_set({ user__id => undef, version => $version, current_version => $version, checked_out => 0, _checkin => 1 }); return $self; } ################################################################################ =back =head1 PRIVATE =head2 Private Class Methods NONE =head2 Private Instance Methods NONE =head2 Private Functions NONE =cut 1; __END__ =head1 AUTHOR =over =item michael soderstrom =item Mark Jaroski =item David Wheeler =back =head1 SEE ALSO L,L =cut