CatalystX-ExtJS-REST
view release on metacpan or search on metacpan
lib/CatalystX/Controller/ExtJS/REST.pm view on Meta::CPAN
if($c->stash->{object}) {
$self->status_ok( $c, entity => $form->form_data( $c->stash->{object} ) );
} else {
$self->status_not_found($c, message => 'Object could not be found.');
}
}
sub object_DELETE {
my ( $self, $c ) = @_;
if($c->stash->{object}) {
$c->stash->{object}->delete;
$self->status_ok( $c, entity => { success => \1, data => {}, message => "Object has been deleted" } );
} else {
$self->status_not_found($c, message => 'Object could not be found.');
}
}
sub path_to_forms {
my ($self, $method) = @_;
(my $file = $self->form_base_file) =~ s/\.yml$//;
$file .= '_' . $method . '.yml';
$file = Path::Class::File->new($file);
return -e $file ? $file : $self->form_base_file;
}
sub get_form {
my ($self, $c, $file) = @_;
my $form = HTML::FormFu::ExtJS->new();
$form->query_type('Catalyst');
my $model_stash = $self->_extjs_config->{model_stash};
$model_stash->{schema} ||= "DBIC";
for my $model ( keys %$model_stash ) {
$form->stash->{$model} = $c->model( $model_stash->{$model} );
}
$form->model_config($self->_extjs_config->{model_config});
if ( $file && !ref $file ) {
if ( $self->has_forms ) {
my $config = $self->forms->{$file} || $self->forms->{default};
$config = { elements => $config } if(ref $config eq 'ARRAY');
$form->populate( $config );
} elsif ( $file eq 'list' ) {
$file = $self->list_base_file;
} else {
$file = $self->path_to_forms($file);
}
}
if ( ref $file ) {
$c->log->debug( 'Loading form ' . $file ) if ( $c->debug );
my $config = $self->load_config_file($file);
$form->populate($config);
}
# To allow your form validation packages, etc, access to the catalyst
# context, a weakened reference of the context is copied into the form's
# stash.
my $context_stash = $self->_extjs_config->{context_stash};
$form->stash->{$context_stash} = $c;
Scalar::Util::weaken( $form->stash->{$context_stash} );
return $form;
}
sub load_config_file {
my ($self, $file) = @_;
my $config;
unless($config = $self->form_config_cache->{$file . ""}) {
die "Neither __PACKAGE__->config->{forms} nor " . $file . " exist."
unless(-e $file);
$config = Config::Any->load_files( {
files => [$file],
use_ext => 1,
driver_args => { General => { -UTF8 => 1 }, },
} );
( undef, $config ) = %{ $config->[0] };
$self->form_config_cache->{$file.""} = $config;
}
return $config;
}
sub handle_uploads {
my ($self, $c, $row, $form) = @_;
my $uploads;
while(my ($k, $v) = each %{$c->req->uploads}) {
next unless $form->get_field($k);
$c->log->debug("Cannot handle multiple uploads per field") if($c->debug && ref $v eq "ARRAY");
$row->$k($v->fh);
}
$row->update;
}
sub status_not_found {
my $self = shift;
$self->next::method(@_);
shift->stash->{rest}->{success} = \0;
}
sub end {
my ( $self, $c ) = @_;
$self->next::method($c);
if(@{$c->error}) {
$self->status_bad_request($c, message => $c->debug ? "@{$c->error}" : 'An error occured while processing your request.');
$c->log->error(@{$c->error});
$c->clear_errors;
$c->stash->{rest}->{success} = \0;
}
if ( $c->req->is_ext_upload ) {
my $stash_key = (
$self->config->{'serialize'}
? $self->config->{'serialize'}->{'stash_key'}
: $self->config->{'stash_key'}
)
|| 'rest';
my $output;
eval { $output = encode_json( $c->stash->{$stash_key} ); };
$c->res->content_type('text/html');
$c->res->output( encode_entities($output) );
}
lib/CatalystX/Controller/ExtJS/REST.pm view on Meta::CPAN
The C<default_rs_method> defaults to the value of L</default_rs_method>. If it is not set
by the configuration, this controller tries to call C<extjs_rest_$class> (i.e. C<extjs_rest_user>).
=head2 Handling Uploads
This module handles your uploads. If there is an upload and the name of that field
exists in you form config, the column is set to an L<IO::File> object. You need to
handle this on the model side because storing a filehandle will most likely fail.
Fortunately, there are modules out there which can help you with that. Have a look at
L<DBIx::Class::InflateColumn::FS>. Don't use L<DBIx::Class:InflateColumn::File>
because it is deprecated and broken.
If you need a more advanced processing of uploaded files, don't hesitate and
overwrite L</handle_uploads>.
=head1 CONFIGURATION
Local configuration:
__PACKAGE__->config({ ... });
Global configuration for all controllers which use CatalystX::Controller::ExtJS::REST:
MyApp->config( {
CatalystX::Controller::ExtJS::REST =>
{ key => value }
} );
=head2 find_method
The method to call on the resultset to get an existing row object.
This can be set to the name of a custom function function which is defined with the (custom) resultset class.
It needs to take the primary key as first parameter.
Defaults to C<find>.
=head2 default_rs_method
This resultset method is called on every request. This is useful if you want to
restrict the resultset, e. g. only find objects which are associated to the
current user. The first parameter is the Catalyst context object and the second
parameter is either C<list> (if a list of objects has been requested) or C<object>
(if only one object is manipulated).
Nothing is called if the specified method does not exist.
This defaults to C<extjs_rest_[controller namespace]>.
A controller C<MyApp::Controller::User> expects a resultset method
C<extjs_rest_user>.
=head2 root_property
Set the root property used by L</list>, update and create which will contain the data.
Defaults to C<data>.
=head2 context_stash
To allow your form validation packages, etc, access to the catalyst context,
a weakened reference of the context is copied into the form's stash.
$form->stash->{context};
This setting allows you to change the key name used in the form stash.
Default value: C<context>
=head2 form_base_path
Defaults to C<root/forms>
=head2 forms
If you define forms in the controller, files will not be loaded and are not required.
You need to have at least the C<default> form defined. It is equivalent to the file
without the request method appended.
Example:
forms => {
default => [
{ name => 'id' },
{ name => 'title' },
],
get => ...
list => ...
options => ...
}
See C<< t/lib/MyApp/Controller/InlineUser.pm >> for a working example.
=head2 limit
The maximum number of rows to return. Defaults to 100.
=head2 list_base_path
Defaults to C<root/lists>
=head2 no_list_metadata
If set to a true value there will be no meta data send with lists.
Defaults to undef. That means the metaData hash will be send by default.
=head2 model_config
=head3 schema
Defaults to C<DBIC>
=head3 resultset
Defaults to L</default_resultset>
=head2 namespace
Defaults to L<Catalyst::Controller/namespace>
=head2 order_by
( run in 3.188 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )