Index: content/content-impl/impl/src/java/org/sakaiproject/content/impl/BaseContentService.java =================================================================== --- content/content-impl/impl/src/java/org/sakaiproject/content/impl/BaseContentService.java (revision 14) +++ content/content-impl/impl/src/java/org/sakaiproject/content/impl/BaseContentService.java (revision 15) @@ -6628,7 +6628,15 @@ try { // get the root collection - ContentCollection oCollection = getCollection(fromContext); + ContentCollection oCollection; + if (fromContext.startsWith("/group/template")) { + // if the original site is a template (i.e. site with id + // starts with "template"), bypass the security permission checking + oCollection = findCollection(fromContext); + if (oCollection == null) throw new IdUnusedException(fromContext); + } else { + oCollection = getCollection(fromContext); + } // Get the collection members from the 'new' collection List oResources = oCollection.getMemberResources(); @@ -11156,3 +11164,4 @@ } // BaseContentService + Index: site-manage/site-manage-tool/tool/src/java/org/sakaiproject/site/tool/SiteAction.java =================================================================== --- site-manage/site-manage-tool/tool/src/java/org/sakaiproject/site/tool/SiteAction.java (revision 14) +++ site-manage/site-manage-tool/tool/src/java/org/sakaiproject/site/tool/SiteAction.java (revision 15) @@ -409,6 +409,9 @@ /** State attribute for state initialization. */ private static final String STATE_INITIALIZED = "site.initialized"; + + /** State attribute for state initialization. */ + private static final String STATE_TEMPLATE_SITE = "site.templateSite"; /** The action for menu */ private static final String STATE_ACTION = "site.action"; @@ -752,6 +755,9 @@ state.removeAttribute(FORM_ADDITIONAL); // don't we need to clena this // too? -daisyf + + state.removeAttribute(STATE_TEMPLATE_SITE); + } // cleanState /** @@ -1092,6 +1098,9 @@ setTermListForContext(context, state, true); // true => only // upcoming terms setSelectedTermForContext(context, state, STATE_TERM_SELECTED); + + // template site - Denny + setTemplateListForContext(context, state); return (String) getContext(data).get("template") + TEMPLATE[1]; case 2: @@ -2128,7 +2137,13 @@ // new site, go to confirmation page context.put("continue", "10"); - if (fromENWModifyView(state)) { + + Site templateSite = (Site) state.getAttribute(STATE_TEMPLATE_SITE); + + // if create based on template, back to 2 + if (templateSite != null) { + context.put("back", "2"); + } else if (fromENWModifyView(state)) { context.put("back", "26"); } else if (state.getAttribute(STATE_IMPORT) != null) { context.put("back", "27"); @@ -3718,6 +3733,9 @@ List siteTypes = (List) state.getAttribute(STATE_SITE_TYPES); if (siteTypes != null) { + // we don't want to skip the site type selection page + // as it contains template selection menu. + /* if (siteTypes.size() == 1) { String siteType = (String) siteTypes.get(0); if (!siteType.equals(ServerConfigurationService.getString( @@ -3731,8 +3749,9 @@ state.setAttribute(STATE_TEMPLATE_INDEX, "1"); } } else { + */ state.setAttribute(STATE_TEMPLATE_INDEX, "1"); - } + //} } } // doNew_site @@ -4009,9 +4028,9 @@ if (type == null) { addAlert(state, rb.getString("java.select") + " "); } else { - setNewSiteType(state, type); if (type.equalsIgnoreCase("course")) { + setNewSiteType(state, type); User user = UserDirectoryService.getCurrentUser(); String currentUserId = user.getEid(); @@ -4058,9 +4077,12 @@ totalSteps = 5; } } else if (type.equals("project")) { + setNewSiteType(state, type); totalSteps = 4; + state.setAttribute(STATE_TEMPLATE_INDEX, "2"); } else if (type.equals(SITE_TYPE_GRADTOOLS_STUDENT)) { + setNewSiteType(state, type); // if a GradTools site use pre-defined site info and exclude // from public listing SiteInfo siteInfo = new SiteInfo(); @@ -4079,7 +4101,41 @@ // skip directly to confirm creation of site state.setAttribute(STATE_TEMPLATE_INDEX, "42"); + } else if (type.equals("template")) { + String templateSiteId = params.getString("selectTemplate"); + Site templateSite = null; + try { + templateSite = SiteService.getSite(templateSiteId); + // save the template site in state + state.setAttribute(STATE_TEMPLATE_SITE, templateSite); + + // the new site type is based on the template site + //System.err.println (templateSite.getType()); + setNewSiteType(state, templateSite.getType()); + } + catch (Exception e) { + // should never happened, as the list of templates are generated + // from existing sites + System.err.println (e.getClass().getName() + " : " + e.getMessage()); + } + + // grab site info from template + SiteInfo siteInfo = new SiteInfo(); + if (state.getAttribute(STATE_SITE_INFO) != null) { + siteInfo = (SiteInfo) state.getAttribute(STATE_SITE_INFO); + } + + // default site information. copied from the template site + siteInfo.description = templateSite.getShortDescription(); + siteInfo.short_description = templateSite.getDescription(); + //siteInfo.iconUrl = templateSite.getIconUrl(); + //siteInfo.include = false; + state.setAttribute(STATE_SITE_INFO, siteInfo); + + totalSteps = 3; + state.setAttribute(STATE_TEMPLATE_INDEX, "2"); } else { + setNewSiteType(state, type); state.setAttribute(STATE_TEMPLATE_INDEX, "2"); } } @@ -4564,6 +4620,12 @@ if (option.equalsIgnoreCase("continue")) { doContinue(data); + + // if create based on template, skip the feature selection + Site templateSite = (Site) state.getAttribute(STATE_TEMPLATE_SITE); + if (templateSite != null) { + state.setAttribute(STATE_TEMPLATE_INDEX, "18"); + } } else if (option.equalsIgnoreCase("back")) { doBack(data); } else if (option.equalsIgnoreCase("cancel")) { @@ -4918,7 +4980,11 @@ addNewSite(params, state); - addFeatures(state); + // if create based on template, skip add features + Site templateSite = (Site) state.getAttribute(STATE_TEMPLATE_SITE); + if (templateSite == null) { + addFeatures(state); + } Site site = getStateSite(state); @@ -6958,6 +7024,9 @@ state.setAttribute(STATE_TEMPLATE_INDEX, "2"); return; } + } else { + // removing previously selected template site + state.removeAttribute(STATE_TEMPLATE_SITE); } updateSiteAttributes(state); @@ -9283,7 +9352,7 @@ } } - // ijmport other tools then + // import other tools then for (int i = 0; i < toolIds.size(); i++) { String toolId = (String) toolIds.get(i); if (!toolId.equalsIgnoreCase("sakai.resources") @@ -9965,7 +10034,17 @@ state.setAttribute(STATE_SITE_INFO, siteInfo); if (state.getAttribute(STATE_MESSAGE) == null) { try { - Site site = SiteService.addSite(id, siteInfo.site_type); + Site site = null; + // add current user as the maintainer + User currentUser = UserDirectoryService.getCurrentUser(); + + // if create based on template, + Site templateSite = (Site) state.getAttribute(STATE_TEMPLATE_SITE); + if (templateSite != null) { + site = SiteService.addSite(id, templateSite); + } else { + site = SiteService.addSite(id, siteInfo.site_type); + } String title = StringUtil.trimToNull(siteInfo.title); String description = siteInfo.description; @@ -9993,7 +10072,52 @@ // commit newly added site in order to enable related realm commitSite(site); + + // transfer site content from template site + if (templateSite != null) { + transferSiteContent (site, templateSite); + + // send an email to track who are using the template + String from = getSetupRequestEmailAddress(); + // send it to the email archive of the template site + // TODO: need a better way to get the email archive address + //String domain = from.substring(from.indexOf('@')); + String templateEmailArchive = templateSite.getId() + + "@" + ServerConfigurationService.getServerName(); + String to = templateEmailArchive; + String headerTo = templateEmailArchive; + String replyTo = templateEmailArchive; + String message_subject = templateSite.getId() + ": copied by " + currentUser.getDisplayId (); + + if (from != null && templateEmailArchive != null) { + StringBuffer buf = new StringBuffer(); + buf.setLength(0); + + // email body + buf.append("Dear template maintainer,\n\n"); + buf.append("Congratulations!\n\n"); + buf.append("The following user just created a new site based on your template.\n\n"); + buf.append("Template name: " + templateSite.getTitle() + "\n"); + buf.append("User : " + currentUser.getDisplayName() + " (" + + currentUser.getDisplayId () + ")\n"); + buf.append("Date : " + new java.util.Date() + "\n"); + buf.append("New site Id : " + site.getId() + "\n"); + buf.append("New site name: " + site.getTitle() + "\n\n"); + buf.append("Cheers,\n"); + buf.append("Alliance Team\n"); + + String content = buf.toString(); + + // to = "alliance@wicaksana.org"; + + EmailService.send(from, to, message_subject, content, headerTo, + replyTo, null); + } + } + + commitSite (site); + } catch (IdUsedException e) { addAlert(state, rb.getString("java.sitewithid") + " " + id + " " + rb.getString("java.exists")); @@ -10016,6 +10140,72 @@ } } // addNewSite + + private void transferSiteContent(Site toSite, Site fromSite) + throws IdInvalidException, IdUsedException, PermissionException { + String id = toSite.getId (); + String templateSiteId = fromSite.getId(); + +// // do copy template using archiving method +// org.sakaiproject.archive.api.ArchiveService archiveService = +// (org.sakaiproject.archive.api.ArchiveService) ComponentManager.get( +// "org.sakaiproject.archive.api.ArchiveService"); +// archiveService.archive (templateSiteId); +// archiveService.merge (templateSiteId + "-archive", id, null); + + // a direct transfer if the tool support entity transfer + String templateSiteCollectionId = + ContentHostingService.getSiteCollection(templateSiteId); + String toSiteCollectionId = + ContentHostingService.getSiteCollection(id); + + // get a list of tools that support tranfer copy + Set importCapableTools = importTools (); +// System.out.println ("Transfer supported tools: " +// + Arrays.toString (importCapableTools.toArray())); + + // get tools used in the template site + Set templateTools = new HashSet (); + List pageList = fromSite.getPages(); + if ((pageList != null) && ! pageList.isEmpty()) { + for (Object objPage : pageList) { + SitePage page = (SitePage) objPage; + List pageToolList = page.getTools(); + + if (pageToolList != null) { + for (Object objToolConf : pageToolList) { + if (objToolConf != null) { + ToolConfiguration toolConf = (ToolConfiguration) objToolConf; + templateTools.add((toolConf.getTool().getId())); + } + } + } + } + } + +// System.out.println ("Template tools: " + +// Arrays.toString (templateTools.toArray())); + + // transfer resources first. is this necessary? + if (templateTools.contains("sakai.resources")) { + transferCopyEntities("sakai.resources", templateSiteCollectionId, + toSiteCollectionId); + templateTools.remove("sakai.resources"); + } + + // commit changes, it might be needed? + commitSite (toSite); + + for (Object objToolId : templateTools) { + String toolId = (String) objToolId; + // System.out.println ("Transferring " + toolId); + + // transfer copy if the tool support EntityTransfer + transferCopyEntities(toolId, templateSiteId, + id); + } + } + /** * %%% legacy properties, to be cleaned up * @@ -11642,6 +11832,8 @@ // if this producer claims this tool id if (ArrayUtil.contains(et.myToolIds(), toolId)) { +// System.out.println ("Transfer " + toolId + " from " + fromContext + " to " + toContext); +// System.out.println (et); et.transferCopyEntities(fromContext, toContext, new Vector()); } @@ -11728,6 +11920,32 @@ } } // setTermListForContext + + // created based on setTermListForContext - Denny + private void setTemplateListForContext(Context context, SessionState state) + { + // find all template sites. + List templateSites = SiteService.getSites( + org.sakaiproject.site.api.SiteService.SelectionType.ANY, + null, null, null, + org.sakaiproject.site.api.SiteService.SortType.TITLE_ASC, null); + + for (Iterator itr = templateSites.iterator(); itr.hasNext(); ) { + Site site = (Site) itr.next(); + // convention: template site should use site id "template*" + // so, only administrator can create a site with a custom site id + if (!site.getId().startsWith("template")) { + // remove non-template sites + itr.remove(); + } else if (!site.isPublished()) { + // remove unpublished template + itr.remove(); + } + } + + context.put("templateList", templateSites); + } // setTemplateListForContext + private void setSelectedTermForContext(Context context, SessionState state, String stateAttribute) { if (state.getAttribute(stateAttribute) != null) { Index: site-manage/site-manage-tool/tool/src/bundle/sitesetupgeneric.properties =================================================================== --- site-manage/site-manage-tool/tool/src/bundle/sitesetupgeneric.properties (revision 14) +++ site-manage/site-manage-tool/tool/src/bundle/sitesetupgeneric.properties (revision 15) @@ -584,10 +584,11 @@ sitetype.acater = Academic term: sitetype.alert = Alert: sitetype.can = Cancel -sitetype.chothetyp = Choose the type of site you want to create. Only instructors can create official course websites. Instructors and students can create project websites. NOTE: Students, if you do not see a tab for your course, contact your instructor for information about when your official course website will be available. +sitetype.chothetyp = You can create a new project site in one of two ways. A Build-Your-Own project site (for experienced users) lets you choose individual site tools and functions. A Template-based site (recommended for new users) comes pre-loaded with essential tools and functions. Please note, you can add or remove tools from either type of project site, once created. sitetype.con = Continue sitetype.crenewsit = Creating a new site sitetype.gratooweb = Grad Tools website +sitetype.project = Build-Your-Own project site sitetype.websit = website sitinfimp.alert = Alert: @@ -997,4 +998,4 @@ alert.protocol=Please use a valid web address. #############UPV Revision ########################### -zip_file_upload = Please select zip file to upload and extract to your site \ No newline at end of file +zip_file_upload = Please select zip file to upload and extract to your site Index: site-manage/site-manage-tool/tool/src/webapp/tools/sakai.sitesetup.xml =================================================================== --- site-manage/site-manage-tool/tool/src/webapp/tools/sakai.sitesetup.xml (revision 14) +++ site-manage/site-manage-tool/tool/src/webapp/tools/sakai.sitesetup.xml (revision 15) @@ -13,14 +13,14 @@ - + - + Index: site-manage/site-manage-tool/tool/src/webapp/vm/sitesetup/chef_site-type.vm =================================================================== --- site-manage/site-manage-tool/tool/src/webapp/vm/sitesetup/chef_site-type.vm (revision 14) +++ site-manage/site-manage-tool/tool/src/webapp/vm/sitesetup/chef_site-type.vm (revision 15) @@ -14,6 +14,22 @@ } } } + + + function selectTemplateSite () + { + for (var i=0; i
@@ -30,7 +46,9 @@

+ + +             + +

+ #end
Index: site-manage/site-manage-tool/tool/src/webapp/vm/sitesetup/chef_site-newSiteInformation.vm =================================================================== --- site-manage/site-manage-tool/tool/src/webapp/vm/sitesetup/chef_site-newSiteInformation.vm (revision 14) +++ site-manage/site-manage-tool/tool/src/webapp/vm/sitesetup/chef_site-newSiteInformation.vm (revision 15) @@ -188,12 +188,10 @@ class="active" accesskey="s" onclick="document.siteInfoForm.option.value='continue'; document.siteInfoForm.submit(); return false;" /> - #if ($!siteTypes.size() > 1) - - #end +