Added file storage access
This commit is contained in:
parent
3c7369ce6b
commit
324567a2ca
4 changed files with 180 additions and 35 deletions
|
@ -9,20 +9,37 @@ abstract class formbase extends moodleform {
|
||||||
/**
|
/**
|
||||||
* Create the form while providing the correct defaults for our type of forms
|
* Create the form while providing the correct defaults for our type of forms
|
||||||
* @param array $ajaxformdata Provide submitted form data through Ajax here
|
* @param array $ajaxformdata Provide submitted form data through Ajax here
|
||||||
*
|
* @throws \moodle_exception if parameters are invalid or access is denied for a specific reason.
|
||||||
*/
|
*/
|
||||||
public function __construct($ajaxformdata=null) {
|
public function __construct($params, $ajaxformdata=null) {
|
||||||
parent::__construct(null, null, 'post', '', null, true, $ajaxformdata);
|
$customdata = static::init_customdata($params);
|
||||||
|
if (static::check_security($customdata)) {
|
||||||
|
|
||||||
|
parent::__construct(null, (array)$customdata, 'post', '', null, true, $ajaxformdata);
|
||||||
|
// Initialize the initial data based on the parameter validation
|
||||||
|
$this->set_data($this->init_formdata((object)$this->_customdata));
|
||||||
|
} else {
|
||||||
|
throw new \moodle_exception('accessexception', 'core');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate custom data from parameters
|
||||||
|
* Also validate parameters and access permissions here
|
||||||
|
*
|
||||||
|
* @param object $params The parameters for form initialization
|
||||||
|
* @return object Form data based on parameters
|
||||||
|
*/
|
||||||
|
abstract public static function init_customdata(object $params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate form data from parameters
|
* Generate form data from parameters
|
||||||
* Also validate parameters and access permissions here
|
* Also validate parameters and access permissions here
|
||||||
*
|
*
|
||||||
* @param object $params The parameters for form initialization
|
* @param object $customdata The parameters for form initialization
|
||||||
* @return array Form data based on parameters
|
* @return array Form data based on parameters
|
||||||
*/
|
*/
|
||||||
abstract public static function init_data(object $params);
|
abstract public function init_formdata(object $customdata);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate security access for this form based on the provided parameters
|
* Validate security access for this form based on the provided parameters
|
||||||
|
@ -32,14 +49,28 @@ abstract class formbase extends moodleform {
|
||||||
* @return bool True if security validation passes.
|
* @return bool True if security validation passes.
|
||||||
* @throws \moodle_exception if access denied for a specific reason.
|
* @throws \moodle_exception if access denied for a specific reason.
|
||||||
*/
|
*/
|
||||||
abstract public static function check_security(object $params);
|
abstract public static function check_security(object $customdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the submission and perform necessary actions
|
||||||
|
* @param object $entry The processed form data
|
||||||
|
* @return bool True if submission successful
|
||||||
|
* @throws \moodle_exception if an error must be given for a specific reason.
|
||||||
|
*/
|
||||||
|
abstract protected function process_submitted_data(object $entry);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the submission and perform necessary actions
|
* Process the submission and perform necessary actions
|
||||||
* @return bool True if submission successful
|
* @return bool True if submission successful
|
||||||
* @throws \moodle_exception if an error must be given for a specific reason.
|
* @throws \moodle_exception if an error must be given for a specific reason.
|
||||||
*/
|
*/
|
||||||
abstract public function process_submission();
|
public function process_submission() {
|
||||||
|
$data = $this->get_data();
|
||||||
|
if($data) {
|
||||||
|
$this->process_submitted_data($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,6 +3,8 @@
|
||||||
namespace local_treestudyplan\local\forms;
|
namespace local_treestudyplan\local\forms;
|
||||||
use local_treestudyplan\studyplan;
|
use local_treestudyplan\studyplan;
|
||||||
use local_treestudyplan\local\helpers\webservicehelper;
|
use local_treestudyplan\local\helpers\webservicehelper;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moodleform class for the studyplan editor. A Moodleform is used here to facilitate a rich editor
|
* Moodleform class for the studyplan editor. A Moodleform is used here to facilitate a rich editor
|
||||||
* in the studyplan description
|
* in the studyplan description
|
||||||
|
@ -13,52 +15,97 @@ class studyplan_editform extends formbase {
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const CAP_EDIT = "local/treestudyplan:editstudyplan";
|
const CAP_EDIT = "local/treestudyplan:editstudyplan";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate security access for this form based on the provided parameters
|
* Translate parameters into customdata.
|
||||||
* Return true if validation passes, false or throw an exception if it does not.
|
|
||||||
*
|
*
|
||||||
* @param object $params The parameters for form initialization
|
* @param object $params The parameters for form initialization
|
||||||
|
* @return array Form data based on parameters
|
||||||
|
*/
|
||||||
|
public static function init_customdata(object $params) {
|
||||||
|
$customdata = new stdClass;
|
||||||
|
$customdata->plan = studyplan::find_by_id($params->studyplanid);
|
||||||
|
$customdata->context = $customdata->plan->context();
|
||||||
|
$customdata->editoroptions = [
|
||||||
|
'trusttext' => true,
|
||||||
|
'subdirs' => true,
|
||||||
|
'maxfiles' => 20,
|
||||||
|
'maxbytes' => 20*1024*1024,
|
||||||
|
'context' => \context_system::instance(),
|
||||||
|
];
|
||||||
|
return $customdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate security access for this form based on the customdata generated by init_customdata
|
||||||
|
* Return true if validation passes, false or throw an exception if it does not.
|
||||||
|
*
|
||||||
|
* @param object $customdata The customdata for this form
|
||||||
* @return bool True if security validation passes.
|
* @return bool True if security validation passes.
|
||||||
* @throws \moodle_exception if access denied for a specific reason.
|
* @throws \moodle_exception if access denied for a specific reason.
|
||||||
*/
|
*/
|
||||||
public static function check_security(object $params) {
|
public static function check_security(object $customdata) {
|
||||||
$plan = studyplan::find_by_id($params->studyplanid);
|
webservicehelper::require_capabilities(self::CAP_EDIT,$customdata->context);
|
||||||
webservicehelper::require_capabilities(self::CAP_EDIT,$plan->context());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate form data from parameters
|
* Generate form data from parameters
|
||||||
* Also validate parameters and access permissions here
|
* Also validate parameters and access permissions here
|
||||||
*
|
*
|
||||||
* @param object $params The parameters for form initialization
|
* @param object $customdata The parameters for form initialization
|
||||||
* @return array Form data based on parameters
|
* @return array Form data based on parameters
|
||||||
*/
|
*/
|
||||||
public static function init_data(object $params) {
|
public function init_formdata(object $customdata) {
|
||||||
$plan = studyplan::find_by_id($params->studyplanid);
|
global $DB;
|
||||||
|
/* Use direct database retrieval to avoid our abstractions causing trouble
|
||||||
|
with existing moodle code assumptions.
|
||||||
|
The form API does seem needlessly convoluted in it's use, but we need the editor...
|
||||||
|
*/
|
||||||
|
$entry = $DB->get_record(studyplan::TABLE, ['id' => $customdata->plan->id()]);
|
||||||
|
$entry = file_prepare_standard_editor( $entry,
|
||||||
|
'description',
|
||||||
|
$customdata->editoroptions,
|
||||||
|
\context_system::instance(),
|
||||||
|
'local_treestudyplan',
|
||||||
|
'studyplan',
|
||||||
|
$entry->id);
|
||||||
|
return $entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the form definition
|
* Set up the form definition
|
||||||
*/
|
*/
|
||||||
public function definition() {
|
public function definition() {
|
||||||
$mform = $this->_form;
|
$mform = $this->_form;
|
||||||
|
$customdata = (object)$this->_customdata;
|
||||||
// Define the form
|
// Define the form
|
||||||
$mform->addElement('editor', 'activityeditor',
|
$mform->addElement('editor', 'description_editor',
|
||||||
get_string('activityeditor', 'assign'), array('rows' => 10), array('maxfiles' => EDITOR_UNLIMITED_FILES,
|
get_string('studyplan_description', 'local_treestudyplan'),
|
||||||
'noclean' => true, 'context' => $this->context, 'subdirs' => true));
|
null,
|
||||||
$mform->addHelpButton('activityeditor', 'activityeditor', 'assign');
|
$customdata->editoroptions);
|
||||||
$mform->setType('activityeditor', PARAM_RAW);
|
$mform->setType('description_editor', PARAM_RAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the submission and perform necessary actions
|
* Process the submitted data and perform necessary actions
|
||||||
|
* @param object $entry The processed form data;
|
||||||
|
* @return bool True if submission successful
|
||||||
* @throws \moodle_exception if an error must be given for a specific reason.
|
* @throws \moodle_exception if an error must be given for a specific reason.
|
||||||
*/
|
*/
|
||||||
public function process_submission()
|
protected function process_submitted_data($entry) {
|
||||||
{
|
$customdata = (object)$this->_customdata;
|
||||||
|
// Process the provided files in the description editor
|
||||||
|
$entry = file_postupdate_standard_editor($entry,
|
||||||
|
'description',
|
||||||
|
$customdata->editoroptions,
|
||||||
|
\context_system::instance(),
|
||||||
|
'local_treestudyplan',
|
||||||
|
'studyplan',
|
||||||
|
$entry->id);
|
||||||
|
|
||||||
|
// Use our own abstraction to update the record, so caches are maintained
|
||||||
|
$customdata->plan->edit(['description' => $entry->description,
|
||||||
|
'descriptionformat' => $entry->descriptionformat]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,14 +56,8 @@ class utilityservice extends \external_api {
|
||||||
|
|
||||||
$mformclassname = "\\local_treestudyplan\\local\\forms\\{$formname}";
|
$mformclassname = "\\local_treestudyplan\\local\\forms\\{$formname}";
|
||||||
$jsonparams = json_decode($params);
|
$jsonparams = json_decode($params);
|
||||||
|
$mform = new $mformclassname( $jsonparams, $ajaxformdata);
|
||||||
if($mformclassname::security_validate($params)){
|
|
||||||
$mform = new $mformclassname($ajaxformdata);
|
|
||||||
$mform->set_data($mformclassname::init_data($jsonparams));
|
|
||||||
return $mform;
|
return $mform;
|
||||||
} else {
|
|
||||||
throw new \moodle_exception('accessexception', 'core');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
73
lib.php
73
lib.php
|
@ -380,3 +380,76 @@ function local_treestudyplan_output_fragment_mod_edit_form($args) {
|
||||||
return $mform->render();
|
return $mform->render();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve the files from the myplugin file areas.
|
||||||
|
*
|
||||||
|
* @param stdClass $course the course object
|
||||||
|
* @param stdClass $cm the course module object
|
||||||
|
* @param stdClass $context the context
|
||||||
|
* @param string $filearea the name of the file area
|
||||||
|
* @param array $args extra arguments (itemid, path)
|
||||||
|
* @param bool $forcedownload whether or not force download
|
||||||
|
* @param array $options additional options affecting the file serving
|
||||||
|
* @return bool false if the file not found, just send the file otherwise and do not return anything
|
||||||
|
*/
|
||||||
|
function local_treestudyplan_pluginfile(
|
||||||
|
$course,
|
||||||
|
$cm,
|
||||||
|
$context,
|
||||||
|
string $filearea,
|
||||||
|
array $args,
|
||||||
|
bool $forcedownload,
|
||||||
|
array $options = []
|
||||||
|
): bool {
|
||||||
|
global $DB,$USER;
|
||||||
|
|
||||||
|
// Check the contextlevel is as expected - the studyplan plugin only uses system context for storing files.
|
||||||
|
// This avoids headaches when moving studyplans, while the security impact is minimal...
|
||||||
|
if ($context->contextlevel != CONTEXT_SYSTEM) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the filearea is one of those used by the plugin.
|
||||||
|
if ($filearea == "studyplan") {
|
||||||
|
// The args is an array containing [itemid, path].
|
||||||
|
// Fetch the itemid from the path.
|
||||||
|
$itemid = array_shift($args);
|
||||||
|
|
||||||
|
$plan = studyplan::find_by_id($itemid);
|
||||||
|
$planctx = $plan->context();
|
||||||
|
// Check if the current user has access to this studyplan
|
||||||
|
if (webservicehelper::has_capabilities(['',''],$planctx) || $plan->has_linked_user($USER)) {
|
||||||
|
// Extract the filename / filepath from the $args array.
|
||||||
|
$filename = array_pop($args); // The last item in the $args array.
|
||||||
|
if (empty($args)) {
|
||||||
|
// $args is empty => the path is '/'.
|
||||||
|
$filepath = '/';
|
||||||
|
} else {
|
||||||
|
// $args contains the remaining elements of the filepath.
|
||||||
|
$filepath = '/' . implode('/', $args) . '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the file from the Files API.
|
||||||
|
$fs = get_file_storage();
|
||||||
|
$file = $fs->get_file(\context_system::instance(), 'local_treestudyplan', $filearea, $itemid, $filepath, $filename);
|
||||||
|
if (!$file) {
|
||||||
|
// The file does not exist.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can now send the file back to the browser - in this case with a cache lifetime of 1 day and no filtering.
|
||||||
|
send_stored_file($file, 24*60*60, 0, $forcedownload, $options);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue