Skip to content

Commit

Permalink
LSNBLDR-857 move lesson subpage tree code from portal to lessonbuilder (
Browse files Browse the repository at this point in the history
  • Loading branch information
payten authored and jonespm committed Aug 25, 2017
1 parent 9002f6b commit ad8af5a
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 274 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,5 @@ public class PageData {

public boolean doesPageFolderExist(final String siteId, final String folder);

public String getLessonSubPageJSON(String userId, boolean isInstructor, List pages);
}
3 changes: 3 additions & 0 deletions lessonbuilder/components/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@
<include>**/*.sql</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/resources</directory>
</resource>
</resources>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.hibernate.CacheMode;
import org.hibernate.Query;
Expand Down Expand Up @@ -78,6 +79,7 @@
import org.sakaiproject.lessonbuildertool.SimpleStudentPage;
import org.sakaiproject.lessonbuildertool.SimpleStudentPageImpl;
import org.sakaiproject.lessonbuildertool.api.LessonBuilderConstants;
import org.sakaiproject.lessonbuildertool.util.LessonsSubNavBuilder;
import org.sakaiproject.site.api.SitePage;
import org.sakaiproject.site.api.SiteService;
import org.sakaiproject.site.api.ToolConfiguration;
Expand Down Expand Up @@ -1806,4 +1808,54 @@ public List<SimplePageItem> findAllChecklistsInSite(String siteId) {
return (List<SimplePageItem>) getHibernateTemplate().findByNamedParam(hql, "site", siteId);
}


public String getLessonSubPageJSON(final String userId, final boolean isInstructor, final List pages) {
final String sql = ("SELECT p.toolId AS sakaiPageId," +
" p.pageId AS lessonsPageId," +
" s.site_id AS sakaiSiteId," +
" s.tool_id AS sakaiToolId," +
" i.id AS itemId," +
" i.name AS itemName," +
" i.description AS itemDescription," +
" i.sakaiId AS itemSakaiId," +
" p2.hidden AS pageHidden," +
" p2.releaseDate AS pageReleaseDate," +
" log.complete AS completed," +
" i.required," +
" i.prerequisite" +
" FROM lesson_builder_pages p" +
" INNER JOIN SAKAI_SITE_TOOL s" +
" ON p.toolId = s.page_id" +
" INNER JOIN lesson_builder_items i" +
" ON (i.pageId = p.pageId AND type = 2)" +
" INNER JOIN lesson_builder_pages p2" +
" ON (p2.pageId = i.sakaiId)" +
" LEFT OUTER JOIN lesson_builder_log log" +
" ON (log.itemId = i.id AND log.userId = ?)" +
" WHERE p.parent IS NULL" +
" AND p.toolId IN (" + pages.stream().map(i -> "?").collect(Collectors.joining(",")) + ")" +
" ORDER BY i.sequence");

final Object [] fields = new Object[pages.size() + 1];
fields[0] = userId;

final List<String> pageIds = LessonsSubNavBuilder.collectPageIds(pages);
for (int i=0; i<pageIds.size(); i++) {
fields[i+1] = pageIds.get(i);
}

final LessonsSubNavBuilder lessonsSubNavBuilder = new LessonsSubNavBuilder(isInstructor);

sqlService.dbRead(sql, fields, new SqlReader() {
public Object readSqlResultRecord(final ResultSet result) {
try {
return lessonsSubNavBuilder.processResult(result);
} catch (SQLException e) {
return null;
}
}
});

return lessonsSubNavBuilder.toJSON();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/**********************************************************************************
*
* Copyright (c) 2017 The Sakai Foundation
*
* Original developers:
*
* New York University
* Payten Giles
* Mark Triggs
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/

package org.sakaiproject.lessonbuildertool.util;

import lombok.extern.slf4j.Slf4j;
import org.json.simple.JSONObject;
import org.sakaiproject.time.cover.TimeService;
import org.sakaiproject.util.ResourceLoader;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DateFormat;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

@Slf4j
public class LessonsSubNavBuilder {

private static ResourceLoader rb = new ResourceLoader("subnav");

private boolean isInstructor;
private Map<String, ArrayList<Map<String, String>>> subnavData;

public LessonsSubNavBuilder(final boolean isInstructor) {
this.isInstructor = isInstructor;
this.subnavData = new HashMap<>();
}

public String toJSON() {
applyPrerequisites();

final Map<String, Object> objectToSerialize = new HashMap<>();
objectToSerialize.put("pages", this.subnavData);
objectToSerialize.put("i18n", getI18n());

return JSONObject.toJSONString(objectToSerialize);
}


public static List<String> collectPageIds(final List pages) {
final List<Map<String,String>> typedPages = (List<Map<String,String>>) pages;
final List<String> pageIds = new ArrayList<>(typedPages.size());

for (Map<String, String> page : typedPages) {
pageIds.add(page.get("pageId"));
}

return pageIds;
}


public Map<String, String> processResult(final ResultSet rs) throws SQLException {
final String sakaiToolId = rs.getString("sakaiToolId");

if (isHidden(rs)) {
return null;
}

if (!this.subnavData.containsKey(sakaiToolId)) {
this.subnavData.put(sakaiToolId, new ArrayList<>());
}

final Map<String, String> subnavItem = new HashMap<>();

subnavItem.put("toolId", rs.getString("sakaiToolId"));
subnavItem.put("siteId", rs.getString("sakaiSiteId"));
subnavItem.put("itemId", rs.getString("itemId"));
subnavItem.put("sendingPage", rs.getString("itemSakaiId"));
subnavItem.put("name", rs.getString("itemName"));
subnavItem.put("description", rs.getString("itemDescription"));
subnavItem.put("hidden", rs.getInt("pageHidden") == 1 ? "true" : "false");

subnavItem.put("required", rs.getInt("required") == 1 ? "true" : "false");
subnavItem.put("completed", rs.getInt("completed") == 1 ? "true" : "false");
subnavItem.put("prerequisite", rs.getInt("prerequisite") == 1 ? "true" : "false");

if (rs.getTimestamp("pageReleaseDate") != null) {
final Timestamp releaseDate = rs.getTimestamp("pageReleaseDate");
if (releaseDate.getTime() > System.currentTimeMillis()) {
subnavItem.put("hidden", "true");
final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, rb.getLocale());
final TimeZone tz = TimeService.getLocalTimeZone();
df.setTimeZone(tz);
subnavItem.put("releaseDate", df.format(releaseDate));
}
}

this.subnavData.get(sakaiToolId).add(subnavItem);

return subnavItem;
}

private boolean isHidden(final ResultSet rs) throws SQLException {
if (this.isInstructor) {
return false;
}

if (rs.getInt("pageHidden") == 1) {
return true;
} else if (rs.getTimestamp("pageReleaseDate") != null) {
if (rs.getTimestamp("pageReleaseDate").getTime() > System.currentTimeMillis()) {
return true;
}
}

return false;
}


private Map<String, String> getI18n() {
final Map<String, String> translations = new HashMap<>();

translations.put("expand", rb.getString("lessons_subnav.expand"));
translations.put("collapse", rb.getString("lessons_subnav.collapse"));
translations.put("open_top_level_page", rb.getString("lessons_subnav.open_top_level_page"));
translations.put("hidden", rb.getString("lessons_subnav.hidden"));
translations.put("hidden_with_release_date", rb.getString("lessons_subnav.hidden_with_release_date"));
translations.put("prerequisite", rb.getString("lessons_subnav.prerequisite"));
translations.put("prerequisite_and_disabled", rb.getString("lessons_subnav.prerequisite_and_disabled"));

return translations;
}

private void applyPrerequisites() {
for (final String pageId : this.subnavData.keySet()) {
boolean prerequisiteApplies = false;
final List<Map<String, String>> pages = this.subnavData.get(pageId);
for (Map<String, String> pageData : pages) {
// If a sibling item with a smaller sequence is required
// we want to disable the current item for students
if (pageData.get("prerequisite").equals("true") && prerequisiteApplies) {
pageData.put("disabledDueToPrerequisite", "true");
pageData.put("disabled", String.valueOf(!this.isInstructor));
}

// Only disable items that have prerequisites below the current item
// when the current item is required and the user is yet to complete it
if (pageData.get("required").equals("true")) {
if (pageData.get("completed").equals("false")) {
prerequisiteApplies = true;
}
}
}
}
}
}
7 changes: 7 additions & 0 deletions lessonbuilder/components/src/resources/subnav.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
lessons_subnav.expand = Expand to show subpages
lessons_subnav.collapse = Collapse to hide subpages
lessons_subnav.open_top_level_page: Click to open top-level page
lessons_subnav.hidden: [Hidden]
lessons_subnav.hidden_with_release_date: [Not released until {releaseDate}]
lessons_subnav.prerequisite: [Has prerequisites]
lessons_subnav.prerequisite_and_disabled: [You must complete all prerequisites before viewing this item]
5 changes: 4 additions & 1 deletion portal/portal-impl/impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>

<dependency>
<groupId>org.sakaiproject.lessonbuilder</groupId>
<artifactId>lessonbuilder-api</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
10 changes: 1 addition & 9 deletions portal/portal-impl/impl/src/bundle/sitenav.properties
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,4 @@ pic_changer_save = Save
pic_changer_cancel = Cancel
pic_changer_remove = Remove
pic_changer_remove_error = Error removing image
pic_changer_upload_error = Error uploading image

lessons_subnav.expand = Expand to show subpages
lessons_subnav.collapse = Collapse to hide subpages
lessons_subnav.open_top_level_page: Click to open top-level page
lessons_subnav.hidden: [Hidden]
lessons_subnav.hidden_with_release_date: [Not released until {releaseDate}]
lessons_subnav.prerequisite: [Has prerequisites]
lessons_subnav.prerequisite_and_disabled: [You must complete all prerequisites before viewing this item]
pic_changer_upload_error = Error uploading image
Loading

0 comments on commit ad8af5a

Please sign in to comment.