Ejemplo n.º 1
0
    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;
Ejemplo n.º 2
0
    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;
    }
Ejemplo n.º 3
0
 /**
  * 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;
     }
 }
Ejemplo n.º 4
0
 /**
  * <p>Возвращает список активных глав и уроков, отсортированный по возрастанию индекса сортировки.</p>
  *
  *
  *
  *
  * @param int $COURSE_ID  Идентификатор курса.
  *
  *
  *
  * @param array $arAddSelectFileds = Array("DETAIL_TEXT" Массив дополнительных полей. Допустимые поля:<br><i>PREVIEW_TEXT</i> -
  * Предварительное описание (анонс);<br><i>PREVIEW_TEXT_TYPE</i> - Тип
  * предварительного описания (text/html);<br><i>PREVIEW_PICTURE</i> - Код картинки в
  * таблице файлов для предварительного просмотра
  * (анонса);<br><i>DETAIL_TEXT_TYPE</i> - Тип детального описания
  * (text/html);<br><i>DETAIL_PICTURE</i> - Код картинки в таблице файлов для
  * детального просмотра;<br><i>DETAIL_TEXT</i> - Детальное описание;<br> По
  * умолчанию массив arAddSelectFileds = Array("DETAIL_TEXT", "DETAIL_TEXT_TYPE", "DETAIL_PICTURE");
  *
  *
  *
  * @param DETAIL_TEXT_TYP $E  
  *
  *
  *
  * @param DETAIL_PICTUR $E  
  *
  *
  *
  * @return CDBResult <p>Возвращается объект <a
  * href="http://dev.1c-bitrix.ru/api_help/main/reference/cdbresult/index.php">CDBResult</a>.</p> </h
  *
  *
  * <h4>Example</h4> 
  * <pre>
  * &lt;?
  * if (CModule::IncludeModule("learning"))
  * {
  *     $res = CCourse::GetCourseContent($COURSE_ID = 105, Array());
  * 
  *     while ($arContent = $res-&gt;GetNext())
  *     {
  *         echo str_repeat("&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;", $arContent["DEPTH_LEVEL"]);
  *         echo ($arContent["TYPE"]=="CH" ? "+": "-").$arContent["NAME"]."&lt;br&gt;";
  *     }
  * 
  *     //<
  *     The above example will output something similar to:
  * 
  *     +Chapter 1
  *       +Chapter 1.1
  *         -Lesson 1.1.1
  *       +Chapter 1.2
  *     +Chapter 2
  *       -Lesson 2
  *     +Chapter 3
  *       +Chapter 3.1
  *         -Lesson 3.1.1
  *         -Lesson 3.1.2
  *         +Chapter 3.1.1
  * 
  *     >//
  * 
  * }
  * 
  * ?&gt;
  * </pre>
  *
  *
  *
  * <h4>See Also</h4> 
  * <ul> <li><a href="http://dev.1c-bitrix.ru/api_help/learning/fields.php#lesson">Поля урока</a></li> <li><a
  * href="http://dev.1c-bitrix.ru/api_help/learning/fields.php#chapter">Поля главы</a></li> <li><a
  * href="http://dev.1c-bitrix.ru/api_help/main/reference/cdbresult/index.php">CDBResult</a></li> <li> <a
  * href="http://dev.1c-bitrix.ru/api_help/learning/classes/clesson/index.php">CLesson</a>::<a
  * href="http://dev.1c-bitrix.ru/api_help/learning/classes/clesson/getlist.php">GetList</a> </li> <li> <a
  * href="http://dev.1c-bitrix.ru/api_help/learning/classes/cchapter/index.php">CChapter</a>::<a
  * href="http://dev.1c-bitrix.ru/api_help/learning/classes/cchapter/getlist.php">GetList</a> </li> <li> <a
  * href="http://dev.1c-bitrix.ru/api_help/learning/classes/cchapter/index.php">CChapter</a>::<a
  * href="http://dev.1c-bitrix.ru/api_help/learning/classes/cchapter/gettreelist.php">GetTreeList</a> </li> </ul> <a
  * name="examples"></a>
  *
  *
  * @static
  * @link http://dev.1c-bitrix.ru/api_help/learning/classes/ccourse/getcoursecontent.php
  * @author Bitrix
  */
 public static function GetCourseContent($COURSE_ID, $arAddSelectFileds = array("DETAIL_TEXT", "DETAIL_TEXT_TYPE", "DETAIL_PICTURE"), $arSelectFields = array())
 {
     global $DB;
     $COURSE_ID = intval($COURSE_ID);
     $CACHE_ID = (string) $COURSE_ID . sha1(serialize($arSelectFields));
     if (!(array_key_exists($CACHE_ID, $GLOBALS["LEARNING_CACHE_COURSE"]) && is_array($GLOBALS["LEARNING_CACHE_COURSE"][$CACHE_ID]))) {
         $oTree = CLearnLesson::GetTree(CCourse::CourseGetLinkedLesson($COURSE_ID), array('EDGE_SORT' => 'asc'), array('ACTIVE' => 'Y', 'CHECK_PERMISSIONS' => 'N'), true, $arSelectFields);
         $arTree = $oTree->GetTreeAsListOldMode();
         $GLOBALS["LEARNING_CACHE_COURSE"][$CACHE_ID] = $arTree;
     }
     $r = new CDBResult();
     $r->InitFromArray($GLOBALS["LEARNING_CACHE_COURSE"][$CACHE_ID]);
     return $r;
 }
Ejemplo n.º 5
0
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"
Ejemplo n.º 6
0
    public function BuildList()
    {
        global $USER;
        $filterParams = GetFilterParams('filter_');
        // list's footer
        $this->oList->AddFooter(array(array('title' => GetMessage('MAIN_ADMIN_LIST_SELECTED'), 'value' => $this->rsData->SelectedRowsCount()), array('counter' => true, 'title' => GetMessage('MAIN_ADMIN_LIST_CHECKED'), 'value' => '0')));
        $oParentPath = new CLearnPath();
        if (isset($_GET['LESSON_PATH'])) {
            $oParentPath->ImportUrlencoded($_GET['LESSON_PATH']);
        }
        $arParentPath = $oParentPath->GetPathAsArray();
        // building list
        while ($arRes = $this->rsData->NavNext(false)) {
            $oCurPath = new CLearnPath();
            $oCurPath->SetPathFromArray(array_merge($arParentPath, array($arRes['LESSON_ID'])));
            $urlCurPath = $oCurPath->ExportUrlencoded();
            unset($oCurPath);
            // PUBLISH_PROHIBITED available in context of most parent course only
            if ($this->contextCourseLessonId !== false) {
                $arRes['PUBLISH_PROHIBITED'] = 'N';
                if (CLearnLesson::IsPublishProhibited($arRes['LESSON_ID'], $this->contextCourseLessonId)) {
                    $arRes['PUBLISH_PROHIBITED'] = 'Y';
                }
            }
            $arRes['SITE_ID'] = '';
            $courseId = CLearnLesson::GetLinkedCourse($arRes['LESSON_ID']);
            if ($courseId !== false) {
                $hrefPrefix = 'learn_course_edit.php?COURSE_ID=' . $courseId;
                $resCourseSites = CCourse::GetSite($courseId);
                while ($arCourseSites = $resCourseSites->Fetch()) {
                    if ($arRes['SITE_ID'] != '') {
                        $arRes['SITE_ID'] .= ' / ';
                    }
                    $arRes['SITE_ID'] .= htmlspecialcharsbx($arCourseSites['LID']);
                }
            } else {
                $hrefPrefix = 'learn_unilesson_edit.php?LESSON_ID=' . $arRes['LESSON_ID'] . '&LESSON_PATH=' . urlencode($urlCurPath);
            }
            $actionEditLesson = $hrefPrefix . '&lang=' . LANG . $filterParams;
            $rowAction = false;
            $rowTitle = '';
            if (!$this->IsSearchMode()) {
                $rowAction = 'learn_unilesson_admin.php?lang=' . LANG . '&set_filter=Y' . '&PARENT_LESSON_ID=' . ($arRes['LESSON_ID'] + 0) . '&LESSON_PATH=' . $urlCurPath . '&' . $this->hrefSearchRetPoint;
                $rowTitle = GetMessage('LEARNING_TRAVERSE');
                // "Traverse list of immediate childs"
                if (!$arRes['IS_CHILDS']) {
                    $rowAction = $actionEditLesson;
                    $rowTitle = GetMessage('LEARNING_EDIT_TITLE');
                }
            }
            $row =& $this->oList->AddRow($arRes['LESSON_ID'], $arRes, $rowAction, $rowTitle);
            $arParents = $arChilds = array();
            $htmlParents = $htmlChilds = '';
            $rsParents = CLearnLesson::GetListOfImmediateParents($arRes['LESSON_ID'], array(), array('CHECK_PERMISSIONS' => 'N'));
            while ($arParent = $rsParents->Fetch()) {
                $arParents[] = $arParent['NAME'];
            }
            $arParents = array_map('htmlspecialcharsbx', $arParents);
            if (count($arParents) > 0) {
                $htmlParents = implode('<hr width="100%" size="1">', $arParents);
            } else {
                $htmlParents = '&nbsp;';
            }
            $rsChilds = CLearnLesson::GetListOfImmediateChilds($arRes['LESSON_ID'], array(), array('CHECK_PERMISSIONS' => 'N'));
            while ($arChild = $rsChilds->Fetch()) {
                $arChilds[] = $arChild['NAME'];
            }
            $arChilds = array_map('htmlspecialcharsbx', $arChilds);
            if (count($arChilds) > 0) {
                $htmlChilds = implode('<hr width="100%" size="1">', $arChilds);
            } else {
                $htmlChilds = '&nbsp;';
            }
            if (isset($arRes['LINKED_LESSON_ID']) && $arRes['LINKED_LESSON_ID'] > 0) {
                $icon = 'learning_icon_courses';
            } elseif (count($arChilds) > 0) {
                $icon = 'learning_icon_chapters';
            } else {
                $icon = 'learning_icon_lessons';
            }
            if (!$this->IsSearchMode()) {
                $row->AddViewField('NAME', '<span class="adm-list-table-icon-link"><span class="adm-submenu-item-link-icon adm-list-table-icon ' . $icon . '"></span>' . ($rowAction === false ? '<span class="adm-list-table-link">' . htmlspecialcharsbx($arRes['NAME']) . '</span>' : '<a href="' . $rowAction . '" class="adm-list-table-link">' . htmlspecialcharsbx($arRes['NAME']) . '</a>') . '</span>');
            } else {
                $actionUseLesson = "(function()\n\t\t\t\t\t{\n\t\t\t\t\t\tvar fnName = '" . str_replace(array("'", ';', ',', "\n", "\r"), '', htmlspecialcharsbx($this->search_retpoint)) . "';\n\t\t\t\t\t\tif ( ! (window.opener && window.opener[fnName]) )\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\twindow.opener[fnName]('" . (int) $arRes['LESSON_ID'] . "', '" . CUtil::JSEscape(htmlspecialcharsbx($arRes['NAME'])) . "');\n\t\t\t\t\t\twindow.close();\n\t\t\t\t\t})();\n\t\t\t\t\t";
                $row->AddViewField('NAME', '<a href="javascript:void(0);" class="adm-list-table-icon-link" onclick="' . $actionUseLesson . '"><span class="adm-submenu-item-link-icon adm-list-table-icon ' . $icon . '"></span><span class="adm-list-table-link">' . htmlspecialcharsbx($arRes['NAME']) . '</span></a>');
            }
            $row->AddViewField('PARENTS', $htmlParents);
            $row->AddEditField('PARENTS', '&nbsp;');
            $row->AddViewField('CHILDS', $htmlChilds);
            $row->AddEditField('CHILDS', '&nbsp;');
            // this is very heavy statistic, so will be a good idea to add settings to the module, which turn off this statistics
            $oLearnTree = CLearnLesson::GetTree($arRes['LESSON_ID']);
            $arTree = $oLearnTree->GetTreeAsList();
            $depth = -1;
            $chapterCount = 0;
            $lessonsCount = 0;
            $questionsCount = CLQuestion::GetCount(array('LESSON_ID' => (int) $arRes['LESSON_ID']));
            foreach ($arTree as $arLessonData) {
                if ($arLessonData['IS_CHILDS']) {
                    ++$chapterCount;
                } else {
                    ++$lessonsCount;
                }
                if ((int) $arLessonData['#DEPTH_IN_TREE'] > $depth) {
                    $depth = (int) $arLessonData['#DEPTH_IN_TREE'];
                }
                $questionsCount += CLQuestion::GetCount(array('LESSON_ID' => (int) $arLessonData['LESSON_ID']));
            }
            // PUBLISH_PROHIBITED available in context of most parent course only
            if ($this->contextCourseLessonId !== false) {
                if ($this->IsLessonUpdateAccess($arRes['LESSON_ID']) === true) {
                    $row->AddInputField('PUBLISH_PROHIBITED', array('size' => '35'));
                    $row->AddCheckField('PUBLISH_PROHIBITED');
                } else {
                    $row->AddCheckField('PUBLISH_PROHIBITED', true);
                }
            }
            // Render CARDINALITY fields
            $htmlDepth = (int) ($depth + 1);
            $htmlChapters = (string) (int) $chapterCount . '&nbsp;[<a href="learn_unilesson_edit.php?lang=' . LANG . '&PROPOSE_RETURN_LESSON_PATH=' . $urlCurPath . '" title="' . GetMessage('LEARNING_UNILESSON_ADD') . '"' . '>+</a>]';
            $htmlLessons = (string) (int) $lessonsCount . '&nbsp;[<a href="learn_unilesson_edit.php?lang=' . LANG . '&PROPOSE_RETURN_LESSON_PATH=' . $urlCurPath . '" title="' . GetMessage('LEARNING_UNILESSON_ADD') . '"' . '>+</a>]';
            $htmlQuestions = '<a href="learn_question_admin.php?lang=' . LANG . '&filter=Y&set_filter=Y' . '&PARENT_LESSON_ID=' . ($arRes['LESSON_ID'] + 0) . '&LESSON_PATH=' . $urlCurPath . '" title="' . GetMessage('LEARNING_QUESTION_ALT') . '">' . (int) $questionsCount . '</a>' . '&nbsp;[' . '<a href="learn_question_edit.php?lang=' . LANG . '&LESSON_PATH=' . $urlCurPath . '&QUESTION_TYPE=S' . '&filter=Y&set_filter=Y' . '&from=learn_menu"' . ' title="' . GetMessage('LEARNING_QUESTION_ADD') . '">+</a>' . ']';
            $row->AddViewField('CARDINALITY_DEPTH', $htmlDepth);
            $row->AddViewField('CARDINALITY_CHAPTERS', $htmlChapters);
            $row->AddViewField('CARDINALITY_LESSONS', $htmlLessons);
            $row->AddViewField('CARDINALITY_QUESTIONS', $htmlQuestions);
            if ($courseId !== false) {
                $testsCount = (int) CTest::GetCount(array('COURSE_ID' => $courseId));
                $htmlTests = '<a href="learn_test_admin.php?lang=' . LANG . '&COURSE_ID=' . $courseId . '&PARENT_LESSON_ID=' . (int) $arRes['LESSON_ID'] . '&LESSON_PATH=' . $urlCurPath . '&filter=Y&set_filter=Y"' . '>' . $testsCount . '</a>' . '&nbsp;[<a href="learn_test_edit.php?lang=' . LANG . '&COURSE_ID=' . $courseId . '&PARENT_LESSON_ID=' . (int) $arRes['LESSON_ID'] . '&LESSON_PATH=' . $urlCurPath . '&filter=Y&set_filter=Y"
					title="' . GetMessage('LEARNING_QUESTION_ADD') . '"' . '>+</a>]';
                $row->AddViewField('CARDINALITY_TESTS', $htmlTests);
            }
            if (!$this->IsSearchMode() && $this->IsLessonUpdateAccess($arRes['LESSON_ID']) === true) {
                $row->AddInputField('NAME', array('size' => '35'));
                // SORT field editing possibly only for courses and for lessons in relation to parent lesson
                if ($this->IsListChildLessonsMode() || $this->IsListAnyCoursesMode()) {
                    $row->AddInputField('SORT', array('size' => '3'));
                }
                $row->AddCheckField('ACTIVE');
                $row->AddInputField('CODE');
            } else {
                $row->AddCheckField('ACTIVE', false);
            }
            $row->AddViewField('CREATED_USER_NAME', $arRes['CREATED_USER_NAME']);
            $arActions = array();
            if (!$this->IsSearchMode()) {
                if ($this->IsLessonUpdateAccess($arRes['LESSON_ID']) === true) {
                    $editTxt = GetMessage('MAIN_ADMIN_MENU_EDIT');
                } else {
                    $editTxt = GetMessage('MAIN_ADMIN_MENU_OPEN');
                }
                // Actions
                $arActions[] = array('ICON' => 'edit', 'TEXT' => $editTxt, 'ACTION' => $this->oList->ActionRedirect($actionEditLesson));
                $arActions[] = array("SEPARATOR" => true);
                $arActions[] = array('ICON' => 'list', 'TEXT' => GetMessage('LEARNING_QUESTION_ALT') . ' (' . ($questionsCount + 0) . ')', 'ACTION' => $this->oList->ActionRedirect('learn_question_admin.php?lang=' . LANG . '&filter=Y&set_filter=Y' . '&PARENT_LESSON_ID=' . ($arRes['LESSON_ID'] + 0) . '&LESSON_PATH=' . urlencode($urlCurPath)));
                /*
                $arActions[] = array(
                	"ICON"=>"copy",
                	"TEXT"=>GetMessage("MAIN_ADMIN_ADD_COPY"),
                	"ACTION"=>$this->oList->ActionRedirect("learn_course_edit.php?COPY_ID=".$f_ID));
                */
                $isDeleteCmdDisabled = true;
                $isDisbandCmdDisabled = true;
                $deleteMSG = '';
                $disbandMSG = '';
                $actionDisband = '';
                $action = '';
                if ($arRes['CHILDS_CNT'] > 0) {
                    $deleteMSG = GetMessage('LEARNING_ADMIN_MENU_DELETE_RECURSIVE') . ' (' . (string) (int) $arRes['CHILDS_CNT'] . ')';
                } else {
                    $deleteMSG = GetMessage("MAIN_ADMIN_MENU_DELETE");
                }
                $disbandMSG = GetMessage('LEARNING_ADMIN_MENU_DISBAND');
                $isEnoughRightsForDisbandLesson = false;
                try {
                    $this->EnsureLessonDisbandAccess($arRes['LESSON_ID']);
                    $isEnoughRightsForDisbandLesson = true;
                } catch (CLearnRenderAdminUnilessonListException $e) {
                    if ($e->GetCode() & CLearnRenderAdminUnilessonListException::C_ACCESS_DENIED) {
                    } else {
                        // bubble exception
                        throw new CLearnRenderAdminUnilessonListException($e->GetMessage(), $e->GetCode());
                    }
                }
                // If we can unlink all neighbours and remove lesson
                if ($isEnoughRightsForDisbandLesson) {
                    $arOPathes = CLearnLesson::GetListOfParentPathes($arRes['LESSON_ID']);
                    $parentPathesCnt = count($arOPathes);
                    // prepare "Disband" command
                    $isDisbandCmdDisabled = false;
                    $actionDisband = $this->oList->ActionDoGroup($arRes['LESSON_ID'], 'disband', 'PARENT_LESSON_ID=' . ($this->requestedParentLessonId + 0));
                    if ($parentPathesCnt >= 1) {
                        $actionDisband = "if(confirm('" . str_replace('#CNT#', $parentPathesCnt, GetMessageJS('LEARNING_CONFIRM_DISBAND_LESSON_WITH_PARENT_PATHES')) . "')) " . '{ ' . $actionDisband . ' }';
                    }
                    $actionDisband = "if(confirm('" . GetMessageJS('LEARNING_ADMIN_MENU_DISBAND_QUESTION') . "')) " . '{ ' . $actionDisband . ' }';
                    // prepare "Remove" command
                    $isDeleteCmdDisabled = false;
                    if ($arRes['CHILDS_CNT'] > 0) {
                        $action = $this->oList->ActionDoGroup($arRes['LESSON_ID'], 'recursive_delete', 'PARENT_LESSON_ID=' . ($this->requestedParentLessonId + 0));
                    } else {
                        // If no childs => "delete" is equal to "disband"
                        $action = $this->oList->ActionDoGroup($arRes['LESSON_ID'], 'disband', 'PARENT_LESSON_ID=' . ($this->requestedParentLessonId + 0));
                    }
                    if ($parentPathesCnt >= 1) {
                        $deleteMSG .= ' [' . $parentPathesCnt . ']';
                        $action = "if(confirm('" . str_replace('#CNT#', $parentPathesCnt, GetMessageJS("LEARNING_CONFIRM_DEL_LESSON_WITH_PARENT_PATHES")) . "')) " . $action;
                    } else {
                        $action = "if(confirm('" . GetMessageJS('LEARNING_CONFIRM_DEL_MESSAGE') . "')) " . $action;
                    }
                }
                // We can "disband" only lessons, that contains childs
                $arActions[] = array("SEPARATOR" => true);
                if ($arRes['CHILDS_CNT'] > 0) {
                    $arActions[] = array('ICON' => 'delete', 'TEXT' => $disbandMSG, 'ACTION' => $actionDisband, 'DISABLED' => $isDisbandCmdDisabled, 'TITLE' => GetMessage('LEARNING_ADMIN_MENU_DISBAND_TITLE'));
                }
                $arActions[] = array('ICON' => 'delete', 'TEXT' => $deleteMSG, 'ACTION' => $action, 'DISABLED' => $isDeleteCmdDisabled);
            } else {
                $arActions[] = array('ICON' => 'list', 'TEXT' => GetMessage('LEARNING_SELECT'), 'ACTION' => $actionUseLesson);
            }
            $row->AddActions($arActions);
        }
        return $this;
    }