package controllers; import java.util.LinkedList; import java.util.List; import managers.NotificationManager; import models.Account; import models.Notification; import play.Configuration; import play.api.i18n.Lang; import play.i18n.MessagesApi; import play.twirl.api.Html; import play.db.jpa.Transactional; import play.mvc.Result; import play.mvc.Security; import views.html.Notification.view; import javax.inject.Inject; @Transactional @Security.Authenticated(Secured.class) public class NotificationController extends BaseController { NotificationManager notificationManager; Configuration configuration; MessagesApi messagesApi; @Inject public NotificationController(NotificationManager notificationManager, Configuration configuration, MessagesApi messagesApi) { this.notificationManager = notificationManager; this.configuration = configuration; this.messagesApi = messagesApi; this.LIMIT = configuration.getInt("htwplus.notification.limit"); } int LIMIT; /** * @deprecated Deprecated since refactor of notification system * @return Html */ public Html view() { return getNotifications(); } /** * Returns all notifications for current user. * * @return Html rendered instance */ @Transactional(readOnly = true) public static Html getNotifications() { Account account = Component.currentAccount(); if (account == null) { return new Html("Das wird nichts"); } List<Notification> list = null; try { list = NotificationManager.findByAccountIdUnread(account.id); } catch (Throwable throwable) { throwable.printStackTrace(); } List<Integer> countedNotifications = NotificationController.countNotifications(list); return views.html.Notification.menuitem.render(list, countedNotifications.get(0), NotificationManager.countUnreadNotificationsForAccountId(account.id) ); } /** * Redirects to the target URL of the notification, if user has access. * * @param notificationId ID of the notification * @return SimpleResult with redirection */ @Transactional public Result forward(Long notificationId) { Notification notification = notificationManager.findById(notificationId); if (notification == null) { flash("info", messagesApi.get(Lang.defaultLang(), "notification.obsolete_notification")); return Secured.nullRedirect(request()); } if (!Secured.hasAccessToNotification(notification)) { flash("error", messagesApi.get(Lang.defaultLang(), "error.access_denied")); return redirect(controllers.routes.Application.index()); } // update only when notification is unread if (!notification.isRead) { notification.isRead = true; notificationManager.update(notification); } return redirect(notification.targetUrl); } /** * Shows all notifications. * * @param page Current page * @return Result */ @Transactional(readOnly = true) public Result showAll(int page) { List<Notification> notifications = null; try { notifications = notificationManager.findByAccountIdForPage(Component.currentAccount().id, LIMIT, page); } catch (Throwable throwable) { throwable.printStackTrace(); } List<Integer> countedNotifications = NotificationController.countNotifications(notifications); Navigation.set(Navigation.Level.NOTIFICATIONS, messagesApi.get(Lang.defaultLang(), "notification.title")); return ok(view.render(notifications, LIMIT, page, notificationManager.countNotificationsForAccountId(Component.currentAccount().id), countedNotifications.get(1) )); } /** * Loops over a notification list and counts: * 1st element (index 0): All notifications * 2nd element (index 1): Unread notifications * 3rd element (index 2): Read notifications * * @param notifications List of notifications * @return List with count of all, unread and read notifications */ public static List<Integer> countNotifications(List<Notification> notifications) { int countAll = 0; int countUnread = 0; int countRead = 0; List<Integer> count = new LinkedList<>(); if (notifications != null) { countAll = notifications.size(); for (Notification notification : notifications) { if (notification.isRead) { countRead++; } } countUnread = countAll - countRead; } // add counted elements to list count.add(0, countAll); count.add(1, countUnread); count.add(2, countRead); return count; } /** * Marks all notifications as read for an Account. * * @return Result */ @Transactional public Result readAll() { notificationManager.markAllAsRead(Component.currentAccount()); flash("success", messagesApi.get(Lang.defaultLang(), "notification.read_everything_ok")); return Secured.nullRedirect(request()); } }