/** * Build an HTML table containing navigation code for the given nodes * * @param array $nodes - The nodes (full sql row) whose children we want to navigate to * @param string $url - The php script to call in the navigational URLs * @param function $countCallback - An optional closure that will be used for the counting * @param bool $showEmpty - Whether to display nodes with count == 0 * @return string $ret - The returned HTML output */ public function buildNodesNavigationHtml($nodes, $url, $countCallback = null, $showEmpty = true, $subtrees = array()) { global $langAvCours, $langAvCourses; $ret = ''; if (count($nodes) > 0) { $nodesWK = array(); $coursedeps = array(); foreach ($nodes as $node) { $nodesWK[$node->id] = $node; } uasort($nodesWK, function ($a, $b) { $priorityA = intval($a->order_priority); $priorityB = intval($b->order_priority); $nameA = Hierarchy::unserializeLangField($a->name); $nameB = Hierarchy::unserializeLangField($b->name); if ($priorityA == $priorityB) { if ($nameA == $nameB) { return 0; } else { return $nameA > $nameB ? 1 : -1; } } else { return $priorityA < $priorityB ? 1 : -1; } }); // course department counting //SELECT COUNT(course_department.id) AS count,department FROM course_department // JOIN course ON course_department.course=course.id // WHERE course.visible != 3 GROUP BY department; /*Database::get()->queryFunc("select department, count(id) as count from course_department group by department", function($row) use (&$coursedeps) { $coursedeps[intval($row->department)] = $row->count; });*/ Database::get()->queryFunc("SELECT COUNT(course_department.id) AS count,department FROM course_department \n JOIN course ON course_department.course = course.id \n WHERE course.visible != " . COURSE_INACTIVE . " GROUP BY department", function ($row) use(&$coursedeps) { $coursedeps[intval($row->department)] = $row->count; }); foreach ($nodesWK as $key => $node) { $id = intval($key); $code = $node->code; $name = self::unserializeLangField($node->name); $count = 0; if (isset($subtrees[$id])) { foreach ($subtrees[$id] as $subkey => $subnode) { // TODO: callback mechanism might need further optimization to avoid repeating extra sql query foreach subnode if ($countCallback !== null && is_callable($countCallback)) { $count += $countCallback($subnode); } else { // fast count using pre-loaded array in memory $count += isset($coursedeps[$subnode]) ? $coursedeps[$subnode] : 0; } } } if ($showEmpty || $count > 0) { $ret .= "<li class='list-group-item' ><a href='{$url}.php?fc=" . $id . "'>" . q($name) . '</a>'; $ret .= strlen(q($code)) > 0 ? " (" . q($code) . ")" : ''; $ret .= "<small> - " . $count . " " . ($count == 1 ? $langAvCours : $langAvCourses) . "</small></li>"; } } } return $ret; }
/** * @param string $code * @param string $title * @param string $prof * @param string $lang * @param string $type - can be null * @param int $vis * @param string $desc * @param mixed $faculty - can be null */ function course_details_form($code, $title, $prof, $lang, $type, $vis, $desc, $faculty) { global $langInfo1, $langInfo2, $langCourseCode, $langLanguage, $langTitle, $langCourseDescription, $langFaculty, $langCourseVis, $langTeacher, $langUsersWillAdd, $langOk, $langAll, $langsTeachers, $langMultiRegType, $langNone, $langOldValue, $treeObj, $langBack, $course_code; list($tree_js, $tree_html) = $treeObj->buildCourseNodePicker(); if ($type) { if (isset($GLOBALS['lang' . $type])) { $type_label = ' (' . $GLOBALS['lang' . $type] . ')'; } else { $type_label = ' (' . $type . ')'; } } else { $type_label = ''; } if (is_array($faculty)) { foreach ($faculty as $entry) { $old_faculty_names[] = q(Hierarchy::unserializeLangField($entry['name'])); } $old_faculty = implode('<br>', $old_faculty_names); } else { $old_faculty = q(Hierarchy::unserializeLangField($faculty) . $type_label); } $formAction = $_SERVER['SCRIPT_NAME']; if (isset($GLOBALS['course_code'])) { $formAction .= '?course=' . $GLOBALS['course_code']; } return action_bar(array( array('title' => $langBack, 'url' => "index.php?course=$course_code", 'icon' => 'fa-reply', 'level' => 'primary-label'))) . " <div class='alert alert-info'>$langInfo1 <br> $langInfo2</div> <div class='row'> <div class='col-md-12'> <div class='form-wrapper' > <form class='form-horizontal' role='form' action='$formAction' method='post' onsubmit='return validateNodePickerForm();' > <div class='form-group'> <label for='course_code' class='col-sm-3 control-label'>$langCourseCode:</label> <div class='col-sm-9'> <input type='text' class='form-control' id='course_code' name='course_code' value='" . q($code) . "'> </div> </div> <div class='form-group'> <label for='course_code' class='col-sm-3 control-label'>$langLanguage:</label> <div class='col-sm-9'> " . lang_select_options('course_lang') . " </div> </div> <div class='form-group'> <label for='course_title' class='col-sm-3 control-label'>$langTitle:</label> <div class='col-sm-9'> <input class='form-control' type='text' id='course_title' name='course_title' value='" . q($title) . "' /> </div> </div> <div class='form-group'> <label class='col-sm-3 control-label'>$langCourseDescription:</label> <div class='col-sm-9'> " . rich_text_editor('course_desc', 10, 40, purify($desc)) . " </div> </div> <div class='form-group'> <label class='col-sm-3 control-label'>$langFaculty:</label> <div class='col-sm-9'> " . $tree_html . "<br>$langOldValue: <i>$old_faculty</i> </div> </div> <div class='form-group'> <label class='col-sm-3 control-label'>$langCourseVis:</label> <div class='col-sm-9'> " . visibility_select($vis) . " </div> </div> <div class='form-group'> <label for='course_prof' class='col-sm-3 control-label'>$langTeacher:</label> <div class='col-sm-9'> <input class='form-control' type='text' id='course_prof' name='course_prof' value='" . q($prof) . "' size='50' /> </div> </div> <div class='form-group'> <label class='col-sm-3 control-label'>$langUsersWillAdd:</label> <div class='col-sm-9'> <input type='radio' name='add_users' value='all' id='add_users_all' checked='checked'> $langAll<br> <input type='radio' name='add_users' value='prof' id='add_users_prof'> $langsTeachers<br> <input type='radio' name='add_users' value='none' id='add_users_none'> $langNone </div> </div> <div class='form-group'> <label class='col-sm-3 control-label'>$langMultiRegType:</label> <div class='col-sm-9'> <input type='checkbox' name='create_users' value='1' id='create_users' checked='checked'> </div> </div> <div class='form-group'> <div class='col-sm-offset-3 col-sm-9'> <input class='btn btn-primary' type='submit' name='create_restored_course' value='$langOk' /> <input type='hidden' name='restoreThis' value='" . q($_POST['restoreThis']) . "' /> </div> </div> " . generate_csrf_token_form_field() . " </form> </div> </div> </div> "; }
($suballowed != null && !in_array($node->id, $suballowed))) { $disabled = true; } // exclude if ($node->lft >= $excludeLft && $node->rgt <= $excludeRgt) { $disabled = true; } $class1 = $disabled ? 'nosel' : ''; $class2 = classOfUserNodes($usernodes, $node); $class = (strlen($class2) > 0) ? $class1 . ' ' . $class2 : $class1; $valcode = ($codesuffix && strlen($node->code) > 0) ? ' (' . $node->code . ')' : ''; $data[] = array( "id" => $node->id, "text" => Hierarchy::unserializeLangField($node->name) . $valcode, "state" => array("disabled" => $disabled), "children" => (($node->rgt - $node->lft) > 1), "li_attr" => array( "tabindex" => intval($node->order_priority) ), "a_attr" => array( "class" => $class ) ); } echo json_encode($data); exit(); function classOfUserNodes($usernodes, $node) {