canvas-lms/app/controllers/context_modules_api_control...

293 lines
10 KiB
Ruby
Raw Normal View History

modules api, closes #10404 also modifies the discussion topic and assignment API controllers to make sure "must_view" requirements are fulfilled test plan: * check the API documentation; ensure it looks okay * create a course with module items of each supported type * set completion criteria of each supported type * create another module, so you can set prerequisites * use the list modules API and verify its output matches the course and the documentation * as a teacher, "state" should be missing * as a student, "state" should be "locked", "unlocked", "started", or "completed" * use the show module API and verify the correct information is returned for a single module * use the list module items API and verify the output * as a teacher, the "completion_requirement" omits the "completed" flag * as a student, "completed" should be true or false, depending on whether the requirement was met * use the show module API and verify the correct information is returned for a single module item * last but not least, verify "must view" requirements can be fulfilled through the api_data_endpoints supplied for files, pages, discussions, and assignments * files are viewed when downloading their content * pages are viewed by the show action (where content is returned) * discussions are viewed when marked read via the mark_topic_read or mark_all_read actions * assignments are viewed by the show action (where description is returned). they are not viewed if the assignment is locked and the user does not have access to the content yet. Change-Id: I0cbbbc542f69215e7b396a501d4d86ff2f76c149 Reviewed-on: https://gerrit.instructure.com/13626 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Simon Williams <simon@instructure.com>
2012-09-12 01:16:48 +08:00
#
# Copyright (C) 2012 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# @API Modules
#
# Modules are collections of learning materials useful for organizing courses
# and optionally providing a linear flow through them. Module items can be
# accessed linearly or sequentially depending on module configuration. Items
# can be unlocked by various criteria such as reading a page or achieving a
# minimum score on a quiz. Modules themselves can be unlocked by the completion
# of other Modules.
#
# @object Module
# {
# // the unique identifier for the module
# id: 123,
# // the state of the module: active, deleted
# workflow_state: active,
modules api, closes #10404 also modifies the discussion topic and assignment API controllers to make sure "must_view" requirements are fulfilled test plan: * check the API documentation; ensure it looks okay * create a course with module items of each supported type * set completion criteria of each supported type * create another module, so you can set prerequisites * use the list modules API and verify its output matches the course and the documentation * as a teacher, "state" should be missing * as a student, "state" should be "locked", "unlocked", "started", or "completed" * use the show module API and verify the correct information is returned for a single module * use the list module items API and verify the output * as a teacher, the "completion_requirement" omits the "completed" flag * as a student, "completed" should be true or false, depending on whether the requirement was met * use the show module API and verify the correct information is returned for a single module item * last but not least, verify "must view" requirements can be fulfilled through the api_data_endpoints supplied for files, pages, discussions, and assignments * files are viewed when downloading their content * pages are viewed by the show action (where content is returned) * discussions are viewed when marked read via the mark_topic_read or mark_all_read actions * assignments are viewed by the show action (where description is returned). they are not viewed if the assignment is locked and the user does not have access to the content yet. Change-Id: I0cbbbc542f69215e7b396a501d4d86ff2f76c149 Reviewed-on: https://gerrit.instructure.com/13626 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Simon Williams <simon@instructure.com>
2012-09-12 01:16:48 +08:00
#
# // the position of this module in the course (1-based)
modules api, closes #10404 also modifies the discussion topic and assignment API controllers to make sure "must_view" requirements are fulfilled test plan: * check the API documentation; ensure it looks okay * create a course with module items of each supported type * set completion criteria of each supported type * create another module, so you can set prerequisites * use the list modules API and verify its output matches the course and the documentation * as a teacher, "state" should be missing * as a student, "state" should be "locked", "unlocked", "started", or "completed" * use the show module API and verify the correct information is returned for a single module * use the list module items API and verify the output * as a teacher, the "completion_requirement" omits the "completed" flag * as a student, "completed" should be true or false, depending on whether the requirement was met * use the show module API and verify the correct information is returned for a single module item * last but not least, verify "must view" requirements can be fulfilled through the api_data_endpoints supplied for files, pages, discussions, and assignments * files are viewed when downloading their content * pages are viewed by the show action (where content is returned) * discussions are viewed when marked read via the mark_topic_read or mark_all_read actions * assignments are viewed by the show action (where description is returned). they are not viewed if the assignment is locked and the user does not have access to the content yet. Change-Id: I0cbbbc542f69215e7b396a501d4d86ff2f76c149 Reviewed-on: https://gerrit.instructure.com/13626 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Simon Williams <simon@instructure.com>
2012-09-12 01:16:48 +08:00
# position: 2,
#
# // the name of this module
# name: "Imaginary Numbers and You",
#
# // (Optional) the date this module will unlock
# unlock_at: "2012-12-31T06:00:00-06:00",
#
# // Whether module items must be unlocked in order
# require_sequential_progress: true,
#
# // IDs of Modules that must be completed before this one is unlocked
# prerequisite_module_ids: [121, 122],
#
# // The state of this Module for the calling user
# // one of 'locked', 'unlocked', 'started', 'completed'
# // (Optional; present only if the caller is a student)
# state: 'started',
#
# // the date the calling user completed the module
# // (Optional; present only if the caller is a student)
# completed_at: nil
# }
class ContextModulesApiController < ApplicationController
before_filter :require_context
include Api::V1::ContextModule
# @API List modules
#
# List the modules in a course
#
# @example_request
# curl -H 'Authorization: Bearer <token>' \
modules api, closes #10404 also modifies the discussion topic and assignment API controllers to make sure "must_view" requirements are fulfilled test plan: * check the API documentation; ensure it looks okay * create a course with module items of each supported type * set completion criteria of each supported type * create another module, so you can set prerequisites * use the list modules API and verify its output matches the course and the documentation * as a teacher, "state" should be missing * as a student, "state" should be "locked", "unlocked", "started", or "completed" * use the show module API and verify the correct information is returned for a single module * use the list module items API and verify the output * as a teacher, the "completion_requirement" omits the "completed" flag * as a student, "completed" should be true or false, depending on whether the requirement was met * use the show module API and verify the correct information is returned for a single module item * last but not least, verify "must view" requirements can be fulfilled through the api_data_endpoints supplied for files, pages, discussions, and assignments * files are viewed when downloading their content * pages are viewed by the show action (where content is returned) * discussions are viewed when marked read via the mark_topic_read or mark_all_read actions * assignments are viewed by the show action (where description is returned). they are not viewed if the assignment is locked and the user does not have access to the content yet. Change-Id: I0cbbbc542f69215e7b396a501d4d86ff2f76c149 Reviewed-on: https://gerrit.instructure.com/13626 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Simon Williams <simon@instructure.com>
2012-09-12 01:16:48 +08:00
# https://<canvas>/api/v1/courses/222/modules
#
# @returns [Module]
def index
if authorized_action(@context, @current_user, :read)
route = polymorphic_url([:api_v1, @context, :context_modules])
scope = @context.modules_visible_to(@current_user)
modules api, closes #10404 also modifies the discussion topic and assignment API controllers to make sure "must_view" requirements are fulfilled test plan: * check the API documentation; ensure it looks okay * create a course with module items of each supported type * set completion criteria of each supported type * create another module, so you can set prerequisites * use the list modules API and verify its output matches the course and the documentation * as a teacher, "state" should be missing * as a student, "state" should be "locked", "unlocked", "started", or "completed" * use the show module API and verify the correct information is returned for a single module * use the list module items API and verify the output * as a teacher, the "completion_requirement" omits the "completed" flag * as a student, "completed" should be true or false, depending on whether the requirement was met * use the show module API and verify the correct information is returned for a single module item * last but not least, verify "must view" requirements can be fulfilled through the api_data_endpoints supplied for files, pages, discussions, and assignments * files are viewed when downloading their content * pages are viewed by the show action (where content is returned) * discussions are viewed when marked read via the mark_topic_read or mark_all_read actions * assignments are viewed by the show action (where description is returned). they are not viewed if the assignment is locked and the user does not have access to the content yet. Change-Id: I0cbbbc542f69215e7b396a501d4d86ff2f76c149 Reviewed-on: https://gerrit.instructure.com/13626 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Simon Williams <simon@instructure.com>
2012-09-12 01:16:48 +08:00
modules = Api.paginate(scope, self, route)
modules_and_progressions = if @context.grants_right?(@current_user, session, :participate_as_student)
modules.map { |m| [m, m.evaluate_for(@current_user)] }
else
modules.map { |m| [m, nil] }
end
render :json => modules_and_progressions.map { |mod, prog| module_json(mod, @current_user, session, prog) }
end
end
# @API Show module
#
# Get information about a single module
#
# @example_request
# curl -H 'Authorization: Bearer <token>' \
modules api, closes #10404 also modifies the discussion topic and assignment API controllers to make sure "must_view" requirements are fulfilled test plan: * check the API documentation; ensure it looks okay * create a course with module items of each supported type * set completion criteria of each supported type * create another module, so you can set prerequisites * use the list modules API and verify its output matches the course and the documentation * as a teacher, "state" should be missing * as a student, "state" should be "locked", "unlocked", "started", or "completed" * use the show module API and verify the correct information is returned for a single module * use the list module items API and verify the output * as a teacher, the "completion_requirement" omits the "completed" flag * as a student, "completed" should be true or false, depending on whether the requirement was met * use the show module API and verify the correct information is returned for a single module item * last but not least, verify "must view" requirements can be fulfilled through the api_data_endpoints supplied for files, pages, discussions, and assignments * files are viewed when downloading their content * pages are viewed by the show action (where content is returned) * discussions are viewed when marked read via the mark_topic_read or mark_all_read actions * assignments are viewed by the show action (where description is returned). they are not viewed if the assignment is locked and the user does not have access to the content yet. Change-Id: I0cbbbc542f69215e7b396a501d4d86ff2f76c149 Reviewed-on: https://gerrit.instructure.com/13626 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Simon Williams <simon@instructure.com>
2012-09-12 01:16:48 +08:00
# https://<canvas>/api/v1/courses/222/modules/123
#
# @returns Module
def show
if authorized_action(@context, @current_user, :read)
mod = @context.modules_visible_to(@current_user).find(params[:id])
modules api, closes #10404 also modifies the discussion topic and assignment API controllers to make sure "must_view" requirements are fulfilled test plan: * check the API documentation; ensure it looks okay * create a course with module items of each supported type * set completion criteria of each supported type * create another module, so you can set prerequisites * use the list modules API and verify its output matches the course and the documentation * as a teacher, "state" should be missing * as a student, "state" should be "locked", "unlocked", "started", or "completed" * use the show module API and verify the correct information is returned for a single module * use the list module items API and verify the output * as a teacher, the "completion_requirement" omits the "completed" flag * as a student, "completed" should be true or false, depending on whether the requirement was met * use the show module API and verify the correct information is returned for a single module item * last but not least, verify "must view" requirements can be fulfilled through the api_data_endpoints supplied for files, pages, discussions, and assignments * files are viewed when downloading their content * pages are viewed by the show action (where content is returned) * discussions are viewed when marked read via the mark_topic_read or mark_all_read actions * assignments are viewed by the show action (where description is returned). they are not viewed if the assignment is locked and the user does not have access to the content yet. Change-Id: I0cbbbc542f69215e7b396a501d4d86ff2f76c149 Reviewed-on: https://gerrit.instructure.com/13626 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Simon Williams <simon@instructure.com>
2012-09-12 01:16:48 +08:00
prog = @context.grants_right?(@current_user, session, :participate_as_student) ? mod.evaluate_for(@current_user) : nil
render :json => module_json(mod, @current_user, session, prog)
end
end
# @undocumented API Update multiple modules
#
# Update multiple modules in an account.
#
# @argument module_ids[] List of ids of modules to update.
# @argument event The action to take on each module. Must be 'delete'.
#
# @response_field completed A list of IDs for modules that were updated.
#
# @example_request
# curl https://<canvas>/api/v1/courses/<course_id>/modules \
# -X PUT \
# -H 'Authorization: Bearer <token>' \
# -d 'event=delete' \
# -d 'module_ids[]=1' \
# -d 'module_ids[]=2'
#
# @example_response
# {
# "completed": [1, 2]
# }
def batch_update
if authorized_action(@context, @current_user, :manage_content)
event = params[:event]
return render(:json => { :message => 'need to specify event' }, :status => :bad_request) unless event.present?
return render(:json => { :message => 'invalid event' }, :status => :bad_request) unless %w(publish unpublish delete).include? event
return render(:json => { :message => 'must specify module_ids[]' }, :status => :bad_request) unless params[:module_ids].present?
module_ids = Api.map_non_sis_ids(Array(params[:module_ids]))
modules = @context.context_modules.not_deleted.find_all_by_id(module_ids)
return render(:json => { :message => 'no modules found' }, :status => :not_found) if modules.empty?
completed_ids = []
modules.each do |mod|
case event
when 'publish'
unless mod.active?
mod.publish
mod.publish_items!
end
when 'unpublish'
mod.unpublish unless mod.unpublished?
when 'delete'
mod.destroy
end
completed_ids << mod.id
end
render :json => { :completed => completed_ids }
end
end
# @API Create a module
#
# Create and return a new module
#
# @argument module[name] [Required] The name of the module
# @argument module[unlock_at] [Optional] The date the module will unlock
# @argument module[position] [Optional] The position of this module in the course (1-based)
# @argument module[require_sequential_progress] [Optional] Whether module items must be unlocked in order
# @argument module[prerequisite_module_ids][] [Optional] IDs of Modules that must be completed before this one is unlocked
# Prerequisite modules must precede this module (i.e. have a lower position value), otherwise they will be ignored
#
# @example_request
#
# curl https://<canvas>/api/v1/courses/<course_id>/modules \
# -X POST \
# -H 'Authorization: Bearer <token>' \
# -d 'module[name]=module' \
# -d 'module[position]=2' \
# -d 'module[prerequisite_module_ids][]=121' \
# -d 'module[prerequisite_module_ids][]=122'
#
# @returns Module
def create
if authorized_action(@context.context_modules.new, @current_user, :create)
return render :json => {:message => "missing module parameter"}, :status => :bad_request unless params[:module]
return render :json => {:message => "missing module name"}, :status => :bad_request unless params[:module][:name].present?
module_parameters = params[:module].slice(:name, :unlock_at, :require_sequential_progress)
@module = @context.context_modules.build(module_parameters)
if ids = params[:module][:prerequisite_module_ids]
@module.prerequisites = ids.map{|id| "module_#{id}"}.join(',')
end
if @domain_root_account.enable_draft?
@module.workflow_state = 'unpublished'
else
@module.workflow_state = 'active'
end
if @module.save && set_position
render :json => module_json(@module, @current_user, session, nil)
else
render :json => @module.errors.to_json, :status => :bad_request
end
end
end
# @API Update a module
#
# Update and return an existing module
#
# @argument module[name] [Optional] The name of the module
# @argument module[unlock_at] [Optional] The date the module will unlock
# @argument module[position] [Optional] The position of the module in the course (1-based)
# @argument module[require_sequential_progress] [Optional] Whether module items must be unlocked in order
# @argument module[prerequisite_module_ids][] [Optional] IDs of Modules that must be completed before this one is unlocked
# Prerequisite modules must precede this module (i.e. have a lower position value), otherwise they will be ignored
# @undocumented @argument module[published] [Optional] Whether the module is published and visible to students
#
# @example_request
#
# curl https://<canvas>/api/v1/courses/<course_id>/modules/<module_id> \
# -X PUT \
# -H 'Authorization: Bearer <token>' \
# -d 'module[name]=module' \
# -d 'module[position]=2' \
# -d 'module[prerequisite_module_ids][]=121' \
# -d 'module[prerequisite_module_ids][]=122'
#
# @returns Module
def update
@module = @context.context_modules.not_deleted.find(params[:id])
if authorized_action(@module, @current_user, :update)
return render :json => {:message => "missing module parameter"}, :status => :bad_request unless params[:module]
module_parameters = params[:module].slice(:name, :unlock_at, :require_sequential_progress)
if ids = params[:module][:prerequisite_module_ids]
if ids.blank?
module_parameters[:prerequisites] = []
else
module_parameters[:prerequisites] = ids.map{|id| "module_#{id}"}.join(',')
end
end
if params[:module].has_key?(:published)
if value_to_boolean(params[:module][:published])
@module.publish
@module.publish_items!
else
@module.unpublish
end
end
if @module.update_attributes(module_parameters) && set_position
render :json => module_json(@module, @current_user, session, nil)
else
render :json => @module.errors.to_json, :status => :bad_request
end
end
end
# @API Delete module
#
# Delete a module
#
# @example_request
#
# curl https://<canvas>/api/v1/courses/<course_id>/modules/<module_id> \
# -X Delete \
# -H 'Authorization: Bearer <token>'
#
# @returns Module
def destroy
@module = @context.context_modules.not_deleted.find(params[:id])
if authorized_action(@module, @current_user, :delete)
@module.destroy
render :json => module_json(@module, @current_user, session, nil)
end
end
def set_position
return true unless @module && params[:module][:position]
if @module.insert_at_position(params[:module][:position], @context.context_modules.not_deleted)
# see ContextModulesController#reorder
@context.touch
@context.context_modules.not_deleted.each{|m| m.save_without_touching_context }
@context.touch
@module.reload
return true
else
@module.errors.add(:position, t(:invalid_position, "Invalid position"))
return false
end
end
modules api, closes #10404 also modifies the discussion topic and assignment API controllers to make sure "must_view" requirements are fulfilled test plan: * check the API documentation; ensure it looks okay * create a course with module items of each supported type * set completion criteria of each supported type * create another module, so you can set prerequisites * use the list modules API and verify its output matches the course and the documentation * as a teacher, "state" should be missing * as a student, "state" should be "locked", "unlocked", "started", or "completed" * use the show module API and verify the correct information is returned for a single module * use the list module items API and verify the output * as a teacher, the "completion_requirement" omits the "completed" flag * as a student, "completed" should be true or false, depending on whether the requirement was met * use the show module API and verify the correct information is returned for a single module item * last but not least, verify "must view" requirements can be fulfilled through the api_data_endpoints supplied for files, pages, discussions, and assignments * files are viewed when downloading their content * pages are viewed by the show action (where content is returned) * discussions are viewed when marked read via the mark_topic_read or mark_all_read actions * assignments are viewed by the show action (where description is returned). they are not viewed if the assignment is locked and the user does not have access to the content yet. Change-Id: I0cbbbc542f69215e7b396a501d4d86ff2f76c149 Reviewed-on: https://gerrit.instructure.com/13626 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Simon Williams <simon@instructure.com>
2012-09-12 01:16:48 +08:00
end