@@ -, +, @@ - Make sure you update database after applying patch - After adding a few pages, confirm that filtering results works (play with different combinations of display location, library and language) - Confirm that pages with specific locations ONLY show up in those - Confirm that table is showing correct data, particularly language, - Confirm that if page has not been published and user does not have - Confirm pagination for table shows and works - Confirm deleting pages works as expected (confirm message before - Confirm link title must be unique when adding new pages - Confirm that editing the details of an existing page works - Confirm that adding a child page will only work if the location of - Confirm Select All/Clear All toggle works - Confirm viewing of CMS pages in OPAC and in staff client works and --- Koha/CmsPage.pm | 2 +- Koha/CmsPages.pm | 78 ++++--- Koha/Schema/Result/Branch.pm | 16 +- Koha/Schema/Result/CmsPage.pm | 150 ++++++++++++ .../bug15326-add_cms_pages_permission.sql | 1 + .../intranet-tmpl/prog/en/includes/tools-menu.inc | 71 ++++-- .../prog/en/modules/tools/cmspages.tt | 259 +++++++++++++-------- .../opac-tmpl/bootstrap/en/includes/masthead.inc | 14 -- .../opac-tmpl/bootstrap/en/includes/navigation.inc | 27 ++- .../bootstrap/en/modules/opac-cmspages.tt | 56 ++--- koha-tmpl/opac-tmpl/bootstrap/less/opac.less | 40 +--- opac/opac-cmspages.pl | 14 +- opac/opac-main.pl | 14 +- tools/cmspages.pl | 41 ++-- 14 files changed, 521 insertions(+), 262 deletions(-) create mode 100644 Koha/Schema/Result/CmsPage.pm create mode 100644 installer/data/mysql/atomicupdate/bug15326-add_cms_pages_permission.sql --- a/Koha/CmsPage.pm +++ a/Koha/CmsPage.pm @@ -39,7 +39,7 @@ Koha::CmsPage - Koha Page Object class =cut -sub type { +sub _type { return 'CmsPage'; } --- a/Koha/CmsPages.pm +++ a/Koha/CmsPages.pm @@ -40,7 +40,7 @@ Koha::CmsPage - Koha CMS Page Object Class =cut -sub type { +sub _type { return 'CmsPage'; } @@ -54,14 +54,13 @@ Adds a new page to the CMS database based on the input data. sub add { my ( $self, $input ) = @_; -warn "input: ", scalar $input->param('location'); carp( 'Koha::CmsPages::add() undefined parameter: input' ) unless defined $input; my $data = { - parent => scalar $input->param( 'parent' ) eq '' ? undef : scalar $input->param( 'parent' ), - location => scalar $input->param( 'location' ) eq '' ? undef : scalar $input->param( 'location'), - branchcode => scalar $input->param( 'branchcode' ) eq '' ? undef : scalar $input->param( 'branchcode' ), + parent => scalar $input->param( 'parent' ) eq '' ? undef : scalar $input->param( 'parent' ), + location => scalar $input->param( 'disp' ) eq '' ? undef : scalar $input->param( 'disp'), + branchcode => scalar $input->param( 'branch' ) eq '' ? undef : scalar $input->param( 'branch' ), lang => scalar $input->param( 'lang' ), - sortorder => scalar $input->param( 'sortorder' ), + sortorder => scalar $input->param( 'number' ), title => scalar $input->param( 'title' ), title_link => scalar $input->param( 'title_link' ), publish => defined (scalar $input->param( 'publish' )), @@ -72,6 +71,30 @@ warn "input: ", scalar $input->param('location'); $data->{'id'} = scalar $input->param( 'id' ); } + # Ensuring link titles are unique + my $title_link = $input->param('title_link'); + if ( Koha::CmsPages->find({ title_link => $title_link }) ) { + my $existing_link = Koha::CmsPages->find({ title_link => $title_link }); + my $link = $existing_link->unblessed; + unless ( $link->{'id'} eq $input->param('id') ) { + return undef; + } + } + + # Ensuring that, if page has parent, provided location suits parent location + my $parent = $input->param('parent'); + my $parent_obj = Koha::CmsPages->find($parent); + if ( $parent_obj ) { + my $parent_unblessed = $parent_obj->unblessed; + if ( $parent_unblessed->{'location'} ne "" ) { + # if parent location is not all interfaces + if ( $parent_unblessed->{'location'} != $input->param('disp') ) { + # if parent location is not the same as provided location + return undef; + } + } + } + my $new_page = $self->_resultset()->update_or_create( $data, { key => 'primary' }); return $new_page; @@ -86,15 +109,24 @@ Lists pages based input filtering paramters for location, branch and language. sub list { my ( $self, $id, $disp, $branch, $lang ) = @_; - my $filter = { }; - $filter->{'location'} = $disp unless not defined $disp; - $filter->{'branch'} = $branch unless not defined $branch; - $filter->{'lang'} = $lang unless not defined $lang; + my %filter; + if ($branch) { + my $branch_push = [ $branch, undef ]; + push @{$filter{'branchcode'}}, $branch_push; + } + if ($lang) { + my $lang_push = [ $lang, undef ]; + push @{$filter{'lang'}}, $lang_push; + } + if ($disp) { + my $disp_push = [ $disp, undef ]; + push @{$filter{'location'}}, $disp_push; + } - my $pages = $self->_resultset()->search( undef, { + my $pages = $self->_resultset()->search( {}, { order_by => { - -asc => [qw/parent location branchcode lang sortorder/] - }, where => $filter + -asc => [qw/parent location branchcode lang sortorder/] + }, where => { %filter } } ); my $page_list = []; @@ -143,20 +175,13 @@ Retrieves all data to show a single CMS page. =cut sub page { - my ( $self, $id ) = @_; - - carp( 'Missing CMS page id parameter in Koha::Pages::page' ) unless defined $id; - - # Probably want to merge these to a single query: - my $top_links = $self->_resultset()->search( - { parent => undef }, { qw/id title_link/ }); + my ( $self, $id ) = @_; - my $page_links = $self->_resultset()->search( - { parent => $id }, { qw/id title_link/ }); + carp( 'Missing CMS page id parameter in Koha::Pages::page' ) unless defined $id; - my $page_data = $self->_resultset()->find( $id ); + my $page_data = $self->_resultset()->find( $id ); - return ( $top_links, $page_links, $page_data ); + return $page_data; } =head3 child_links @@ -168,9 +193,8 @@ Lists pages which are children of a specific id (or undef for root). sub child_links { my ( $self, $id ) = @_; - # 'id' can be undefined if listing top-level links. - my $rs = $self->_resultset()->search({ parent => $id }, - { columns => [qw/id title_link/] } ); + # 'id' can be undefined if listing top-level links. + my $rs = $self->_resultset()->search({ parent => $id }, { qw/id title_link/ }); return $rs; } --- a/Koha/Schema/Result/Branch.pm +++ a/Koha/Schema/Result/Branch.pm @@ -413,6 +413,21 @@ __PACKAGE__->has_many( { cascade_copy => 0, cascade_delete => 0 }, ); +=head2 cms_pages + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "cms_pages", + "Koha::Schema::Result::CmsPage", + { "foreign.branchcode" => "self.branchcode" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + =head2 collections Type: has_many @@ -622,7 +637,6 @@ __PACKAGE__->many_to_many("categorycodes", "branchrelations", "categorycode"); # Created by DBIx::Class::Schema::Loader v0.07042 @ 2017-11-09 11:42:45 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LmN2FlbKiZTRX+egCHuDjQ - # You can replace this text with custom code or comments, and it will be preserved on regeneration sub koha_objects_class { --- a/Koha/Schema/Result/CmsPage.pm +++ a/Koha/Schema/Result/CmsPage.pm @@ -0,0 +1,150 @@ +use utf8; +package Koha::Schema::Result::CmsPage; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +=head1 NAME + +Koha::Schema::Result::CmsPage + +=cut + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +=head1 TABLE: C + +=cut + +__PACKAGE__->table("cms_pages"); + +=head1 ACCESSORS + +=head2 id + + data_type: 'integer' + is_auto_increment: 1 + is_nullable: 0 + +=head2 parent + + data_type: 'integer' + is_nullable: 1 + +=head2 branchcode + + data_type: 'varchar' + is_foreign_key: 1 + is_nullable: 1 + size: 10 + +=head2 lang + + data_type: 'varchar' + default_value: (empty string) + is_nullable: 0 + size: 25 + +=head2 title + + data_type: 'varchar' + is_nullable: 1 + size: 255 + +=head2 title_link + + data_type: 'varchar' + is_nullable: 1 + size: 64 + +=head2 sortorder + + data_type: 'integer' + default_value: 0 + is_nullable: 0 + +=head2 location + + data_type: 'tinyint' + is_nullable: 1 + +=head2 publish + + data_type: 'tinyint' + default_value: 0 + is_nullable: 0 + +=head2 content + + data_type: 'text' + is_nullable: 1 + +=cut + +__PACKAGE__->add_columns( + "id", + { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, + "parent", + { data_type => "integer", is_nullable => 1 }, + "branchcode", + { data_type => "varchar", is_foreign_key => 1, is_nullable => 1, size => 10 }, + "lang", + { data_type => "varchar", default_value => "", is_nullable => 0, size => 25 }, + "title", + { data_type => "varchar", is_nullable => 1, size => 255 }, + "title_link", + { data_type => "varchar", is_nullable => 1, size => 64 }, + "sortorder", + { data_type => "integer", default_value => 0, is_nullable => 0 }, + "location", + { data_type => "tinyint", is_nullable => 1 }, + "publish", + { data_type => "tinyint", default_value => 0, is_nullable => 0 }, + "content", + { data_type => "text", is_nullable => 1 }, +); + +=head1 PRIMARY KEY + +=over 4 + +=item * L + +=back + +=cut + +__PACKAGE__->set_primary_key("id"); + +=head1 RELATIONS + +=head2 branchcode + +Type: belongs_to + +Related object: L + +=cut + +__PACKAGE__->belongs_to( + "branchcode", + "Koha::Schema::Result::Branch", + { branchcode => "branchcode" }, + { + is_deferrable => 1, + join_type => "LEFT", + on_delete => "CASCADE", + on_update => "CASCADE", + }, +); + + +# Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-12-12 02:41:09 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:9044j1OZyypCpGV71FgvYg + + +# You can replace this text with custom code or comments, and it will be preserved on regeneration +1; --- a/installer/data/mysql/atomicupdate/bug15326-add_cms_pages_permission.sql +++ a/installer/data/mysql/atomicupdate/bug15326-add_cms_pages_permission.sql @@ -0,0 +1, @@ +INSERT IGNORE INTO permissions (`module_bit`, `code`, `description`) VALUES ('13', 'edit_pages', 'Create, edit and delete CMS pages for OPAC and staff interfaces'); --- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc @@ -1,3 +1,23 @@ + + [% END # / OpacPublic %] --- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/navigation.inc +++ a/koha-tmpl/opac-tmpl/bootstrap/en/includes/navigation.inc @@ -1,12 +1,23 @@
-[% IF ( cms_nav_left ) %] - -[% END %] -[% OpacNav %]
+ [% IF ( links ) %] +

Pages

+
    + [% FOREACH link IN links %] + [% IF ( link.publish == '1' || link.publish == '0' && CAN_user_tools_edit_pages ) %] + [% IF ( link.location == '' || link.location == '2' ) %] + [% IF ( link.parent != '' ) %] + [% FOREACH parent IN parent_list %] + [% IF ( parent.id == link.parent ) %]
  • [% parent.title_link %][% link.title_link %]
  • [% END %] + [% END %] + [% ELSE %] +
  • [% link.title_link %]
  • + [% END %] + [% END %][% END %] + [% END %] +
+ [% END %] + [% OpacNav %] + [% IF IsPatronPage %]
[% INCLUDE usermenu.inc %]
[% END %] --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-cmspages.tt +++ a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-cmspages.tt @@ -1,7 +1,7 @@ [% USE Koha %] [% USE Branches %] [% INCLUDE 'doc-head-open.inc' %] -[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %][% IF (cms_page.title) %] - [% cms_page.title %][% ELSE %] catalog[% END%] +[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online catalog[% END %][% IF (cms_page.title) %] › [% cms_page.title %][% END%] [% INCLUDE 'doc-head-close.inc' %] [% BLOCK cssinclude %][% END %] @@ -10,8 +10,12 @@
@@ -39,48 +43,16 @@ [% ELSE %]
[% END %] - [% cms_page.content %] + + [% IF ( cms_page.publish == 1 ) || ( cms_page.publish == 0 && CAN_user_tools_edit_pages ) %] + [% cms_page.content %] + [% ELSE %] + This page has not been published. + [% END %] + [% IF ( OpacMainUserBlock ) %]
[% OpacMainUserBlock %]
[% END %]
- [% IF ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) || OpacNavRight ) %] -
- [% IF Koha.Preference( 'opacuserlogin' ) == 1 %] - [% UNLESS ( loggedinusername ) %] - [% UNLESS ( casAuthentication || shibbolethAuthentication ) %] -
-
- -
- Log in to your account: - - -
- -
- [% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %]

Don't have an account? Register here.

[% END %] -
- [% IF Koha.Preference( 'NoLoginInstructions' ) %] -
- [% Koha.Preference( 'NoLoginInstructions' ) %] -
- [% END %] -
-
- [% END # /casAuthentication %] - [% IF persona %] - Sign in with your email - [% END # /persona %] - [% END # / loggedinusername %] - [% END # /opacuserlogin %] - [% IF ( OpacNavRight ) %] -
- [% OpacNavRight %] -
- [% END # /OpacNavRight %] -
- [% END # /opacuserlogin || OpacNavRight %] -
--- a/koha-tmpl/opac-tmpl/bootstrap/less/opac.less +++ a/koha-tmpl/opac-tmpl/bootstrap/less/opac.less @@ -221,37 +221,15 @@ td { } #cms_nav_top { - li { - margin-bottom: -1em; - display: inline; - white-space: nowrap; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - background-color: #eee; - border: 1px solid #D2D2CF; - border-bottom: none; - padding: 0.1em 0.8em 0em 0.8em; - font-weight: bold; - font-size: 1.2em; - border-bottom: 1px solid #D2D2CF; - a { - text-decoration: none; - } - &.cms_nav_top_active { - background-color: #fff; - border-bottom: 1px solid #FFF; - } - } - ul { - margin: 0; - display: inline; - } - display: inline; -} - -ul#cms_nav_left { - list-style-type: none; - padding: 0; + list-style-type: circle; + padding: 0; + margin: 0; + a { + text-decoration: none; + } + a:hover { + text-decoration: underline; + } } #news { --- a/opac/opac-cmspages.pl +++ a/opac/opac-cmspages.pl @@ -23,6 +23,7 @@ use C4::Auth; use C4::Output; use C4::Languages qw( getTranslatedLanguages accept_language ); use Koha::CmsPages; +use Data::Dumper; my $input = new CGI; my $id = scalar $input->param( 'id' ) // ''; @@ -42,11 +43,14 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( my ( $theme, $news_lang, $availablethemes ) = C4::Templates::themelanguage( C4::Context->config( 'opachtdocs'), 'opac-cmspages.tt', 'opac', $input ); -my ($cms_nav_top, $cms_nav_left, $cms_data) = Koha::CmsPages->page( $id ); +# List all pages, if id is set generate parent page list and data. +my ( $page_list, $parent_list, $page_data ) = Koha::CmsPages->list( $id ); + +my $links = Koha::CmsPages->search( {}, { order_by => 'sortorder' } ); +my $cms_data = Koha::CmsPages->page( $id ); $template->param( - cms_page => $cms_data, - cms_nav_top => $cms_nav_top, - cms_nav_left => $cms_nav_left, + links => $links, + cms_page => $cms_data, + parent_list => $parent_list, ); - output_html_with_http_headers $input, $cookie, $template->output; --- a/opac/opac-main.pl +++ a/opac/opac-main.pl @@ -29,7 +29,7 @@ use C4::Members; use C4::Overdues; use Koha::Checkouts; use Koha::Holds; -use Koha::CmsPages qw( list ); +use Koha::CmsPages; my $input = new CGI; my $dbh = C4::Context->dbh; @@ -96,9 +96,17 @@ $template->param( daily_quote => $quote, ); +my $id = scalar $input->param( 'id' ) // ''; +my ( $page_list, $parent_list, $page_data ) = Koha::CmsPages->list( $id ); +my $links = Koha::CmsPages->search( {}, { order_by => 'parent' } ); +my $cms_data = Koha::CmsPages->page( $id ); $template->param( - cms_nav_top => Koha::CmsPages->child_links( undef ), -); + links => $links, + cms_page => $cms_data, + parent_list => $parent_list, + ); + + if (C4::Context->preference('GoogleIndicTransliteration')) { $template->param('GoogleIndicTransliteration' => 1); --- a/tools/cmspages.pl +++ a/tools/cmspages.pl @@ -23,8 +23,8 @@ use CGI qw( -utf8 ); use C4::Auth; use C4::Output; use C4::Languages qw( getTranslatedLanguages ); -use Koha::Database; use Koha::CmsPages; +use Koha::Libraries; my $link_self = '/cgi-bin/koha/tools/cmspages.pl'; @@ -50,17 +50,14 @@ $template->param( disp => $disp ); -my $schema = Koha::Database->new->schema; -my @branches = $schema->resultset( 'Branch' )->all; -$template->param( branch_list => @branches ); - my $lang_list = getTranslatedLanguages; +my $branches = Koha::Libraries->search( {}, { order_by => ['branchcode'] }, ); # List all pages, if id is set generate parent page list and data. my ( $page_list, $parent_list, $page_data ) = Koha::CmsPages->list( $id ); $template->param( - page_list_count => scalar $page_list, + branch_list => $branches, page_list => $page_list, parent_list => $parent_list, data => $page_data, @@ -74,17 +71,35 @@ if ( $op eq 'form' ) { id => $id, op => 'add' ); -} - -if ( $op eq 'add' ) { - Koha::CmsPages->add( $cgi ); - print $cgi->redirect( $link_self ); - +} elsif ( $op eq 'add' ) { + my $success = Koha::CmsPages->add( $cgi ); + unless ($success) { + $template->param( failed_add => 1 ); + } + if ($success) { + print $cgi->redirect( $link_self ); + } } elsif ( $op eq 'del' ) { # param => multi_param; no list-ctx warnings Koha::CmsPages->remove( $cgi->multi_param( 'ids' ) ); print $cgi->redirect( $link_self ); +} elsif ( $op eq 'view' ) { + my $cms_data = Koha::CmsPages->page( $id ); + my $links = Koha::CmsPages->search( {}, { order_by => 'sortorder' } ); + $template->param( + links => $links, + cms_page => $cms_data, + view => 1, + id => $id, + op => 'view', + ); +} elsif ( $op eq 'filter' ) { + my ( $page_list, $parent_list, $page_data ) = Koha::CmsPages->list( $id, $disp, $branch, $lang ); + $template->param( + page_list => $page_list, + parent_list => $parent_list, + data => $page_data, + ); } - $template->param( link_self => $link_self ); output_html_with_http_headers $cgi, $cookie, $template->output; --