--- /dev/null
+package com.pentila.entSavoie.actualites.widgets;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.liferay.contacts.util.GroupFilter;
+import com.liferay.contacts.util.OrganizationFilter;
+import com.liferay.portal.kernel.bean.PortletBeanLocatorUtil;
+import com.liferay.portal.kernel.dao.orm.Criterion;
+import com.liferay.portal.kernel.dao.orm.DynamicQuery;
+import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
+import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
+import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
+import com.liferay.portal.kernel.exception.PortalException;
+import com.liferay.portal.kernel.exception.SystemException;
+import com.liferay.portal.kernel.json.JSONArray;
+import com.liferay.portal.kernel.json.JSONFactoryUtil;
+import com.liferay.portal.kernel.json.JSONObject;
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
+import com.liferay.portal.kernel.util.ListUtil;
+import com.liferay.portal.kernel.util.OrderByComparator;
+import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
+import com.liferay.portal.model.Group;
+import com.liferay.portal.model.Organization;
+import com.liferay.portal.model.Role;
+import com.liferay.portal.model.RoleConstants;
+import com.liferay.portal.model.User;
+import com.liferay.portal.service.GroupLocalServiceUtil;
+import com.liferay.portal.service.RoleLocalServiceUtil;
+import com.liferay.portal.theme.ThemeDisplay;
+import com.liferay.portlet.blogs.model.BlogsEntry;
+import com.liferay.portlet.blogs.util.service.BlogsEntryLocalServiceUtil;
+import com.pentila.entSavoie.ENTRoleUtilFactory;
+import com.pentila.entSavoie.ENTRolesConstants;
+import com.pentila.entSavoie.blogEntryInfos.model.BlogEntryDelegate;
+import com.pentila.entSavoie.blogEntryInfos.model.BlogEntryInfos;
+import com.pentila.entSavoie.blogEntryInfos.model.ConfirmReadBlogEntry;
+import com.pentila.entSavoie.blogEntryInfos.service.BlogEntryDelegateLocalServiceUtil;
+import com.pentila.entSavoie.blogEntryInfos.service.BlogEntryInfosLocalServiceUtil;
+import com.pentila.entSavoie.blogEntryInfos.service.ClpSerializer;
+import com.pentila.entSavoie.blogEntryInfos.service.ConfirmReadBlogEntryLocalServiceUtil;
+import com.pentila.entSavoie.blogs.BlogsEntryHeader;
+import com.pentila.entSavoie.utils.BlogsEntryHeaderDateComparator;
+import com.pentila.entSavoie.utils.ENTOrganizationsUtil;
+import com.pentila.entSavoie.utils.GroupCacheUtil;
+
+/**
+ * Class which has methods to get news
+ * @author ALE
+ *
+ */
+public class NewsGetter {
+
+
+ private static Log logger = LogFactoryUtil.getLog(NewsGetter.class);
+
+ public static JSONObject getAllNews(User user, long groupScopeId, int startLimit, int endLimit, boolean isWelcomePage,
+ boolean getNewsGroups, boolean getNewsHM, boolean getNewsHighPriority, ThemeDisplay themeDisplay)
+ throws PortalException, SystemException {
+
+ // Returned Json object
+ JSONObject ret = JSONFactoryUtil.createJSONObject();
+ Date now = new Date();
+
+ // Blog entry headers
+ List<BlogsEntryHeader> blogsEntryHeadersList = new ArrayList<BlogsEntryHeader>();
+ List<BlogsEntryHeader> finalBlogsEntryHeaderList = new ArrayList<BlogsEntryHeader>();
+ List<BlogsEntryHeader> finalHMBlogsEntryHeaderList = new ArrayList<BlogsEntryHeader>();
+
+ // Blog entry infos
+ List<BlogEntryInfos> blogEntryInfosList = new ArrayList<BlogEntryInfos>();
+ List<BlogEntryInfos> finalBlogEntryInfosList = new ArrayList<BlogEntryInfos>();
+ List<BlogEntryInfos> finalHMBlogEntryInfosList = new ArrayList<BlogEntryInfos>();
+
+ // Define all roles
+ Role headmasterRole = ENTRoleUtilFactory.getInstance(user.getCompanyId()).getRole(ENTRolesConstants.NATIONAL_4);
+ Boolean isHeadMaster = RoleLocalServiceUtil.hasUserRole(user.getUserId(), headmasterRole.getRoleId());
+
+ Role adminGrpRole = ENTRoleUtilFactory.getInstance(user.getCompanyId()).getRole(ENTRolesConstants.GROUP_ADMIN);
+ Boolean isGrpAdmin = RoleLocalServiceUtil.hasUserRole(user.getUserId(), adminGrpRole.getRoleId());
+
+ Role adminRole = ENTRoleUtilFactory.getInstance(user.getCompanyId()).getRole(RoleConstants.ADMINISTRATOR);
+ Boolean isAdministrator = RoleLocalServiceUtil.hasUserRole(user.getUserId(), adminRole.getRoleId());
+
+ // Check if user is delegate for his etab
+ List<BlogEntryDelegate> listBed = BlogEntryDelegateLocalServiceUtil.getEtabUserDelegate(user.getUserId());
+ Boolean isDelegate = false;
+ if (!listBed.isEmpty()) {
+ isDelegate = true;
+ }
+
+
+ // We're already in a group (accesAteliers)
+ if (!isWelcomePage) {
+
+ List<Long> listGroupId = new ArrayList<Long>();
+ listGroupId.add(groupScopeId);
+
+ blogsEntryHeadersList = com.liferay.portlet.blogs.util.service.BlogsEntryLocalServiceUtil.getBlogsEntryHeadersByGroupIdList(listGroupId);
+
+ blogEntryInfosList.addAll(getBlogEntryInfosListForGroupIdList(listGroupId, false));
+ } else {
+ List<Long> globalGroupIdList = getGroupList(user, isDelegate, "");
+ globalGroupIdList.add(getRootGroup(user.getCompanyId()).getGroupId());
+
+ // Fetch BlogsEntry objects for all groups
+ blogsEntryHeadersList = com.liferay.portlet.blogs.util.service.BlogsEntryLocalServiceUtil.getBlogsEntryHeadersByGroupIdList(globalGroupIdList);
+
+ // Fetch BlogEntryInfos objects for all groups
+ blogEntryInfosList = getBlogEntryInfosListForGroupIdList(globalGroupIdList, false);
+ }
+
+ // List of already added news id (to avoid duplicates)
+ List<Long> lbeAlreadyPut = new ArrayList<Long>();
+
+ for (BlogsEntryHeader blogsEntryHeader : blogsEntryHeadersList) {
+
+ boolean isAuthor = blogsEntryHeader.getUserId() == user.getUserId();
+
+ for (BlogEntryInfos bei : blogEntryInfosList) {
+ if (bei.getBlogEntryId() == blogsEntryHeader.getEntryId()) {
+ if ((bei.getBlogEntryGroup()) == 0) {
+ finalBlogsEntryHeaderList.add(blogsEntryHeader);
+ } else if (!lbeAlreadyPut.contains(bei.getBlogEntryGroup())) {
+ // Adding the blog entry to the list is done just below
+ // finalBlogsEntryList.add(blogsEntry);
+ lbeAlreadyPut.add(bei.getBlogEntryGroup());
+ } else {
+ break;
+ }
+
+ // Check date validity and ownership
+ if ((bei.getExpirationDate().after(now) && now.after(bei.getParutionDate())) || isAuthor) {
+
+ // Get classic news (left column)
+ if (!bei.getHeadMaster()) {
+ finalBlogsEntryHeaderList.add(blogsEntryHeader);
+ finalBlogEntryInfosList.add(bei);
+ continue;
+ }
+
+ // Get headmaster news (right column)
+ if (bei.getHeadMaster()) {
+ // on ajoute dans headMaster
+ finalHMBlogsEntryHeaderList.add(blogsEntryHeader);
+ finalHMBlogEntryInfosList.add(bei);
+ }
+ }
+ }
+ } // end loop over blogentryinfos
+ } // end loop over blogentries
+
+ // Sort news by descending date
+ OrderByComparator obc = new BlogsEntryHeaderDateComparator();
+ Collections.sort(finalBlogsEntryHeaderList, obc);
+ Collections.sort(finalHMBlogsEntryHeaderList, obc);
+
+ // Process sub-lists if needed
+ List<BlogsEntryHeader> allHMBlogsEntryList = new ArrayList<BlogsEntryHeader>();
+ allHMBlogsEntryList.addAll(finalHMBlogsEntryHeaderList);
+
+ long totalNewsGroup = finalBlogsEntryHeaderList.size();
+ long totalNewsHM = finalHMBlogsEntryHeaderList.size();
+
+ if (getNewsGroups) {
+ if (endLimit > finalBlogsEntryHeaderList.size()) {
+ finalBlogsEntryHeaderList = finalBlogsEntryHeaderList.subList(startLimit, finalBlogsEntryHeaderList.size());
+ } else {
+ finalBlogsEntryHeaderList = finalBlogsEntryHeaderList.subList(startLimit, endLimit);
+ }
+ }
+
+ if (getNewsHM) {
+ if (endLimit > finalHMBlogsEntryHeaderList.size()) {
+ finalHMBlogsEntryHeaderList = finalHMBlogsEntryHeaderList.subList(startLimit, finalHMBlogsEntryHeaderList.size());
+ } else {
+ finalHMBlogsEntryHeaderList = finalHMBlogsEntryHeaderList.subList(startLimit, endLimit);
+ }
+ }
+
+ Map<Long, JSONArray> mapBEItoJSONArraySchool = JSONProxy.getJSONGroupsForAllBEIId(user, themeDisplay, finalBlogEntryInfosList, finalHMBlogEntryInfosList);
+
+ boolean canEditOrg = isHeadMaster || isGrpAdmin;
+
+ // Now create returned Json objects
+ JSONArray actus = JSONFactoryUtil.createJSONArray();
+ JSONArray actusHeadMaster = JSONFactoryUtil.createJSONArray();
+ JSONArray actusHeadMasterHighPriorityToRead = JSONFactoryUtil.createJSONArray();
+
+ if (getNewsGroups) {
+ for (BlogsEntryHeader beh : finalBlogsEntryHeaderList) {
+ for (BlogEntryInfos bei : finalBlogEntryInfosList) {
+ if (beh.getEntryId() == bei.getBlogEntryId()) {
+ actus.put(
+ JSONProxy.getActuAsJson(beh, bei, user, isAdministrator, canEditOrg, themeDisplay, mapBEItoJSONArraySchool.get(bei.getBlogEntryGroup())));
+ }
+ }
+ }
+
+ } else {
+ totalNewsGroup = 0;
+ }
+
+ if (getNewsHM) {
+ for (BlogsEntryHeader beh : finalHMBlogsEntryHeaderList) {
+ for (BlogEntryInfos bei : finalHMBlogEntryInfosList) {
+ if (beh.getEntryId() == bei.getBlogEntryId()) {
+ actusHeadMaster.put(
+ JSONProxy.getActuAsJson(beh, bei, user, isAdministrator, canEditOrg, themeDisplay, mapBEItoJSONArraySchool.get(bei.getBlogEntryGroup())));
+ }
+ }
+ }
+ } else {
+ totalNewsHM = 0;
+ }
+
+ if (getNewsHighPriority) {
+ actusHeadMasterHighPriorityToRead = getHighPriorityNewsToRead(user, themeDisplay, finalHMBlogsEntryHeaderList,
+ finalHMBlogEntryInfosList, isAdministrator, mapBEItoJSONArraySchool, canEditOrg);
+ }
+
+ ret.put("totalNewsGroup", totalNewsGroup);
+ ret.put("totalNewsHM", totalNewsHM);
+ ret.put("newsGroup", actus);
+ ret.put("newsHM", actusHeadMaster);
+ ret.put("newsHighPriority", actusHeadMasterHighPriorityToRead);
+ return ret;
+ }
+
+ /**
+ *
+ * @param user
+ * @param themeDisplay
+ * @param finalBlogsEntryList
+ * @param finalBlogEntryInfosList
+ * @param isAdministrator
+ * @param mapBEItoJSONArraySchool
+ * @param canEditOrg
+ * @throws SystemException
+ * @throws PortalException
+ */
+ private static JSONArray getHighPriorityNewsToRead(User user, ThemeDisplay themeDisplay,
+ List<BlogsEntryHeader> finalBlogsEntryHeaderList, List<BlogEntryInfos> finalBlogEntryInfosList, Boolean isAdministrator,
+ Map<Long, JSONArray> mapBEItoJSONArraySchool, boolean canEditOrg) throws SystemException, PortalException {
+ JSONArray actusHeadMasterHighPriorityToRead = JSONFactoryUtil.createJSONArray();
+ Map<BlogsEntryHeader,BlogEntryInfos> mapHighPriorityBlogEntryWithBEI = new HashMap<BlogsEntryHeader, BlogEntryInfos>();
+
+ for (BlogsEntryHeader beh : finalBlogsEntryHeaderList) {
+ for (BlogEntryInfos bei : finalBlogEntryInfosList) {
+ if (beh.getEntryId() == bei.getBlogEntryId() && bei.getHighPriority()) {
+ mapHighPriorityBlogEntryWithBEI.put(beh, bei);
+ }
+ }
+ }
+
+ List<ConfirmReadBlogEntry> confirmRead = ConfirmReadBlogEntryLocalServiceUtil.getConfirmReadFromBlogEntryInfosList(
+ ListUtil.fromCollection(mapHighPriorityBlogEntryWithBEI.values()), user.getUserId());
+
+ Map<BlogsEntryHeader,BlogEntryInfos> mapHighPriorityNewsNToRead = new HashMap<BlogsEntryHeader, BlogEntryInfos>();
+
+ // get the non-read high prioirity news
+ for(Entry<BlogsEntryHeader,BlogEntryInfos> aBEHtoBEIEntry : mapHighPriorityBlogEntryWithBEI.entrySet()){
+ boolean hasBeenRead = false;
+ for(ConfirmReadBlogEntry aReadConfirmation : confirmRead){
+ if(aReadConfirmation.getBlogEntryInfosId() == aBEHtoBEIEntry.getValue().getBlogEntryInfosId() ||
+ user.getUserId() == aBEHtoBEIEntry.getKey().getUserId()){
+ hasBeenRead = true;
+ break;
+ }
+ }
+ if(!hasBeenRead){
+ mapHighPriorityNewsNToRead.put(aBEHtoBEIEntry.getKey(), aBEHtoBEIEntry.getValue());
+ }
+
+
+ }
+
+ for(Entry<BlogsEntryHeader,BlogEntryInfos> anEntryToRead : mapHighPriorityNewsNToRead.entrySet()){
+ actusHeadMasterHighPriorityToRead.put(
+ JSONProxy.getActuAsJson(
+ anEntryToRead.getKey(), anEntryToRead.getValue(), user,
+ isAdministrator, canEditOrg, themeDisplay,
+ mapBEItoJSONArraySchool.get(
+ anEntryToRead.getValue().getBlogEntryGroup())));
+ }
+ return actusHeadMasterHighPriorityToRead;
+ }
+
+ /**
+ * GEt the list of groups
+ * @param search
+ * @param user
+ * @return
+ * @throws SystemException
+ * @throws PortalException
+ */
+ public static JSONArray getBroadcastGroup(String search, User user) throws SystemException, PortalException{
+
+ Role adminRole = ENTRoleUtilFactory.getInstance(user.getCompanyId()).getRole(RoleConstants.ADMINISTRATOR);
+ Boolean isAdministrator = RoleLocalServiceUtil.hasUserRole(user.getUserId(), adminRole.getRoleId());
+
+ boolean hasOrgRoot = isAdministrator;
+
+ // Check if user is delegate for his etab
+ List<BlogEntryDelegate> listBed = BlogEntryDelegateLocalServiceUtil.getEtabUserDelegate(user.getUserId());
+ Boolean isDelegate = false;
+ if (!listBed.isEmpty()) {
+ isDelegate = true;
+ }
+
+ List<Long> diffusionGroupIds = new ArrayList<Long>();
+
+ // Students and parents may have access to personal groups where they are administrators => they have only the right to publish in these groups
+ // Other profiles have the right to publish in all groups they belong to
+ boolean isStudentOrParent = false;
+ try {
+ isStudentOrParent = ENTRolesConstants.isStudent(user) || ENTRolesConstants.isParent(user);
+ } catch (Exception e) {
+ }
+ if (isStudentOrParent) {
+ diffusionGroupIds = GroupCacheUtil.getUserPersonalAdminGroupIdsWithNews(user, search);
+ } else {
+ diffusionGroupIds = getGroupList(user, isDelegate, search);
+ }
+
+ List<Group> diffusionGroups = GroupFilter.getGroupsFromGroupIds(diffusionGroupIds);
+
+
+ // Add root org for administrators only
+ if (isAdministrator) {
+ diffusionGroups.add(getRootGroup(user.getCompanyId()));
+ }
+
+ return JSONProxy.getJSONBroadcastGroups(user, diffusionGroups, hasOrgRoot);
+ }
+
+ /**
+ * Returns the user's groups matching the given filter
+ */
+ private static List<Long> getGroupList(User user, boolean isDelegate, String filter) throws SystemException {
+
+ boolean isGrpAdmin = false;
+ try {
+ Role adminGrpRole = ENTRoleUtilFactory.getInstance(user.getCompanyId()).getRole(ENTRolesConstants.GROUP_ADMIN);
+ isGrpAdmin = RoleLocalServiceUtil.hasUserRole(user.getUserId(), adminGrpRole.getRoleId());
+ } catch (Exception e) {
+
+ }
+ List<Long> userGroupIds = new ArrayList<Long>();
+ // Delegate user has access to all groups of its school
+ if (isDelegate && !isGrpAdmin) {
+ userGroupIds = GroupCacheUtil.getUserGroupIdsWithNews(user, filter);
+
+ // TODO userGroupIds = getSchoolGroupsWithNewsEnabled(user);
+ List<Organization> allSchoolOrgs = OrganizationFilter.getAllUserSchoolOrganizations(user);
+ allSchoolOrgs.addAll(OrganizationFilter.getAllUserSchoolsIncludingSchoolComplex(user));
+ List<Organization> allNonArchivedSchoolOrgs = new ArrayList<Organization>();
+ for (Organization org : allSchoolOrgs) {
+ if (!OrganizationFilter.isArchived(org)) {
+ allNonArchivedSchoolOrgs.add(org);
+ }
+ }
+ List<Group> allSchoolGroups = GroupFilter.getGroupsFromOrganizations(allNonArchivedSchoolOrgs);
+ for (Group group : allSchoolGroups) {
+ if (!userGroupIds.contains(group.getGroupId())) {
+ userGroupIds.add(group.getGroupId());
+ }
+ }
+ } else {
+ userGroupIds = GroupCacheUtil.getUserGroupIdsWithNews(user, filter);
+ }
+
+ return userGroupIds;
+ }
+
+
+ /**
+ * Get the list of blog entries for a given list of group ids
+ *
+ * @param groupIdList
+ * @return
+ */
+ public static List<BlogEntryInfos> getBlogEntryInfosListForGroupIdList(List<Long> groupIdList, boolean isHighPrio) {
+
+ if (groupIdList == null || groupIdList.isEmpty()) {
+ return new ArrayList<BlogEntryInfos>();
+ }
+ ClassLoader classLoader = (ClassLoader)PortletBeanLocatorUtil.locate(ClpSerializer.getServletContextName(),"portletClassLoader");
+ DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(BlogEntryInfos.class, "bei", classLoader);
+ Criterion globalCriterion = null;
+
+ // Using 'in' is much faster than disjunctions
+ Long[] groupIds = new Long[groupIdList.size()];
+ int idx = 0;
+ for (Long groupId : groupIdList) {
+ groupIds[idx] = groupId;
+ idx++;
+ }
+ dynamicQuery.add(PropertyFactoryUtil.forName("groupId").in(groupIds));
+
+ // Filter on high priority blog entryinfos if needed
+ if (isHighPrio) {
+ globalCriterion = RestrictionsFactoryUtil.eq("bei.highPriority", true);
+ dynamicQuery.add(globalCriterion);
+ }
+
+ List<BlogEntryInfos> blogEntryInfosList = new ArrayList<BlogEntryInfos>();
+ try {
+ // Execute the query
+ List<BlogEntryInfos> objs = BlogEntryInfosLocalServiceUtil.dynamicQuery(dynamicQuery);
+ return objs;
+ } catch (Exception e) {
+ logger.error(e);
+ }
+
+ return blogEntryInfosList;
+ }
+
+
+
+ /**
+ * Get the list of blog entries for a given list of group ids
+ * @param groupIdList
+ * @return
+ */
+ public static List<BlogsEntry> getBlogsEntryListForGroupIdList(List<Long> groupIdList) {
+
+ if (groupIdList == null || groupIdList.isEmpty()) {
+ return new ArrayList<BlogsEntry>();
+ }
+
+ DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(BlogsEntry.class, "be", PortalClassLoaderUtil.getClassLoader());
+
+ // Using 'in' is much faster than disjunctions
+ Long[] groupIds = new Long[groupIdList.size()];
+ int idx = 0;
+ for (Long groupId : groupIdList) {
+ groupIds[idx] = groupId;
+ idx++;
+ }
+ dynamicQuery.add(PropertyFactoryUtil.forName("groupId").in(groupIds));
+
+ List<BlogsEntry> blogsEntryList = new ArrayList<BlogsEntry>();
+ try {
+ //Execute the query
+ List<BlogsEntry> objs = BlogsEntryLocalServiceUtil.dynamicQuery(dynamicQuery);
+ return objs;
+ } catch (Exception e) {
+ logger.error(e);
+ }
+ return blogsEntryList;
+ }
+
+ private static Group getRootGroup(long companyId) {
+ try {
+ Organization rootOrg = ENTOrganizationsUtil.getOrCreateRootOrg(companyId);
+ Group rootGroup = GroupLocalServiceUtil.getOrganizationGroup(companyId, rootOrg.getOrganizationId());
+ return rootGroup;
+ } catch (Exception e) {
+ logger.error("Error while fetching root group", e);
+ }
+ return null;
+ }
+
+}