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