public static function CanUserViewLessonAsPublic($arParams) { // Parse options (user_id from $arParams will be automaticaly resolved) $options = self::ParseParamsWithUser($arParams, array('COURSE_ID' => array('type' => 'strictly_castable_to_integer', 'mandatory' => true), 'LESSON_ID' => array('type' => 'strictly_castable_to_integer', 'mandatory' => true))); // Is it course? $linkedLessonId = CCourse::CourseGetLinkedLesson($options['COURSE_ID']); if ($linkedLessonId === false) { return false; } // Access denied $lessonId = $options['LESSON_ID']; $breakOnLessonId = $linkedLessonId; // save resources // Is lesson included into given course? $isLessonChildOfCourse = false; $arOPathes = CLearnLesson::GetListOfParentPathes($lessonId, $breakOnLessonId); foreach ($arOPathes as $oPath) { $topLessonId = $oPath->GetTop(); if ($topLessonId !== false && $topLessonId == $linkedLessonId) { $isLessonChildOfCourse = true; break; } } if (!$isLessonChildOfCourse) { return false; } // Access denied // Check permissions for course $isCourseAccessible = self::CanUserViewLessonContent(array('lesson_id' => $linkedLessonId)); // Permissions for all lessons/chapters in public are equivalent to course permissions return $isCourseAccessible; }
public static function OnGetRatingContentOwner($arParams) { if ($arParams['ENTITY_TYPE_ID'] == 'LEARN_LESSON') { $arFilter = array('LESSON_ID' => intval($arParams['ENTITY_ID'])); $Item = CLearnLesson::GetList($arOrder = array(), $arFilter); if ($arItem = $Item->Fetch()) { return $arItem['CREATED_BY']; } else { return 0; } } return false; }
/** * simple & stupid stub * @deprecated */ public static function GetList($arOrder = 'will be ignored', $arFilter = array()) { // We must replace '...ID' => '...LESSON_ID', // where '...' is some operation (such as '!', '<=', etc.) foreach ($arFilter as $key => $value) { // If key ends with 'ID' if (strlen($key) >= 2 && strtoupper(substr($key, -2)) === 'ID') { // And prefix before 'ID' doesn't contains letters if (!preg_match("/[a-zA-Z_]+/", substr($key, 0, -2))) { $prefix = ''; if (strlen($key) > 2) { $prefix = substr($key, 0, -2); } $arFields[$prefix . 'LESSON_ID'] = $arFilter[$key]; unset($arFilter[$key]); } } } return CLearnLesson::GetList(array(), $arFilter); }
public static function OnSearchReindex($NS = array(), $oCallback = null, $callback_method = '') { global $DB; static $arCourseToSiteCache = array(); $arResult = array(); $arAllSitesPathes = array(); $elementStartId = 0; $indexElementType = 'C'; // start reindex from courses $by = $order = ''; $sites = CLang::GetList($by, $order, array('TYPE' => 'C')); while ($site = $sites->Fetch()) { $arAllSitesPathes[$site['LID']] = array('C' => CCourse::GetSitePathes($site['LID'], 'C'), 'H' => CCourse::GetSitePathes($site['LID'], 'H'), 'L' => CCourse::GetSitePathes($site['LID'], 'L')); } $arCoursesFilter = array(); $arLessonsFilter = array('LINKED_LESSON_ID' => ''); if ($NS['MODULE'] === 'learning' && strlen($NS['ID']) > 0) { $indexElementType = substr($NS['ID'], 0, 1); $elementStartId = (int) substr($NS['ID'], 1); if (strlen($NS['SITE_ID']) > 0) { $arCoursesFilter['SITE_ID'] = $NS['SITE_ID']; } } $arCoursesFilter['>ID'] = $elementStartId; if ($indexElementType === 'C') { $rsCourse = CCourse::GetList(array('ID' => 'ASC'), $arCoursesFilter); while ($arCourse = $rsCourse->Fetch()) { try { $arCourse["SITE_ID"] = CCourse::GetSiteId($arCourse['ID']); $arPathes = $arAllSitesPathes[$arCourse['SITE_ID']]['C']; $linkedLessonId = CCourse::CourseGetLinkedLesson($arCourse['ID']); if ($linkedLessonId === false) { continue; } $arGroupPermissions = CLearnAccess::GetSymbolsAccessibleToLesson($linkedLessonId, CLearnAccess::OP_LESSON_READ); } catch (LearnException $e) { continue; // skip indexation of this item } $arSiteIds = array(); foreach ($arPathes as $k => $path) { $arCourse["PATH"] = $path; $Url = str_replace("#COURSE_ID#", $arCourse["ID"], $arCourse["PATH"]); $arSiteIds[$arCourse['SITE_ID']] = $Url; } if ($arCourse["DETAIL_TEXT_TYPE"] !== 'text') { $detailText = CSearch::KillTags($arCourse['DETAIL_TEXT']); } else { $detailText = strip_tags($arCourse['DETAIL_TEXT']); } if (strlen($detailText) > 0) { $dataBody = $detailText; } else { $dataBody = $arCourse['NAME']; } $Result = array("ID" => "C" . $arCourse["ID"], "LAST_MODIFIED" => $arCourse["TIMESTAMP_X"], "TITLE" => $arCourse["NAME"], "BODY" => $dataBody, "SITE_ID" => $arSiteIds, "PERMISSIONS" => $arGroupPermissions, "COURSE_ID" => "C" . $arCourse["ID"]); if ($oCallback) { $res = call_user_func(array($oCallback, $callback_method), $Result); if (!$res) { return "C" . $arCourse["ID"]; } } else { $arResult[] = $Result; } } // Reindex of courses finished. Let's reindex lessons now. $indexElementType = 'U'; $elementStartId = 0; } $arLessonsFilter['>LESSON_ID'] = $elementStartId; if ($indexElementType === 'U') { $rsLessons = CLearnLesson::GetList(array('LESSON_ID' => 'ASC'), $arLessonsFilter); while ($arLessonFromDb = $rsLessons->Fetch()) { $arLessonsWithCourse = array(); // list of lessons in context of some course $arOParentPathes = CLearnLesson::GetListOfParentPathes($arLessonFromDb['LESSON_ID']); foreach ($arOParentPathes as $oParentPath) { $arParentLessons = $oParentPath->GetPathAsArray(); foreach ($arParentLessons as $lessonId) { $linkedCourseId = CLearnLesson::GetLinkedCourse($lessonId); if ($linkedCourseId !== false && $linkedCourseId > 0) { $arLessonsWithCourse[] = array_merge($arLessonFromDb, array('PARENT_COURSE_ID' => $linkedCourseId)); } } } foreach ($arLessonsWithCourse as $arLesson) { try { $arGroupPermissions = CLearnAccess::GetSymbolsAccessibleToLesson($arLesson['LESSON_ID'], CLearnAccess::OP_LESSON_READ); $courseId = $arLesson['PARENT_COURSE_ID']; if (!isset($arCourseToSiteCache[$courseId])) { $strSql = "SELECT SITE_ID FROM b_learn_course_site WHERE COURSE_ID=" . (int) $courseId; $rc = $DB->Query($strSql, true); if ($rc === false) { continue; } $arCourseToSiteCache[$courseId] = array(); while ($arCourseSite = $rc->fetch()) { $arCourseToSiteCache[$courseId][] = $arCourseSite['SITE_ID']; } } $arAllowedSites = $arCourseToSiteCache[$courseId]; if (empty($arAllowedSites)) { continue; } $arSiteIds = array(); $lessonType = 'L'; if ($arLesson['IS_CHILDS']) { $lessonType = 'H'; } foreach ($arAllSitesPathes as $siteId => $arSitePathesByLessonType) { if (!in_array($siteId, $arAllowedSites, true)) { continue; } foreach ($arSitePathesByLessonType as $someLessonType => $arPathes) { // skip wrong types of lessons if ($lessonType !== $someLessonType) { continue; } foreach ($arPathes as $k => $path) { if ($lessonType == 'H') { $Url = str_replace("#CHAPTER_ID#", '0' . $arLesson['LESSON_ID'], $path); } else { $Url = str_replace("#LESSON_ID#", $arLesson['LESSON_ID'], $path); } $Url = str_replace("#COURSE_ID#", $arLesson['PARENT_COURSE_ID'], $Url); $arSiteIds[$siteId] = $Url; } } } } catch (LearnException $e) { continue; // skip indexation of this item } if ($arLesson["DETAIL_TEXT_TYPE"] !== 'text') { $detailText = CSearch::KillTags($arLesson['DETAIL_TEXT']); } else { $detailText = strip_tags($arLesson['DETAIL_TEXT']); } if (strlen($detailText) > 0) { $dataBody = $detailText; } else { $dataBody = $arLesson['NAME']; } $Result = array("ID" => 'U' . $arLesson['LESSON_ID'], "LAST_MODIFIED" => $arLesson['TIMESTAMP_X'], "TITLE" => $arLesson['NAME'], "BODY" => $dataBody, "SITE_ID" => $arSiteIds, "PERMISSIONS" => $arGroupPermissions); if ($oCallback) { $res = call_user_func(array($oCallback, $callback_method), $Result); if (!$res) { return 'U' . $arLesson['LESSON_ID']; } } else { $arResult[] = $Result; } } } } if ($oCallback) { $rc = false; } else { $rc = $arResult; } return $rc; }
/** * This function builds subquery (for oracle) or comma-separated * list of lessons IDs (for mysql/mssql) for SQL WHERE clause, * which selects/contains all child lessons (only childs, * without parent lesson). This functions prevents cycling. * * Warning: currently * * @example * on oracle SQLClauseForAllSubLessons(13) returns subquery: * SELECT b_learn_lesson_edges.TARGET_NODE * FROM b_learn_lesson_edges * START WITH b_learn_lesson_edges.SOURCE_NODE=13 * CONNECT BY NOCYCLE PRIOR b_learn_lesson_edges.TARGET_NODE = b_learn_lesson_edges.SOURCE_NODE * * on mysql/mssql SQLClauseForAllSubLessons(13) returns list of child lessons: * 14, 16, 120, 875, 476 * * Any of this strings can be used in WHERE IN(...our string...) clause. * * Complete example: * <?php * $parentLessonId = 447; * $clauseChilds = CLearnHelper::SQLClauseForAllSubLessons($parentLessonId); * $strSql = " * SELECT * * FROM b_learn_lesson * WHERE ID IN ($clauseChilds) OR (ID = $parentLessonId)"; * // Selects list of all childs with parentLessonId included. * $CDBresult = $DB->Query ($strSql); * * @param int parent lesson id * @return string for using in WHERE IN() clause: sql subquery or * comma-separated list of lesson's ids. */ public static function SQLClauseForAllSubLessons($parentLessonId) { global $DBType; if (!(is_numeric($parentLessonId) && is_int($parentLessonId + 0))) { throw new LearnException('$parentLessonId must be strictly castable to integer', LearnException::EXC_ERR_ALL_PARAMS); } if ($DBType === 'oracle') { // This subquery gets ids of all childs lesson for given $parentLessonId $rc = "\n\t\t\t\tSELECT b_learn_lesson_edges.TARGET_NODE\n\t\t\t\tFROM b_learn_lesson_edges\n\t\t\t\tSTART WITH b_learn_lesson_edges.SOURCE_NODE=" . ($parentLessonId + 0) . "\n\t\t\t\tCONNECT BY NOCYCLE PRIOR b_learn_lesson_edges.TARGET_NODE = b_learn_lesson_edges.SOURCE_NODE"; return $rc; } elseif ($DBType === 'mysql' || $DBType === 'mssql') { // MySQL & MSSQL supports "WHERE IN(...)" clause for more than 10 000 elements $oTree = CLearnLesson::GetTree($parentLessonId, array('EDGE_SORT' => 'ASC'), array('CHECK_PERMISSIONS' => 'N')); $arChildLessonsIds = $oTree->GetLessonsIdListInTree(); // parent lesson id isn't included // We need escape data for SQL $arChildLessonsIdsEscaped = array_map('intval', $arChildLessonsIds); $sqlChildLessonsIdsList = implode(', ', $arChildLessonsIdsEscaped); // No childs => nothing must be selected if (strlen($sqlChildLessonsIdsList) == 0) { $sqlChildLessonsIdsList = 'NULL'; } // NULL != any value. NULL != NULL too. return $sqlChildLessonsIdsList; } }
public static function getActiveLearningChaptersPeriod($courseLessonId, $userId) { $arGroupsPeriods = self::getActiveLearningGroupsPeriod($courseLessonId, $userId); if (!$arGroupsPeriods['IS_EXISTS']) { return false; } $arChaptersActiveFrom = array(); $arGroupsActiveFrom = $arGroupsPeriods['GROUPS_ACTIVE_FROM']; $arLessons = array(); $rs = CLearnLesson::GetListOfImmediateChilds($courseLessonId, array(), array('CHECK_PERMISSIONS' => 'N'), array('LESSON_ID')); $arMinChaptersActiveFromTimestamp = array(); while ($ar = $rs->fetch()) { $arLessons[$ar['LESSON_ID']] = $ar['NAME']; $arChaptersActiveFrom[$ar['LESSON_ID']] = null; $arMinChaptersActiveFromTimestamp[$ar['LESSON_ID']] = PHP_INT_MAX; } // Get the nearest dates, when lesson can be opened foreach ($arGroupsActiveFrom as $groupId => $groupActiveFrom) { if ($groupActiveFrom === null) { continue; } $arDelays = CLearningGroupLesson::getDelays($groupId, array_keys($arLessons)); $groupActiveFromTs = MakeTimeStamp($groupActiveFrom); foreach ($arDelays as $lessonId => $delay) { $fromTs = $groupActiveFromTs + 86400 * $delay; // 24h is 86400 seconds // search for nearest dates if ($fromTs < $arMinChaptersActiveFromTimestamp[$lessonId]) { $arChaptersActiveFrom[$lessonId] = ConvertTimeStamp($fromTs, 'FULL'); $arMinChaptersActiveFromTimestamp[$lessonId] = $fromTs; } } } return $arChaptersActiveFrom; }
$bCanUserEdit = CLearnAccessMacroses::CanUserEditLesson(array('lesson_id' => $arParams['LESSON_ID'])) || $USER->IsAdmin(); $bCanUserRemove = CLearnAccessMacroses::CanUserRemoveLesson(array('lesson_id' => $arParams['LESSON_ID'])) || $USER->IsAdmin(); if ($bCanUserEdit || $bCanUserRemove) { $arAreaButtons = array(); $deleteReturnUrl = ""; if ($bCanUserRemove) { if ($parent = $this->GetParent()) { $parentLessonId = 0; $lessonPath = ""; if (strlen($arParams["LESSON_PATH"]) > 0) { $path = new CLearnPath(); $path->ImportUrlencoded($arParams["LESSON_PATH"]); $path->PopBottom(); $lessonPath = $path->ExportUrlencoded(); $lessonId = $path->PopBottom(); $edgesToParents = CLearnLesson::ListImmediateParents($arParams["LESSON_ID"]); foreach ($edgesToParents as $arEdgeToParent) { if ((int) $arEdgeToParent['PARENT_LESSON'] === (int) $lessonId) { $parentLessonId = $lessonId; break; } } } if ($parentLessonId) { $deleteReturnUrl = CComponentEngine::MakePathFromTemplate($parent->arResult["FOLDER"] . $parent->arResult["URL_TEMPLATES"]["chapter.detail"], array("CHAPTER_ID" => "0" . $parentLessonId, "COURSE_ID" => $arParams['COURSE_ID'])); $deleteReturnUrl .= strpos($deleteReturnUrl, "?") !== false ? "&" : "?"; $deleteReturnUrl .= "LESSON_PATH=" . $lessonPath; } else { $deleteReturnUrl = CComponentEngine::MakePathFromTemplate($parent->arResult["FOLDER"] . $parent->arResult["URL_TEMPLATES"]["course.detail"], array("COURSE_ID" => $arParams['COURSE_ID'])); } }
$rsQuestion = CLQuestion::GetByID($arTestResult["QUESTION_ID"]); if ($arQuestion = $rsQuestion->GetNext()) { // Resolve links "?COURSE_ID={SELF}". Don't relay on it, this behaviour // can be changed in future without any notifications. if (isset($arQuestion['DESCRIPTION'])) { $arQuestion['DESCRIPTION'] = CLearnHelper::PatchLessonContentLinks($arQuestion['DESCRIPTION'], $arParams['COURSE_ID']); } if ($arQuestion["QUESTION_TYPE"] != "T") { if ($arTest["SHOW_ERRORS"] == "Y" && $result["CORRECT"] == "N" && $result["ANSWERED"] == "Y" && $arQuestion["INCORRECT_MESSAGE"]) { $sessIncorrectMessage = $arQuestion; if ($arTest["NEXT_QUESTION_ON_ERROR"] == "N" && $arTest["PASSAGE_TYPE"] == 2) { $arResult["REDIRECT_PAGE"] = str_replace("#PAGE_ID#", array_key_exists($arParams["PAGE_NUMBER_VARIABLE"], $_REQUEST) ? $arResult["NAV"]["PAGE_NUMBER"] - 1 : 1, $arResult["PAGE_TEMPLATE"]); } } } elseif ($arQuestion["EMAIL_ANSWER"] == "Y") { $rsLesson = CLearnLesson::GetByID($arQuestion['LESSON_ID']); if ($arLesson = $rsLesson->GetNext()) { $rsTeacher = CUser::GetByID($arLesson["CREATED_BY"]); if ($arTeacher = $rsTeacher->GetNext()) { $courseName = ""; $rsCourse = CCourse::GetByID($arTest["COURSE_ID"]); if ($arCourse = $rsCourse->GetNext()) { $courseName = $arCourse["NAME"]; } $arEventFields = array("ID" => $testResultID, "ATTEMPT_ID" => $sessAttemptID, "TEST_NAME" => $arTest["NAME"], "COURSE_NAME" => $courseName, "USER" => "(" . $USER->GetLogin() . ")" . (strlen($USER->GetFullName()) > 0 ? " " . $USER->GetFullName() : ""), "DATE" => date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), time()), "QUESTION_TEXT" => $arQuestion["NAME"], "ANSWER_TEXT" => $_REQUEST["answer"], "EMAIL_FROM" => COption::GetOptionString("main", "email_from", "*****@*****.**"), "EMAIL_TO" => $arTeacher["EMAIL"], "MESSAGE_TITLE" => GetMessage("LEARNING_NEW_TEXT_ANSWER")); $arrSITE = LANG; CEvent::Send("NEW_LEARNING_TEXT_ANSWER", $arrSITE, $arEventFields, "N"); } } } }
$APPLICATION->SetTitle($arResult["COURSE"]["NAME"]); } $parent =& $this->GetParent(); //Course description item $url = CComponentEngine::MakePathFromTemplate($arParams["COURSE_DETAIL_TEMPLATE"], array("COURSE_ID" => $arParams["COURSE_ID"])); $arResult["ITEMS"][] = array("NAME" => GetMessage("LEARNING_COURSE_DESCRIPTION"), "URL" => $url, "TYPE" => "CD", "SELECTED" => $parent->arResult["VARIABLES"]["INDEX"] == "Y", "DEPTH_LEVEL" => 1); $CHAPTER_ID = $parent->arResult["VARIABLES"]["CHAPTER_ID"]; if ($CHAPTER_ID > 0) { if (CLearnPath::IsUrlencodedPath($CHAPTER_ID)) { $oTmp = new CLearnPath(); $oTmp->ImportUrlencoded($CHAPTER_ID); $CHAPTER_ID = (int) $oTmp->GetBottom(); } elseif (substr($CHAPTER_ID, 0, 1) === '0') { $CHAPTER_ID = (int) substr($CHAPTER_ID, 1); } else { $CHAPTER_ID = (int) CLearnLesson::LessonIdByChapterId($CHAPTER_ID); } } else { $CHAPTER_ID = false; } $lessonCount = 0; $lessonCurrent = 0; // Get Course Content $arContents = CLearnCacheOfLessonTreeComponent::GetData($arParams['COURSE_ID']); foreach ($arContents as $arContent) { if ($arContent["TYPE"] == "CH") { $itemURL = CComponentEngine::MakePathFromTemplate($arParams["CHAPTER_DETAIL_TEMPLATE"], array("CHAPTER_ID" => '0' . $arContent["ID"], "COURSE_ID" => $arParams["COURSE_ID"])); if ($CHAPTER_ID == $arContent["ID"]) { $arContent["SELECTED"] = true; } else { $arContent["SELECTED"] = false;
:</td> <td> <input type="text" name="SORT" size="4" maxlength="10" value="<?php echo htmlspecialcharsbx($str_SORT); ?> "> </td> </tr> <?php $tabControl->EndCustomField("SORT"); $tabControl->AddSection("LEARNING_ACTIVATION_SCHEDULE", GetMessage('LEARNING_ACTIVATION_SCHEDULE')); $tabControl->BeginCustomField("PROPERTY_2", GetMessage('LEARNING_ACTIVATION_SCHEDULE_TITLE'), false); $html = '<table cellpadding="0" cellspacing="0" border="0" class="nopadding" width="100%" id="tb' . md5($name) . '">'; $arLessons = $arDelays = array(); if ($ID && $str_COURSE_LESSON_ID) { $rs = CLearnLesson::GetListOfImmediateChilds($str_COURSE_LESSON_ID, array('SORT' => 'ASC')); while ($ar = $rs->getNext()) { $arLessons[$ar['LESSON_ID']] = $ar['NAME']; } $arDelays = CLearningGroupLesson::getDelays($ID, array_keys($arLessons)); foreach ($arLessons as $lessonId => $lessonName) { $period = $arDelays[$lessonId]; $html .= '<tr><td>'; $html .= $lessonName; $html .= '</td><td>'; $html .= '<input type="text" name="PERIOD_L[' . $lessonId . ']" size="4" maxlength="5" value="' . htmlspecialcharsbx($period) . '">'; $html .= '</td></tr>'; } } else { $html .= GetMessage('LEARNING_AVAILABLE_AFTER_ELEMENT_CREATION'); }
public static function GetFilter($arFilter) { global $DBType; if (!is_array($arFilter)) { $arFilter = array(); } $arSqlSearch = array(); foreach ($arFilter as $key => $val) { $res = CLearnHelper::MkOperationFilter($key); $key = $res["FIELD"]; $cOperationType = $res["OPERATION"]; $key = strtoupper($key); switch ($key) { case "ID": case "SORT": case "LESSON_ID": case "POINT": $arSqlSearch[] = CLearnHelper::FilterCreate("CQ." . $key, $val, "number", $bFullJoin, $cOperationType); break; case "COURSE_ID": // was: $arSqlSearch[] = CLearnHelper::FilterCreate("C.".$key, $val, "number", $bFullJoin, $cOperationType); $courseLessonId = CCourse::CourseGetLinkedLesson($val); if ($courseLessonId === false) { break; } // it is not a course, so skipping if ($DBType === 'oracle') { // This subquery gets ids of all childs lesson for given $courseLessonId $subQuery = "\n\t\t\t\t\t\t\tSELECT TLE.TARGET_NODE\n\t\t\t\t\t\t\tFROM b_learn_lesson_edges TLE\n\t\t\t\t\t\t\tSTART WITH TLE.SOURCE_NODE=" . ($courseLessonId + 0) . "\n\t\t\t\t\t\t\tCONNECT BY NOCYCLE PRIOR TLE.TARGET_NODE = TLE.SOURCE_NODE"; // But we need also $courseLessonId itself, so final clause will be: $arSqlSearch[] = '(CQ.LESSON_ID IN (' . $subQuery . ') OR CQ.LESSON_ID = ' . ($courseLessonId + 0) . ')'; } elseif ($DBType === 'mysql' || $DBType === 'mssql') { // MySQL & MSSQL supports "WHERE IN(...)" clause for more than 10 000 elements // add to sql "WHERE" constraint: lessons id only from given array $sqlCourseLessonsIdsList = ''; $oTree = CLearnLesson::GetTree($courseLessonId); $arChildLessonForCourse = $oTree->GetLessonsIdListInTree(); // root lesson not in tree, so add it $arChildLessonForCourse[] = $courseLessonId; // We need escape data for SQL $arChildLessonForCourseEscaped = array_map('intval', $arChildLessonForCourse); $sqlCourseLessonsIdsList = implode(', ', $arChildLessonForCourseEscaped); if (strlen($sqlCourseLessonsIdsList) > 0) { $arSqlSearch[] = 'CQ.LESSON_ID IN (' . $sqlCourseLessonsIdsList . ')'; } } else { throw new LearnException('Unsupported DB engine: ' . $DBType, LearnException::EXC_ERR_ALL_GIVEUP); } break; case "NAME": $arSqlSearch[] = CLearnHelper::FilterCreate("CQ." . $key, $val, "string", $bFullJoin, $cOperationType); break; case "QUESTION_TYPE": case "ACTIVE": case "SELF": case "CORRECT_REQUIRED": $arSqlSearch[] = CLearnHelper::FilterCreate("CQ." . $key, $val, "string_equal", $bFullJoin, $cOperationType); break; } } return $arSqlSearch; }
protected function _MakeItems($TITLE, $TYPE, $LAUNCH, $PARENT_ID) { global $APPLICATION; if ($PARENT_ID === 0) { $linkToParentLessonId = CCourse::CourseGetLinkedLesson($this->COURSE_ID); } else { $linkToParentLessonId = (int) $PARENT_ID; } if ($TYPE == "LES") { $arFields = array('NAME' => $TITLE, 'LAUNCH' => $LAUNCH, 'DETAIL_TEXT_TYPE' => "file"); } elseif ($TYPE == "CHA") { $arFields = array('NAME' => $TITLE); } else { return $PARENT_ID; } // properties (in context of parent) by default $arProperties = array('SORT' => 500); $ID = CLearnLesson::Add($arFields, false, $linkToParentLessonId, $arProperties); if ($ID > 0) { return $ID; } else { if ($e = $APPLICATION->GetException()) { $this->arWarnings[$TYPE][] = array("TITLE" => $TITLE, "TEXT" => $e->GetString()); } } }
public function _GetCourseContent($parentLessonId, $DEPTH_LEVEL = 1) { global $DB; $res = CLearnLesson::GetListOfImmediateChilds($parentLessonId, array('EDGE_SORT' => 'asc')); while ($arRes = $res->Fetch()) { $arRes['ID'] = $arRes['LESSON_ID']; // for compatibility if ($arRes['IS_CHILDS'] == '1') { $itemType = 'CHA'; } else { $itemType = 'LES'; } if (CLearnLesson::IsPublishProhibited($arRes['LESSON_ID'], $parentLessonId)) { $arRes['META_PUBLISH_PROHIBITED'] = 'Y'; } else { $arRes['META_PUBLISH_PROHIBITED'] = 'N'; } $r = ++$this->RefID; $this->arItems[$r] = $this->_CreateContent($itemType, $arRes, $r); $this->strItems .= '<item identifier="' . $itemType . $r . '" identifierref="RES' . $r . '"><title>' . htmlspecialcharsbx($arRes["NAME"]) . '</title>'; $this->strResourses .= '<resource identifier="RES' . $r . '" type="webcontent" href="res' . $r . '.xml">' . $this->_GetResourceFiles($r) . '</resource>'; $this->createQuestionItems($arRes["ID"]); // Load content recursively for chapters if ($arRes['IS_CHILDS'] == '1') { $this->_GetCourseContent($arRes["ID"], $DEPTH_LEVEL + 1); } $this->strItems .= "</item>"; } }
if ($str_QUESTIONS_FROM == "A" && intval($str_QUESTIONS_AMOUNT) == 0) { echo " checked"; } ?> onClick="OnChangeAnswer('');"><label for="QUESTIONS_FROM_A"><?php echo GetMessage("LEARNING_QUESTIONS_FROM_ALL"); ?> </label></td> </tr> <?php $linkedLessonId = CCourse::CourseGetLinkedLesson($COURSE_ID); if ($linkedLessonId === false) { throw new Exception(); } $oTree = CLearnLesson::GetTree($linkedLessonId); $arSubLessons = $oTree->GetTreeAsList(); // because of some troubles with backward compatibility, some clients can have QUESTIONS_FROM === 'H' if ($str_QUESTIONS_FROM == "H") { ?> <input style="display:none;" type="radio" name="QUESTIONS_FROM" value="H" checked="checked"> <input type="hidden" name="QUESTIONS_FROM_ID_H" value="<?php echo $str_QUESTIONS_FROM_ID; ?> "> <?php } ?> <tr> <td colspan="2"> <input type="radio" name="QUESTIONS_FROM" id="QUESTIONS_FROM_R" value="R"
public function SaveInlineEditedItems() { if (!$this->IsNeedSaveInlineEditedItems()) { return $this; } if (check_bitrix_sessid() !== true) { throw new CLearnRenderAdminUnilessonListException('', CLearnRenderAdminUnilessonListException::C_ACCESS_DENIED); } foreach ($_POST['FIELDS'] as $lessonId => $arFields) { $arEdgeProperties = array(); $wasError = false; try { // skip not changed items if (!$this->oList->IsUpdated($lessonId)) { continue; } // throws exception if access denied $this->EnsureLessonUpdateAccess($lessonId); $courseId = CLearnLesson::GetLinkedCourse($lessonId); // Depends on current list mode, we must update sort index // of element (only for course) or sort index of relation between // child and parent lessons. // So, we must rename SORT to COURSE_SORT or EDGE_SORT if (array_key_exists('SORT', $arFields)) { if ($this->IsListAnyCoursesMode() && $courseId !== false) { $arFields['COURSE_SORT'] = $arFields['SORT']; } elseif ($this->IsListChildLessonsMode()) { $arFields['EDGE_SORT'] = $arFields['SORT']; } else { throw new CLearnRenderAdminUnilessonListException('', CLearnRenderAdminUnilessonListException::C_LOGIC | CLearnRenderAdminUnilessonListException::C_ACTION_UPDATE_FAIL); } unset($arFields['SORT']); } if (isset($arFields['EDGE_SORT'])) { if (isset($_GET['PARENT_LESSON_ID'])) { $arEdgeProperties['SORT'] = $arFields['EDGE_SORT']; } unset($arFields['EDGE_SORT']); } // PUBLISH_PROHIBITED if (array_key_exists('PUBLISH_PROHIBITED', $arFields)) { // PUBLISH_PROHIBITED available in context of most parent course only if ($this->contextCourseLessonId !== false && in_array($arFields['PUBLISH_PROHIBITED'], array('N', 'Y'), true)) { $isProhibited = true; if ($arFields['PUBLISH_PROHIBITED'] === 'N') { $isProhibited = false; } CLearnLesson::PublishProhibitionSetTo($lessonId, $this->contextCourseLessonId, $isProhibited); } unset($arFields['PUBLISH_PROHIBITED']); } // Courses must be updated throws CCourse::Update(); if ($courseId === false) { CLearnLesson::Update($lessonId, $arFields); } else { $ob = new CCourse(); if (!$ob->Update($courseId, $arFields)) { throw new CLearnRenderAdminUnilessonListException('', CLearnRenderAdminUnilessonListException::C_ACTION_UPDATE_FAIL); } unset($ob); } if (isset($_GET['PARENT_LESSON_ID']) && count($arEdgeProperties) > 0) { CLearnLesson::RelationUpdate($_GET['PARENT_LESSON_ID'], $lessonId, $arEdgeProperties); } } catch (CLearnRenderAdminUnilessonListException $e) { $wasError = true; $errorText = $e->getMessage(); $errorCode = $e->getCode(); } catch (Exception $e) { $wasError = true; $errorText = $e->getMessage(); $errorCode = 0; // Because we checks below only CLearnRenderAdminUnilessonListException codes } if ($wasError) { if ($errorCode & CLearnRenderAdminUnilessonListException::C_ACCESS_DENIED) { // Access denied $errmsg = GetMessage('LEARNING_SAVE_ERROR') . ': ' . GetMessage('LEARNING_ACCESS_D'); if (strlen($errorText) > 0) { $errmsg .= ': ' . $errorText; } } else { // Some error occured during update operation $errmsg = GetMessage('LEARNING_SAVE_ERROR') . $lessonId; if (strlen($errorText) > 0) { $errmsg .= ' (' . $errorText . ')'; } } $this->oList->AddUpdateError($errmsg, $lessonId); } } return $this; }
$rsQuestion = CLQuestion::GetByID($arTestResult["QUESTION_ID"]); if ($arQuestion = $rsQuestion->GetNext()) { // Resolve links "?COURSE_ID={SELF}". Don't relay on it, this behaviour // can be changed in future without any notifications. if (isset($arQuestion['DESCRIPTION'])) { $arQuestion['DESCRIPTION'] = CLearnHelper::PatchLessonContentLinks($arQuestion['DESCRIPTION'], $arParams['COURSE_ID']); } if ($arQuestion["QUESTION_TYPE"] != "T") { if ($arTest["SHOW_ERRORS"] == "Y" && $result["CORRECT"] == "N" && $result["ANSWERED"] == "Y" && $arQuestion["INCORRECT_MESSAGE"]) { $sessIncorrectMessage = $arQuestion; if ($arTest["NEXT_QUESTION_ON_ERROR"] == "N" && $arTest["PASSAGE_TYPE"] == 2) { $arResult["REDIRECT_PAGE"] = str_replace("#PAGE_ID#", array_key_exists($arParams["PAGE_NUMBER_VARIABLE"], $_REQUEST) ? $arResult["NAV"]["PAGE_NUMBER"] - 1 : 1, $arResult["PAGE_TEMPLATE"]); } } } elseif ($arQuestion["EMAIL_ANSWER"] == "Y") { $rsLesson = CLearnLesson::GetList(array(), array("LESSON_ID" => $arQuestion['LESSON_ID'], "CHECK_PERMISSIONS" => "N")); if ($arLesson = $rsLesson->GetNext()) { $rsTeacher = CUser::GetByID($arLesson["CREATED_BY"]); if ($arTeacher = $rsTeacher->GetNext()) { $courseName = ""; $rsCourse = CCourse::GetByID($arTest["COURSE_ID"]); if ($arCourse = $rsCourse->GetNext()) { $courseName = $arCourse["NAME"]; } $arEventFields = array("ID" => $testResultID, "ATTEMPT_ID" => $sessAttemptID, "TEST_NAME" => $arTest["NAME"], "COURSE_NAME" => $courseName, "USER" => "(" . $USER->GetLogin() . ")" . (strlen($USER->GetFullName()) > 0 ? " " . $USER->GetFullName() : ""), "DATE" => date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), time()), "QUESTION_TEXT" => $arQuestion["NAME"], "ANSWER_TEXT" => $_REQUEST["answer"], "EMAIL_FROM" => COption::GetOptionString("main", "email_from", "*****@*****.**"), "EMAIL_TO" => $arTeacher["EMAIL"], "MESSAGE_TITLE" => GetMessage("LEARNING_NEW_TEXT_ANSWER")); $arrSITE = LANG; CEvent::Send("NEW_LEARNING_TEXT_ANSWER", $arrSITE, $arEventFields, "N"); } } } }
} } $APPLICATION->SetPageProperty("learning_search_params", $searchParams); $lessonID = 0; if ($arVariables["LESSON_ID"] > 0) { $lessonID = intval($arVariables["LESSON_ID"]); } elseif (isset($arVariables['CHAPTER_ID'])) { // Lesson is not given, so try get chapter_id if (CLearnPath::IsUrlencodedPath($arVariables['CHAPTER_ID'])) { $LESSON_PATH = new CLearnPath(); $LESSON_PATH->ImportUrlencoded($arVariables['CHAPTER_ID']); $lessonID = (int) $LESSON_PATH->GetBottom(); } elseif (substr($arVariables['CHAPTER_ID'], 0, 1) === '0') { $lessonID = (int) substr($arVariables['CHAPTER_ID'], 1); } else { $lessonID = (int) CLearnLesson::LessonIdByChapterId($arVariables['CHAPTER_ID']); } } $linkedLessonId = false; if ($arParams["COURSE_ID"] > 0) { $linkedLessonId = CCourse::CourseGetLinkedLesson($arParams["COURSE_ID"]); } if ($arParams["CHECK_PERMISSIONS"] !== 'N') { $isAccessible = false; try { if ($lessonID > 0) { $arPermissionsParams = array('COURSE_ID' => $arParams['COURSE_ID'], 'LESSON_ID' => $lessonID); $isAccessible = CLearnAccessMacroses::CanUserViewLessonAsPublic($arPermissionsParams, $allowAccessViaLearningGroups = false); } elseif ($linkedLessonId !== false) { $arPermissionsParams = array('lesson_id' => $linkedLessonId); $isAccessible = CLearnAccessMacroses::CanUserViewLessonContent($arPermissionsParams, $allowAccessViaLearningGroups = false);
if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_CREATE)) { $Perm = 'X'; } else { $APPLICATION->SetTitle(GetMessage('LEARNING_ACCESS_D')); require $_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_admin_after.php"; $aContext = array(array("ICON" => "btn_list", "TEXT" => GetMessage("LEARNING_BACK_TO_ADMIN"), "LINK" => "learn_unilesson_admin.php?lang=" . LANG . '&PARENT_LESSON_ID=-1' . GetFilterParams("filter_"), "TITLE" => GetMessage("LEARNING_BACK_TO_ADMIN"))); $context = new CAdminContextMenu($aContext); $context->Show(); CAdminMessage::ShowMessage(GetMessage("LEARNING_ACCESS_D")); require $_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/epilog_admin.php"; die; } } $aTabs = array(array("DIV" => "edit1", "TAB" => GetMessage("LEARNING_ADMIN_TAB1"), "ICON" => "main_user_edit", "TITLE" => GetMessage("LEARNING_ADMIN_TAB1_EX")), array("DIV" => "edit2", "TAB" => GetMessage("LEARNING_ADMIN_TAB3"), "ICON" => "main_user_edit", "TITLE" => GetMessage("LEARNING_ADMIN_TAB3_EX")), array("DIV" => "edit3", "TAB" => GetMessage("LEARNING_ADMIN_TAB4"), "ICON" => "main_user_edit", "TITLE" => GetMessage("LEARNING_ADMIN_TAB4_EX"))); if ($COURSE_ID > 0 && ($linkedLessonId = CCourse::CourseGetLinkedLesson($COURSE_ID))) { $arOPathes = CLearnLesson::GetListOfParentPathes($linkedLessonId); $arOPathes_cnt = count($arOPathes); $tabName = GetMessage("LEARNING_ADMIN_TAB5"); if ($arOPathes_cnt > 1) { $tabName .= ' (' . $arOPathes_cnt . ')'; } $aTabs[] = array("DIV" => "edit4", "ICON" => "main_user_edit", "TAB" => $tabName, "TITLE" => GetMessage("LEARNING_ADMIN_TAB5_EX")); } $aTabs[] = array("DIV" => "edit5", "ICON" => "main_user_edit", "TAB" => GetMessage("LEARNING_PERMISSIONS"), "TITLE" => GetMessage("LEARNING_PERMISSIONS")); $aTabs[] = $USER_FIELD_MANAGER->EditFormTab('LEARNING_LESSONS'); $tabControl = new CAdminForm("courseTabControl", $aTabs, true, $bDenyAutosave); if ($_SERVER["REQUEST_METHOD"] == "POST" && $Perm >= "X" && strlen($_POST["Update"]) > 0 && check_bitrix_sessid()) { $course = new CCourse(); $arPREVIEW_PICTURE = $_FILES["PREVIEW_PICTURE"]; $arPREVIEW_PICTURE["del"] = $PREVIEW_PICTURE_del; $arPREVIEW_PICTURE["MODULE_ID"] = "learning";
} ?> </td> </tr> <?php if ($bContentReadOnly) { $tabControl->EndCustomField('EDGE_SORT'); } else { $tabControl->EndCustomField('EDGE_SORT', '<input type="hidden" id="EDGE_SORT" name="EDGE_SORT" value="' . $str_EDGE_SORT . '">'); } } unset($resParentLessonData, $arParentLessonData); } // PUBLISH_PROHIBITED - Only in context of most top course if ($topCourseLessonId !== false) { $resRootLessonData = CLearnLesson::GetByID($topCourseLessonId); $arRootLessonData = $resRootLessonData->Fetch(); if (is_array($arRootLessonData)) { $tabControl->BeginCustomField('PUBLISH_PROHIBITED', GetMessage('LEARNING_COURSE_ADM_PUBLISH_PROHIBITED'), false); ?> <!-- PUBLISH_PROHIBITED --> <tr> <td><?php echo $tabControl->GetCustomLabelHTML(); ?> :</td> <td> <label> <?php if ($bContentReadOnly) { echo $str_PUBLISH_PROHIBITED;
public function GetPathAsHumanReadableString($delimiter = ' / ', $pattern = '#NAME#') { $arHumanReadablePath = array(); foreach ($this->arPath as $lessonId) { $rc = CLearnLesson::GetByID($lessonId); $rc = $rc->Fetch(); $id = '???'; $name = '???'; if (isset($rc['LESSON_ID'])) { $id = $rc['LESSON_ID']; } if (isset($rc['NAME'])) { $name = htmlspecialcharsbx($rc['NAME']); } $txt = $pattern; $txt = str_replace('#LESSON_ID#', $id, $txt); $txt = str_replace('#NAME#', $name, $txt); $arHumanReadablePath[] = $txt; } return implode($delimiter, $arHumanReadablePath); }
$rsCourse = CCourse::GetList(array(), array("ID" => $arParams["COURSE_ID"], "ACTIVE" => "Y", "CHECK_PERMISSIONS" => 'N')); if (!($arCourse = $rsCourse->GetNext())) { $this->AbortResultCache(); ShowError(GetMessage("LEARNING_COURSE_DENIED")); return; } // Resolve links "?COURSE_ID={SELF}". Don't relay on it, this behaviour // can be changed in future without any notifications. if (isset($arCourse['DETAIL_TEXT'])) { $arCourse['DETAIL_TEXT'] = CLearnHelper::PatchLessonContentLinks($arCourse['DETAIL_TEXT'], $arParams['COURSE_ID']); } if (isset($arCourse['PREVIEW_TEXT'])) { $arCourse['PREVIEW_TEXT'] = CLearnHelper::PatchLessonContentLinks($arCourse['PREVIEW_TEXT'], $arParams['COURSE_ID']); } // Lesson $rsLesson = CLearnLesson::GetList(array(), array('LESSON_ID' => $arParams['LESSON_ID'], 'ACTIVE' => 'Y', 'CHECK_PERMISSIONS' => 'N')); if (!($arLesson = $rsLesson->GetNext())) { $this->AbortResultCache(); ShowError(GetMessage("LEARNING_LESSON_DENIED")); return; } // Images $arLesson["PREVIEW_PICTURE_ARRAY"] = CFile::GetFileArray($arLesson["PREVIEW_PICTURE"]); $arLesson["DETAIL_PICTURE_ARRAY"] = CFile::GetFileArray($arLesson["DETAIL_PICTURE"]); // Resolve links "?COURSE_ID={SELF}". Don't relay on it, this behaviour // can be changed in future without any notifications. if (isset($arLesson['DETAIL_TEXT'])) { $arLesson['DETAIL_TEXT'] = CLearnHelper::PatchLessonContentLinks($arLesson['DETAIL_TEXT'], $arParams['COURSE_ID']); } if (isset($arLesson['PREVIEW_TEXT'])) { $arLesson['PREVIEW_TEXT'] = CLearnHelper::PatchLessonContentLinks($arLesson['PREVIEW_TEXT'], $arParams['COURSE_ID']);
protected function _MakeItems($TITLE, $TYPE, $RES_ID, $PARENT_ID) { global $APPLICATION; if ($PARENT_ID === 0) { $linkToParentLessonId = CCourse::CourseGetLinkedLesson($this->COURSE_ID); } else { $linkToParentLessonId = (int) $PARENT_ID; } $createUnilesson = false; if ($TYPE == "LES") { $arFields = array('NAME' => $TITLE); $createUnilesson = true; } elseif ($TYPE == "CHA") { $arFields = array('NAME' => $TITLE); $createUnilesson = true; } elseif ($TYPE == "QUE") { $arFields = array("NAME" => $TITLE, "LESSON_ID" => $linkToParentLessonId); $cl = new CLQuestion(); } elseif ($TYPE == "TES") { $arFields = array("NAME" => $TITLE, "COURSE_ID" => $this->COURSE_ID); $cl = new CTest(); } elseif ($TYPE === 'TMK') { $arFields = array(); $cl = new CLTestMark(); } else { return $PARENT_ID; } $r = new CDataXML(); if (!$r->Load($this->package_dir . "/" . strtolower($RES_ID) . ".xml")) { $r = false; } if ($r !== false) { if ($TYPE == "QUE") { if (($data = $r->SelectNodes("/questestinterop/item/presentation/")) && ($resp = $r->SelectNodes("/questestinterop/item/resprocessing/"))) { $arQ = array(); $arData = $data->__toArray(); $arResp = $resp->__toArray(); if (is_set($arData["#"]["material"][0]["#"], "mattext")) { $arQ["NAME"] = $arData["#"]["material"][0]["#"]["mattext"][0]["#"]; } if (is_set($arData["#"]["material"][0]["#"], "matimage")) { $imageDescription = ''; if (is_set($arData["#"]["material"][0]["#"], 'image_description')) { $imageDescription = $arData["#"]["material"][0]["#"]['image_description'][0]['#']; } $arQ["FILE_ID"] = array("MODULE_ID" => "learning", "name" => basename($arData["#"]["material"][0]["#"]["matimage"][0]["@"]["uri"]), "tmp_name" => $this->package_dir . "/" . $arData["#"]["material"][0]["#"]["matimage"][0]["@"]["uri"], "size" => @filesize($this->package_dir . "/" . $arData["#"]["material"][0]["#"]["matimage"][0]["@"]["uri"]), "type" => $arData["#"]["material"][0]["#"]["matimage"][0]["@"]["imagtype"], 'description' => $imageDescription); } if (is_set($arData["#"]["response_lid"][0]["@"], "rcardinality")) { switch ($arData["#"]["response_lid"][0]["@"]["rcardinality"]) { case "Multiple": $arQ["QUESTION_TYPE"] = 'M'; break; case "Text": $arQ["QUESTION_TYPE"] = 'T'; break; case "Sort": $arQ["QUESTION_TYPE"] = 'R'; break; default: $arQ["QUESTION_TYPE"] = 'S'; break; } } if (is_set($arResp["#"]["respcondition"][0]["#"], "setvar")) { $arQ["POINT"] = $arResp["#"]["respcondition"][0]["#"]["setvar"][0]['#']; } //Additional if ($bx = $r->SelectNodes("/questestinterop/item/bitrix/")) { $arQ = array_merge($arQ, $this->_MakeFields($bx->__toArray(), $TYPE)); unset($bx); } $arFields = array_merge($arFields, $arQ); $cl = new CLQuestion(); $ID = $cl->Add($arFields); if ($ID > 0) { $PARENT_ID = $ID; $arCorrect = array(); if (is_set($arResp["#"]["respcondition"][0]["#"], "conditionvar") && is_set($arResp["#"]["respcondition"][0]["#"]["conditionvar"][0]["#"], "varequal")) { foreach ($arResp["#"]["respcondition"][0]["#"]["conditionvar"][0]["#"]["varequal"] as $ar) { $arCorrect[] = $ar["#"]; } } if (is_set($arData["#"]["response_lid"][0]["#"], "render_choice") && is_set($arData["#"]["response_lid"][0]["#"]["render_choice"][0]["#"], "response_label")) { $i = 0; foreach ($arData["#"]["response_lid"][0]["#"]["render_choice"][0]["#"]["response_label"] as $ar) { $i += 10; $cl = new CLAnswer(); $arFields = array("QUESTION_ID" => $PARENT_ID, "SORT" => $i, "CORRECT" => in_array($ar["@"]["ident"], $arCorrect) ? "Y" : "N", "ANSWER" => $ar["#"]["material"][0]["#"]["mattext"][0]["#"]); $AswerID = $cl->Add($arFields); $res = $AswerID > 0; if (!$res) { if ($e = $APPLICATION->GetException()) { $this->arWarnings[$TYPE][] = array("TITLE" => $TITLE, "TEXT" => $e->GetString()); } } } } } else { if ($e = $APPLICATION->GetException()) { $this->arWarnings[$TYPE][] = array("TITLE" => $TITLE, "TEXT" => $e->GetString()); } } unset($cl); unset($data); unset($arQ); unset($resp); unset($arData); unset($arResp); return $PARENT_ID; } } else { if ($data = $r->SelectNodes("/content/")) { $ar = $data->__toArray(); $arFields = array_merge($arFields, $this->_MakeFields($ar, $TYPE)); if ($TYPE === 'TMK') { $arFields['TEST_ID'] = (int) $PARENT_ID; } if (is_set($arFields, "COMPLETED_SCORE") && intval($arFields["COMPLETED_SCORE"]) <= 0) { unset($arFields["COMPLETED_SCORE"]); } if (is_set($arFields, "PREVIOUS_TEST_ID") && intval($arFields["PREVIOUS_TEST_ID"]) <= 0 || !CTest::GetByID($arFields["PREVIOUS_TEST_ID"])->Fetch()) { unset($arFields["PREVIOUS_TEST_ID"], $arFields["PREVIOUS_TEST_SCORE"]); } } } } if ($createUnilesson === false) { $ID = $cl->Add($arFields); unset($cl); } else { $bProhibitPublish = false; // properties (in context of parent) by default $arProperties = array('SORT' => 500); // Lesson's sort order in context of parent if (isset($arFields['EDGE_SORT'])) { $arFields['SORT'] = (int) $arFields['EDGE_SORT']; unset($arFields['EDGE_SORT']); } if (isset($arFields['SORT'])) { $arProperties['SORT'] = (int) $arFields['SORT']; // Lessons doesn't have more SORT field unset($arFields['SORT']); } if (isset($arFields['META_PUBLISH_PROHIBITED'])) { if ($arFields['META_PUBLISH_PROHIBITED'] === 'Y') { $bProhibitPublish = true; } unset($arFields['META_PUBLISH_PROHIBITED']); } // unset fields, that are absent in unilesson $arUnilessonFields = $arFields; $arFieldsNames = array_keys($arUnilessonFields); foreach ($arFieldsNames as $fieldName) { if (!in_array(strtoupper($fieldName), $this->arLessonWritableFields)) { unset($arUnilessonFields[$fieldName]); } } $ID = CLearnLesson::Add($arUnilessonFields, false, $linkToParentLessonId, $arProperties); if ($bProhibitPublish && $ID > 0) { CLearnLesson::PublishProhibitionSetTo($ID, $linkToParentLessonId, $bProhibitPublish); } } if ($ID > 0) { return $ID; } else { if ($e = $APPLICATION->GetException()) { $this->arWarnings[$TYPE][] = array("TITLE" => $TITLE, "TEXT" => $e->GetString()); } } }
CAdminMessage::ShowMessage(GetMessage('LEARNING_BAD_LESSON')); require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_admin.php'; exit; } $uriLessonPath = $oPath->ExportUrlencoded(); unset($lessonPath); if (isset($from) && strlen($from) > 0) { $str_from = "&from=" . htmlspecialcharsbx($from); } else { $str_from = ""; } $oAccess = CLearnAccess::GetInstance($USER->GetID()); $bAccessLessonModify = $oAccess->IsLessonAccessible($LESSON_ID, CLearnAccess::OP_LESSON_WRITE); $lesson = CLearnLesson::GetList(array(), array('LESSON_ID' => $LESSON_ID)); $arLesson = $lesson->Fetch(); $oTree = CLearnLesson::GetTree($LESSON_ID, array('EDGE_SORT' => 'asc'), array(), false); $arSubLessons = $oTree->GetTreeAsList(); $arSubLessonsIDs = array(); foreach ($arSubLessons as $arSubLesson) { $arSubLessonsIDs[] = (int) $arSubLesson['LESSON_ID']; } $arSubLessonsIDs[] = (int) $LESSON_ID; if (!$bAccessLessonModify) { $APPLICATION->SetTitle(GetMessage('LEARNING_QUESTION')); require $_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_admin_after.php"; $aContext = array(array("ICON" => "btn_list", "TEXT" => GetMessage("LEARNING_BACK_TO_ADMIN"), "LINK" => "learn_unilesson_admin.php?lang=" . LANG . GetFilterParams("filter_") . '&LESSON_PATH=' . $uriLessonPath, "TITLE" => GetMessage("LEARNING_BACK_TO_ADMIN"))); $context = new CAdminContextMenu($aContext); $context->Show(); CAdminMessage::ShowMessage(GetMessage("LEARNING_BAD_LESSON")); require $_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/epilog_admin.php"; die;
echo $str_QUESTION_TYPE; ?> "> </td> </tr> <?php $tabControl->EndCustomField("QUESTION_TYPE"); $tabControl->BeginCustomField("LESSON_ID", GetMessage("LEARNING_LESSON"), false); ?> <tr class="adm-detail-required-field"> <td><?php echo $tabControl->GetCustomLabelHTML(); ?> :</td> <td><?php $rsLesson = CLearnLesson::GetByID($LESSON_ID); $arLesson = $rsLesson->GetNext(); $curDir = $APPLICATION->GetCurDir(); if (substr($curDir, -1) !== '/') { $curDir .= '/'; } ?> <script> function module_learning_js_admin_function_change_attached_lesson(lesson_id, name) { BX('attached_lesson_id').value = lesson_id; BX('attached_lesson_name').innerHTML = name; } </script> <div style="padding:0px;"> <span id="attached_lesson_name"><?php
$this->AbortResultCache(); ShowError(GetMessage("LEARNING_COURSE_DENIED")); return; } // Resolve links "?COURSE_ID={SELF}". Don't relay on it, this behaviour // can be changed in future without any notifications. if (isset($arCourse['DETAIL_TEXT'])) { $arCourse['DETAIL_TEXT'] = CLearnHelper::PatchLessonContentLinks($arCourse['DETAIL_TEXT'], $arCourse['ID']); } if (isset($arCourse['PREVIEW_TEXT'])) { $arCourse['PREVIEW_TEXT'] = CLearnHelper::PatchLessonContentLinks($arCourse['PREVIEW_TEXT'], $arCourse['ID']); } $rsChapter = false; //Chapter if (isset($arParams["CHAPTER_ID"])) { $rsChapter = CLearnLesson::GetList(array(), array("LESSON_ID" => $arParams["CHAPTER_ID"], "ACTIVE" => "Y", "CHECK_PERMISSIONS" => 'N')); } if ($rsChapter === false || !($arChapter = $rsChapter->GetNext())) { $this->AbortResultCache(); ShowError(GetMessage("LEARNING_CHAPTER_DENIED")); return; } //Images $arChapter["PREVIEW_PICTURE_ARRAY"] = CFile::GetFileArray($arChapter["PREVIEW_PICTURE"]); $arChapter["DETAIL_PICTURE_ARRAY"] = CFile::GetFileArray($arChapter["DETAIL_PICTURE"]); // Resolve links "?COURSE_ID={SELF}". Don't relay on it, this behaviour // can be changed in future without any notifications. if (isset($arChapter['DETAIL_TEXT'])) { $arChapter['DETAIL_TEXT'] = CLearnHelper::PatchLessonContentLinks($arChapter['DETAIL_TEXT'], $arParams['COURSE_ID']); } if (isset($arChapter['PREVIEW_TEXT'])) {
function __learning_admin_get_menu($THIS, $arPath = array(), $deep = 0, &$immediateChildsIds, $loadOnlySpecialEntities = false) { $immediateChildsIds = array(); // puts here ids of all immediate childs $deep = (int) $deep; // Index in path for current parentLessonId $indexInPath = $deep - 1; // Path doesn't include top root element ('all courses' or 'all unilessons') $arMenu = array(); //$urlPath = $oPath->ExportUrlencoded(); // current lesson id (not exists only for top root) if (isset($arPath[$deep])) { $currentLessonIdInPath = (int) $arPath[$deep]; } else { $currentLessonIdInPath = false; } // Path to current element $arCurrentDeepPath = array(); foreach ($arPath as $key => $value) { if ($key === $deep) { break; } $arCurrentDeepPath[] = $value; } if ($deep === 0) { // We are at the top level, so we must get list of all courses $CDBResult = CCourse::GetList(array('COURSE_SORT' => 'ASC')); } else { // If not parent with such indexInPath => we are deep too much. if (!isset($arPath[$indexInPath])) { return $arMenu; } // no items $parentLessonId = $arPath[$indexInPath]; $oCurrentDeepPath = new CLearnPath(); $oCurrentDeepPath->SetPathFromArray(array_merge($arCurrentDeepPath)); $urlPath = $oCurrentDeepPath->ExportUrlencoded(); $arMenu[] = array("text" => GetMessage("LEARNING_QUESTION"), "url" => "learn_question_admin.php?lang=" . LANG . '&PARENT_LESSON_ID=' . ($parentLessonId + 0) . '&LESSON_PATH=' . $urlPath . "&from=learn_menu", "icon" => "learning_icon_question", "more_url" => array("learn_question_admin.php?lang=" . LANG . '&PARENT_LESSON_ID=' . ($parentLessonId + 0) . '&LESSON_PATH=' . $urlPath . "&from=learn_menu", "learn_question_edit.php?lang=" . LANG . '&LESSON_PATH=' . $urlPath . "&from=learn_menu", "learn_question_admin.php?lang=" . LANG . '&PARENT_LESSON_ID=' . ($parentLessonId + 0) . '&LESSON_PATH=' . $urlPath, "learn_question_edit.php?lang=" . LANG . '&LESSON_PATH=' . $urlPath, "learn_question_admin.php?lang=" . LANG . '&LESSON_PATH=' . $urlPath), "title" => GetMessage("LEARNING_QUESTION_LIST")); $CDBResult = CLearnLesson::GetListOfImmediateChilds($parentLessonId, array('EDGE_SORT' => 'ASC')); // determine, is parent a course (only for courses in subroot level)? if ($deep === 1) { $immediateParentCourse = CLearnLesson::GetLinkedCourse($parentLessonId); if ($immediateParentCourse !== false) { // immediate parent is a course, so we must add entity 'Tests' $arMenu[] = array('text' => GetMessage('LEARNING_TESTS'), 'url' => 'learn_test_admin.php?lang=' . LANG . '&filter=Y&set_filter=Y' . '&COURSE_ID=' . ($immediateParentCourse + 0) . '&PARENT_LESSON_ID=' . ($parentLessonId + 0) . '&LESSON_PATH=' . $urlPath, 'icon' => 'learning_icon_tests', 'more_url' => array('learn_test_admin.php?lang=' . LANG . '&set_filter=Y' . '&COURSE_ID=' . ($immediateParentCourse + 0) . '&PARENT_LESSON_ID=' . ($parentLessonId + 0) . '&LESSON_PATH=' . $urlPath, 'learn_test_edit.php?lang=' . LANG . '&filter=Y&set_filter=Y' . '&COURSE_ID=' . ($immediateParentCourse + 0) . '&PARENT_LESSON_ID=' . ($parentLessonId + 0) . '&LESSON_PATH=' . $urlPath), 'title' => GetMessage('LEARNING_TESTS_LIST')); unset($urlPath); unset($oCurrentDeepPath); } } } if ($loadOnlySpecialEntities) { return $arMenu; } // When listing courses, limit it's count if ($deep === 0) { $items = 0; $learning_menu_max_courses = (int) COption::GetOptionString("learning", "menu_max_courses", "10"); } while ($arData = $CDBResult->GetNext()) { // When listing courses, limit it's count if ($deep === 0) { if ($items >= $learning_menu_max_courses) { // add element 'other courses' $arMenu[] = array('text' => GetMessage('LEARNING_MENU_COURSES_OTHER'), 'url' => 'learn_unilesson_admin.php?lang=' . LANG . '&PARENT_LESSON_ID=-1', 'title' => GetMessage('LEARNING_MENU_COURSES_ALT'), 'more_url' => array('learn_test_admin.php', 'learn_test_edit.php', 'learn_unilesson_admin.php', 'learn_unilesson_edit.php', 'learn_question_admin.php', 'learn_question_edit.php')); // stop adding courses to menu break; } $items++; } $arSubImmediateChildsIds = false; $arCurItemPath = $arCurrentDeepPath; $arCurItemPath[] = $arData['LESSON_ID'] + 0; // Remember all immediate childs $immediateChildsIds[] = $arData['LESSON_ID'] + 0; $oCurItemPath = new CLearnPath(); $oCurItemPath->SetPathFromArray($arCurItemPath); $urlCurItemPath = $oCurItemPath->ExportUrlencoded(); $arItem = array('text' => $arData['NAME'], 'url' => 'learn_unilesson_admin.php?lang=' . LANG . '&PARENT_LESSON_ID=' . ($arData['LESSON_ID'] + 0) . '&LESSON_PATH=' . $oCurItemPath->ExportUrlencoded(), 'title' => $arData['NAME'], 'items_id' => 'menu_learning_courses_new_' . implode('_', $arCurItemPath), "icon" => "learning_icon_courses", 'module_id' => 'learning', 'more_url' => array('learn_unilesson_admin.php?lang=' . LANG . '&set_filter=Y' . '&PARENT_LESSON_ID=' . ($arData['LESSON_ID'] + 0) . '&LESSON_PATH=' . $urlCurItemPath, 'learn_unilesson_admin.php?lang=' . LANG . '&PARENT_LESSON_ID=' . ($arData['LESSON_ID'] + 0) . '&LESSON_PATH=' . $urlCurItemPath, 'learn_unilesson_admin.php?lang=' . LANG . '&set_filter=Y' . '&LESSON_PATH=' . $urlCurItemPath, 'learn_question_admin.php?lang=' . LANG . '&filter=Y&set_filter=Y' . '&LESSON_PATH=' . $urlCurItemPath, 'learn_question_edit.php?lang=' . LANG . '&set_filter=Y' . '&LESSON_PATH=' . $urlCurItemPath, 'learn_unilesson_edit.php?lang=' . LANG . '&LESSON_ID=' . ($arData['LESSON_ID'] + 0) . '&LESSON_PATH=' . $urlCurItemPath, 'learn_unilesson_edit.php?lang=' . LANG . '&PARENT_LESSON_ID=' . ($arData['LESSON_ID'] + 0) . '&LESSON_PATH=' . $urlCurItemPath)); $arItem['items'] = array(); if ($deep === 0 && isset($arData['LINKED_LESSON_ID']) && $arData['LINKED_LESSON_ID'] > 0) { $arItem['page_icon'] = $arItem['icon'] = 'learning_icon_courses'; $arItem['dynamic'] = true; $loadOnlySpecialEntities = false; // Load child items only for lesson in current path if ($arData['LESSON_ID'] == $currentLessonIdInPath) { $arItem['items'] = __learning_admin_get_menu($THIS, $arPath, $deep + 1, $arSubImmediateChildsIds); } } else { $loadOnlySpecialEntities = false; $childsCnt = CLearnLesson::CountImmediateChilds($arData['LESSON_ID']); $questionsCnt = CLQuestion::GetCount(array('LESSON_ID' => (int) $arData['LESSON_ID'])); if ($childsCnt > 0) { $arItem['page_icon'] = $arItem['icon'] = 'learning_icon_chapters'; } else { $arItem['page_icon'] = $arItem['icon'] = 'learning_icon_lessons'; } $arItem['dynamic'] = true; // Load child items only for lesson in current path if ($arData['LESSON_ID'] == $currentLessonIdInPath) { $arItem['items'] = __learning_admin_get_menu($THIS, $arPath, $deep + 1, $arSubImmediateChildsIds); } } // now, adds items into more_url (it needs when edit form for childs opened) if (is_array($arSubImmediateChildsIds)) { $oSubItemPath = new CLearnPath(); foreach ($arSubImmediateChildsIds as $k => $v) { // determine path for every child $arSubItemPath = $arCurItemPath; $arSubItemPath[] = $v; // child id added to current path $oSubItemPath->SetPathFromArray($arSubItemPath); $arItem['more_url'][] = 'learn_unilesson_edit.php?lang=' . LANG . '&filter=Y&set_filter=Y' . '&LESSON_ID=' . ($v + 0) . '&LESSON_PATH=' . $oSubItemPath->ExportUrlencoded(); } unset($oSubItemPath); $arSubImmediateChildsIds = false; } $arMenu[] = $arItem; unset($oCurItemPath, $arCurItemPath, $urlCurItemPath, $arItem); } return $arMenu; }
} $APPLICATION->SetPageProperty("learning_search_params", $searchParams); $lessonID = 0; if ($arVariables["LESSON_ID"] > 0) { $lessonID = intval($arVariables["LESSON_ID"]); } else { // Lesson is not given, so try get chapter_id if (isset($_REQUEST['CHAPTER_ID'])) { if (CLearnPath::IsUrlencodedPath($_REQUEST['CHAPTER_ID'])) { $LESSON_PATH = new CLearnPath(); $LESSON_PATH->ImportUrlencoded($_REQUEST['CHAPTER_ID']); $lessonID = (int) $LESSON_PATH->GetBottom(); } elseif (substr($_REQUEST['CHAPTER_ID'], 0, 1) === '0') { $lessonID = (int) substr($_REQUEST['CHAPTER_ID'], 1); } else { $lessonID = (int) CLearnLesson::LessonIdByChapterId($_REQUEST['CHAPTER_ID']); } } } $linkedLessonId = false; if ($arParams["COURSE_ID"] > 0) { $linkedLessonId = CCourse::CourseGetLinkedLesson($arParams["COURSE_ID"]); } if ($arParams["CHECK_PERMISSIONS"] !== 'N') { $isAccessible = false; try { if ($lessonID > 0) { $arPermissionsParams = array('COURSE_ID' => $arParams['COURSE_ID'], 'LESSON_ID' => $lessonID); $isAccessible = CLearnAccessMacroses::CanUserViewLessonAsPublic($arPermissionsParams, $allowAccessViaLearningGroups = false); } elseif ($linkedLessonId !== false) { $arPermissionsParams = array('lesson_id' => $linkedLessonId);
/** * WARNING: tree build algorithm skips duplicated lessons, so * if there is some duplicates lessons, only one of them * will be in resulted tree. */ protected function BuildTreeRecursive($rootLessonId, $arOrder, $arFilter, $depth = 0, $parentChapterId = NULL, $arSelectFields, $arRootPath) { $oPath = new CLearnPath(); $arLessons = array(); $CDBResult = CLearnLesson::GetListOfImmediateChilds($rootLessonId, $arOrder, $arFilter, $arSelectFields); while (($arData = $CDBResult->Fetch()) !== false) { // Skip lessons that are already in tree (prevent cycling) if (in_array($arData['LESSON_ID'], $this->arLessonsInTree)) { continue; } // Skip lessons prohibited for publishing if (in_array((int) $arData['LESSON_ID'], $this->arPublishProhibitedLessons, true)) { continue; } // Path as array for current LESSON_ID $arCurrentLessonPath = $arRootPath; $arCurrentLessonPath[] = (int) $arData['LESSON_ID']; $oPath->SetPathFromArray($arCurrentLessonPath); $strUrlencodedCurrentLessonPath = $oPath->ExportUrlencoded(); // Register lesson $this->arLessonsInTree[] = $arData['LESSON_ID']; $this->arLessonsAsList[] = array_merge($arData, array('#DEPTH_IN_TREE' => $depth, '#LESSON_PATH' => $strUrlencodedCurrentLessonPath)); // hack: we don't know yet, what index name must be for element in array. // And we must preserve order in array elements (for compatibility). // But we will know index name after BuildTreeRecursive will be called, which // adds to array new elements. So create bother elements, and after remove unneeded. $this->arLessonsAsListOldMode['LE' . $arData['LESSON_ID']] = array(); $this->arLessonsAsListOldMode['CH' . $arData['LESSON_ID']] = array(); $item = $arData; $item['#childs'] = array(); $lessonType_oldDataModel = 'LE'; if ($arData['IS_CHILDS']) { $lessonType_oldDataModel = 'CH'; $item['#childs'] = $this->BuildTreeRecursive($arData['LESSON_ID'], $arOrder, $arFilter, $depth + 1, $arData['LESSON_ID'], $arSelectFields, $arCurrentLessonPath); // It still can be zero childs due to $arFilter, publish prohibition or prevent cycling instead of non-zero $arData['IS_CHILDS'] if (count($item['#childs']) == 0) { $lessonType_oldDataModel = 'LE'; } } // remove unneeded element caused by hack above if ($lessonType_oldDataModel === 'LE') { unset($this->arLessonsAsListOldMode['CH' . $arData['LESSON_ID']]); } else { unset($this->arLessonsAsListOldMode['LE' . $arData['LESSON_ID']]); } $this->arLessonsAsListOldMode[$lessonType_oldDataModel . $arData['LESSON_ID']] = array_merge($arData, array('ID' => $arData['LESSON_ID'], 'CHAPTER_ID' => $parentChapterId, 'SORT' => $arData['EDGE_SORT'], 'TYPE' => $lessonType_oldDataModel, 'DEPTH_LEVEL' => $depth + 1, '#LESSON_PATH' => $strUrlencodedCurrentLessonPath)); $arLessons[] = $item; } return $arLessons; }
if ($arParams["SET_TITLE"] == "Y") { $APPLICATION->SetTitle($arResult["CHAPTER"]["NAME"]); } $bCanEdit = CLearnAccessMacroses::CanUserEditLesson(array('lesson_id' => $arParams['CHAPTER_ID'])) || $USER->IsAdmin(); if ($bCanEdit) { $deleteReturnUrl = ""; if ($parent = $this->GetParent()) { $parentLessonId = 0; $lessonPath = ""; if (strlen($arParams["LESSON_PATH"]) > 0) { $path = new CLearnPath(); $path->ImportUrlencoded($arParams["LESSON_PATH"]); $path->PopBottom(); $lessonPath = $path->ExportUrlencoded(); $lessonId = $path->PopBottom(); $edgesToParents = CLearnLesson::ListImmediateParents($arParams['CHAPTER_ID']); foreach ($edgesToParents as $arEdgeToParent) { if ((int) $arEdgeToParent['PARENT_LESSON'] === (int) $lessonId) { $parentLessonId = $lessonId; break; } } } if ($parentLessonId) { $deleteReturnUrl = CComponentEngine::MakePathFromTemplate($parent->arResult["FOLDER"] . $parent->arResult["URL_TEMPLATES"]["chapter.detail"], array("CHAPTER_ID" => "0" . $parentLessonId, "COURSE_ID" => $arParams["COURSE_ID"])); $deleteReturnUrl .= strpos($deleteReturnUrl, "?") !== false ? "&" : "?"; $deleteReturnUrl .= "LESSON_PATH=" . $lessonPath; } else { $deleteReturnUrl = CComponentEngine::MakePathFromTemplate($parent->arResult["FOLDER"] . $parent->arResult["URL_TEMPLATES"]["course.detail"], array("COURSE_ID" => $arParams["COURSE_ID"])); } }
public static function ProccessPOST($oAccess, $LESSON_ID, $sort = false) { $isAccessUseCache = true; if ($sort === false) { $sort = 500; } // Remove/add relations from/to parent if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_LINK_TO_PARENTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($LESSON_ID, CLearnAccess::OP_LESSON_LINK_TO_PARENTS, $isAccessUseCache) || $oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_UNLINK_FROM_PARENTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($LESSON_ID, CLearnAccess::OP_LESSON_UNLINK_FROM_PARENTS, $isAccessUseCache)) { $arCurParentsIds = array(); $resParents = CLearnLesson::GetListOfImmediateParents($LESSON_ID); while ($arParent = $resParents->Fetch()) { $arCurParentsIds[] = (int) $arParent['LESSON_ID']; } $arDestParentsIds = array(); if (isset($_POST['RELATION_PARENT']) && is_array($_POST['RELATION_PARENT'])) { foreach ($_POST['RELATION_PARENT'] as $key => $relatedLessonId) { $arDestParentsIds[] = (int) $relatedLessonId; } } // remove relations if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_UNLINK_FROM_PARENTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($LESSON_ID, CLearnAccess::OP_LESSON_UNLINK_FROM_PARENTS, $isAccessUseCache)) { $arRemoveIds = array_diff($arCurParentsIds, $arDestParentsIds); foreach ($arRemoveIds as $relatedLessonId) { if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_UNLINK_DESCENDANTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($relatedLessonId, CLearnAccess::OP_LESSON_UNLINK_DESCENDANTS, $isAccessUseCache)) { CLearnLesson::RelationRemove($relatedLessonId, $LESSON_ID); } } } // add relations if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_LINK_TO_PARENTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($LESSON_ID, CLearnAccess::OP_LESSON_LINK_TO_PARENTS, $isAccessUseCache)) { $arAddIds = array_diff($arDestParentsIds, $arCurParentsIds); foreach ($arAddIds as $relatedLessonId) { if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_LINK_DESCENDANTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($relatedLessonId, CLearnAccess::OP_LESSON_LINK_DESCENDANTS, $isAccessUseCache)) { CLearnLesson::RelationAdd($relatedLessonId, $LESSON_ID, array('SORT' => $sort)); } } } } // Remove/add relations from/to childs if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_LINK_DESCENDANTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($LESSON_ID, CLearnAccess::OP_LESSON_LINK_DESCENDANTS, $isAccessUseCache) || $oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_UNLINK_DESCENDANTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($LESSON_ID, CLearnAccess::OP_LESSON_UNLINK_DESCENDANTS, $isAccessUseCache)) { $arCurChildsIds = array(); $resChilds = CLearnLesson::GetListOfImmediateChilds($LESSON_ID); while ($arChild = $resChilds->Fetch()) { $arCurChildsIds[] = (int) $arChild['LESSON_ID']; } $arDestChildsIds = array(); if (isset($_POST['RELATION_CHILD']) && is_array($_POST['RELATION_CHILD'])) { foreach ($_POST['RELATION_CHILD'] as $key => $relatedLessonId) { $arDestChildsIds[] = (int) $relatedLessonId; } } // remove relations if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_UNLINK_DESCENDANTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($LESSON_ID, CLearnAccess::OP_LESSON_UNLINK_DESCENDANTS, $isAccessUseCache)) { $arRemoveIds = array_diff($arCurChildsIds, $arDestChildsIds); foreach ($arRemoveIds as $relatedLessonId) { if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_UNLINK_FROM_PARENTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($relatedLessonId, CLearnAccess::OP_LESSON_UNLINK_FROM_PARENTS, $isAccessUseCache)) { CLearnLesson::RelationRemove($LESSON_ID, $relatedLessonId); } } } // add relations if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_LINK_DESCENDANTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($LESSON_ID, CLearnAccess::OP_LESSON_LINK_DESCENDANTS, $isAccessUseCache)) { $arAddIds = array_diff($arDestChildsIds, $arCurChildsIds); foreach ($arAddIds as $relatedLessonId) { if ($oAccess->IsBaseAccess(CLearnAccess::OP_LESSON_LINK_TO_PARENTS, $isAccessUseCache) || $oAccess->IsLessonAccessible($relatedLessonId, CLearnAccess::OP_LESSON_LINK_TO_PARENTS, $isAccessUseCache)) { CLearnLesson::RelationAdd($LESSON_ID, $relatedLessonId, array('SORT' => $sort)); } } } } }