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 = '