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 )