<?php

/*
 * FORMA - The E-Learning Suite
 *
 * Copyright (c) 2013-2023 (Forma)
 * https://www.formalms.org
 * License https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 *
 * from docebo 4.0.5 CE 2008-2012 (c) docebo
 * License https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 */

defined('IN_FORMA') or exit('Direct access is forbidden');

class CompetencesAdmController extends AdmController
{
    protected $model;
    protected $json;

    protected $base_link_course;
    protected $base_link_competence;

    /*
     * initialize the class
     */
    public array $permissions;

    public function init()
    {
        parent::init();
        require_once _base_ . '/lib/lib.json.php';
        $this->json = new Services_JSON();
        $this->model = new CompetencesAdm();

        $this->base_link_course = 'alms/course';
        $this->base_link_competence = 'adm/competences';

        $this->permissions = [
            'view' => checkPerm('view', true, 'competences'),			//view module
            'add' => checkPerm('mod', true, 'competences'),			//create competences
            'mod' => checkPerm('mod', true, 'competences'),			//edit competences, create/edit/remove categories
            'del' => checkPerm('mod', true, 'competences'),			//delete competences
            'associate_user' => checkPerm('associate_user', true, 'competences'), //manage users for competence
        ];
    }

    //--- internal private methods -----------------------------------------------
    protected function _getErrorMessage($code)
    {
        $message = '';

        switch ($code) {
            case 'no permission':		$message = "You don't have permission to do this."; break;
            case 'invalid category':	$message = Lang::t('_INVALID_CATEGORY', 'competences'); break;
            case 'invalid competence':	$message = Lang::t('_INVALID_COMPETENCE', 'fncroles'); break;
            case 'invalid course':		$message = Lang::t('_INVALID_COURSE', 'competences'); break;
            case 'no users':			$message = Lang::t('_NO_USERS', 'competences'); break;
            default:					$message = Lang::t('_OPERATION_FAILURE', 'standard'); break;
        }

        return $message;
    }

    protected function _getNodeActions($node)
    {
        if (!is_array($node)) {
            return false;
        } //unrecognized type for node data
        $actions = [];
        $id_action = $node['id'];
        $is_root = ($id_action == 0);

        //permissions
        $can_mod = $this->permissions['mod'];
        $can_del = $this->permissions['mod'];

        //rename action
        if ($can_mod) {
            $actions[] = [
                'id' => 'mod_' . $id_action,
                'command' => 'modify',
                'icon' => 'standard/edit.png',
                'alt' => Lang::t('_MOD', 'standard'),
            ];
        }

        //delete action
        if ($can_del) {
            if ($node['is_leaf'] && $node['count_objects'] <= 0 && !$is_root) {
                $actions[] = [
                    'id' => 'del_' . $id_action,
                    'command' => 'delete',
                    'icon' => 'standard/delete.png',
                    'alt' => Lang::t('_DEL', 'standard'),
                ];
            } else {
                $actions[] = [
                    'id' => 'del_' . $id_action,
                    'command' => false,
                    'icon' => 'blank.png',
                ];
            }
        }

        return $actions;
    }

    protected function _setCategoriesTreeArray(&$list, &$output, $id_category)
    {
        $t_arr = [];
        for ($i = 0; $i < count($list); ++$i) {
            if ($list[$i]->id_parent == $id_category) {
                $t_arr[$list[$i]->id_category] = $list[$i]->name;
            }
        }
        if (count($t_arr) <= 0) {
            return;
        }
        asort($t_arr);
        foreach ($t_arr as $key => $value) {
            $output[$key] = [
                'id_category' => $key,
                'label' => $value,
                'children' => [],
            ];
            $this->_setCategoriesTreeArray($list, $output[$key]['children'], $key);
        }
    }

    protected function _setCategoriesTreeDropdown(&$tree_arr, &$output, $level, $is_last)
    {
        $count = count($tree_arr);
        $i = 0;
        foreach ($tree_arr as $info) {
            ++$i;
            $_is_last = ($i == $count);
            $_char = ($_is_last ? '&nbsp;' : '&nbsp;'); //$_char = ($_is_last ? '└' : '├');
            $_label = '';
            for ($j = 0; $j < $level; ++$j) {
                $_label .= '&nbsp;' . ($is_last ? '&nbsp;' : '&nbsp;');
            }//$_label .= '&nbsp;'.($is_last ? '&nbsp;' : '│');
            $_label .= '&nbsp;' . $_char . '&nbsp;';
            $output[$info['id_category']] = $_label . $info['label'];
            if (count($info['children']) > 0) {
                $this->_setCategoriesTreeDropdown($info['children'], $output, $level + 1, $_is_last);
            }
        }
    }

    /*
     * extract all categories and compose dropdown list with indentation
     */
    protected function _getCategoriesDropdownList()
    {
        $output = ['0' => '(root)'];

        $categories = $this->model->getAllCategories();
        $tree_arr = [];
        $this->_setCategoriesTreeArray($categories, $tree_arr, 0);
        $this->_setCategoriesTreeDropdown($tree_arr, $output, 0, false);
        //unset($tree_arr);
        //unset($categories);

        return $output;
    }

    protected function _assignActions(&$nodes)
    {
        if (!is_array($nodes)) {
            return;
        }
        for ($i = 0, $iMax = count($nodes); $i < $iMax; ++$i) {
            $nodes[$i]['node']['options'] = $this->_getNodeActions($nodes[$i]['node']);
            if (isset($nodes[$i]['children']) && count($nodes[$i]['children']) > 0) {
                $this->_assignActions($nodes[$i]['children']);
            }
        }
    }

    protected function _getFromSession($index, $default = null)
    {
        if (!$this->session->has('competences_status_' . $index)) {
            $this->session->set('competences_status_' . $index, $default);
            $this->session->save();
        }

        return $this->session->get('competences_status_' . $index);
    }

    protected function _setInSession($index, $value)
    {
        $this->session->set('competences_status_' . $index, $value);
        $this->session->save();
    }

    //--- Tasks ------------------------------------------------------------------

    /*
     * Render the main page of the competences management module
     */
    public function showTask()
    {
        //tabview widget, used in category editing
        Yuilib::load('tabview');

        //encode some data
        $arr_typologies = $this->model->getCompetenceTypologies();
        $arr_types = $this->model->getCompetenceTypes();

        $typologies_dropdown = '[';
        $first = true;
        foreach ($arr_typologies as $key => $value) {
            if (!$first) {
                $typologies_dropdown .= ',';
            } else {
                $first = false;
            }
            $typologies_dropdown .= '{value: "' . $key . '", label: "' . $value . '"}';
        }

        $types_dropdown = '[';
        $first = true;
        foreach ($arr_types as $key => $value) {
            if (!$first) {
                $types_dropdown .= ',';
            } else {
                $first = false;
            }
            $types_dropdown .= '{value: "' . $key . '", label: "' . $value . '"}';
        }
        $typologies_dropdown .= ']';
        $types_dropdown .= ']';

        //render view
        $this->render('show', [
            'permissions' => $this->permissions,
            'selected_node' => $this->_getFromSession('selected_node', 0),
            'filter_text' => $this->_getFromSession('filter_text', ''),
            'show_descendants' => $this->_getFromSession('show_descendants', false),
            'language' => Lang::get(),
            'startIndex' => $this->_getFromSession('startIndex', 0),
            'results' => $this->_getFromSession('results', FormaLms\lib\Get::sett('visuItem', 25)),
            'rowsPerPage' => $this->_getFromSession('rowsPerPage', FormaLms\lib\Get::sett('visuItem', 25)),
            'sort' => $this->_getFromSession('sort', 0),
            'dir' => $this->_getFromSession('dir', 'asc'),
            'typologies' => $this->json->encode($arr_typologies),
            'types' => $this->json->encode($arr_types),
            'typologies_dropdown' => $typologies_dropdown,
            'types_dropdown' => $types_dropdown,
        ]);
    }

    public function gettreedataTask()
    {
        $command = FormaLms\lib\Get::req('command', DOTY_ALPHANUM, '');

        switch ($command) {
            case 'expand':
                $node_id = FormaLms\lib\Get::req('node_id', DOTY_INT, 0);
                $initial = (FormaLms\lib\Get::req('initial', DOTY_INT, 0) > 0 ? true : false);

                if ($initial) {
                    //get selected category from session and set the expanded tree
                    $node_id = $this->_getFromSession('selected_node', 0);
                    $nodes = $this->model->getInitialCategories($node_id, false);

                    //set nodes action recursively
                    $this->_assignActions($nodes);

                    //set output
                    if (is_array($nodes)) {
                        $output = [
                            'success' => true,
                            'nodes' => $nodes,
                            'initial' => $initial,
                        ];
                    } else {
                        $output = ['success' => false];
                    }
                } else {
                    //extract node data
                    $nodes = $this->model->getCategories($node_id);

                    //if request is invalid, return error message ...
                    if (!is_array($nodes)) {
                        echo $this->json->encode(['success' => false]);

                        return;
                    }

                    //create actions for every node
                    for ($i = 0; $i < count($nodes); ++$i) {
                        $nodes[$i]['options'] = $this->_getNodeActions($nodes[$i]);
                    }
                    //set output
                    $output = [
                        'success' => true,
                        'nodes' => $nodes,
                        'initial' => $initial,
                    ];
                }
                echo $this->json->encode($output);
             break;

            case 'set_selected_node':
                $this->_setInSession('selected_node', FormaLms\lib\Get::Req('node_id', DOTY_INT, 0));
             break;

            case 'delete':
                //check permissions
                if (!$this->permissions['mod']) {
                    $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
                    echo $this->json->encode($output);

                    return;
                }

                $output = ['success' => false];
                $id = FormaLms\lib\Get::req('node_id', DOTY_INT, -1);
                if ($id > 0) {
                    $output['success'] = $this->model->deleteCategory($id);
                }
                echo $this->json->encode($output);
             break;

            case 'movefolder':
                //check permissions
                if (!$this->permissions['mod']) {
                    $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
                    echo $this->json->encode($output);

                    return;
                }

                $this->move_categoryTask();
             break;
        }
    }

    public function addcategoryTask()
    {
    }

    public function renamecategoryTask()
    {
        $id = FormaLms\lib\Get::req('id', DOTY_INT, -1);
        if ($id <= 0) {
            //...
        }
    }

    //----------------------------------------------------------------------------

    public function gettabledataTask()
    {
        //read from input and prepare filter and pagination variables
        $id_category = FormaLms\lib\Get::req('id_category', DOTY_INT, 0);
        $descendants = (FormaLms\lib\Get::req('descendants', DOTY_INT, 0) > 0 ? true : false);
        $startIndex = FormaLms\lib\Get::req('startIndex', DOTY_INT, 0);
        $results = FormaLms\lib\Get::req('results', DOTY_INT, FormaLms\lib\Get::sett('visuItem', 25));
        $rowsPerPage = FormaLms\lib\Get::req('rowsPerPage', DOTY_INT, $results);
        $sort = FormaLms\lib\Get::req('sort', DOTY_STRING, '');
        $dir = FormaLms\lib\Get::req('dir', DOTY_STRING, 'asc');
        $filter_text = FormaLms\lib\Get::req('filter_text', DOTY_STRING, '');

        $searchFilter = [
            'text' => $filter_text,
        ];

        //get total from database and validate the results count
        $total = $this->model->getCompetencesTotal($id_category, $descendants, $searchFilter);
        if ($startIndex >= $total) {
            if ($total < $results) {
                $startIndex = 0;
            } else {
                $startIndex = $total - $results;
            }
        }

        //set pagination argument
        $pagination = [
            'startIndex' => $startIndex,
            'results' => $results,
            'sort' => $sort,
            'dir' => $dir,
        ];

        //update session pagination and filter values
        $this->_setInSession('startIndex', $startIndex);
        $this->_setInSession('results', $results);
        $this->_setInSession('sort', $sort);
        $this->_setInSession('dir', $dir);
        $this->_setInSession('filter_text', $filter_text);
        $this->_setInSession('show_descendants', $descendants);
        $this->_setInSession('rowsPerPage', $rowsPerPage);

        //read records from database
        $list = $this->model->getCompetencesList($id_category, $descendants, $pagination, $searchFilter);

        //prepare the data for sending
        $output_results = [];
        if (is_array($list) && count($list) > 0) {
            $_typologies = $this->model->getCompetenceTypologies();
            $_types = $this->model->getCompetenceTypes();

            foreach ($list as $idst => $record) {
                //format description field
                $description = strip_tags($record->description);
                if (strlen($description) > 100) {
                    $description = substr($description, 0, 97) . '...';
                }

                //prepare output record
                $output_results[] = [
                    'id' => $record->id_competence,
                    'name' => Layout::highlight($record->name, $filter_text),
                    'description' => Layout::highlight($description, $filter_text),
                    'typology' => $_typologies[$record->typology],
                    'type' => $_types[$record->type],
                    'id_typology' => $record->typology,
                    'id_type' => $record->type,
                    'users' => $record->users,
                    'del' => 'ajax.adm_server.php?r=' . $this->base_link_competence . '/del_competence&id=' . (int) $record->id_competence,
                ];
            }
        }

        $output = [
            'totalRecords' => $total,
            'startIndex' => $startIndex,
            'sort' => $sort,
            'dir' => $dir,
            'rowsPerPage' => $rowsPerPage,
            'results' => count($list),
            'records' => $output_results,
        ];

        echo $this->json->encode($output);
    }

    public function add_categoryTask()
    {
        //check permissions
        if (!$this->permissions['add']) {
            $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
            echo $this->json->encode($output);

            return;
        }

        $id_parent = FormaLms\lib\Get::req('id', DOTY_INT, -1);
        if ($id_parent < 0) {
            $output = [
                'success' => false,
                'message' => UIFeedback::perror($this->_getErrorMessage('invalid category')),
            ];
            echo $this->json->encode($output);

            return;
        }

        $this->render('category_editmask', [
            'title' => Lang::t('_NEW_CATEGORY', 'competences'),
            'id_parent' => $id_parent,
            'json' => $this->json,
        ]);
    }

    public function mod_categoryTask()
    {
        //check permissions
        if (!$this->permissions['mod']) {
            $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
            echo $this->json->encode($output);

            return;
        }

        $id_category = FormaLms\lib\Get::req('id', DOTY_INT, -1);
        if ($id_category <= 0) {
            $output = [
                'success' => false,
                'message' => UIFeedback::perror($this->_getErrorMessage('invalid category')),
            ];
            echo $this->json->encode($output);

            return;
        }

        //retrieve category info (name and description
        $info = $this->model->getCategoryInfo($id_category);

        $this->render('category_editmask', [
            'title' => Lang::t('_MOD', 'competences'),
            'id_category' => $id_category,
            'category_langs' => $info->langs,
            'json' => $this->json,
        ]);
    }

    public function add_competenceTask()
    {
        $back_url = 'index.php?r=' . $this->base_link_competence . '/show';

        //check permissions
        if (!$this->permissions['mod']) {
            Util::jump_to($back_url);
        }

        $id_category = FormaLms\lib\Get::req('id', DOTY_INT, -1);
        if ($id_category < 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid category'),
                'back_url' => $back_url,
            ]);

            return;
        }

        $this->render('competence_editmask', [
            'id_category' => $id_category,
            'competence_typologies' => $this->model->getCompetenceTypologies(),
            'competence_types' => $this->model->getCompetenceTypes(),
            'competence_categories' => $this->_getCategoriesDropdownList(),
        ]);
    }

    public function mod_competenceTask()
    {
        $back_url = 'index.php?r=' . $this->base_link_competence . '/show';

        //check permissions
        if (!$this->permissions['mod']) {
            Util::jump_to($back_url);
        }

        $id_competence = FormaLms\lib\Get::req('id', DOTY_INT, -1);
        if ($id_competence <= 0) { //invalid competence
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid competence'),
                'back_url' => $back_url,
            ]);

            return;
        }

        //get competence info and prepare data to send to editmask
        $info = $this->model->getCompetenceInfo($id_competence);

        $this->render('competence_editmask', [
            'id_competence' => $id_competence,
            'id_category' => $info->id_category,
            'competence_langs' => $info->langs,
            'competence_typology' => $info->typology,
            'competence_type' => $info->type,
            //'competence_score' => $info->score,
            //'competence_expiration' => $info->expiration,
            'competence_typologies' => $this->model->getCompetenceTypologies(),
            'competence_types' => $this->model->getCompetenceTypes(),
            'competence_categories' => $this->_getCategoriesDropdownList(),
        ]);
    }

    public function add_category_actionTask()
    {
        //check permissions
        if (!$this->permissions['add']) {
            $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
            echo $this->json->encode($output);

            return;
        }

        //set up the data to insert into DB
        $id_parent = FormaLms\lib\Get::req('id_parent', DOTY_INT, -1);
        if ($id_parent < 0) {
            $output = [
                'success' => false,
                'message' => UIFeedback::perror($this->_getErrorMessage('invalid category')),
            ];
            echo $this->json->encode($output);

            return;
        }
        $names = FormaLms\lib\Get::req('name', DOTY_MIXED, []);
        $descriptions = FormaLms\lib\Get::req('description', DOTY_MIXED, []);
        $langs = [];

        //validate inputs
        if (is_array($names)) {
            //prepare langs array
            $lang_codes = \FormaLms\lib\Forma::langManager()->getAllLangcode();
            foreach ($lang_codes as $lang_code) {
                $langs[$lang_code] = [
                    'name' => (isset($names[$lang_code]) ? $names[$lang_code] : ''),
                    'description' => (isset($descriptions[$lang_code]) ? $descriptions[$lang_code] : ''),
                ];
            }
        }

        //insert data in the DB
        $res = $this->model->createCategory($id_parent, $langs);
        if ($res) {
            //return node data to add in the treeview of the page
            $nodedata = [
                'id' => $res,
                'label' => $this->model->getCategoryName($res, Lang::get()),
                'is_leaf' => true,
                'count_objects' => 0,
            ];
            $nodedata['options'] = $this->_getNodeActions($nodedata);
            $output = [
                'success' => true,
                'node' => $nodedata,
                'id_parent' => $id_parent,
            ];
        } else {
            $output = [
                'success' => false,
                'message' => UIFeedback::perror($this->_getErrorMessage('create category')),
            ];
        }
        echo $this->json->encode($output);
    }

    public function mod_category_actionTask()
    {
        //check permissions
        if (!$this->permissions['mod']) {
            $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
            echo $this->json->encode($output);

            return;
        }

        //set up the data to insert into DB
        $id_category = FormaLms\lib\Get::req('id_category', DOTY_INT, -1);
        if ($id_category < 0) {
            $output = [
                'success' => false,
                'message' => UIFeedback::perror($this->_getErrorMessage('invalid category')),
            ];
            echo $this->json->encode($output);

            return;
        }
        $names = FormaLms\lib\Get::req('name', DOTY_MIXED, []);
        $descriptions = FormaLms\lib\Get::req('description', DOTY_MIXED, []);
        $langs = [];

        //validate inputs
        if (is_array($names)) {
            //prepare langs array
            $lang_codes = \FormaLms\lib\Forma::langManager()->getAllLangcode();
            foreach ($lang_codes as $lang_code) {
                $langs[$lang_code] = [
                    'name' => (isset($names[$lang_code]) ? $names[$lang_code] : ''),
                    'description' => (isset($descriptions[$lang_code]) ? $descriptions[$lang_code] : ''),
                ];
            }
        }

        //insert data in the DB
        $res = $this->model->updateCategory($id_category, $langs);
        if ($res) {
            $_language = FormaLms\lib\Get::req('lang', DOTY_ALPHANUM, Lang::get());
            $output = [
                'success' => true,
                'new_name' => (isset($names[$lang_code]) ? $names[$lang_code] : ''),
            ];
        } else {
            $output = [
                'success' => false,
                'message' => UIFeedback::perror($this->_getErrorMessage('edit category')),
            ];
        }
        echo $this->json->encode($output);
    }

    public function move_categoryTask()
    {
        //check permissions
        if (!$this->permissions['mod']) {
            $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
            echo $this->json->encode($output);

            return;
        }

        $src = FormaLms\lib\Get::req('src', DOTY_INT, -1);
        $dest = FormaLms\lib\Get::req('dest', DOTY_INT, -1);

        $output = [];

        if ($src <= 0 || $dest < 0) {
            $output['success'] = false;
            $output['message'] = UIFeedback::perror($this->_getErrorMessage('invalid category'));
            echo $this->json->encode($output);

            return;
        }

        $res = $this->model->moveCategory($src, $dest);
        $output['success'] = $res ? true : false;
        if (!$res) {
            $output['message'] = UIFeedback::perror($this->_getErrorMessage('move category'));
        }
        echo $this->json->encode($output);
    }

    public function add_competence_actionTask()
    {
        $back_url = 'index.php?r=' . $this->base_link_competence . '/show';

        if (isset($_POST['undo'])) {
            //--- UNDO: return to catalogue list -------------------------------------
            Util::jump_to($back_url);
        }

        //check permissions
        if (!$this->permissions['add']) {
            Util::jump_to($back_url);
        }

        //read inputs
        $id_category = FormaLms\lib\Get::req('id_category', DOTY_INT, -1);
        if ($id_category < 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid category'),
                'back_url' => $back_url,
            ]);

            return;
        }

        $params = new stdClass();
        $params->typology = FormaLms\lib\Get::req('typology', DOTY_STRING, 'skill');
        $params->type = FormaLms\lib\Get::req('type', DOTY_STRING, 'score');
        //$params->score = FormaLms\lib\Get::req('score', DOTY_ALPHANUM, '0');
        //$params->expiration = FormaLms\lib\Get::req('expiration', DOTY_INT, 0);

        $_lang_name = FormaLms\lib\Get::req('name', DOTY_MIXED, []);
        $_lang_desc = FormaLms\lib\Get::req('description', DOTY_MIXED, []);

        $_arr_langs = [];
        $arr = \FormaLms\lib\Forma::langManager()->getAllLangcode();
        foreach ($arr as $lang_code) {
            $_arr_langs[$lang_code] = [
                'name' => (isset($_lang_name[$lang_code]) ? $_lang_name[$lang_code] : ''),
                'description' => (isset($_lang_desc[$lang_code]) ? $_lang_desc[$lang_code] : ''),
            ];
        }
        $params->langs = $_arr_langs;

        $res = $this->model->createCompetence($id_category, $params);

        Util::jump_to($back_url . '&res=' . ($res ? 'ok_create' : 'err_create'));
    }

    public function mod_competence_actionTask()
    {
        $back_url = 'index.php?r=' . $this->base_link_competence . '/show';

        if (isset($_POST['undo'])) {
            //--- UNDO: return to catalogue list -------------------------------------
            Util::jump_to($back_url);
        }

        //check permissions
        if (!$this->permissions['mod']) {
            Util::jump_to($back_url);
        }

        //read inputs
        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, -1);
        if ($id_competence <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid competence'),
                'back_url' => $back_url,
            ]);

            return;
        }

        $params = new stdClass();
        $params->id_category = FormaLms\lib\Get::req('id_category', DOTY_INT, 0);
        $params->typology = FormaLms\lib\Get::req('typology', DOTY_STRING, 'skill');
        $params->type = FormaLms\lib\Get::req('type', DOTY_STRING, 'score');
        //$params->score = FormaLms\lib\Get::req('score', DOTY_ALPHANUM, '0');
        //$params->expiration = FormaLms\lib\Get::req('expiration', DOTY_INT, 0);

        $_lang_name = FormaLms\lib\Get::req('name', DOTY_MIXED, []);
        $_lang_desc = FormaLms\lib\Get::req('description', DOTY_MIXED, []);

        $_arr_langs = [];
        $arr = \FormaLms\lib\Forma::langManager()->getAllLangcode();
        foreach ($arr as $lang_code) {
            $_arr_langs[$lang_code] = [
                'name' => (isset($_lang_name[$lang_code]) ? $_lang_name[$lang_code] : ''),
                'description' => (isset($_lang_desc[$lang_code]) ? $_lang_desc[$lang_code] : ''),
            ];
        }
        $params->langs = $_arr_langs;

        $res = $this->model->updateCompetence($id_competence, $params);

        Util::jump_to($back_url . '&res=' . ($res ? 'ok_modify' : 'err_modify'));
    }

    public function del_competenceTask()
    {
        //check permissions
        if (!$this->permissions['del']) {
            $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
            echo $this->json->encode($output);

            return;
        }

        //check associations with course
        if ($this->model->getCompetenceCoursesTotal(FormaLms\lib\Get::req('id', DOTY_INT, -1)) > 0) {
            $output = ['success' => false, 'message' => UIFeedback::perror(Lang::t('_WITH_COURSE_ASSOCIATIONS', 'competences'))];
            echo $this->json->encode($output);

            return;
        }

        //check associations with fncrole
        if ($this->model->getCompetenceFncRolesTotal(FormaLms\lib\Get::req('id', DOTY_INT, -1)) > 0) {
            $output = ['success' => false, 'message' => UIFeedback::perror(Lang::t('_WITH_FNCROLE_ASSOCIATIONS', 'competences'))];
            echo $this->json->encode($output);

            return;
        }

        //check associations with user
        if ($this->model->getCompetenceUsersTotal(FormaLms\lib\Get::req('id', DOTY_INT, -1)) > 0) {
            $output = ['success' => false, 'message' => UIFeedback::perror(Lang::t('_WITH_USER_ASSOCIATIONS', 'competences'))];
            echo $this->json->encode($output);

            return;
        }

        $output = ['success' => false];
        $id = FormaLms\lib\Get::req('id', DOTY_INT, -1);
        if ($id > 0) {
            $output['success'] = $this->model->deleteCompetence($id);
        }
        echo $this->json->encode($output);
    }

    public function show_usersTask()
    {
        $back_url = 'index.php?r=' . $this->base_link_competence . '/show';

        //check permissions
        if (!$this->permissions['associate_user']) {
            Util::jump_to($back_url);
        }

        //read inputs
        $id_competence = FormaLms\lib\Get::req('id', DOTY_INT, -1);
        if ($id_competence <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid competence'),
                'back_url' => $back_url,
            ]);

            return;
        }

        $result_message = '';
        switch (FormaLms\lib\Get::req('res', DOTY_STRING, '')) {
            case 'no_users':
                $result_message = UIFeedback::notice(Lang::t('_OPERATION_FAILURE', 'standard'), true);
             break;
            case 'invalid_competence_type':
                $result_message = UIFeedback::error(Lang::t('_OPERATION_FAILURE', 'standard'), true);
             break;
            case 'ok_assign':
                $count = FormaLms\lib\Get::req('count', DOTY_INT, -1);
                $result_message = UIFeedback::info(Lang::t('_OPERATION_SUCCESSFUL', 'standard'), true);
             break;
        }

        //render view
        $this->render('show_users', [
            'filter_text' => '',
            'competence_info' => $this->model->getCompetenceInfo($id_competence),
            'result_message' => $result_message,
            'count_users' => $this->model->getCompetenceUsersTotal($id_competence),
        ]);
    }

    public function getuserstabledataTask()
    {
        //check permissions
        if (!$this->permissions['associate_user']) {
            $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
            echo $this->json->encode($output);

            return;
        }

        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, -1);

        $startIndex = FormaLms\lib\Get::req('startIndex', DOTY_INT, 0);
        $results = FormaLms\lib\Get::req('results', DOTY_INT, FormaLms\lib\Get::sett('visuItem', 25));
        $rowsPerPage = FormaLms\lib\Get::req('rowsPerPage', DOTY_INT, $results);
        $sort = FormaLms\lib\Get::req('sort', DOTY_STRING, '');
        $dir = FormaLms\lib\Get::req('dir', DOTY_STRING, 'asc');
        $filter_text = FormaLms\lib\Get::req('filter_text', DOTY_STRING, '');

        $searchFilter = [
            'text' => $filter_text,
        ];

        //get total from database and validate the results count
        $total = $this->model->getCompetenceUsersTotal($id_competence, $searchFilter);
        if ($startIndex >= $total) {
            if ($total < $results) {
                $startIndex = 0;
            } else {
                $startIndex = $total - $results;
            }
        }

        //set pagination argument
        $pagination = [
            'startIndex' => $startIndex,
            'results' => $results,
            'sort' => $sort,
            'dir' => $dir,
        ];

        $list = $this->model->getCompetenceUsersList($id_competence, $pagination, $searchFilter);

        $output_results = [];
        if (is_array($list)) {
            $acl_man = \FormaLms\lib\Forma::getAclManager();
            $required_users = $this->model->getRequiredUsers($id_competence);

            foreach ($list as $user) {
                $output_results[] = [
                    'idst' => $user->id_user,
                    'userid' => Layout::highlight($acl_man->relativeId($user->userid), $filter_text),
                    'firstname' => Layout::highlight($user->firstname, $filter_text),
                    'lastname' => Layout::highlight($user->lastname, $filter_text),
                    'last_assign_date' => Format::date($user->last_assign_date, 'datetime'),
                    //'date_expire' => $_date_expire,
                    //'is_required' => (in_array($user->id_user, $required_users) ? '1' : '0'),
                    'score' => $user->score_got,
                    'unassign' => 'ajax.adm_server.php?r=' . $this->base_link_competence . '/unassign_user&id_competence=' . (int) $id_competence . '&id_user=' . (int) $user->id_user,
                ];
            }
        }

        $output = [
            'totalRecords' => $total,
            'startIndex' => $startIndex,
            'sort' => $sort,
            'dir' => $dir,
            'rowsPerPage' => $rowsPerPage,
            'results' => count($list),
            'records' => $output_results,
        ];

        echo $this->json->encode($output);
    }

    public function assign_users()
    {
        //check permissions
        if (!$this->permissions['associate_user']) {
            Util::jump_to('index.php?r=' . $this->base_link_competence . '/show');
        }

        require_once _adm_ . '/lib/lib.directory.php';
        require_once _adm_ . '/class.module/class.directory.php';

        //read inputs
        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, -1);
        if ($id_competence <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid competence'),
                'back_url' => 'index.php?r=' . $this->base_link_competence . '/show',
            ]);

            return;
        }

        //navigation urls
        $back_url = 'index.php?r=' . $this->base_link_competence . '/show_users&id=' . (int) $id_competence;
        $jump_url = 'index.php?r=' . $this->base_link_competence . '/assign_users&id=' . (int) $id_competence;

        //competence details
        $info = $this->model->getCompetenceInfo($id_competence);
        $name = $this->model->getCompetenceName($id_competence);

        //page_title
        $page_title_arr = [
            $back_url => Lang::t('_COMPETENCES', 'competences'),
            $name,
            Lang::t('_ASSIGN_USERS', 'competences'),
        ];

        if (isset($_POST['cancelselector'])) {
            //--- UNDO: return to catalogue list -------------------------------------
            Util::jump_to($back_url);
        } elseif (isset($_POST['okselector'])) {
            //--- SAVE: users selection has been done --------------------------------

            $acl_man = \FormaLms\lib\Forma::getAclManager();
            $user_selector = new UserSelector();
            $selection = $user_selector->getSelection($_POST);
            $users_selected = $acl_man->getAllUsersFromIdst($selection);
            $competence_users = $this->model->getCompetenceUsers($id_competence, true);
            $users_existent = array_keys($competence_users);

            //retrieve newly selected users
            $_common_users = array_intersect($users_existent, $users_selected);
            $_new_users = array_diff($users_selected, $_common_users);
            $_old_users = array_diff($users_existent, $_common_users);
            unset($_common_users); //free some memory

            //if no users to add: check removed users (if any) then go back
            if (empty($_new_users)) {
                $res = $this->model->removeCompetenceUsers($id_competence, $_old_users, true);
                $message = $res ? 'ok_assign' : 'err_assign';
                Util::jump_to('index.php?r=' . $this->base_link_competence . '/show_users&id=' . (int) $id_competence . '&res=' . $message);
            }

            //assign scores, if the competence type is 'score' (otherwise assign directly score 1 and go back)
            $type = $info->type;
            if ($type == 'score') {
                require_once _base_ . '/lib/lib.table.php';
                $table = new Table();

                $head_label = [];
                $head_style = [];

                $head_label[] = Lang::t('_USERNAME', 'standard');
                $head_label[] = Lang::t('_NAME');
                $head_label[] = Lang::t('_SCORE', 'competences');

                $head_style[] = '';
                $head_style[] = '';
                $head_style[] = 'img-cell';

                $table->addHead($head_label, $head_style);

                $user_model = new UsermanagementAdm();
                $_user_data = $user_model->getUsersDetails($_new_users, true, true);

                $_std_score = 0;
                foreach ($_new_users as $id_user) {
                    if (isset($_user_data[$id_user]) && is_object($_user_data[$id_user])) {
                        $line = [];

                        $line[] = $acl_man->relativeId($_user_data[$id_user]->userid);
                        $line[] = $_user_data[$id_user]->lastname . ' ' . $_user_data[$id_user]->firstname;
                        $line[] = Form::getInputTextfield('textfield', 'assign_score_' . $id_user, 'assign_score[' . $id_user . ']', $_std_score, '', 255, '');

                        $table->addBody($line);
                    }
                }

                $foot = [];
                $foot[] = ['label' => '<b>' . Lang::t('_TOTAL', 'standard') . ': ' . count($_new_users) . '</b>', 'colspan' => 2];
                $foot[] = Form::getInputTextfield('textfield', '_score_', '_score_', $_std_score, '', 255, '') . '<br />'
                    . Form::getButton('set_score', false, Lang::t('_SET', 'standard'))
                    . Form::getButton('reset_score', false, Lang::t('_RESET', 'standard'));

                $table->addFoot($foot);

                $this->render('users_assign', [
                    'id_competence' => $id_competence,
                    'title' => $page_title_arr,
                    'type' => $type,
                    'form_url' => 'index.php?r=' . $this->base_link_competence . '/assign_users_action',
                    'table' => $table,
                    'score_std_value' => $_std_score,
                    'del_selection' => implode(',', $_old_users),
                ]);
            } else {
                $data = [];
                foreach ($_new_users as $id_user) {
                    $data[$id_user] = 1;
                }
                $res1 = $this->model->assignCompetenceUsers($id_competence, $data, true);
                $res2 = $this->model->removeCompetenceUsers($id_competence, $_old_users, true);
                $message = $res1 && $res2 ? 'ok_assign' : 'err_assign';
                Util::jump_to('index.php?r=' . $this->base_link_competence . '/show_users&id=' . (int) $id_competence . '&res=' . $message);
            }
        } else {
            //--- USER SELECTION IS IN PROGRESS: show selector -----------------------
            $user_selector = new UserSelector();

            $user_selector->show_user_selector = true;
            $user_selector->show_group_selector = true;
            $user_selector->show_orgchart_selector = true;
            $user_selector->show_fncrole_selector = true;
            //$user_select->show_orgchart_simple_selector = TRUE;

            //filter selectable user by sub-admin permission
            $acl_man = \FormaLms\lib\Forma::getAclManager();
            $user_selector->setUserFilter('exclude', [$acl_man->getAnonymousId()]);
            if (\FormaLms\lib\FormaUser::getCurrentUser()->getUserLevelId() != ADMIN_GROUP_GODADMIN) {
                require_once _base_ . '/lib/lib.preference.php';
                $adminManager = new AdminPreference();
                $admin_tree = $adminManager->getAdminTree(\FormaLms\lib\FormaUser::getCurrentUser()->getIdST());
                $admin_users = $acl_man->getAllUsersFromIdst($admin_tree);
                $user_selector->setUserFilter('user', $admin_users);
                $user_selector->setUserFilter('group', $admin_tree);
            }

            if (FormaLms\lib\Get::req('is_updating', DOTY_INT, false)) {
                //...
            } else {
                //set initial selection
                $selection = $this->model->getCompetenceUsers($id_competence);
                $user_selector->requested_tab = PEOPLEVIEW_TAB;
                $user_selector->resetSelection($selection);
            }

            $user_selector->addFormInfo(
                Form::getHidden('is_updating', 'is_updating', 1) .
                Form::getHidden('id_competence', 'id_competence', $id_competence)
            );

            //draw selector
            $user_selector->loadSelector(
                Util::str_replace_once('&', '&amp;', $jump_url),
                $page_title_arr,
                false,
                true
            );
        }
    }

    public function assign_users_action()
    {
        $back_url = 'index.php?r=' . $this->base_link_competence . '/show';

        //check permissions
        if (!$this->permissions['associate_user']) {
            Util::jump_to($back_url);
        }

        //read inputs
        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, -1);
        if ($id_competence <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid competence'),
                'back_url' => $back_url,
            ]);

            return;
        }
        $assign = FormaLms\lib\Get::req('assign_score', DOTY_MIXED, []);
        $remove = FormaLms\lib\Get::req('del_selection', DOTY_STRING, '');
        $allValue = FormaLms\lib\Get::req('_score_', DOTY_INT, 0);

        if($allValue) {
            foreach($assign as $userId => $assigned_user) {
                $assign[$userId] = $allValue;
            }
        }

        $del_selection = ($remove != '' ? explode(',', $remove) : []);

        $res1 = $this->model->assignCompetenceUsers($id_competence, $assign, true);
        $res2 = $this->model->removeCompetenceUsers($id_competence, $del_selection, true);
        //$tracked = $this->model->trackOperation();

        $message = $res1 && $res2 ? 'ok_assign' : 'err_assign';
        Util::jump_to('index.php?r=' . $this->base_link_competence . '/show_users&id=' . (int) $id_competence . '&res=' . $message);
    }

    public function user_history()
    {
        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, -1);
        if ($id_competence <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid competence'),
                'back_url' => 'index.php?r=' . $this->base_link_competence . '/show',
            ]);

            return;
        }

        $id_user = FormaLms\lib\Get::req('id_user', DOTY_INT, -1);
        if ($id_user <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid user'),
                'back_url' => 'index.php?r=' . $this->base_link_competence . '/show',
            ]);

            return;
        }

        $history = $this->model->getUserHistoryData($id_competence, $id_user);
    }

    public function unassign_userTask()
    {
        //check permissions
        if (!$this->permissions['associate_user']) {
            $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
            echo $this->json->encode($output);

            return;
        }

        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, -1);
        if ($id_competence <= 0) {
            $output = [
                'success' => false,
                'message' => UIFeedback::perror($this->_getErrorMessage('invalid competence')),
            ];
            echo $this->json->encode($output);

            return;
        }

        $id_user = FormaLms\lib\Get::req('id_user', DOTY_INT, -1);
        if ($id_user <= 0) {
            $output = [
                'success' => false,
                'message' => UIFeedback::perror($this->_getErrorMessage('invalid user')),
            ];
            echo $this->json->encode($output);

            return;
        }

        $res = $this->model->removeCompetenceUsers($id_competence, $id_user, true);
        $output = ['success' => $res ? true : false];
        if (!$res) {
            $output['message'] = Lang::t('_ERROR_WHILE_SAVING', 'standard');
        }

        echo $this->json->encode($output);
    }

    public function mod_usersTask()
    {
        $base_url = 'index.php?r=' . $this->base_link_competence . '/show';

        //check permissions
        if (!$this->permissions['associate_user']) {
            Util::jump_to($base_url);
        }

        //read inputs
        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, -1);
        if ($id_competence <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid competence'),
                'back_url' => $base_url,
            ]);

            return;
        }

        $back_url = 'index.php?r=' . $this->base_link_competence . '/show_users&id=' . (int) $id_competence;

        //competence details
        $info = $this->model->getCompetenceInfo($id_competence);
        $name = $this->model->getCompetenceName($id_competence);

        //page_title
        $page_title_arr = [
            $base_url => Lang::t('_COMPETENCES', 'competences'),
            $back_url => Lang::t('_USERS', 'competences') . ': ' . $name,
            Lang::t('_MOD', 'competences'),
        ];

        $competence_users = $this->model->getCompetenceUsers($id_competence, true);
        $users = array_keys($competence_users);

        if (empty($users)) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('no users'),
                'back_url' => $back_url,
            ]);

            return;
        }

        //assign scores, if the competence type is 'score' (otherwise assign directly score 1 and go back)
        $type = $info->type;
        if ($type == 'score') {
            require_once _base_ . '/lib/lib.table.php';
            $table = new Table();

            $head_label = [];
            $head_style = [];

            $head_label[] = Lang::t('_USERNAME', 'standard');
            $head_label[] = Lang::t('_NAME');
            $head_label[] = Lang::t('_SCORE', 'competences');

            $head_style[] = '';
            $head_style[] = '';
            $head_style[] = 'img-cell';

            $table->addHead($head_label, $head_style);

            $user_model = new UsermanagementAdm();
            $_user_data = $user_model->getUsersDetails($users, true, true);

            $_std_score = 0;
            $acl_man = \FormaLms\lib\Forma::getAclManager();;
            foreach (array_keys($_user_data) as $id_user) {
                $line = [];

                $line[] = $acl_man->relativeId($_user_data[$id_user]->userid);
                $line[] = $_user_data[$id_user]->lastname . ' ' . $_user_data[$id_user]->firstname;
                $line[] = Form::getInputTextfield(
                    'textfield',
                    'assign_score_' . $id_user,
                    'assign_score[' . $id_user . ']',
                    $competence_users[$id_user]->score_got,
                    '',
                    255,
                    ''
                );

                $table->addBody($line);
            }

            $foot = [];
            $foot[] = ['label' => '<b>' . Lang::t('_TOTAL', 'standard') . ': ' . count($users) . '</b>', 'colspan' => 2];
            $foot[] = Form::getInputTextfield('textfield', '_score_', '_score_', $_std_score, '', 255, '') . '<br />'
                . Form::getButton('set_score', false, Lang::t('_SET', 'standard'))
                . Form::getButton('reset_score', false, Lang::t('_RESET', 'standard'));

            $table->addFoot($foot);

            $this->render('users_mod', [
                'id_competence' => $id_competence,
                'title' => $page_title_arr,
                'type' => $type,
                'form_url' => 'index.php?r=' . $this->base_link_competence . '/mod_users_action',
                'table' => $table,
                'score_std_value' => $_std_score,
            ]);
        } else {
            $message = '';
            Util::jump_to('index.php?r=' . $this->base_link_competence . '/show_users&id=' . (int) $id_competence . '&res=' . $message);
        }
    }

    public function mod_users_actionTask()
    {
        $base_url = 'index.php?r=' . $this->base_link_competence . '/show';

        //check permissions
        if (!$this->permissions['associate_user']) {
            Util::jump_to($base_url);
        }

        //read inputs
        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, -1);
        if ($id_competence <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid competence'),
                'back_url' => $base_url,
            ]);

            return;
        }

        $back_url = 'index.php?r=' . $this->base_link_competence . '/show_users&id=' . (int) $id_competence;

        //competence details
        $info = $this->model->getCompetenceInfo($id_competence);
        $competence_users = $this->model->getCompetenceUsers($id_competence, true);

        if (empty($competence_users)) {
            Util::jump_to($back_url . '&res=no_users');
        }
        if ($info->type == 'flag') {
            Util::jump_to($back_url . '&res=invalid_competence_type');
        }

        $count = 0;
        $success = 0;
        $values = FormaLms\lib\Get::req('assign_score', DOTY_MIXED, []);
        foreach ($values as $id_user => $score) {
            if (isset($competence_users[$id_user])) {
                if ($score != $competence_users[$id_user]->score_got) {
                    ++$count;
                    $params = new stdClass();
                    $params->score_got = $score;
                    $res = $this->model->modifyCompetenceUsers($id_competence, $id_user, $params, true);
                    if ($res) {
                        ++$success;
                    }
                }
            }
        }

        Util::jump_to($back_url . '&res=ok_assign&count=' . (int) $count);
    }

    public function change_user_scoreTask()
    {
        //check permissions
        if (!$this->permissions['associate_user']) {
            $output = ['success' => false, 'message' => $this->_getErrorMessage('no permission')];
            echo $this->json->encode($output);

            return;
        }

        $id_user = FormaLms\lib\Get::req('id_user', DOTY_INT, -1);
        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, -1);
        $old_score = FormaLms\lib\Get::req('old_score', DOTY_FLOAT, -1.0);
        $new_score = FormaLms\lib\Get::req('new_score', DOTY_FLOAT, -1.0);

        $output = ['success' => true];

        if ($id_user <= 0) {
            $output['success'] = false;
            echo $this->json->encode($output);

            return;
        }

        if ($id_competence <= 0) {
            $output['success'] = false;
            echo $this->json->encode($output);

            return;
        }

        if ($new_score != $old_score) {
            $params = new stdClass();
            $params->score_got = $new_score;
            $res = $this->model->modifyCompetenceUsers($id_competence, $id_user, $params, true);
            if (!$res) {
                $output['success'] = false;
            } else {
                $output['date'] = Format::date(date('Y-m-d H:i:s'), 'datetime');
            }
        }

        echo $this->json->encode($output);
    }

    /*
     * interface for competences management in course module
     */
    public function man_courseTask()
    {
        $id_course = FormaLms\lib\Get::req('id_course', DOTY_INT, 0);
        if ($id_course <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid course'),
                'back_url' => $base_url,
            ]);

            return;
        }

        $cmodel = new CourseAlms();
        $course_info = $cmodel->getInfo($id_course);
        $course_name = ($course_info['code'] !== '' ? '[' . $course_info['code'] . '] ' : '') . $course_info['name'];

        $title_arr = [
            'index.php?r=' . $this->base_link_course . '/show' => Lang::t('_COURSES', 'course'),
            Lang::t('_COMPETENCES', 'competences') . ' : ' . $course_name,
        ];

        $res = FormaLms\lib\Get::req('res', DOTY_ALPHANUM, '');
        $result_message = '';
        switch ($res) {
            case 'ok_competences': $result_message = Lang::t('_OPERATION_SUCCESSFUL', 'standard'); break;
            case 'err_competences': $result_message = Lang::t('_OPERATION_FAILURE', 'standard'); break;
        }

        $this->render('man_course', [
            'id_course' => $id_course,
            'has_scores' => $this->model->courseHasScoreCompetences($id_course),
            'title_arr' => $title_arr,
            'result_message' => $result_message,
            'filter_text' => '',
            'base_link_competence' => $this->base_link_competence,
        ]);
    }

    /*
     * competences selector for course
     */
    public function assign_to_course()
    {
        $base_url = 'index.php?r=' . $this->base_link_competence . '/show';

        $id_course = FormaLms\lib\Get::req('id_course', DOTY_INT, 0);
        if ($id_course <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid course'),
                'back_url' => $base_url,
            ]);

            return;
        }

        //navigation urls
        $back_url = 'index.php?r=' . $this->base_link_competence . '/man_course&id_course=' . (int) $id_course;
        $jump_url = 'index.php?r=' . $this->base_link_competence . '/assign_to_course&id_course=' . (int) $id_course;

        //selector commands
        $save = FormaLms\lib\Get::req('save', DOTY_MIXED, false);
        $undo = FormaLms\lib\Get::req('undo', DOTY_MIXED, false);

        if ($undo !== false) {
            Util::jump_to($back_url);
        } elseif ($save !== false) {
            $selection = FormaLms\lib\Get::req('competences_selection', DOTY_MIXED, []);
            $selection_str = (is_array($selection) && isset($selection['course_competences_selector']) ? $selection['course_competences_selector'] : '');
            $competences_selected = $selection_str != '' ? explode(',', $selection_str) : [];
            $competences_existent = $this->model->getCourseCompetences($id_course);

            //retrieve newly selected competences
            $_common_competences = array_intersect($competences_existent, $competences_selected);
            $_new_competences = array_diff($competences_selected, $_common_competences); //new competences to add
            $_old_competences = array_diff($competences_existent, $_common_competences); //old competences to delete
            unset($_common_competences); //free some memory

            require_once _base_ . '/lib/lib.table.php';
            $table = new Table();
            $label_h = [
                Lang::t('_NAME', 'standard'),
                Lang::t('_DESCRIPTION', 'standard'),
                Lang::t('_TYPOLOGY', 'competences'),
                Lang::t('_SCORE', 'competences'),
            ];
            $style_h = [
                '',
                '',
                'img-cell',
                'img-cell',
            ];
            $table->addHead($label_h, $style_h);

            $counter = 0; //how many score type competences
            $info = $this->model->getCompetencesInfo($_new_competences);
            $lang_code = Lang::get();
            $std_value = 0;
            foreach ($info as $id => $competence) {
                if ($competence->type == 'score') {
                    ++$counter;
                    $line = [];
                    $line[] = $competence->langs[$lang_code]['name'];
                    $line[] = $competence->langs[$lang_code]['description'];
                    $line[] = $competence->typology;
                    $line[] = Form::getInputTextfield('textfield', 'score_assigned_' . $id, 'score_assigned[' . $id . ']', $std_value, '', 255, '');
                    $table->addBody($line);
                }
            }

            if ($counter > 0) {
                $foot = [
                    ['colspan' => 3, 'label' => ''],
                    Form::getInputTextfield('textfield', 'score_assigned', false, $std_value, '', 255, '') . '<br />'
                        . Form::getButton('set_score', 'set_score', Lang::t('_SET', 'standard'), false, '', true, false)
                        . Form::getButton('reset_score', 'reset_score', Lang::t('_RESET', 'standard'), false, '', true, false),
                ];
                $table->addFoot($foot);

                $title_arr = [
                    'index.php?r=' . $this->base_link_course . '/show' => Lang::t('_COURSES', 'course'),
                    $back_url => Lang::t('_COMPETENCES', 'competences'),
                    Lang::t('_SELECT'),
                ];

                $this->render('course_assign_score', [
                    'id_course' => $id_course,
                    'title_arr' => $title_arr,
                    'table' => $table,
                    'del_selection' => (count($_old_competences) > 0 ? implode(',', $_old_competences) : ''),
                    'new_selection' => (count($_new_competences) > 0 ? implode(',', $_new_competences) : ''),
                    'base_link_competence' => $this->base_link_competence,
                ]);
            } else {
                $scores = [];
                foreach ($_new_competences as $id_competence) {
                    //any competence in here is a flag type competence
                    $scores[$id_competence] = 1;
                }

                //insert newly selected competences in database
                $res1 = $this->model->assignCourseCompetences($id_course, $scores);
                $res2 = $this->model->deleteCourseCompetences($id_course, $_old_competences);

                //go back to main page, with result message
                Util::jump_to($back_url . '&res=' . ($res1 && $res2 ? 'ok_competences' : 'err_competences'));
            }
        } else {
            $title_arr = [
                'index.php?r=' . $this->base_link_course . '/show' => Lang::t('_COURSES', 'course'),
                $back_url => Lang::t('_COMPETENCES', 'competences'),
                Lang::t('_SELECT', 'competences'),
            ];

            //render the courses selector
            $selection = $this->model->getCourseCompetences($id_course);

            $this->render('assign_to_course', [
                'id_course' => $id_course,
                'title_arr' => $title_arr,
                'selection' => $selection,
                'base_link_competence' => $this->base_link_competence,
            ]);
        }
    }

    public function assign_to_course_actionTask()
    {
        $id_course = FormaLms\lib\Get::req('id_course', DOTY_INT, 0);
        if ($id_course <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid course'),
                'back_url' => 'index.php?r=' . $this->base_link_competence . '/show',
            ]);

            return;
        }

        //set back url
        $back_url = 'index.php?r=' . $this->base_link_competence . '/man_course&id_course=' . (int) $id_course;

        //form commands
        $save = FormaLms\lib\Get::req('save', DOTY_MIXED, false);
        $undo = FormaLms\lib\Get::req('undo', DOTY_MIXED, false);

        if ($undo) {
            Util::jump_to($back_url);
        }

        //read and decode inputs
        $scores = FormaLms\lib\Get::req('score_assigned', DOTY_MIXED, false);

        $new_selection_str = FormaLms\lib\Get::req('new_selection', DOTY_STRING, '');
        $new_selection = ($new_selection_str == '' ? [] : explode(',', $new_selection_str));

        $del_selection_str = FormaLms\lib\Get::req('del_selection', DOTY_STRING, '');
        $del_selection = ($del_selection_str == '' ? [] : explode(',', $del_selection_str));

        //prepare scores for DB insertion
        $_scores = [];
        foreach ($new_selection as $id_competence) {
            $_scores[$id_competence] = array_key_exists($id_competence, $scores) ? $scores[$id_competence] : 1;
        }

        //insert newly selected competences in database
        $res1 = $this->model->assignCourseCompetences($id_course, $_scores);
        $res2 = $this->model->deleteCourseCompetences($id_course, $_del_selection);

        //go back to main page, with result message
        Util::jump_to($back_url . '&res=' . ($res1 && $res2 ? 'ok_competences' : 'err_competences'));
    }

    public function getcoursetabledataTask()
    {
        //read from input and prepare filter and pagination variables
        $id_course = FormaLms\lib\Get::req('id_course', DOTY_INT, -1);
        //TO DO: if $id_course <= 0 ...

        $startIndex = FormaLms\lib\Get::req('startIndex', DOTY_INT, 0);
        $results = FormaLms\lib\Get::req('results', DOTY_INT, FormaLms\lib\Get::sett('visuItem', 25));
        $rowsPerPage = FormaLms\lib\Get::req('rowsPerPage', DOTY_INT, $results);
        $sort = FormaLms\lib\Get::req('sort', DOTY_STRING, '');
        $dir = FormaLms\lib\Get::req('dir', DOTY_STRING, 'asc');
        $filter_text = FormaLms\lib\Get::req('filter_text', DOTY_STRING, '');

        $searchFilter = [
            'text' => $filter_text,
        ];

        //get total from database and validate the results count
        $total = $this->model->getCourseCompetencesTotal($id_course, $searchFilter);
        if ($startIndex >= $total) {
            if ($total < $results) {
                $startIndex = 0;
            } else {
                $startIndex = $total - $results;
            }
        }

        //set pagination argument
        $pagination = [
            'startIndex' => $startIndex,
            'results' => $results,
            'sort' => $sort,
            'dir' => $dir,
        ];

        //read records from database
        $list = $this->model->getCourseCompetencesList($id_course, $pagination, $searchFilter);

        //prepare the data for sending
        $output_results = [];
        if (is_array($list) && count($list) > 0) {
            foreach ($list as $idst => $record) {
                //prepare output record
                $output_results[] = [
                    'id' => $record->id_competence,
                    'name' => Layout::highlight($record->name, $filter_text),
                    'description' => Layout::highlight($record->description, $filter_text),
                    'typology' => $record->typology,
                    'type' => $record->type,
                    'score' => $record->score,
                    'del' => 'ajax.adm_server.php?r=' . $this->base_link_competence . '/del_course_competence&id_course=' . (int) $id_course . '&id_competence=' . (int) $record->id_competence,
                ];
            }
        }

        $output = [
            'totalRecords' => $total,
            'startIndex' => $startIndex,
            'sort' => $sort,
            'dir' => $dir,
            'rowsPerPage' => $rowsPerPage,
            'results' => count($list),
            'records' => $output_results,
        ];

        echo $this->json->encode($output);
    }

    /*
     * modified course scores assigned to competences
     */
    public function mod_course_competencesTask()
    {
        $id_course = FormaLms\lib\Get::req('id_course', DOTY_INT, 0);
        if ($id_course <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid course'),
                'back_url' => 'index.php?r=' . $this->base_link_competence . '/show',
            ]);

            return;
        }

        $back_url = 'index.php?r=' . $this->base_link_competence . '/man_course&id_course=' . (int) $id_course;
        $arr_competences = $this->model->getCourseCompetences($id_course);

        require_once _base_ . '/lib/lib.table.php';
        $table = new Table();
        $label_h = [
            Lang::t('_NAME', 'standard'),
            Lang::t('_DESCRIPTION', 'standard'),
            Lang::t('_TYPOLOGY', 'competences'),
            Lang::t('_SCORE', 'competences'),
        ];
        $style_h = [
            '',
            '',
            'img-cell',
            'img-cell',
        ];
        $table->addHead($label_h, $style_h);

        $counter = 0; //how many score type competences
        $info = $this->model->getCompetencesInfo($arr_competences);
        $lang_code = Lang::get();
        $std_value = 0;
        foreach ($info as $id => $competence) {
            if ($competence->type == 'score') {
                ++$counter;
                $line = [];
                $line[] = $competence->langs[$lang_code]['name'];
                $line[] = $competence->langs[$lang_code]['description'];
                $line[] = $competence->typology;
                $line[] = Form::getInputTextfield('textfield', 'score_assigned_' . $id, 'score_assigned[' . $id . ']', $std_value, '', 255, '');
                $table->addBody($line);
            }
        }

        if ($counter > 0) {
            $foot = [
                ['colspan' => 3, 'label' => ''],
                Form::getInputTextfield('textfield', 'score_assigned', false, $std_value, '', 255, '') . '<br />'
                    . Form::getButton('set_score', 'set_score', Lang::t('_SET', 'standard'), false, '', true, false)
                    . Form::getButton('reset_score', 'reset_score', Lang::t('_RESET', 'standard'), false, '', true, false),
            ];
            $table->addFoot($foot);

            $title_arr = [
                'index.php?r=' . $this->base_link_course . '/show' => Lang::t('_COURSES', 'course'),
                $back_url => Lang::t('_COMPETENCES', 'competences'),
                Lang::t('_SCORE'),
            ];

            $this->render('mod_course_assign_score', [
                'id_course' => $id_course,
                'title_arr' => $title_arr,
                'table' => $table,
            ]);
        } else {
            //go back to main page, no score to assign
            Util::jump_to($back_url);
        }
    }

    public function mod_course_competences_actionTask()
    {
        $id_course = FormaLms\lib\Get::req('id_course', DOTY_INT, 0);
        if ($id_course <= 0) {
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid course'),
                'back_url' => 'index.php?r=' . $this->base_link_competence . '/show',
            ]);

            return;
        }

        //set back url
        $back_url = 'index.php?r=' . $this->base_link_competence . '/man_course&id_course=' . (int) $id_course;

        //form commands
        $save = FormaLms\lib\Get::req('save', DOTY_MIXED, false);
        $undo = FormaLms\lib\Get::req('undo', DOTY_MIXED, false);

        if ($undo) {
            Util::jump_to($back_url);
        }

        $scores = FormaLms\lib\Get::req('score_assigned', DOTY_MIXED, []);
        $res = $this->model->updateCourseCompetences($id_course, $scores);

        //go back to main page, with result message

        Util::jump_to($back_url . '&res=' . ($res ? 'ok_competences' : 'err_competences'));
    }

    /*
     * remove a score assignment for a competence
     */
    public function del_course_competenceTask()
    {
        $id_course = FormaLms\lib\Get::req('id_course', DOTY_INT, 0);
        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, 0);

        $output = [];
        if ($id_course <= 0 || $id_competence <= 0) {
            $message_text = ($id_course <= 0 ? $this->_getErrorMessage('invalid course') : $this->_getErrorMessage('invalid competence'));
            $output['success'] = false;
            $output['message'] = UIFeedback::perror($message_text);
        } else {
            $res = $this->model->deleteCourseCompetences((int) $id_course, (int) $id_competence);
            $output['success'] = $res ? true : false;
            if (!$res) {
                $output['message'] = UIFeedback::perror($this->_getErrorMessage('remove course competence'));
            }
        }

        echo $this->json->encode($output);
    }

    public function view_competence_reportTask()
    {
        $id_competence = FormaLms\lib\Get::req('id', DOTY_INT, -1);
        if ($id_competence <= 0) { //invalid competence
            $this->render('invalid', [
                'message' => $this->_getErrorMessage('invalid competence'),
                'back_url' => 'index.php?r=' . $this->base_link_competence . '/show',
            ]);

            return;
        }

        $filter_text = '';
        $filter_set = FormaLms\lib\Get::req('filter_set', DOTY_INT, -1);
        $filter_reset = FormaLms\lib\Get::req('filter_reset', DOTY_INT, -1);
        if ($filter_set != -1) {
            $filter_text = FormaLms\lib\Get::req('filter_text', DOTY_STRING, '');
        }
        if ($filter_reset != -1) {
            $filter_text = '';
        }

        $userdata = $this->model->getCompetenceUsers($id_competence, true, $filter_text);

        $umodel = new UsermanagementAdm();
        $uinfo = $umodel->getUsersDetails(array_keys($userdata), true, true);

        $icon_history = '<span class="ico-sprite subs_elem"><span>' . Lang::t('_HISTORY', 'standard') . '</span></span>';

        $table = new Table();
        $label_h = [
            Lang::t('_USERNAME', 'standard'),
            Lang::t('_LASTNAME', 'standard'),
            Lang::t('_FIRSTNAME', 'standard'),
            Lang::t('_SCORE', 'competences'),
            Lang::t('_DATE_LAST_COMPLETE', 'subscribe'),
            $icon_history,
        ];
        $style_h = [
            '',
            '',
            '',
            'img-cell',
            'img-cell',
            'img-cell',
        ];
        $table->addHead($label_h, $style_h);

        $type = $this->model->getCompetenceType($id_competence);
        $acl_man = \FormaLms\lib\Forma::getAclManager();;
        foreach ($userdata as $id_user => $record) {
            $line = [];

            $line[] = Layout::highlight($acl_man->relativeId($uinfo[$id_user]->userid), $filter_text);
            $line[] = Layout::highlight($uinfo[$id_user]->lastname, $filter_text);
            $line[] = Layout::highlight($uinfo[$id_user]->firstname, $filter_text);
            $line[] = ($type == 'score' ? $record->score_got : '-');
            $line[] = Format::date($record->last_assign_date, 'datetime');
            $line[] = $icon_history;

            $table->addBody($line);
        }

        $this->render('competence_users', [
            'id_competence' => $id_competence,
            'filter_text' => $filter_text,
            'table' => $table,
        ]);
    }

    public function competences_autocompleteTask()
    {
        $query = FormaLms\lib\Get::req('query', DOTY_STRING, '');
        $results = FormaLms\lib\Get::Req('results', DOTY_INT, FormaLms\lib\Get::sett('visuItem', 25));
        $output = ['competences' => []];
        if ($query != '') {
            $competences = $this->model->searchCompetencesByName($query, $results, true);
            foreach ($competences as $competence) {
                $output['competences'][] = [
                    'id_competence' => $competence->id_competence,
                    'name' => $competence->name,
                    'name_highlight' => Layout::highlight($competence->name, $query),
                    'type' => $competence->type,
                    'typology' => $competence->typology,
                ];
            }
        }
        echo $this->json->encode($output);
    }

    public function inline_editTask()
    {
        $id_competence = FormaLms\lib\Get::req('id_competence', DOTY_INT, 0);

        if ($id_competence <= 0) {
            echo $this->json->encode(['success' => true]);

            return;
        }

        //Update info
        $new_value = FormaLms\lib\Get::req('new_value', DOTY_MIXED, '');
        $old_value = FormaLms\lib\Get::req('old_value', DOTY_MIXED, '');
        $column = FormaLms\lib\Get::req('column', DOTY_STRING, '');
        $language = FormaLms\lib\Get::req('language', DOTY_STRING, Lang::get());

        if ($new_value === $old_value) {
            echo $this->json->encode(['success' => true]);
        } else {
            switch ($column) {
                case 'name':
                    $res = $this->model->updateCompetenceName($id_competence, $new_value, $language);
                    $output = ['success' => $res ? true : false];
                    if ($res) {
                        $output['new_value'] = stripslashes($new_value);
                    }
                    echo $this->json->encode($output);
                 break;

                case 'description':
                    $res = $this->model->updateCompetenceDescription($id_competence, $new_value, $language);
                    $output = ['success' => $res ? true : false];
                    if ($res) {
                        $output['new_value'] = stripslashes($new_value);
                    }
                    echo $this->json->encode($output);
                 break;

                case 'typology':
                    $res = $this->model->updateCompetenceTypology($id_competence, $new_value);
                    $output = ['success' => $res ? true : false];
                    if ($res) {
                        $typologies = $this->model->getCompetenceTypologies();
                        $output['new_value'] = $typologies[$new_value];
                    }
                    echo $this->json->encode($output);
                 break;

                case 'type':
                    $res = $this->model->updateCompetenceType($id_competence, $new_value);
                    $output = ['success' => $res ? true : false];
                    if ($res) {
                        $types = $this->model->getCompetenceTypes();
                        $output['new_value'] = $types[$new_value];
                    }
                    echo $this->json->encode($output);
                 break;

                default:
                    echo $this->json->encode(['success' => false]);
                 break;
            }
        }
    }
}
