628 lines
24 KiB
PHP
628 lines
24 KiB
PHP
<?php
|
|
// This file is part of the Studyplan plugin for Moodle
|
|
//
|
|
// Moodle is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Moodle 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 General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
|
/**
|
|
* Class to process information about a course
|
|
* @package local_treestudyplan
|
|
* @copyright 2023 P.M. Kuipers
|
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
|
|
namespace local_treestudyplan;
|
|
defined('MOODLE_INTERNAL') || die();
|
|
|
|
require_once($CFG->libdir.'/externallib.php');
|
|
require_once($CFG->libdir.'/gradelib.php');
|
|
require_once($CFG->dirroot.'/course/lib.php');
|
|
|
|
use core_course\local\repository\caching_content_item_readonly_repository;
|
|
use core_course\local\repository\content_item_readonly_repository;
|
|
use \grade_item;
|
|
use \grade_scale;
|
|
use \grade_outcome;
|
|
|
|
/**
|
|
* Class to process information about a course
|
|
*/
|
|
class courseinfo {
|
|
/**
|
|
* Table name used in this class
|
|
* @var string */
|
|
const TABLE = 'course';
|
|
|
|
/** @var stdClass */
|
|
private $course;
|
|
/** @var \context */
|
|
private $context;
|
|
/** @var \context */
|
|
private $coursecontext;
|
|
/** @var studyitem */
|
|
private $studyitem;
|
|
/** @var array */
|
|
private static $contentitems = null;
|
|
/**
|
|
* Cache of enrolled students in a particular course
|
|
* @var array
|
|
*/
|
|
private static $coursestudents = [];
|
|
/**
|
|
* Return database identifier
|
|
* @return int
|
|
*/
|
|
public function id() {
|
|
return $this->course->id;
|
|
}
|
|
|
|
/**
|
|
* Return short name
|
|
* @return string
|
|
*/
|
|
public function shortname() {
|
|
return $this->course->shortname;
|
|
}
|
|
|
|
/**
|
|
* Return course record
|
|
* @return \stdClass
|
|
*/
|
|
public function course() {
|
|
return $this->course;
|
|
}
|
|
|
|
/**
|
|
* Return course context
|
|
* @return \context
|
|
*/
|
|
public function course_context() {
|
|
return $this->coursecontext;
|
|
}
|
|
|
|
/**
|
|
* Return course's category context
|
|
* @return \context
|
|
*/
|
|
public function category_context() {
|
|
return $this->context;
|
|
}
|
|
|
|
/**
|
|
* Get content items (activity icons) from the repository
|
|
* @return content_item[]
|
|
*/
|
|
protected function get_contentitems() {
|
|
global $PAGE;
|
|
if (empty(static::$contentitems)) {
|
|
$PAGE->set_context(\context_system::instance());
|
|
static::$contentitems = (new content_item_readonly_repository())->find_all();
|
|
}
|
|
return static::$contentitems;
|
|
}
|
|
|
|
/**
|
|
* Check if current user is teacher in this course
|
|
* @return book
|
|
*/
|
|
protected function am_teacher() : bool {
|
|
global $USER;
|
|
return is_enrolled($this->coursecontext, $USER, 'mod/assign:grade');
|
|
}
|
|
|
|
/**
|
|
* Check if specified user can select gradables in this course
|
|
* @param int $userid User id to check for . Leave empty to check current user
|
|
*/
|
|
protected function i_can_select_gradables($userid = -1) {
|
|
global $USER, $DB;
|
|
if ($userid <= 0) {
|
|
$usr = $USER;
|
|
} else {
|
|
$usr = $DB->get_record('user', ['id' => $userid, 'deleted' => 0]);
|
|
}
|
|
return($usr && is_enrolled($this->coursecontext, $usr, 'local/treestudyplan:selectowngradables'));
|
|
}
|
|
|
|
/**
|
|
* Get specific contentitem (activity icons) by name
|
|
* @param mixed $name Name of content item
|
|
* @return content_item|null
|
|
*/
|
|
public static function get_contentitem($name) {
|
|
$contentitems = static::get_contentitems();
|
|
for ($i = 0; $i < count($contentitems); $i++) {
|
|
if ($contentitems[$i]->get_name() == $name) {
|
|
return $contentitems[$i];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Construct courseinfo based on course id and
|
|
* @param int $id Course id
|
|
* @param studyitem|null $studyitem Studyitem linking this course (if applicable)
|
|
*/
|
|
public function __construct($id, studyitem $studyitem = null) {
|
|
global $DB;
|
|
$this->studyitem = $studyitem;
|
|
$this->course = \get_course($id);
|
|
$this->context = \context_coursecat::instance($this->course->category);
|
|
$this->coursecontext = \context_course::instance($this->course->id);
|
|
}
|
|
|
|
/**
|
|
* Check if a course with the given ID exists
|
|
* @param int $id Course id
|
|
* @return bool
|
|
*/
|
|
public static function exists($id) {
|
|
global $DB;
|
|
return is_numeric($id) && $DB->record_exists(self::TABLE, ['id' => $id]);
|
|
}
|
|
|
|
/**
|
|
* Find course id from shortname
|
|
* @param string $shortname Shortname of the course
|
|
* @return int Course id
|
|
*/
|
|
public static function id_from_shortname($shortname) {
|
|
global $DB;
|
|
|
|
return $DB->get_field(self::TABLE, "id", ['shortname' => $shortname]);
|
|
}
|
|
|
|
/**
|
|
* Determine course timing [future, present or past] based on a course date
|
|
* @param stdClass $course Course database record
|
|
* @return string 'future', 'present' or 'past'
|
|
*/
|
|
public static function coursetiming($course) {
|
|
$now = time();
|
|
if ($now > $course->startdate) {
|
|
if ($course->enddate > 0 && $now > $course->enddate) {
|
|
return "past";
|
|
} else {
|
|
return "present";
|
|
}
|
|
} else {
|
|
return "future";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determine course timing for this course [future, present or past]
|
|
* @return string 'future', 'present' or 'past'
|
|
*/
|
|
public function timing() {
|
|
return self::coursetiming($this->course);
|
|
}
|
|
|
|
/**
|
|
* Determine proper display name for this course based on config settings, custom fields etc...
|
|
* @return string Display name for the course
|
|
*/
|
|
public function displayname() {
|
|
$displayfield = get_config("local_treestudyplan", "display_field");
|
|
if ($displayfield == "idnumber") {
|
|
$idnumber = trim(preg_replace("/\s+/u", " ", $this->course->idnumber));
|
|
if (strlen($idnumber) > 0) {
|
|
return $this->course->idnumber;
|
|
}
|
|
} else if ($displayfield == "fullname") {
|
|
$fullname = trim(preg_replace("/\s+/u", " ", $this->course->fullname));
|
|
if (strlen($fullname) > 0) {
|
|
return $fullname;
|
|
}
|
|
} else if (strpos( $displayfield , "customfield_") === 0) {
|
|
$fieldname = substr($displayfield, strlen("customfield_"));
|
|
|
|
$handler = \core_customfield\handler::get_handler('core_course', 'course');
|
|
$datas = $handler->get_instance_data($this->course->id);
|
|
foreach ($datas as $data) {
|
|
if ($data->get_field()->get('shortname') == $fieldname) {
|
|
$value = trim(preg_replace("/\s+/u", " ", $data->get_value()));
|
|
if (strlen($value) > 0) {
|
|
return $value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Fallback to shortname when the specified display field fails, since shortname is never empty.
|
|
return $this->course->shortname;
|
|
}
|
|
|
|
/**
|
|
* Webservice structure for basic info
|
|
* @param int $value Webservice requirement constant
|
|
*/
|
|
public static function simple_structure($value = VALUE_REQUIRED) : \external_description {
|
|
return new \external_single_structure([
|
|
"id" => new \external_value(PARAM_INT, 'linked course id'),
|
|
"fullname" => new \external_value(PARAM_TEXT, 'linked course name'),
|
|
"shortname" => new \external_value(PARAM_TEXT, 'linked course shortname'),
|
|
"displayname" => new \external_value(PARAM_TEXT, 'linked course displayname'),
|
|
"context" => contextinfo::structure(VALUE_OPTIONAL),
|
|
], 'referenced course information', $value);
|
|
}
|
|
|
|
/**
|
|
* Webservice model for basic info
|
|
* @return array Webservice data model
|
|
*/
|
|
public function simple_model() {
|
|
$contextinfo = new contextinfo($this->context);
|
|
$info = [
|
|
'id' => $this->course->id,
|
|
'fullname' => $this->course->fullname,
|
|
'shortname' => $this->course->shortname,
|
|
'displayname' => $this->displayname(),
|
|
'context' => $contextinfo->model()
|
|
];
|
|
|
|
return $info;
|
|
}
|
|
|
|
/**
|
|
* Webservice structure for editor info
|
|
* @param int $value Webservice requirement constant
|
|
*/
|
|
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
|
return new \external_single_structure([
|
|
"id" => new \external_value(PARAM_INT, 'linked course id'),
|
|
"fullname" => new \external_value(PARAM_TEXT, 'linked course name'),
|
|
"shortname" => new \external_value(PARAM_TEXT, 'linked course shortname'),
|
|
"displayname" => new \external_value(PARAM_TEXT, 'linked course displayname'),
|
|
"context" => contextinfo::structure(VALUE_OPTIONAL),
|
|
"ctxid" => new \external_value(PARAM_INT, 'course context id name'),
|
|
"grades" => new \external_multiple_structure(gradeinfo::editor_structure(),
|
|
'grade list (legacy list)', VALUE_OPTIONAL),
|
|
"completion" => corecompletioninfo::editor_structure(VALUE_OPTIONAL),
|
|
"competency" => coursecompetencyinfo::editor_structure(VALUE_OPTIONAL),
|
|
"timing" => new \external_value(PARAM_TEXT, '(past|present|future)'),
|
|
"startdate" => new \external_value(PARAM_TEXT, 'Course start date'),
|
|
"enddate" => new \external_value(PARAM_TEXT, 'Course end date'),
|
|
"amteacher" => new \external_value(PARAM_BOOL, 'Requesting user is teacher in this course'),
|
|
"canupdatecourse" => new \external_value(PARAM_BOOL, "If the current user can update this course"),
|
|
"canselectgradables" => new \external_value(PARAM_BOOL, 'Requesting user can change selected gradables'),
|
|
"numenrolled" => new \external_value(PARAM_INT, 'number of students from this studyplan enrolled in the course'),
|
|
"tag" => new \external_value(PARAM_TEXT, 'Tag'),
|
|
"extrafields" => self::extrafields_structure(),
|
|
], 'referenced course information', $value);
|
|
}
|
|
|
|
/**
|
|
* Webservice model for editor info
|
|
* @param studyitem $studyitem Specify a specific study item to check gradable selections for. Leave empty to use default
|
|
* @return array Webservice data model
|
|
*/
|
|
public function editor_model() {
|
|
$contextinfo = new contextinfo($this->context);
|
|
$timing = $this->timing();
|
|
|
|
if (isset($this->studyitem)) {
|
|
$numenrolled = $this->count_enrolled_students($this->studyitem->studyline()->studyplan()->find_linked_userids());
|
|
} else {
|
|
$numenrolled = 0;
|
|
}
|
|
|
|
$info = [
|
|
'id' => $this->course->id,
|
|
'fullname' => $this->course->fullname,
|
|
'shortname' => $this->course->shortname,
|
|
'displayname' => $this->displayname(),
|
|
'context' => $contextinfo->model(),
|
|
'ctxid' => $this->coursecontext->id,
|
|
'timing' => $timing,
|
|
'startdate' => date("Y-m-d", $this->course->startdate),
|
|
'enddate' => date("Y-m-d", $this->course->enddate),
|
|
'amteacher' => $this->am_teacher(),
|
|
'canupdatecourse' => \has_capability("moodle/course:update", $this->coursecontext),
|
|
'canselectgradables' => $this->i_can_select_gradables(),
|
|
'tag' => "Editormodel",
|
|
'extrafields' => $this->extrafields_model(true),
|
|
'grades' => [],
|
|
'numenrolled' => $numenrolled,
|
|
];
|
|
|
|
if (isset($this->studyitem)) {
|
|
$aggregator = $this->studyitem->studyline()->studyplan()->aggregator();
|
|
|
|
if ($aggregator->use_manualactivityselection()) {
|
|
$gradables = gradeinfo::list_course_gradables($this->course, $this->studyitem );
|
|
foreach ($gradables as $gradable) {
|
|
$info['grades'][] = $gradable->editor_model($this->studyitem);
|
|
}
|
|
}
|
|
if ($aggregator->use_corecompletioninfo()) {
|
|
$cc = new corecompletioninfo($this->course, $this->studyitem);
|
|
$studentlist = $this->studyitem->studyline()->studyplan()->find_linked_userids();
|
|
$info['completion'] = $cc->editor_model($studentlist);
|
|
}
|
|
if ($aggregator->use_coursecompetencies()) {
|
|
$ci = new coursecompetencyinfo($this->course, $this->studyitem);
|
|
$studentlist = $this->studyitem->studyline()->studyplan()->find_linked_userids();
|
|
$info['competency'] = $ci->editor_model($studentlist);
|
|
}
|
|
}
|
|
return $info;
|
|
}
|
|
|
|
/**
|
|
* Webservice structure for userinfo
|
|
* @param int $value Webservice requirement constant
|
|
*/
|
|
public static function user_structure($value = VALUE_REQUIRED) : \external_description {
|
|
return new \external_single_structure([
|
|
"id" => new \external_value(PARAM_INT, 'linked course id'),
|
|
"fullname" => new \external_value(PARAM_TEXT, 'linked course name'),
|
|
"shortname" => new \external_value(PARAM_TEXT, 'linked course shortname'),
|
|
"displayname" => new \external_value(PARAM_TEXT, 'linked course displayname'),
|
|
"context" => contextinfo::structure(VALUE_OPTIONAL),
|
|
"ctxid" => new \external_value(PARAM_INT, 'course context id name'),
|
|
"grades" => new \external_multiple_structure(gradeinfo::user_structure(), 'grade list (legacy list)', VALUE_OPTIONAL),
|
|
"completion" => corecompletioninfo::user_structure(VALUE_OPTIONAL),
|
|
"competency" => coursecompetencyinfo::user_structure(VALUE_OPTIONAL),
|
|
"timing" => new \external_value(PARAM_TEXT, '(past|present|future)'),
|
|
"startdate" => new \external_value(PARAM_TEXT, 'Course start date'),
|
|
"enddate" => new \external_value(PARAM_TEXT, 'Course end date'),
|
|
"enrolled" => new \external_value(PARAM_BOOL, 'True if student is enrolled as student in this course'),
|
|
"extrafields" => self::extrafields_structure(),
|
|
"showprogressbar" => new \external_value(PARAM_BOOL, "Whether to show the progress bar in the header"),
|
|
], 'course information', $value);
|
|
}
|
|
|
|
/**
|
|
* List all users enrolled in a course as student by userid
|
|
* @param int $courseid Course id of the course to check
|
|
* @return int[] Array if user ids
|
|
*/
|
|
public static function get_course_students($courseid) : array {
|
|
global $CFG;
|
|
if (!array_key_exists($courseid, self::$coursestudents)) {
|
|
$students = [];
|
|
$context = \context_course::instance($courseid);
|
|
foreach (explode(', ', $CFG->gradebookroles) as $roleid) {
|
|
$roleid = trim($roleid);
|
|
$students = array_keys(get_role_users($roleid, $context, false, 'u.id', 'u.id ASC'));
|
|
}
|
|
self::$coursestudents[$courseid] = $students;
|
|
}
|
|
return self::$coursestudents[$courseid];
|
|
}
|
|
|
|
/**
|
|
* Check if a user is enrolled as a student in this course
|
|
* (Has a gradebook role)
|
|
* @param int $userid The user Id to check
|
|
*/
|
|
public function is_enrolled_student($userid) : bool {
|
|
global $CFG;
|
|
foreach (explode(', ', $CFG->gradebookroles) as $roleid) {
|
|
if (user_has_role_assignment($userid, $roleid, $this->coursecontext->id)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* List how many users from a list also enrolled as students
|
|
* (Has a gradebook role)
|
|
* @param int[] $userids The user Ids to check
|
|
*/
|
|
private function count_enrolled_students(array $userids) {
|
|
$count = 0;
|
|
foreach ($userids as $userid) {
|
|
if ($this->is_enrolled_student($userid)) {
|
|
$count++;
|
|
}
|
|
}
|
|
return $count;
|
|
}
|
|
|
|
/**
|
|
* Webservice model for user info
|
|
* @param int $userid ID of user to check specific info for
|
|
* @return array Webservice data model
|
|
*/
|
|
public function user_model($userid) {
|
|
global $DB;
|
|
$contextinfo = new contextinfo($this->context);
|
|
|
|
$timing = $this->timing();
|
|
|
|
$info = [
|
|
'id' => $this->course->id,
|
|
'fullname' => $this->course->fullname,
|
|
'shortname' => $this->course->shortname,
|
|
'displayname' => $this->displayname(),
|
|
'context' => $contextinfo->model(),
|
|
'ctxid' => $this->coursecontext->id,
|
|
'timing' => $timing,
|
|
'startdate' => date("Y-m-d", $this->course->startdate),
|
|
'enddate' => date("Y-m-d", $this->course->enddate),
|
|
'grades' => [],
|
|
'enrolled' => $this->is_enrolled_student($userid),
|
|
'extrafields' => $this->extrafields_model(),
|
|
'showprogressbar' => get_config("local_treestudyplan","courseprogressbar"),
|
|
];
|
|
|
|
|
|
if (isset($this->studyitem)) {
|
|
$aggregator = $this->studyitem->studyline()->studyplan()->aggregator();
|
|
|
|
if ($aggregator->use_manualactivityselection()) {
|
|
$gradables = gradeinfo::list_studyitem_gradables($this->studyitem);
|
|
foreach ($gradables as $gi) {
|
|
$info['grades'][] = $gi->user_model($userid);
|
|
}
|
|
}
|
|
if ($aggregator->use_corecompletioninfo()) {
|
|
$cc = new corecompletioninfo($this->course, $this->studyitem);
|
|
$info['completion'] = $cc->user_model($userid);
|
|
}
|
|
if ($aggregator->use_coursecompetencies()) {
|
|
$ci = new coursecompetencyinfo($this->course, $this->studyitem);
|
|
$info['competency'] = $ci->user_model($userid);
|
|
}
|
|
}
|
|
return $info;
|
|
}
|
|
|
|
|
|
/**
|
|
* Webservice structure for extra fields
|
|
* @param int $value Webservice requirement constant
|
|
*/
|
|
public static function extrafields_structure($value = VALUE_REQUIRED) : \external_description {
|
|
return new \external_multiple_structure(new \external_single_structure([
|
|
"title" => new \external_value(PARAM_RAW, 'title'),
|
|
"value" => new \external_value(PARAM_RAW, 'value'),
|
|
"position" => new \external_value(PARAM_TEXT, 'position'),
|
|
"type" => new \external_value(PARAM_TEXT, 'value type'),
|
|
"fieldname" => new \external_value(PARAM_TEXT, 'field name'),
|
|
"checked" => new \external_value(PARAM_BOOL, 'checkbox value',VALUE_OPTIONAL),
|
|
"courseid" => new \external_value(PARAM_TEXT, 'course id number'),
|
|
], 'referenced course information'), $value);
|
|
}
|
|
|
|
/**
|
|
* Webservice model for basic info
|
|
* @param $includeteachervisible Include custom fiel
|
|
* @return array Webservice data model
|
|
*/
|
|
public function extrafields_model($includeteachervisible=false) {
|
|
$list = [];
|
|
for ($i=1; $i <= 5; $i++) {
|
|
$field = get_config('local_treestudyplan','courseinfo'.$i.'_field');
|
|
if ($field) {
|
|
$title = self::extrafields_localize_title(get_config('local_treestudyplan','courseinfo'.$i.'_title'));
|
|
$pos = get_config('local_treestudyplan','courseinfo'.$i.'_position');
|
|
[$value,$type, $raw] = $this->extrafields_value($field,$includeteachervisible);
|
|
if ($type) {
|
|
$list[] = [
|
|
"title" => $title,
|
|
"value" => $value,
|
|
"position" => $pos,
|
|
"type" => $type,
|
|
"fieldname" => $field,
|
|
"courseid" => $this->course->id,
|
|
"checked" => ($type=="checkbox")?($raw?true:false):null,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
return $list;
|
|
}
|
|
|
|
protected static function extrafields_localize_title($field) {
|
|
$lang = trim(current_language());
|
|
$lines = explode("\n",$field);
|
|
$title = "";
|
|
$fallback = ""; // Fallback to first title
|
|
foreach ($lines as $l) {
|
|
$parts = explode("|",$l,2);
|
|
if (count($parts) > 0) {
|
|
// Set the first line as fallback.
|
|
if (empty($firsttitle) && !empty($parts[0])) {
|
|
$fallback = $parts[0];
|
|
}
|
|
if (count($parts) == 1 && empty($title)) {
|
|
// Set line without language as default if no localized line found
|
|
$title = trim($parts[0]);
|
|
} else if (trim($parts[1]) == $lang) {
|
|
return trim($parts[0]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return default title or fall back to first localizef title.
|
|
return (strlen($title) > 0)?$title:$fallback;
|
|
}
|
|
|
|
/**
|
|
* Determine value and type of an extra field for this course
|
|
* @return array [value,type] of the field for this
|
|
*/
|
|
protected function extrafields_value($fieldname,$includeteachervisible=false) {
|
|
|
|
if ($fieldname == "description") {
|
|
// Process embedded files.
|
|
$value = \file_rewrite_pluginfile_urls(
|
|
// The description content
|
|
$this->course()->summary,
|
|
// The pluginfile URL which will serve the request.
|
|
'pluginfile.php',
|
|
// The combination of contextid / component / filearea / itemid
|
|
// form the virtual bucket that file are stored in.
|
|
$this->coursecontext->id, // System instance is always used for this
|
|
'course',
|
|
'summary',
|
|
''
|
|
);
|
|
return [$value, "textarea", $this->course()->summary];
|
|
} else if ($fieldname == "idnumber") {
|
|
$idnumber = trim(preg_replace("/\s+/u", " ", $this->course->idnumber));
|
|
return [$idnumber, "text", $this->course->idnumber];
|
|
} else if ($fieldname == "contacts") {
|
|
$cle = new \core_course_list_element($this->course());
|
|
$contacts = $cle->get_course_contacts();
|
|
$value = "";
|
|
foreach ($contacts as $uid => $contact) {
|
|
if(strlen($value) > 0) {
|
|
$value .= ", ";
|
|
}
|
|
$value .= $contact["username"];
|
|
}
|
|
if (empty($value)) {
|
|
$value = get_string("none");
|
|
}
|
|
return [$value, "text", $value];
|
|
} else if (strpos( $fieldname , "customfield_") === 0) {
|
|
$fieldshortname = substr($fieldname, strlen("customfield_"));
|
|
|
|
$handler = \core_customfield\handler::get_handler('core_course', 'course');
|
|
$datas = $handler->get_instance_data($this->course->id);
|
|
foreach ($datas as $data) {
|
|
$field = $data->get_field();
|
|
$fshortname = $field->get('shortname');
|
|
if ($fshortname == $fieldshortname) {
|
|
$visibility = $field->get_configdata_property("visibility");
|
|
$raw = $data->get_value();
|
|
$type = $field->get('type');
|
|
|
|
// Only show if visibility is "Everyone" or ("Teachers" and in teacher view )
|
|
if ($visibility > 0 && ($visibility == 2 || $includeteachervisible)) {
|
|
if ($type == "date") {
|
|
// Date should be converted to YYYY-MM-DD so the javascript can properly format it.
|
|
if ($raw == 0) {
|
|
$value = "";
|
|
} else {
|
|
// Convert to YYYY-MM-DD format.
|
|
$value = date("Y-m-d", $raw);
|
|
}
|
|
} else {
|
|
// Everything else can just use the export value.
|
|
$value = $data->export_value();
|
|
}
|
|
|
|
return [$value,$type,$raw];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Fallback to empty if finding a match fails.
|
|
return [null,null,null];
|
|
}
|
|
}
|