diff --git a/main/install/configuration.dist.php b/main/install/configuration.dist.php index 536ddf389f..76798923a7 100644 --- a/main/install/configuration.dist.php +++ b/main/install/configuration.dist.php @@ -2347,6 +2347,22 @@ INSERT INTO `extra_field` (`extra_field_type`, `field_type`, `variable`, `displa //CREATE INDEX c_attendance_sheet_user ON track_e_access_complete (attendance_sheet_id, user_id); //$_configuration['attendance_allow_comments'] = false; +// Enable categories in Wiki tool. +// 1. Run the following DB changes: +/* +CREATE TABLE c_wiki_rel_category (wiki_id INT NOT NULL, category_id INT NOT NULL, INDEX IDX_AC88945BAA948DBE (wiki_id), INDEX IDX_AC88945B12469DE2 (category_id), PRIMARY KEY(wiki_id, category_id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB; +CREATE TABLE c_wiki_category (id INT AUTO_INCREMENT NOT NULL, c_id INT NOT NULL, session_id INT DEFAULT NULL, tree_root INT DEFAULT NULL, parent_id INT DEFAULT NULL, name VARCHAR(255) NOT NULL, lft INT NOT NULL, lvl INT NOT NULL, rgt INT NOT NULL, INDEX IDX_17F1099A91D79BD3 (c_id), INDEX IDX_17F1099A613FECDF (session_id), INDEX IDX_17F1099AA977936C (tree_root), INDEX IDX_17F1099A727ACA70 (parent_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB; +ALTER TABLE c_wiki_rel_category ADD CONSTRAINT FK_AC88945BAA948DBE FOREIGN KEY (wiki_id) REFERENCES c_wiki (iid) ON DELETE CASCADE; +ALTER TABLE c_wiki_rel_category ADD CONSTRAINT FK_AC88945B12469DE2 FOREIGN KEY (category_id) REFERENCES c_wiki_category (id) ON DELETE CASCADE; +ALTER TABLE c_wiki_category ADD CONSTRAINT FK_17F1099A91D79BD3 FOREIGN KEY (c_id) REFERENCES course (id) ON DELETE CASCADE; +ALTER TABLE c_wiki_category ADD CONSTRAINT FK_17F1099A613FECDF FOREIGN KEY (session_id) REFERENCES session (id) ON DELETE CASCADE; +ALTER TABLE c_wiki_category ADD CONSTRAINT FK_17F1099AA977936C FOREIGN KEY (tree_root) REFERENCES c_wiki_category (id) ON DELETE CASCADE; +ALTER TABLE c_wiki_category ADD CONSTRAINT FK_17F1099A727ACA70 FOREIGN KEY (parent_id) REFERENCES c_wiki_category (id) ON DELETE CASCADE; +*/ +// 2. Add an "@" before "ORM\ManyToMany" and "@ORM\JoinTable" in the "CWiki::$categories" property definition (in src/Chamilo/CourseBundle/Entity/CWiki.php) +// 3. Add an "@" before "ORM\Entity" in the "CWikiCategory" class definition (in src/Chamilo/CourseBundle/Entity/CWikiCategory.php) +//$_configuration['wiki_categories_enabled'] = false; + // KEEP THIS AT THE END // -------- Custom DB changes // Add user activation by confirmation email diff --git a/main/wiki/index.php b/main/wiki/index.php index 209e5f6247..5dd09dab6d 100755 --- a/main/wiki/index.php +++ b/main/wiki/index.php @@ -71,7 +71,7 @@ if ($groupId) { $is_allowed_to_edit = api_is_allowed_to_edit(false, true); // The page we are dealing with -$page = isset($_GET['title']) ? $_GET['title'] : 'index'; +$page = $_GET['title'] ?? 'index'; $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : 'showpage'; $view = isset($_GET['view']) ? Security::remove_XSS($_GET['view']) : null; @@ -88,8 +88,8 @@ $wiki->blockConcurrentEditions(api_get_user_id(), $action); /* MAIN WIKI AREA */ ob_start(); -$handleAction = $wiki->handleAction($action); -if (!$handleAction && $action == 'export_to_pdf') { +$wiki->handleAction($action); +if ($action == 'export_to_pdf') { $wiki->handleAction('showpage'); } $content = ob_get_contents(); diff --git a/main/wiki/wiki.inc.php b/main/wiki/wiki.inc.php index 03f6e8986a..b17f16fb9e 100755 --- a/main/wiki/wiki.inc.php +++ b/main/wiki/wiki.inc.php @@ -2,7 +2,10 @@ /* For licensing terms, see /license.txt */ +use Chamilo\CourseBundle\Entity\CWiki; +use Chamilo\CourseBundle\Entity\CWikiCategory; use ChamiloSession as Session; +use Doctrine\DBAL\Driver\Statement; /** * Class Wiki @@ -55,6 +58,7 @@ class Wiki $this->groupfilter = ' group_id="'.$this->group_id.'"'; } $this->courseInfo = api_get_course_info(); + $this->courseCode = api_get_course_id(); $this->url = api_get_path(WEB_CODE_PATH).'wiki/index.php?'.api_get_cidreq(); } @@ -282,7 +286,7 @@ class Wiki * * @param array $values * - * @return language string saying that the changes are stored + * @return string */ public function save_wiki($values) { @@ -290,7 +294,7 @@ class Wiki $tbl_wiki_conf = $this->tbl_wiki_conf; $_course = $this->courseInfo; - $time = api_get_utc_datetime(); + $time = api_get_utc_datetime(null, false, true); $session_id = api_get_session_id(); $groupId = api_get_group_id(); $userId = api_get_user_id(); @@ -362,38 +366,43 @@ class Wiki $_clean['max_version'] = $values['max_version']; } - $values['assignment'] = isset($values['assignment']) ? $values['assignment'] : 0; - $values['page_id'] = isset($values['page_id']) ? $values['page_id'] : 0; - - $params = [ - 'c_id' => $course_id, - 'addlock' => 1, - 'visibility' => 1, - 'visibility_disc' => 1, - 'addlock_disc' => 1, - 'ratinglock_disc' => 1, - 'page_id' => $pageId, - 'reflink' => trim($values['reflink']), - 'title' => trim($values['title']), - 'content' => $values['content'], - 'user_id' => $userId, - 'group_id' => $groupId, - 'dtime' => $time, - 'assignment' => $values['assignment'], - 'comment' => $values['comment'], - 'progress' => $values['progress'], - 'version' => $version, - 'linksto' => $linkTo, - 'user_ip' => $_SERVER['REMOTE_ADDR'], - 'session_id' => $session_id, - 'page_id' => $values['page_id'], - 'editlock' => 0, - 'is_editing' => 0, - 'time_edit' => $time, - 'tag' => '', - ]; - - $id = Database::insert($tbl_wiki, $params); + $values['assignment'] = $values['assignment'] ?? 0; + $values['page_id'] = $values['page_id'] ?? 0; + + $em = Database::getManager(); + + $newWiki = (new CWiki()) + ->setCId($course_id) + ->setAddlock(1) + ->setVisibility(1) + ->setVisibilityDisc(1) + ->setAddlockDisc(1) + ->setRatinglockDisc(1) + ->setPageId($pageId) + ->setReflink(trim($values['reflink'])) + ->setTitle(trim($values['title'])) + ->setContent($values['content']) + ->setUserId($userId) + ->setGroupId($groupId) + ->setDtime($time) + ->setAssignment($values['assignment']) + ->setComment($values['comment']) + ->setProgress($values['progress']) + ->setVersion($version) + ->setLinksto($linkTo) + ->setUserIp(api_get_real_ip()) + ->setSessionId($session_id) + ->setPageId($values['page_id']) + ->setEditlock(0) + ->setIsEditing(0) + ->setTimeEdit($time) + ->setTag('') + ; + + $em->persist($newWiki); + $em->flush(); + + $id = $newWiki->getIid(); if ($id > 0) { $sql = "UPDATE $tbl_wiki SET id = iid WHERE iid = $id"; @@ -414,6 +423,8 @@ class Wiki WHERE c_id = '.$course_id.' AND iid ="'.$id.'"'; Database::query($sql); } + + self::assignCategoriesToWiki($newWiki, $values['category'] ?? []); } // Update wiki config @@ -490,49 +501,62 @@ class Wiki $r_version, $r_linksto ) { - $tbl_wiki = $this->tbl_wiki; $_course = $this->courseInfo; $r_user_id = api_get_user_id(); $r_dtime = api_get_utc_datetime(); + $dTime = api_get_utc_datetime(null, false, true); $r_version = $r_version + 1; $r_comment = get_lang('RestoredFromVersion').': '.$c_version; $session_id = api_get_session_id(); $course_id = api_get_course_int_id(); $groupInfo = GroupManager::get_group_properties($r_group_id); - $params = [ - 'c_id' => $course_id, - 'page_id' => $r_page_id, - 'reflink' => $r_reflink, - 'title' => $r_title, - 'content' => $r_content, - 'user_id' => $r_user_id, - 'group_id' => $r_group_id, - 'dtime' => $r_dtime, - 'assignment' => $r_assignment, - 'comment' => $r_comment, - 'progress' => $r_progress, - 'version' => $r_version, - 'linksto' => $r_linksto, - 'user_ip' => $_SERVER['REMOTE_ADDR'], - 'session_id' => $session_id, - ]; - $id = Database::insert($tbl_wiki, $params); + $em = Database::getManager(); + + $newWiki = (new CWiki()) + ->setCId($course_id) + ->setPageId($r_page_id) + ->setReflink($r_reflink) + ->setTitle($r_title) + ->setContent($r_content) + ->setUserId($r_user_id) + ->setGroupId($r_group_id) + ->setDtime($dTime) + ->setAssignment($r_assignment) + ->setComment($r_comment) + ->setProgress($r_progress) + ->setVersion($r_version) + ->setLinksto($r_linksto) + ->setUserIp(api_get_real_ip()) + ->setSessionId($session_id) + ->setAddlock(0) + ->setEditlock(0) + ->setVisibility(0) + ->setAddlockDisc(0) + ->setVisibilityDisc(0) + ->setRatinglockDisc(0) + ->setIsEditing(0) + ->setTag('') + ; + + $em->persist($newWiki); + $em->flush(); + + $newWiki->setId( + $newWiki->getIid() + ); - if ($id) { - $sql = "UPDATE $tbl_wiki SET id = iid WHERE iid = $id"; - Database::query($sql); + $em->flush(); - api_item_property_update( - $_course, - 'wiki', - $id, - 'WikiAdded', - api_get_user_id(), - $groupInfo - ); - self::check_emailcue($r_reflink, 'P', $r_dtime, $r_user_id); - } + api_item_property_update( + $_course, + 'wiki', + $newWiki->getIid(), + 'WikiAdded', + api_get_user_id(), + $groupInfo + ); + self::check_emailcue($r_reflink, 'P', $r_dtime, $r_user_id); return get_lang('PageRestored'); } @@ -590,8 +614,6 @@ class Wiki * @author Patrick Cool , Ghent University * * @todo consider merging this with the function save_wiki into one single function. - * - * @return string Message of success */ public function save_new_wiki($values) { @@ -658,13 +680,13 @@ class Wiki $_clean['linksto'] = self::links_to($_clean['content']); // cleaning config variables - $_clean['task'] = isset($values['task']) ? $values['task'] : ''; - $_clean['feedback1'] = isset($values['feedback1']) ? $values['feedback1'] : ''; - $_clean['feedback2'] = isset($values['feedback2']) ? $values['feedback2'] : ''; - $_clean['feedback3'] = isset($values['feedback3']) ? $values['feedback3'] : ''; - $_clean['fprogress1'] = isset($values['fprogress1']) ? $values['fprogress1'] : ''; - $_clean['fprogress2'] = isset($values['fprogress2']) ? $values['fprogress2'] : ''; - $_clean['fprogress3'] = isset($values['fprogress3']) ? $values['fprogress3'] : ''; + $_clean['task'] = $values['task'] ?? ''; + $_clean['feedback1'] = $values['feedback1'] ?? ''; + $_clean['feedback2'] = $values['feedback2'] ?? ''; + $_clean['feedback3'] = $values['feedback3'] ?? ''; + $_clean['fprogress1'] = $values['fprogress1'] ?? ''; + $_clean['fprogress2'] = $values['fprogress2'] ?? ''; + $_clean['fprogress3'] = $values['fprogress3'] ?? ''; if (isset($values['initstartdate']) && $values['initstartdate'] == 1) { $_clean['startdate_assig'] = $values['startdate_assig']; @@ -678,9 +700,9 @@ class Wiki $_clean['enddate_assig'] = null; } - $_clean['delayedsubmit'] = isset($values['delayedsubmit']) ? $values['delayedsubmit'] : ''; - $_clean['max_text'] = isset($values['max_text']) ? $values['max_text'] : ''; - $_clean['max_version'] = isset($values['max_version']) ? $values['max_version'] : ''; + $_clean['delayedsubmit'] = $values['delayedsubmit'] ?? ''; + $_clean['max_text'] = $values['max_text'] ?? ''; + $_clean['max_version'] = $values['max_version'] ?? ''; $course_id = api_get_course_int_id(); @@ -701,29 +723,39 @@ class Wiki ''. $values['title'].''; } else { - $dtime = api_get_utc_datetime(); - - $params = [ - 'c_id' => $course_id, - 'reflink' => $_clean['reflink'], - 'title' => $_clean['title'], - 'content' => $_clean['content'], - 'user_id' => $_clean['user_id'], - 'group_id' => $groupId, - 'dtime' => $dtime, - 'visibility' => $_clean['visibility'], - 'visibility_disc' => $_clean['visibility_disc'], - 'ratinglock_disc' => $_clean['ratinglock_disc'], - 'assignment' => $_clean['assignment'], - 'comment' => $_clean['comment'], - 'progress' => $_clean['progress'], - 'version' => $_clean['version'], - 'linksto' => $_clean['linksto'], - 'user_ip' => $_SERVER['REMOTE_ADDR'], - 'session_id' => $session_id, - 'addlock_disc' => 1, - ]; - $id = Database::insert($tbl_wiki, $params); + $em = Database::getManager(); + $dtime = api_get_utc_datetime(null, false, true); + + $newWiki = (new CWiki()) + ->setCId($course_id) + ->setReflink($_clean['reflink']) + ->setTitle($_clean['title']) + ->setContent($_clean['content']) + ->setUserId($_clean['user_id']) + ->setGroupId($groupId) + ->setDtime($dtime) + ->setVisibility($_clean['visibility']) + ->setVisibilityDisc($_clean['visibility_disc']) + ->setRatinglockDisc($_clean['ratinglock_disc']) + ->setAssignment($_clean['assignment']) + ->setComment($_clean['comment']) + ->setProgress($_clean['progress']) + ->setVersion($_clean['version']) + ->setLinksto($_clean['linksto']) + ->setUserIp(api_get_real_ip()) + ->setSessionId($session_id) + ->setAddlock(0) + ->setAddlockDisc(1) + ->setEditlock(0) + ->setIsEditing(0) + ->setTag('') + ; + + $em->persist($newWiki); + $em->flush(); + + $id = $newWiki->getIid(); + if ($id > 0) { $sql = "UPDATE $tbl_wiki SET id = iid WHERE iid = $id"; Database::query($sql); @@ -762,6 +794,8 @@ class Wiki Database::insert($tbl_wiki_conf, $params); + self::assignCategoriesToWiki($newWiki, $values['category'] ?? []); + $this->setWikiData($id); self::check_emailcue(0, 'A'); @@ -771,11 +805,7 @@ class Wiki } } - /** - * @param FormValidator $form - * @param array $row - */ - public function setForm($form, $row = []) + public function setForm(FormValidator $form, array $row = []) { $toolBar = api_is_allowed_to_edit(null, true) ? [ @@ -808,6 +838,25 @@ class Wiki $progress ); + if (true === api_get_configuration_value('wiki_categories_enabled')) { + $em = Database::getManager(); + + $categories = $em->getRepository(CWikiCategory::class) + ->findByCourse( + api_get_course_entity(), + api_get_session_entity() + ); + + $form->addSelectFromCollection( + 'category', + get_lang('Categories'), + $categories, + ['multiple' => 'multiple'], + false, + 'getNodeName' + ); + } + if ((api_is_allowed_to_edit(false, true) || api_is_platform_admin()) && isset($row['reflink']) && $row['reflink'] != 'index' @@ -940,7 +989,7 @@ class Wiki $_GET['title'] ) : ''; $form->setDefaults(['title' => $title]); - $form->addElement('button', 'SaveWikiNew', get_lang('Save')); + $form->addButtonSave(get_lang('Save'), 'SaveWikiNew'); $form->display(); if ($form->validate()) { @@ -965,7 +1014,7 @@ class Wiki self::auto_add_page_users($values); } - $return_message = self::save_new_wiki($values); + $return_message = $this->save_new_wiki($values); if ($return_message == false) { Display::addFlash( @@ -998,21 +1047,17 @@ class Wiki * * @author Patrick Cool , Ghent University * @author Juan Carlos RaƱa Trabado - * - * @param string $newtitle - * - * @return string html code */ - public function display_wiki_entry($newtitle) + public function display_wiki_entry(string $newtitle) { - $tbl_wiki = $this->tbl_wiki; - $tbl_wiki_conf = $this->tbl_wiki_conf; - $condition_session = $this->condition_session; + $tblWiki = $this->tbl_wiki; + $tblWikiConf = $this->tbl_wiki_conf; + $conditionSession = $this->condition_session; $groupfilter = $this->groupfilter; $page = $this->page; - $session_id = api_get_session_id(); - $course_id = api_get_course_int_id(); + $sessionId = api_get_session_id(); + $courseId = api_get_course_int_id(); if ($newtitle) { $pageMIX = $newtitle; //display the page after it is created @@ -1027,12 +1072,12 @@ class Wiki } // First, check page visibility in the first page version - $sql = 'SELECT * FROM '.$tbl_wiki.' + $sql = 'SELECT * FROM '.$tblWiki.' WHERE - c_id = '.$course_id.' AND - reflink="'.Database::escape_string($pageMIX).'" AND - '.$groupfilter.$condition_session.' - ORDER BY id ASC'; + c_id = '.$courseId.' AND + reflink = "'.Database::escape_string($pageMIX).'" AND + '.$groupfilter.$conditionSession.' + ORDER BY id'; $result = Database::query($sql); $row = Database::fetch_array($result, 'ASSOC'); @@ -1042,18 +1087,18 @@ class Wiki } // second, show the last version - $sql = 'SELECT * FROM '.$tbl_wiki.' w - INNER JOIN '.$tbl_wiki_conf.' wc - ON (wc.page_id = w.page_id AND wc.c_id = w.c_id) - WHERE - w.c_id = '.$course_id.' AND - w.reflink = "'.Database::escape_string($pageMIX).'" AND - w.session_id = '.$session_id.' AND - w.'.$groupfilter.' '.$filter.' - ORDER BY id DESC'; + $sql = 'SELECT * FROM '.$tblWiki.' w + INNER JOIN '.$tblWikiConf.' wc + ON (wc.page_id = w.page_id AND wc.c_id = w.c_id) + WHERE + w.c_id = '.$courseId.' AND + w.reflink = "'.Database::escape_string($pageMIX).'" AND + w.session_id = '.$sessionId.' AND + w.'.$groupfilter.' '.$filter.' + ORDER BY id DESC'; $result = Database::query($sql); - // we do not need a while loop since we are always displaying the last version + // we do not need awhile loop since we are always displaying the last version $row = Database::fetch_array($result, 'ASSOC'); //log users access to wiki (page_id) @@ -1062,23 +1107,23 @@ class Wiki } //update visits if ($row && $row['id']) { - $sql = 'UPDATE '.$tbl_wiki.' SET hits=(hits+1) - WHERE c_id = '.$course_id.' AND id='.$row['id'].''; + $sql = 'UPDATE '.$tblWiki.' SET hits=(hits+1) + WHERE c_id = '.$courseId.' AND id='.$row['id']; Database::query($sql); } $groupInfo = GroupManager::get_group_properties(api_get_group_id()); - // if both are empty and we are displaying the index page then we display the default text. - if ($row['content'] == '' && $row['title'] == '' && $page == 'index') { + // if both are empty, and we are displaying the index page then we display the default text. + if (!$row || ($row['content'] == '' && $row['title'] == '' && $page == 'index')) { if (api_is_allowed_to_edit(false, true) || api_is_platform_admin() || GroupManager::is_user_in_group(api_get_user_id(), $groupInfo) || api_is_allowed_in_course() ) { //Table structure for better export to pdf - $default_table_for_content_Start = '
'; - $default_table_for_content_End = '
'; + $default_table_for_content_Start = '
'; + $default_table_for_content_End = '
'; $content = $default_table_for_content_Start. sprintf( get_lang('DefaultContent'), @@ -1087,13 +1132,15 @@ class Wiki $default_table_for_content_End; $title = get_lang('DefaultTitle'); } else { - return Display::addFlash( + Display::addFlash( Display::return_message( get_lang('WikiStandBy'), 'normal', false ) ); + + return; } } else { if (true === api_get_configuration_value('wiki_html_strict_filtering')) { @@ -1104,68 +1151,64 @@ class Wiki $title = Security::remove_XSS($row['title']); } - //assignment mode: identify page type - $icon_assignment = null; - if ($row['assignment'] == 1) { - $icon_assignment = Display::return_icon( - 'wiki_assignment.png', - get_lang('AssignmentDescExtra'), - '', - ICON_SIZE_SMALL - ); - } elseif ($row['assignment'] == 2) { - $icon_assignment = Display::return_icon( - 'wiki_work.png', - get_lang('AssignmentWork'), - '', - ICON_SIZE_SMALL - ); - } + if (self::wiki_exist($title)) { + //assignment mode: identify page type + $icon_assignment = null; + if ($row['assignment'] == 1) { + $icon_assignment = Display::return_icon('wiki_assignment.png', get_lang('AssignmentDescExtra')); + } elseif ($row['assignment'] == 2) { + $icon_assignment = Display::return_icon('wiki_work.png', get_lang('AssignmentWork')); + } - // task mode - $icon_task = null; - if (!empty($row['task'])) { - $icon_task = Display::return_icon( - 'wiki_task.png', - get_lang('StandardTask'), - '', - ICON_SIZE_SMALL - ); + // task mode + $icon_task = null; + if (!empty($row['task'])) { + $icon_task = Display::return_icon('wiki_task.png', get_lang('StandardTask')); + } + + $pageTitle = $icon_assignment.PHP_EOL.$icon_task.' '.api_htmlentities($title); + } else { + $pageTitle = api_htmlentities($title); } // Show page. Show page to all users if isn't hide page. Mode assignments: if student is the author, can view - if ($KeyVisibility == "1" || - api_is_allowed_to_edit(false, true) || - api_is_platform_admin() || - ($row['assignment'] == 2 && $KeyVisibility == "0" && (api_get_user_id() == $row['user_id'])) || - api_is_allowed_in_course() + if ($KeyVisibility != "1" + && !api_is_allowed_to_edit(false, true) + && !api_is_platform_admin() + && ($row['assignment'] != 2 || $KeyVisibility != "0" || api_get_user_id() != $row['user_id']) + && !api_is_allowed_in_course() ) { - $actionsLeft = ''; - // menu edit page - $editLink = ''. - Display::return_icon( - 'edit.png', - get_lang('EditThisPage'), - '', - ICON_SIZE_MEDIUM - ).''; + return; + } - if (api_is_allowed_to_edit(false, true)) { + $actionsLeft = ''; + $actionsRight = ''; + // menu edit page + $editLink = '' + .Display::return_icon('edit.png', get_lang('EditThisPage'), [], ICON_SIZE_MEDIUM).''; + + if (api_is_allowed_to_edit(false, true)) { + $actionsLeft .= $editLink; + } else { + if ((api_is_allowed_in_course() || + GroupManager::is_user_in_group( + api_get_user_id(), + $groupInfo + )) + ) { $actionsLeft .= $editLink; } else { - if ((api_is_allowed_in_course() || - GroupManager::is_user_in_group( - api_get_user_id(), - $groupInfo - )) - ) { - $actionsLeft .= $editLink; - } else { - $actionsLeft .= ''; - } + $actionsLeft .= ''; } + } + + $pageProgress = 0; + $pageScore = 0; - $actionsRight = ''; + if ($row && $row['id']) { + $pageProgress = $row['progress'] * 10; + $pageScore = $row['score']; $protect_page = null; $lock_unlock_protect = null; @@ -1177,7 +1220,7 @@ class Wiki $protect_page = Display::return_icon( 'lock.png', get_lang('PageLockedExtra'), - '', + [], ICON_SIZE_MEDIUM ); $lock_unlock_protect = 'unlock'; @@ -1185,17 +1228,16 @@ class Wiki $protect_page = Display::return_icon( 'unlock.png', get_lang('PageUnlockedExtra'), - '', + [], ICON_SIZE_MEDIUM ); $lock_unlock_protect = 'lock'; } } - if ($row['id']) { - $actionsRight .= ''. - $protect_page.''; - } + $actionsRight .= ''. + $protect_page.''; $visibility_page = null; $lock_unlock_visibility = null; @@ -1207,7 +1249,7 @@ class Wiki $visibility_page = Display::return_icon( 'visible.png', get_lang('ShowPageExtra'), - '', + [], ICON_SIZE_MEDIUM ); $lock_unlock_visibility = 'invisible'; @@ -1215,25 +1257,26 @@ class Wiki $visibility_page = Display::return_icon( 'invisible.png', get_lang('HidePageExtra'), - '', + [], ICON_SIZE_MEDIUM ); $lock_unlock_visibility = 'visible'; } } - if ($row['id']) { - $actionsRight .= ''. - $visibility_page.''; - } + $actionsRight .= ''.$visibility_page.''; + // Only available if row['id'] is set //page action: notification + $lock_unlock_notify_page = ''; + if (api_is_allowed_to_session_edit()) { if (self::check_notify_page($page) == 1) { $notify_page = Display::return_icon( 'messagebox_info.png', get_lang('NotifyByEmail'), - '', + [], ICON_SIZE_MEDIUM ); $lock_unlock_notify_page = 'unlocknotify'; @@ -1241,164 +1284,148 @@ class Wiki $notify_page = Display::return_icon( 'mail.png', get_lang('CancelNotifyByEmail'), - '', + [], ICON_SIZE_MEDIUM ); $lock_unlock_notify_page = 'locknotify'; } } - // Only available if row['id'] is set - if ($row['id']) { - if (api_is_allowed_to_session_edit(false, true) && - api_is_allowed_to_edit() || - GroupManager::is_user_in_group( - api_get_user_id(), - $groupInfo - ) - ) { - // menu discuss page - $actionsRight .= ''. - Display::return_icon( - 'discuss.png', - get_lang('DiscussThisPage'), - '', - ICON_SIZE_MEDIUM - ).''; - } - - //menu history - $actionsRight .= ''. - Display::return_icon( - 'history.png', - get_lang('ShowPageHistory'), - '', - ICON_SIZE_MEDIUM - ).''; - //menu linkspages - $actionsRight .= ''. - Display::return_icon( - 'what_link_here.png', - get_lang('LinksPages'), - '', + if (api_is_allowed_to_session_edit(false, true) + && api_is_allowed_to_edit() + || GroupManager::is_user_in_group(api_get_user_id(), $groupInfo) + ) { + // menu discuss page + $actionsRight .= '' + .Display::return_icon( + 'discuss.png', + get_lang('DiscussThisPage'), + [], ICON_SIZE_MEDIUM ).''; + } - //menu delete wikipage - if (api_is_allowed_to_edit(false, true) || - api_is_platform_admin() - ) { - $actionsRight .= ''. - Display::return_icon( - 'delete.png', - get_lang('DeleteThisPage'), - '', - ICON_SIZE_MEDIUM - ).''; - } + //menu history + $actionsRight .= ''. + Display::return_icon( + 'history.png', + get_lang('ShowPageHistory'), + [], + ICON_SIZE_MEDIUM + ).''; + //menu linkspages + $actionsRight .= '' + .Display::return_icon( + 'what_link_here.png', + get_lang('LinksPages'), + [], + ICON_SIZE_MEDIUM + ).''; - $actionsRight .= ''. - $notify_page.''; + //menu delete wikipage + if (api_is_allowed_to_edit(false, true) || + api_is_platform_admin() + ) { + $actionsRight .= '' + .Display::return_icon( + 'delete.png', + get_lang('DeleteThisPage'), + [], + ICON_SIZE_MEDIUM + ).''; + } - // Page action: copy last version to doc area - if (api_is_allowed_to_edit(false, true) || - api_is_platform_admin() - ) { - $actionsRight .= ''. - Display::return_icon( - 'export_to_documents.png', - get_lang('ExportToDocArea'), - '', - ICON_SIZE_MEDIUM - ).''; - } + $actionsRight .= ''.$notify_page.''; - $actionsRight .= ''. - Display::return_icon( - 'pdf.png', - get_lang('ExportToPDF'), - '', + // Page action: copy last version to doc area + if (api_is_allowed_to_edit(false, true) || + api_is_platform_admin() + ) { + $actionsRight .= '' + .Display::return_icon( + 'export_to_documents.png', + get_lang('ExportToDocArea'), + [], ICON_SIZE_MEDIUM ).''; + } - $unoconv = api_get_configuration_value('unoconv.binaries'); - if ($unoconv) { - $actionsRight .= ''. - Display::return_icon( - 'export_doc.png', - get_lang('ExportToDoc'), - [], - ICON_SIZE_MEDIUM - ).''; - } + $actionsRight .= '' + .Display::return_icon( + 'pdf.png', + get_lang('ExportToPDF'), + [], + ICON_SIZE_MEDIUM + ).''; - //export to print?> - - ' + .Display::return_icon( + 'export_doc.png', + get_lang('ExportToDoc'), + [], ICON_SIZE_MEDIUM - ), - '#', - ['onclick' => "javascript: goprint();"] - ); + ).''; } - echo Display::toolbarAction( - 'toolbar-wikistudent', - [$actionsLeft, $actionsRight] + //export to print?> + + "javascript: goprint();"] ); + } - if (self::wiki_exist($title)) { - $pageTitle = $icon_assignment.' '. - $icon_task.' '.api_htmlentities($title); - } else { - $pageTitle = api_htmlentities($title); - } + echo Display::toolbarAction( + 'toolbar-wikistudent', + [$actionsLeft, $actionsRight] + ); - $pageWiki = self::make_wiki_link_clickable( - self::detect_external_link( - self::detect_anchor_link( - self::detect_mail_link( - self::detect_ftp_link( - self::detect_irc_link( - self::detect_news_link($content) - ) - ) - ) - ) - ) - ); + $pageWiki = self::detect_news_link($content); + $pageWiki = self::detect_irc_link($pageWiki); + $pageWiki = self::detect_ftp_link($pageWiki); + $pageWiki = self::detect_mail_link($pageWiki); + $pageWiki = self::detect_anchor_link($pageWiki); + $pageWiki = self::detect_external_link($pageWiki); + $pageWiki = self::make_wiki_link_clickable($pageWiki); + + $footerWiki = ''; + // wikicontent require to print wiki document + echo '
'.Display::panel($pageWiki, $pageTitle, $footerWiki).'
'; //end filter visibility } /** @@ -1572,6 +1599,11 @@ class Wiki $result = Database::query($sql); $row = Database::fetch_array($result); + + if (!$row) { + return 0; + } + $status_editlock = $row['editlock']; $id = $row['page_id']; @@ -1600,7 +1632,7 @@ class Wiki } //show status - return $row['editlock']; + return (int) $row['editlock']; } /** @@ -1622,9 +1654,14 @@ class Wiki c_id = '.$course_id.' AND reflink="'.Database::escape_string($page).'" AND '.$groupfilter.$condition_session.' - ORDER BY id ASC'; + ORDER BY id'; $result = Database::query($sql); $row = Database::fetch_array($result); + + if (!$row) { + return 0; + } + $status_visibility = $row['visibility']; //change status if (api_is_allowed_to_edit(false, true) || @@ -1909,7 +1946,8 @@ class Wiki type="P"'; $result = Database::query($sql); $row = Database::fetch_array($result); - $idm = $row['id']; + + $idm = $row ? $row['id'] : 0; if (empty($idm)) { $status_notify = 0; } else { @@ -1987,7 +2025,7 @@ class Wiki c_id = '.$course_id.' AND id="'.$id.'" AND user_id="'.api_get_user_id().'" AND type="D"'; $result = Database::query($sql); $row = Database::fetch_array($result); - $idm = $row['id']; + $idm = $row ? $row['id'] : 0; if (empty($idm)) { $status_notify_disc = 0; @@ -2045,7 +2083,7 @@ class Wiki $result = Database::query($sql); $row = Database::fetch_array($result); - $idm = $row['user_id']; + $idm = $row ? $row['user_id'] : 0; if (empty($idm)) { $status_notify_all = 0; @@ -2065,7 +2103,6 @@ class Wiki } if (isset($_GET['actionpage']) && - isset($_GET['actionpage']) && $_GET['actionpage'] == 'unlocknotifyall' && $status_notify_all == 1 ) { @@ -2103,7 +2140,7 @@ class Wiki $session_id = api_get_session_id(); $course_id = api_get_course_int_id(); $group_properties = GroupManager::get_group_properties($groupId); - $group_name = $group_properties['name']; + $group_name = $group_properties ? $group_properties['name'] : ''; $allow_send_mail = false; //define the variable to below $email_assignment = null; if ($type == 'P') { @@ -2686,7 +2723,7 @@ class Wiki $values['assignment'] = 2; } $this->assig_user_id = $assig_user_id; - self::save_new_wiki($values); + $this->save_new_wiki($values); } } @@ -2708,130 +2745,111 @@ class Wiki $values['assignment'] = 1; } $this->assig_user_id = $assig_user_id; - self::save_new_wiki($values); + $this->save_new_wiki($values); } } } /** * Displays the results of a wiki search. - * - * @param string Search term - * @param int Whether to search the contents (1) or just the titles (0) - * @param int */ public function display_wiki_search_results( - $search_term, - $search_content = 0, - $all_vers = 0 + string $search_term, + int $search_content = 0, + int $all_vers = 0, + array $categoryIdList = [], + bool $matchAllCategories = false ) { $tbl_wiki = $this->tbl_wiki; - $condition_session = $this->condition_session; - $groupfilter = $this->groupfilter; - $_course = $this->courseInfo; + $sessionCondition = api_get_session_condition($this->session_id, true, false, 'wp.session_id'); + $groupfilter = ' wp.group_id = '.$this->group_id.' '; + $subGroupfilter = ' s2.group_id = '.$this->group_id.' '; + $subSessionCondition = api_get_session_condition($this->session_id, true, false, 's2.session_id').' '; + $categoryIdList = array_map('intval', $categoryIdList); + $categoriesJoin = ''; + + if ($categoryIdList) { + if ($matchAllCategories) { + foreach ($categoryIdList as $categoryId) { + $categoriesJoin .= "INNER JOIN c_wiki_rel_category AS wrc$categoryId + ON (wp.iid = wrc$categoryId.wiki_id AND wrc$categoryId.category_id = $categoryId) + INNER JOIN c_wiki_category AS wc$categoryId + ON (wrc$categoryId.category_id = wc$categoryId.id) "; + } + } else { + $categoriesJoin = 'INNER JOIN c_wiki_rel_category AS wrc ON (wp.iid = wrc.wiki_id) + INNER JOIN c_wiki_category AS wc ON (wrc.category_id = wc.id) '; + } + } + + $categoriesCondition = !$matchAllCategories + ? ($categoryIdList ? 'AND wc.id IN ('.implode(', ', $categoryIdList).')' : '') + : ''; + $course_id = api_get_course_int_id(); - echo ''.get_lang('WikiSearchResults').': '.Security::remove_XSS( - $search_term - ); - echo ''; + echo ''.get_lang('WikiSearchResults').': '.Security::remove_XSS($search_term).''; //only by professors when page is hidden if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) { - if ($all_vers == '1') { - if ($search_content == '1') { - $sql = "SELECT * FROM ".$tbl_wiki." - WHERE - c_id = $course_id AND - title LIKE '%".Database::escape_string($search_term)."%' OR - content LIKE '%".Database::escape_string( - $search_term - )."%' AND ".$groupfilter.$condition_session; - } else { - $sql = "SELECT * FROM ".$tbl_wiki." - WHERE - c_id = $course_id AND - title LIKE '%".Database::escape_string( - $search_term - )."%' AND ".$groupfilter.$condition_session; + if (1 === $all_vers) { + $sql = "SELECT * FROM $tbl_wiki AS wp $categoriesJoin + WHERE wp.c_id = $course_id + AND (wp.title LIKE '%".Database::escape_string($search_term)."%' "; + + if (1 === $search_content) { + $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' "; } + + $sql .= ") AND ".$groupfilter.$sessionCondition.$categoriesCondition; } else { - if ($search_content == '1') { - // warning don't use group by reflink because don't return the last version - $sql = "SELECT * FROM ".$tbl_wiki." s1 - WHERE - s1.c_id = $course_id AND - title LIKE '%".Database::escape_string($search_term)."%' OR - content LIKE '%".Database::escape_string($search_term)."%' AND - id=( - SELECT MAX(s2.id) - FROM ".$tbl_wiki." s2 - WHERE - s2.c_id = $course_id AND - s1.reflink = s2.reflink AND - ".$groupfilter.$condition_session.")"; - } else { + // warning don't use group by reflink because don't return the last version + $sql = "SELECT * FROM $tbl_wiki AS wp + WHERE wp.c_id = $course_id + AND (wp.title LIKE '%".Database::escape_string($search_term)."%' "; + + if (1 === $search_content) { // warning don't use group by reflink because don't return the last version - $sql = "SELECT * FROM ".$tbl_wiki." s1 - WHERE - s1.c_id = $course_id AND - title LIKE '%".Database::escape_string( - $search_term - )."%' AND - id = ( - SELECT MAX(s2.id) - FROM ".$tbl_wiki." s2 - WHERE - s2.c_id = $course_id AND - s1.reflink = s2.reflink AND - ".$groupfilter.$condition_session.")"; + $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' "; } + + $sql .= ") AND wp.id IN ( + SELECT MAX(s2.id) + FROM ".$tbl_wiki." s2 $categoriesJoin + WHERE s2.c_id = $course_id + AND s2.reflink = wp.reflink + AND ".$subGroupfilter.$subSessionCondition.$categoriesCondition." + )"; } } else { - if ($all_vers == '1') { - if ($search_content == '1') { + if (1 === $all_vers) { + $sql = "SELECT * FROM $tbl_wiki AS wp $categoriesJoin + WHERE wp.c_id = $course_id + AND wp.visibility = 1 + AND (wp.title LIKE '%".Database::escape_string($search_term)."%' "; + + if (1 === $search_content) { //search all pages and all versions - $sql = "SELECT * FROM ".$tbl_wiki." - WHERE - c_id = $course_id AND - visibility=1 AND - title LIKE '%".Database::escape_string($search_term)."%' OR - content LIKE '%".Database::escape_string($search_term)."%' AND - ".$groupfilter.$condition_session; - } else { - $sql = "SELECT * FROM ".$tbl_wiki." - WHERE - c_id = $course_id AND - visibility=1 AND - title LIKE '%".Database::escape_string($search_term)."%' AND - ".$groupfilter.$condition_session; + $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' "; } + + $sql .= ") AND ".$groupfilter.$sessionCondition.$categoriesCondition; } else { - if ($search_content == '1') { - $sql = "SELECT * FROM ".$tbl_wiki." s1 - WHERE - s1.c_id = $course_id AND - visibility=1 AND - title LIKE '%".Database::escape_string($search_term)."%' OR - content LIKE '%".Database::escape_string($search_term)."%' AND - id=( - SELECT MAX(s2.id) - FROM ".$tbl_wiki." s2 - WHERE s2.c_id = $course_id AND - s1.reflink = s2.reflink AND - ".$groupfilter.$condition_session.")"; - } else { - // warning don't use group by reflink because don't return the last version - $sql = "SELECT * FROM ".$tbl_wiki." s1 - WHERE - s1.c_id = $course_id AND - visibility=1 AND - title LIKE '%".Database::escape_string($search_term)."%' AND - id = ( - SELECT MAX(s2.id) FROM ".$tbl_wiki." s2 - WHERE s2.c_id = $course_id AND - s1.reflink = s2.reflink AND - ".$groupfilter.$condition_session.")"; + // warning don't use group by reflink because don't return the last version + $sql = "SELECT * FROM $tbl_wiki AS wp + WHERE wp.c_id = $course_id + AND wp.visibility = 1 + AND (wp.title LIKE '%".Database::escape_string($search_term)."%' "; + + if (1 === $search_content) { + $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' "; } + + $sql .= ") AND wp.id IN ( + SELECT MAX(s2.id) FROM $tbl_wiki s2 $categoriesJoin + WHERE s2.c_id = $course_id + AND s2.reflink = wp.reflink + AND ".$subGroupfilter.$subSessionCondition.$categoriesCondition." + )"; } } @@ -2840,132 +2858,104 @@ class Wiki //show table $rows = []; if (Database::num_rows($result) > 0) { + $self = api_get_self(); + $cidReq = api_get_cidreq(); + + $iconEdit = Display::return_icon('edit.png', get_lang('EditPage')); + $iconDiscuss = Display::return_icon('discuss.png', get_lang('Discuss')); + $iconHistory = Display::return_icon('history.png', get_lang('History')); + $iconLinks = Display::return_icon('what_link_here.png', get_lang('LinksPages')); + $iconDelete = Display::return_icon('delete.png', get_lang('Delete')); + while ($obj = Database::fetch_object($result)) { //get author $userinfo = api_get_user_info($obj->user_id); - //get time - $year = substr($obj->dtime, 0, 4); - $month = substr($obj->dtime, 5, 2); - $day = substr($obj->dtime, 8, 2); - $hours = substr($obj->dtime, 11, 2); - $minutes = substr($obj->dtime, 14, 2); - $seconds = substr($obj->dtime, 17, 2); //get type assignment icon + $ShowAssignment = ''; if ($obj->assignment == 1) { - $ShowAssignment = Display::return_icon( - 'wiki_assignment.png', - get_lang('AssignmentDesc'), - '', - ICON_SIZE_SMALL - ); + $ShowAssignment = Display::return_icon('wiki_assignment.png', get_lang('AssignmentDesc')); } elseif ($obj->assignment == 2) { - $ShowAssignment = Display::return_icon( - 'wiki_work.png', - get_lang('AssignmentWork'), - '', - ICON_SIZE_SMALL - ); + $ShowAssignment = Display::return_icon('wiki_work.png', get_lang('AssignmentWork')); } elseif ($obj->assignment == 0) { - $ShowAssignment = Display::return_icon( - 'px_transparent.gif' - ); + $ShowAssignment = Display::return_icon('px_transparent.gif'); } $row = []; $row[] = $ShowAssignment; - if ($all_vers == '1') { - $row[] = ''. - api_htmlentities($obj->title).''; - } else { - $row[] = ''. - $obj->title.''; + $wikiLinkParams = [ + 'action' => 'showpage', + 'title' => api_htmlentities($obj->reflink), + 'session_id' => (int) $_GET['session_id'], + 'group_id' => (int) $_GET['group_id'], + ]; + + if (1 === $all_vers) { + $wikiLinkParams['view'] = $obj->id; } - $row[] = ($obj->user_id != 0 && $userinfo !== false) ? UserManager::getUserProfileLink( - $userinfo - ) : get_lang('Anonymous').' ('.$obj->user_ip.')'; - $row[] = $year.'-'.$month.'-'.$day.' '.$hours.":".$minutes.":".$seconds; + $row[] = Display::url( + api_htmlentities($obj->title), + "$self?$cidReq&".http_build_query($wikiLinkParams) + ).$this->returnCategoriesBlock($obj->iid, '
', '
'); + + $row[] = ($obj->user_id != 0 && $userinfo !== false) + ? UserManager::getUserProfileLink($userinfo) + : get_lang('Anonymous').' ('.$obj->user_ip.')'; + $row[] = api_convert_and_format_date($obj->dtime); - if ($all_vers == '1') { + if (1 === $all_vers) { $row[] = $obj->version; } else { $showdelete = ''; - if (api_is_allowed_to_edit( - false, - true - ) || api_is_platform_admin()) { - $showdelete = ' '. - Display::return_icon( - 'delete.png', - get_lang('Delete'), - '', - ICON_SIZE_SMALL - ); + if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) { + $showdelete = Display::url( + $iconDelete, + "$self?$cidReq&".http_build_query([ + 'action' => 'delete', + 'title' => api_htmlentities($obj->reflink), + 'group_id' => (int) $_GET['group_id'], + ]) + ); } - $row[] = ''. - Display::return_icon( - 'edit.png', - get_lang('EditPage'), - '', - ICON_SIZE_SMALL - ).' - '. - Display::return_icon( - 'discuss.png', - get_lang('Discuss'), - '', - ICON_SIZE_SMALL - ).' - '. - Display::return_icon( - 'history.png', - get_lang('History'), - '', - ICON_SIZE_SMALL - ).' '. - Display::return_icon( - 'what_link_here.png', - get_lang('LinksPages'), - '', - ICON_SIZE_SMALL - ).''.$showdelete; - } - $rows[] = $row; + + $row[] = Display::url( + $iconEdit, + "$self?$cidReq&".http_build_query([ + 'action' => 'edit', + 'title' => api_htmlentities($obj->reflink), + 'group_id' => (int) $_GET['group_id'], + ]) + ) + .Display::url( + $iconDiscuss, + "$self?$cidReq&".http_build_query([ + 'action' => 'discuss', + 'title' => api_htmlentities($obj->reflink), + 'session_id' => (int) $_GET['session_id'], + 'group_id' => (int) $_GET['group_id'], + ]) + ) + .Display::url( + $iconHistory, + "$self?$cidReq&".http_build_query([ + 'action' => 'history', + 'title' => api_htmlentities($obj->reflink), + 'session_id' => (int) $_GET['session_id'], + 'group_id' => (int) $_GET['group_id'], + ]) + ) + .Display::url( + $iconLinks, + "$self?$cidReq&".http_build_query([ + 'action' => 'links', + 'title' => api_htmlentities($obj->reflink), + 'group_id' => (int) $_GET['group_id'], + ]) + ) + .$showdelete; + } + $rows[] = $row; } $table = new SortableTableFromArrayConfig( @@ -2979,9 +2969,10 @@ class Wiki ); $table->set_additional_parameters( [ - 'cidReq' => $_GET['cidReq'], + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, 'action' => $_GET['action'], - 'group_id' => intval($_GET['group_id']), 'mode_table' => 'yes2', 'search_term' => $search_term, 'search_content' => $search_content, @@ -2994,21 +2985,19 @@ class Wiki true, ['style' => 'width:30px;'] ); - $table->set_header(1, get_lang('Title'), true); - if ($all_vers == '1') { - $table->set_header(2, get_lang('Author'), true); - $table->set_header(3, get_lang('Date'), true); - $table->set_header(4, get_lang('Version'), true); + $table->set_header(1, get_lang('Title')); + if (1 === $all_vers) { + $table->set_header(2, get_lang('Author')); + $table->set_header(3, get_lang('Date')); + $table->set_header(4, get_lang('Version')); } else { $table->set_header( 2, - get_lang('Author').' ('.get_lang('LastVersion').')', - true + get_lang('Author').' '.get_lang('LastVersion').'' ); $table->set_header( 3, - get_lang('Date').' ('.get_lang('LastVersion').')', - true + get_lang('Date').' '.get_lang('LastVersion').'' ); $table->set_header( 4, @@ -3930,27 +3919,17 @@ class Wiki $userinfo = api_get_user_info($obj->user_id); $row = []; if ($obj->user_id != 0 && $userinfo !== false) { - $row[] = UserManager::getUserProfileLink($userinfo).' - '; + $row[] = Display::url( + $userinfo['complete_name_with_username'], + $this->url.'&'.http_build_query(['action' => 'usercontrib', 'user_id' => (int) $obj->user_id]) + ); } else { $row[] = get_lang('Anonymous').' ('.$obj->user_ip.')'; } - $row[] = ''.$obj->NUM_EDIT.''; + $row[] = Display::url( + $obj->NUM_EDIT, + $this->url.'&'.http_build_query(['action' => 'usercontrib', 'user_id' => (int) $obj->user_id]) + ); $rows[] = $row; } @@ -3965,10 +3944,10 @@ class Wiki ); $table->set_additional_parameters( [ - 'cidReq' => Security::remove_XSS($_GET['cidReq']), + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, 'action' => Security::remove_XSS($action), - 'session_id' => Security::remove_XSS($_GET['session_id']), - 'group_id' => Security::remove_XSS($_GET['group_id']), ] ); $table->set_header(0, get_lang('Author'), true); @@ -4438,10 +4417,6 @@ class Wiki */ public function allPages($action) { - $tbl_wiki = $this->tbl_wiki; - $course_id = $this->course_id; - $session_id = $this->session_id; - $groupfilter = $this->groupfilter; $_course = $this->courseInfo; echo '
'.get_lang('AllPages'); @@ -4458,204 +4433,171 @@ class Wiki } echo '
'; - if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) { - // only by professors if page is hidden - // warning don't use group by reflink because does not return the last version - $sql = 'SELECT * - FROM '.$tbl_wiki.' s1 - WHERE s1.c_id = '.$course_id.' AND id=( - SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2 - WHERE - s2.c_id = '.$course_id.' AND - s1.reflink = s2.reflink AND - '.$groupfilter.' AND - session_id='.$session_id.')'; - } else { - // warning don't use group by reflink because does not return the last version - $sql = 'SELECT * FROM '.$tbl_wiki.' s1 - WHERE visibility=1 AND s1.c_id = '.$course_id.' AND id=( - SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2 - WHERE - s2.c_id = '.$course_id.' AND - s1.reflink = s2.reflink AND - '.$groupfilter.' AND - session_id='.$session_id.')'; - } - - $allpages = Database::query($sql); - //show table - if (Database::num_rows($allpages) > 0) { - while ($obj = Database::fetch_object($allpages)) { - //get author - $userinfo = api_get_user_info($obj->user_id); - $username = api_htmlentities( - sprintf(get_lang('LoginX'), $userinfo['username']), - ENT_QUOTES - ); + $table = new SortableTable( + 'AllPages_table', + function () { + $result = $this->gelAllPagesQuery(true); + + return (int) Database::fetch_assoc($result)['nbr']; + }, + function ($from, $numberOfItems, $column, $direction) { + $result = $this->gelAllPagesQuery(false, $from, $numberOfItems, $column, $direction); + $rows = []; + while ($data = Database::fetch_assoc($result)) { + $rows[] = [ + $data['col0'], + [$data['col1'], $data['reflink'], $data['iid']], + [$data['col2'], $data['user_ip']], + $data['col3'], + $data['reflink'], + ]; + } + + return $rows; + } + ); + $table->set_additional_parameters( + [ + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, + 'action' => Security::remove_XSS($action), + ] + ); + $table->set_header( + 0, + get_lang('Type'), + true, + ['style' => 'width:30px;'] + ); + $table->set_header(1, get_lang('Title')); + $table->set_header( + 2, + get_lang('Author').' '.get_lang('LastVersion').'' + ); + $table->set_header( + 3, + get_lang('Date').' '.get_lang('LastVersion').'' + ); + if (api_is_allowed_to_session_edit(false, true)) { + $table->set_header( + 4, + get_lang('Actions'), + false, + ['style' => 'width: 145px;'] + ); + } + $table->set_column_filter( + 0, + function ($value, string $urlParams, array $row) { + $return = ''; //get type assignment icon - if ($obj->assignment == 1) { - $ShowAssignment = Display::return_icon( + if (1 == $value) { + $return .= Display::return_icon( 'wiki_assignment.png', get_lang('AssignmentDesc'), '', ICON_SIZE_SMALL ); - } elseif ($obj->assignment == 2) { - $ShowAssignment = Display::return_icon( + } elseif (2 == $value) { + $return .= Display::return_icon( 'wiki_work.png', get_lang('AssignmentWork'), '', ICON_SIZE_SMALL ); - } elseif ($obj->assignment == 0) { - $ShowAssignment = Display::return_icon( + } elseif (0 == $value) { + $return .= Display::return_icon( 'px_transparent.gif' ); } //get icon task - if (!empty($obj->task)) { - $icon_task = Display::return_icon( + if (!empty($row['task'])) { + $return .= Display::return_icon( 'wiki_task.png', get_lang('StandardTask'), '', ICON_SIZE_SMALL ); } else { - $icon_task = Display::return_icon('px_transparent.gif'); + $return .= Display::return_icon('px_transparent.gif'); } - $row = []; - $row[] = $ShowAssignment.$icon_task; - $row[] = ' - '.api_htmlentities($obj->title).''; + return $return; + } + ); + $table->set_column_filter( + 1, + function ($value) { + list($title, $refLink, $iid) = $value; + + return Display::url( + api_htmlentities($title), + $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($refLink)]) + ) + .$this->returnCategoriesBlock($iid, '
', '
'); + } + ); + $table->set_column_filter( + 2, + function ($value) { + list($userId, $userIp) = $value; + //get author + $userinfo = api_get_user_info($userId); + if ($userinfo !== false) { - $row[] = UserManager::getUserProfileLink($userinfo); - } else { - $row[] = get_lang('Anonymous').' ('.api_htmlentities( - $obj->user_ip - ).')'; - } - $row[] = api_get_local_time( - $obj->dtime - ); - $showdelete = ''; - if (api_is_allowed_to_edit( - false, - true - ) || api_is_platform_admin()) { - $showdelete = ' '. - Display::return_icon( - 'delete.png', - get_lang('Delete'), - '', - ICON_SIZE_SMALL - ); + return UserManager::getUserProfileLink($userinfo); } + + return get_lang('Anonymous').' ('.api_htmlentities($userIp).')'; + } + ); + $table->set_column_filter( + 3, + function ($value) { + return api_get_local_time($value); + } + ); + $table->set_column_filter( + 4, + function ($value) { + $actions = ''; + if (api_is_allowed_to_session_edit(false, true)) { - $row[] = ''. - Display::return_icon( - 'edit.png', - get_lang('EditPage'), - '', - ICON_SIZE_SMALL - ).' '. - Display::return_icon( - 'discuss.png', - get_lang('Discuss'), - '', - ICON_SIZE_SMALL - ).' '. - Display::return_icon( - 'history.png', - get_lang('History'), - '', - ICON_SIZE_SMALL - ).' - '. - Display::return_icon( - 'what_link_here.png', - get_lang('LinksPages'), - '', - ICON_SIZE_SMALL - ).''.$showdelete; + $actions = Display::url( + Display::return_icon('edit.png', get_lang('EditPage')), + $this->url.'&'.http_build_query(['action' => 'edit', 'title' => api_htmlentities($value)]) + ) + .Display::url( + Display::return_icon('discuss.png', get_lang('Discuss')), + $this->url.'&'.http_build_query(['action' => 'discuss', 'title' => api_htmlentities($value)]) + ) + .Display::url( + Display::return_icon('history.png', get_lang('History')), + $this->url.'&'.http_build_query(['action' => 'history', 'title' => api_htmlentities($value)]) + ) + .Display::url( + Display::return_icon('what_link_here.png', get_lang('LinksPages')), + $this->url.'&'.http_build_query(['action' => 'links', 'title' => api_htmlentities($value)]) + ) + ; } - $rows[] = $row; - } - $table = new SortableTableFromArrayConfig( - $rows, - 1, - 10, - 'AllPages_table', - '', - '', - 'ASC' - ); - $table->set_additional_parameters( - [ - 'cidReq' => Security::remove_XSS($_GET['cidReq']), - 'action' => Security::remove_XSS($action), - 'group_id' => Security::remove_XSS($_GET['group_id']), - ] - ); - $table->set_header( - 0, - get_lang('Type'), - true, - ['style' => 'width:30px;'] - ); - $table->set_header(1, get_lang('Title'), true); - $table->set_header( - 2, - get_lang('Author').' ('.get_lang('LastVersion').')', - true - ); - $table->set_header( - 3, - get_lang('Date').' ('.get_lang('LastVersion').')', - true - ); - if (api_is_allowed_to_session_edit(false, true)) { - $table->set_header( - 4, - get_lang('Actions'), - true, - ['style' => 'width:130px;'] - ); + if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) { + $actions .= Display::url( + Display::return_icon('delete.png', get_lang('Delete')), + $this->url.'&'.http_build_query(['action' => 'delete', 'title' => api_htmlentities($value)]) + ) + ; + } + + return $actions; } - $table->display(); - } + ); + $table->display(); } /** @@ -4794,10 +4736,10 @@ class Wiki ); $table->set_additional_parameters( [ - 'cidReq' => api_get_course_id(), + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, 'action' => Security::remove_XSS($action), - 'session_id' => api_get_session_id(), - 'group_id' => api_get_group_id(), ] ); $table->set_header( @@ -4880,17 +4822,14 @@ class Wiki $page = 'index'; } - echo '
'; - echo get_lang( - 'LinksPagesFrom' - ).': '.$ShowAssignment.' '. - api_htmlentities($row['title']).''; - echo '
'; + echo '
' + .get_lang('LinksPagesFrom').": $ShowAssignment " + .Display::url( + api_htmlentities($row['title']), + $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($page)]) + ) + .'
' + ; //fix index to title Main page into linksto @@ -4956,13 +4895,10 @@ class Wiki $row = []; $row[] = $ShowAssignment; - $row[] = ''. - api_htmlentities($obj->title).''; + $row[] = Display::url( + api_htmlentities($obj->title), + $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($obj->reflink)]) + ); if ($userinfo !== false) { $row[] = UserManager::getUserProfileLink($userinfo); } else { @@ -4983,9 +4919,10 @@ class Wiki ); $table->set_additional_parameters( [ - 'cidReq' => Security::remove_XSS($_GET['cidReq']), + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, 'action' => Security::remove_XSS($action), - 'group_id' => intval($_GET['group_id']), ] ); $table->set_header( @@ -5010,25 +4947,25 @@ class Wiki echo '
'.get_lang('SearchPages').'
'; if (isset($_GET['mode_table'])) { if (!isset($_GET['SearchPages_table_page_nr'])) { - $_GET['search_term'] = isset($_POST['search_term']) ? $_POST['search_term'] : ''; - $_GET['search_content'] = isset($_POST['search_content']) ? $_POST['search_content'] : ''; - $_GET['all_vers'] = isset($_POST['all_vers']) ? $_POST['all_vers'] : ''; + $_GET['search_term'] = $_POST['search_term'] ?? ''; + $_GET['search_content'] = $_POST['search_content'] ?? ''; + $_GET['all_vers'] = $_POST['all_vers'] ?? ''; + $_GET['categories'] = $_POST['categories'] ?? []; + $_GET['match_all_categories'] = isset($_POST['match_all_categories']); } - self::display_wiki_search_results( + $this->display_wiki_search_results( $_GET['search_term'], - $_GET['search_content'], - $_GET['all_vers'] + (int) $_GET['search_content'], + (int) $_GET['all_vers'], + $_GET['categories'], + $_GET['match_all_categories'] ); } else { // initiate the object $form = new FormValidator( 'wiki_search', 'post', - api_get_self().'?cidReq='.api_get_course_id( - ).'&action='.api_htmlentities( - $action - ).'&session_id='.api_get_session_id( - ).'&group_id='.api_get_group_id().'&mode_table=yes1' + $this->url.'&'.http_build_query(['action' => api_htmlentities($action), 'mode_table' => 'yes1']) ); // Setting the form elements @@ -5039,18 +4976,30 @@ class Wiki true, ['autofocus' => 'autofocus'] ); - $form->addElement( - 'checkbox', - 'search_content', - null, - get_lang('AlsoSearchContent') - ); - $form->addElement( - 'checkbox', - 'all_vers', - null, - get_lang('IncludeAllVersions') - ); + $form->addCheckBox('search_content', '', get_lang('AlsoSearchContent')); + $form->addCheckbox('all_vers', '', get_lang('IncludeAllVersions')); + + if (true === api_get_configuration_value('wiki_categories_enabled')) { + $categories = Database::getManager() + ->getRepository(CWikiCategory::class) + ->findByCourse(api_get_course_entity(), api_get_session_entity()) + ; + + $form->addSelectFromCollection( + 'categories', + get_lang('Categories'), + $categories, + ['multiple' => 'multiple'], + false, + 'getNodeName' + ); + $form->addCheckBox( + 'match_all_categories', + '', + get_lang('OnlyThoseThatCorrespondToAllTheSelectedCategories') + ); + } + $form->addButtonSearch(get_lang('Search'), 'SubmitWikiSearch'); // setting the rules @@ -5064,10 +5013,12 @@ class Wiki if ($form->validate()) { $form->display(); $values = $form->exportValues(); - self::display_wiki_search_results( + $this->display_wiki_search_results( $values['search_term'], - $values['search_content'], - $values['all_vers'] + (int) $values['search_content'], + (int) $values['all_vers'], + $values['categories'] ?? [], + isset($values['match_all_categories']) ); } else { $form->display(); @@ -5086,14 +5037,15 @@ class Wiki $course_id = $this->course_id; $condition_session = $this->condition_session; $groupfilter = $this->groupfilter; - $userId = intval($userId); + $userId = (int) $userId; $userinfo = api_get_user_info($userId); if ($userinfo !== false) { - echo '
'. - get_lang('UserContributions').': '.UserManager::getUserProfileLink($userinfo). - ''. - '
'; + echo '
' + .Display::url( + get_lang('UserContributions').': '.$userinfo['complete_name_with_username'], + $this->url.'&'.http_build_query(['action' => 'usercontrib', 'user_id' => $userId]) + ) + ; } if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) { @@ -5143,12 +5095,15 @@ class Wiki $row = []; $row[] = api_get_local_time($obj->dtime); $row[] = $ShowAssignment; - $row[] = ''. - api_htmlentities($obj->title).''; + $row[] = Display::url( + api_htmlentities($obj->title), + $this->url.'&' + .http_build_query([ + 'action' => 'showpage', + 'title' => api_htmlentities($obj->reflink), + 'view' => (int) $obj->id, + ]) + ); $row[] = Security::remove_XSS($obj->version); $row[] = Security::remove_XSS($obj->comment); $row[] = Security::remove_XSS($obj->progress).' %'; @@ -5167,11 +5122,11 @@ class Wiki ); $table->set_additional_parameters( [ - 'cidReq' => Security::remove_XSS($_GET['cidReq']), + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, 'action' => Security::remove_XSS($action), 'user_id' => intval($userId), - 'session_id' => intval($_GET['session_id']), - 'group_id' => intval($_GET['group_id']), ] ); $table->set_header( @@ -5275,13 +5230,10 @@ class Wiki $row = []; $row[] = $ShowAssignment; - $row[] = ''. - api_htmlentities($obj->title).''; + $row[] = Display::url( + api_htmlentities($obj->title), + $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($obj->reflink)]) + ); $row[] = $obj->MAX; $rows[] = $row; } @@ -5297,10 +5249,10 @@ class Wiki ); $table->set_additional_parameters( [ - 'cidReq' => Security::remove_XSS($_GET['cidReq']), + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, 'action' => Security::remove_XSS($action), - 'session_id' => intval($_GET['session_id']), - 'group_id' => intval($_GET['group_id']), ] ); $table->set_header( @@ -5459,10 +5411,11 @@ class Wiki $current_row['version'], $last_row['version'], $current_row['linksto'] - ).': '. - api_htmlentities($last_row['title']).'', + ).': ' + .Display::url( + api_htmlentities($last_row['title']), + $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($last_row['reflink'])]) + ), 'confirmation', false ) @@ -5493,8 +5446,6 @@ class Wiki * Check last version. * * @param int $view - * - * @return bool */ public function checkLastVersion($view) { @@ -5520,31 +5471,35 @@ class Wiki $last_row = Database::fetch_array($result); if ($view < $last_row['id']) { - $message = '
'.get_lang('NoAreSeeingTheLastVersion').'
- '.get_lang("Version").' ( - - '.$current_row['version'].' - / - - '.$last_row['version'].' - )
'.get_lang("ConvertToLastVersion").': - '. - get_lang("Restore").'
'; - Display::addFlash( - Display::return_message($message, 'warning', false) - ); + $message = '
'.get_lang('NoAreSeeingTheLastVersion').'
' + .get_lang("Version").' (' + .Display::url( + $current_row['version'], + $this->url.'&'.http_build_query([ + 'action' => 'showpage', + 'title' => api_htmlentities($current_row['reflink']), + 'view' => (int) $_GET['view'], + ]), + ['title' => get_lang('CurrentVersion')] + ) + .' / ' + .Display::url( + $last_row['version'], + $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($last_row['reflink'])]), + ['title' => get_lang('LastVersion')] + ) + .')
'.get_lang('ConvertToLastVersion').': ' + .Display::url( + get_lang("Restore"), + $this->url.'&'.http_build_query([ + 'action' => 'restorepage', + 'title' => api_htmlentities($last_row['reflink']), + 'view' => (int) $_GET['view'], + ]) + ) + .'
' + ; + echo Display::return_message($message, 'warning', false); } } @@ -5618,13 +5573,10 @@ class Wiki $rows = []; foreach ($linked as $linked_show) { $row = []; - $row[] = ''. - str_replace('_', ' ', $linked_show).''; + $row[] = Display::url( + str_replace('_', ' ', $linked_show), + $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => str_replace('_', ' ', $linked_show)]) + ); $rows[] = $row; } @@ -5639,10 +5591,10 @@ class Wiki ); $table->set_additional_parameters( [ - 'cidReq' => Security::remove_XSS($_GET['cidReq']), + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, 'action' => Security::remove_XSS($this->action), - 'session_id' => intval($_GET['session_id']), - 'group_id' => intval($_GET['group_id']), ] ); $table->set_header(0, get_lang('Title'), true); @@ -5756,13 +5708,10 @@ class Wiki //show table $row = []; $row[] = $ShowAssignment; - $row[] = ''. - api_htmlentities($orphaned_title).''; + $row[] = Display::url( + api_htmlentities($orphaned_title), + $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($orphaned_show)]) + ); $rows[] = $row; } @@ -5777,10 +5726,10 @@ class Wiki ); $table->set_additional_parameters( [ - 'cidReq' => Security::remove_XSS($_GET['cidReq']), + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, 'action' => Security::remove_XSS($this->action), - 'session_id' => intval($_GET['session_id']), - 'group_id' => intval($_GET['group_id']), ] ); $table->set_header( @@ -5852,21 +5801,11 @@ class Wiki foreach ($wanted as $wanted_show) { $row = []; $wanted_show = Security::remove_XSS($wanted_show); - $row[] = ''.str_replace( - '_', - ' ', - $wanted_show - ).''; //meter un remove xss en lugar de htmlentities + $row[] = Display::url( + str_replace('_', ' ', $wanted_show), + $this->url.'&'.http_build_query(['action' => 'addnew', 'title' => str_replace('_', ' ', $wanted_show)]), + ['class' => 'new_wiki_link'] + ); $rows[] = $row; } @@ -5881,10 +5820,10 @@ class Wiki ); $table->set_additional_parameters( [ - 'cidReq' => Security::remove_XSS($_GET['cidReq']), + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, 'action' => Security::remove_XSS($this->action), - 'session_id' => intval($_GET['session_id']), - 'group_id' => intval($_GET['group_id']), ] ); $table->set_header(0, get_lang('Title'), true); @@ -5948,13 +5887,10 @@ class Wiki $row = []; $row[] = $ShowAssignment; - $row[] = ''. - api_htmlentities($obj->title).''; + $row[] = Display::url( + api_htmlentities($obj->title), + $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($obj->reflink)]) + ); $row[] = $obj->tsum; $rows[] = $row; } @@ -5970,10 +5906,10 @@ class Wiki ); $table->set_additional_parameters( [ - 'cidReq' => Security::remove_XSS($_GET['cidReq']), + 'cidReq' => $this->courseCode, + 'gidReq' => $this->group_id, + 'id_session' => $this->session_id, 'action' => Security::remove_XSS($this->action), - 'session_id' => intval($_GET['session_id']), - 'group_id' => intval($_GET['group_id']), ] ); $table->set_header( @@ -5990,8 +5926,6 @@ class Wiki /** * Get actions bar. - * - * @return string */ public function showActionBar() { @@ -5999,35 +5933,26 @@ class Wiki $session_id = $this->session_id; $groupId = $this->group_id; $page = $this->page; - $actionsLeft = ''; - $actionsLeft .= ''. - Display::return_icon( - 'home.png', - get_lang('Home'), - '', - ICON_SIZE_MEDIUM - ).''; + $actionsLeft = Display::url( + Display::return_icon('home.png', get_lang('Home'), [], ICON_SIZE_MEDIUM), + $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => 'index']) + ); - if (api_is_allowed_to_session_edit( - false, - true - ) && api_is_allowed_to_edit()) { + if (api_is_allowed_to_session_edit(false, true) && api_is_allowed_to_edit()) { // menu add page - $actionsLeft .= '' - .Display::return_icon( - 'new_document.png', - get_lang('AddNew'), - '', - ICON_SIZE_MEDIUM - ).''; + $actionsLeft .= '' + .Display::return_icon('new_document.png', get_lang('AddNew'), [], ICON_SIZE_MEDIUM).''; } - $lock_unlock_addnew = null; - $protect_addnewpage = null; + if ( + true === api_get_configuration_value('wiki_categories_enabled') + && (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) + ) { + $actionsLeft .= Display::url( + Display::return_icon('folder.png', get_lang('Categories'), [], ICON_SIZE_MEDIUM), + $this->url.'&action=category' + ); - if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) { // page action: enable or disable the adding of new pages if (self::check_addnewpagelock() == 0) { $protect_addnewpage = Display::return_icon( @@ -6045,46 +5970,19 @@ class Wiki } // menu find - $actionsLeft .= ''. - Display::return_icon( - 'search.png', - get_lang('SearchPages'), - '', - ICON_SIZE_MEDIUM - ).''; + $actionsLeft .= '' + .Display::return_icon('search.png', get_lang('SearchPages'), '', ICON_SIZE_MEDIUM).''; ///menu more - $actionsLeft .= ''. - Display::return_icon( - 'statistics.png', - get_lang('Statistics'), - '', - ICON_SIZE_MEDIUM - ).''; + $actionsLeft .= '' + .Display::return_icon('statistics.png', get_lang('Statistics'), [], ICON_SIZE_MEDIUM).''; // menu all pages - $actionsLeft .= ''. - Display::return_icon( - 'list_badges.png', - get_lang('AllPages'), - '', - ICON_SIZE_MEDIUM - ).''; + $actionsLeft .= '' + .Display::return_icon('list_badges.png', get_lang('AllPages'), [], ICON_SIZE_MEDIUM).''; // menu recent changes - $actionsLeft .= ''. - Display::return_icon( - 'history.png', - get_lang('RecentChanges'), - '', - ICON_SIZE_MEDIUM - ).''; + $actionsLeft .= '' + .Display::return_icon('history.png', get_lang('RecentChanges'), [], ICON_SIZE_MEDIUM).''; echo Display::toolbarAction('toolbar-wiki', [$actionsLeft]); } @@ -6186,101 +6084,83 @@ class Wiki } $sql = 'SELECT * - FROM '.$tbl_wiki.' w INNER JOIN '.$tbl_wiki_conf.' c - ON (w.c_id = c.c_id AND w.page_id = c.page_id) - WHERE - w.c_id = '.$course_id.' AND - w.reflink= "'.Database::escape_string($page).'" AND - w.'.$groupfilter.$condition_session.' - ORDER BY id DESC'; + FROM '.$tbl_wiki.' w INNER JOIN '.$tbl_wiki_conf.' c + ON (w.c_id = c.c_id AND w.page_id = c.page_id) + WHERE + w.c_id = '.$course_id.' AND + w.reflink= "'.Database::escape_string($page).'" AND + w.'.$groupfilter.$condition_session.' + ORDER BY id DESC'; $result = Database::query($sql); $row = Database::fetch_array($result); - // we do not need a while loop since we are always displaying the last version - if ($row['content'] == '' && $row['title'] == '' && $page == '') { - Display::addFlash( - Display::return_message( - get_lang('MustSelectPage'), - 'error', - false - ) - ); - - return; - } elseif ($row['content'] == '' && $row['title'] == '' && $page == 'index') { - // Table structure for better export to pdf - $default_table_for_content_Start = '
'; - $default_table_for_content_End = '
'; - $content = $default_table_for_content_Start.sprintf( - get_lang('DefaultContent'), - api_get_path(WEB_IMG_PATH) - ).$default_table_for_content_End; - $title = get_lang('DefaultTitle'); - $page_id = 0; + $PassEdit = false; + // Check if is a wiki group + if (!empty($groupId)) { + $groupInfo = GroupManager::get_group_properties($groupId); + //Only teacher, platform admin and group members can edit a wiki group + if (api_is_allowed_to_edit(false, true) || + api_is_platform_admin() || + GroupManager::is_user_in_group($userId, $groupInfo) + ) { + $PassEdit = true; + } else { + Display::addFlash( + Display::return_message( + get_lang('OnlyEditPagesGroupMembers') + ) + ); + } } else { - $content = api_html_entity_decode($row['content']); - $title = api_html_entity_decode($row['title']); - $page_id = $row['page_id']; + $PassEdit = true; } - // Only teachers and platform admin can edit the index page. - // Only teachers and platform admin can edit an assignment teacher. - // And users in groups + $content = '
' + .sprintf(get_lang('DefaultContent'), api_get_path(WEB_IMG_PATH)) + .'
'; + $title = get_lang('DefaultTitle'); + $page_id = 0; - if (($row['reflink'] == 'index' || $row['reflink'] == '' || $row['assignment'] == 1) && - (!api_is_allowed_to_edit( - false, - true - ) && $groupId == 0) && !api_is_allowed_in_course() - ) { - Display::addFlash( - Display::return_message( - get_lang('OnlyEditPagesCourseManager'), - 'error' - ) - ); - } else { - $PassEdit = false; - // Check if is a wiki group - if (!empty($groupId)) { - $groupInfo = GroupManager::get_group_properties($groupId); - //Only teacher, platform admin and group members can edit a wiki group - if (api_is_allowed_to_edit(false, true) || - api_is_platform_admin() || - GroupManager::is_user_in_group($userId, $groupInfo) - ) { - $PassEdit = true; - } else { - Display::addFlash( - Display::return_message( - get_lang('OnlyEditPagesGroupMembers') - ) - ); - } - } else { - $PassEdit = true; + $icon_assignment = ''; + + // we do not need awhile loop since we are always displaying the last version + if ($row) { + if ($row['content'] == '' && $row['title'] == '' && $page == '') { + Display::addFlash( + Display::return_message(get_lang('MustSelectPage'), 'error', false) + ); + + return; } - $icon_assignment = null; - // check if is a assignment + $content = api_html_entity_decode($row['content']); + $title = api_html_entity_decode($row['title']); + $page_id = $row['page_id']; + + // Only teachers and platform admin can edit the index page. + // Only teachers and platform admin can edit an assignment teacher. + // And users in groups + + if (($row['reflink'] == 'index' || $row['reflink'] == '' || $row['assignment'] == 1) + && (!api_is_allowed_to_edit(false, true) && $groupId == 0) + && !api_is_allowed_in_course() + ) { + Display::addFlash( + Display::return_message(get_lang('OnlyEditPagesCourseManager'), 'error') + ); + + return; + } + + // check if is an assignment if ($row['assignment'] == 1) { Display::addFlash( Display::return_message(get_lang('EditAssignmentWarning')) ); - $icon_assignment = Display::return_icon( - 'wiki_assignment.png', - get_lang('AssignmentDescExtra'), - '', - ICON_SIZE_SMALL - ); + $icon_assignment = Display::return_icon('wiki_assignment.png', get_lang('AssignmentDescExtra')); } elseif ($row['assignment'] == 2) { - $icon_assignment = Display::return_icon( - 'wiki_work.png', - get_lang('AssignmentWorkExtra'), - '', - ICON_SIZE_SMALL - ); + $icon_assignment = Display::return_icon('wiki_work.png', get_lang('AssignmentWorkExtra')); if (($userId == $row['user_id']) == false) { if (api_is_allowed_to_edit( false, @@ -6289,10 +6169,7 @@ class Wiki $PassEdit = true; } else { Display::addFlash( - Display::return_message( - get_lang('LockByTeacher'), - 'warning' - ) + Display::return_message(get_lang('LockByTeacher'), 'warning') ); $PassEdit = false; } @@ -6302,282 +6179,217 @@ class Wiki } if ($PassEdit) { - //show editor if edit is allowed <<<<< if ($row['editlock'] == 1 && (api_is_allowed_to_edit(false, true) == false || api_is_platform_admin() == false) ) { Display::addFlash( - Display::return_message( - get_lang('PageLockedExtra') - ) + Display::return_message(get_lang('PageLockedExtra')) ); - } else { - // Check tasks - if (!empty($row['startdate_assig']) && time() < - api_strtotime($row['startdate_assig']) - ) { - $message = get_lang( - 'TheTaskDoesNotBeginUntil' - ).': '.api_get_local_time($row['startdate_assig']); + } + } + } - Display::addFlash( - Display::return_message( - $message, - 'warning' - ) - ); + if ($PassEdit) { + //show editor if edit is allowed <<<<< + if ((!empty($row['id']) && $row['editlock'] != 1) + || api_is_allowed_to_edit(false, true) != false + && api_is_platform_admin() != false + ) { + // Check tasks + if (!empty($row['startdate_assig']) && time() < + api_strtotime($row['startdate_assig']) + ) { + $message = get_lang('TheTaskDoesNotBeginUntil').': '.api_get_local_time($row['startdate_assig']); - if (!api_is_allowed_to_edit(false, true)) { - $this->redirectHome(); - } + Display::addFlash( + Display::return_message($message, 'warning') + ); + + if (!api_is_allowed_to_edit(false, true)) { + $this->redirectHome(); } + } - if (!empty($row['enddate_assig']) && - time() > strtotime($row['enddate_assig']) && - $row['delayedsubmit'] == 0 - ) { - $message = get_lang( - 'TheDeadlineHasBeenCompleted' - ).': '.api_get_local_time($row['enddate_assig']); - Display::addFlash( - Display::return_message( - $message, - 'warning' - ) - ); - if (!api_is_allowed_to_edit(false, true)) { - $this->redirectHome(); - } + if (!empty($row['enddate_assig']) && + time() > strtotime($row['enddate_assig']) && + $row['delayedsubmit'] == 0 + ) { + $message = get_lang('TheDeadlineHasBeenCompleted').': '.api_get_local_time($row['enddate_assig']); + Display::addFlash( + Display::return_message($message, 'warning') + ); + if (!api_is_allowed_to_edit(false, true)) { + $this->redirectHome(); } + } - if (!empty($row['max_version']) && $row['version'] >= $row['max_version']) { - $message = get_lang('HasReachedMaxiNumVersions'); - Display::addFlash( - Display::return_message( - $message, - 'warning' - ) - ); - if (!api_is_allowed_to_edit(false, true)) { - $this->redirectHome(); - } + if (!empty($row['max_version']) && $row['version'] >= $row['max_version']) { + $message = get_lang('HasReachedMaxiNumVersions'); + Display::addFlash( + Display::return_message($message, 'warning') + ); + if (!api_is_allowed_to_edit(false, true)) { + $this->redirectHome(); } + } - if (!empty($row['max_text']) && $row['max_text'] <= self::word_count( - $row['content'] - )) { - $message = get_lang('HasReachedMaxNumWords'); - Display::addFlash( - Display::return_message( - $message, - 'warning' - ) - ); - if (!api_is_allowed_to_edit(false, true)) { - $this->redirectHome(); - } + if (!empty($row['max_text']) && $row['max_text'] <= self::word_count( + $row['content'] + )) { + $message = get_lang('HasReachedMaxNumWords'); + Display::addFlash( + Display::return_message($message, 'warning') + ); + if (!api_is_allowed_to_edit(false, true)) { + $this->redirectHome(); } + } - if (!empty($row['task'])) { - //previous change 0 by text - if (!empty($row['startdate_assig'])) { - $message_task_startdate = get_lang('No'); - } else { - $message_task_startdate = api_get_local_time( - $row['startdate_assig'] - ); - } + if (!empty($row['task'])) { + //previous change 0 by text + $message_task_startdate = empty($row['startdate_assig']) + ? api_get_local_time($row['startdate_assig']) + : get_lang('No'); - if (!empty($row['enddate_assig'])) { - $message_task_enddate = get_lang('No'); - } else { - $message_task_enddate = api_get_local_time( - $row['enddate_assig'] - ); - } + $message_task_enddate = empty($row['enddate_assig']) + ? api_get_local_time($row['enddate_assig']) + : get_lang('No'); - if ($row['delayedsubmit'] == 0) { - $message_task_delayedsubmit = get_lang('No'); - } else { - $message_task_delayedsubmit = get_lang('Yes'); - } + $message_task_delayedsubmit = $row['delayedsubmit'] == 0 ? get_lang('No') : get_lang('Yes'); - if ($row['max_version'] == 0) { - $message_task_max_version = get_lang('No'); - } else { - $message_task_max_version = $row['max_version']; - } + $message_task_max_version = $row['max_version'] == 0 ? get_lang('No') : $row['max_version']; - if ($row['max_text'] == 0) { - $message_task_max_text = get_lang('No'); - } else { - $message_task_max_text = $row['max_text']; - } + $message_task_max_text = $row['max_text'] == 0 ? get_lang('No') : $row['max_text']; - // Comp message - $message_task = ''.get_lang( - 'DescriptionOfTheTask' - ).'

'.$row['task'].'


'; - $message_task .= '

'.get_lang( - 'StartDate' - ).': '.$message_task_startdate.'

'; - $message_task .= '

'.get_lang( - 'EndDate' - ).': '.$message_task_enddate; - $message_task .= ' ('.get_lang( - 'AllowLaterSends' - ).') '.$message_task_delayedsubmit.'

'; - $message_task .= '

'.get_lang( - 'OtherSettings' - ).': '.get_lang( - 'NMaxVersion' - ).': '.$message_task_max_version; - $message_task .= ' '.get_lang( - 'NMaxWords' - ).': '.$message_task_max_text; - // Display message - Display::addFlash( - Display::return_message( - $message_task - ) - ); - } + // Comp message + $message_task = ''.get_lang('DescriptionOfTheTask').'

'.$row['task'].'


' + .'

'.get_lang('StartDate').': '.$message_task_startdate.'

' + .'

'.get_lang('EndDate').': '.$message_task_enddate + .' ('.get_lang('AllowLaterSends').') '.$message_task_delayedsubmit.'

' + .'

'.get_lang('OtherSettings').': '.get_lang('NMaxVersion').': '.$message_task_max_version + .' '.get_lang('NMaxWords').': '.$message_task_max_text.'

'; + // Display message + Display::addFlash( + Display::return_message($message_task) + ); + } + if (!empty($row['id'])) { $feedback_message = ''; if ($row['progress'] == $row['fprogress1'] && !empty($row['fprogress1'])) { - $feedback_message = ''.get_lang( - 'Feedback' - ).'

'.api_htmlentities( - $row['feedback1'] - ).'

'; + $feedback_message = ''.get_lang('Feedback').'' + .'

'.api_htmlentities($row['feedback1']).'

'; } elseif ($row['progress'] == $row['fprogress2'] && !empty($row['fprogress2'])) { - $feedback_message = ''.get_lang( - 'Feedback' - ).'

'.api_htmlentities( - $row['feedback2'] - ).'

'; + $feedback_message = ''.get_lang('Feedback').'' + .'

'.api_htmlentities($row['feedback2']).'

'; } elseif ($row['progress'] == $row['fprogress3'] && !empty($row['fprogress3'])) { - $feedback_message = ''.get_lang( - 'Feedback' - ).'

'.api_htmlentities( - $row['feedback3'] - ).'

'; + $feedback_message = ''.get_lang('Feedback').'' + .'

'.api_htmlentities($row['feedback3']).'

'; } if (!empty($feedback_message)) { Display::addFlash( - Display::return_message( - $feedback_message - ) + Display::return_message($feedback_message) ); } + } + + // Previous checking for concurrent editions + if (!empty($row['id']) && $row['is_editing'] == 0) { + Display::addFlash( + Display::return_message(get_lang('WarningMaxEditingTime')) + ); + $time_edit = api_get_utc_datetime(); + $sql = 'UPDATE '.$tbl_wiki.' SET + is_editing = "'.$userId.'", + time_edit = "'.$time_edit.'" + WHERE c_id = '.$course_id.' AND id="'.$row['id'].'"'; + Database::query($sql); + } elseif (!empty($row['id']) && $row['is_editing'] != $userId) { + $timestamp_edit = strtotime($row['time_edit']); + $time_editing = time() - $timestamp_edit; + $max_edit_time = 1200; // 20 minutes + $rest_time = $max_edit_time - $time_editing; + + $userinfo = api_get_user_info($row['is_editing']); + if ($userinfo !== false) { + $is_being_edited = get_lang('ThisPageisBeginEditedBy').PHP_EOL + .UserManager::getUserProfileLink($userinfo).PHP_EOL + .get_lang('ThisPageisBeginEditedTryLater').PHP_EOL + .date("i", $rest_time).PHP_EOL + .get_lang('MinMinutes'); - // Previous checking for concurrent editions - if ($row['is_editing'] == 0) { Display::addFlash( - Display::return_message( - get_lang('WarningMaxEditingTime') - ) + Display::return_message($is_being_edited, 'normal', false) ); - $time_edit = api_get_utc_datetime(); - $sql = 'UPDATE '.$tbl_wiki.' SET - is_editing = "'.$userId.'", - time_edit = "'.$time_edit.'" - WHERE c_id = '.$course_id.' AND id="'.$row['id'].'"'; - Database::query($sql); - } elseif ($row['is_editing'] != $userId) { - $timestamp_edit = strtotime($row['time_edit']); - $time_editing = time() - $timestamp_edit; - $max_edit_time = 1200; // 20 minutes - $rest_time = $max_edit_time - $time_editing; + } - $userinfo = api_get_user_info($row['is_editing']); - if ($userinfo !== false) { - $is_being_edited = get_lang( - 'ThisPageisBeginEditedBy' - ).' '.UserManager::getUserProfileLink( - $userinfo - ).' - '.get_lang( - 'ThisPageisBeginEditedTryLater' - ).' '.date("i", $rest_time).' '.get_lang( - 'MinMinutes' - ).''; - } + $this->redirectHome(); + } + + // Form. + $url = api_get_self().'?action=edit&title='.urlencode($page).'&session_id='.api_get_session_id() + .'&group_id='.api_get_group_id().'&'.api_get_cidreq(); + $form = new FormValidator('wiki', 'post', $url); + $form->addElement( + 'header', + $icon_assignment.str_repeat(' ', 3).api_htmlentities($title) + ); + self::setForm($form, !empty($row['id']) ? $row : []); + $form->addElement('hidden', 'title'); + $form->addButtonSave(get_lang('Save'), 'SaveWikiChange'); + $row['title'] = $title; + $row['page_id'] = $page_id; + $row['reflink'] = $page; + $row['content'] = $content; + + if (!empty($row['id']) && true === api_get_configuration_value('wiki_categories_enabled')) { + $wiki = Database::getManager()->find(CWiki::class, $row['id']); + + foreach ($wiki->getCategories() as $category) { + $row['category'][] = $category->getId(); + } + } + $form->setDefaults($row); + $form->display(); + + // Saving a change + if ($form->validate()) { + $versionFromSession = Session::read('_version'); + if (empty($_POST['title'])) { Display::addFlash( Display::return_message( - $is_being_edited, - 'normal', - false + get_lang("NoWikiPageTitle"), + 'error' + ) + ); + } elseif (!self::double_post($_POST['wpost_id'])) { + //double post + } elseif ($_POST['version'] != '' && $versionFromSession != 0 && $_POST['version'] != $versionFromSession) { + //prevent concurrent users and double version + Display::addFlash( + Display::return_message( + get_lang("EditedByAnotherUser"), + 'error' + ) + ); + } else { + $returnMessage = self::save_wiki( + $form->exportValues() + ); + Display::addFlash( + Display::return_message( + $returnMessage, + 'confirmation' ) ); - - $this->redirectHome(); - } - - // Form. - $url = api_get_self().'?action=edit&title='.urlencode( - $page - ).'&session_id='.api_get_session_id( - ).'&group_id='.api_get_group_id().'&'.api_get_cidreq(); - $form = new FormValidator('wiki', 'post', $url); - $form->addElement( - 'header', - $icon_assignment.str_repeat( - ' ', - 3 - ).api_htmlentities($title) - ); - self::setForm($form, $row); - $form->addElement('hidden', 'title'); - $form->addButtonSave(get_lang('Save'), 'SaveWikiChange'); - $row['title'] = $title; - $row['page_id'] = $page_id; - $row['reflink'] = $page; - $row['content'] = $content; - - $form->setDefaults($row); - $form->display(); - - // Saving a change - if ($form->validate()) { - $versionFromSession = Session::read('_version'); - if (empty($_POST['title'])) { - Display::addFlash( - Display::return_message( - get_lang("NoWikiPageTitle"), - 'error' - ) - ); - } elseif (!self::double_post($_POST['wpost_id'])) { - //double post - } elseif ($_POST['version'] != '' && $versionFromSession != 0 && $_POST['version'] != $versionFromSession) { - //prevent concurrent users and double version - Display::addFlash( - Display::return_message( - get_lang("EditedByAnotherUser"), - 'error' - ) - ); - } else { - $returnMessage = self::save_wiki( - $form->exportValues() - ); - Display::addFlash( - Display::return_message( - $returnMessage, - 'confirmation' - ) - ); - } - $wikiData = self::getWikiData(); - $redirectUrl = $this->url.'&action=showpage&title='.$wikiData['reflink'].'&'.api_get_cidreq( - ); - header('Location: '.$redirectUrl); - exit; } + $wikiData = self::getWikiData(); + $redirectUrl = $this->url.'&action=showpage&title='.$wikiData['reflink'].'&'.api_get_cidreq(); + header('Location: '.$redirectUrl); + exit; } } } @@ -6901,42 +6713,28 @@ class Wiki echo ' '; echo ' '; echo ' '; echo ' '; echo ' '; echo ''; echo ''; echo ''; echo ' '; @@ -6946,10 +6744,8 @@ class Wiki /** * Kind of controller. - * - * @param string $action */ - public function handleAction($action) + public function handleAction(string $action) { $page = $this->page; switch ($action) { @@ -7068,10 +6864,7 @@ class Wiki self::getLinks($page); break; case 'addnew': - if (api_get_session_id() != 0 && api_is_allowed_to_session_edit( - false, - true - ) == false) { + if (api_get_session_id() != 0 && api_is_allowed_to_session_edit(false, true) == false) { api_not_allowed(); } $groupInfo = GroupManager::get_group_properties( @@ -7090,32 +6883,21 @@ class Wiki api_is_allowed_in_course() ) { Display::addFlash( - Display::return_message( - get_lang('GoAndEditMainPage'), - 'normal', - false - ) + Display::return_message(get_lang('GoAndEditMainPage'), 'normal', false) ); } else { Display::addFlash( - Display::return_message( - get_lang('WikiStandBy'), - 'normal', - false - ) + Display::return_message(get_lang('WikiStandBy'), 'normal', false) ); } - } elseif (self::check_addnewpagelock( - ) == 0 && (api_is_allowed_to_edit( - false, - true - ) == false || api_is_platform_admin() == false)) { + } elseif (self::check_addnewpagelock() == 0 + && ( + api_is_allowed_to_edit(false, true) == false + || api_is_platform_admin() == false + ) + ) { Display::addFlash( - Display::return_message( - get_lang('AddPagesLocked'), - 'error', - false - ) + Display::return_message(get_lang('AddPagesLocked'), 'error', false) ); } else { $groupInfo = GroupManager::get_group_properties( @@ -7132,18 +6914,12 @@ class Wiki self::display_new_wiki_form(); } else { Display::addFlash( - Display::return_message( - get_lang('OnlyAddPagesGroupMembers'), - 'normal', - false - ) + Display::return_message(get_lang('OnlyAddPagesGroupMembers'), 'normal', false) ); } } break; case 'show': - self::display_wiki_entry($page); - break; case 'showpage': self::display_wiki_entry($page); break; @@ -7166,6 +6942,12 @@ class Wiki self::exportTo($_GET['id'], 'odt'); exit; break; + case 'category': + $this->addCategory(); + break; + case 'delete_category': + $this->deleteCategory(); + break; } } @@ -7197,4 +6979,234 @@ class Wiki return false; } + + private function returnCategoriesBlock(int $wikiId, string $tagStart = '
', string $tagEnd = '
'): string + { + if (true !== api_get_configuration_value('wiki_categories_enabled') || empty($wikiId)) { + return ''; + } + + $wiki = Database::getManager()->find(CWiki::class, $wikiId); + + return $tagStart.implode(', ', $wiki->getCategories()->getValues()).$tagEnd; + } + + private function gelAllPagesQuery( + $onlyCount = false, + $from = 0, + $numberOfItems = 10, + $column = 0, + $direction = 'ASC' + ): ?Statement { + $tblWiki = $this->tbl_wiki; + + $fields = $onlyCount + ? 'COUNT(s1.iid) AS nbr' + : 's1.assignment col0, s1.title col1, s1.user_id col2, s1.dtime col3, s1.reflink, s1.user_ip, s1.iid'; + + $query = 'SELECT '.$fields.' FROM '.$tblWiki.' s1 WHERE s1.c_id = '.$this->course_id.' '; + + if (!api_is_allowed_to_edit(false, true) && !api_is_platform_admin()) { + // warning don't use group by reflink because does not return the last version + $query .= 'AND visibility = 1 '; + } + + $query .= 'AND id = ( + SELECT MAX(s2.id) FROM '.$tblWiki.' s2 + WHERE s2.c_id = '.$this->course_id.' + AND s1.reflink = s2.reflink + AND '.$this->groupfilter.' + AND session_id = '.$this->session_id.' + ) '; + + if (!$onlyCount) { + $query .= "ORDER BY col$column $direction LIMIT $from, $numberOfItems"; + } + + return Database::query($query); + } + + private function deleteCategory() + { + if (!api_is_allowed_to_edit(false, true) && !api_is_platform_admin()) { + api_not_allowed(true); + } + + if (true !== api_get_configuration_value('wiki_categories_enabled')) { + api_not_allowed(true); + } + + $em = Database::getManager(); + + $category = null; + + if (isset($_GET['id'])) { + $category = $em->find(CWikiCategory::class, $_GET['id']); + + if (!$category) { + api_not_allowed(true); + } + } + + $em->remove($category); + $em->flush(); + + Display::addFlash( + Display::return_message(get_lang('CategoryDeleted'), 'success') + ); + + header('Location: index.php?'.api_get_cidreq().'&action=category'); + exit; + } + + private function addCategory() + { + if (!api_is_allowed_to_edit(false, true) && !api_is_platform_admin()) { + api_not_allowed(true); + } + + if (true !== api_get_configuration_value('wiki_categories_enabled')) { + api_not_allowed(true); + } + + $categoryRepo = Database::getManager()->getRepository(CWikiCategory::class); + + $categoryToEdit = null; + + if (isset($_GET['id'])) { + $categoryToEdit = $categoryRepo->find($_GET['id']); + + if (!$categoryToEdit) { + api_not_allowed(true); + } + } + + $course = api_get_course_entity(); + $session = api_get_session_entity(); + + if ($categoryToEdit + && ($course !== $categoryToEdit->getCourse() || $session !== $categoryToEdit->getSession()) + ) { + api_not_allowed(true); + } + + $self = api_get_self(); + $cidReq = api_get_cidreq(); + $iconEdit = Display::return_icon('edit.png', get_lang('Edit')); + $iconDelete = Display::return_icon('delete.png', get_lang('Delete')); + + $categories = $categoryRepo->findByCourse($course, $session); + $categoryList = array_map( + function (CWikiCategory $category) use ($self, $cidReq, $iconEdit, $iconDelete) { + $actions = []; + $actions[] = Display::url( + $iconEdit, + "$self?$cidReq&".http_build_query(['action' => 'category', 'id' => $category->getId()]) + ); + $actions[] = Display::url( + $iconDelete, + "$self?$cidReq&".http_build_query(['action' => 'delete_category', 'id' => $category->getId()]) + ); + + return [ + $category->getNodeName(), + implode(PHP_EOL, $actions), + ]; + }, + $categories + ); + + $table = new SortableTableFromArray($categoryList); + $table->set_header(0, get_lang('Name'), false); + $table->set_header(1, get_lang('Actions'), false, ['class' => 'text-right'], ['class' => 'text-right']); + + $form = $this->createCategoryForm($categoryToEdit); + $form->display(); + echo '
'; + $table->display(); + } + + private function createCategoryForm(CWikiCategory $category = null): FormValidator + { + $em = Database::getManager(); + $categoryRepo = $em->getRepository(CWikiCategory::class); + + $course = api_get_course_entity($this->courseInfo['real_id']); + $session = api_get_session_entity($this->session_id); + + $categories = $categoryRepo->findByCourse($course, $session); + + $formAction = $this->url.'&'.http_build_query([ + 'action' => 'category', + 'id' => $category ? $category->getId() : null, + ]); + + $form = new FormValidator('category', 'post', $formAction); + $form->addHeader(get_lang('AddCategory')); + $form->addSelectFromCollection('parent', get_lang('Parent'), $categories, [], true, 'getNodeName'); + $form->addText('name', get_lang('Name')); + + if ($category) { + $form->addButtonUpdate(get_lang('Update')); + } else { + $form->addButtonSave(get_lang('Save')); + } + + if ($form->validate()) { + $values = $form->exportValues(); + $parent = $categoryRepo->find($values['parent']); + + if (!$category) { + $category = (new CWikiCategory()) + ->setCourse($course) + ->setSession($session) + ; + + $em->persist($category); + + Display::addFlash( + Display::return_message(get_lang('CategoryAdded'), 'success') + ); + } else { + Display::addFlash( + Display::return_message(get_lang('CategoryEdited'), 'success') + ); + } + + $category + ->setName($values['name']) + ->setParent($parent) + ; + + $em->flush(); + + header('Location: index.php?'.api_get_cidreq().'&action=category'); + exit; + } + + if ($category) { + $form->setDefaults([ + 'parent' => $category->getParent() ? $category->getParent()->getId() : 0, + 'name' => $category->getName(), + ]); + } + + return $form; + } + + private static function assignCategoriesToWiki(CWiki $wiki, array $categoriesIdList) + { + if (true !== api_get_configuration_value('wiki_categories_enabled')) { + return; + } + + $em = Database::getManager(); + + foreach ($categoriesIdList as $categoryId) { + $category = $em->find(CWikiCategory::class, $categoryId); + $wiki->addCategory($category); + } + + $em->flush(); + } } diff --git a/src/Chamilo/CourseBundle/Entity/CWiki.php b/src/Chamilo/CourseBundle/Entity/CWiki.php index 5dbd70ad3d..eb3fc3fef4 100644 --- a/src/Chamilo/CourseBundle/Entity/CWiki.php +++ b/src/Chamilo/CourseBundle/Entity/CWiki.php @@ -3,6 +3,8 @@ namespace Chamilo\CourseBundle\Entity; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; /** @@ -219,6 +221,23 @@ class CWiki * @ORM\Column(name="session_id", type="integer", nullable=true) */ protected $sessionId; + /** + * @var Collection + * + * Add @ to the next lines if api_get_configuration_value('wiki_categories_enabled') is true + * ORM\ManyToMany(targetEntity="Chamilo\CourseBundle\Entity\CWikiCategory", inversedBy="wikiPages") + * ORM\JoinTable( + * name="c_wiki_rel_category", + * joinColumns={@ORM\JoinColumn(name="wiki_id", referencedColumnName="iid", onDelete="CASCADE")}, + * inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id", onDelete="CASCADE")} + * ) + */ + private $categories; + + public function __construct() + { + $this->categories = new ArrayCollection(); + } /** * Set pageId. @@ -844,6 +863,11 @@ class CWiki return $this->id; } + public function getIid(): int + { + return $this->iid; + } + /** * Set cId. * @@ -867,4 +891,17 @@ class CWiki { return $this->cId; } + + public function getCategories() + { + return $this->categories; + } + + public function addCategory(CWikiCategory $category): CWiki + { + $category->addWikiPage($this); + $this->categories->add($category); + + return $this; + } } diff --git a/src/Chamilo/CourseBundle/Entity/CWikiCategory.php b/src/Chamilo/CourseBundle/Entity/CWikiCategory.php new file mode 100644 index 0000000000..ae640e315a --- /dev/null +++ b/src/Chamilo/CourseBundle/Entity/CWikiCategory.php @@ -0,0 +1,192 @@ + + * @ORM\ManyToMany(targetEntity="Chamilo\CourseBundle\Entity\CWiki", mappedBy="categories") + */ + private $wikiPages; + /** + * @var Course + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course") + * @ORM\JoinColumn(name="c_id", referencedColumnName="id", nullable=false, onDelete="CASCADE") + */ + private $course; + /** + * @var Session|null + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Session") + * @ORM\JoinColumn(name="session_id", referencedColumnName="id", onDelete="CASCADE") + */ + private $session; + /** + * @var int|null + * @Gedmo\TreeLeft() + * @ORM\Column(name="lft", type="integer") + */ + private $lft; + /** + * @var int|null + * @Gedmo\TreeLevel() + * @ORM\Column(name="lvl", type="integer") + */ + private $lvl; + /** + * @var int|null + * @Gedmo\TreeRight() + * @ORM\Column(name="rgt", type="integer") + */ + private $rgt; + /** + * @var CWikiCategory|null + * @ORM\ManyToOne(targetEntity="Chamilo\CourseBundle\Entity\CWikiCategory") + * @ORM\JoinColumn(name="tree_root", referencedColumnName="id", onDelete="CASCADE") + */ + private $root; + /** + * @var CWikiCategory|null + * @Gedmo\TreeParent() + * @ORM\ManyToOne(targetEntity="Chamilo\CourseBundle\Entity\CWikiCategory", inversedBy="children") + * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE") + */ + private $parent; + /** + * @var Collection + * @ORM\OneToMany(targetEntity="Chamilo\CourseBundle\Entity\CWikiCategory", mappedBy="parent") + * @ORM\OrderBy({"lft"="ASC"}) + */ + private $children; + + public function __construct() + { + $this->parent = null; + $this->children = new ArrayCollection(); + $this->wikiPages = new ArrayCollection(); + } + + public function __toString() + { + return $this->name; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getNodeName(): string + { + return str_repeat('    ', $this->lvl).$this->name; + } + + public function setName(string $name): CWikiCategory + { + $this->name = $name; + + return $this; + } + + public function getCourse(): Course + { + return $this->course; + } + + public function setCourse(Course $course): CWikiCategory + { + $this->course = $course; + + return $this; + } + + public function getSession(): ?Session + { + return $this->session; + } + + public function setSession(?Session $session): CWikiCategory + { + $this->session = $session; + + return $this; + } + + public function getRoot(): ?CWikiCategory + { + return $this->root; + } + + public function getParent(): ?CWikiCategory + { + return $this->parent; + } + + public function setParent(?CWikiCategory $parent): CWikiCategory + { + $this->parent = $parent; + + return $this; + } + + public function getChildren(): Collection + { + return $this->children; + } + + public function setChildren(Collection $children): CWikiCategory + { + $this->children = $children; + + return $this; + } + + public function addWikiPage(CWiki $page): CWikiCategory + { + $this->wikiPages->add($page); + + return $this; + } + + public function getWikiPages(): Collection + { + return $this->wikiPages; + } + + public function getLvl(): ?int + { + return $this->lvl; + } +} diff --git a/src/Chamilo/CourseBundle/Entity/Repository/CWikiCategoryRepository.php b/src/Chamilo/CourseBundle/Entity/Repository/CWikiCategoryRepository.php new file mode 100644 index 0000000000..56a83ffa0b --- /dev/null +++ b/src/Chamilo/CourseBundle/Entity/Repository/CWikiCategoryRepository.php @@ -0,0 +1,44 @@ +findBy(['course' => $course, 'session' => $session], ['lft' => 'ASC']); + } + + public function countByCourse(Course $course, ?Session $session): int + { + return $this->count(['couse' => $course, 'session' => $session]); + } + + /** + * @return array|string + */ + public function buildCourseTree(Course $course, ?Session $session, array $options = []) + { + $whereParams = ['course' => $course]; + + if ($session) { + $whereParams['session'] = $session; + } + + $qb = $this->createQueryBuilder('c') + ->where('c.course = :course') + ->andWhere($session ? 'c.session = :session' : 'c.session IS NULL') + ->orderBy('c.lft', 'ASC') + ->setParameters($whereParams) + ->getQuery() + ; + + return $this->buildTree($qb->getArrayResult(), $options); + } +}