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.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.SKIP_BUILTIN_CHECK) 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 068 for (String id : pageIds) 069 { 070 AbstractSitemapElement sitemapElmt = _resolver.resolveById(id); 071 072 if (!hasRight(sitemapElmt)) 073 { 074 noRightPages.add(Map.of("id", id, "title", sitemapElmt.getTitle())); 075 } 076 else 077 { 078 sitemapElmt.setValue(DefaultPage.METADATA_ROBOTS_DISALLOW, exclude); 079 sitemapElmt.saveChanges(); 080 allRightIds.add(id); 081 082 Map<String, Object> eventParams = new HashMap<>(); 083 eventParams.put(sitemapElmt instanceof Sitemap ? ObservationConstants.ARGS_SITEMAP : ObservationConstants.ARGS_SITEMAP_ELEMENT, sitemapElmt); 084 _observationManager.notify(new Event(ObservationConstants.EVENT_ROBOTS_CHANGED, _currentUserProvider.getUser(), eventParams)); 085 } 086 } 087 088 return Map.of("allright-pages", allRightIds, "noright-pages", noRightPages); 089 } 090 091 /** 092 * Get the robots status of given pages or sitemap 093 * @param pageIds The page ids or sitemap id 094 * @return the result 095 */ 096 @Callable (rights = Callable.SKIP_BUILTIN_CHECK) 097 public Map<String, Object> getStatus (List<String> pageIds) 098 { 099 Map<String, Object> results = new HashMap<>(); 100 101 results.put("nomodifiable-pages", new ArrayList<>()); 102 results.put("noright-pages", new ArrayList<>()); 103 results.put("included-pages", new ArrayList<>()); 104 results.put("excluded-pages", new ArrayList<>()); 105 results.put("parent-excluded-pages", new ArrayList<>()); 106 107 for (String pageId : pageIds) 108 { 109 SitemapElement pageOrSitemap = _resolver.resolveById(pageId); 110 111 Map<String, Object> pageParams = getSitemapElementDefaultParameters(pageOrSitemap); 112 113 if (pageOrSitemap instanceof Page && !(pageOrSitemap instanceof ModifiablePage)) 114 { 115 pageParams.put("description", getNoModifiablePageDescription((Page) pageOrSitemap)); 116 117 @SuppressWarnings("unchecked") 118 List<Map<String, Object>> nomodifiablePages = (List<Map<String, Object>>) results.get("nomodifiable-pages"); 119 nomodifiablePages.add(pageParams); 120 } 121 else if (!hasRight(pageOrSitemap)) 122 { 123 pageParams.put("description", getNoRightSitemapElementDescription(pageOrSitemap)); 124 125 @SuppressWarnings("unchecked") 126 List<Map<String, Object>> norightPages = (List<Map<String, Object>>) results.get("noright-pages"); 127 norightPages.add(pageParams); 128 } 129 else 130 { 131 if (_isExcludedFromSEO((ModelLessDataAwareAmetysObject) pageOrSitemap)) 132 { 133 pageParams.put("description", _getExcludedDescription(pageOrSitemap)); 134 135 @SuppressWarnings("unchecked") 136 List<Map<String, Object>> excludedPages = (List<Map<String, Object>>) results.get("excluded-pages"); 137 excludedPages.add(pageParams); 138 } 139 else if (_isParentExcludedFromSEO(pageOrSitemap)) 140 { 141 pageParams.put("description", _getParentExcludedDescription(pageOrSitemap)); 142 143 @SuppressWarnings("unchecked") 144 List<Map<String, Object>> excludedPages = (List<Map<String, Object>>) results.get("parent-excluded-pages"); 145 excludedPages.add(pageParams); 146 } 147 else 148 { 149 pageParams.put("description", _getIncludedDescription(pageOrSitemap)); 150 151 @SuppressWarnings("unchecked") 152 List<Map<String, Object>> includedPages = (List<Map<String, Object>>) results.get("included-pages"); 153 includedPages.add(pageParams); 154 155 } 156 } 157 } 158 159 return results; 160 } 161 162 private I18nizableText _getExcludedDescription (SitemapElement pageOrSitemap) 163 { 164 if (pageOrSitemap instanceof Page) 165 { 166 List<String> i18nParameters = new ArrayList<>(); 167 i18nParameters.add(((Page) pageOrSitemap).getTitle()); 168 169 I18nizableText ed = (I18nizableText) this._script.getParameters().get("page-excluded-description"); 170 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 171 } 172 else 173 { 174 Map<String, I18nizableTextParameter> i18nParameters = new HashMap<>(); 175 i18nParameters.put("title", getSitemapTitle((Sitemap) pageOrSitemap)); 176 i18nParameters.put("name", new I18nizableText(pageOrSitemap.getSitemapName())); 177 178 I18nizableText ed = (I18nizableText) this._script.getParameters().get("sitemap-excluded-description"); 179 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 180 } 181 } 182 183 private I18nizableText _getParentExcludedDescription (SitemapElement pageOrSitemap) 184 { 185 return _getExcludedDescription(pageOrSitemap); 186 } 187 188 private I18nizableText _getIncludedDescription (SitemapElement pageOrSitemap) 189 { 190 if (pageOrSitemap instanceof Page) 191 { 192 List<String> i18nParameters = new ArrayList<>(); 193 i18nParameters.add(((Page) pageOrSitemap).getTitle()); 194 195 I18nizableText ed = (I18nizableText) this._script.getParameters().get("page-included-description"); 196 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 197 } 198 else 199 { 200 Map<String, I18nizableTextParameter> i18nParameters = new HashMap<>(); 201 i18nParameters.put("title", getSitemapTitle((Sitemap) pageOrSitemap)); 202 i18nParameters.put("name", new I18nizableText(pageOrSitemap.getSitemapName())); 203 204 I18nizableText ed = (I18nizableText) this._script.getParameters().get("sitemap-included-description"); 205 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 206 } 207 } 208 209 private boolean _isExcludedFromSEO (ModelLessDataAwareAmetysObject pageOrSitemap) 210 { 211 return pageOrSitemap.getValue(DefaultPage.METADATA_ROBOTS_DISALLOW, false); 212 } 213 214 private boolean _isParentExcludedFromSEO (SitemapElement pageOrSitemap) 215 { 216 AmetysObject parent = pageOrSitemap.getParent(); 217 while (parent != null && parent instanceof SitemapElement) 218 { 219 boolean excluded = _isExcludedFromSEO((ModelLessDataAwareAmetysObject) parent); 220 if (excluded) 221 { 222 return true; 223 } 224 225 parent = parent.getParent(); 226 } 227 228 return false; 229 } 230}