001/* 002 * Copyright 2010 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.web.clientsideelement; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025 026import org.ametys.core.observation.Event; 027import org.ametys.core.observation.ObservationManager; 028import org.ametys.core.ui.Callable; 029import org.ametys.core.ui.ClientSideElement; 030import org.ametys.plugins.repository.AmetysObject; 031import org.ametys.runtime.i18n.I18nizableText; 032import org.ametys.runtime.i18n.I18nizableTextParameter; 033import org.ametys.web.ObservationConstants; 034import org.ametys.web.repository.page.LockablePage; 035import org.ametys.web.repository.page.ModifiablePage; 036import org.ametys.web.repository.page.Page; 037import org.ametys.web.repository.page.SitemapElement; 038import org.ametys.web.repository.page.jcr.AbstractSitemapElement; 039import org.ametys.web.repository.page.jcr.DefaultPage; 040import org.ametys.web.repository.sitemap.Sitemap; 041 042/** 043 * This {@link ClientSideElement} creates a button representing the SEO properties of a page 044 */ 045public class PageRobotsClientSideElement extends AbstractSitemapElementClientSideElement 046{ 047 private ObservationManager _observationManager; 048 049 @Override 050 public void service(ServiceManager smanager) throws ServiceException 051 { 052 super.service(smanager); 053 _observationManager = (ObservationManager) smanager.lookup(ObservationManager.ROLE); 054 } 055 056 /** 057 * Allow/Disallow the robots on a page or sitemap 058 * @param pageIds the selected pages or sitemap 059 * @param exclude true to disallow the robots on the selected pages, false otherwise 060 * @return the results with successful pages and pages with failure 061 */ 062 @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION) 063 public Map<String, Object> editRobots (List<String> pageIds, boolean exclude) 064 { 065 List<String> allRightIds = new ArrayList<>(); 066 List<Map<String, Object>> noRightPages = new ArrayList<>(); 067 List<Map<String, Object>> lockedPages = new ArrayList<>(); 068 069 for (String id : pageIds) 070 { 071 AbstractSitemapElement sitemapElmt = _resolver.resolveById(id); 072 073 if (!hasRight(sitemapElmt)) 074 { 075 noRightPages.add(Map.of("id", id, "title", sitemapElmt.getTitle())); 076 } 077 if (sitemapElmt instanceof LockablePage lockablePage && lockablePage.isLocked()) 078 { 079 noRightPages.add(Map.of("id", id, "title", sitemapElmt.getTitle())); 080 } 081 else 082 { 083 sitemapElmt.setValue(DefaultPage.METADATA_ROBOTS_DISALLOW, exclude); 084 sitemapElmt.saveChanges(); 085 allRightIds.add(id); 086 087 Map<String, Object> eventParams = new HashMap<>(); 088 eventParams.put(sitemapElmt instanceof Sitemap ? ObservationConstants.ARGS_SITEMAP : ObservationConstants.ARGS_SITEMAP_ELEMENT, sitemapElmt); 089 _observationManager.notify(new Event(ObservationConstants.EVENT_ROBOTS_CHANGED, _currentUserProvider.getUser(), eventParams)); 090 } 091 } 092 093 return Map.of("allright-pages", allRightIds, "noright-pages", noRightPages, "locked-pages", lockedPages); 094 } 095 096 /** 097 * Get the robots status of given pages or sitemap 098 * @param pageIds The page ids or sitemap id 099 * @return the result 100 */ 101 @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION) 102 public Map<String, Object> getStatus (List<String> pageIds) 103 { 104 Map<String, Object> results = new HashMap<>(); 105 106 results.put("nomodifiable-pages", new ArrayList<>()); 107 results.put("noright-pages", new ArrayList<>()); 108 results.put("included-pages", new ArrayList<>()); 109 results.put("excluded-pages", new ArrayList<>()); 110 results.put("parent-excluded-pages", new ArrayList<>()); 111 112 for (String pageId : pageIds) 113 { 114 SitemapElement pageOrSitemap = _resolver.resolveById(pageId); 115 116 Map<String, Object> pageParams = getSitemapElementDefaultParameters(pageOrSitemap); 117 118 if (pageOrSitemap instanceof Page && !(pageOrSitemap instanceof ModifiablePage)) 119 { 120 pageParams.put("description", getNoModifiablePageDescription((Page) pageOrSitemap)); 121 122 @SuppressWarnings("unchecked") 123 List<Map<String, Object>> nomodifiablePages = (List<Map<String, Object>>) results.get("nomodifiable-pages"); 124 nomodifiablePages.add(pageParams); 125 } 126 else if (!hasRight(pageOrSitemap)) 127 { 128 pageParams.put("description", getNoRightSitemapElementDescription(pageOrSitemap)); 129 130 @SuppressWarnings("unchecked") 131 List<Map<String, Object>> norightPages = (List<Map<String, Object>>) results.get("noright-pages"); 132 norightPages.add(pageParams); 133 } 134 else 135 { 136 if (_isExcludedFromSEO(pageOrSitemap)) 137 { 138 pageParams.put("description", _getExcludedDescription(pageOrSitemap)); 139 140 @SuppressWarnings("unchecked") 141 List<Map<String, Object>> excludedPages = (List<Map<String, Object>>) results.get("excluded-pages"); 142 excludedPages.add(pageParams); 143 } 144 else if (_isParentExcludedFromSEO(pageOrSitemap)) 145 { 146 pageParams.put("description", _getParentExcludedDescription(pageOrSitemap)); 147 148 @SuppressWarnings("unchecked") 149 List<Map<String, Object>> excludedPages = (List<Map<String, Object>>) results.get("parent-excluded-pages"); 150 excludedPages.add(pageParams); 151 } 152 else 153 { 154 pageParams.put("description", _getIncludedDescription(pageOrSitemap)); 155 156 @SuppressWarnings("unchecked") 157 List<Map<String, Object>> includedPages = (List<Map<String, Object>>) results.get("included-pages"); 158 includedPages.add(pageParams); 159 160 } 161 } 162 } 163 164 return results; 165 } 166 167 private I18nizableText _getExcludedDescription (SitemapElement pageOrSitemap) 168 { 169 if (pageOrSitemap instanceof Page) 170 { 171 List<String> i18nParameters = new ArrayList<>(); 172 i18nParameters.add(pageOrSitemap.getTitle()); 173 174 I18nizableText ed = (I18nizableText) this._script.getParameters().get("page-excluded-description"); 175 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 176 } 177 else 178 { 179 Map<String, I18nizableTextParameter> i18nParameters = new HashMap<>(); 180 i18nParameters.put("title", getSitemapTitle((Sitemap) pageOrSitemap)); 181 i18nParameters.put("name", new I18nizableText(pageOrSitemap.getSitemapName())); 182 183 I18nizableText ed = (I18nizableText) this._script.getParameters().get("sitemap-excluded-description"); 184 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 185 } 186 } 187 188 private I18nizableText _getParentExcludedDescription (SitemapElement pageOrSitemap) 189 { 190 return _getExcludedDescription(pageOrSitemap); 191 } 192 193 private I18nizableText _getIncludedDescription (SitemapElement pageOrSitemap) 194 { 195 if (pageOrSitemap instanceof Page) 196 { 197 List<String> i18nParameters = new ArrayList<>(); 198 i18nParameters.add(pageOrSitemap.getTitle()); 199 200 I18nizableText ed = (I18nizableText) this._script.getParameters().get("page-included-description"); 201 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 202 } 203 else 204 { 205 Map<String, I18nizableTextParameter> i18nParameters = new HashMap<>(); 206 i18nParameters.put("title", getSitemapTitle((Sitemap) pageOrSitemap)); 207 i18nParameters.put("name", new I18nizableText(pageOrSitemap.getSitemapName())); 208 209 I18nizableText ed = (I18nizableText) this._script.getParameters().get("sitemap-included-description"); 210 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 211 } 212 } 213 214 private boolean _isExcludedFromSEO (SitemapElement pageOrSitemap) 215 { 216 return pageOrSitemap.getValueOrDefault(DefaultPage.METADATA_ROBOTS_DISALLOW, false); 217 } 218 219 private boolean _isParentExcludedFromSEO (SitemapElement pageOrSitemap) 220 { 221 AmetysObject parent = pageOrSitemap.getParent(); 222 while (parent != null && parent instanceof SitemapElement sitemapElementParent) 223 { 224 boolean excluded = _isExcludedFromSEO(sitemapElementParent); 225 if (excluded) 226 { 227 return true; 228 } 229 230 parent = parent.getParent(); 231 } 232 233 return false; 234 } 235}