Actualización
This commit is contained in:
38
main/gradebook/lib/be/PortfolioLink.php
Normal file
38
main/gradebook/lib/be/PortfolioLink.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class PortfolioLink.
|
||||
*/
|
||||
class PortfolioLink extends EvalLink
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->set_type(LINK_PORTFOLIO);
|
||||
}
|
||||
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('Portfolio');
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'portfolio';
|
||||
}
|
||||
|
||||
protected function get_evaluation()
|
||||
{
|
||||
$this->evaluation = parent::get_evaluation();
|
||||
$this->evaluation->set_type('portfolio');
|
||||
|
||||
return $this->evaluation;
|
||||
}
|
||||
}
|
||||
803
main/gradebook/lib/be/abstractlink.class.php
Normal file
803
main/gradebook/lib/be/abstractlink.class.php
Normal file
@@ -0,0 +1,803 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\GradebookLink;
|
||||
|
||||
/**
|
||||
* Class AbstractLink
|
||||
* Defines a gradebook AbstractLink object.
|
||||
* To implement specific links,
|
||||
* extend this class and define a type in LinkFactory.
|
||||
* Use the methods in LinkFactory to create link objects.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
* @author Julio Montoya <gugli100@gmail.com> security improvements
|
||||
*/
|
||||
abstract class AbstractLink implements GradebookItem
|
||||
{
|
||||
public $course_id;
|
||||
public $studentList;
|
||||
/** @var GradebookLink */
|
||||
public $entity;
|
||||
protected $id;
|
||||
protected $type;
|
||||
protected $ref_id;
|
||||
protected $user_id;
|
||||
protected $course_code;
|
||||
/** @var Category */
|
||||
protected $category;
|
||||
protected $created_at;
|
||||
protected $weight;
|
||||
protected $visible;
|
||||
protected $session_id;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->course_id = api_get_course_int_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function has_results();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function get_link();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function is_valid_link();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function get_type_name();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function needs_name_and_description();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function needs_max();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function needs_results();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function is_allowed_to_change_name();
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_id()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_ref_id()
|
||||
{
|
||||
return (int) $this->ref_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_session_id()
|
||||
{
|
||||
return (int) $this->session_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_user_id()
|
||||
{
|
||||
return $this->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_course_code()
|
||||
{
|
||||
return $this->course_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Category
|
||||
*/
|
||||
public function getCategory()
|
||||
{
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*/
|
||||
public function setCategory($category)
|
||||
{
|
||||
$this->category = $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_category_id()
|
||||
{
|
||||
return $this->category->get_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $category_id
|
||||
*/
|
||||
public function set_category_id($category_id)
|
||||
{
|
||||
$categories = Category::load($category_id);
|
||||
if (isset($categories[0])) {
|
||||
$this->setCategory($categories[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public function get_date()
|
||||
{
|
||||
return $this->created_at;
|
||||
}
|
||||
|
||||
public function get_weight()
|
||||
{
|
||||
return $this->weight;
|
||||
}
|
||||
|
||||
public function is_locked()
|
||||
{
|
||||
return isset($this->locked) && 1 == $this->locked ? true : false;
|
||||
}
|
||||
|
||||
public function is_visible()
|
||||
{
|
||||
return $this->visible;
|
||||
}
|
||||
|
||||
public function set_id($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function set_type($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function set_ref_id($ref_id)
|
||||
{
|
||||
$this->ref_id = $ref_id;
|
||||
}
|
||||
|
||||
public function set_user_id($user_id)
|
||||
{
|
||||
$this->user_id = $user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $course_code
|
||||
*/
|
||||
public function set_course_code($course_code)
|
||||
{
|
||||
$courseInfo = api_get_course_info($course_code);
|
||||
if ($courseInfo) {
|
||||
$this->course_code = $course_code;
|
||||
$this->course_id = $courseInfo['real_id'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getStudentList()
|
||||
{
|
||||
if (empty($this->studentList)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->studentList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $list
|
||||
*/
|
||||
public function setStudentList($list)
|
||||
{
|
||||
$this->studentList = $list;
|
||||
}
|
||||
|
||||
public function set_date($date)
|
||||
{
|
||||
$this->created_at = $date;
|
||||
}
|
||||
|
||||
public function set_weight($weight)
|
||||
{
|
||||
$this->weight = $weight;
|
||||
}
|
||||
|
||||
public function set_visible($visible)
|
||||
{
|
||||
$this->visible = $visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*/
|
||||
public function set_session_id($id)
|
||||
{
|
||||
$this->session_id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $locked
|
||||
*/
|
||||
public function set_locked($locked)
|
||||
{
|
||||
$this->locked = $locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCourseId()
|
||||
{
|
||||
return (int) $this->course_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve links and return them as an array of extensions of AbstractLink.
|
||||
* To keep consistency, do not call this method but LinkFactory::load instead.
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $type
|
||||
* @param int $ref_id
|
||||
* @param int $user_id
|
||||
* @param string $course_code
|
||||
* @param int $category_id
|
||||
* @param int $visible
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function load(
|
||||
$id = null,
|
||||
$type = null,
|
||||
$ref_id = null,
|
||||
$user_id = null,
|
||||
$course_code = null,
|
||||
$category_id = null,
|
||||
$visible = null
|
||||
) {
|
||||
$tbl_grade_links = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$sql = 'SELECT * FROM '.$tbl_grade_links;
|
||||
$paramcount = 0;
|
||||
if (isset($id)) {
|
||||
$sql .= ' WHERE id = '.intval($id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($type)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' type = '.intval($type);
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($ref_id)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' ref_id = '.intval($ref_id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($user_id)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' user_id = '.intval($user_id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($course_code)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= " course_code = '".Database::escape_string($course_code)."'";
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($category_id)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' category_id = '.intval($category_id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($visible)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' visible = '.intval($visible);
|
||||
}
|
||||
|
||||
$result = Database::query($sql);
|
||||
$links = self::create_objects_from_sql_result($result);
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert this link into the database.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->add_linked_data();
|
||||
if (isset($this->type) &&
|
||||
isset($this->ref_id) &&
|
||||
isset($this->user_id) &&
|
||||
isset($this->course_code) &&
|
||||
isset($this->category) &&
|
||||
isset($this->weight) &&
|
||||
isset($this->visible)
|
||||
) {
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$sql = "SELECT count(*) count FROM $table
|
||||
WHERE
|
||||
ref_id = ".$this->get_ref_id()." AND
|
||||
category_id = ".$this->category->get_id()." AND
|
||||
course_code = '".$this->course_code."' AND
|
||||
type = ".$this->type;
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result, 'ASSOC');
|
||||
|
||||
if ($row['count'] == 0) {
|
||||
$params = [
|
||||
'type' => $this->get_type(),
|
||||
'ref_id' => $this->get_ref_id(),
|
||||
'user_id' => $this->get_user_id(),
|
||||
'course_code' => $this->get_course_code(),
|
||||
'category_id' => $this->get_category_id(),
|
||||
'weight' => $this->get_weight(),
|
||||
'visible' => $this->is_visible(),
|
||||
'created_at' => api_get_utc_datetime(),
|
||||
'locked' => 0,
|
||||
];
|
||||
$id = Database::insert($table, $params);
|
||||
$this->set_id($id);
|
||||
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the properties of this link in the database.
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$em = Database::getManager();
|
||||
|
||||
$link = $em->find('ChamiloCoreBundle:GradebookLink', $this->id);
|
||||
|
||||
if (!$link) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::add_link_log($this->id);
|
||||
|
||||
$this->save_linked_data();
|
||||
|
||||
$link
|
||||
->setType($this->get_type())
|
||||
->setRefId($this->get_ref_id())
|
||||
->setUserId($this->get_user_id())
|
||||
->setCourseCode($this->get_course_code())
|
||||
->setCategoryId($this->get_category_id())
|
||||
->setWeight($this->get_weight())
|
||||
->setVisible($this->is_visible());
|
||||
|
||||
$em->merge($link);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $evaluationId
|
||||
*/
|
||||
public static function add_link_log($evaluationId, $nameLog = null)
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG);
|
||||
$dateobject = self::load($evaluationId, null, null, null, null);
|
||||
$now = api_get_utc_datetime();
|
||||
$arreval = get_object_vars($dateobject[0]);
|
||||
$description_log = isset($arreval['description']) ? $arreval['description'] : '';
|
||||
if (empty($nameLog)) {
|
||||
if (isset($_POST['name_link'])) {
|
||||
$name_log = isset($_POST['name_link']) ? $_POST['name_link'] : $arreval['course_code'];
|
||||
} elseif (isset($_POST['link_'.$evaluationId]) && $_POST['link_'.$evaluationId]) {
|
||||
$name_log = $_POST['link_'.$evaluationId];
|
||||
} else {
|
||||
$name_log = $arreval['course_code'];
|
||||
}
|
||||
} else {
|
||||
$name_log = $nameLog;
|
||||
}
|
||||
|
||||
$params = [
|
||||
'id_linkeval_log' => $arreval['id'],
|
||||
'name' => $name_log,
|
||||
'description' => $description_log,
|
||||
'created_at' => $now,
|
||||
'weight' => $arreval['weight'],
|
||||
'visible' => $arreval['visible'],
|
||||
'type' => 'Link',
|
||||
'user_id_log' => api_get_user_id(),
|
||||
];
|
||||
Database::insert($table, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this link from the database.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->delete_linked_data();
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$sql = 'DELETE FROM '.$table.'
|
||||
WHERE id = '.intval($this->id);
|
||||
Database::query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of possible categories where this link can be moved to.
|
||||
* Notice: its own parent will be included in the list: it's up to the frontend
|
||||
* to disable this element.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 3 subelements (id, name, level)
|
||||
*/
|
||||
public function get_target_categories()
|
||||
{
|
||||
// links can only be moved to categories inside this course
|
||||
$targets = [];
|
||||
$level = 0;
|
||||
$categories = Category::load(null, null, $this->get_course_code(), 0);
|
||||
foreach ($categories as $cat) {
|
||||
$targets[] = [$cat->get_id(), $cat->get_name(), $level + 1];
|
||||
$targets = $this->addTargetSubcategories(
|
||||
$targets,
|
||||
$level + 1,
|
||||
$cat->get_id()
|
||||
);
|
||||
}
|
||||
|
||||
return $targets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this link to the given category.
|
||||
* If this link moves to outside a course, delete it.
|
||||
*/
|
||||
public function move_to_cat($cat)
|
||||
{
|
||||
if ($this->get_course_code() != $cat->get_course_code()) {
|
||||
$this->delete();
|
||||
} else {
|
||||
$this->set_category_id($cat->get_id());
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find links by name
|
||||
* To keep consistency, do not call this method but LinkFactory::find_links instead.
|
||||
*
|
||||
* @todo can be written more efficiently using a new (but very complex) sql query
|
||||
*
|
||||
* @param string $name_mask
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function find_links($name_mask, $selectcat)
|
||||
{
|
||||
$rootcat = Category::load($selectcat);
|
||||
$links = $rootcat[0]->get_links((api_is_allowed_to_edit() ? null : api_get_user_id()), true);
|
||||
$foundlinks = [];
|
||||
foreach ($links as $link) {
|
||||
if (!(api_strpos(api_strtolower($link->get_name()), api_strtolower($name_mask)) === false)) {
|
||||
$foundlinks[] = $link;
|
||||
}
|
||||
}
|
||||
|
||||
return $foundlinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_item_type()
|
||||
{
|
||||
return 'L';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'link';
|
||||
}
|
||||
|
||||
public function get_all_links()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function add_linked_data()
|
||||
{
|
||||
}
|
||||
|
||||
public function save_linked_data()
|
||||
{
|
||||
}
|
||||
|
||||
public function delete_linked_data()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function set_name($name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*/
|
||||
public function set_description($description)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $max
|
||||
*/
|
||||
public function set_max($max)
|
||||
{
|
||||
}
|
||||
|
||||
public function get_view_url($stud_id)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks a link.
|
||||
*
|
||||
* @param int $locked 1 or unlocked 0
|
||||
*
|
||||
* */
|
||||
public function lock($locked)
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$sql = "UPDATE $table SET locked = '".intval($locked)."'
|
||||
WHERE id='".$this->id."'";
|
||||
Database::query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current user ranking.
|
||||
*
|
||||
* @param int $userId
|
||||
* @param array $studentList Array with user id and scores
|
||||
* Example: [1 => 5.00, 2 => 8.00]
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getCurrentUserRanking($userId, $studentList)
|
||||
{
|
||||
$ranking = null;
|
||||
$currentUserId = $userId;
|
||||
if (!empty($studentList) && !empty($currentUserId)) {
|
||||
$studentList = array_map('floatval', $studentList);
|
||||
asort($studentList);
|
||||
$ranking = $count = count($studentList);
|
||||
|
||||
foreach ($studentList as $userId => $position) {
|
||||
if ($currentUserId == $userId) {
|
||||
break;
|
||||
}
|
||||
$ranking--;
|
||||
}
|
||||
|
||||
// If no ranking was detected.
|
||||
if ($ranking == 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [$ranking, $count];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSkillsFromItem()
|
||||
{
|
||||
$toolType = '';
|
||||
switch ($this->type) {
|
||||
case LINK_ATTENDANCE:
|
||||
$toolType = ITEM_TYPE_ATTENDANCE;
|
||||
break;
|
||||
case LINK_EXERCISE:
|
||||
$toolType = ITEM_TYPE_EXERCISE;
|
||||
break;
|
||||
case LINK_FORUM_THREAD:
|
||||
$toolType = ITEM_TYPE_FORUM_THREAD;
|
||||
break;
|
||||
case LINK_LEARNPATH:
|
||||
$toolType = ITEM_TYPE_LEARNPATH;
|
||||
break;
|
||||
case LINK_HOTPOTATOES:
|
||||
$toolType = ITEM_TYPE_HOTPOTATOES;
|
||||
break;
|
||||
case LINK_STUDENTPUBLICATION:
|
||||
$toolType = ITEM_TYPE_STUDENT_PUBLICATION;
|
||||
break;
|
||||
case LINK_SURVEY:
|
||||
$toolType = ITEM_TYPE_SURVEY;
|
||||
break;
|
||||
case LINK_PORTFOLIO:
|
||||
$toolType = ITEM_TYPE_PORTFOLIO;
|
||||
break;
|
||||
}
|
||||
|
||||
$skillToString = Skill::getSkillRelItemsToString($toolType, $this->get_ref_id());
|
||||
|
||||
return $skillToString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $itemId
|
||||
* @param int $linkType
|
||||
* @param string $courseCode
|
||||
* @param int $sessionId
|
||||
*
|
||||
* @return array|bool|\Doctrine\DBAL\Driver\Statement
|
||||
*/
|
||||
public static function getGradebookLinksFromItem($itemId, $linkType, $courseCode, $sessionId = 0)
|
||||
{
|
||||
if (empty($courseCode) || empty($itemId) || empty($linkType)) {
|
||||
return false;
|
||||
}
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$tableCategory = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
|
||||
$itemId = (int) $itemId;
|
||||
$linkType = (int) $linkType;
|
||||
$sessionId = (int) $sessionId;
|
||||
|
||||
$sessionCondition = api_get_session_condition($sessionId, true, false, 'c.session_id');
|
||||
$courseCode = Database::escape_string($courseCode);
|
||||
|
||||
$sql = "SELECT DISTINCT l.*
|
||||
FROM $table l INNER JOIN $tableCategory c
|
||||
ON (c.course_code = l.course_code AND c.id = l.category_id)
|
||||
WHERE
|
||||
ref_id = $itemId AND
|
||||
type = $linkType AND
|
||||
l.course_code = '$courseCode'
|
||||
$sessionCondition ";
|
||||
|
||||
$result = Database::query($sql);
|
||||
if (Database::num_rows($result)) {
|
||||
$result = Database::store_result($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Doctrine\DBAL\Driver\Statement|null $result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function create_objects_from_sql_result($result)
|
||||
{
|
||||
$links = [];
|
||||
$allow = api_get_configuration_value('allow_gradebook_stats');
|
||||
if ($allow) {
|
||||
$em = Database::getManager();
|
||||
$repo = $em->getRepository('ChamiloCoreBundle:GradebookLink');
|
||||
}
|
||||
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
$link = LinkFactory::create($data['type']);
|
||||
$link->set_id($data['id']);
|
||||
$link->set_type($data['type']);
|
||||
$link->set_ref_id($data['ref_id']);
|
||||
$link->set_user_id($data['user_id']);
|
||||
$link->set_course_code($data['course_code']);
|
||||
$link->set_category_id($data['category_id']);
|
||||
$link->set_date($data['created_at']);
|
||||
$link->set_weight($data['weight']);
|
||||
$link->set_visible($data['visible']);
|
||||
$link->set_locked($data['locked']);
|
||||
|
||||
//session id should depend of the category --> $data['category_id']
|
||||
$session_id = api_get_session_id();
|
||||
$link->set_session_id($session_id);
|
||||
|
||||
if ($allow) {
|
||||
$link->entity = $repo->find($data['id']);
|
||||
}
|
||||
$links[] = $link;
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function used by get_target_categories().
|
||||
*
|
||||
* @param array $targets
|
||||
* @param int $level
|
||||
* @param int $catid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function addTargetSubcategories($targets, $level, $catid)
|
||||
{
|
||||
$subcats = Category::load(null, null, null, $catid);
|
||||
foreach ($subcats as $cat) {
|
||||
$targets[] = [$cat->get_id(), $cat->get_name(), $level + 1];
|
||||
$targets = $this->addTargetSubcategories(
|
||||
$targets,
|
||||
$level + 1,
|
||||
$cat->get_id()
|
||||
);
|
||||
}
|
||||
|
||||
return $targets;
|
||||
}
|
||||
}
|
||||
276
main/gradebook/lib/be/attendancelink.class.php
Normal file
276
main/gradebook/lib/be/attendancelink.class.php
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Gradebook link to attendance item.
|
||||
*
|
||||
* @author Christian Fasanando (christian1827@gmail.com)
|
||||
*/
|
||||
class AttendanceLink extends AbstractLink
|
||||
{
|
||||
private $attendance_table = null;
|
||||
private $itemprop_table = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_ATTENDANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('Attendance');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of all attendances available.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links()
|
||||
{
|
||||
if (empty($this->course_code)) {
|
||||
return [];
|
||||
}
|
||||
$tbl_attendance = $this->get_attendance_table();
|
||||
$sessionId = $this->get_session_id();
|
||||
|
||||
$sql = 'SELECT att.id, att.name, att.attendance_qualify_title
|
||||
FROM '.$tbl_attendance.' att
|
||||
WHERE
|
||||
att.c_id = '.$this->course_id.' AND
|
||||
att.active = 1 AND
|
||||
att.session_id = '.$sessionId;
|
||||
|
||||
$result = Database::query($sql);
|
||||
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
if (isset($data['attendance_qualify_title']) && '' != $data['attendance_qualify_title']) {
|
||||
$cats[] = [$data['id'], $data['attendance_qualify_title']];
|
||||
} else {
|
||||
$cats[] = [$data['id'], $data['name']];
|
||||
}
|
||||
}
|
||||
$my_cats = isset($cats) ? $cats : [];
|
||||
|
||||
return $my_cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone done this exercise yet ?
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT);
|
||||
$sessionId = $this->get_session_id();
|
||||
|
||||
$sql = 'SELECT count(*) AS number FROM '.$tbl_attendance_result."
|
||||
WHERE
|
||||
session_id = $sessionId AND
|
||||
c_id = '.$this->course_id.' AND
|
||||
attendance_id = '".$this->get_ref_id()."'";
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $stud_id
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
$tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT);
|
||||
$sessionId = $this->get_session_id();
|
||||
|
||||
// get attendance qualify max
|
||||
$sql = 'SELECT att.attendance_qualify_max
|
||||
FROM '.$this->get_attendance_table().' att
|
||||
WHERE
|
||||
att.c_id = '.$this->course_id.' AND
|
||||
att.id = '.$this->get_ref_id().' AND
|
||||
att.session_id = '.$sessionId;
|
||||
$query = Database::query($sql);
|
||||
$attendance = Database::fetch_array($query, 'ASSOC');
|
||||
|
||||
// Get results
|
||||
$sql = 'SELECT *
|
||||
FROM '.$tbl_attendance_result.'
|
||||
WHERE c_id = '.$this->course_id.' AND attendance_id = '.$this->get_ref_id();
|
||||
if (isset($stud_id)) {
|
||||
$sql .= ' AND user_id = '.intval($stud_id);
|
||||
}
|
||||
$scores = Database::query($sql);
|
||||
// for 1 student
|
||||
if (isset($stud_id)) {
|
||||
if ($data = Database::fetch_array($scores, 'ASSOC')) {
|
||||
return [
|
||||
$data['score'],
|
||||
$attendance['attendance_qualify_max'],
|
||||
];
|
||||
} else {
|
||||
//We sent the 0/attendance_qualify_max instead of null for correct calculations
|
||||
return [0, $attendance['attendance_qualify_max']];
|
||||
}
|
||||
} else {
|
||||
// all students -> get average
|
||||
$students = []; // user list, needed to make sure we only
|
||||
// take first attempts into account
|
||||
$rescount = 0;
|
||||
$sum = 0;
|
||||
$sumResult = 0;
|
||||
$bestResult = 0;
|
||||
|
||||
while ($data = Database::fetch_array($scores)) {
|
||||
if (!(array_key_exists($data['user_id'], $students))) {
|
||||
if (0 != $attendance['attendance_qualify_max']) {
|
||||
$students[$data['user_id']] = $data['score'];
|
||||
$rescount++;
|
||||
$sum += $data['score'] / $attendance['attendance_qualify_max'];
|
||||
$sumResult += $data['score'];
|
||||
if ($data['score'] > $bestResult) {
|
||||
$bestResult = $data['score'];
|
||||
}
|
||||
$weight = $attendance['attendance_qualify_max'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == $rescount) {
|
||||
return [null, null];
|
||||
} else {
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
return [$bestResult, $weight];
|
||||
break;
|
||||
case 'average':
|
||||
return [$sumResult / $rescount, $weight];
|
||||
break;
|
||||
case 'ranking':
|
||||
return AbstractLink::getCurrentUserRanking($stud_id, $students);
|
||||
break;
|
||||
default:
|
||||
return [$sum, $rescount];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$this->get_attendance_data();
|
||||
$attendance_title = isset($this->attendance_data['name']) ? $this->attendance_data['name'] : '';
|
||||
$attendance_qualify_title = isset($this->attendance_data['attendance_qualify_title']) ? $this->attendance_data['attendance_qualify_title'] : '';
|
||||
if (isset($attendance_qualify_title) && '' != $attendance_qualify_title) {
|
||||
return $this->attendance_data['attendance_qualify_title'];
|
||||
} else {
|
||||
return $attendance_title;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_description()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this still links to an exercise.
|
||||
*/
|
||||
public function is_valid_link()
|
||||
{
|
||||
$sql = 'SELECT count(att.id) FROM '.$this->get_attendance_table().' att
|
||||
WHERE att.c_id = '.$this->course_id.' AND att.id = '.$this->get_ref_id();
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
// it was extracts the attendance id
|
||||
$sessionId = $this->get_session_id();
|
||||
$sql = 'SELECT * FROM '.$this->get_attendance_table().' att
|
||||
WHERE att.c_id = '.$this->course_id.' AND att.id = '.$this->get_ref_id();
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result, 'ASSOC');
|
||||
$attendance_id = $row['id'];
|
||||
$url = api_get_path(WEB_PATH).'main/attendance/index.php?action=attendance_sheet_list&gradebook=view&attendance_id='.$attendance_id.'&'.api_get_cidreq_params($this->get_course_code(), $sessionId);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'attendance';
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the student publications.
|
||||
*/
|
||||
private function get_attendance_table()
|
||||
{
|
||||
$this->attendance_table = Database::get_course_table(TABLE_ATTENDANCE);
|
||||
|
||||
return $this->attendance_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|bool
|
||||
*/
|
||||
private function get_attendance_data()
|
||||
{
|
||||
$tbl_name = $this->get_attendance_table();
|
||||
if ('' == $tbl_name) {
|
||||
return false;
|
||||
} elseif (!isset($this->attendance_data)) {
|
||||
$sql = 'SELECT * FROM '.$this->get_attendance_table().' att
|
||||
WHERE att.c_id = '.$this->course_id.' AND att.id = '.$this->get_ref_id();
|
||||
$query = Database::query($sql);
|
||||
$this->attendance_data = Database::fetch_array($query);
|
||||
}
|
||||
|
||||
return $this->attendance_data;
|
||||
}
|
||||
}
|
||||
2889
main/gradebook/lib/be/category.class.php
Normal file
2889
main/gradebook/lib/be/category.class.php
Normal file
File diff suppressed because it is too large
Load Diff
70
main/gradebook/lib/be/dropboxlink.class.php
Normal file
70
main/gradebook/lib/be/dropboxlink.class.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Gradebook link to dropbox item.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class DropboxLink extends EvalLink
|
||||
{
|
||||
private $dropbox_table = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_DROPBOX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of a document
|
||||
* This function is loaded when using a gradebook as a tab (gradebook = -1) see issue #2705.
|
||||
*/
|
||||
public function get_view_url($stud_id)
|
||||
{
|
||||
// find a file uploaded by the given student,
|
||||
// with the same title as the evaluation name
|
||||
|
||||
$eval = $this->get_evaluation();
|
||||
$sql = 'SELECT filename FROM '.$this->get_dropbox_table().'
|
||||
WHERE
|
||||
c_id = '.$this->course_id.' AND
|
||||
uploader_id = '.intval($stud_id)." AND
|
||||
title = '".Database::escape_string($eval->get_name())."'";
|
||||
|
||||
$result = Database::query($sql);
|
||||
if ($fileurl = Database::fetch_row($result)) {
|
||||
return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('LMSDropbox');
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'dropbox';
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the dropbox database table.
|
||||
*/
|
||||
private function get_dropbox_table()
|
||||
{
|
||||
$this->dropbox_table = Database::get_course_table(TABLE_DROPBOX_FILE);
|
||||
|
||||
return $this->dropbox_table;
|
||||
}
|
||||
}
|
||||
187
main/gradebook/lib/be/evallink.class.php
Normal file
187
main/gradebook/lib/be/evallink.class.php
Normal file
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class to be used as basis for links referring to Evaluation objects.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
abstract class EvalLink extends AbstractLink
|
||||
{
|
||||
protected $evaluation;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return $eval->has_results();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param string $type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function calc_score($userId = null, $type = null)
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return $eval->calc_score($userId, $type);
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
// course/platform admin can go to the view_results page
|
||||
if (api_is_allowed_to_edit()) {
|
||||
return 'gradebook_view_result.php?'.api_get_cidreq().'&selecteval='.$eval->get_id();
|
||||
} elseif (ScoreDisplay::instance()->is_custom()) {
|
||||
// students can go to the statistics page (if custom display enabled)
|
||||
|
||||
return 'gradebook_statistics.php?'.api_get_cidreq().'&selecteval='.$eval->get_id();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return $eval->get_name();
|
||||
}
|
||||
|
||||
public function get_description()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return $eval->get_description();
|
||||
}
|
||||
|
||||
public function get_max()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return $eval->get_max();
|
||||
}
|
||||
|
||||
public function is_valid_link()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return isset($eval);
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function add_linked_data()
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->add();
|
||||
$this->set_ref_id($this->evaluation->get_id());
|
||||
}
|
||||
}
|
||||
|
||||
public function save_linked_data()
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function delete_linked_data()
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->delete_with_results();
|
||||
}
|
||||
}
|
||||
|
||||
public function set_name($name)
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_name($name);
|
||||
}
|
||||
}
|
||||
|
||||
public function set_description($description)
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_description($description);
|
||||
}
|
||||
}
|
||||
|
||||
public function set_max($max)
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_max($max);
|
||||
}
|
||||
}
|
||||
|
||||
// Functions overriding non-trivial implementations from AbstractLink
|
||||
public function set_date($date)
|
||||
{
|
||||
$this->created_at = $date;
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_date($date);
|
||||
}
|
||||
}
|
||||
|
||||
public function set_weight($weight)
|
||||
{
|
||||
$this->weight = $weight;
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_weight($weight);
|
||||
}
|
||||
}
|
||||
|
||||
public function set_visible($visible)
|
||||
{
|
||||
$this->visible = $visible;
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_visible($visible);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the linked evaluation.
|
||||
*/
|
||||
protected function get_evaluation()
|
||||
{
|
||||
if (!isset($this->evaluation)) {
|
||||
if (isset($this->ref_id)) {
|
||||
$evalarray = Evaluation::load($this->get_ref_id());
|
||||
$this->evaluation = $evalarray[0];
|
||||
} else {
|
||||
$eval = new Evaluation();
|
||||
$eval->set_category_id(-1);
|
||||
$eval->set_date(api_get_utc_datetime()); // these values will be changed
|
||||
$eval->set_weight(0); // when the link setter
|
||||
$eval->set_visible(0); // is called
|
||||
$eval->set_id(-1); // a 'real' id will be set when eval is added to db
|
||||
$eval->set_user_id($this->get_user_id());
|
||||
$eval->set_course_code($this->get_course_code());
|
||||
$this->evaluation = $eval;
|
||||
$this->set_ref_id($eval->get_id());
|
||||
}
|
||||
}
|
||||
|
||||
return $this->evaluation;
|
||||
}
|
||||
}
|
||||
1000
main/gradebook/lib/be/evaluation.class.php
Normal file
1000
main/gradebook/lib/be/evaluation.class.php
Normal file
File diff suppressed because it is too large
Load Diff
676
main/gradebook/lib/be/exerciselink.class.php
Normal file
676
main/gradebook/lib/be/exerciselink.class.php
Normal file
@@ -0,0 +1,676 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class ExerciseLink
|
||||
* Defines a gradebook ExerciseLink object.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class ExerciseLink extends AbstractLink
|
||||
{
|
||||
// This variable is used in the WSGetGradebookUserItemScore service, to check base course tests.
|
||||
public $checkBaseExercises = false;
|
||||
private $course_info;
|
||||
private $exercise_table;
|
||||
private $exercise_data = [];
|
||||
private $is_hp;
|
||||
|
||||
/**
|
||||
* @param int $hp
|
||||
*/
|
||||
public function __construct($hp = 0)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_EXERCISE);
|
||||
$this->is_hp = $hp;
|
||||
if (1 == $this->is_hp) {
|
||||
$this->set_type(LINK_HOTPOTATOES);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of all exercises available.
|
||||
*
|
||||
* @param bool $getOnlyHotPotatoes
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links($getOnlyHotPotatoes = false)
|
||||
{
|
||||
$TBL_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT);
|
||||
$tableItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
|
||||
$exerciseTable = $this->get_exercise_table();
|
||||
$lpItemTable = Database::get_course_table(TABLE_LP_ITEM);
|
||||
$lpTable = Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
$documentPath = api_get_path(SYS_COURSE_PATH).$this->course_code.'/document';
|
||||
if (empty($this->course_code)) {
|
||||
return [];
|
||||
}
|
||||
$sessionId = $this->get_session_id();
|
||||
if (empty($sessionId)) {
|
||||
$session_condition = api_get_session_condition(0, true, false, 'e.session_id');
|
||||
} else {
|
||||
$session_condition = api_get_session_condition($sessionId, true, true, 'e.session_id');
|
||||
}
|
||||
|
||||
// @todo
|
||||
$uploadPath = null;
|
||||
$courseId = $this->course_id;
|
||||
|
||||
$sql = "SELECT iid, title FROM $exerciseTable e
|
||||
WHERE
|
||||
c_id = $courseId AND
|
||||
active = 1
|
||||
$session_condition ";
|
||||
|
||||
$sqlLp = "SELECT e.iid, e.title, lp.name lp_name
|
||||
FROM $exerciseTable e
|
||||
INNER JOIN $lpItemTable i
|
||||
ON (e.c_id = i.c_id AND e.iid = i.path)
|
||||
INNER JOIN $lpTable lp
|
||||
ON (lp.c_id = e.c_id AND lp.id = i.lp_id)
|
||||
WHERE
|
||||
e.c_id = $courseId AND
|
||||
active = 0 AND
|
||||
item_type = 'quiz'
|
||||
$session_condition";
|
||||
|
||||
$sql2 = "SELECT d.path as path, d.comment as comment, ip.visibility as visibility, d.id
|
||||
FROM $TBL_DOCUMENT d
|
||||
INNER JOIN $tableItemProperty ip
|
||||
ON (d.id = ip.ref AND d.c_id = ip.c_id)
|
||||
WHERE
|
||||
d.c_id = $courseId AND
|
||||
ip.c_id = $courseId AND
|
||||
ip.tool = '".TOOL_DOCUMENT."' AND
|
||||
(d.path LIKE '%htm%') AND
|
||||
(d.path LIKE '%HotPotatoes_files%') AND
|
||||
d.path LIKE '".Database::escape_string($uploadPath.'/%/%')."' AND
|
||||
ip.visibility = '1'
|
||||
";
|
||||
|
||||
require_once api_get_path(SYS_CODE_PATH).'exercise/hotpotatoes.lib.php';
|
||||
|
||||
$exerciseInLP = [];
|
||||
if (!$this->is_hp) {
|
||||
$result = Database::query($sql);
|
||||
$resultLp = Database::query($sqlLp);
|
||||
$exerciseInLP = Database::store_result($resultLp);
|
||||
} else {
|
||||
$result2 = Database::query($sql2);
|
||||
}
|
||||
|
||||
$cats = [];
|
||||
$exerciseList = [];
|
||||
if (isset($result)) {
|
||||
if (Database::num_rows($result) > 0) {
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
$cats[] = [$data['iid'], $data['title']];
|
||||
$exerciseList[] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
$hotPotatoes = [];
|
||||
if (isset($result2)) {
|
||||
if (Database::num_rows($result2) > 0) {
|
||||
while ($row = Database::fetch_array($result2)) {
|
||||
$attribute['path'][] = $row['path'];
|
||||
$attribute['visibility'][] = $row['visibility'];
|
||||
$attribute['comment'][] = $row['comment'];
|
||||
$attribute['id'] = $row['id'];
|
||||
|
||||
if (isset($attribute['path']) && is_array($attribute['path'])) {
|
||||
foreach ($attribute['path'] as $path) {
|
||||
$title = GetQuizName($path, $documentPath);
|
||||
if ($title == '') {
|
||||
$title = basename($path);
|
||||
}
|
||||
$element = [$attribute['id'], $title.'(HP)'];
|
||||
$cats[] = $element;
|
||||
$hotPotatoes[] = $element;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($getOnlyHotPotatoes) {
|
||||
return $hotPotatoes;
|
||||
}
|
||||
|
||||
if (!empty($exerciseInLP)) {
|
||||
$allExercises = array_column($exerciseList, 'iid');
|
||||
|
||||
foreach ($exerciseInLP as $exercise) {
|
||||
if (in_array($exercise['iid'], $allExercises)) {
|
||||
continue;
|
||||
}
|
||||
$allExercises[] = $exercise['iid'];
|
||||
//$lpName = strip_tags($exercise['lp_name']);
|
||||
/*$cats[] = [
|
||||
$exercise['iid'],
|
||||
strip_tags(Exercise::get_formated_title_variable($exercise['title'])).
|
||||
' ('.get_lang('ToolLearnpath').' - '.$lpName.')',
|
||||
];*/
|
||||
$cats[] = [
|
||||
$exercise['iid'],
|
||||
strip_tags(Exercise::get_formated_title_variable($exercise['title'])),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone done this exercise yet ?
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$tbl_stats = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
|
||||
$sessionId = $this->get_session_id();
|
||||
$course_id = api_get_course_int_id($this->get_course_code());
|
||||
$sql = "SELECT count(exe_id) AS number
|
||||
FROM $tbl_stats
|
||||
WHERE
|
||||
session_id = $sessionId AND
|
||||
c_id = $course_id AND
|
||||
exe_exo_id = ".$this->get_ref_id();
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return $number[0] != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the score of this exercise. Only the first attempts are taken into account.
|
||||
*
|
||||
* @param int $stud_id student id (default: all students who have results -
|
||||
* then the average is returned)
|
||||
* @param string $type
|
||||
*
|
||||
* @return array (score, max) if student is given
|
||||
* array (sum of scores, number of scores) otherwise
|
||||
* or null if no scores available
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
$allowStats = api_get_configuration_value('allow_gradebook_stats');
|
||||
if ($allowStats) {
|
||||
$link = $this->entity;
|
||||
if (!empty($link)) {
|
||||
$weight = $link->getScoreWeight();
|
||||
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
$bestResult = $link->getBestScore();
|
||||
|
||||
return [$bestResult, $weight];
|
||||
|
||||
break;
|
||||
case 'average':
|
||||
$count = count($link->getUserScoreList());
|
||||
//$count = count($this->getStudentList());
|
||||
if (empty($count)) {
|
||||
return [0, $weight];
|
||||
}
|
||||
$sumResult = array_sum($link->getUserScoreList());
|
||||
|
||||
return [$sumResult / $count, $weight];
|
||||
|
||||
break;
|
||||
case 'ranking':
|
||||
return [null, null];
|
||||
break;
|
||||
default:
|
||||
if (!empty($stud_id)) {
|
||||
$scoreList = $link->getUserScoreList();
|
||||
$result = [0, $weight];
|
||||
if (isset($scoreList[$stud_id])) {
|
||||
$result = [$scoreList[$stud_id], $weight];
|
||||
}
|
||||
|
||||
return $result;
|
||||
} else {
|
||||
$studentCount = count($this->getStudentList());
|
||||
$sumResult = array_sum($link->getUserScoreList());
|
||||
$result = [$sumResult, $studentCount];
|
||||
}
|
||||
|
||||
return $result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tblStats = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
|
||||
$tblHp = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTPOTATOES);
|
||||
$tblDoc = Database::get_course_table(TABLE_DOCUMENT);
|
||||
|
||||
/* the following query should be similar (in conditions) to the one used
|
||||
in exercise/exercise.php, look for note-query-exe-results marker*/
|
||||
$sessionId = $this->get_session_id();
|
||||
$courseId = $this->getCourseId();
|
||||
$exerciseData = $this->get_exercise_data();
|
||||
$exerciseId = isset($exerciseData['iid']) ? (int) $exerciseData['iid'] : 0;
|
||||
$stud_id = (int) $stud_id;
|
||||
|
||||
if (empty($exerciseId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$key = 'exercise_link_id:'.
|
||||
$this->get_id().
|
||||
'exerciseId:'.$exerciseId.'student:'.$stud_id.'session:'.$sessionId.'courseId:'.$courseId.'type:'.$type;
|
||||
|
||||
$useCache = api_get_configuration_value('gradebook_use_apcu_cache');
|
||||
$cacheAvailable = api_get_configuration_value('apc') && $useCache;
|
||||
$cacheDriver = null;
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver = new \Doctrine\Common\Cache\ApcuCache();
|
||||
if ($cacheDriver->contains($key)) {
|
||||
return $cacheDriver->fetch($key);
|
||||
}
|
||||
}
|
||||
|
||||
$exercise = new Exercise($courseId);
|
||||
$exercise->read($exerciseId);
|
||||
|
||||
if (!$this->is_hp) {
|
||||
if (false == $exercise->exercise_was_added_in_lp) {
|
||||
$sql = "SELECT * FROM $tblStats
|
||||
WHERE
|
||||
exe_exo_id = $exerciseId AND
|
||||
orig_lp_id = 0 AND
|
||||
orig_lp_item_id = 0 AND
|
||||
status <> 'incomplete' AND
|
||||
session_id = $sessionId AND
|
||||
c_id = $courseId
|
||||
";
|
||||
} else {
|
||||
$lpCondition = null;
|
||||
if (!empty($exercise->lpList)) {
|
||||
//$lpId = $exercise->getLpBySession($sessionId);
|
||||
$lpList = [];
|
||||
foreach ($exercise->lpList as $lpData) {
|
||||
if ($this->checkBaseExercises) {
|
||||
if ((int) $lpData['session_id'] == 0) {
|
||||
$lpList[] = $lpData['lp_id'];
|
||||
}
|
||||
} else {
|
||||
if ((int) $lpData['session_id'] == $sessionId) {
|
||||
$lpList[] = $lpData['lp_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($lpList) && !empty($sessionId)) {
|
||||
// Check also if an LP was added in the base course.
|
||||
foreach ($exercise->lpList as $lpData) {
|
||||
if ((int) $lpData['session_id'] == 0) {
|
||||
$lpList[] = $lpData['lp_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$lpCondition = ' (orig_lp_id = 0 OR (orig_lp_id IN ("'.implode('", "', $lpList).'"))) AND ';
|
||||
}
|
||||
|
||||
$sql = "SELECT *
|
||||
FROM $tblStats
|
||||
WHERE
|
||||
exe_exo_id = $exerciseId AND
|
||||
$lpCondition
|
||||
status <> 'incomplete' AND
|
||||
session_id = $sessionId AND
|
||||
c_id = $courseId ";
|
||||
}
|
||||
|
||||
if (!empty($stud_id) && 'ranking' !== $type) {
|
||||
$sql .= " AND exe_user_id = $stud_id ";
|
||||
}
|
||||
$sql .= ' ORDER BY exe_id DESC ';
|
||||
} else {
|
||||
$sql = "SELECT * FROM $tblHp hp
|
||||
INNER JOIN $tblDoc doc
|
||||
ON (hp.exe_name = doc.path AND doc.c_id = hp.c_id)
|
||||
WHERE
|
||||
hp.c_id = $courseId AND
|
||||
doc.id = $exerciseId";
|
||||
|
||||
if (!empty($stud_id)) {
|
||||
$sql .= " AND hp.exe_user_id = $stud_id ";
|
||||
}
|
||||
}
|
||||
|
||||
$scores = Database::query($sql);
|
||||
|
||||
if (isset($stud_id) && empty($type)) {
|
||||
// for 1 student
|
||||
if ($data = Database::fetch_array($scores, 'ASSOC')) {
|
||||
$attempts = Database::query($sql);
|
||||
$counter = 0;
|
||||
while ($attempt = Database::fetch_array($attempts)) {
|
||||
$counter++;
|
||||
}
|
||||
$result = [$data['exe_result'], $data['exe_weighting'], $data['exe_date'], $counter];
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
} else {
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// all students -> get average
|
||||
// normal way of getting the info
|
||||
$students = []; // user list, needed to make sure we only
|
||||
// take first attempts into account
|
||||
$student_count = 0;
|
||||
$sum = 0;
|
||||
$bestResult = 0;
|
||||
$weight = 0;
|
||||
$sumResult = 0;
|
||||
$studentList = $this->getStudentList();
|
||||
$studentIdList = [];
|
||||
if (!empty($studentList)) {
|
||||
$studentIdList = array_column($studentList, 'user_id');
|
||||
}
|
||||
|
||||
while ($data = Database::fetch_array($scores, 'ASSOC')) {
|
||||
// Only take into account users in the current student list.
|
||||
if (!empty($studentIdList)) {
|
||||
if (!in_array($data['exe_user_id'], $studentIdList)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($students[$data['exe_user_id']])) {
|
||||
if ($data['exe_weighting'] != 0) {
|
||||
$students[$data['exe_user_id']] = $data['exe_result'];
|
||||
$student_count++;
|
||||
if ($data['exe_result'] > $bestResult) {
|
||||
$bestResult = $data['exe_result'];
|
||||
}
|
||||
$sum += $data['exe_result'] / $data['exe_weighting'];
|
||||
$sumResult += $data['exe_result'];
|
||||
$weight = $data['exe_weighting'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($student_count == 0) {
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, null);
|
||||
}
|
||||
|
||||
return null;
|
||||
} else {
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
$result = [$bestResult, $weight];
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
break;
|
||||
case 'average':
|
||||
$count = count($this->getStudentList());
|
||||
if (empty($count)) {
|
||||
$result = [0, $weight];
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = [$sumResult / $count, $weight];
|
||||
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
break;
|
||||
case 'ranking':
|
||||
$ranking = AbstractLink::getCurrentUserRanking($stud_id, $students);
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $ranking);
|
||||
}
|
||||
|
||||
return $ranking;
|
||||
break;
|
||||
default:
|
||||
$result = [$sum, $student_count];
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL where to go to if the user clicks on the link.
|
||||
* First we go to exercise_jump.php and then to the result page.
|
||||
* Check this php file for more info.
|
||||
*/
|
||||
public function get_link()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
$data = $this->get_exercise_data();
|
||||
$exerciseId = $data['iid'];
|
||||
$path = isset($data['path']) ? $data['path'] : '';
|
||||
|
||||
return api_get_path(WEB_CODE_PATH).'gradebook/exercise_jump.php?'
|
||||
.http_build_query(
|
||||
[
|
||||
'path' => $path,
|
||||
'session_id' => $sessionId,
|
||||
'cidReq' => $this->get_course_code(),
|
||||
'gradebook' => 'view',
|
||||
'exerciseId' => $exerciseId,
|
||||
'type' => $this->get_type(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name to display: same as exercise title.
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$documentPath = api_get_path(SYS_COURSE_PATH).$this->course_code.'/document';
|
||||
require_once api_get_path(SYS_CODE_PATH).'exercise/hotpotatoes.lib.php';
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
if ($this->is_hp == 1) {
|
||||
if (isset($data['path'])) {
|
||||
$title = GetQuizName($data['path'], $documentPath);
|
||||
if ($title == '') {
|
||||
$title = basename($data['path']);
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
}
|
||||
|
||||
return strip_tags(Exercise::get_formated_title_variable($data['title']));
|
||||
}
|
||||
|
||||
public function getLpListToString()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
$lpList = Exercise::getLpListFromExercise($data['iid'], $this->getCourseId());
|
||||
$lpListToString = '';
|
||||
if (!empty($lpList)) {
|
||||
foreach ($lpList as &$list) {
|
||||
$list['name'] = Display::label($list['name'], 'warning');
|
||||
}
|
||||
$lpListToString = implode(' ', array_column($lpList, 'name'));
|
||||
}
|
||||
|
||||
return $lpListToString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description to display: same as exercise description.
|
||||
*/
|
||||
public function get_description()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
return isset($data['description']) ? $data['description'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this still links to an exercise.
|
||||
*/
|
||||
public function is_valid_link()
|
||||
{
|
||||
$exerciseData = $this->get_exercise_data();
|
||||
|
||||
return !empty($exerciseData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type_name()
|
||||
{
|
||||
if ($this->is_hp == 1) {
|
||||
return 'HotPotatoes';
|
||||
}
|
||||
|
||||
return get_lang('Quiz');
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'exercise';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hp
|
||||
*/
|
||||
public function setHp($hp)
|
||||
{
|
||||
$this->hp = $hp;
|
||||
}
|
||||
|
||||
public function getBestScore()
|
||||
{
|
||||
return $this->getStats('best');
|
||||
}
|
||||
|
||||
public function getStats($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database contents of this exercise.
|
||||
*/
|
||||
public function get_exercise_data()
|
||||
{
|
||||
$tableItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
|
||||
if ($this->is_hp == 1) {
|
||||
$table = Database::get_course_table(TABLE_DOCUMENT);
|
||||
} else {
|
||||
$table = Database::get_course_table(TABLE_QUIZ_TEST);
|
||||
}
|
||||
|
||||
$exerciseId = $this->get_ref_id();
|
||||
|
||||
if (empty($this->exercise_data)) {
|
||||
if ($this->is_hp == 1) {
|
||||
$sql = "SELECT * FROM $table ex
|
||||
INNER JOIN $tableItemProperty ip
|
||||
ON (ip.ref = ex.id AND ip.c_id = ex.c_id)
|
||||
WHERE
|
||||
ip.c_id = $this->course_id AND
|
||||
ex.c_id = $this->course_id AND
|
||||
ip.ref = $exerciseId AND
|
||||
ip.tool = '".TOOL_DOCUMENT."' AND
|
||||
ex.path LIKE '%htm%' AND
|
||||
ex.path LIKE '%HotPotatoes_files%' AND
|
||||
ip.visibility = 1";
|
||||
$result = Database::query($sql);
|
||||
$this->exercise_data = Database::fetch_array($result);
|
||||
} else {
|
||||
// Try with iid
|
||||
$sql = "SELECT * FROM $table
|
||||
WHERE
|
||||
iid = $exerciseId";
|
||||
$result = Database::query($sql);
|
||||
$rows = Database::num_rows($result);
|
||||
|
||||
if (!empty($rows)) {
|
||||
$this->exercise_data = Database::fetch_array($result);
|
||||
} else {
|
||||
// Try wit id
|
||||
$sql = "SELECT * FROM $table
|
||||
WHERE
|
||||
iid = $exerciseId";
|
||||
$result = Database::query($sql);
|
||||
$this->exercise_data = Database::fetch_array($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->exercise_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->exercise_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the exercise.
|
||||
*/
|
||||
private function get_exercise_table()
|
||||
{
|
||||
$this->exercise_table = Database::get_course_table(TABLE_QUIZ_TEST);
|
||||
|
||||
return $this->exercise_table;
|
||||
}
|
||||
}
|
||||
357
main/gradebook/lib/be/forumthreadlink.class.php
Normal file
357
main/gradebook/lib/be/forumthreadlink.class.php
Normal file
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class ForumThreadLink.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class ForumThreadLink extends AbstractLink
|
||||
{
|
||||
private $forum_thread_table;
|
||||
private $itemprop_table;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_FORUM_THREAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('ForumThreads');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of all exercises available.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links()
|
||||
{
|
||||
if (empty($this->course_code)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$tbl_grade_links = Database::get_course_table(TABLE_FORUM_THREAD);
|
||||
$tbl_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
|
||||
$sessionId = $this->get_session_id();
|
||||
|
||||
if ($sessionId) {
|
||||
$session_condition = 'tl.session_id='.$sessionId;
|
||||
} else {
|
||||
$session_condition = '(tl.session_id = 0 OR tl.session_id IS NULL)';
|
||||
}
|
||||
|
||||
$sql = 'SELECT tl.thread_id, tl.thread_title, tl.thread_title_qualify
|
||||
FROM '.$tbl_grade_links.' tl INNER JOIN '.$tbl_item_property.' ip
|
||||
ON (tl.thread_id = ip.ref AND tl.c_id = ip.c_id)
|
||||
WHERE
|
||||
tl.c_id = '.$this->course_id.' AND
|
||||
ip.c_id = '.$this->course_id.' AND
|
||||
ip.tool = "forum_thread" AND
|
||||
ip.visibility <> 2 AND
|
||||
'.$session_condition.'
|
||||
';
|
||||
|
||||
$result = Database::query($sql);
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
if (isset($data['thread_title_qualify']) && '' != $data['thread_title_qualify']) {
|
||||
$cats[] = [$data['thread_id'], $data['thread_title_qualify']];
|
||||
} else {
|
||||
$cats[] = [$data['thread_id'], $data['thread_title']];
|
||||
}
|
||||
}
|
||||
$my_cats = isset($cats) ? $cats : [];
|
||||
|
||||
return $my_cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone done this exercise yet ?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$table = Database::get_course_table(TABLE_FORUM_POST);
|
||||
|
||||
$sql = "SELECT count(*) AS number FROM $table
|
||||
WHERE
|
||||
c_id = ".$this->course_id." AND
|
||||
thread_id = '".$this->get_ref_id()."'
|
||||
";
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $stud_id
|
||||
* @param string $type
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
|
||||
$threadInfo = get_thread_information('', $this->get_ref_id());
|
||||
$thread_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
|
||||
$sessionId = $this->get_session_id();
|
||||
$sessionCondition = api_get_session_condition(
|
||||
$sessionId,
|
||||
true,
|
||||
false,
|
||||
'session_id'
|
||||
);
|
||||
|
||||
$sql = 'SELECT thread_qualify_max
|
||||
FROM '.Database::get_course_table(TABLE_FORUM_THREAD)."
|
||||
WHERE
|
||||
c_id = ".$this->course_id." AND
|
||||
thread_id = '".$this->get_ref_id()."'
|
||||
$sessionCondition
|
||||
";
|
||||
$query = Database::query($sql);
|
||||
$assignment = Database::fetch_array($query);
|
||||
|
||||
$sql = "SELECT * FROM $thread_qualify
|
||||
WHERE
|
||||
c_id = ".$this->course_id." AND
|
||||
thread_id = ".$this->get_ref_id()."
|
||||
$sessionCondition
|
||||
";
|
||||
if (isset($stud_id)) {
|
||||
$sql .= ' AND user_id = '.intval($stud_id);
|
||||
}
|
||||
|
||||
// order by id, that way the student's first attempt is accessed first
|
||||
$sql .= ' ORDER BY qualify_time DESC';
|
||||
$scores = Database::query($sql);
|
||||
|
||||
// for 1 student
|
||||
if (isset($stud_id)) {
|
||||
if (0 == $threadInfo['thread_peer_qualify']) {
|
||||
// Classic way of calculate score
|
||||
if ($data = Database::fetch_array($scores)) {
|
||||
return [
|
||||
$data['qualify'],
|
||||
$assignment['thread_qualify_max'],
|
||||
];
|
||||
} else {
|
||||
// We sent the 0/thread_qualify_max instead of null for correct calculations
|
||||
return [0, $assignment['thread_qualify_max']];
|
||||
}
|
||||
} else {
|
||||
// Take average
|
||||
$score = 0;
|
||||
$counter = 0;
|
||||
if (Database::num_rows($scores)) {
|
||||
while ($data = Database::fetch_array($scores, 'ASSOC')) {
|
||||
$score += $data['qualify'];
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
// If no result
|
||||
if (empty($counter) || $counter <= 2) {
|
||||
return [0, $assignment['thread_qualify_max']];
|
||||
}
|
||||
|
||||
return [$score / $counter, $assignment['thread_qualify_max']];
|
||||
}
|
||||
} else {
|
||||
// All students -> get average
|
||||
$students = []; // user list, needed to make sure we only
|
||||
// take first attempts into account
|
||||
$counter = 0;
|
||||
$sum = 0;
|
||||
$bestResult = 0;
|
||||
$weight = 0;
|
||||
$sumResult = 0;
|
||||
|
||||
while ($data = Database::fetch_array($scores)) {
|
||||
if (!(array_key_exists($data['user_id'], $students))) {
|
||||
if (0 != $assignment['thread_qualify_max']) {
|
||||
$students[$data['user_id']] = $data['qualify'];
|
||||
$counter++;
|
||||
$sum += $data['qualify'] / $assignment['thread_qualify_max'];
|
||||
$sumResult += $data['qualify'];
|
||||
if ($data['qualify'] > $bestResult) {
|
||||
$bestResult = $data['qualify'];
|
||||
}
|
||||
$weight = $assignment['thread_qualify_max'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == $counter) {
|
||||
return [null, null];
|
||||
} else {
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
return [$bestResult, $weight];
|
||||
break;
|
||||
case 'average':
|
||||
return [$sumResult / $counter, $weight];
|
||||
break;
|
||||
case 'ranking':
|
||||
return AbstractLink::getCurrentUserRanking($stud_id, $students);
|
||||
break;
|
||||
default:
|
||||
return [$sum, $counter];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$this->get_exercise_data();
|
||||
$thread_title = isset($this->exercise_data['thread_title']) ? $this->exercise_data['thread_title'] : '';
|
||||
$thread_title_qualify = isset($this->exercise_data['thread_title_qualify']) ? $this->exercise_data['thread_title_qualify'] : '';
|
||||
if (isset($thread_title_qualify) && '' != $thread_title_qualify) {
|
||||
return $this->exercise_data['thread_title_qualify'];
|
||||
}
|
||||
|
||||
return $thread_title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_description()
|
||||
{
|
||||
return ''; //$this->exercise_data['description'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this still links to an exercise.
|
||||
*/
|
||||
public function is_valid_link()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
$sql = 'SELECT count(id) from '.$this->get_forum_thread_table().'
|
||||
WHERE
|
||||
c_id = '.$this->course_id.' AND
|
||||
thread_id = '.$this->get_ref_id().' AND
|
||||
session_id='.$sessionId;
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
//it was extracts the forum id
|
||||
$sql = 'SELECT * FROM '.$this->get_forum_thread_table()."
|
||||
WHERE
|
||||
c_id = '.$this->course_id.' AND
|
||||
thread_id = '".$this->get_ref_id()."' AND
|
||||
session_id = $sessionId ";
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result, 'ASSOC');
|
||||
$forum_id = $row['forum_id'];
|
||||
|
||||
$url = api_get_path(WEB_PATH).'main/forum/viewthread.php?'.api_get_cidreq_params($this->get_course_code(), $sessionId).'&thread='.$this->get_ref_id().'&gradebook=view&forum='.$forum_id;
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'forum';
|
||||
}
|
||||
|
||||
public function save_linked_data()
|
||||
{
|
||||
$weight = $this->get_weight();
|
||||
$ref_id = $this->get_ref_id();
|
||||
|
||||
if (!empty($ref_id)) {
|
||||
$sql = 'UPDATE '.$this->get_forum_thread_table().' SET
|
||||
thread_weight='.api_float_val($weight).'
|
||||
WHERE c_id = '.$this->course_id.' AND thread_id= '.$ref_id;
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
public function delete_linked_data()
|
||||
{
|
||||
$ref_id = $this->get_ref_id();
|
||||
if (!empty($ref_id)) {
|
||||
// Cleans forum
|
||||
$sql = 'UPDATE '.$this->get_forum_thread_table().' SET
|
||||
thread_qualify_max = 0,
|
||||
thread_weight = 0,
|
||||
thread_title_qualify = ""
|
||||
WHERE c_id = '.$this->course_id.' AND thread_id= '.$ref_id;
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the student publications.
|
||||
*/
|
||||
private function get_forum_thread_table()
|
||||
{
|
||||
return $this->forum_thread_table = Database::get_course_table(TABLE_FORUM_THREAD);
|
||||
}
|
||||
|
||||
private function get_exercise_data()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
if ($sessionId) {
|
||||
$session_condition = 'session_id = '.$sessionId;
|
||||
} else {
|
||||
$session_condition = '(session_id = 0 OR session_id IS NULL)';
|
||||
}
|
||||
|
||||
if (!isset($this->exercise_data)) {
|
||||
$sql = 'SELECT * FROM '.$this->get_forum_thread_table().'
|
||||
WHERE
|
||||
c_id = '.$this->course_id.' AND
|
||||
thread_id = '.$this->get_ref_id().' AND
|
||||
'.$session_condition;
|
||||
$query = Database::query($sql);
|
||||
$this->exercise_data = Database::fetch_array($query);
|
||||
}
|
||||
|
||||
return $this->exercise_data;
|
||||
}
|
||||
}
|
||||
34
main/gradebook/lib/be/gradebookitem.class.php
Normal file
34
main/gradebook/lib/be/gradebookitem.class.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Interface for all displayable items in the gradebook.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
interface GradebookItem
|
||||
{
|
||||
public function get_item_type();
|
||||
|
||||
public function get_id();
|
||||
|
||||
public function get_name();
|
||||
|
||||
public function get_description();
|
||||
|
||||
public function get_course_code();
|
||||
|
||||
public function get_weight();
|
||||
|
||||
public function get_date();
|
||||
|
||||
public function is_visible();
|
||||
|
||||
public function get_icon_name();
|
||||
|
||||
public function getStudentList();
|
||||
|
||||
public function setStudentList($list);
|
||||
|
||||
public function calc_score($stud_id = null, $type = null);
|
||||
}
|
||||
7
main/gradebook/lib/be/index.html
Normal file
7
main/gradebook/lib/be/index.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; url=../../gradebook.php">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
257
main/gradebook/lib/be/learnpathlink.class.php
Normal file
257
main/gradebook/lib/be/learnpathlink.class.php
Normal file
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Defines a gradebook LearnpathLink object.
|
||||
*
|
||||
* @author Yannick Warnier <yannick.warnier@beeznest.com>
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class LearnpathLink extends AbstractLink
|
||||
{
|
||||
private $course_info;
|
||||
private $learnpath_table;
|
||||
private $learnpath_data;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_LEARNPATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of all learnpaths available.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links()
|
||||
{
|
||||
if (empty($this->course_code)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$session_id = $this->get_session_id();
|
||||
if (empty($session_id)) {
|
||||
$session_condition = api_get_session_condition(0, true);
|
||||
} else {
|
||||
$session_condition = api_get_session_condition($session_id, true, true);
|
||||
}
|
||||
|
||||
$sql = 'SELECT id, name FROM '.$this->get_learnpath_table().'
|
||||
WHERE c_id = '.$this->course_id.' '.$session_condition.' ';
|
||||
$result = Database::query($sql);
|
||||
|
||||
$cats = [];
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
$cats[] = [$data['id'], $data['name']];
|
||||
}
|
||||
|
||||
return $cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone used this learnpath yet ?
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$tbl_stats = Database::get_course_table(TABLE_LP_VIEW);
|
||||
$sql = "SELECT count(id) AS number FROM $tbl_stats
|
||||
WHERE c_id = ".$this->course_id." AND lp_id = ".$this->get_ref_id();
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_array($result, 'NUM');
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the progress of this learnpath. Only the last attempt are taken into account.
|
||||
*
|
||||
* @param $stud_id student id (default: all students who have results - then the average is returned)
|
||||
* @param $type The type of score we want to get: best|average|ranking
|
||||
*
|
||||
* @return array (score, max) if student is given
|
||||
* array (sum of scores, number of scores) otherwise
|
||||
* or null if no scores available
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
$tbl_stats = Database::get_course_table(TABLE_LP_VIEW);
|
||||
$session_id = $this->get_session_id();
|
||||
if (empty($session_id)) {
|
||||
$session_id = api_get_session_id();
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM $tbl_stats
|
||||
WHERE
|
||||
c_id = ".$this->course_id." AND
|
||||
lp_id = ".$this->get_ref_id()." AND
|
||||
session_id = $session_id ";
|
||||
|
||||
if (isset($stud_id)) {
|
||||
$sql .= ' AND user_id = '.intval($stud_id);
|
||||
}
|
||||
|
||||
// order by id, that way the student's first attempt is accessed first
|
||||
$sql .= ' ORDER BY view_count DESC';
|
||||
|
||||
$scores = Database::query($sql);
|
||||
// for 1 student
|
||||
if (isset($stud_id)) {
|
||||
if ($data = Database::fetch_assoc($scores)) {
|
||||
return [$data['progress'], 100];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// all students -> get average
|
||||
$students = []; // user list, needed to make sure we only
|
||||
// take first attempts into account
|
||||
$rescount = 0;
|
||||
$sum = 0;
|
||||
$bestResult = 0;
|
||||
$sumResult = 0;
|
||||
while ($data = Database::fetch_array($scores)) {
|
||||
if (!(array_key_exists($data['user_id'], $students))) {
|
||||
$students[$data['user_id']] = $data['progress'];
|
||||
$rescount++;
|
||||
$sum += $data['progress'] / 100;
|
||||
$sumResult += $data['progress'];
|
||||
|
||||
if ($data['progress'] > $bestResult) {
|
||||
$bestResult = $data['progress'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == $rescount) {
|
||||
return [null, null];
|
||||
} else {
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
return [$bestResult, 100];
|
||||
break;
|
||||
case 'average':
|
||||
return [$sumResult / $rescount, 100];
|
||||
break;
|
||||
case 'ranking':
|
||||
return AbstractLink::getCurrentUserRanking($stud_id, $students);
|
||||
break;
|
||||
default:
|
||||
return [$sum, $rescount];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL where to go to if the user clicks on the link.
|
||||
*/
|
||||
public function get_link()
|
||||
{
|
||||
$session_id = $this->get_session_id();
|
||||
$url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.api_get_cidreq_params(
|
||||
$this->get_course_code(),
|
||||
$session_id
|
||||
).'&gradebook=view';
|
||||
|
||||
if (!api_is_allowed_to_edit() || null == $this->calc_score(api_get_user_id())) {
|
||||
$url .= '&action=view&lp_id='.$this->get_ref_id();
|
||||
} else {
|
||||
$url .= '&action=build&lp_id='.$this->get_ref_id();
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name to display: same as learnpath title.
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$data = $this->get_learnpath_data();
|
||||
|
||||
return $data['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description to display: same as learnpath description.
|
||||
*/
|
||||
public function get_description()
|
||||
{
|
||||
$data = $this->get_learnpath_data();
|
||||
|
||||
return $data['description'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this still links to a learnpath.
|
||||
*/
|
||||
public function is_valid_link()
|
||||
{
|
||||
$sql = 'SELECT count(id) FROM '.$this->get_learnpath_table().'
|
||||
WHERE c_id = '.$this->course_id.' AND id = '.$this->get_ref_id().' ';
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result, 'NUM');
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('LearningPaths');
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'learnpath';
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the learnpath.
|
||||
*/
|
||||
private function get_learnpath_table()
|
||||
{
|
||||
$this->learnpath_table = Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
return $this->learnpath_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database contents of this learnpath.
|
||||
*/
|
||||
private function get_learnpath_data()
|
||||
{
|
||||
if (!isset($this->learnpath_data)) {
|
||||
$sql = 'SELECT * FROM '.$this->get_learnpath_table().'
|
||||
WHERE c_id = '.$this->course_id.' AND id = '.$this->get_ref_id().' ';
|
||||
$result = Database::query($sql);
|
||||
$this->learnpath_data = Database::fetch_array($result);
|
||||
}
|
||||
|
||||
return $this->learnpath_data;
|
||||
}
|
||||
}
|
||||
132
main/gradebook/lib/be/linkfactory.class.php
Normal file
132
main/gradebook/lib/be/linkfactory.class.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class LinkFactory
|
||||
* Factory for link objects.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class LinkFactory
|
||||
{
|
||||
/**
|
||||
* Retrieve links and return them as an array of extensions of AbstractLink.
|
||||
*
|
||||
* @param int $id link id
|
||||
* @param int $type link type
|
||||
* @param int $ref_id reference id
|
||||
* @param int $user_id user id (link owner)
|
||||
* @param string $course_code course code
|
||||
* @param int $category_id parent category
|
||||
* @param int $visible visible
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function load(
|
||||
$id = null,
|
||||
$type = null,
|
||||
$ref_id = null,
|
||||
$user_id = null,
|
||||
$course_code = null,
|
||||
$category_id = null,
|
||||
$visible = null
|
||||
) {
|
||||
return AbstractLink::load(
|
||||
$id,
|
||||
$type,
|
||||
$ref_id,
|
||||
$user_id,
|
||||
$course_code,
|
||||
$category_id,
|
||||
$visible
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the link object referring to an evaluation.
|
||||
*/
|
||||
public function get_evaluation_link($eval_id)
|
||||
{
|
||||
$links = AbstractLink::load(null, null, $eval_id);
|
||||
foreach ($links as $link) {
|
||||
if (is_a($link, 'EvalLink')) {
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find links by name.
|
||||
*
|
||||
* @param string $name_mask search string
|
||||
*
|
||||
* @return array link objects matching the search criterium
|
||||
*/
|
||||
public function find_links($name_mask, $selectcat)
|
||||
{
|
||||
return AbstractLink::find_links($name_mask, $selectcat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to create specific link objects.
|
||||
*
|
||||
* @param int $type link type
|
||||
*/
|
||||
public static function create($type)
|
||||
{
|
||||
$type = (int) $type;
|
||||
switch ($type) {
|
||||
case LINK_EXERCISE:
|
||||
return new ExerciseLink();
|
||||
case LINK_HOTPOTATOES:
|
||||
return new ExerciseLink(1);
|
||||
case LINK_DROPBOX:
|
||||
return new DropboxLink();
|
||||
case LINK_STUDENTPUBLICATION:
|
||||
return new StudentPublicationLink();
|
||||
case LINK_LEARNPATH:
|
||||
return new LearnpathLink();
|
||||
case LINK_FORUM_THREAD:
|
||||
return new ForumThreadLink();
|
||||
case LINK_ATTENDANCE:
|
||||
return new AttendanceLink();
|
||||
case LINK_SURVEY:
|
||||
return new SurveyLink();
|
||||
case LINK_PORTFOLIO:
|
||||
return new PortfolioLink();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of all known link types.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_all_types()
|
||||
{
|
||||
$types = [
|
||||
LINK_EXERCISE,
|
||||
//LINK_DROPBOX,
|
||||
LINK_HOTPOTATOES,
|
||||
LINK_STUDENTPUBLICATION,
|
||||
LINK_LEARNPATH,
|
||||
LINK_FORUM_THREAD,
|
||||
LINK_ATTENDANCE,
|
||||
LINK_SURVEY,
|
||||
];
|
||||
|
||||
if (api_get_configuration_value('allow_portfolio_tool')) {
|
||||
$types[] = LINK_PORTFOLIO;
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
}
|
||||
}
|
||||
323
main/gradebook/lib/be/result.class.php
Normal file
323
main/gradebook/lib/be/result.class.php
Normal file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Defines a gradebook Result object.
|
||||
*
|
||||
* @author Bert Steppé, Stijn Konings
|
||||
*/
|
||||
class Result
|
||||
{
|
||||
private $id;
|
||||
private $user_id;
|
||||
private $evaluation;
|
||||
private $created_at;
|
||||
private $score;
|
||||
|
||||
/**
|
||||
* Result constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->created_at = api_get_utc_datetime();
|
||||
}
|
||||
|
||||
public function get_id()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function get_user_id()
|
||||
{
|
||||
return $this->user_id;
|
||||
}
|
||||
|
||||
public function get_evaluation_id()
|
||||
{
|
||||
return $this->evaluation;
|
||||
}
|
||||
|
||||
public function get_date()
|
||||
{
|
||||
return $this->created_at;
|
||||
}
|
||||
|
||||
public function get_score()
|
||||
{
|
||||
return $this->score;
|
||||
}
|
||||
|
||||
public function set_id($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function set_user_id($user_id)
|
||||
{
|
||||
$this->user_id = $user_id;
|
||||
}
|
||||
|
||||
public function set_evaluation_id($evaluation_id)
|
||||
{
|
||||
$this->evaluation = $evaluation_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $creation_date
|
||||
*/
|
||||
public function set_date($creation_date)
|
||||
{
|
||||
$this->created_at = $creation_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $score
|
||||
*/
|
||||
public function set_score($score)
|
||||
{
|
||||
$this->score = $score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve results and return them as an array of Result objects.
|
||||
*
|
||||
* @param $id result id
|
||||
* @param $user_id user id (student)
|
||||
* @param $evaluation_id evaluation where this is a result for
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function load($id = null, $user_id = null, $evaluation_id = null)
|
||||
{
|
||||
$tbl_user = Database::get_main_table(TABLE_MAIN_USER);
|
||||
$tbl_grade_results = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
|
||||
$tbl_course_rel_course = Database::get_main_table(TABLE_MAIN_COURSE_USER);
|
||||
$tbl_session_rel_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
|
||||
$sessionId = api_get_session_id();
|
||||
$list_user_course_list = [];
|
||||
|
||||
if (is_null($id) && is_null($user_id) && !is_null($evaluation_id)) {
|
||||
// Verified_if_exist_evaluation
|
||||
$sql = 'SELECT COUNT(*) AS count
|
||||
FROM '.$tbl_grade_results.'
|
||||
WHERE evaluation_id="'.Database::escape_string($evaluation_id).'"';
|
||||
|
||||
$result = Database::query($sql);
|
||||
$existEvaluation = Database::result($result, 0, 0);
|
||||
|
||||
if (0 != $existEvaluation) {
|
||||
if ($sessionId) {
|
||||
$sql = 'SELECT c_id, user_id as user_id, status
|
||||
FROM '.$tbl_session_rel_course_user.'
|
||||
WHERE
|
||||
status= 0 AND
|
||||
c_id = "'.api_get_course_int_id().'" AND
|
||||
session_id = '.$sessionId;
|
||||
} else {
|
||||
$sql = 'SELECT c_id, user_id, status
|
||||
FROM '.$tbl_course_rel_course.'
|
||||
WHERE status ="'.STUDENT.'" AND c_id = "'.api_get_course_int_id().'" ';
|
||||
}
|
||||
|
||||
$res_course_rel_user = Database::query($sql);
|
||||
while ($row_course_rel_user = Database::fetch_array($res_course_rel_user, 'ASSOC')) {
|
||||
$list_user_course_list[] = $row_course_rel_user;
|
||||
}
|
||||
$current_date = api_get_utc_datetime();
|
||||
for ($i = 0; $i < count($list_user_course_list); $i++) {
|
||||
$sql_verified = 'SELECT COUNT(*) AS count
|
||||
FROM '.$tbl_grade_results.'
|
||||
WHERE
|
||||
user_id="'.intval($list_user_course_list[$i]['user_id']).'" AND
|
||||
evaluation_id="'.intval($evaluation_id).'";';
|
||||
$res_verified = Database::query($sql_verified);
|
||||
$info_verified = Database::result($res_verified, 0, 0);
|
||||
if (0 == $info_verified) {
|
||||
$sql_insert = 'INSERT INTO '.$tbl_grade_results.'(user_id,evaluation_id,created_at,score)
|
||||
VALUES ("'.intval($list_user_course_list[$i]['user_id']).'","'.intval($evaluation_id).'","'.$current_date.'",0);';
|
||||
Database::query($sql_insert);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$userIdList = [];
|
||||
foreach ($list_user_course_list as $data) {
|
||||
$userIdList[] = $data['user_id'];
|
||||
}
|
||||
$userIdListToString = implode("', '", $userIdList);
|
||||
|
||||
$sql = "SELECT lastname, gr.id, gr.user_id, gr.evaluation_id, gr.created_at, gr.score
|
||||
FROM $tbl_grade_results gr
|
||||
INNER JOIN $tbl_user u
|
||||
ON gr.user_id = u.user_id ";
|
||||
|
||||
if (!empty($userIdList)) {
|
||||
$sql .= " AND u.user_id IN ('$userIdListToString')";
|
||||
}
|
||||
|
||||
$paramcount = 0;
|
||||
if (!empty($id)) {
|
||||
$sql .= ' WHERE gr.id = '.intval($id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (!empty($user_id)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' gr.user_id = '.intval($user_id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (!empty($evaluation_id)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' gr.evaluation_id = '.intval($evaluation_id);
|
||||
}
|
||||
$sql .= ' ORDER BY u.lastname, u.firstname';
|
||||
|
||||
$result = Database::query($sql);
|
||||
$allres = [];
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
$res = new Result();
|
||||
$res->set_id($data['id']);
|
||||
$res->set_user_id($data['user_id']);
|
||||
$res->set_evaluation_id($data['evaluation_id']);
|
||||
$res->set_date(api_get_local_time($data['created_at']));
|
||||
$res->set_score($data['score']);
|
||||
$allres[] = $res;
|
||||
}
|
||||
|
||||
return $allres;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert this result into the database.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (isset($this->user_id) && isset($this->evaluation)) {
|
||||
$tbl_grade_results = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
|
||||
$sql = "INSERT INTO ".$tbl_grade_results
|
||||
." (user_id, evaluation_id,
|
||||
created_at";
|
||||
if (isset($this->score)) {
|
||||
$sql .= ",score";
|
||||
}
|
||||
$sql .= ") VALUES
|
||||
(".(int) $this->get_user_id().", ".(int) $this->get_evaluation_id()
|
||||
.", '".$this->get_date()."' ";
|
||||
if (isset($this->score)) {
|
||||
$sql .= ", ".$this->get_score();
|
||||
}
|
||||
$sql .= ")";
|
||||
Database::query($sql);
|
||||
} else {
|
||||
exit('Error in Result add: required field empty');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* insert log result.
|
||||
*/
|
||||
public function addResultLog($userid, $evaluationid)
|
||||
{
|
||||
if (isset($userid) && isset($evaluationid)) {
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_LOG);
|
||||
$result = new Result();
|
||||
|
||||
$arr_result = $result->load(null, $userid, $evaluationid);
|
||||
$arr = get_object_vars($arr_result[0]);
|
||||
|
||||
$sql = 'INSERT INTO '.$table
|
||||
.' (id_result,user_id, evaluation_id,created_at';
|
||||
if (isset($arr['score'])) {
|
||||
$sql .= ',score';
|
||||
}
|
||||
$sql .= ') VALUES
|
||||
('.(int) $arr['id'].','.(int) $arr['user_id'].', '.(int) $arr['evaluation']
|
||||
.", '".api_get_utc_datetime()."'";
|
||||
if (isset($arr['score'])) {
|
||||
$sql .= ', '.$arr['score'];
|
||||
}
|
||||
$sql .= ')';
|
||||
|
||||
Database::query($sql);
|
||||
} else {
|
||||
exit('Error in Result add: required field empty');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the properties of this result in the database.
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
|
||||
$sql = 'UPDATE '.$table.'
|
||||
SET user_id = '.$this->get_user_id()
|
||||
.', evaluation_id = '.$this->get_evaluation_id()
|
||||
.', score = ';
|
||||
if (isset($this->score)) {
|
||||
$sql .= $this->get_score();
|
||||
} else {
|
||||
$sql .= 'null';
|
||||
}
|
||||
if (isset($this->id)) {
|
||||
$sql .= " WHERE id = {$this->id}";
|
||||
} else {
|
||||
$sql .= " WHERE evaluation_id = {$this->evaluation}
|
||||
AND user_id = {$this->user_id}
|
||||
";
|
||||
}
|
||||
|
||||
// no need to update creation date
|
||||
Database::query($sql);
|
||||
|
||||
Evaluation::generateStats($this->get_evaluation_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this result from the database.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
|
||||
$sql = 'DELETE FROM '.$table.' WHERE id = '.$this->id;
|
||||
Database::query($sql);
|
||||
$allowMultipleAttempts = api_get_configuration_value('gradebook_multiple_evaluation_attempts');
|
||||
if ($allowMultipleAttempts) {
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_ATTEMPT);
|
||||
$sql = "DELETE FROM $table WHERE result_id = ".$this->id;
|
||||
Database::query($sql);
|
||||
}
|
||||
|
||||
Evaluation::generateStats($this->get_evaluation_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if exists a result with its user and evaluation.
|
||||
*
|
||||
* @throws \Doctrine\ORM\Query\QueryException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists()
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
|
||||
$sql = "SELECT COUNT(*) AS count
|
||||
FROM $table gr
|
||||
WHERE gr.evaluation_id = {$this->evaluation}
|
||||
AND gr.user_id = {$this->user_id}
|
||||
";
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result);
|
||||
$count = (int) $row['count'];
|
||||
|
||||
return $count > 0;
|
||||
}
|
||||
}
|
||||
427
main/gradebook/lib/be/studentpublicationlink.class.php
Normal file
427
main/gradebook/lib/be/studentpublicationlink.class.php
Normal file
@@ -0,0 +1,427 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Gradebook link to student publication item.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class StudentPublicationLink extends AbstractLink
|
||||
{
|
||||
private $studpub_table;
|
||||
private $itemprop_table;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_STUDENTPUBLICATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of a document
|
||||
* This function is loaded when using a gradebook as a tab (gradebook = -1)
|
||||
* see issue #2705.
|
||||
*/
|
||||
public function get_view_url($stud_id)
|
||||
{
|
||||
return null;
|
||||
// find a file uploaded by the given student,
|
||||
// with the same title as the evaluation name
|
||||
|
||||
$eval = $this->get_evaluation();
|
||||
$stud_id = (int) $stud_id;
|
||||
$itemProperty = $this->get_itemprop_table();
|
||||
$workTable = $this->get_studpub_table();
|
||||
$courseId = $this->course_id;
|
||||
|
||||
$sql = "SELECT pub.url
|
||||
FROM $itemProperty prop
|
||||
INNER JOIN $workTable pub
|
||||
ON (prop.c_id = pub.c_id AND prop.ref = pub.id)
|
||||
WHERE
|
||||
prop.c_id = $courseId AND
|
||||
pub.c_id = $courseId AND
|
||||
prop.tool = 'work' AND
|
||||
prop.insert_user_id = $stud_id AND
|
||||
pub.title = '".Database::escape_string($eval->get_name())."' AND
|
||||
pub.session_id=".api_get_session_id();
|
||||
|
||||
$result = Database::query($sql);
|
||||
if ($fileurl = Database::fetch_row($result)) {
|
||||
return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('Works');
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of all exercises available.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links()
|
||||
{
|
||||
if (empty($this->course_code)) {
|
||||
return [];
|
||||
}
|
||||
$em = Database::getManager();
|
||||
$sessionId = $this->get_session_id();
|
||||
$session = $em->find('ChamiloCoreBundle:Session', $sessionId);
|
||||
/*
|
||||
if (empty($session_id)) {
|
||||
$session_condition = api_get_session_condition(0, true);
|
||||
} else {
|
||||
$session_condition = api_get_session_condition($session_id, true, true);
|
||||
}
|
||||
$sql = "SELECT id, url, title FROM $tbl_grade_links
|
||||
WHERE c_id = {$this->course_id} AND filetype='folder' AND active = 1 $session_condition ";*/
|
||||
|
||||
//Only show works from the session
|
||||
//AND has_properties != ''
|
||||
$links = $em
|
||||
->getRepository('ChamiloCourseBundle:CStudentPublication')
|
||||
->findBy([
|
||||
'cId' => $this->course_id,
|
||||
'active' => true,
|
||||
'filetype' => 'folder',
|
||||
'session' => $session,
|
||||
]);
|
||||
|
||||
foreach ($links as $data) {
|
||||
$work_name = $data->getTitle();
|
||||
if (empty($work_name)) {
|
||||
$work_name = basename($data->getUrl());
|
||||
}
|
||||
$cats[] = [$data->getId(), $work_name];
|
||||
}
|
||||
$cats = isset($cats) ? $cats : [];
|
||||
|
||||
return $cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone done this exercise yet ?
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
$id = $data['id'];
|
||||
|
||||
$em = Database::getManager();
|
||||
$session = $em->find('ChamiloCoreBundle:Session', $this->get_session_id());
|
||||
$results = $em
|
||||
->getRepository('ChamiloCourseBundle:CStudentPublication')
|
||||
->findBy([
|
||||
'cId' => $this->course_id,
|
||||
'parentId' => $id,
|
||||
'session' => $session,
|
||||
]);
|
||||
|
||||
return 0 != count($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $stud_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
$stud_id = (int) $stud_id;
|
||||
$em = Database::getManager();
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
if (empty($data)) {
|
||||
return [];
|
||||
}
|
||||
$id = $data['id'];
|
||||
$session = api_get_session_entity($this->get_session_id());
|
||||
|
||||
$assignment = $em
|
||||
->getRepository('ChamiloCourseBundle:CStudentPublication')
|
||||
->findOneBy([
|
||||
'cId' => $this->course_id,
|
||||
'id' => $id,
|
||||
'session' => $session,
|
||||
])
|
||||
;
|
||||
|
||||
$parentId = !$assignment ? 0 : $assignment->getId();
|
||||
|
||||
if (empty($session)) {
|
||||
$dql = 'SELECT a FROM ChamiloCourseBundle:CStudentPublication a
|
||||
WHERE
|
||||
a.cId = :course AND
|
||||
a.active = :active AND
|
||||
a.parentId = :parent AND
|
||||
a.session is null AND
|
||||
a.qualificatorId <> 0
|
||||
';
|
||||
|
||||
$params = [
|
||||
'course' => $this->course_id,
|
||||
'parent' => $parentId,
|
||||
'active' => true,
|
||||
];
|
||||
} else {
|
||||
$dql = 'SELECT a FROM ChamiloCourseBundle:CStudentPublication a
|
||||
WHERE
|
||||
a.cId = :course AND
|
||||
a.active = :active AND
|
||||
a.parentId = :parent AND
|
||||
a.session = :session AND
|
||||
a.qualificatorId <> 0
|
||||
';
|
||||
|
||||
$params = [
|
||||
'course' => $this->course_id,
|
||||
'parent' => $parentId,
|
||||
'session' => $session,
|
||||
'active' => true,
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($stud_id)) {
|
||||
$dql .= ' AND a.userId = :student ';
|
||||
$params['student'] = $stud_id;
|
||||
}
|
||||
|
||||
$order = api_get_setting('student_publication_to_take_in_gradebook');
|
||||
|
||||
switch ($order) {
|
||||
case 'last':
|
||||
// latest attempt
|
||||
$dql .= ' ORDER BY a.sentDate DESC';
|
||||
break;
|
||||
case 'first':
|
||||
default:
|
||||
// first attempt
|
||||
$dql .= ' ORDER BY a.id';
|
||||
break;
|
||||
}
|
||||
|
||||
$scores = $em->createQuery($dql)->execute($params);
|
||||
|
||||
// for 1 student
|
||||
if (!empty($stud_id)) {
|
||||
if (!count($scores)) {
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
$data = $scores[0];
|
||||
|
||||
return [
|
||||
$data->getQualification(),
|
||||
$assignment->getQualification(),
|
||||
api_get_local_time($assignment->getDateOfQualification()),
|
||||
1,
|
||||
];
|
||||
}
|
||||
|
||||
$students = []; // user list, needed to make sure we only
|
||||
// take first attempts into account
|
||||
$rescount = 0;
|
||||
$sum = 0;
|
||||
$bestResult = 0;
|
||||
$weight = 0;
|
||||
$sumResult = 0;
|
||||
|
||||
foreach ($scores as $data) {
|
||||
if (!(array_key_exists($data->getUserId(), $students))) {
|
||||
if (0 != $assignment->getQualification()) {
|
||||
$students[$data->getUserId()] = $data->getQualification();
|
||||
$rescount++;
|
||||
$sum += $data->getQualification() / $assignment->getQualification();
|
||||
$sumResult += $data->getQualification();
|
||||
|
||||
if ($data->getQualification() > $bestResult) {
|
||||
$bestResult = $data->getQualification();
|
||||
}
|
||||
$weight = $assignment->getQualification();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == $rescount) {
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
return [$bestResult, $weight];
|
||||
break;
|
||||
case 'average':
|
||||
return [$sumResult / $rescount, $weight];
|
||||
break;
|
||||
case 'ranking':
|
||||
return AbstractLink::getCurrentUserRanking($stud_id, $students);
|
||||
break;
|
||||
default:
|
||||
return [$sum, $rescount];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
$this->get_exercise_data();
|
||||
$name = isset($this->exercise_data['title']) && !empty($this->exercise_data['title']) ? $this->exercise_data['title'] : get_lang('Untitled');
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
public function get_description()
|
||||
{
|
||||
$this->get_exercise_data();
|
||||
|
||||
return isset($this->exercise_data['description']) ? $this->exercise_data['description'] : null;
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
$url = api_get_path(WEB_PATH).'main/work/work.php?'.api_get_cidreq_params($this->get_course_code(), $sessionId).'&id='.$this->exercise_data['id'].'&gradebook=view';
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function is_valid_link()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
$id = $data['id'];
|
||||
$sql = 'SELECT count(id) FROM '.$this->get_studpub_table().'
|
||||
WHERE
|
||||
c_id = "'.$this->course_id.'" AND
|
||||
id = '.$id;
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'studentpublication';
|
||||
}
|
||||
|
||||
public function save_linked_data()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
$id = $data['id'];
|
||||
|
||||
$weight = api_float_val($this->get_weight());
|
||||
if (!empty($id)) {
|
||||
//Cleans works
|
||||
$sql = 'UPDATE '.$this->get_studpub_table().'
|
||||
SET weight= '.$weight.'
|
||||
WHERE c_id = '.$this->course_id.' AND id ='.$id;
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function delete_linked_data()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!empty($id)) {
|
||||
//Cleans works
|
||||
$sql = 'UPDATE '.$this->get_studpub_table().'
|
||||
SET weight = 0
|
||||
WHERE c_id = '.$this->course_id.' AND id ='.$id;
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the student publications.
|
||||
*/
|
||||
private function get_studpub_table()
|
||||
{
|
||||
return $this->studpub_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the item properties.
|
||||
*/
|
||||
private function get_itemprop_table()
|
||||
{
|
||||
return $this->itemprop_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_exercise_data()
|
||||
{
|
||||
$course_info = api_get_course_info($this->get_course_code());
|
||||
if (!isset($this->exercise_data)) {
|
||||
$sql = 'SELECT * FROM '.$this->get_studpub_table()."
|
||||
WHERE
|
||||
c_id ='".$course_info['real_id']."' AND
|
||||
id = '".$this->get_ref_id()."' ";
|
||||
$query = Database::query($sql);
|
||||
$this->exercise_data = Database::fetch_array($query);
|
||||
|
||||
// Try with iid
|
||||
if (empty($this->exercise_data)) {
|
||||
$sql = 'SELECT * FROM '.$this->get_studpub_table()."
|
||||
WHERE
|
||||
c_id ='".$course_info['real_id']."' AND
|
||||
iid = '".$this->get_ref_id()."' ";
|
||||
$query = Database::query($sql);
|
||||
$this->exercise_data = Database::fetch_array($query);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->exercise_data;
|
||||
}
|
||||
}
|
||||
313
main/gradebook/lib/be/surveylink.class.php
Normal file
313
main/gradebook/lib/be/surveylink.class.php
Normal file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Gradebook link to a survey item.
|
||||
*
|
||||
* @author Ivan Tcholakov <ivantcholakov@gmail.com>, 2010
|
||||
*/
|
||||
class SurveyLink extends AbstractLink
|
||||
{
|
||||
private $survey_table;
|
||||
private $survey_data = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_SURVEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$this->get_survey_data();
|
||||
|
||||
return $this->survey_data['code'].': '.self::html_to_text($this->survey_data['title']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_description()
|
||||
{
|
||||
$this->get_survey_data();
|
||||
|
||||
return $this->survey_data['subtitle'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('Survey');
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of all surveys available.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links()
|
||||
{
|
||||
if (empty($this->course_code)) {
|
||||
exit('Error in get_all_links() : course code not set');
|
||||
}
|
||||
$tbl_survey = $this->get_survey_table();
|
||||
$sessionId = $this->get_session_id();
|
||||
$course_id = $this->getCourseId();
|
||||
|
||||
$sql = 'SELECT survey_id, title, code FROM '.$tbl_survey.'
|
||||
WHERE c_id = '.$course_id.' AND session_id = '.$sessionId;
|
||||
$result = Database::query($sql);
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
$links[] = [
|
||||
$data['survey_id'],
|
||||
api_trunc_str(
|
||||
$data['code'].': '.self::html_to_text($data['title']),
|
||||
80
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return isset($links) ? $links : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone done this survey yet?
|
||||
* Implementation of the AbstractLink class, mainly used dynamically in gradebook/lib/fe.
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$ref_id = $this->get_ref_id();
|
||||
$sessionId = $this->get_session_id();
|
||||
$courseId = $this->getCourseId();
|
||||
|
||||
$tbl_survey = Database::get_course_table(TABLE_SURVEY);
|
||||
$tbl_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
|
||||
$sql = "SELECT
|
||||
COUNT(i.answered)
|
||||
FROM $tbl_survey AS s
|
||||
JOIN $tbl_survey_invitation AS i ON s.code = i.survey_code
|
||||
WHERE
|
||||
s.c_id = $courseId AND
|
||||
i.c_id = $courseId AND
|
||||
s.survey_id = $ref_id AND
|
||||
i.session_id = $sessionId";
|
||||
|
||||
$sql_result = Database::query($sql);
|
||||
$data = Database::fetch_array($sql_result);
|
||||
|
||||
return 0 != $data[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate score for a student (to show in the gradebook).
|
||||
*
|
||||
* @param int $stud_id
|
||||
* @param string $type Type of result we want (best|average|ranking)
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
// Note: Max score is assumed to be always 1 for surveys,
|
||||
// only student's participation is to be taken into account.
|
||||
$max_score = 1;
|
||||
$ref_id = $this->get_ref_id();
|
||||
$sessionId = $this->get_session_id();
|
||||
$courseId = $this->getCourseId();
|
||||
$tbl_survey = Database::get_course_table(TABLE_SURVEY);
|
||||
$tbl_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
|
||||
$get_individual_score = !is_null($stud_id);
|
||||
|
||||
$sql = "SELECT i.answered
|
||||
FROM $tbl_survey AS s
|
||||
JOIN $tbl_survey_invitation AS i
|
||||
ON s.code = i.survey_code
|
||||
WHERE
|
||||
s.c_id = $courseId AND
|
||||
i.c_id = $courseId AND
|
||||
s.survey_id = $ref_id AND
|
||||
i.session_id = $sessionId
|
||||
";
|
||||
|
||||
if ($get_individual_score) {
|
||||
$sql .= ' AND i.user = '.intval($stud_id);
|
||||
}
|
||||
|
||||
$sql_result = Database::query($sql);
|
||||
|
||||
if ($get_individual_score) {
|
||||
// for 1 student
|
||||
if ($data = Database::fetch_array($sql_result)) {
|
||||
return [$data['answered'] ? $max_score : 0, $max_score];
|
||||
}
|
||||
|
||||
return [0, $max_score];
|
||||
} else {
|
||||
// for all the students -> get average
|
||||
$rescount = 0;
|
||||
$sum = 0;
|
||||
$bestResult = 0;
|
||||
while ($data = Database::fetch_array($sql_result)) {
|
||||
$sum += $data['answered'] ? $max_score : 0;
|
||||
$rescount++;
|
||||
if ($data['answered'] > $bestResult) {
|
||||
$bestResult = $data['answered'];
|
||||
}
|
||||
}
|
||||
$sum = $sum / $max_score;
|
||||
|
||||
if (0 == $rescount) {
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
return [$bestResult, $rescount];
|
||||
break;
|
||||
case 'average':
|
||||
return [$sum, $rescount];
|
||||
break;
|
||||
case 'ranking':
|
||||
return null;
|
||||
break;
|
||||
default:
|
||||
return [$sum, $rescount];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this still links to a survey.
|
||||
*/
|
||||
public function is_valid_link()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
$courseId = $this->getCourseId();
|
||||
|
||||
$sql = 'SELECT count(survey_id) FROM '.$this->get_survey_table().'
|
||||
WHERE
|
||||
c_id = '.$courseId.' AND
|
||||
survey_id = '.$this->get_ref_id().' AND
|
||||
session_id = '.$sessionId;
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
if (api_get_configuration_value('hide_survey_reporting_button')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (api_is_allowed_to_edit()) {
|
||||
// Let students make access only through "Surveys" tool.
|
||||
$tbl_name = $this->get_survey_table();
|
||||
$sessionId = $this->get_session_id();
|
||||
$courseId = $this->getCourseId();
|
||||
|
||||
if ('' != $tbl_name) {
|
||||
$sql = 'SELECT survey_id
|
||||
FROM '.$this->get_survey_table().'
|
||||
WHERE
|
||||
c_id = '.$courseId.' AND
|
||||
survey_id = '.$this->get_ref_id().' AND
|
||||
session_id = '.$sessionId;
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result, 'ASSOC');
|
||||
$survey_id = $row['survey_id'];
|
||||
|
||||
return api_get_path(WEB_PATH).'main/survey/reporting.php?'.api_get_cidreq_params($this->get_course_code(), $sessionId).'&survey_id='.$survey_id;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the icon for this tool.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'survey';
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the surveys.
|
||||
*/
|
||||
private function get_survey_table()
|
||||
{
|
||||
$this->survey_table = Database::get_course_table(TABLE_SURVEY);
|
||||
|
||||
return $this->survey_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the survey data from the c_survey table with the current object id.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function get_survey_data()
|
||||
{
|
||||
$tbl_name = $this->get_survey_table();
|
||||
|
||||
if ('' == $tbl_name) {
|
||||
return false;
|
||||
} elseif (empty($this->survey_data)) {
|
||||
$courseId = $this->getCourseId();
|
||||
$sessionId = $this->get_session_id();
|
||||
|
||||
$sql = 'SELECT * FROM '.$tbl_name.'
|
||||
WHERE
|
||||
c_id = '.$courseId.' AND
|
||||
survey_id = '.$this->get_ref_id().' AND
|
||||
session_id = '.$sessionId;
|
||||
$query = Database::query($sql);
|
||||
$this->survey_data = Database::fetch_array($query);
|
||||
}
|
||||
|
||||
return $this->survey_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function html_to_text($string)
|
||||
{
|
||||
return strip_tags($string);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user