Bug 27251: Rewrite QOTD with the Koha REST API
This patch replace the QOTD editor with our new way to CRUD the adminitration page (like libraries and STMP servers) Test plan: Play with the QOTD by adding, removing, updating quotes Try to find bugs :) Bug 27251: Fix capitalization Signed-off-by: Andrew Fuerste-Henry <andrew@bywatersolutions.com> Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de> Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This commit is contained in:
parent
bcb5b076ce
commit
401987bdad
|
|
@ -33,6 +33,22 @@ Koha::Quote - Koha Quote object class
|
|||
|
||||
=cut
|
||||
|
||||
=head3 to_api_mapping
|
||||
|
||||
This method returns the mapping for representing a Koha::Quote object
|
||||
on the API.
|
||||
|
||||
=cut
|
||||
|
||||
sub to_api_mapping {
|
||||
return {
|
||||
id => 'quote_id',
|
||||
source => 'source',
|
||||
text => 'text',
|
||||
timestamp => 'displayed_on',
|
||||
};
|
||||
}
|
||||
|
||||
=head3 _type
|
||||
|
||||
=cut
|
||||
|
|
@ -41,4 +57,4 @@ sub _type {
|
|||
return 'Quote';
|
||||
}
|
||||
|
||||
1;
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,139 @@
|
|||
package Koha::REST::V1::Quotes;
|
||||
|
||||
# This file is part of Koha.
|
||||
#
|
||||
# Koha is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Koha is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
use Koha::Quotes;
|
||||
|
||||
use Try::Tiny;
|
||||
|
||||
=head1 API
|
||||
|
||||
=head2 Methods
|
||||
|
||||
=head3 list
|
||||
|
||||
=cut
|
||||
|
||||
sub list {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
return try {
|
||||
my $quotes_set = Koha::Quotes->new;
|
||||
my $quotes = $c->objects->search( $quotes_set );
|
||||
return $c->render( status => 200, openapi => $quotes );
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
=head3 get
|
||||
|
||||
=cut
|
||||
|
||||
sub get {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
return try {
|
||||
my $quote = Koha::Quotes->find( $c->validation->param('quote_id') );
|
||||
unless ($quote) {
|
||||
return $c->render( status => 404,
|
||||
openapi => { error => "quote not found" } );
|
||||
}
|
||||
|
||||
return $c->render( status => 200, openapi => $quote->to_api );
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
}
|
||||
}
|
||||
|
||||
=head3 add
|
||||
|
||||
=cut
|
||||
|
||||
sub add {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
return try {
|
||||
my $quote = Koha::Quote->new_from_api( $c->validation->param('body') );
|
||||
$quote->store;
|
||||
$c->res->headers->location( $c->req->url->to_string . '/' . $quote->id );
|
||||
return $c->render(
|
||||
status => 201,
|
||||
openapi => $quote->to_api
|
||||
);
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 update
|
||||
|
||||
=cut
|
||||
|
||||
sub update {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $quote = Koha::Quotes->find( $c->validation->param('quote_id') );
|
||||
|
||||
if ( not defined $quote ) {
|
||||
return $c->render( status => 404,
|
||||
openapi => { error => "Object not found" } );
|
||||
}
|
||||
|
||||
return try {
|
||||
$quote->set_from_api( $c->validation->param('body') );
|
||||
$quote->store();
|
||||
return $c->render( status => 200, openapi => $quote->to_api );
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 delete
|
||||
|
||||
=cut
|
||||
|
||||
sub delete {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $quote = Koha::Quotes->find( $c->validation->param('quote_id') );
|
||||
if ( not defined $quote ) {
|
||||
return $c->render( status => 404,
|
||||
openapi => { error => "Object not found" } );
|
||||
}
|
||||
|
||||
return try {
|
||||
$quote->delete;
|
||||
return $c->render(
|
||||
status => 204,
|
||||
openapi => q{}
|
||||
);
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -65,6 +65,9 @@
|
|||
"patron_balance": {
|
||||
"$ref": "definitions/patron_balance.json"
|
||||
},
|
||||
"quote": {
|
||||
"$ref": "definitions/quote.json"
|
||||
},
|
||||
"allows_renewal": {
|
||||
"$ref": "definitions/allows_renewal.json"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"quote_id": {
|
||||
"$ref": "../x-primitives.json#/quote_id"
|
||||
},
|
||||
"source": {
|
||||
"description": "source of the quote",
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"description": "text",
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"displayed_on": {
|
||||
"description": "Last display date",
|
||||
"type": ["string", "null"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["quote_id", "source", "text"]
|
||||
}
|
||||
|
|
@ -32,6 +32,9 @@
|
|||
"order_id_pp": {
|
||||
"$ref": "parameters/order.json#/order_id_pp"
|
||||
},
|
||||
"quote_id_pp": {
|
||||
"$ref": "parameters/quote.json#/quote_id_pp"
|
||||
},
|
||||
"smtp_server_id_pp": {
|
||||
"$ref": "parameters/smtp_server.json#/smtp_server_id_pp"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"quote_id_pp": {
|
||||
"name": "quote_id",
|
||||
"in": "path",
|
||||
"description": "Quote internal identifier",
|
||||
"required": true,
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
|
|
@ -137,6 +137,12 @@
|
|||
"/public/patrons/{patron_id}/guarantors/can_see_checkouts": {
|
||||
"$ref": "paths/public_patrons.json#/~1public~1patrons~1{patron_id}~1guarantors~1can_see_checkouts"
|
||||
},
|
||||
"/quotes": {
|
||||
"$ref": "paths/quotes.json#/~1quotes"
|
||||
},
|
||||
"/quotes/{quote_id}": {
|
||||
"$ref": "paths/quotes.json#/~1quotes~1{quote_id}"
|
||||
},
|
||||
"/return_claims": {
|
||||
"$ref": "paths/return_claims.json#/~1return_claims"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,327 @@
|
|||
{
|
||||
"/quotes": {
|
||||
"get": {
|
||||
"x-mojo-to": "Quotes#list",
|
||||
"operationId": "listQuotes",
|
||||
"tags": [
|
||||
"quotes"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "quote_id",
|
||||
"in": "query",
|
||||
"description": "Case insensitive search on quote id",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "source",
|
||||
"in": "query",
|
||||
"description": "Case insensitive search on source",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "text",
|
||||
"in": "query",
|
||||
"description": "Case insensitive search on text",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "displayed_on",
|
||||
"in": "query",
|
||||
"description": "Case Insensative search on last displayed date",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "../parameters.json#/match"
|
||||
},
|
||||
{
|
||||
"$ref": "../parameters.json#/order_by"
|
||||
},
|
||||
{
|
||||
"$ref": "../parameters.json#/page"
|
||||
},
|
||||
{
|
||||
"$ref": "../parameters.json#/per_page"
|
||||
},
|
||||
{
|
||||
"$ref": "../parameters.json#/q_param"
|
||||
},
|
||||
{
|
||||
"$ref": "../parameters.json#/q_body"
|
||||
},
|
||||
{
|
||||
"$ref": "../parameters.json#/q_header"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A list of quotes",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "../definitions.json#/quote"
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Access forbidden",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal error",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"503": {
|
||||
"description": "Under maintenance",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-koha-authorization": {
|
||||
"permissions": {
|
||||
"catalogue": "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"x-mojo-to": "Quotes#add",
|
||||
"operationId": "addQuote",
|
||||
"tags": [
|
||||
"quotes"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"description": "A JSON object containing informations about the new quote",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/quote"
|
||||
}
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Quote added",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/quote"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Authentication required",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Access forbidden",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal error",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"503": {
|
||||
"description": "Under maintenance",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-koha-authorization": {
|
||||
"permissions": {
|
||||
"tools": "edit_quotes"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/quotes/{quote_id}": {
|
||||
"get": {
|
||||
"x-mojo-to": "Quotes#get",
|
||||
"operationId": "getQuote",
|
||||
"tags": [
|
||||
"quotes"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "../parameters.json#/quote_id_pp"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A Quote",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/quote"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Quote not found",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal error",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"503": {
|
||||
"description": "Under maintenance",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-koha-authorization": {
|
||||
"permissions": {
|
||||
"catalogue": "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"x-mojo-to": "Quotes#update",
|
||||
"operationId": "updateQuote",
|
||||
"tags": [
|
||||
"quotes"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "../parameters.json#/quote_id_pp"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"description": "a quote object",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/quote"
|
||||
}
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A quote",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/quote"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Authentication required",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Access forbidden",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Quote not found",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal error",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"503": {
|
||||
"description": "Under maintenance",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-koha-authorization": {
|
||||
"permissions": {
|
||||
"tools": "edit_quotes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"x-mojo-to": "Quotes#delete",
|
||||
"operationId": "deleteQuote",
|
||||
"tags": [
|
||||
"quotes"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "../parameters.json#/quote_id_pp"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "Quote deleted"
|
||||
},
|
||||
"401": {
|
||||
"description": "Authentication required",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Access forbidden",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Quote not found",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal error",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
},
|
||||
"503": {
|
||||
"description": "Under maintenance",
|
||||
"schema": {
|
||||
"$ref": "../definitions.json#/error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-koha-authorization": {
|
||||
"permissions": {
|
||||
"tools": "edit_quotes"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -52,6 +52,10 @@
|
|||
"type": "integer",
|
||||
"description": "internally assigned fund identifier",
|
||||
"readOnly": true
|
||||
},
|
||||
"quote_id": {
|
||||
"type": "integer",
|
||||
"description": "internally assigned quote identifier",
|
||||
"readOnly": true
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
<div id="toolbar" class="btn-toolbar">
|
||||
<div class="btn-group"><a class="btn btn-default" id="add_quote" href="#"><i class="fa fa-plus"></i> Add quote</a></div>
|
||||
<div class="btn-group"><a class="btn btn-default" id="delete_quote" href="#"><i class="fa fa-trash"></i> Delete quote(s)</a></div>
|
||||
<div class="btn-group"><a class="btn btn-default" id="import_quotes" href="/cgi-bin/koha/tools/quotes-upload.pl"><i class="fa fa-folder-open"></i> Import quotes</a></div>
|
||||
</div>
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
<div id="toolbar" class="btn-toolbar" style="visibility: hidden; position: absolute">
|
||||
<div class="btn-group"><a class="btn btn-default" id="save_quotes" href="#"><i class="fa fa-save"></i> Save quotes</a></div>
|
||||
<div class="btn-group"><a class="btn btn-default" id="delete_quote" href="#"><i class="fa fa-trash"></i> Delete quote(s)</a></div>
|
||||
<div class="btn-group"><a href="/cgi-bin/koha/tools/quotes-upload.pl" id="cancel_quotes" class="btn btn-default"><i class="fa fa-remove"></i> Cancel import</a></div>
|
||||
</div>
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
[% END %]
|
||||
[% IF ( daily_quote ) %]
|
||||
<div id="area-news">
|
||||
<h3>Quote of the Day</h3>
|
||||
<h3>Quote of the day</h3>
|
||||
<div class="newsitem">
|
||||
<span id="daily-quote-text">[% daily_quote.text | html %]</span><span id="daily-quote-sep"> ~ </span><span id="daily-quote-source">[% daily_quote.source | html %]</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,9 +18,18 @@
|
|||
<div class="row">
|
||||
<div class="col-sm-10 col-sm-push-2">
|
||||
<main>
|
||||
<div id="toolbar" class="btn-toolbar" style="visibility: hidden; position: absolute">
|
||||
<div class="btn-group"><a class="btn btn-default" id="save_quotes" href="#"><i class="fa fa-save"></i> Save quotes</a></div>
|
||||
<div class="btn-group"><a href="/cgi-bin/koha/tools/quotes-upload.pl" id="cancel_quotes" class="btn btn-default"><i class="fa fa-remove"></i> Cancel import</a></div>
|
||||
</div>
|
||||
|
||||
[% INCLUDE 'quotes-upload-toolbar.inc' %]
|
||||
<h2>Quote uploader</h2>
|
||||
|
||||
<div id="messages" style="display: none;">
|
||||
<div class="import_success dialog message" style="display: none;"></div>
|
||||
<div class="import_errors dialog alert" style="display: none;"></div>
|
||||
</div>
|
||||
|
||||
<div id="instructions">
|
||||
<fieldset id="file_uploader_help" class="rows">
|
||||
<legend>Instructions</legend>
|
||||
|
|
@ -34,12 +43,12 @@
|
|||
<div id="file_editor_inst">
|
||||
<ul>
|
||||
<li>Click on any field to edit the contents; Press the <Enter> key to save edit.</li>
|
||||
<li>Click on one or more quote numbers to select entire quotes for deletion; Click the 'Delete Quote(s)' button to delete selected quotes.</li>
|
||||
<li>Click the 'Save Quotes' button in the toolbar to save the entire batch of quotes.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<fieldset id="file_uploader" class="rows">
|
||||
<legend>Upload quotes</legend>
|
||||
<div id="file_upload">
|
||||
|
|
@ -232,7 +241,6 @@
|
|||
$('#file_uploader').css("top","-150px");
|
||||
$('#quotes_editor').css("visibility","visible");
|
||||
$("#save_quotes").on("click", yuiGetData);
|
||||
$("#delete_quote").on("click", fnClickDeleteRow);
|
||||
|
||||
oTable = $('#quotes_editor').dataTable( {
|
||||
"bAutoWidth" : false,
|
||||
|
|
@ -262,8 +270,6 @@
|
|||
/* do foo on various cells in the current row */
|
||||
var quoteNum = $('td', nRow)[0].innerHTML;
|
||||
$(nRow).attr("id", quoteNum); /* set row ids to quote number */
|
||||
$('td:eq(0)', nRow).click(function() {$(this.parentNode).toggleClass('selected',this.clicked);}); /* add row selectors */
|
||||
$('td:eq(0)', nRow).attr("title", _("Click ID to select/deselect quote"));
|
||||
/* apply no_edit id to noEditFields */
|
||||
noEditFields = [0]; /* number */
|
||||
for (i=0; i<noEditFields.length; i++) {
|
||||
|
|
@ -335,44 +341,44 @@
|
|||
|
||||
$('#file_upload').one('change', fnHandleFileSelect);
|
||||
|
||||
});
|
||||
|
||||
var MSG_IMPORT_SUCCESS = _("%s quotes imported successfully");
|
||||
var MSG_IMPORT_ERROR = _("%s quotes have not been imported. An error occurred");
|
||||
function fnGetData(element) {
|
||||
var jqXHR = $.ajax({
|
||||
url : "/cgi-bin/koha/tools/quotes/quotes-upload_ajax.pl",
|
||||
type : "POST",
|
||||
contentType : "application/x-www-form-urlencoded", // we must claim this mimetype or CGI will not decode the URL encoding
|
||||
dataType : "json",
|
||||
data : {
|
||||
"quote" : encodeURI ( JSON.stringify(oTable.fnGetData()) ),
|
||||
"action" : "add",
|
||||
},
|
||||
success : function(){
|
||||
var response = JSON.parse(jqXHR.responseText);
|
||||
if (response.success) {
|
||||
alert(_("%s quotes saved.").format(response.records));
|
||||
window.location.reload(true); // is this the best route?
|
||||
} else {
|
||||
alert(_("%s quotes saved, but an error has occurred. Please ask your administrator to check the server log for more details.").format(response.records));
|
||||
window.location.reload(true); // is this the best route?
|
||||
}
|
||||
},
|
||||
var lines = oTable.fnGetData();
|
||||
$(lines).each(function(line){
|
||||
var data = {source: this[1], text: this[2]};
|
||||
var success = 0; var error = 0;
|
||||
$.ajax({
|
||||
url : "/api/v1/quotes",
|
||||
method : "POST",
|
||||
data : JSON.stringify(data),
|
||||
dataType : "application/json",
|
||||
success : function(data) {
|
||||
$("#messages").show();
|
||||
var import_success = $("#messages .import_success");
|
||||
import_success.show();
|
||||
import_success.data("nb")
|
||||
nb_success = import_success.data("nb") || 0;
|
||||
nb_success++;
|
||||
$("#messages .import_success").text(MSG_IMPORT_SUCCESS.format(nb_success));
|
||||
import_success.data("nb", nb_success);
|
||||
},
|
||||
error : function(xhr) {
|
||||
if (xhr.status==201) { this.success(null, "Created", xhr); return; }
|
||||
$("#messages").show();
|
||||
var import_error = $("#messages .import_error");
|
||||
import_error.show();
|
||||
import_error.data("nb")
|
||||
nb_error = import_error.data("nb") || 0;
|
||||
nb_error++;
|
||||
$("#messages .import_error").text(MSG_IMPORT_ERROR.format(nb_error));
|
||||
import_error.data("nb", nb_error);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function fnClickDeleteRow() {
|
||||
var idsToDelete = oTable.$('.selected').map(function() {
|
||||
return this.id;
|
||||
}).get().join(', ');
|
||||
if (!idsToDelete) {
|
||||
alert(_("Please select a quote(s) by clicking the quote id(s) you desire to delete."));
|
||||
}
|
||||
else if (confirm(_("Are you sure you wish to delete quote(s) %s?").format(idsToDelete))) {
|
||||
oTable.$('.selected').each(function(){
|
||||
oTable.fnDeleteRow(this);
|
||||
});
|
||||
}
|
||||
}
|
||||
}); // $(document).ready
|
||||
</script>
|
||||
[% END %]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
[% USE raw %]
|
||||
[% USE Asset %]
|
||||
[% SET footerjs = 1 %]
|
||||
[% INCLUDE 'doc-head-open.inc' %]
|
||||
<title>Koha › Tools › Quote editor</title>
|
||||
[% INCLUDE 'doc-head-close.inc' %]
|
||||
[% Asset.css("css/quotes.css") | $raw %]
|
||||
[% INCLUDE 'doc-head-open.inc' %]
|
||||
<title>Koha › Tools › Quote editor</title>
|
||||
[% INCLUDE 'doc-head-close.inc' %]
|
||||
[% Asset.css("css/quotes.css") | $raw %]
|
||||
</head>
|
||||
|
||||
<body id="tools_quotes" class="tools">
|
||||
|
|
@ -18,43 +18,110 @@
|
|||
<div class="col-sm-10 col-sm-push-2">
|
||||
<main>
|
||||
|
||||
[% INCLUDE 'quotes-toolbar.inc' %]
|
||||
<h2>Quote editor</h2>
|
||||
<div id="instructions">
|
||||
<fieldset id="quote_editor_help" class="rows">
|
||||
<legend>Instructions</legend>
|
||||
<div id="quote_editor_inst">
|
||||
<ul>
|
||||
<li>Click on the 'Add quote' button to add a single quote; Press the <Enter> key to save the quote.<br />
|
||||
<strong>Note: </strong>Both the 'source' and 'text' fields must have content in order for the quote to be saved.</li>
|
||||
<li>Click on any field to edit the contents; Press the <Enter> key to save edit.</li>
|
||||
<li>Click on one or more quote numbers to select entire quotes for deletion; Click the 'Delete quote(s)' button to delete selected quotes.</li>
|
||||
<li>Click the 'Import quotes' button in the toolbar to import a CSV file of quotes.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</fieldset>
|
||||
[% FOREACH m IN messages %]
|
||||
<div class="dialog [% m.type | html %]" id="quote_action_result_dialog">
|
||||
[% SWITCH m.code %]
|
||||
[% CASE 'error_on_update' %]
|
||||
An error occurred when updating this quote. Perhaps it already exists.
|
||||
[% CASE 'error_on_insert' %]
|
||||
An error occurred when adding this quote.
|
||||
[% CASE 'success_on_update' %]
|
||||
Quote updated successfully.
|
||||
[% CASE 'success_on_insert' %]
|
||||
Quote added successfully.
|
||||
[% CASE %]
|
||||
[% m.code | html %]
|
||||
[% END %]
|
||||
</div>
|
||||
[% END %]
|
||||
|
||||
<div class="dialog message" id="quote_delete_success" style="display: none;"></div>
|
||||
<div class="dialog alert" id="quote_delete_error" style="display: none;"></div>
|
||||
|
||||
[% IF op == 'list' %]
|
||||
<div id="toolbar" class="btn-toolbar">
|
||||
<a class="btn btn-default" id="newquote" href="/cgi-bin/koha/tools/quotes.pl?op=add_form"><i class="fa fa-plus"></i> New quote</a>
|
||||
<a class="btn btn-default" id="import_quotes" href="/cgi-bin/koha/tools/quotes-upload.pl"><i class="fa fa-folder-open"></i> Import quotes</a>
|
||||
</div>
|
||||
[% END %]
|
||||
|
||||
[% IF op == 'add_form' %]
|
||||
<h3>[% IF quote %]Modify quote[% ELSE %]New quote[% END %]</h3>
|
||||
<form action="/cgi-bin/koha/tools/quotes.pl" id="Aform" name="Aform" class="validated" method="post">
|
||||
<fieldset class="rows">
|
||||
<input type="hidden" name="op" value="add_validate" />
|
||||
<ol>
|
||||
<li>
|
||||
<label for="text" class="required">Source: </label>
|
||||
<input type="text" name="source" id="source" value="[% quote.source | html %]" class="required" required="required" />
|
||||
<span class="required">Required</span>
|
||||
</li>
|
||||
<li>
|
||||
<label for="text" class="required">Text: </label>
|
||||
<textarea name="text" id="text" class="required" required="required" />[% quote.text | html %]</textarea>
|
||||
<span class="required">Required</span>
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
<fieldset class="action">
|
||||
<input type="hidden" name="id" value="[% quote.id %]" />
|
||||
<input type="submit" value="Submit" />
|
||||
<a class="cancel" href="/cgi-bin/koha/tools/quotes.pl">Cancel</a>
|
||||
</fieldset>
|
||||
</form>
|
||||
[% END %]
|
||||
|
||||
[% IF op == 'delete_confirm' %]
|
||||
<div class="dialog alert">
|
||||
<form action="/cgi-bin/koha/tools/quotes.pl" method="post">
|
||||
<h3>Are you sure you want to delete the following quote?</h3>
|
||||
[% quote.source | html %] - [% quote.text | html %]
|
||||
<input type="hidden" name="op" value="delete_confirmed" />
|
||||
<input type="hidden" name="id" value="[% quote.id | html %]" />
|
||||
<button type="submit" class="approve"><i class="fa fa-fw fa-check"></i> Yes, delete</button>
|
||||
</form>
|
||||
<form action="/cgi-bin/koha/tools/quotes.pl" method="get">
|
||||
<button type="submit" class="deny"><i class="fa fa-fw fa-remove"></i> No, do not delete</button>
|
||||
</form>
|
||||
</div>
|
||||
[% END %]
|
||||
|
||||
[% IF op == 'list' %]
|
||||
<h3>Quotes</h3>
|
||||
[% IF quotes_count > 0 %]
|
||||
<table id="quotes">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Source</th>
|
||||
<th>Text</th>
|
||||
<th>Last display</th>
|
||||
<th data-class-name="actions">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
[% ELSE %]
|
||||
<div class="dialog message">There are no quotes defined. <a href="/cgi-bin/koha/tools/quotes.pl?op=add_form">Start defining quotes</a>.</div>
|
||||
[% END %]
|
||||
|
||||
<div id="delete_confirm_modal" class="modal" tabindex="-1" role="dialog" aria-labelledby="delete_confirm_modal_label" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="delete_confirm_modal_label">Delete quote</h3>
|
||||
</div>
|
||||
<table id="quotes_editor">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><span style="cursor: help" id="id_help">ID</span></th>
|
||||
<th>Source</th>
|
||||
<th>Text</th>
|
||||
<th>Last displayed</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- tbody content is generated by DataTables -->
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>Loading data...</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<fieldset id="footer" class="action">
|
||||
</fieldset>
|
||||
<div class="modal-body">
|
||||
<div id="delete_confirm_dialog"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn btn-default" id="delete_confirm_modal_button" role="button" data-toggle="modal">Delete</a>
|
||||
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div> <!-- /.modal-content -->
|
||||
</div> <!-- /.modal-dialog -->
|
||||
</div> <!-- #delete_confirm_modal -->
|
||||
[% END %]
|
||||
|
||||
</main>
|
||||
</div> <!-- /.col-sm-10.col-sm-push-2 -->
|
||||
|
|
@ -68,164 +135,99 @@
|
|||
|
||||
[% MACRO jsinclude BLOCK %]
|
||||
[% Asset.js("js/tools-menu.js") | $raw %]
|
||||
[% INCLUDE 'js-date-format.inc' %]
|
||||
[% INCLUDE 'datatables.inc' %]
|
||||
[% Asset.js("lib/jquery/plugins/dataTables.fnReloadAjax.js") | $raw %]
|
||||
[% Asset.js("lib/jquery/plugins/jquery.jeditable.mini.js") | $raw %]
|
||||
|
||||
<script>
|
||||
var oTable; /* oTable needs to be global */
|
||||
var sEmptyTable = _("No quotes available. Please use the 'Add quote' button to add a quote."); /* override the default message in datatables.inc */
|
||||
$(document).ready(function() {
|
||||
/* NOTE: This is an ajax-source datatable and *not* a server-side sourced datatable. */
|
||||
/* See the datatable docs if you don't understand this difference. */
|
||||
oTable = $("#quotes_editor").dataTable({
|
||||
"bAutoWidth" : false,
|
||||
"bProcessing" : true,
|
||||
"bPaginate" : true,
|
||||
"sPaginationType" : "full_numbers",
|
||||
"sDom": '<"top pager"iflp>rt<"bottom pager"flp><"clear">',
|
||||
"sAjaxSource" : "/cgi-bin/koha/tools/quotes/quotes_ajax.pl",
|
||||
"aoColumns" : [
|
||||
{ "sWidth": "3%" },
|
||||
{ "sWidth": "11%" },
|
||||
{ "sWidth": "75%" },
|
||||
{ "sWidth": "11%" },
|
||||
],
|
||||
"oLanguage": dataTablesDefaults.oLanguage,
|
||||
"fnPreDrawCallback": function(oSettings) {
|
||||
return true;
|
||||
|
||||
var quotes_url = '/api/v1/quotes';
|
||||
var quotes = $("#quotes").api({
|
||||
"ajax": {
|
||||
"url": quotes_url
|
||||
},
|
||||
"fnRowCallback": function( nRow, aData, iDisplayIndex ) {
|
||||
/* do foo on the current row and its child nodes */
|
||||
var noEditFields = [];
|
||||
var quoteID = $('td', nRow)[0].innerHTML;
|
||||
$(nRow).attr("id", quoteID); /* set row ids to quote id */
|
||||
$('td:eq(0)', nRow).click(function() {$(this.parentNode).toggleClass('selected',this.clicked);}); /* add row selectors */
|
||||
$('td:eq(0)', nRow).attr("title", _("Click ID to select/deselect quote"));
|
||||
$('td', nRow).attr("id",quoteID); /* FIXME: this is a bit of a hack */
|
||||
if (isNaN(quoteID)) {
|
||||
noEditFields = [0,1,2,3]; /* all fields when adding a quote */
|
||||
} else {
|
||||
noEditFields = [0,3]; /* id, timestamp */
|
||||
}
|
||||
/* apply no_edit id to noEditFields */
|
||||
for (i=0; i<noEditFields.length; i++) {
|
||||
$('td', nRow)[noEditFields[i]].setAttribute("id","no_edit");
|
||||
}
|
||||
return nRow;
|
||||
},
|
||||
"fnDrawCallback": function(oSettings) {
|
||||
/* Apply the jEditable handlers to the table on all fields w/o the no_edit id */
|
||||
$('#quotes_editor tbody td[id!="no_edit"]').editable( "/cgi-bin/koha/tools/quotes/quotes_ajax.pl", {
|
||||
"submitdata" : function ( value, settings ) {
|
||||
return {
|
||||
"column" : oTable.fnGetPosition( this )[2],
|
||||
"action" : "edit",
|
||||
};
|
||||
},
|
||||
"placeholder" : "Saving data...",
|
||||
});
|
||||
},
|
||||
});
|
||||
$("#add_quote").click(function(){
|
||||
fnClickAddRow();
|
||||
return false;
|
||||
});
|
||||
$("#delete_quote").click(function(){
|
||||
fnClickDeleteRow();
|
||||
return false;
|
||||
});
|
||||
$("#id_help").on("click",function(e){
|
||||
e.stopPropagation();
|
||||
alert( _("Click on the quote's id to select or deselect the quote. Multiple quotes may be selected.") );
|
||||
});
|
||||
});
|
||||
|
||||
function fnClickAddQuote(e, node) {
|
||||
if (e.charCode) {
|
||||
/* some browsers only give charCode, so this will need to be */
|
||||
/* fixed up to handle that */
|
||||
console.log('charCode: '+e.charCode);
|
||||
}
|
||||
if (e.keyCode == 13) {
|
||||
var quoteSource = $('#quoteSource').val();
|
||||
var quoteText = $('#quoteText').val()
|
||||
/* If passed a quote source, add the quote to the db */
|
||||
if (quoteSource && quoteText) {
|
||||
$.ajax({
|
||||
url: "/cgi-bin/koha/tools/quotes/quotes_ajax.pl",
|
||||
type: "POST",
|
||||
data: {
|
||||
"source" : quoteSource,
|
||||
"text" : quoteText,
|
||||
"action" : "add",
|
||||
},
|
||||
success: function(data){
|
||||
var newQuote = data[0];
|
||||
var aRow = oTable.fnUpdate(
|
||||
newQuote,
|
||||
node,
|
||||
undefined,
|
||||
false,
|
||||
false
|
||||
);
|
||||
oTable.fnPageChange( 'last' );
|
||||
$('.add_quote_button').attr('onclick', 'fnClickAddRow()'); // re-enable add button
|
||||
'emptyTable': '<div class="dialog message">'+_("There are no quotes defined.")+' <a href="/cgi-bin/koha/tools/quotes.pl?op=add_form">'+_("Start defining quotes")+'</a>.</div>',
|
||||
"columnDefs": [ {
|
||||
"targets": [0,1,2,3],
|
||||
"render": function (data, type, row, meta) {
|
||||
if ( type == 'display' ) {
|
||||
if ( data != null ) {
|
||||
return data.escapeHtml();
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert(_("Please supply both the text and source of the quote before saving."));
|
||||
}
|
||||
} else if (e.keyCode == 27) {
|
||||
if (confirm(_("Are you sure you want to cancel adding this quote?"))) {
|
||||
oTable.fnDeleteRow(node);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fnClickAddRow() {
|
||||
$('.add_quote_button').removeAttr('onclick'); // disable add button once it has been clicked
|
||||
var aRow = oTable.fnAddData(
|
||||
[
|
||||
'NA', // this is hackish to fool the datatable sort routine into placing this row at the end of the list...
|
||||
'<input id="quoteSource" type="text" style="width:99%" onkeydown="fnClickAddQuote(event,this.parentNode.parentNode)"/>',
|
||||
'<input id="quoteText" type="text" style="width:99%" onkeydown="fnClickAddQuote(event,this.parentNode.parentNode)"/>',
|
||||
'0000-00-00 00:00:00',
|
||||
],
|
||||
false
|
||||
);
|
||||
oTable.fnPageChange( 'last' );
|
||||
$('#quoteSource').focus();
|
||||
}
|
||||
|
||||
function fnClickDeleteRow() {
|
||||
var idsToDelete = oTable.$('.selected').map(function() {
|
||||
return this.id;
|
||||
}).get().join(', ');
|
||||
if (!idsToDelete) {
|
||||
alert(_("Please select a quote(s) by clicking the quote id(s) you desire to delete."));
|
||||
} else if (confirm(_("Are you sure you wish to delete quote(s) %s?").format(idsToDelete))) {
|
||||
oTable.$('.selected').each(function(){
|
||||
var quoteID = $(this).attr('id');
|
||||
$.ajax({
|
||||
url: "/cgi-bin/koha/tools/quotes/quotes_ajax.pl",
|
||||
type: "POST",
|
||||
data: {
|
||||
"id" : quoteID,
|
||||
"action" : "delete",
|
||||
return data;
|
||||
}
|
||||
} ],
|
||||
"columns": [
|
||||
{
|
||||
"data": "quote_id",
|
||||
"searchable": true,
|
||||
"orderable": true
|
||||
},
|
||||
{
|
||||
"data": "source",
|
||||
"searchable": true,
|
||||
"orderable": true
|
||||
},
|
||||
{
|
||||
"data": "text",
|
||||
"searchable": true,
|
||||
"orderable": true
|
||||
},
|
||||
{
|
||||
"data": function( row, type, val, meta ) {
|
||||
return $datetime(row.displayed_on);
|
||||
},
|
||||
/* Delete the row from the datatable */
|
||||
success: function(){
|
||||
oTable.fnDeleteRow(this);
|
||||
oTable.fnReloadAjax(null, null, true);
|
||||
}
|
||||
"searchable": true,
|
||||
"orderable": true
|
||||
},
|
||||
{
|
||||
"data": function( row, type, val, meta ) {
|
||||
|
||||
var result = '<a class="btn btn-default btn-xs" href="/cgi-bin/koha/tools/quotes.pl?op=add_form&id='+encodeURIComponent(row.quote_id)+'" role="button"><i class="fa fa-pencil" aria-hidden="true"></i> '+_("Edit")+'</a>';
|
||||
result += '<form action="/cgi-bin/koha/tools/quotes.pl" method="post">';
|
||||
result += '<input type="hidden" name="id" value="'+row.quote_id.escapeHtml()+'" />'+"\n";
|
||||
|
||||
result += '<a class="btn btn-default btn-xs delete_quote" role="button" href="#" data-toggle="modal" data-target="#delete_confirm_modal" data-quote-id="'+ encodeURIComponent(row.quote_id) +'"><i class="fa fa-trash" aria-hidden="true"></i> '+_("Delete")+'</a>';
|
||||
|
||||
return result;
|
||||
},
|
||||
"searchable": false,
|
||||
"orderable": false
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
$('#quotes').on( "click", '.delete_quote', function () {
|
||||
var quote_id = decodeURIComponent($(this).data('quote-id'));
|
||||
|
||||
$("#delete_confirm_dialog").html(
|
||||
_("You are about to delete the quote #%s.").format(quote_id)
|
||||
);
|
||||
|
||||
$("#delete_confirm_modal_button").unbind("click").on( "click", function () {
|
||||
$.ajax({
|
||||
method: "DELETE",
|
||||
url: "/api/v1/quotes/"+quote_id
|
||||
}).success(function() {
|
||||
$("#delete_confirm_modal").modal('hide');
|
||||
quotes.api().ajax.reload(function (data) {
|
||||
if (data.recordsTotal == 0) {
|
||||
$("#quotes").hide();
|
||||
}
|
||||
$("#quote_action_result_dialog").hide();
|
||||
$("#quote_delete_success").html(_("Quote #%s deleted successfully.").format(quote_id)).show();
|
||||
});
|
||||
}).error(function () {
|
||||
$("#quote_delete_error").html(_("Error deleting quote #%s. Check the logs.").format(quote_id)).show();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
[% END %]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# Copyright 2012 Foundations Bible College Inc.
|
||||
#
|
||||
# This file is part of Koha.
|
||||
#
|
||||
# Koha is free software; you can redistribute it and/or modify it
|
||||
|
|
@ -20,23 +18,80 @@
|
|||
use Modern::Perl;
|
||||
|
||||
use CGI qw ( -utf8 );
|
||||
use autouse 'Data::Dumper' => qw(Dumper);
|
||||
use Try::Tiny;
|
||||
|
||||
use C4::Auth;
|
||||
use C4::Koha;
|
||||
use C4::Context;
|
||||
use C4::Output;
|
||||
use Koha::Quotes;
|
||||
|
||||
my $cgi = CGI->new;
|
||||
my $input = CGI->new;
|
||||
|
||||
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
|
||||
{
|
||||
template_name => "tools/quotes.tt",
|
||||
query => $cgi,
|
||||
type => "intranet",
|
||||
flagsrequired => { tools => 'edit_quotes' },
|
||||
debug => 1,
|
||||
template_name => "tools/quotes.tt",
|
||||
query => $input,
|
||||
type => "intranet",
|
||||
flagsrequired => { tools => 'edit_quotes' },
|
||||
debug => 1,
|
||||
}
|
||||
);
|
||||
|
||||
output_html_with_http_headers $cgi, $cookie, $template->output;
|
||||
my $id = $input->param('id');
|
||||
my $op = $input->param('op') || 'list';
|
||||
my @messages;
|
||||
|
||||
if ( $op eq 'add_form' ) {
|
||||
$template->param( quote => Koha::Quotes->find($id), );
|
||||
}
|
||||
elsif ( $op eq 'add_validate' ) {
|
||||
my @fields = qw(
|
||||
source
|
||||
text
|
||||
);
|
||||
|
||||
if ($id) {
|
||||
my $quote = Koha::Quotes->find($id);
|
||||
for my $field (@fields) {
|
||||
$quote->$field( scalar $input->param($field) );
|
||||
}
|
||||
|
||||
try {
|
||||
$quote->store;
|
||||
push @messages, { type => 'message', code => 'success_on_update' };
|
||||
}
|
||||
catch {
|
||||
push @messages, { type => 'alert', code => 'error_on_update' };
|
||||
}
|
||||
}
|
||||
else {
|
||||
my $quote = Koha::Quote->new(
|
||||
{
|
||||
id => $id,
|
||||
( map { $_ => scalar $input->param($_) || undef } @fields )
|
||||
}
|
||||
);
|
||||
|
||||
try {
|
||||
$quote->store;
|
||||
push @messages, { type => 'message', code => 'success_on_insert' };
|
||||
}
|
||||
catch {
|
||||
push @messages, { type => 'alert', code => 'error_on_insert' };
|
||||
};
|
||||
}
|
||||
$op = 'list';
|
||||
}
|
||||
else {
|
||||
$op = 'list';
|
||||
}
|
||||
|
||||
$template->param( quotes_count => Koha::Quotes->search->count )
|
||||
if $op eq 'list';
|
||||
|
||||
$template->param(
|
||||
messages => \@messages,
|
||||
op => $op,
|
||||
);
|
||||
|
||||
output_html_with_http_headers $input, $cookie, $template->output;
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# Copyright 2012 Foundations Bible College Inc.
|
||||
#
|
||||
# This file is part of Koha.
|
||||
#
|
||||
# Koha is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Koha is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use CGI qw ( -utf8 );
|
||||
use JSON;
|
||||
use URI::Escape;
|
||||
use autouse 'Data::Dumper' => qw(Dumper);
|
||||
|
||||
use C4::Auth;
|
||||
use C4::Koha;
|
||||
use C4::Context;
|
||||
use C4::Output;
|
||||
|
||||
my $cgi = CGI->new;
|
||||
my $dbh = C4::Context->dbh;
|
||||
|
||||
my ( $status, $cookie, $sessionID ) = C4::Auth::check_api_auth( $cgi, { tools => 'edit_quotes' } );
|
||||
unless ($status eq "ok") {
|
||||
print $cgi->header(-type => 'application/json', -status => '403 Forbidden');
|
||||
print to_json({ auth_status => $status });
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $success = 'true';
|
||||
my $quotes_tmp = uri_unescape( $cgi->param('quote' ) );
|
||||
my $quotes = decode_json( $quotes_tmp );
|
||||
|
||||
my $action = $cgi->param('action');
|
||||
|
||||
my $sth = $dbh->prepare('INSERT INTO quotes (source, text) VALUES (?, ?);');
|
||||
|
||||
my $insert_count = 0;
|
||||
|
||||
foreach my $quote (@$quotes) {
|
||||
$insert_count++ if $sth->execute($quote->[1], $quote->[2]);
|
||||
if ($sth->err) {
|
||||
warn sprintf('Database returned the following error: %s', $sth->errstr);
|
||||
$success = 'false';
|
||||
}
|
||||
}
|
||||
|
||||
print $cgi->header('application/json');
|
||||
|
||||
print to_json({
|
||||
success => $success,
|
||||
records => $insert_count,
|
||||
});
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# Copyright 2012 Foundations Bible College Inc.
|
||||
#
|
||||
# This file is part of Koha.
|
||||
#
|
||||
# Koha is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Koha is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use CGI qw ( -utf8 );
|
||||
use JSON;
|
||||
use autouse 'Data::Dumper' => qw(Dumper);
|
||||
|
||||
use C4::Auth;
|
||||
use C4::Context;
|
||||
|
||||
my $cgi = CGI->new;
|
||||
my $dbh = C4::Context->dbh;
|
||||
my $sort_columns = ["id", "source", "text", "timestamp"];
|
||||
|
||||
my ( $status, $cookie, $sessionID ) = C4::Auth::check_api_auth( $cgi, { tools => 'edit_quotes' } );
|
||||
unless ($status eq "ok") {
|
||||
print $cgi->header(-type => 'application/json', -status => '403 Forbidden');
|
||||
print to_json({ auth_status => $status });
|
||||
exit 0;
|
||||
}
|
||||
|
||||
# NOTE: This is a collection of ajax functions for use with tools/quotes.pl
|
||||
|
||||
my $params = $cgi->Vars; # NOTE: Multivalue parameters NOT allowed!!
|
||||
|
||||
print $cgi->header('application/json; charset=utf-8');
|
||||
|
||||
my $action = $params->{'action'} || 'get';
|
||||
if ($action eq 'add') {
|
||||
my $sth = $dbh->prepare('INSERT INTO quotes (source, text) VALUES (?, ?);');
|
||||
$sth->execute($params->{'source'}, $params->{'text'});
|
||||
if ($sth->err) {
|
||||
warn sprintf('Database returned the following error: %s', $sth->errstr);
|
||||
exit 0;
|
||||
}
|
||||
my $new_quote_id = $dbh->{q{mysql_insertid}}; # ALERT: mysqlism here
|
||||
$sth = $dbh->prepare('SELECT * FROM quotes WHERE id = ?;');
|
||||
$sth->execute($new_quote_id);
|
||||
print to_json($sth->fetchall_arrayref, {utf8 =>1});
|
||||
exit 0;
|
||||
}
|
||||
elsif ($action eq 'edit') {
|
||||
my $aaData = [];
|
||||
my $editable_columns = [qw(source text)]; # pay attention to element order; these columns match the quotes table columns
|
||||
my $sth = $dbh->prepare("UPDATE quotes SET $editable_columns->[$params->{'column'}-1] = ? WHERE id = ?;");
|
||||
$sth->execute($params->{'value'}, $params->{'id'});
|
||||
if ($sth->err) {
|
||||
warn sprintf('Database returned the following error: %s', $sth->errstr);
|
||||
exit 1;
|
||||
}
|
||||
$sth = $dbh->prepare("SELECT $editable_columns->[$params->{'column'}-1] FROM quotes WHERE id = ?;");
|
||||
$sth->execute($params->{'id'});
|
||||
$aaData = $sth->fetchrow_array();
|
||||
print Encode::encode('utf8', $aaData);
|
||||
|
||||
exit 0;
|
||||
}
|
||||
elsif ($action eq 'delete') {
|
||||
my $sth = $dbh->prepare("DELETE FROM quotes WHERE id = ?;");
|
||||
$sth->execute($params->{'id'});
|
||||
if ($sth->err) {
|
||||
warn sprintf('Database returned the following error: %s', $sth->errstr);
|
||||
exit 1;
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
else {
|
||||
my $aaData = [];
|
||||
my $iTotalRecords = '';
|
||||
my $sth = '';
|
||||
|
||||
$iTotalRecords = $dbh->selectrow_array('SELECT count(*) FROM quotes;');
|
||||
$sth = $dbh->prepare("SELECT * FROM quotes;");
|
||||
|
||||
$sth->execute();
|
||||
if ($sth->err) {
|
||||
warn sprintf('Database returned the following error: %s', $sth->errstr);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
$aaData = $sth->fetchall_arrayref;
|
||||
my $iTotalDisplayRecords = $iTotalRecords; # no filtering happening here
|
||||
|
||||
|
||||
print to_json({
|
||||
iTotalRecords => $iTotalRecords,
|
||||
iTotalDisplayRecords=> $iTotalDisplayRecords,
|
||||
sEcho => $params->{'sEcho'},
|
||||
aaData => $aaData,
|
||||
}, {utf8 =>1});
|
||||
}
|
||||
Loading…
Reference in New Issue