diff --git a/extensions/BugzillaDonationBanner/Config.pm b/extensions/BugzillaDonationBanner/Config.pm new file mode 100644 index 000000000..9a2d77639 --- /dev/null +++ b/extensions/BugzillaDonationBanner/Config.pm @@ -0,0 +1,16 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::BugzillaDonationBanner; + +use 5.14.0; +use strict; +use warnings; + +use constant NAME => 'BugzillaDonationBanner'; + +__PACKAGE__->NAME; diff --git a/extensions/BugzillaDonationBanner/Extension.pm b/extensions/BugzillaDonationBanner/Extension.pm new file mode 100644 index 000000000..6854f13c8 --- /dev/null +++ b/extensions/BugzillaDonationBanner/Extension.pm @@ -0,0 +1,124 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::BugzillaDonationBanner; + +use 5.14.0; +use strict; +use warnings; +use base qw(Bugzilla::Extension); + +use Bugzilla::Constants; +use Bugzilla::Install::Filesystem; +use Bugzilla::User::Setting qw(add_setting); +use Bugzilla::Extension::BugzillaDonationBanner::Donation; + +our $VERSION = '1.0'; + +sub config_add_panels { + my ($self, $args) = @_; + $args->{panel_modules}->{Donation} + = 'Bugzilla::Extension::BugzillaDonationBanner::Config'; +} + +sub install_before_final_checks { + add_setting({ + name => 'donate_banner_pref', + options => ['next_upgrade', 'specific_date', 'never'], + default => 'next_upgrade', + category => 'Bugzilla.org', + }); + add_setting({ + name => 'donate_banner_last_version', + default => '0.0', + category => 'Bugzilla.org', + }); + add_setting({ + name => 'donate_banner_reminder_date', + default => '1970-01-01', + category => 'Bugzilla.org', + }); +} + +sub install_filesystem { + my ($self, $args) = @_; + my $files = $args->{files}; + my $extension_dir = bz_locations()->{extensionsdir} . '/' + . __PACKAGE__->NAME; + + $files->{"$extension_dir/bin/donate.cgi"} + = {perms => Bugzilla::Install::Filesystem::WS_EXECUTE}; + $files->{"$extension_dir/web/buggie_watering.svg"} + = {perms => Bugzilla::Install::Filesystem::WS_SERVE}; + $files->{"$extension_dir/web/donation-banner.css"} + = {perms => Bugzilla::Install::Filesystem::WS_SERVE}; + $files->{"$extension_dir/web/donation-banner.js"} + = {perms => Bugzilla::Install::Filesystem::WS_SERVE}; +} + +sub app_startup { + my ($self, $args) = @_; + my $app = $args->{app}; + my $r = $app->routes; + + Bugzilla::App::CGI->load_one( + 'bugzilla_donation_banner_cgi', + 'extensions/BugzillaDonationBanner/bin/donate.cgi' + ); + $r->post('/extensions/BugzillaDonationBanner/bin/donate.cgi') + ->to('CGI#bugzilla_donation_banner_cgi'); +} + +sub template_before_process { + my ($self, $args) = @_; + my ($file, $vars) = @$args{qw(file vars)}; + + if ($file =~ m{(?:^|/)index\.html\.tmpl$}) { + $vars->{donation} + = Bugzilla::Extension::BugzillaDonationBanner::Donation::get_banner(); + } +} + +sub user_preferences_settings { + my ($self, $args) = @_; + my $skip_settings = $args->{skip_settings}; + $skip_settings->{donate_banner_pref} = 1; + $skip_settings->{donate_banner_last_version} = 1; + $skip_settings->{donate_banner_reminder_date} = 1; +} + +sub user_preferences { + my ($self, $args) = @_; + return unless $args->{current_tab} eq 'donate'; + + my $vars = $args->{vars}; + my $user = Bugzilla->user; + my $cgi = Bugzilla->cgi; + + if ($args->{save_changes}) { + my $pref = $cgi->param('donate_banner_pref') || 'next_upgrade'; + my $date = $cgi->param('donate_banner_reminder_date') || ''; + Bugzilla::Extension::BugzillaDonationBanner::Donation::save_preference( + $pref, $date); + $vars->{changes_saved} = 1; + } + + $vars->{settings} = $user->settings(1); + $vars->{donation} + = Bugzilla::Extension::BugzillaDonationBanner::Donation::get_banner(1); + $vars->{donate_pref} = $user->setting('donate_banner_pref'); + $vars->{today} + = Bugzilla::Extension::BugzillaDonationBanner::Donation::today(); + my $reminder_date = $user->setting('donate_banner_reminder_date'); + $vars->{reminder_date} + = !$reminder_date || $reminder_date eq '1970-01-01' + ? $vars->{today} + : $reminder_date; + ${$args->{handled}} = 1; +} + +__PACKAGE__->NAME; diff --git a/extensions/BugzillaDonationBanner/bin/donate.cgi b/extensions/BugzillaDonationBanner/bin/donate.cgi new file mode 100644 index 000000000..aaa5e5bfc --- /dev/null +++ b/extensions/BugzillaDonationBanner/bin/donate.cgi @@ -0,0 +1,29 @@ +#!/usr/bin/env perl + +use 5.14.0; +use strict; +use warnings; + +use lib qw(../../.. ../../../lib); + +use Bugzilla; +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Token qw(check_hash_token); +use Bugzilla::Extension::BugzillaDonationBanner::Donation; + +my $cgi = Bugzilla->cgi; +if ($cgi->request_method ne 'POST') { + ThrowCodeError('illegal_request_method', + {method => $cgi->request_method, accepted => ['POST']}); +} + +Bugzilla->login(LOGIN_REQUIRED) unless Bugzilla->user->id; +check_hash_token($cgi->param('token'), ['donation_banner']); + +Bugzilla::Extension::BugzillaDonationBanner::Donation::dismiss( + scalar $cgi->param('donate_action'), + scalar $cgi->param('donate_banner_reminder_date'), +); + +$cgi->base_redirect(); diff --git a/extensions/BugzillaDonationBanner/lib/Config.pm b/extensions/BugzillaDonationBanner/lib/Config.pm new file mode 100644 index 000000000..1193b338c --- /dev/null +++ b/extensions/BugzillaDonationBanner/lib/Config.pm @@ -0,0 +1,28 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::BugzillaDonationBanner::Config; + +use 5.14.0; +use strict; +use warnings; + +use Bugzilla::Config::Common; + +our $sortkey = 175; + +use constant get_param_list => ( + { + name => 'donation_banner_visibility', + type => 's', + choices => ['admins_only', 'end_users', 'disabled'], + default => 'admins_only', + checker => \&check_multi, + }, +); + +1; diff --git a/extensions/BugzillaDonationBanner/lib/Donation.pm b/extensions/BugzillaDonationBanner/lib/Donation.pm new file mode 100644 index 000000000..e6a5c21e0 --- /dev/null +++ b/extensions/BugzillaDonationBanner/lib/Donation.pm @@ -0,0 +1,130 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::BugzillaDonationBanner::Donation; + +use 5.14.0; +use strict; +use warnings; + +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Token qw(issue_hash_token); +use Bugzilla::User::Setting qw(clear_settings_cache); +use Bugzilla::Util qw(validate_date); + +use DateTime; + +use constant BANNER_URL => 'https://bugzilla.org/donate'; +use constant BANNER_MESSAGES => ( + 'Help us make Bugzilla better more often.', + 'A small donation helps keep Bugzilla moving forward.', + 'Support the people who keep Bugzilla running.', + 'Even a little funding helps Bugzilla improve more quickly.', + 'If Bugzilla helps your team, consider helping Bugzilla too.', +); + +sub today { + return DateTime->now(time_zone => Bugzilla->local_timezone)->ymd; +} + +sub get_banner { + my ($ignore_preference) = @_; + my $user = Bugzilla->user; + return undef if !$user->id; + + my $visibility = Bugzilla->params->{donation_banner_visibility} + || 'admins_only'; + return undef if $visibility eq 'disabled'; + return undef if $visibility eq 'admins_only' && !$user->in_group('admin'); + + my $settings = $user->settings; + my $pref = $settings->{donate_banner_pref}->{value}; + my $last_version = $settings->{donate_banner_last_version}->{value} || '0.0'; + my $reminder_date + = $settings->{donate_banner_reminder_date}->{value} || '1970-01-01'; + my $current_version = BUGZILLA_VERSION; + + my ($show, $show_thanks) = (0, 0); + if ($pref eq 'next_upgrade') { + $show = $last_version ne $current_version; + $show_thanks = $show + && $user->in_group('admin') + && $last_version ne '0' + && $last_version ne '0.0'; + } + elsif ($pref eq 'specific_date') { + $show = $reminder_date le today(); + } + + return undef if !$show && !$ignore_preference; + + my @messages = BANNER_MESSAGES; + my $data = { + url => BANNER_URL, + message => $messages[int(rand(@messages))], + show_thanks => $show_thanks, + token => issue_hash_token(['donation_banner']), + today => today(), + settings_link => 'editparams.cgi?section=donation#donation_banner_visibility_desc', + }; + + if ($visibility eq 'admins_only') { + $data->{visibility_note} + = 'This message is only shown to logged-in users with admin privs.'; + } + elsif ($user->in_group('admin')) { + $data->{visibility_note} + = 'This message is visible to all logged-in users.'; + } + + return $data; +} + +sub save_preference { + my ($pref, $date) = @_; + my $user = Bugzilla->user; + my $settings = $user->settings; + + if ($pref eq 'specific_date') { + validate_date($date) + || ThrowUserError('illegal_date', {date => $date, format => 'YYYY-MM-DD'}); + $settings->{donate_banner_reminder_date}->set($date); + } + elsif ($pref ne 'next_upgrade' && $pref ne 'never') { + ThrowUserError('invalid_parameter', { + name => 'donate_banner_pref', + err => "must be one of 'next_upgrade', 'specific_date', or 'never'", + }); + } + + $settings->{donate_banner_pref}->set($pref); + $settings->{donate_banner_last_version}->set(BUGZILLA_VERSION); + clear_settings_cache($user->id); +} + +sub dismiss { + my ($action, $date) = @_; + my $settings = Bugzilla->user->settings; + + if ($action eq 'next_upgrade') { + save_preference('next_upgrade', ''); + } + elsif ($action eq 'week' || $action eq 'month') { + my $dt = DateTime->now(time_zone => Bugzilla->local_timezone); + $dt->add(days => $action eq 'week' ? 7 : 30); + save_preference('specific_date', $dt->ymd); + } + elsif ($action eq 'date') { + save_preference('specific_date', $date); + } + elsif ($action eq 'never') { + save_preference('never', ''); + } +} + +1; diff --git a/extensions/BugzillaDonationBanner/template/en/default/account/prefs/donate.html.tmpl b/extensions/BugzillaDonationBanner/template/en/default/account/prefs/donate.html.tmpl new file mode 100644 index 000000000..6bb151ab2 --- /dev/null +++ b/extensions/BugzillaDonationBanner/template/en/default/account/prefs/donate.html.tmpl @@ -0,0 +1,36 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + #%] + +[% PROCESS "donation/banner.html.tmpl" show_dismissal=0 %] + +
Choose when you want to be reminded about supporting Bugzilla on the home page:
+ +| + | + + | +