diff --git a/main/admin/settings.lib.php b/main/admin/settings.lib.php index 2f2a683327..ecf2671de8 100755 --- a/main/admin/settings.lib.php +++ b/main/admin/settings.lib.php @@ -1227,8 +1227,14 @@ function displayTemplates() ); $table->set_header(0, get_lang('Image'), true, ['style' => 'width: 101px;']); $table->set_header(1, get_lang('Title')); - $table->set_header(2, get_lang('Actions'), false, ['style' => 'width:50px;']); - $table->set_column_filter(2, 'actionsFilter'); + if (true === api_get_configuration_value('template_activate_language_filter')) { + $table->set_header(2, get_lang('Language')); + $table->set_header(3, get_lang('Actions'), false, ['style' => 'width:50px;']); + $table->set_column_filter(3, 'actionsFilter'); + } else { + $table->set_header(2, get_lang('Actions'), false, ['style' => 'width:50px;']); + $table->set_column_filter(2, 'actionsFilter'); + } $table->set_column_filter(0, 'searchImageFilter'); $table->display(); } @@ -1285,7 +1291,11 @@ function getTemplateData($from, $number_of_items, $column, $direction) $direction = !in_array(strtolower(trim($direction)), ['asc', 'desc']) ? 'asc' : $direction; // The sql statement. - $sql = "SELECT image as col0, title as col1, id as col2 FROM $table_system_template"; + if (true === api_get_configuration_value('template_activate_language_filter')) { + $sql = "SELECT image as col0, title as col1, language as col2, id as col3 FROM $table_system_template"; + } else { + $sql = "SELECT image as col0, title as col1, id as col2 FROM $table_system_template"; + } $sql .= " ORDER BY col$column $direction "; $sql .= " LIMIT $from,$number_of_items"; $result = Database::query($sql); @@ -1353,6 +1363,8 @@ function searchImageFilter($image) */ function addEditTemplate() { + global $language_interface; + $em = Database::getManager(); // Initialize the object. $id = isset($_GET['id']) ? (int) $_GET['id'] : 0; @@ -1386,6 +1398,11 @@ function addEditTemplate() true, ['ToolbarSet' => 'Documents', 'Width' => '100%', 'Height' => '400'] ); + if (true === api_get_configuration_value('template_activate_language_filter')) { + $form->addSelectLanguage('language', get_lang('Language'), null); + } else { + $form->addHidden('language', $language_interface); + } // Setting the form elements: the form to upload an image to be used with the template. if (empty($template->getImage())) { @@ -1402,6 +1419,7 @@ function addEditTemplate() // Forcing get_lang(). $defaults['title'] = $template->getTitle(); $defaults['comment'] = $template->getComment(); + $defaults['language'] = $template->getLanguage(); // Adding an extra field: a hidden field with the id of the template we are editing. $form->addElement('hidden', 'template_id'); @@ -1446,8 +1464,7 @@ function addEditTemplate() // if the form validates (complies to all rules) we save the information, // else we display the form again (with error message if needed) if ($form->validate()) { - $check = Security::check_token('post'); - + $check = Security::check_token('post', null, 'frm'); if ($check) { // Exporting the values. $values = $form->exportValues(); @@ -1498,6 +1515,7 @@ function addEditTemplate() ->setTitle($values['title']) ->setComment(Security::remove_XSS($values['comment'])) ->setContent(Security::remove_XSS($templateContent, COURSEMANAGERLOWSECURITY)) + ->setLanguage($values['language']) ->setImage($new_file_name); $em->persist($template); $em->flush(); @@ -1515,6 +1533,7 @@ function addEditTemplate() $template ->setTitle($values['title']) ->setComment(Security::remove_XSS($values['comment'])) + ->setLanguage($values['language']) ->setContent(Security::remove_XSS($templateContent, COURSEMANAGERLOWSECURITY)); if ($isDelete) { @@ -1536,12 +1555,13 @@ function addEditTemplate() echo Display::return_message(get_lang('TemplateEdited'), 'confirm'); } } - Security::clear_token(); - displayTemplates(); + Security::clear_token('frm'); + header('Location: '.api_get_path(WEB_CODE_PATH).'admin/settings.php?category=Templates'); + exit; } else { - $token = Security::get_token(); - $form->addElement('hidden', 'sec_token'); - $form->setConstants(['sec_token' => $token]); + $token = Security::get_token('frm'); + $form->addElement('hidden', 'frm_sec_token'); + $form->setConstants(['frm_sec_token' => $token]); // Display the form. $form->display(); } diff --git a/main/inc/ajax/lang.ajax.php b/main/inc/ajax/lang.ajax.php index 65757efca2..093cfbafc4 100644 --- a/main/inc/ajax/lang.ajax.php +++ b/main/inc/ajax/lang.ajax.php @@ -16,6 +16,63 @@ switch ($action) { echo api_get_language_translate_html(); break; + case 'translate_portfolio_category': + + if (isset($_REQUEST['new_language']) && isset($_REQUEST['variable_language']) && isset($_REQUEST['category_id'])) { + + $newLanguage = Security::remove_XSS($_REQUEST['new_language']); + $langVariable = Security::remove_XSS($_REQUEST['variable_language']); + $categoryId = (int) $_REQUEST['category_id']; + $languageId = (int) $_REQUEST['id']; + $subLanguageId = (int) $_REQUEST['sub']; + + $langFilesToLoad = SubLanguageManager:: get_lang_folder_files_list( + api_get_path(SYS_LANG_PATH).'english', + true + ); + + $fileLanguage = $langFilesToLoad[0].'.inc.php'; + $allDataOfLanguage = SubLanguageManager::get_all_information_of_sub_language($languageId, $subLanguageId); + + $pathFolder = api_get_path(SYS_LANG_PATH).$allDataOfLanguage['dokeos_folder'].'/'.$fileLanguage; + $allFileOfDirectory = SubLanguageManager::get_all_language_variable_in_file($pathFolder); + $returnValue = SubLanguageManager::add_file_in_language_directory($pathFolder); + + //update variable language + // Replace double quotes to avoid parse errors + $newLanguage = str_replace('"', '\"', $newLanguage); + $newLanguage = str_replace("\n", "\\n", $newLanguage); + $allFileOfDirectory[$langVariable] = "\"".$newLanguage."\";"; + + $resultArray = []; + foreach ($allFileOfDirectory as $key => $value) { + $resultArray[$key] = SubLanguageManager::write_data_in_file($pathFolder, $value, $key); + } + + $variablesWithProblems = ''; + if (!empty($resultArray)) { + foreach ($resultArray as $key => $result) { + if ($result == false) { + $variablesWithProblems .= $key.'
'; + } + } + } + + if (isset($_REQUEST['redirect'])) { + $message = Display::return_message(get_lang('TheNewWordHasBeenAdded'), 'success'); + if (!empty($variablesWithProblems)) { + $message = Display::return_message( + $pathFolder.' '.get_lang('IsNotWritable').'
'.api_ucwords(get_lang('ErrorsFound')) + .':
'.$variablesWithProblems, + 'error' + ); + } + Display::addFlash($message); + header('Location: '.api_get_path(WEB_CODE_PATH).'portfolio/index.php?'.api_get_cidreq().'&action=translate_category&id='.$categoryId.'&sub_language='.$subLanguageId); + exit; + } + } + break; default: echo ''; } diff --git a/main/inc/lib/PortfolioController.php b/main/inc/lib/PortfolioController.php index 4e8e37996c..9c2a7abf25 100644 --- a/main/inc/lib/PortfolioController.php +++ b/main/inc/lib/PortfolioController.php @@ -56,6 +56,188 @@ class PortfolioController $this->baseUrl = api_get_self().'?'.($cidreq ? $cidreq.'&' : ''); } + /** + * + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + */ + public function translateCategory($category, $languages, $languageId) + { + global $interbreadcrumb; + + $originalName = $category->getTitle(); + $variableLanguage = '$'.$this->getLanguageVariable($originalName); + + $translateUrl = api_get_path(WEB_AJAX_PATH).'lang.ajax.php?a=translate_portfolio_category'; + $form = new FormValidator('new_lang_variable', 'POST', $translateUrl); + $form->addHeader(get_lang('AddWordForTheSubLanguage')); + $form->addText('variable_language', get_lang('LanguageVariable'), false); + $form->addText('original_name', get_lang('OriginalName'), false); + + $languagesOptions = [0 => get_lang('None')]; + foreach ($languages as $language) { + $languagesOptions[$language->getId()] = $language->getOriginalName(); + } + + $form->addSelect( + 'sub_language', + [get_lang('SubLanguage'), get_lang('OnlyActiveSubLanguagesAreListed')], + $languagesOptions + ); + + if ($languageId) { + $languageInfo = api_get_language_info($languageId); + $form->addText( + 'new_language', + [get_lang('Translation'), get_lang('IfThisTranslationExistsThisWillReplaceTheTerm')] + ); + + $form->addHidden('category_id', $category->getId()); + $form->addHidden('id', $languageInfo['parent_id']); + $form->addHidden('sub', $languageInfo['id']); + $form->addHidden('sub_language_id', $languageInfo['id']); + $form->addHidden('redirect', true); + $form->addButtonSave(get_lang('Save')); + } + + $form->setDefaults([ + 'variable_language' => $variableLanguage, + 'original_name' => $originalName, + 'sub_language' => $languageId, + ]); + $form->addRule('sub_language', get_lang('Required'), 'required'); + $form->freeze(['variable_language', 'original_name']); + + $interbreadcrumb[] = [ + 'name' => get_lang('Portfolio'), + 'url' => $this->baseUrl, + ]; + $interbreadcrumb[] = [ + 'name' => get_lang('Categories'), + 'url' => $this->baseUrl.'action=list_categories&parent_id='.$category->getParentId(), + ]; + $interbreadcrumb[] = [ + 'name' => Security::remove_XSS($category->getTitle()), + 'url' => $this->baseUrl.'action=edit_category&id='.$category->getId(), + ]; + + $actions = []; + $actions[] = Display::url( + Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM), + $this->baseUrl.'action=edit_category&id='.$category->getId() + ); + + $js = ''; + $content = $form->returnForm(); + + $this->renderView($content.$js, get_lang('TranslateCategory'), $actions); + } + + /** + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + */ + public function listCategories() + { + global $interbreadcrumb; + + $parentId = isset($_REQUEST['parent_id']) ? (int) $_REQUEST['parent_id'] : 0; + $table = new HTML_Table(['class' => 'table table-hover table-striped data_table']); + $headers = [ + get_lang('Title'), + get_lang('Description'), + ]; + if ($parentId === 0) { + $headers[] = get_lang('SubCategories'); + } + $headers[] = get_lang('Actions'); + + $column = 0; + foreach ($headers as $header) { + $table->setHeaderContents(0, $column, $header); + $column++; + } + $currentUserId = api_get_user_id(); + $row = 1; + $categories = $this->getCategoriesForIndex(null, $parentId); + + foreach ($categories as $category) { + $column = 0; + $subcategories = $this->getCategoriesForIndex(null, $category->getId()); + $linkSubCategories = $category->getTitle(); + if (count($subcategories) > 0) { + $linkSubCategories = Display::url( + $category->getTitle(), + $this->baseUrl.'action=list_categories&parent_id='.$category->getId() + ); + } + $table->setCellContents($row, $column++, $linkSubCategories); + $table->setCellContents($row, $column++, strip_tags($category->getDescription())); + if ($parentId === 0) { + $table->setCellContents($row, $column++, count($subcategories)); + } + + // Actions + $links = null; + // Edit action + $url = $this->baseUrl.'action=edit_category&id='.$category->getId(); + $links .= Display::url(Display::return_icon('edit.png', get_lang('Edit')), $url).' '; + // Visible action : if active + if ($category->isVisible() != 0) { + $url = $this->baseUrl.'action=hide_category&id='.$category->getId(); + $links .= Display::url(Display::return_icon('visible.png', get_lang('Hide')), $url).' '; + } else { // else if not active + $url = $this->baseUrl.'action=show_category&id='.$category->getId(); + $links .= Display::url(Display::return_icon('invisible.png', get_lang('Show')), $url).' '; + } + // Delete action + $url = $this->baseUrl.'action=delete_category&id='.$category->getId(); + $links .= Display::url(Display::return_icon('delete.png', get_lang('Delete')), $url, ['onclick' => 'javascript:if(!confirm(\''.get_lang('AreYouSureToDeleteJS').'\')) return false;']); + + $table->setCellContents($row, $column++, $links); + $row++; + } + + $interbreadcrumb[] = [ + 'name' => get_lang('Portfolio'), + 'url' => $this->baseUrl, + ]; + if ($parentId > 0) { + $interbreadcrumb[] = [ + 'name' => get_lang('Categories'), + 'url' => $this->baseUrl.'action=list_categories', + ]; + } + + $actions = []; + $actions[] = Display::url( + Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM), + $this->baseUrl.($parentId > 0 ? 'action=list_categories' : '') + ); + if ($currentUserId == $this->owner->getId() && $parentId === 0) { + $actions[] = Display::url( + Display::return_icon('new_folder.png', get_lang('AddCategory'), [], ICON_SIZE_MEDIUM), + $this->baseUrl.'action=add_category' + ); + } + $content = $table->toHtml(); + + $pageTitle = get_lang('Categories'); + if ($parentId > 0) { + $em = Database::getManager(); + $parentCategory = $em->find('ChamiloCoreBundle:PortfolioCategory', $parentId); + $pageTitle = $parentCategory->getTitle().' : '.get_lang('SubCategories'); + } + + $this->renderView($content, $pageTitle, $actions); + } + /** * @throws \Doctrine\ORM\ORMException * @throws \Doctrine\ORM\OptimisticLockException @@ -78,6 +260,18 @@ class PortfolioController } $form->addHtmlEditor('description', get_lang('Description'), false, false, ['ToolbarSet' => 'Minimal']); + + $parentSelect = $form->addSelect( + 'parent_id', + get_lang('ParentCategory') + ); + $parentSelect->addOption(get_lang('Level0'), 0); + $currentUserId = api_get_user_id(); + $categories = $this->getCategoriesForIndex(null, 0); + foreach ($categories as $category) { + $parentSelect->addOption($category->getTitle(), $category->getId()); + } + $form->addButtonCreate(get_lang('Create')); if ($form->validate()) { @@ -87,6 +281,7 @@ class PortfolioController $category ->setTitle($values['title']) ->setDescription($values['description']) + ->setParentId($values['parent_id']) ->setUser($this->owner); $this->em->persist($category); @@ -96,7 +291,7 @@ class PortfolioController Display::return_message(get_lang('CategoryAdded'), 'success') ); - header("Location: {$this->baseUrl}"); + header("Location: {$this->baseUrl}action=list_categories"); exit; } @@ -104,11 +299,15 @@ class PortfolioController 'name' => get_lang('Portfolio'), 'url' => $this->baseUrl, ]; + $interbreadcrumb[] = [ + 'name' => get_lang('Categories'), + 'url' => $this->baseUrl.'action=list_categories', + ]; $actions = []; $actions[] = Display::url( Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM), - $this->baseUrl + $this->baseUrl.'action=list_categories' ); $content = $form->returnForm(); @@ -142,7 +341,12 @@ class PortfolioController if (api_get_configuration_value('save_titles_as_html')) { $form->addHtmlEditor('title', get_lang('Title'), true, false, ['ToolbarSet' => 'TitleAsHtml']); } else { - $form->addText('title', get_lang('Title')); + $translateUrl = $this->baseUrl.'action=translate_category&id='.$category->getId(); + $translateButton = Display::toolbarButton(get_lang('TranslateThisTerm'), $translateUrl, 'language', 'link'); + $form->addText( + 'title', + [get_lang('Title'), $translateButton] + ); $form->applyFilter('title', 'trim'); } @@ -169,7 +373,7 @@ class PortfolioController Display::return_message(get_lang('Updated'), 'success') ); - header("Location: $this->baseUrl"); + header("Location: {$this->baseUrl}action=list_categories&parent_id=".$category->getParentId()); exit; } @@ -177,11 +381,24 @@ class PortfolioController 'name' => get_lang('Portfolio'), 'url' => $this->baseUrl, ]; + $interbreadcrumb[] = [ + 'name' => get_lang('Categories'), + 'url' => $this->baseUrl.'action=list_categories', + ]; + if ($category->getParentId() > 0) { + $em = Database::getManager(); + $parentCategory = $em->find('ChamiloCoreBundle:PortfolioCategory', $category->getParentId()); + $pageTitle = $parentCategory->getTitle().' : '.get_lang('SubCategories'); + $interbreadcrumb[] = [ + 'name' => Security::remove_XSS($pageTitle), + 'url' => $this->baseUrl.'action=list_categories&parent_id='.$category->getParentId(), + ]; + } $actions = []; $actions[] = Display::url( Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM), - $this->baseUrl + $this->baseUrl.'action=list_categories&parent_id='.$category->getParentId() ); $content = $form->returnForm(); @@ -208,7 +425,7 @@ class PortfolioController Display::return_message(get_lang('VisibilityChanged'), 'success') ); - header("Location: $this->baseUrl"); + header("Location: {$this->baseUrl}action=list_categories"); exit; } @@ -229,7 +446,7 @@ class PortfolioController Display::return_message(get_lang('CategoryDeleted'), 'success') ); - header("Location: $this->baseUrl"); + header("Location: {$this->baseUrl}action=list_categories"); exit; } @@ -243,10 +460,6 @@ class PortfolioController { global $interbreadcrumb; - $categories = $this->em - ->getRepository('ChamiloCoreBundle:PortfolioCategory') - ->findBy(['user' => $this->owner]); - $form = new FormValidator('add_portfolio', 'post', $this->baseUrl.'action=add_item'); if (api_get_configuration_value('save_titles_as_html')) { @@ -255,15 +468,29 @@ class PortfolioController $form->addText('title', get_lang('Title')); $form->applyFilter('title', 'trim'); } + $editorConfig = [ + 'ToolbarSet' => 'NotebookStudent', + 'Width' => '100%', + 'Height' => '400', + 'cols-size' => [2, 10, 0], + ]; + $form->addHtmlEditor('content', get_lang('Content'), true, false, $editorConfig); - $form->addHtmlEditor('content', get_lang('Content'), true, false, ['ToolbarSet' => 'NotebookStudent']); - $form->addSelectFromCollection( + $categoriesSelect = $form->addSelect( 'category', - [get_lang('Category'), get_lang('PortfolioCategoryFieldHelp')], - $categories, - [], - true + [get_lang('Category'), get_lang('PortfolioCategoryFieldHelp')] ); + $categoriesSelect->addOption(get_lang('SelectACategory'), 0); + $parentCategories = $this->getCategoriesForIndex(null, 0); + foreach ($parentCategories as $parentCategory) { + $categoriesSelect->addOption($parentCategory->getTitle(), $parentCategory->getId()); + $subCategories = $this->getCategoriesForIndex(null, $parentCategory->getId()); + if (count($subCategories) > 0) { + foreach ($subCategories as $subCategory) { + $categoriesSelect->addOption(' — '.$subCategory->getTitle(), $subCategory->getId()); + } + } + } $extraField = new ExtraField('portfolio'); $extra = $extraField->addElements($form); @@ -360,11 +587,46 @@ class PortfolioController Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM), $this->baseUrl ); - - $content = $form->returnForm(); + $actions[] = ''. + Display::return_icon('expand.png', get_lang('Expand'), ['id' => 'expand'], ICON_SIZE_MEDIUM). + Display::return_icon('contract.png', get_lang('Collapse'), ['id' => 'contract', 'class' => 'hide'], ICON_SIZE_MEDIUM).''; + + $js = ''; + $content = '
+
+
+
+
+
+
+
+
+
+ '.$form->returnForm().' +
+
'; $this->renderView( - $content."", + $content.$js, get_lang('AddPortfolioItem'), $actions ); @@ -418,8 +680,13 @@ class PortfolioController ); } } - - $form->addHtmlEditor('content', get_lang('Content'), true, false, ['ToolbarSet' => 'NotebookStudent']); + $editorConfig = [ + 'ToolbarSet' => 'NotebookStudent', + 'Width' => '100%', + 'Height' => '400', + 'cols-size' => [2, 10, 0], + ]; + $form->addHtmlEditor('content', get_lang('Content'), true, false, $editorConfig); $form->addSelectFromCollection( 'category', [get_lang('Category'), get_lang('PortfolioCategoryFieldHelp')], @@ -492,10 +759,46 @@ class PortfolioController Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM), $this->baseUrl ); - $content = $form->returnForm(); + $actions[] = ''. + Display::return_icon('expand.png', get_lang('Expand'), ['id' => 'expand'], ICON_SIZE_MEDIUM). + Display::return_icon('contract.png', get_lang('Collapse'), ['id' => 'contract', 'class' => 'hide'], ICON_SIZE_MEDIUM).''; + + $js = ''; + $content = '
+
+
+
+
+
+
+
+
+
+ '.$form->returnForm().' +
+
'; $this->renderView( - $content."", + $content.$js, get_lang('EditPortfolioItem'), $actions ); @@ -568,51 +871,115 @@ class PortfolioController $actions = []; - if ($currentUserId == $this->owner->getId()) { + if (api_is_platform_admin()) { $actions[] = Display::url( Display::return_icon('add.png', get_lang('Add'), [], ICON_SIZE_MEDIUM), $this->baseUrl.'action=add_item' ); $actions[] = Display::url( Display::return_icon('folder.png', get_lang('AddCategory'), [], ICON_SIZE_MEDIUM), - $this->baseUrl.'action=add_category' + $this->baseUrl.'action=list_categories' ); $actions[] = Display::url( Display::return_icon('waiting_list.png', get_lang('PortfolioDetails'), [], ICON_SIZE_MEDIUM), $this->baseUrl.'action=details' ); } else { - $actions[] = Display::url( - Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM), - $this->baseUrl - ); + if ($currentUserId == $this->owner->getId()) { + $actions[] = Display::url( + Display::return_icon('add.png', get_lang('Add'), [], ICON_SIZE_MEDIUM), + $this->baseUrl.'action=add_item' + ); + $actions[] = Display::url( + Display::return_icon('waiting_list.png', get_lang('PortfolioDetails'), [], ICON_SIZE_MEDIUM), + $this->baseUrl.'action=details' + ); + } else { + $actions[] = Display::url( + Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM), + $this->baseUrl + ); + } } $frmStudentList = null; $frmTagList = null; $categories = []; - + $portfolio = []; if ($this->course) { $frmTagList = $this->createFormTagFilter($listByUser); $frmStudentList = $this->createFormStudentFilter($listByUser); $frmStudentList->setDefaults(['user' => $this->owner->getId()]); + // it translates the category title with the current user language + $categories = $this->getCategoriesForIndex(null, 0); + if (count($categories) > 0) { + foreach ($categories as &$category) { + $translated = $this->translateDisplayName($category->getTitle()); + $category->setTitle($translated); + } + } } else { - $categories = $this->getCategoriesForIndex($currentUserId); + // it displays the list in Network Social for the current user + $portfolio = $this->getCategoriesForIndex(); } $items = $this->getItemsForIndex($listByUser, $frmTagList); + // it gets and translate the sub-categories + $categoryId = $httpRequest->query->getInt('categoryId'); + $subCategoryIdsReq = isset($_REQUEST['subCategoryIds']) ? Security::remove_XSS($_REQUEST['subCategoryIds']) : ''; + $subCategoryIds = $subCategoryIdsReq; + if ('all' !== $subCategoryIdsReq) { + $subCategoryIds = !empty($subCategoryIdsReq) ? explode(',', $subCategoryIdsReq) : []; + } + $subcategories = []; + if ($categoryId > 0) { + $subcategories = $this->getCategoriesForIndex(null, $categoryId); + if (count($subcategories) > 0) { + foreach ($subcategories as &$subcategory) { + $translated = $this->translateDisplayName($subcategory->getTitle()); + $subcategory->setTitle($translated); + } + } + } $template = new Template(null, false, false, false, false, false, false); $template->assign('user', $this->owner); $template->assign('course', $this->course); $template->assign('session', $this->session); - $template->assign('portfolio', $categories); + $template->assign('portfolio', $portfolio); + $template->assign('categories', $categories); $template->assign('uncategorized_items', $items); $template->assign('frm_student_list', $this->course ? $frmStudentList->returnForm() : ''); $template->assign('frm_tag_list', $this->course ? $frmTagList->returnForm() : ''); - + $template->assign('category_id', $categoryId); + $template->assign('subcategories', $subcategories); + $template->assign('subcategory_ids', $subCategoryIds); + + $js = ''; + $template->assign('js_script', $js); $layout = $template->get_template('portfolio/list.html.twig'); + + Display::addFlash( + Display::return_message(get_lang('PortfolioPostAddHelp'), 'info', false) + ); + $content = $template->fetch($layout); $this->renderView($content, get_lang('Portfolio'), $actions); @@ -2033,6 +2400,8 @@ class PortfolioController $frmTagList->addHidden('gidReq', 0); $frmTagList->addHidden('gradebook', 0); $frmTagList->addHidden('origin', ''); + $frmTagList->addHidden('categoryId', 0); + $frmTagList->addHidden('subCategoryIds', ''); if ($listByUser) { $frmTagList->addHidden('user', $this->owner->getId()); @@ -2098,15 +2467,18 @@ class PortfolioController return $frmStudentList; } - private function getCategoriesForIndex(int $currentUserId): array + private function getCategoriesForIndex(?int $currentUserId = null, ?int $parentId = null): array { $categoriesCriteria = []; - $categoriesCriteria['user'] = $this->owner; - - if ($currentUserId !== $this->owner->getId()) { + if (isset($currentUserId)) { + $categoriesCriteria['user'] = $this->owner; + } + if (!api_is_platform_admin() && $currentUserId !== $this->owner->getId()) { $categoriesCriteria['isVisible'] = true; } - + if (isset($parentId)) { + $categoriesCriteria['parentId'] = $parentId; + } return $this->em ->getRepository(PortfolioCategory::class) ->findBy($categoriesCriteria); @@ -2160,6 +2532,36 @@ class PortfolioController $queryBuilder->setParameter('text', '%'.$values['text'].'%'); } + + // Filters by category level 0 + $searchCategories = []; + if (!empty($values['categoryId'])) { + $searchCategories[] = $values['categoryId']; + $subCategories = $this->getCategoriesForIndex(null, $values['categoryId']); + if (count($subCategories) > 0) { + foreach ($subCategories as $subCategory) { + $searchCategories[] = $subCategory->getId(); + } + } + $queryBuilder->andWhere('pi.category IN('.implode(',', $searchCategories).')'); + } + + // Filters by sub-category, don't show the selected values + $diff = []; + if (!empty($values['subCategoryIds']) && !('all' === $values['subCategoryIds'])) { + $subCategoryIds = explode(',', $values['subCategoryIds']); + $diff = array_diff($searchCategories, $subCategoryIds); + } else { + if (trim($values['subCategoryIds']) === '') { + $diff = $searchCategories; + } + } + if (!empty($diff)) { + unset($diff[0]); + if (!empty($diff)) { + $queryBuilder->andWhere('pi.category NOT IN('.implode(',', $diff).')'); + } + } } if ($listByUser) { @@ -2515,4 +2917,32 @@ class PortfolioController return $doc->saveHTML(); } + + /** + * It parsers a title for a variable in lang + * + * @param $defaultDisplayText + * @return string + */ + private function getLanguageVariable($defaultDisplayText) + { + $variableLanguage = api_replace_dangerous_char(strtolower($defaultDisplayText)); + $variableLanguage = str_replace('-', '_', $variableLanguage); + $variableLanguage = api_underscore_to_camel_case($variableLanguage); + + return $variableLanguage; + } + + /** + * It translates the text as parameter + * + * @param $defaultDisplayText + * @return mixed + */ + private function translateDisplayName($defaultDisplayText) + { + $variableLanguage = $this->getLanguageVariable($defaultDisplayText); + + return isset($GLOBALS[$variableLanguage]) ? $GLOBALS[$variableLanguage] : $defaultDisplayText; + } } diff --git a/main/install/configuration.dist.php b/main/install/configuration.dist.php index 7b98d8c290..ac33888ccf 100755 --- a/main/install/configuration.dist.php +++ b/main/install/configuration.dist.php @@ -450,6 +450,7 @@ ALTER TABLE c_tool CHANGE name name LONGTEXT NOT NULL; -- Only with allow_portfolio_tool enabled ALTER TABLE portfolio CHANGE title title LONGTEXT NOT NULL; ALTER TABLE portfolio_category CHANGE title title LONGTEXT NOT NULL; +ALTER TABLE portfolio_category ADD parent_id INT(11) NOT NULL DEFAULT 0; New changes: @@ -1132,6 +1133,10 @@ VALUES (2, 13, 'session_courses_read_only_mode', 'Lock Course In Session', 1, 1, );*/ // $_configuration['mail_template_system'] = false; +// Enable filter by language for system and courses templates +//ALTER TABLE system_template ADD language VARCHAR(40) NOT NULL DEFAULT 'english'; +// $_configuration['template_activate_language_filter'] = false; + // Students can only upload one publication // $_configuration['allow_only_one_student_publication_per_user'] = false; diff --git a/main/portfolio/index.php b/main/portfolio/index.php index 71885f76f0..e8be2ca8c1 100755 --- a/main/portfolio/index.php +++ b/main/portfolio/index.php @@ -19,16 +19,53 @@ if (false === api_get_configuration_value('allow_portfolio_tool')) { api_not_allowed(true); } +$httpRequest = HttpRequest::createFromGlobals(); +$action = $httpRequest->query->get('action', 'list'); + +// It validates the management of categories will be only for admins +if (in_array($action , ['list_categories', 'add_category', 'edit_category']) && !api_is_platform_admin()) { + api_not_allowed(true); +} + +// It includes the user language for translations +$checkUserLanguage = true; +if ($checkUserLanguage) { + global $_user; + $langPath = api_get_path(SYS_LANG_PATH).$_user['language'].'/trad4all.inc.php'; + if (file_exists($langPath)) { + require_once $langPath; + } +} + $controller = new \PortfolioController(); $em = Database::getManager(); -$httpRequest = HttpRequest::createFromGlobals(); - -$action = $httpRequest->query->get('action', 'list'); $htmlHeadXtra[] = api_get_js('portfolio.js'); switch ($action) { + case 'translate_category': + $id = $httpRequest->query->getInt('id'); + $languageId = $httpRequest->query->getInt('sub_language'); + + /** @var PortfolioCategory $category */ + $category = $em->find('ChamiloCoreBundle:PortfolioCategory', $id); + + if (empty($category)) { + break; + } + + $languages = $em + ->getRepository('ChamiloCoreBundle:Language') + ->findAllPlatformSubLanguages(); + + $controller->translateCategory($category, $languages, $languageId); + + return; + case 'list_categories': + $controller->listCategories(); + + return; case 'add_category': $controller->addCategory(); diff --git a/main/template/default/portfolio/list.html.twig b/main/template/default/portfolio/list.html.twig index 30b6c4392b..20fb45f550 100644 --- a/main/template/default/portfolio/list.html.twig +++ b/main/template/default/portfolio/list.html.twig @@ -18,6 +18,37 @@ {% endif %}
+ {% if (categories) %} +
+ {% for category in categories %} + + {% endfor %} + +
+ {% if (subcategories) %} +
+
+ {% for subcategory in subcategories %} + + {% endfor %} +
+ {% endif %} + {% endif %} {% if _u.id != user.id %}

{{ user.completeName }} {{ user.username }}

{% endif %} @@ -99,3 +130,6 @@ {% endif %} }); +{% if (js_script) %} + {{ js_script }} +{% endif %} diff --git a/src/Chamilo/CoreBundle/Component/Editor/CkEditor/CkEditor.php b/src/Chamilo/CoreBundle/Component/Editor/CkEditor/CkEditor.php index 33cae7a314..46cab0b2c2 100644 --- a/src/Chamilo/CoreBundle/Component/Editor/CkEditor/CkEditor.php +++ b/src/Chamilo/CoreBundle/Component/Editor/CkEditor/CkEditor.php @@ -161,8 +161,8 @@ class CkEditor extends Editor public function simpleFormatTemplates() { $templates = $this->getEmptyTemplate(); - - if (api_is_allowed_to_edit(false, true)) { + // The templates are visible for all users in the course + if (api_is_allowed_to_edit(false, true) || api_is_allowed_in_course()) { $platformTemplates = $this->getPlatformTemplates(); $templates = array_merge($templates, $platformTemplates); } @@ -208,8 +208,25 @@ class CkEditor extends Editor */ private function getPlatformTemplates() { - $entityManager = \Database::getManager(); - $systemTemplates = $entityManager->getRepository('ChamiloCoreBundle:SystemTemplate')->findAll(); + if (true === api_get_configuration_value('template_activate_language_filter')) { + global $language_interface; + + $courseInfo = api_get_course_info(); + if (isset($courseInfo['language'])) { + $language = $courseInfo['language']; + } else { + $language = $language_interface; + } + + $entityManager = \Database::getManager(); + $systemTemplates = $entityManager->getRepository('ChamiloCoreBundle:SystemTemplate')->findBy([ + 'language' => $language, + ]); + } else { + $entityManager = \Database::getManager(); + $systemTemplates = $entityManager->getRepository('ChamiloCoreBundle:SystemTemplate')->findAll(); + } + $cssTheme = api_get_path(WEB_CSS_PATH).'themes/'.api_get_visual_theme().'/'; $search = ['{CSS_THEME}', '{IMG_DIR}', '{REL_PATH}', '{COURSE_DIR}', '{CSS}']; $replace = [ diff --git a/src/Chamilo/CoreBundle/Entity/PortfolioCategory.php b/src/Chamilo/CoreBundle/Entity/PortfolioCategory.php index 0b8f6207a1..cb35e272c1 100644 --- a/src/Chamilo/CoreBundle/Entity/PortfolioCategory.php +++ b/src/Chamilo/CoreBundle/Entity/PortfolioCategory.php @@ -62,6 +62,13 @@ class PortfolioCategory */ protected $isVisible = true; + /** + * @var int + * + * @ORM\Column(name="parent_id", type="integer") + */ + protected $parentId = 0; + /** * @var \Doctrine\Common\Collections\ArrayCollection * @@ -201,6 +208,26 @@ class PortfolioCategory return $this; } + /** + * @return int + */ + public function getParentId() + { + return $this->parentId; + } + + /** + * @param int $parentId + */ + public function setParentId(int $parentId) + { + $this->parentId = $parentId; + + return $this; + } + + + /** * Get items. * diff --git a/src/Chamilo/CoreBundle/Entity/SystemTemplate.php b/src/Chamilo/CoreBundle/Entity/SystemTemplate.php index 4bf549d643..4623d7b9e9 100644 --- a/src/Chamilo/CoreBundle/Entity/SystemTemplate.php +++ b/src/Chamilo/CoreBundle/Entity/SystemTemplate.php @@ -50,6 +50,13 @@ class SystemTemplate */ protected $content; + /** + * @var string + * + * @ORM\Column(name="language", type="string", length=40, nullable=true, unique=false) + */ + protected $language; + public function __construct() { $this->comment = ''; @@ -151,6 +158,30 @@ class SystemTemplate return $this->content; } + /** + * Set language. + * + * @param string $language + * + * @return SystemTemplate + */ + public function setLanguage($language) + { + $this->language = $language; + + return $this; + } + + /** + * Get language. + * + * @return string + */ + public function getLanguage() + { + return $this->language; + } + /** * Get id. *