Articulate
view release on metacpan or search on metacpan
lib/Articulate/Storage/Local.pm view on Meta::CPAN
my $fn =
$self->ensure_exists( $self->true_location( $location . '/settings.yml' ) );
YAML::DumpFile( $fn, $settings );
return $settings;
}
=head3 get_settings_complete
$storage->get_settings_complete('zone/public/article/hello-world')
Retrieves the settings for the content at that location.
=cut
sub get_settings_complete {
my $self = shift;
my $location = shift->location;
throw_error Internal => "Bad location $location"
unless $self->navigation->valid_location($location);
my @paths = split /\//, $location;
my $current_path = $self->true_location('') . '/';
my $settings = {};
foreach my $p (@paths) {
my $fn = $current_path . 'settings.yml';
my $lvl_settings = {};
$lvl_settings = YAML::LoadFile($fn) if -e $fn;
$settings = hash_merge( $settings, $lvl_settings );
}
return $settings;
}
=head3 get_content
$storage->get_content('zone/public/article/hello-world')
Retrieves the content at that location.
=cut
sub get_content {
my $self = shift;
my $location = shift->location;
throw_error Internal => "Bad location $location"
unless $self->navigation->valid_location($location);
throw_error NotFound => "No content at $location"
unless $self->item_exists($location);
my $fn = $self->true_location( $location . '/content.blob' );
open my $fh, '<', $fn
or throw_error Internal => "Cannot open file $fn to read";
return '' . ( join '', <$fh> );
}
=head3 set_content
$storage->set_content('zone/public/article/hello-world', $blob);
Places content at that location.
=cut
sub _is_upload {
my $content = shift;
return ( blessed $content and $content->isa('Articulate::File') )
; # todo: have this wrapped by an articulate class which interfaces with the FrameworkAdapter
}
sub _write_data {
my ( $content, $fn ) = @_;
open my $fh, '>', $fn
or throw_error Internal => "Cannot open file $fn to write";
print $fh $content;
close $fh;
}
sub _copy_upload {
my ( $content, $fn ) = @_;
my $content_fh = $content->io;
local $/;
open my $fh, '>', $fn
or throw_error Internal => "Cannot open file $fn to write";
binmode $fh, ':raw';
print $fn while <$content_fh>;
close $fh;
}
sub _write_content {
my ( $content, $fn ) = @_;
$content //= '';
if ( _is_upload($content) ) {
_copy_upload( $content, $fn );
}
else {
_write_data( $content, $fn );
}
}
sub set_content {
my $self = shift;
my $item = shift;
my $location = $item->location;
throw_error Internal => "Bad location $location"
unless $self->navigation->valid_location($location);
throw_error NotFound => "No content at $location"
unless $self->item_exists($location);
my $fn =
$self->ensure_exists( $self->true_location( $location . '/content.blob' ) );
_write_content( $item->content, $fn );
return $location;
}
=head3 create_item
$storage->create_item('zone/public/article/hello-world', $meta, $blob);
Places meta and content at that location.
=cut
sub create_item {
my $self = shift;
my $item = shift;
my $location = $item->location;
throw_error Internal => "Bad location " . $location
unless $self->navigation->valid_location($location);
throw_error AlreadyExists => "Cannot create: item already exists at "
. $location
if $self->item_exists($location);
{
my $fn =
$self->ensure_exists(
$self->true_location( $location . '/content.blob' ) );
_write_content( $item->content, $fn );
}
{
my $fn =
$self->ensure_exists( $self->true_location( $location . '/meta.yml' ) );
YAML::DumpFile( $fn, $item->meta );
}
$item->content( $self->get_content($item) );
return $item;
}
=head3 item_exists
if ($storage->item_exists( 'zone/public/article/hello-world')) {
...
}
Determines if the item has been created (only the C<meta.yml> is
tested).
( run in 3.558 seconds using v1.01-cache-2.11-cpan-b16cb0d3907 )