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.plugins.repository.data.ametysobject.ModelLessDataAwareAmetysObject; 032import org.ametys.runtime.i18n.I18nizableText; 033import org.ametys.runtime.i18n.I18nizableTextParameter; 034import org.ametys.web.ObservationConstants; 035import org.ametys.web.repository.page.LockablePage; 036import org.ametys.web.repository.page.ModifiablePage; 037import org.ametys.web.repository.page.Page; 038import org.ametys.web.repository.page.SitemapElement; 039import org.ametys.web.repository.page.jcr.AbstractSitemapElement; 040import org.ametys.web.repository.page.jcr.DefaultPage; 041import org.ametys.web.repository.sitemap.Sitemap; 042 043/** 044 * This {@link ClientSideElement} creates a button representing the SEO properties of a page 045 */ 046public class PageRobotsClientSideElement extends AbstractSitemapElementClientSideElement 047{ 048 private ObservationManager _observationManager; 049 050 @Override 051 public void service(ServiceManager smanager) throws ServiceException 052 { 053 super.service(smanager); 054 _observationManager = (ObservationManager) smanager.lookup(ObservationManager.ROLE); 055 } 056 057 /** 058 * Allow/Disallow the robots on a page or sitemap 059 * @param pageIds the selected pages or sitemap 060 * @param exclude true to disallow the robots on the selected pages, false otherwise 061 * @return the results with successful pages and pages with failure 062 */ 063 @Callable (rights = Callable.SKIP_BUILTIN_CHECK) 064 public Map<String, Object> editRobots (List<String> pageIds, boolean exclude) 065 { 066 List<String> allRightIds = new ArrayList<>(); 067 List<Map<String, Object>> noRightPages = new ArrayList<>(); 068 List<Map<String, Object>> lockedPages = new ArrayList<>(); 069 070 for (String id : pageIds) 071 { 072 AbstractSitemapElement sitemapElmt = _resolver.resolveById(id); 073 074 if (!hasRight(sitemapElmt)) 075 { 076 noRightPages.add(Map.of("id", id, "title", sitemapElmt.getTitle())); 077 } 078 if (sitemapElmt instanceof LockablePage lockablePage && lockablePage.isLocked()) 079 { 080 noRightPages.add(Map.of("id", id, "title", sitemapElmt.getTitle())); 081 } 082 else 083 { 084 sitemapElmt.setValue(DefaultPage.METADATA_ROBOTS_DISALLOW, exclude); 085 sitemapElmt.saveChanges(); 086 allRightIds.add(id); 087 088 Map<String, Object> eventParams = new HashMap<>(); 089 eventParams.put(sitemapElmt instanceof Sitemap ? ObservationConstants.ARGS_SITEMAP : ObservationConstants.ARGS_SITEMAP_ELEMENT, sitemapElmt); 090 _observationManager.notify(new Event(ObservationConstants.EVENT_ROBOTS_CHANGED, _currentUserProvider.getUser(), eventParams)); 091 } 092 } 093 094 return Map.of("allright-pages", allRightIds, "noright-pages", noRightPages, "locked-pages", lockedPages); 095 } 096 097 /** 098 * Get the robots status of given pages or sitemap 099 * @param pageIds The page ids or sitemap id 100 * @return the result 101 */ 102 @Callable (rights = Callable.SKIP_BUILTIN_CHECK) 103 public Map<String, Object> getStatus (List<String> pageIds) 104 { 105 Map<String, Object> results = new HashMap<>(); 106 107 results.put("nomodifiable-pages", new ArrayList<>()); 108 results.put("noright-pages", new ArrayList<>()); 109 results.put("included-pages", new ArrayList<>()); 110 results.put("excluded-pages", new ArrayList<>()); 111 results.put("parent-excluded-pages", new ArrayList<>()); 112 113 for (String pageId : pageIds) 114 { 115 SitemapElement pageOrSitemap = _resolver.resolveById(pageId); 116 117 Map<String, Object> pageParams = getSitemapElementDefaultParameters(pageOrSitemap); 118 119 if (pageOrSitemap instanceof Page && !(pageOrSitemap instanceof ModifiablePage)) 120 { 121 pageParams.put("description", getNoModifiablePageDescription((Page) pageOrSitemap)); 122 123 @SuppressWarnings("unchecked") 124 List<Map<String, Object>> nomodifiablePages = (List<Map<String, Object>>) results.get("nomodifiable-pages"); 125 nomodifiablePages.add(pageParams); 126 } 127 else if (!hasRight(pageOrSitemap)) 128 { 129 pageParams.put("description", getNoRightSitemapElementDescription(pageOrSitemap)); 130 131 @SuppressWarnings("unchecked") 132 List<Map<String, Object>> norightPages = (List<Map<String, Object>>) results.get("noright-pages"); 133 norightPages.add(pageParams); 134 } 135 else 136 { 137 if (_isExcludedFromSEO((ModelLessDataAwareAmetysObject) pageOrSitemap)) 138 { 139 pageParams.put("description", _getExcludedDescription(pageOrSitemap)); 140 141 @SuppressWarnings("unchecked") 142 List<Map<String, Object>> excludedPages = (List<Map<String, Object>>) results.get("excluded-pages"); 143 excludedPages.add(pageParams); 144 } 145 else if (_isParentExcludedFromSEO(pageOrSitemap)) 146 { 147 pageParams.put("description", _getParentExcludedDescription(pageOrSitemap)); 148 149 @SuppressWarnings("unchecked") 150 List<Map<String, Object>> excludedPages = (List<Map<String, Object>>) results.get("parent-excluded-pages"); 151 excludedPages.add(pageParams); 152 } 153 else 154 { 155 pageParams.put("description", _getIncludedDescription(pageOrSitemap)); 156 157 @SuppressWarnings("unchecked") 158 List<Map<String, Object>> includedPages = (List<Map<String, Object>>) results.get("included-pages"); 159 includedPages.add(pageParams); 160 161 } 162 } 163 } 164 165 return results; 166 } 167 168 private I18nizableText _getExcludedDescription (SitemapElement pageOrSitemap) 169 { 170 if (pageOrSitemap instanceof Page) 171 { 172 List<String> i18nParameters = new ArrayList<>(); 173 i18nParameters.add(pageOrSitemap.getTitle()); 174 175 I18nizableText ed = (I18nizableText) this._script.getParameters().get("page-excluded-description"); 176 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 177 } 178 else 179 { 180 Map<String, I18nizableTextParameter> i18nParameters = new HashMap<>(); 181 i18nParameters.put("title", getSitemapTitle((Sitemap) pageOrSitemap)); 182 i18nParameters.put("name", new I18nizableText(pageOrSitemap.getSitemapName())); 183 184 I18nizableText ed = (I18nizableText) this._script.getParameters().get("sitemap-excluded-description"); 185 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 186 } 187 } 188 189 private I18nizableText _getParentExcludedDescription (SitemapElement pageOrSitemap) 190 { 191 return _getExcludedDescription(pageOrSitemap); 192 } 193 194 private I18nizableText _getIncludedDescription (SitemapElement pageOrSitemap) 195 { 196 if (pageOrSitemap instanceof Page) 197 { 198 List<String> i18nParameters = new ArrayList<>(); 199 i18nParameters.add(pageOrSitemap.getTitle()); 200 201 I18nizableText ed = (I18nizableText) this._script.getParameters().get("page-included-description"); 202 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 203 } 204 else 205 { 206 Map<String, I18nizableTextParameter> i18nParameters = new HashMap<>(); 207 i18nParameters.put("title", getSitemapTitle((Sitemap) pageOrSitemap)); 208 i18nParameters.put("name", new I18nizableText(pageOrSitemap.getSitemapName())); 209 210 I18nizableText ed = (I18nizableText) this._script.getParameters().get("sitemap-included-description"); 211 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 212 } 213 } 214 215 private boolean _isExcludedFromSEO (ModelLessDataAwareAmetysObject pageOrSitemap) 216 { 217 return pageOrSitemap.getValue(DefaultPage.METADATA_ROBOTS_DISALLOW, false); 218 } 219 220 private boolean _isParentExcludedFromSEO (SitemapElement pageOrSitemap) 221 { 222 AmetysObject parent = pageOrSitemap.getParent(); 223 while (parent != null && parent instanceof SitemapElement) 224 { 225 boolean excluded = _isExcludedFromSEO((ModelLessDataAwareAmetysObject) parent); 226 if (excluded) 227 { 228 return true; 229 } 230 231 parent = parent.getParent(); 232 } 233 234 return false; 235 } 236}