diff --git a/main/admin/extra_field_options.php b/main/admin/extra_field_options.php new file mode 100644 index 0000000000..5f4809485b --- /dev/null +++ b/main/admin/extra_field_options.php @@ -0,0 +1,167 @@ + 'index.php','name' => get_lang('PlatformAdmin')); + +$tool_name = null; + +$action = isset($_GET['action']) ? $_GET['action'] : null; +$field_id = isset($_GET['field_id']) ? $_GET['field_id'] : null; + +if (empty($field_id)) { + api_not_allowed(); +} +if (!in_array($type, ExtraField::getValidExtraFieldTypes())) { + api_not_allowed(); +} + +$extra_field = new ExtraField($type); +$extra_field_info = $extra_field->get($field_id); + +$check = Security::check_token('request'); +$token = Security::get_token(); + +if ($action == 'add') { + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type,'name' => $extra_field->pageName); + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type.'&action=edit&id='.$extra_field_info['id'],'name' => $extra_field_info['field_display_text']); + $interbreadcrumb[]=array('url' => 'extra_field_options.php?type='.$extra_field->type.'&field_id='.$extra_field_info['id'], 'name' => get_lang('EditExtraFieldOptions')); + $interbreadcrumb[]=array('url' => '#','name' => get_lang('Add')); +} elseif ($action == 'edit') { + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type,'name' => $extra_field->pageName); + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type.'&action=edit&id='.$extra_field_info['id'],'name' => $extra_field_info['field_display_text']); + $interbreadcrumb[]=array('url' => 'extra_field_options.php?type='.$extra_field->type.'&field_id='.$extra_field_info['id'], 'name' => get_lang('EditExtraFieldOptions')); + + $interbreadcrumb[]=array('url' => '#','name' => get_lang('Edit')); +} else { + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type,'name' => $extra_field->pageName); + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type.'&action=edit&id='.$extra_field_info['id'],'name' => $extra_field_info['field_display_text']); + $interbreadcrumb[]=array('url' => '#','name' => get_lang('EditExtraFieldOptions')); +} + +//jqgrid will use this URL to do the selects +$params = 'field_id='.$field_id.'&type='.$extra_field->type; +$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_extra_field_options&'.$params; + +//The order is important you need to check the the $column variable in the model.ajax.php file +$columns = array(get_lang('Name'), get_lang('Value'), get_lang('Order'), get_lang('Actions')); + +//Column config +$column_model = array( + array('name'=>'option_display_text', 'index'=>'option_display_text', 'width'=>'180', 'align'=>'left'), + array('name'=>'option_value', 'index'=>'option_value', 'width'=>'', 'align'=>'left','sortable'=>'false'), + array('name'=>'option_order', 'index'=>'option_order', 'width'=>'', 'align'=>'left','sortable'=>'false'), + array('name'=>'actions', 'index'=>'actions', 'width'=>'100', 'align'=>'left','formatter'=>'action_formatter','sortable'=>'false') +); +//Autowidth +$extra_params['autowidth'] = 'true'; +//height auto +$extra_params['height'] = 'auto'; + +//With this function we can add actions to the jgrid (edit, delete, etc) +$action_links = 'function action_formatter(cellvalue, options, rowObject) { + return \''.Display::return_icon('edit.png',get_lang('Edit'),'',ICON_SIZE_SMALL).''. + ' '.Display::return_icon('delete.png',get_lang('Delete'),'',ICON_SIZE_SMALL).''. + '\'; + }'; +$htmlHeadXtra[]=' +'; + +// The header. +Display::display_header($tool_name); + +echo Display::page_header($extra_field_info['field_display_text']); + +$obj = new ExtraFieldOption($extra_field->type); +$obj->field_id = $field_id; + +// Action handling: Add +switch ($action) { + case 'add': + if (api_get_session_id() != 0 && !api_is_allowed_to_session_edit(false, true)) { + api_not_allowed(); + } + $url = api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&'.$params; + $form = $obj->return_form($url, 'add'); + + // The validation or display + if ($form->validate()) { + if ($check) { + $values = $form->exportValues(); + $res = $obj->save_one_item($values); + if ($res) { + Display::display_confirmation_message(get_lang('ItemAdded')); + } + } + $obj->display(); + } else { + /*echo '
'; + echo ''.Display::return_icon('back.png',get_lang('Back'),'',ICON_SIZE_MEDIUM).''; + echo '
'; */ + $form->addElement('hidden', 'sec_token'); + $form->setConstants(array('sec_token' => $token)); + $form->display(); + } + break; + case 'edit': + // Action handling: Editing + $url = api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&id='.intval($_GET['id']).'&'.$params; + $form = $obj->return_form($url, 'edit'); + + // The validation or display + if ($form->validate()) { + if ($check) { + $values = $form->exportValues(); + $res = $obj->update($values); + Display::display_confirmation_message(sprintf(get_lang('ItemUpdated'), $values['name']), false); + } + $obj->display(); + } else { + /*echo '
'; + echo ''.Display::return_icon('back.png',get_lang('Back'),'',ICON_SIZE_MEDIUM).''; + echo '
';*/ + $form->addElement('hidden', 'sec_token'); + $form->setConstants(array('sec_token' => $token)); + $form->display(); + } + break; + case 'delete': + // Action handling: delete + if ($check) { + $res = $obj->delete($_GET['id']); + if ($res) { + Display::display_confirmation_message(get_lang('ItemDeleted')); + } + } + $obj->display(); + break; + default: + $obj->display(); + break; +} +Display :: display_footer(); diff --git a/main/admin/extra_field_workflow.php b/main/admin/extra_field_workflow.php new file mode 100644 index 0000000000..0feb2fdf26 --- /dev/null +++ b/main/admin/extra_field_workflow.php @@ -0,0 +1,212 @@ + 'index.php','name' => get_lang('PlatformAdmin')); + +$tool_name = null; + +$action = isset($_GET['action']) ? $_GET['action'] : null; +$field_id = isset($_GET['field_id']) ? $_GET['field_id'] : null; + +if (empty($field_id)) { + api_not_allowed(); +} +if (!in_array($type, ExtraField::getValidExtraFieldTypes())) { + api_not_allowed(); +} + +$extraField = new ExtraField($type); +$extraFieldInfo = $extraField->get($field_id); + +$check = Security::check_token('request'); +$token = Security::get_token(); + +if ($action == 'add') { + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type,'name' => $extraField->pageName); + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type.'&action=edit&id='.$extraFieldInfo['id'],'name' => $extraFieldInfo['field_display_text']); + $interbreadcrumb[]=array('url' => 'extra_field_options.php?type='.$extraField->type.'&field_id='.$extraFieldInfo['id'], 'name' => get_lang('EditExtraFieldOptions')); + $interbreadcrumb[]=array('url' => '#','name' => get_lang('Add')); +} elseif ($action == 'edit') { + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type,'name' => $extraField->pageName); + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type.'&action=edit&id='.$extraFieldInfo['id'],'name' => $extraFieldInfo['field_display_text']); + $interbreadcrumb[]=array('url' => 'extra_field_options.php?type='.$extraField->type.'&field_id='.$extraFieldInfo['id'], 'name' => get_lang('EditExtraFieldOptions')); + + $interbreadcrumb[]=array('url' => '#','name' => get_lang('Edit')); +} else { + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type,'name' => $extraField->pageName); + $interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type.'&action=edit&id='.$extraFieldInfo['id'],'name' => $extraFieldInfo['field_display_text']); + $interbreadcrumb[]=array('url' => '#','name' => get_lang('EditExtraFieldOptions')); +} + +$roleId = isset($_REQUEST['roleId']) ? $_REQUEST['roleId'] : null; + +//jqgrid will use this URL to do the selects +$params = 'field_id='.$field_id.'&type='.$extraField->type.'&roleId='.$roleId; +$paramsNoRole = 'field_id='.$field_id.'&type='.$extraField->type; + +//The order is important you need to check the the $column variable in the model.ajax.php file +$columns = array(get_lang('Name'), get_lang('Value'), get_lang('Order'), get_lang('Actions')); + +$htmlHeadXtra[]=''; + +// The header. +Display::display_header($tool_name); + +echo Display::page_header($extraFieldInfo['field_display_text']); + +$obj = new ExtraFieldOption($type); +$columns = array('option_display_text', 'option_value', 'option_order'); +$result = Database::select('*', $obj->table, array('where' => array("field_id = ? " => $field_id), 'order'=>"option_order ASC")); + +$table = new HTML_Table(array('class' => 'data_table')); +$column = 0; +$row = 0; +$table->setHeaderContents($row, $column, get_lang('CurrentStatus')); +$column++; +foreach ($result as $item) { + $table->setHeaderContents($row, $column, $item['option_display_text']); + $column++; +} +$row++; + +$form = new FormValidator('workflow', 'post', api_get_self().'?'.$params); +$options = api_get_user_roles(); +$options[0] = get_lang('SelectAnOption'); +ksort($options); +$form->addElement('select', 'status', get_lang('SelectRole'), $options, array('onclick' => 'changeStatus(this)')); + +$checks = $app['orm.em']->getRepository('ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption')->findBy(array('fieldId' => $field_id, 'roleId' => $roleId)); +$includedFields = array(); +if (!empty($checks)) { + foreach ($checks as $availableField) { + $includedFields[$availableField->getFieldOptionId()][] = $availableField->getRelatedFieldOptionId(); + } +} + +foreach ($result as $item) { + $column = 0; + $table->setCellContents($row, $column, $item['option_display_text']); + $column++; + $value = null; + + foreach ($result as $itemCol) { + $id = 'extra_field_status_'.$item['id'].'_'.$itemCol['id']; + $idForm = 'extra_field_status['.$item['id'].']['.$itemCol['id'].']'; + $attributes = array('onclick' => 'setHidden(this)'); + $value = 0; + + if (isset($includedFields[$itemCol['id']]) && in_array($item['id'], $includedFields[$itemCol['id']])) { + $value = 1; + $attributes['checked'] = 'checked'; + } + + $element = Display::input('checkbox', $id, null, $attributes); + $table->setCellContents($row, $column, $element); + $form->addElement('hidden', 'hidden_'.$idForm, $value, array('id' => 'hidden_'.$id)); + $column++; + } + $row++; +} + +if (!empty($roleId)) { + $form->addElement('html', $table->toHtml()); + $group = array(); + $group[]= $form->createElement('button', 'submit', get_lang('Save')); + $group[]= $form->createElement('button', 'select_all', get_lang('SelectAll'), array('class' => 'btn select_all')); + $group[]= $form->createElement('button', 'unselect_all', get_lang('UnSelectAll'), array('class' => 'btn unselect_all')); + $form->addGroup($group, '', null, ' '); + + $form->setDefaults(array('status' => $roleId)); +} else { + $form->addElement('button', 'submit', get_lang('Edit')); +} + +$form->display(); + +if ($form->validate()) { + $values = $form->getSubmitValues(); + $result = $values['hidden_extra_field_status']; + if (!empty($result)) { + foreach ($result as $id => $items) { + foreach ($items as $subItemId => $value) { + $extraFieldOptionRelFieldOption = $app['orm.em']->getRepository('ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption')->findOneBy( + array( + 'fieldId' => $field_id, + 'fieldOptionId' => $subItemId, + 'roleId' => $roleId, + 'relatedFieldOptionId' => $id + ) + ); + + if ($value == 1) { + if (empty($extraFieldOptionRelFieldOption)) { + $extraFieldOptionRelFieldOption = new \ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption(); + $extraFieldOptionRelFieldOption->setFieldId($field_id); + $extraFieldOptionRelFieldOption->setFieldOptionId($subItemId); + $extraFieldOptionRelFieldOption->setRelatedFieldOptionId($id); + $extraFieldOptionRelFieldOption->setRoleId($roleId); + $app['orm.ems']['db_write']->persist($extraFieldOptionRelFieldOption); + } + } else { + + if ($extraFieldOptionRelFieldOption) { + $app['orm.ems']['db_write']->remove($extraFieldOptionRelFieldOption); + } + } + + } + } + $app['orm.ems']['db_write']->flush(); + header('Location:'.api_get_self().'?'.$params); + exit; + } +} + +Display :: display_footer(); diff --git a/main/admin/extra_fields.php b/main/admin/extra_fields.php new file mode 100644 index 0000000000..fa2ad6f91f --- /dev/null +++ b/main/admin/extra_fields.php @@ -0,0 +1,218 @@ + 'index.php','name' => get_lang('PlatformAdmin')); + +$tool_name = null; + +$action = isset($_GET['action']) ? $_GET['action'] : null; +if (!in_array($extraFieldType, ExtraField::getValidExtraFieldTypes())) { + api_not_allowed(); +} + +$check = Security::check_token('request'); +$token = Security::get_token(); + +$obj = new ExtraField($extraFieldType); + +$obj->setupBreadcrumb($interbreadcrumb, $action); + +//jqgrid will use this URL to do the selects +$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_extra_fields&type='.$extraFieldType; + +//The order is important you need to check the the $column variable in the model.ajax.php file +$columns = $obj->getJqgridColumnNames(); + +//Column config +$column_model = $obj->getJqgridColumnModel(); + +//Autowidth +$extra_params['autowidth'] = 'true'; +//height auto +$extra_params['height'] = 'auto'; +$extra_params['sortname'] = 'field_order'; + +$action_links = $obj->getJqgridActionLinks($token); + +$htmlHeadXtra[]=''; + +// The header. +Display::display_header($tool_name); + +// Action handling: Add + +switch ($action) { + case 'add': + if (api_get_session_id() != 0 && !api_is_allowed_to_session_edit(false, true)) { + api_not_allowed(); + } + $url = api_get_self().'?type='.$obj->type.'&action='.Security::remove_XSS($_GET['action']); + $form = $obj->return_form($url, 'add'); + + // The validation or display + if ($form->validate()) { + //if ($check) { + $values = $form->exportValues(); + $res = $obj->save($values); + if ($res) { + Display::display_confirmation_message(get_lang('ItemAdded')); + } + //} + $obj->display(); + } else { + echo '
'; + echo ''.Display::return_icon('back.png',get_lang('Back'),'',ICON_SIZE_MEDIUM).''; + echo '
'; + $form->addElement('hidden', 'sec_token'); + $form->setConstants(array('sec_token' => $token)); + $form->display(); + } + break; + case 'edit': + // Action handling: Editing + $url = api_get_self().'?type='.$obj->type.'&action='.Security::remove_XSS($_GET['action']).'&id='.intval($_GET['id']); + $form = $obj->return_form($url, 'edit'); + + // The validation or display + if ($form->validate()) { + //if ($check) { + $values = $form->exportValues(); + $res = $obj->update($values); + Display::display_confirmation_message(sprintf(get_lang('ItemUpdated'), $values['field_variable']), false); + //} + $obj->display(); + } else { + echo '
'; + echo ''.Display::return_icon('back.png',get_lang('Back'),'',ICON_SIZE_MEDIUM).''; + echo '
'; + $form->addElement('hidden', 'sec_token'); + $form->setConstants(array('sec_token' => $token)); + $form->display(); + } + break; + case 'delete': + // Action handling: delete + //if ($check) { + $res = $obj->delete($_GET['id']); + if ($res) { + Display::display_confirmation_message(get_lang('ItemDeleted')); + } + //} + $obj->display(); + break; + default: + $obj->display(); + break; +} +Display :: display_footer(); + + +/* + +CREATE TABLE IF NOT EXISTS lp_field( + id INT NOT NULL auto_increment, + field_type int NOT NULL DEFAULT 1, + field_variable varchar(64) NOT NULL, + field_display_text varchar(64), + field_default_value text, + field_order int, + field_visible tinyint default 0, + field_changeable tinyint default 0, + field_filter tinyint default 0, + tms DATETIME NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY(id) +); +DROP TABLE IF EXISTS lp_field_options; +CREATE TABLE IF NOT EXISTS lp_field_options ( + id int NOT NULL auto_increment, + field_id int NOT NULL, + option_value text, + option_display_text varchar(64), + option_order int, + tms DATETIME NOT NULL default '0000-00-00 00:00:00', + priority VARCHAR(255), + priority_message VARCHAR(255), + PRIMARY KEY (id) +); +DROP TABLE IF EXISTS lp_field_values; +CREATE TABLE IF NOT EXISTS lp_field_values( + id bigint NOT NULL auto_increment, + lp_id int unsigned NOT NULL, + field_id int NOT NULL, + field_value text, + comment VARCHAR(100) default '', + tms DATETIME NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY(id) +); + +ALTER TABLE lp_field_values ADD INDEX (lp_id, field_id); + + + + */ diff --git a/main/admin/specific_fields_add.php b/main/admin/specific_fields_add.php index c1f3654c25..99a9dcb047 100644 --- a/main/admin/specific_fields_add.php +++ b/main/admin/specific_fields_add.php @@ -74,4 +74,4 @@ if ($form->validate()) { // Display form Display::display_header($tool_name); $form->display(); -Display::display_footer(); \ No newline at end of file +Display::display_footer(); diff --git a/main/announcements/announcement_email.class.php b/main/announcements/announcement_email.class.php index 77284a4999..cc08d3cda0 100644 --- a/main/announcements/announcement_email.class.php +++ b/main/announcements/announcement_email.class.php @@ -220,13 +220,16 @@ class AnnouncementEmail */ public function message($receiverUserId) { - //$title = $this->announcement('title'); + $content = $this->announcement('content'); $content = stripslashes($content); - $content = AnnouncementManager::parse_content($receiverUserId, $content, $this->course('code')); + $content = AnnouncementManager::parse_content($content, $this->course('code'), $session_id); + $session_id = $this->session_id; $user_email = $this->sender('mail'); - $course_param = api_get_cidreq(); + //$course_param = api_get_cidreq(); + // Build the link by hand because api_get_cidreq() doesn't accept course params + $course_param = 'cidReq='.api_get_course_id().'&id_session='.$session_id.'&gidReq='.api_get_group_id(); $course_name = $this->course('title'); $result = "
$content
"; @@ -277,7 +280,7 @@ class AnnouncementEmail /** * Send emails to users. */ - public function send() + public function send($sendToUsersInSession = false) { $sender = $this->sender(); $subject = $this->subject(); @@ -294,6 +297,22 @@ class AnnouncementEmail $sender['user_id'] ); } + + if ($sendToUsersInSession) { + $sessionList = SessionManager::get_session_by_course($this->course['code']); + if (!empty($sessionList)) { + foreach ($sessionList as $sessionInfo) { + $sessionId = $sessionInfo['id']; + $message = $this->message(null, $sessionId); + $userList = CourseManager::get_user_list_from_course_code($this->course['code'], $sessionId); + if (!empty($userList)) { + foreach ($userList as $user) { + MessageManager::send_message_simple($user['user_id'], $subject, $message, $sender['user_id']); + } + } + } + } + } $this->log_mail_sent(); } diff --git a/main/announcements/announcements.inc.php b/main/announcements/announcements.inc.php index 3d3b0bf1cb..12cc5d0c2d 100644 --- a/main/announcements/announcements.inc.php +++ b/main/announcements/announcements.inc.php @@ -1,15 +1,11 @@ $modify_icons"; } - $content = self::parse_content($result['to_user_id'], $content, api_get_course_id()); + $content = self::parse_content($result['to_user_id'], $content, api_get_course_id(), api_get_session_id()); echo "$content"; @@ -366,13 +362,15 @@ class AnnouncementManager api_item_property_update($_course, TOOL_ANNOUNCEMENT, $last_id, "AnnouncementAdded", api_get_user_id(), '', $user); } } + } else { + // the message is sent to everyone, so we set the group to 0 + api_item_property_update($_course, TOOL_ANNOUNCEMENT, $last_id, "AnnouncementAdded", api_get_user_id(), '0'); } if ($sendToUsersInSession) { self::addAnnouncementToAllUsersInSessions($last_id); } - return $last_id; } } @@ -490,6 +488,11 @@ class AnnouncementManager $sql_delete = "DELETE FROM $tbl_item_property WHERE c_id = $course_id AND ref='$id' AND tool='announcement'"; Database::query($sql_delete); + if ($sendToUsersInSession) { + self::addAnnouncementToAllUsersInSessions($id); + } + + if ($sendToUsersInSession) { self::addAnnouncementToAllUsersInSessions($id); } @@ -552,7 +555,6 @@ class AnnouncementManager } } } - } /** @@ -709,7 +711,7 @@ class AnnouncementManager */ public static function construct_not_selected_select_form($group_list = null, $user_list = null, $to_already_selected) { - echo ''; // adding the groups to the select form if ($group_list) { foreach ($group_list as $this_group) { @@ -1208,12 +1210,9 @@ class AnnouncementManager Database::query($sql); } - /** - * @param int $id - */ - public static function send_email($id) + public static function send_email($annoucement_id, $sendToUsersInSession = false) { - $email = AnnouncementEmail::create(null, $id); - $email->send(); + $email = AnnouncementEmail::create(null, $annoucement_id); + $email->send($sendToUsersInSession); } } diff --git a/main/announcements/announcements.php b/main/announcements/announcements.php index b96e02ed10..4fe35c21f4 100644 --- a/main/announcements/announcements.php +++ b/main/announcements/announcements.php @@ -365,7 +365,7 @@ if (api_is_allowed_to_edit(false,true) OR (api_get_course_setting('allow_user_ed /* MAIL FUNCTION */ if ($_POST['email_ann'] && empty($_POST['onlyThoseMails'])) { - AnnouncementManager::send_email($id); + AnnouncementManager::send_email($id, $sendToUsersInSession); } $message = get_lang('AnnouncementModified'); } @@ -385,7 +385,7 @@ if (api_is_allowed_to_edit(false,true) OR (api_get_course_setting('allow_user_ed /* MAIL FUNCTION */ if ($_POST['email_ann'] && empty($_POST['onlyThoseMails'])) { - AnnouncementManager::send_email($insert_id); + AnnouncementManager::send_email($insert_id, $sendToUsersInSession); } } // end condition token @@ -647,9 +647,11 @@ if ($display_form) { echo ' '; - echo '
'; - echo ''; - echo '
'; + if (api_get_session_id() == 0) { + echo '
'; + echo ''; + echo '
'; + } if (!isset($announcement_to_modify) ) $announcement_to_modify =''; diff --git a/main/course_description/course_description_controller.php b/main/course_description/course_description_controller.php index 49b35a899e..fb42c01d47 100644 --- a/main/course_description/course_description_controller.php +++ b/main/course_description/course_description_controller.php @@ -37,123 +37,122 @@ class CourseDescriptionController { // extends Controller { $course_description->set_session_id($session_id); $data = array(); - $course_description_data = $course_description->get_description_data(); - - $data['descriptions'] = $course_description_data['descriptions']; - $data['default_description_titles'] = $course_description->get_default_description_title(); - $data['default_description_title_editable'] = $course_description->get_default_description_title_editable(); - $data['default_description_icon'] = $course_description->get_default_description_icon(); - $data['messages'] = $messages; - - // Fix for chrome XSS filter for videos in iframes - BT#7930 + $course_description_data = $course_description->get_description_data(); + + $data['descriptions'] = $course_description_data['descriptions']; + $data['default_description_titles'] = $course_description->get_default_description_title(); + $data['default_description_title_editable'] = $course_description->get_default_description_title_editable(); + $data['default_description_icon'] = $course_description->get_default_description_icon(); + $data['messages'] = $messages; + $browser = api_get_navigator(); + if (strpos($data['descriptions'], 'view->set_data($data); - $this->view->set_layout('layout'); - $this->view->set_template('listing'); - $this->view->render(); + + // render to the view + $this->view->set_data($data); + $this->view->set_layout('layout'); + $this->view->set_template('listing'); + $this->view->render(); } - /** - * It's used for editing a course description, - * render to listing or edit view - * @param int description type - */ - public function edit($id, $description_type) { - $course_description = new CourseDescription(); - $session_id = api_get_session_id(); - $course_description->set_session_id($session_id); - $data = array(); - $data['id'] = $id; - if (strtoupper($_SERVER['REQUEST_METHOD']) == "POST") { - if (!empty($_POST['title']) && !empty($_POST['contentDescription'])) { - - $check = Security::check_token(); - if ($check) { - $title = $_POST['title']; - if (api_get_setting('wcag_anysurfer_public_pages')=='true') { - $content = WCAG_Rendering::prepareXHTML(); - } else { - $content = $_POST['contentDescription']; - } - $description_type = $_POST['description_type']; - $id = $_POST['id']; - $progress = $_POST['progress']; - - $course_description->set_description_type($description_type); - $course_description->set_title($title); - $course_description->set_content($content); - - $course_description->set_progress($progress); - - $thematic_advance = $course_description->get_data_by_id($id); - - if (!empty($thematic_advance)) { - $course_description->set_id($id); - $affected_rows = $course_description->update(); - } else { - $affected_rows = $course_description->insert(); + /** + * It's used for editing a course description, + * render to listing or edit view + * @param int description type + */ + public function edit($id, $description_type) + { + $course_description = new CourseDescription(); + $session_id = api_get_session_id(); + $course_description->set_session_id($session_id); + $data = array(); + $data['id'] = $id; + if (strtoupper($_SERVER['REQUEST_METHOD']) == "POST") { + if (!empty($_POST['title']) && !empty($_POST['contentDescription'])) { + + $check = Security::check_token(); + if ($check) { + $title = $_POST['title']; + if (api_get_setting('wcag_anysurfer_public_pages') == 'true') { + $content = WCAG_Rendering::prepareXHTML(); + } else { + $content = $_POST['contentDescription']; + } + $description_type = $_POST['description_type']; + $id = $_POST['id']; + $progress = $_POST['progress']; + $course_description->set_description_type($description_type); + $course_description->set_title($title); + $course_description->set_content($content); + + $course_description->set_progress($progress); + + $thematic_advance = $course_description->get_data_by_id($id); + + if (!empty($thematic_advance)) { + $course_description->set_id($id); + $affected_rows = $course_description->update(); + } else { + $affected_rows = $course_description->insert(); + } + Security::clear_token(); } - Security::clear_token(); - } - - if ($affected_rows) { - $message['edit'] = true; - } - $this->listing(false,$message); - - } else { - $data['error'] = 1; - $data['default_description_titles'] = $course_description->get_default_description_title(); - $data['default_description_title_editable'] = $course_description->get_default_description_title_editable(); - $data['default_description_icon'] = $course_description->get_default_description_icon(); - $data['question'] = $course_description->get_default_question(); - $data['information'] = $course_description->get_default_information(); - $data['description_title'] = $_POST['title']; - $data['description_content'] = $_POST['contentDescription']; - $data['description_type'] = $_POST['description_type']; - $data['progress'] = $_POST['progress']; - $data['descriptions'] = $course_description->get_data_by_id($_POST['id']); - // render to the view - $this->view->set_data($data); - $this->view->set_layout('layout'); - $this->view->set_template('edit'); - $this->view->render(); - } - } else { - - $data['default_description_titles'] = $course_description->get_default_description_title(); - $data['default_description_title_editable'] = $course_description->get_default_description_title_editable(); - $data['default_description_icon'] = $course_description->get_default_description_icon(); - $data['question'] = $course_description->get_default_question(); - $data['information'] = $course_description->get_default_information(); - - $data['description_type'] = $description_type; - - if (!empty($id)) { - if (isset($_GET['id_session'])) { - $session_id = intval($_GET['id_session']); - } - $course_description_data = $course_description->get_data_by_id($id, null, $session_id); - $data['description_type'] = $course_description_data['description_type']; - $data['description_title'] = $course_description_data['description_title']; - $data['description_content'] = $course_description_data['description_content']; - $data['progress'] = $course_description_data['progress']; - $data['descriptions'] = $course_description->get_data_by_description_type($description_type, null, $session_id); - } - // render to the view - $this->view->set_data($data); - $this->view->set_layout('layout'); - $this->view->set_template('edit'); - $this->view->render(); + + if ($affected_rows) { + $message['edit'] = true; + } + $this->listing(false, $message); + } else { + $data['error'] = 1; + $data['default_description_titles'] = $course_description->get_default_description_title(); + $data['default_description_title_editable'] = $course_description->get_default_description_title_editable(); + $data['default_description_icon'] = $course_description->get_default_description_icon(); + $data['question'] = $course_description->get_default_question(); + $data['information'] = $course_description->get_default_information(); + $data['description_title'] = $_POST['title']; + $data['description_content'] = $_POST['contentDescription']; + $data['description_type'] = $_POST['description_type']; + $data['progress'] = $_POST['progress']; + $data['descriptions'] = $course_description->get_data_by_id($_POST['id']); + // render to the view + $this->view->set_data($data); + $this->view->set_layout('layout'); + $this->view->set_template('edit'); + $this->view->render(); + } + } else { + + $data['default_description_titles'] = $course_description->get_default_description_title(); + $data['default_description_title_editable'] = $course_description->get_default_description_title_editable(); + $data['default_description_icon'] = $course_description->get_default_description_icon(); + $data['question'] = $course_description->get_default_question(); + $data['information'] = $course_description->get_default_information(); + + $data['description_type'] = $description_type; + + if (!empty($id)) { + if (isset($_GET['id_session'])) { + $session_id = intval($_GET['id_session']); + } + $course_description_data = $course_description->get_data_by_id($id, null, $session_id); + $data['description_type'] = $course_description_data['description_type']; + $data['description_title'] = $course_description_data['description_title']; + $data['description_content'] = $course_description_data['description_content']; + $data['progress'] = $course_description_data['progress']; + $data['descriptions'] = $course_description->get_data_by_description_type($description_type, null, $session_id); + } + // render to the view + $this->view->set_data($data); + $this->view->set_layout('layout'); + $this->view->set_template('edit'); + $this->view->render(); + } } - } - - /** + + /** * It's used for adding a course description, * render to listing or add view */ diff --git a/main/document/document.php b/main/document/document.php index 110db20748..bb7d6afa5e 100644 --- a/main/document/document.php +++ b/main/document/document.php @@ -1510,11 +1510,13 @@ if (isset($documentAndFolders) && is_array($documentAndFolders)) { if ($groupId == 0 || GroupManager::user_has_access($userId, $groupId, GroupManager::GROUP_TOOL_DOCUMENTS)) { $count = 1; $countedPaths = array(); + $countedPaths = array(); + foreach ($documentAndFolders as $key => $document_data) { $row = array(); $row['id'] = $document_data['id']; $row['type'] = $document_data['filetype']; - + // If the item is invisible, wrap it in a span with class invisible. $is_visible = DocumentManager::is_visible_by_id( $document_data['id'], @@ -1606,6 +1608,7 @@ if (isset($documentAndFolders) && is_array($documentAndFolders)) { $row[] = $size; $row[] = $document_name; + $total_size = $total_size + $size; if (!isset($countedPaths[$document_data['path']])) { $total_size = $total_size + $size; $countedPaths[$document_data['path']] = true; diff --git a/main/exercice/exercise.class.php b/main/exercice/exercise.class.php index fe104f73e7..198f8ac292 100644 --- a/main/exercice/exercise.class.php +++ b/main/exercice/exercise.class.php @@ -3410,6 +3410,7 @@ class Exercise ); return $return_array; } + /** * Sends a notification when a user ends an examn * @@ -3911,13 +3912,13 @@ class Exercise $isRandomByCategory = $this->selectRandomByCat(); // on tri les categories en fonction du terme entre [] en tete de la description de la categorie /* - * ex de catégories : + * ex de catégories : * [biologie] Maitriser les mecanismes de base de la genetique * [biologie] Relier les moyens de depenses et les agents infectieux * [biologie] Savoir ou est produite l'enrgie dans les cellules et sous quelle forme * [chimie] Classer les molles suivant leur pouvoir oxydant ou reacteur - * [chimie] Connaître la denition de la theoie acide/base selon Brönsted - * [chimie] Connaître les charges des particules + * [chimie] Connaître la denition de la theoie acide/base selon Brönsted + * [chimie] Connaître les charges des particules * On veut dans l'ordre des groupes definis par le terme entre crochet au debut du titre de la categorie */ // If test option is Grouped By Categories @@ -4179,8 +4180,8 @@ class Exercise } /** - * @return string - */ + * @return string + */ public function get_formated_title() { return api_html_entity_decode($this->selectTitle()); @@ -4212,5 +4213,86 @@ class Exercise { return api_htmlentities($in_title); } + + /** + * @param int courseid + * @param int sessionid + * @return array exercises + */ + public function getExercisesByCouseSession($courseId, $sessionId) + { + $tbl_quiz = Database::get_course_table(TABLE_QUIZ_TEST); + $sql = "SELECT * FROM $tbl_quiz cq " + . "WHERE " + . "cq.c_id = %s AND " + . "( cq.session_id = %s OR cq.session_id = 0 ) AND " + . "cq.active = 0 " + . "ORDER BY cq.id"; + $sql = sprintf($sql, $courseId, $sessionId); + + $result = Database::query($sql); + + $rows = array(); + while($row = Database::fetch_array($result, 'ASSOC')) { + $rows[] = $row; + } + + return $rows; + } + + + /** + * @param int courseid + * @param int sessionid + * @param array quizId + * @return array exercises + */ + public function getExerciseAndResult($courseId, $sessionId, $quizId = array()) + { + if (empty($quizId)) { + return array(); + } + $ids = is_array($quizId) ? $quizId : array($quizId); + $ids = array_map('intval', $quizId); + $ids = implode(',', $quizId); + + $tbl_quiz = Database::get_course_table(TABLE_QUIZ_TEST); + $track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + + $whSession = ""; + if ($sessionId != 0) { + $sql = "SELECT * FROM $track_exercises te " + . "INNER JOIN c_quiz cq ON cq.id = te.exe_exo_id " + . "INNER JOIN course c ON te.exe_cours_id = c.code AND c.id = cq.c_id " + . "WHERE " + . "c.id = %s AND " + . "te.session_id = %s AND " + . "cq.id IN (%s) " + . "ORDER BY cq.id "; + + $sql = sprintf($sql, $courseId, $sessionId, $ids); + $whSession = "te.session_id = %s AND "; + } else { + $sql = "SELECT * FROM $track_exercises te " + . "INNER JOIN c_quiz cq ON cq.id = te.exe_exo_id " + . "INNER JOIN course c ON te.exe_cours_id = c.code AND c.id = cq.c_id " + . "WHERE " + . "c.id = %s AND " + . "cq.id IN (%s) " + . "ORDER BY cq.id "; + $sql = sprintf($sql, $courseId, $ids); + } + + $sql = sprintf($sql, $courseId, $sessionId, $ids); + + $result = Database::query($sql); + + $rows = array(); + while($row = Database::fetch_array($result, 'ASSOC')) { + $rows[] = $row; + } + + return $rows; + } } diff --git a/main/exercice/exercise.lib.php b/main/exercice/exercise.lib.php index 6ded64cbdb..37e6eeb091 100644 --- a/main/exercice/exercise.lib.php +++ b/main/exercice/exercise.lib.php @@ -1482,6 +1482,7 @@ function convert_score($score, $weight) { * @param int 0 = only inactive exercises * 1 = only active exercises, * 2 = all exercises + * 3 = active <> -1 * @return array array with exercise data */ function get_all_exercises($course_info = null, $session_id = 0, $check_publication_dates = false, $search_exercise = '', $search_all_sessions = false, $active = 2) { @@ -1511,7 +1512,9 @@ function get_all_exercises($course_info = null, $session_id = 0, $check_publicat //Show courses by active status $active_sql = ''; - if ($active != 2) { + if ($active == 3) { + $active_sql = ' active <> -1 AND'; + } else if ($active != 2) { $active_sql = sprintf(' active = %d AND', $active); } @@ -1529,13 +1532,18 @@ function get_all_exercises($course_info = null, $session_id = 0, $check_publicat } /** * Get exercise information by id - * @param int Exercise Id - * @return array Exercise info + * @param int $exerciseId Exercise Id + * @param int $courseId The course ID (necessary as c_quiz.id is not unique) + * @return array Exercise info */ -function get_exercise_by_id($exerciseId = 0) -{ +function get_exercise_by_id($exerciseId = 0, $courseId = null) { $TBL_EXERCICES = Database :: get_course_table(TABLE_QUIZ_TEST); - $conditions = array('where' => array('id = ?' => array($exerciseId))); + if (empty($courseId)) { + $courseId = api_get_course_int_id(); + } else { + $courseId = intval($courseId); + } + $conditions = array('where' => array('id = ?' => array($exerciseId), ' AND c_id = ? ' => $courseId)); return Database::select('*', $TBL_EXERCICES, $conditions); } /** diff --git a/main/exercice/exercise_show.php b/main/exercice/exercise_show.php index bec2f1e84b..7594e50a5f 100644 --- a/main/exercice/exercise_show.php +++ b/main/exercice/exercise_show.php @@ -166,7 +166,7 @@ if (!empty($track_exercise_info)) { // if the results_disabled of the Quiz is 1 when block the script $result_disabled = $track_exercise_info['results_disabled']; - if (!(api_is_platform_admin() || api_is_course_admin()) ) { + if (!(api_is_platform_admin() || api_is_course_admin() || api_is_course_coach()) ) { if ($result_disabled == 1) { //api_not_allowed(); $show_results = false; diff --git a/main/inc/ajax/course.ajax.php b/main/inc/ajax/course.ajax.php index a2838dd6d3..424e3efe57 100644 --- a/main/inc/ajax/course.ajax.php +++ b/main/inc/ajax/course.ajax.php @@ -54,38 +54,46 @@ switch ($action) { break; case 'search_course': if (api_is_platform_admin()) { - $courseList = Coursemanager::get_courses_list( - 0, - 10, - 1, //$orderby = 1, - 'ASC', - -1, - $_REQUEST['q'], - null, - true - ); + if (!empty($_GET['session_id']) && intval($_GET['session_id'])) { + //if session is defined, lets find only courses of this session + $courseList = SessionManager::get_course_list_by_session_id( + intval($_GET['session_id']), + $_GET['q'] + ); + } else { + //if session is not defined lets search all courses STARTING with $_GET['q'] + //TODO change this function to search not only courses STARTING with $_GET['q'] + $courseList = Coursemanager::get_courses_list( + 0, //offset + 0, //howMany + 1, //$orderby = 1 + 'ASC', + -1, //visibility + $_GET['q'], + null, //$urlId + true //AlsoSearchCode + ); + } + $results = array(); require_once api_get_path(LIBRARY_PATH).'course_category.lib.php'; - foreach ($courseList as $courseInfo) { - $title = $courseInfo['title']; + if (!empty($courseList)) { - if (!empty($courseInfo['category_code'])) { - $parents = getParentsToString($courseInfo['category_code']); - $title = $parents.$courseInfo['title']; - } + foreach ($courseList as $courseInfo) { + $title = $courseInfo['title']; - $results[] = array( - 'id' => $courseInfo['id'], - 'text' => $title - ); - } + if (!empty($courseInfo['category_code'])) { + $parents = getParentsToString($courseInfo['category_code']); + $title = $parents.$courseInfo['title']; + } - if (!empty($results)) { - /*foreach ($results as &$item) { - $item['id'] = $item['code']; - }*/ + $results[] = array( + 'id' => $courseInfo['id'], + 'text' => $title + ); + } echo json_encode($results); } else { echo json_encode(array()); @@ -118,6 +126,36 @@ switch ($action) { } } break; + case 'search_course_by_session_all': + if (api_is_platform_admin()) + { + if ($_GET['session_id'] == 'TODOS' || $_GET['session_id'] == 'T') { + $_GET['session_id'] = '%'; + } + + $results = SessionManager::get_course_list_by_session_id_like($_GET['session_id'], $_GET['q']); + + //$results = SessionManager::get_sessions_list(array('s.name LIKE' => "%".$_REQUEST['q']."%")); + $results2 = array(); + if (!empty($results)) { + foreach ($results as $item) { + $item2 = array(); + foreach ($item as $id => $internal) { + if ($id == 'id') { + $item2[$id] = $internal; + } + if ($id == 'title') { + $item2['text'] = $internal; + } + } + $results2[] = $item2; + } + echo json_encode($results2); + } else { + echo json_encode(array()); + } + } + break; case 'search_user_by_course': if (api_is_platform_admin()) { @@ -137,7 +175,7 @@ switch ($action) { $result = Database::query($sql_query); while ($user = Database::fetch_assoc($result)) { - $data[] = array('id' => $user['id'], 'text' => $user['username'] ); + $data[] = array('id' => $user['id'], 'text' => $user['username'] . ' (' . $user['firstname'] . ' ' . $user['lastname'] . ')'); } if (!empty($data)) @@ -150,24 +188,25 @@ switch ($action) { } break; case 'search_exercise_by_course': - if (api_is_platform_admin()) - { + if (api_is_platform_admin()) { $course = api_get_course_info_by_id($_GET['course_id']); require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.lib.php'; $session_id = (!empty($_GET['session_id'])) ? intval($_GET['session_id']) : 0 ; - $exercises = get_all_exercises($course, $session_id, false, $_GET['q'], true, 2); + $exercises = get_all_exercises($course, $session_id, false, $_GET['q'], true, 3); - foreach ($exercises as $exercise) - { - $data[] = array('id' => $exercise['id'], 'text' => $exercise['title'] ); + foreach ($exercises as $exercise) { + //if (api_get_item_visibility($course, 'quiz', $exercise['id'])) { + $data[] = array('id' => $exercise['id'], 'text' => html_entity_decode($exercise['title']) ); + //} } if (!empty($data)) { + $data[] = array('id' => 'T', 'text' => 'TODOS'); echo json_encode($data); } else { - echo json_encode(array()); + echo json_encode(array(array('id' => 'T', 'text' => 'TODOS'))); } } break; @@ -176,7 +215,7 @@ switch ($action) { { $survey = Database :: get_course_table(TABLE_SURVEY); - $sql = "SELECT survey_id as id, title + $sql = "SELECT survey_id as id, title, anonymous FROM $survey WHERE c_id = %d AND session_id = %d @@ -186,7 +225,8 @@ switch ($action) { $result = Database::query($sql_query); while ($survey = Database::fetch_assoc($result)) { - $data[] = array('id' => $survey['id'], 'text' => $survey['title'] ); + $survey['title'] .= ($survey['anonymous'] == 1) ? ' (' . get_lang('Anonymous') . ')': ''; + $data[] = array('id' => $survey['id'], 'text' => strip_tags(html_entity_decode($survey['title']))); } if (!empty($data)) { diff --git a/main/inc/ajax/course_home.ajax.php b/main/inc/ajax/course_home.ajax.php index 4587950911..140bd0fa68 100644 --- a/main/inc/ajax/course_home.ajax.php +++ b/main/inc/ajax/course_home.ajax.php @@ -135,11 +135,15 @@ switch ($action) { $count = 0; foreach ($course_list as $item) { - if (isset($course_id) && !empty($course_id)) { - if ($course_id != $item['id']) { - continue; - } - } +// var_dump($course_list);Exit; +// if(!$item['visibility']) { +// echo "xxx";Exit; +// } +// if (isset($course_id) && !empty($course_id)) { +// if ($course_id != $item['id']) { +// continue; +// } +// } $list = new LearnpathList(api_get_user_id(), $item['code'], $session_id); $flat_list = $list->get_flat_list(); $lps[$item['code']] = $flat_list; diff --git a/main/inc/ajax/extra_field.ajax.php b/main/inc/ajax/extra_field.ajax.php new file mode 100644 index 0000000000..540a2ae3b2 --- /dev/null +++ b/main/inc/ajax/extra_field.ajax.php @@ -0,0 +1,30 @@ +get_second_select_field_options_by_field($field_id, $option_value_id, true); + } + break; + case 'search_tags': + $type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null; + $fieldId = isset($_REQUEST['field_id']) ? $_REQUEST['field_id'] : null; + $tag = isset($_REQUEST['tag']) ? $_REQUEST['tag'] : null; + $extraFieldOption = new ExtraFieldOption($type); + echo $extraFieldOption->getSearchOptionsByField($tag, $fieldId, 10, 'json'); + break; + default: + exit; + break; +} +exit; diff --git a/main/inc/ajax/model.ajax.php b/main/inc/ajax/model.ajax.php index f8d2fdec39..9ca3511093 100644 --- a/main/inc/ajax/model.ajax.php +++ b/main/inc/ajax/model.ajax.php @@ -316,6 +316,7 @@ switch ($action) { break; case 'get_sessions': $courseId = isset($_GET['course_id']) && !empty($_GET['course_id']) ? intval($_GET['course_id']) : null; + $where_condition = str_replace('category_name', 'sc.name', $where_condition); if (!empty($courseId)) { $whereCondition .= " AND c.id = $courseId"; } @@ -324,26 +325,33 @@ switch ($action) { case 'get_session_lp_progress': case 'get_session_progress': //@TODO replace this for a more efficient function (not retrieving the whole data) - $course = api_get_course_info_by_id($courseId); - $users = CourseManager::get_student_list_from_course_code($course['code'], true, intval($_GET['session_id'])); + $course = api_get_course_info_by_id($_GET['course_id']); + $users = CourseManager::get_student_list_from_course_code($course['code'], true, $_GET['session_id'], $_GET['date_from'], $_GET['date_to']); $count = count($users); break; case 'get_exercise_progress': //@TODO replace this for a more efficient function (not retrieving the whole data) - $records = SessionManager::get_exercise_progress(intval($_GET['session_id']), intval($_GET['course_id']), intval($_GET['exercise_id'])); + $records = Tracking::get_exercise_progress($_GET['session_id'], $_GET['course_id'], $_GET['exercise_id'], $_GET['date_from'], $_GET['date_to']); $count = count($records); break; case 'get_session_access_overview': //@TODO replace this for a more efficient function (not retrieving the whole data) - $records = SessionManager::get_user_data_access_tracking_overview($_GET['session_id'], $_GET['course_id'], $_GET['student_id'], $_GET['profile'], $_GET['date_to'], $_GET['date_from'], $options); + $records = SessionManager::get_user_data_access_tracking_overview($_GET['session_id'], $_GET['course_id'], $_GET['student_id'], $_GET['profile'], $_GET['date_from'], $_GET['date_to'], $options); $count = count($records); break; case 'get_survey_overview': //@TODO replace this for a more efficient function (not retrieving the whole data) - $records = SessionManager::get_survey_overview(intval($_GET['session_id']), intval($_GET['course_id']), intval($_GET['survey_id']), $options); + $records = SessionManager::get_survey_overview($_GET['session_id'], $_GET['course_id'], $_GET['survey_id'], $_GET['date_from'], $_GET['date_to'], $options); $count = count($records); break; - /*case 'get_extra_fields': + case 'get_exercise_grade': + //@TODO replace this for a more efficient function (not retrieving the whole data) + $course = api_get_course_info_by_id($_GET['course_id']); + $users = CourseManager::get_student_list_from_course_code($course['code'], true, $_GET['session_id']); + + $count = count($users); + break; + case 'get_extra_fields': $type = $_REQUEST['type']; $obj = new ExtraField($type); $count = $obj->get_count(); @@ -353,7 +361,7 @@ switch ($action) { $field_id = $_REQUEST['field_id']; $obj = new ExtraFieldOption($type); $count = $obj->get_count_by_field_id($field_id); - break;*/ + break; case 'get_timelines': require_once $libpath.'timeline.lib.php'; $obj = new Timeline(); @@ -720,6 +728,9 @@ switch ($action) { 'name', 'nbr_courses', 'nbr_users', 'category_name', 'date_start','date_end', 'coach_name', 'session_active', 'visibility' ); + //Rename Category_name + $where_condition = str_replace('category_name', 'sc.name', $where_condition); + $result = SessionManager::get_sessions_admin( array( 'where' => $whereCondition, @@ -729,14 +740,11 @@ switch ($action) { ); break; case 'get_exercise_progress': - $sessionId = 0; - if (!empty($_GET['course_id']) && !empty($_GET['exercise_id'])) - { - $sessionId = intval($_GET['session_id']); - $courseId = intval($_GET['course_id']); - $exerciseId = intval($_GET['exercise_id']); - $answer = intval($_GET['answer']); - } + $sessionId = intval($_GET['session_id']); + $courseId = intval($_GET['course_id']); + $exerciseId = intval($_GET['exercise_id']); + $date_from = $_GET['date_from']; + $date_to = $_GET['date_to']; $columns = array( 'session', @@ -748,11 +756,12 @@ switch ($action) { 'time', 'question_id', 'question', + 'description', 'answer', - 'correct' + 'correct', ); - $result = SessionManager::get_exercise_progress($sessionId, $courseId, $exerciseId, $answer, + $result = Tracking::get_exercise_progress($sessionId, $courseId, $exerciseId, $date_from, $date_to, array( 'where' => $whereCondition, 'order' => "$sidx $sord", @@ -767,6 +776,7 @@ switch ($action) { $courseId = intval($_GET['course_id']); $course = api_get_course_info_by_id($courseId); } + /** * Add lessons of course * @@ -784,7 +794,7 @@ switch ($action) { } $columns[] = 'total'; - $result = SessionManager::get_session_lp_progress($sessionId, $courseId, + $result = SessionManager::get_session_lp_progress($sessionId, $courseId, $date_from, $date_to, array( 'where' => $whereCondition, 'order' => "$sidx $sord", @@ -801,6 +811,8 @@ switch ($action) { $sessionId = intval($_GET['session_id']); $courseId = intval($_GET['course_id']); $surveyId = intval($_GET['survey_id']); + $date_from = $_GET['date_from']; + $date_to = $_GET['date_to']; //$course = api_get_course_info_by_id($courseId); } /** @@ -819,7 +831,7 @@ switch ($action) { $columns[] = $question_id; } - $result = SessionManager::get_survey_overview($sessionId, $courseId, $surveyId, + $result = SessionManager::get_survey_overview($sessionId, $courseId, $surveyId, $date_from, $date_to, array( 'where' => $whereCondition, 'order' => "$sidx $sord", @@ -841,7 +853,7 @@ switch ($action) { 'homeworks', 'wikis', 'surveys', - //course description + //exercises 'course_description_progress', //exercises 'lessons_total' , @@ -878,7 +890,7 @@ switch ($action) { $sessionId = 0; if (!empty($_GET['course_id']) && !empty($_GET['session_id'])) { $sessionId = intval($_GET['session_id']); - $courseId = intval($_GET['course_id']); + $courseId = intval($_GET['course_id']); } $result = SessionManager::get_session_progress($sessionId, $courseId, array( @@ -897,6 +909,7 @@ switch ($action) { 'clicks', 'ip', 'timeLoggedIn', + 'session' ); $sessionId = 0; if (!empty($_GET['course_id']) && !empty($_GET['session_id'])) { @@ -1074,6 +1087,95 @@ switch ($action) { $result = $new_result; } break; + case 'get_exercise_grade': + $objExercise = new Exercise(); + $exercises = $objExercise->getExercisesByCouseSession($_GET['course_id'], $_GET['session_id']); + $cntExer = 4; + if (!empty($exercises)) { + $cntExer += count($exercises); + } + + $columns = array(); + //Get dynamic column names + $i = 1; + $column_names = array(); + foreach (range(1, $cntExer) as $cnt) { + switch ($cnt) { + case 1: + $columns[] = 'session'; + $column_names[] = get_lang('Section'); + break; + case 2: + $columns[] = 'username'; + $column_names[] = get_lang('Username'); + break; + case 3: + $columns[] = 'name'; + $column_names[] = get_lang('Name'); + break; + case $cntExer: + $columns[] = 'finalScore'; + $column_names[] = get_lang('FinalScore'); + break; + default: + $title = ""; + if (!empty($exercises[$cnt - 4]['title'])) { + $title = ucwords(strtolower(trim($exercises[$cnt - 4]['title']))); + } + $columns[] = 'exer' . $i; + $column_names[] = $title; + $i++; + break; + } + } + + $quizIds = array(); + if (!empty($exercises)) { + foreach($exercises as $exercise) { + $quizIds[] = $exercise['id']; + } + } + + $course = api_get_course_info_by_id($_GET['course_id']); + $listUserSess = CourseManager::get_student_list_from_course_code($course['code'], true, $_GET['session_id']); + + $usersId = array_keys($listUserSess); + + $users = UserManager::get_user_list_by_ids($usersId, null, "lastname, firstname", "$start , $limit"); + $exeResults = $objExercise->getExerciseAndResult($_GET['course_id'], $_GET['session_id'], $quizIds); + + $arrGrade = array(); + foreach ($exeResults as $exeResult) { + $arrGrade[$exeResult['exe_user_id']][$exeResult['exe_exo_id']] = $exeResult['exe_result']; + } + + $result = array(); + $i = 0; + foreach ($users as $user) { + $sessionInfo = SessionManager::fetch($listUserSess[$user['user_id']]['id_session']); + $result[$i]['session'] = $sessionInfo['name']; + $result[$i]['username'] = $user['username']; + $result[$i]['name'] = $user['lastname'] . " " . $user['firstname']; + $j = 1; + $finalScore = 0; + foreach ($quizIds as $quizID) { + $grade = ""; + if (!empty($arrGrade [$user['user_id']][$quizID]) || $arrGrade [$user['user_id']][$quizID] == 0) { + $finalScore += $grade = $arrGrade [$user['user_id']][$quizID]; + } + $result[$i]['exer' . $j] = $grade; + $j++; + } + + if ($finalScore > 20) { + $finalScore = 20; + } + + $result[$i]['finalScore'] = number_format($finalScore, 2); + + $i++; + } + break; case 'get_extra_field_options': $obj = new ExtraFieldOption($type); $columns = array('option_display_text', 'option_value', 'option_order'); @@ -1146,11 +1248,12 @@ $allowed_actions = array( 'get_grade_models', 'get_event_email_template', 'get_user_skill_ranking', - //'get_extra_fields', - //'get_extra_field_options', + 'get_extra_fields', + 'get_extra_field_options', //'get_course_exercise_medias', 'get_user_course_report', - 'get_user_course_report_resumed' + 'get_user_course_report_resumed', + 'get_exercise_grade' ); //5. Creating an obj to return a json @@ -1183,7 +1286,13 @@ if (in_array($action, $allowed_actions)) { case 'xls': //TODO add date if exists $file_name = (!empty($action)) ? $action : 'company_report'; - Export::export_table_xls($array, $file_name); + require_once api_get_path(LIBRARY_PATH).'browser/Browser.php'; + $browser = new Browser(); + if ($browser->getPlatform() == Browser::PLATFORM_WINDOWS) { + Export::export_table_xls_html($array, $file_name, 'ISO-8859-15'); + } else { + Export::export_table_xls_html($array, $file_name); + } break; case 'csv': default: @@ -1199,7 +1308,6 @@ if (in_array($action, $allowed_actions)) { if (!empty($result)) { foreach ($result as $row) { - //print_r($row); // if results tab give not id, set id to $i otherwise id="null" for all of the jqgrid - ref #4235 if (!isset($row['id']) || isset($row['id']) && $row['id'] == '') { $response->rows[$i]['id']= $i; diff --git a/main/inc/ajax/session.ajax.php b/main/inc/ajax/session.ajax.php index 160e6272db..bdf8ff7e1b 100644 --- a/main/inc/ajax/session.ajax.php +++ b/main/inc/ajax/session.ajax.php @@ -47,9 +47,33 @@ switch ($action) { } } break; + case 'search_session_all': + if (api_is_platform_admin()) { + $results = SessionManager::get_sessions_list(array('s.name LIKE' => "%".$_REQUEST['q']."%", 'c.id ='=>$_REQUEST['course_id'])); + $results2 = array(); + if (!empty($results)) { + foreach ($results as $item) { + $item2 = array(); + foreach ($item as $id => $internal) { + if ($id == 'id') { + $item2[$id] = $internal; + } + if ($id == 'name') { + $item2['text'] = $internal; + } + } + $results2[] = $item2; + } + $results2[] = array('T', 'text' => 'TODOS', 'id' => 'T'); + echo json_encode($results2); + } else { + echo json_encode(array(array('T', 'text' => 'TODOS', 'id' => 'T'))); + } + } + break; case 'search_session_by_course': if (api_is_platform_admin()) { - $results = SessionManager::get_sessions_list(array('s.name LIKE' => "%".$_REQUEST['q']."%")); + $results = SessionManager::get_sessions_list(array('s.name LIKE' => "%".$_REQUEST['q']."%", 'c.id ='=>$_REQUEST['course_id'])); $results2 = array(); if (!empty($results)) { foreach ($results as $item) { @@ -64,9 +88,10 @@ switch ($action) { } $results2[] = $item2; } + $results2[] = array('T', 'text' => 'TODOS', 'id' => 'T'); echo json_encode($results2); } else { - echo json_encode(array()); + echo json_encode(array(array('T', 'text' => 'TODOS', 'id' => 'T'))); } } break; diff --git a/main/inc/global_error_message.inc.php b/main/inc/global_error_message.inc.php index a2f95683b0..2af1610cf9 100644 --- a/main/inc/global_error_message.inc.php +++ b/main/inc/global_error_message.inc.php @@ -50,7 +50,7 @@ $TechnicalIssuesDescription = 'This portal is currently experiencing technical i if (is_int($global_error_code) && $global_error_code > 0) { - $theme = 'chamilo/'; + $theme = 'chamilo_red_utp/'; $css_path = 'main/css/'; $css_file = $css_path.$theme.'default.css'; $bootstrap_file = $css_path.'bootstrap.css'; diff --git a/main/inc/introductionSection.inc.php b/main/inc/introductionSection.inc.php index 27943ac97a..43c255bff4 100644 --- a/main/inc/introductionSection.inc.php +++ b/main/inc/introductionSection.inc.php @@ -280,3 +280,9 @@ if ($intro_dispCommand) { } } $introduction_section .= ''; + +$browser = api_get_navigator(); + +if (strpos($introduction_section, ' 2"; + + $joinSession = ""; + //Session creation date + if (!empty($date_from) && !empty($date_to)) { + $joinSession = "INNER JOIN " . Database::get_main_table(TABLE_MAIN_SESSION) . " s"; + } + + $sql_query = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER)." scu + $joinSession + WHERE scu.course_code = '$course_code' AND scu.status <> 2"; + + if (!empty($date_from) && !empty($date_to)) { + $date_from = Database::escape_string($date_from); + $date_to = Database::escape_string($date_to); + $sql_query .= " AND s.date_start >= '$date_from' AND s.date_end <= '$date_to'"; + } + if ($session_id != 0) { - $sql_query .= ' AND id_session = '.$session_id; + $sql_query .= ' AND scu.id_session = '.$session_id; } + $rs = Database::query($sql_query); while($student = Database::fetch_array($rs)) { $students[$student['id_user']] = $student; diff --git a/main/inc/lib/database.constants.inc.php b/main/inc/lib/database.constants.inc.php index 2093bcaf62..7a5e68c123 100644 --- a/main/inc/lib/database.constants.inc.php +++ b/main/inc/lib/database.constants.inc.php @@ -62,6 +62,10 @@ define('TABLE_MAIN_USER_FIELD', 'user_field'); define('TABLE_MAIN_USER_FIELD_OPTIONS', 'user_field_options'); define('TABLE_MAIN_USER_FIELD_VALUES', 'user_field_values'); +define('TABLE_MAIN_LP_FIELD', 'lp_field'); +define('TABLE_MAIN_LP_FIELD_OPTIONS', 'lp_field_options'); +define('TABLE_MAIN_LP_FIELD_VALUES', 'lp_field_values'); + //User tags define('TABLE_MAIN_TAG', 'tag'); define('TABLE_MAIN_USER_REL_TAG', 'user_rel_tag'); diff --git a/main/inc/lib/display.lib.php b/main/inc/lib/display.lib.php index 507adb633d..2e49e34b0d 100644 --- a/main/inc/lib/display.lib.php +++ b/main/inc/lib/display.lib.php @@ -95,9 +95,6 @@ class Display if (!empty($page_header)) { self::$global_template->assign('header', $page_header); } - - self::$global_template->assign('course_code', api_get_course_id()); - echo self::$global_template->show_header_template(); } @@ -935,15 +932,17 @@ class Display * This function need to be in the ready jquery function example --> $(function() { } * In order to work this function needs the Display::grid_html function with the same div id * - * @param string div id - * @param string url where the jqgrid will ask for data (if datatype = json) - * @param array Visible columns (you should use get_lang). An array in which we place the names of the columns. + * @param string $div_id div id + * @param string $url url where the jqgrid will ask for data (if datatype = json) + * @param array $column_names Visible columns (you should use get_lang). An array in which we place the names of the columns. * This is the text that appears in the head of the grid (Header layer). * Example: colname {name:'date', index:'date', width:120, align:'right'}, - * @param array the column model : Array which describes the parameters of the columns.This is the most important part of the grid. + * @param array $column_model the column model : Array which describes the parameters of the columns.This is the most important part of the grid. * For a full description of all valid values see colModel API. See the url above. - * @param array extra parameters - * @param array data that will be loaded + * @param array $extra_params extra parameters + * @param array $data data that will be loaded + * @param string $formatter A string that will be appended to the JSON returned + * @param bool $fixed_width not implemented yet * @return string the js code * */ @@ -955,7 +954,7 @@ class Display $extra_params, $data = array(), $formatter = '', - $width_fix = false + $fixed_width = false ) { $obj = new stdClass(); $obj->first = 'first'; @@ -1022,7 +1021,10 @@ class Display // Adding extra params if (!empty($extra_params)) { foreach ($extra_params as $key => $element) { - $obj->$key = $element; + // the groupHeaders key gets a special treatment + if ($key != 'groupHeaders') { + $obj->$key = $element; + } } } @@ -1040,7 +1042,8 @@ class Display $json_encode = json_encode($obj); if (!empty($data)) { - //Converts the "data":"js_variable" to "data":js_variable othersiwe it will not work + //Converts the "data":"js_variable" to "data":js_variable, + // otherwise it will not work $json_encode = str_replace('"data":"'.$data_var.'"', '"data":'.$data_var.'', $json_encode); } @@ -1055,9 +1058,27 @@ class Display // Creating the jqgrid element. $json .= '$("#'.$div_id.'").jqGrid({'; //$json .= $beforeSelectRow; + $json .= $json_encode; + $json .= '});'; + //Grouping headers option + if (isset($extra_params['groupHeaders'])) { + $groups = ''; + foreach ($extra_params['groupHeaders'] as $group) { + //{ "startColumnName" : "courses", "numberOfColumns" : 1, "titleText" : "Order Info" }, + $groups .= '{ "startColumnName" : "' . $group['startColumnName'] . '", "numberOfColumns" : ' . $group['numberOfColumns'] . ', "titleText" : "' . $group['titleText'] . '" },'; + + } + $json .= '$("#'.$div_id.'").jqGrid("setGroupHeaders", { + "useColSpanStyle" : false, + "groupHeaders" : [ + ' . $groups . ' + ] + });'; + } + $all_text = addslashes(get_lang('All')); $json .= '$("'.$obj->pager.' option[value='.$all_value.']").text("'.$all_text.'");'; $json.= "\n"; diff --git a/main/inc/lib/document.lib.php b/main/inc/lib/document.lib.php index 1071786874..cc1261aae0 100644 --- a/main/inc/lib/document.lib.php +++ b/main/inc/lib/document.lib.php @@ -2695,7 +2695,7 @@ class DocumentManager $session_condition = " AND props.id_session='" . $session_id . "' "; } - $sql = "SELECT SUM(size) FROM " . $TABLE_ITEMPROPERTY . " AS props, " . $TABLE_DOCUMENT . " AS docs + $sql = "SELECT coalesce(docs.size, 0), docs.path, docs.filetype FROM " . $TABLE_ITEMPROPERTY . " AS props, " . $TABLE_DOCUMENT . " AS docs WHERE props.c_id = $course_id AND docs.c_id = $course_id AND docs.id = props.ref AND @@ -2703,15 +2703,22 @@ class DocumentManager props.visibility <> 2 $group_condition $session_condition + ORDER BY docs.id "; $result = Database::query($sql); - - if ($result && Database::num_rows($result) != 0) { - $row = Database::fetch_row($result); - return $row[0]; - } else { - return 0; + + //Not count the same file more than once + //if there is more than once just take the last + $docsSize = array(); + while ($row = Database::fetch_row($result)) { + $md5Key = md5($row[1]); + if (!empty($row[2]) && $row[2] == 'folder') { + $docsSize[$md5Key] = 4096; + } else { + $docsSize[$md5Key] = $row[0]; + } } + return array_sum($docsSize); } /** diff --git a/main/inc/lib/events.lib.inc.php b/main/inc/lib/events.lib.inc.php index b6a39d1d93..918e4ca158 100644 --- a/main/inc/lib/events.lib.inc.php +++ b/main/inc/lib/events.lib.inc.php @@ -1472,7 +1472,7 @@ function delete_attempt($exe_id, $user_id, $course_code, $session_id, $question_ * @param int $user_id * @param string $course_code * @param int $question_id - * @todo add session_id for 1.10 + * @todo add session_id for 10 */ function delete_attempt_hotspot($exe_id, $user_id, $course_code, $session_id = 0, $question_id) { $table_track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT); @@ -1504,11 +1504,32 @@ function event_course_login($course_code, $user_id, $session_id) { $course_code = Database::escape_string($course_code); $user_id = intval($user_id); $session_id = intval($session_id); + $session_lifetime = 3600; - $sql = "INSERT INTO $course_tracking_table(course_code, user_id, login_course_date, logout_course_date, counter, session_id) - VALUES('".$course_code."', '".$user_id."', '$time', '$time', '1', '".$session_id."')"; - Database::query($sql); + //We select the last record for the current course in the course tracking table + $sql = "SELECT course_access_id FROM $course_tracking_table + WHERE user_id = $user_id AND + course_code = '$course_code' AND + session_id = $session_id AND + login_course_date > '$time' - INTERVAL $session_lifetime SECOND + ORDER BY login_course_date DESC LIMIT 0,1"; + $result = Database::query($sql); + //error_log(preg_replace('/\s+/',' ',$sql)); + + if (Database::num_rows($result) > 0) { + $i_course_access_id = Database::result($result,0,0); + //We update the course tracking table + $sql = "UPDATE $course_tracking_table SET logout_course_date = '$time', counter = counter+1 + WHERE course_access_id = ".intval($i_course_access_id)." AND session_id = ".$session_id; + Database::query($sql); + //error_log(preg_replace('/\s+/',' ',$sql)); + } else { + $sql="INSERT INTO $course_tracking_table (course_code, user_id, login_course_date, logout_course_date, counter, session_id)" . + "VALUES('".$course_code."', '".$user_id."', '$time', '$time', '1','".$session_id."')"; + Database::query($sql); + //error_log(preg_replace('/\s+/',' ',$sql)); + } // Course catalog stats modifications see #4191 CourseManager::update_course_ranking(null, null, null, null, true, false); } diff --git a/main/inc/lib/export.lib.inc.php b/main/inc/lib/export.lib.inc.php index 8f11a2f5dc..3dfb4a966e 100644 --- a/main/inc/lib/export.lib.inc.php +++ b/main/inc/lib/export.lib.inc.php @@ -68,7 +68,7 @@ class Export $file->put($row); } $file->close(); - DocumentManager::file_send_for_download($path, true, $filename.'.csv'); + DocumentManager::file_send_for_download($path, false, $filename.'.csv'); unlink($path); exit; } @@ -78,17 +78,50 @@ class Export * @param array $data * @param string $filename */ - public static function export_table_xls($data, $filename = 'export') + public static function export_table_xls($data, $filename = 'export', $encoding = 'utf-8') { $file = api_get_path(SYS_ARCHIVE_PATH).uniqid('').'.xls'; $handle = fopen($file, 'a+'); + $systemEncoding = api_get_system_encoding(); foreach ($data as $row) { - fwrite($handle, implode("\t", $row)."\n"); + $string = implode("\t", $row); + if ($encoding != 'utf-8') { + $string = api_convert_encoding($string, $encoding, $systemEncoding); + } + fwrite($handle, $string."\n"); } fclose($handle); - DocumentManager::file_send_for_download($file, true, $filename.'.xls'); + DocumentManager::file_send_for_download($file, false, $filename.'.xls'); } + /** + * Export tabular data to XLS-file (as html table) + * @param array $data + * @param string $filename + */ + public static function export_table_xls_html($data, $filename = 'export', $encoding = 'utf-8') + { + $file = api_get_path(SYS_ARCHIVE_PATH).uniqid('').'.xls'; + $handle = fopen($file, 'a+'); + $systemEncoding = api_get_system_encoding(); + fwrite($handle, ''); + foreach ($data as $id => $row) { + foreach ($row as $id2 => $row2) { + $data[$id][$id2] = api_htmlentities($row2); + } + } + foreach ($data as $row) { + $string = implode("'; + if ($encoding != 'utf-8') { + $string = api_convert_encoding($string, $encoding, $systemEncoding); + } + fwrite($handle, $string."\n"); + } + fwrite($handle, '
", $row); + $string = '
' . $string . '
'); + fclose($handle); + DocumentManager::file_send_for_download($file, false, $filename.'.xls'); + } /** * Export tabular data to XML-file * @param array Simple array of data to put in XML diff --git a/main/inc/lib/extra_field.lib.php b/main/inc/lib/extra_field.lib.php new file mode 100644 index 0000000000..e97011f348 --- /dev/null +++ b/main/inc/lib/extra_field.lib.php @@ -0,0 +1,1648 @@ + '=', //equal + 'ne' => '<>', //not equal + 'lt' => '<', //less than + 'le' => '<=', //less than or equal + 'gt' => '>', //greater than + 'ge' => '>=', //greater than or equal + 'bw' => 'LIKE', //begins with + 'bn' => 'NOT LIKE', //doesn't begin with + 'in' => 'LIKE', //is in + 'ni' => 'NOT LIKE', //is not in + 'ew' => 'LIKE', //ends with + 'en' => 'NOT LIKE', //doesn't end with + 'cn' => 'LIKE', //contains + 'nc' => 'NOT LIKE' //doesn't contain + ); + + const FIELD_TYPE_TEXT = 1; + const FIELD_TYPE_TEXTAREA = 2; + const FIELD_TYPE_RADIO = 3; + const FIELD_TYPE_SELECT = 4; + const FIELD_TYPE_SELECT_MULTIPLE = 5; + const FIELD_TYPE_DATE = 6; + const FIELD_TYPE_DATETIME = 7; + const FIELD_TYPE_DOUBLE_SELECT = 8; + const FIELD_TYPE_DIVIDER = 9; + const FIELD_TYPE_TAG = 10; + const FIELD_TYPE_TIMEZONE = 11; + const FIELD_TYPE_SOCIAL_PROFILE = 12; + const FIELD_TYPE_CHECKBOX = 13; + + public $type = 'user'; //or session or course + public $handler_id = 'user_id'; + public $pageName; + public $pageUrl; + + /** + * @param string $type + */ + public function __construct($type) + { + $this->type = $type; + switch ($this->type) { + case 'course': + $this->table_field_options = Database::get_main_table(TABLE_MAIN_COURSE_FIELD_OPTIONS); + $this->table_field_values = Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES); + + //Used for the model + $this->table = Database::get_main_table(TABLE_MAIN_COURSE_FIELD); + $this->handler_id = 'course_code'; + $this->handlerEntityId = 'courseCode'; + $this->primaryKey = 'id'; + break; + case 'user': + $this->table_field_options = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS); + $this->table_field_values = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES); + + //Used for the model + $this->table = Database::get_main_table(TABLE_MAIN_USER_FIELD); + $this->handler_id = 'user_id'; + $this->handlerEntityId = 'userId'; + $this->primaryKey = 'user_id'; + break; + case 'session': + $this->table_field_options = Database::get_main_table(TABLE_MAIN_SESSION_FIELD_OPTIONS); + $this->table_field_values = Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES); + + //Used for the model + $this->table = Database::get_main_table(TABLE_MAIN_SESSION_FIELD); + $this->handler_id = 'session_id'; + $this->handlerEntityId = 'sessionId'; + $this->primaryKey = 'id'; + break; + case 'question': + $this->table_field_options = Database::get_main_table(TABLE_MAIN_QUESTION_FIELD_OPTIONS); + $this->table_field_values = Database::get_main_table(TABLE_MAIN_QUESTION_FIELD_VALUES); + + //Used for the model + $this->table = Database::get_main_table(TABLE_MAIN_QUESTION_FIELD); + $this->handler_id = 'question_id'; + $this->handlerEntityId = 'questionId'; + $this->primaryKey = 'iid'; + break; + case 'lp': + $this->table_field_options = Database::get_main_table(TABLE_MAIN_LP_FIELD_OPTIONS); + $this->table_field_values = Database::get_main_table(TABLE_MAIN_LP_FIELD_VALUES); + + // Used for the model + $this->table = Database::get_main_table(TABLE_MAIN_LP_FIELD); + $this->handler_id = 'lp_id'; + $this->handlerEntityId = 'lpId'; + $this->primaryKey = 'id'; + break; + } + $this->pageUrl = 'extra_fields.php?type='.$this->type; + // Example QuestionFields + $this->pageName = get_lang(ucwords($this->type).'Fields'); + } + + static function getValidExtraFieldTypes() + { + return array( + 'user', + 'course', + 'session', + 'question', + 'lp' + ); + } + + public function get_count() + { + $row = Database::select('count(*) as count', $this->table, array(), 'first'); + + return $row['count']; + } + + public function get_all($where_conditions = array(), $order_field_options_by = null) + { + $options = Database::select( + '*', + $this->table, + array('where' => $where_conditions, 'order' => 'field_order ASC') + ); + + $field_option = new ExtraFieldOption($this->type); + if (!empty($options)) { + foreach ($options as &$option) { + $option['options'] = $field_option->get_field_options_by_field( + $option['id'], + false, + $order_field_options_by + ); + } + } + + return $options; + } + + + public function get_handler_field_info_by_field_variable($field_variable) + { + $field_variable = Database::escape_string($field_variable); + $sql_field = "SELECT * FROM {$this->table} WHERE field_variable = '$field_variable'"; + $result = Database::query($sql_field); + if (Database::num_rows($result)) { + $r_field = Database::fetch_array($result, 'ASSOC'); + + return $r_field; + } else { + return false; + } + } + + public function get_max_field_order() + { + $sql = "SELECT MAX(field_order) FROM {$this->table}"; + $res = Database::query($sql); + + $order = 0; + if (Database::num_rows($res) > 0) { + $row = Database::fetch_row($res); + $order = $row[0] + 1; + } + + return $order; + } + + public static function get_extra_fields_by_handler($handler) + { + $types = array(); + $types[self::FIELD_TYPE_TEXT] = get_lang('FieldTypeText'); + $types[self::FIELD_TYPE_TEXTAREA] = get_lang('FieldTypeTextarea'); + $types[self::FIELD_TYPE_RADIO] = get_lang('FieldTypeRadio'); + $types[self::FIELD_TYPE_SELECT] = get_lang('FieldTypeSelect'); + $types[self::FIELD_TYPE_SELECT_MULTIPLE] = get_lang('FieldTypeSelectMultiple'); + $types[self::FIELD_TYPE_DATE] = get_lang('FieldTypeDate'); + $types[self::FIELD_TYPE_DATETIME] = get_lang('FieldTypeDatetime'); + $types[self::FIELD_TYPE_DOUBLE_SELECT] = get_lang('FieldTypeDoubleSelect'); + $types[self::FIELD_TYPE_DIVIDER] = get_lang('FieldTypeDivider'); + $types[self::FIELD_TYPE_TAG] = get_lang('FieldTypeTag'); + $types[self::FIELD_TYPE_TIMEZONE] = get_lang('FieldTypeTimezone'); + $types[self::FIELD_TYPE_SOCIAL_PROFILE] = get_lang('FieldTypeSocialProfile'); + + switch ($handler) { + case 'course': + case 'session': + case 'user': + break; + } + + return $types; + } + + /** + * Add elements to a form + * + * @param FormValidator $form + * @param int $item_id + * @return array|bool + */ + public function addElements($form, $item_id = null) + { + if (empty($form)) { + return false; + } + + $extra_data = false; + if (!empty($item_id)) { + $extra_data = self::get_handler_extra_data($item_id); + if ($form) { + $form->setDefaults($extra_data); + } + } + + $extra_fields = $this->get_all(null, 'option_order'); + $extra = $this->set_extra_fields_in_form( + $form, + $extra_data, + $this->type.'_field', + false, + false, + $extra_fields, + $item_id + ); + + return $extra; + } + + /** + * + * @param int $item_id (session_id, question_id, course id) + * @return array + */ + public function get_handler_extra_data($item_id) + { + if (empty($item_id)) { + return array(); + } + + $extra_data = array(); + $fields = self::get_all(); + $field_values = new ExtraFieldValue($this->type); + + if (!empty($fields) > 0) { + foreach ($fields as $field) { + $field_value = $field_values->get_values_by_handler_and_field_id($item_id, $field['id']); + if ($field_value) { + $field_value = $field_value['field_value']; + + switch ($field['field_type']) { + case ExtraField::FIELD_TYPE_DOUBLE_SELECT: + $selected_options = explode( + '::', + $field_value + ); + $extra_data['extra_'.$field['field_variable']]['extra_'.$field['field_variable']] = $selected_options[0]; + $extra_data['extra_'.$field['field_variable']]['extra_'.$field['field_variable'].'_second'] = $selected_options[1]; + break; + case ExtraField::FIELD_TYPE_SELECT_MULTIPLE: + $field_value = explode(';', $field_value); + case ExtraField::FIELD_TYPE_RADIO: + $extra_data['extra_'.$field['field_variable']]['extra_'.$field['field_variable']] = $field_value; + break; + default: + $extra_data['extra_'.$field['field_variable']] = $field_value; + break; + } + } else { + // Set default values + if (isset($field['field_default_value']) && !empty($field['field_default_value'])) { + $extra_data['extra_'.$field['field_variable']] = $field['field_default_value']; + } + } + } + } + + return $extra_data; + } + + public function get_all_extra_field_by_type($field_type) + { + // all the information of the field + $sql = "SELECT * FROM {$this->table} WHERE field_type='".Database::escape_string($field_type)."'"; + $result = Database::query($sql); + $return = array(); + while ($row = Database::fetch_array($result)) { + $return[] = $row['id']; + } + + return $return; + } + + + public function get_field_types() + { + return self::get_extra_fields_by_handler($this->type); + } + + public function get_field_type_by_id($id) + { + $types = self::get_field_types(); + if (isset($types[$id])) { + return $types[$id]; + } + + return null; + } + + /** + * Converts a string like this: + * France:Paris;Bretagne;Marseilles;Lyon|Belgique:Bruxelles;Namur;Liège;Bruges|Peru:Lima;Piura; + * into + * array('France' => array('Paris', 'Bregtane', 'Marseilles'), 'Belgique' => array('Namur', 'Liège', etc + * @param string $string + * @return array + */ + static function extra_field_double_select_convert_string_to_array($string) + { + $options = explode('|', $string); + $options_parsed = array(); + $id = 0; + if (!empty($options)) { + foreach ($options as $sub_options) { + $options = explode(':', $sub_options); + $sub_sub_options = explode(';', $options[1]); + $options_parsed[$id] = array('label' => $options[0], 'options' => $sub_sub_options); + $id++; + } + } + + return $options_parsed; + } + + static function extra_field_double_select_convert_array_to_ordered_array($options) + { + $options_parsed = array(); + if (!empty($options)) { + foreach ($options as $option) { + if ($option['option_value'] == 0) { + $options_parsed[$option['id']][] = $option; + } else { + $options_parsed[$option['option_value']][] = $option; + } + } + } + + return $options_parsed; + } + + /** + * @param array options the result of the get_field_options_by_field() array + */ + static function extra_field_double_select_convert_array_to_string($options) + { + $string = null; + $options_parsed = self::extra_field_double_select_convert_array_to_ordered_array($options); + + if (!empty($options_parsed)) { + foreach ($options_parsed as $option) { + foreach ($option as $key => $item) { + $string .= $item['option_display_text']; + if ($key == 0) { + $string .= ':'; + } else { + if (isset($option[$key + 1])) { + $string .= ';'; + } + } + } + $string .= '|'; + } + } + + if (!empty($string)) { + $string = substr($string, 0, strlen($string) - 1); + } + + return $string; + } + + /** + * @param array $params + * @return array + */ + public function clean_parameters($params) + { + if (!isset($params['field_variable']) || empty($params['field_variable'])) { + $params['field_variable'] = trim(strtolower(str_replace(" ", "_", $params['field_display_text']))); + } + + if (!isset($params['field_order'])) { + $max_order = self::get_max_field_order(); + $params['field_order'] = $max_order; + } + + return $params; + } + + /** + * @param array $params + * @param bool $show_query + * @return bool + */ + public function save($params, $show_query = false) + { + $session_field_info = self::get_handler_field_info_by_field_variable($params['field_variable']); + $params = self::clean_parameters($params); + if ($session_field_info) { + return $session_field_info['id']; + } else { + if (!isset($params['tms'])) { + $params['tms'] = api_get_utc_datetime(); + } + $id = parent::save($params, $show_query); + if ($id) { + $session_field_option = new ExtraFieldOption($this->type); + $params['field_id'] = $id; + $session_field_option->save($params); + } + + return $id; + } + } + + + public function update($params) + { + $params = self::clean_parameters($params); + if (isset($params['id'])) { + $field_option = new ExtraFieldOption($this->type); + $params['field_id'] = $params['id']; + $field_option->save($params); + } + parent::update($params); + } + + public function delete($id) + { + parent::delete($id); + $field_option = new ExtraFieldOption($this->type); + $field_option->delete_all_options_by_field_id($id); + + $session_field_values = new ExtraFieldValue($this->type); + $session_field_values->delete_all_values_by_field_id($id); + } + + /** + * @param FormValidator $form + * @param array $extraData + * @param string $form_name + * @param bool $admin_permissions + * @param int $user_id + * @param array $extra + * @param int $itemId + * + * @return array + */ + public function set_extra_fields_in_form( + $form, + $extraData, + $form_name, + $admin_permissions = false, + $user_id = null, + $extra = array(), + $itemId = null + ) { + $user_id = intval($user_id); + $type = $this->type; + + // User extra fields + if ($type == 'user') { + $extra = UserManager::get_extra_fields(0, 50, 5, 'ASC', true, null, true); + } + + $jquery_ready_content = null; + + if (!empty($extra)) { + foreach ($extra as $field_details) { + + // Getting default value id if is set + $defaultValueId = null; + if (isset($field_details['options']) && !empty($field_details['options'])) { + $valueToFind = null; + if (isset($field_details['field_default_value'])) { + $valueToFind = $field_details['field_default_value']; + } + // If a value is found we override the default value + if (isset($extraData['extra_'.$field_details['field_variable']])) { + $valueToFind = $extraData['extra_'.$field_details['field_variable']]; + } + + foreach ($field_details['options'] as $option) { + if ($option['option_value'] == $valueToFind) { + $defaultValueId = $option['id']; + } + } + } + + if (!$admin_permissions) { + if ($field_details['field_visible'] == 0) { + continue; + } + } + + switch ($field_details['field_type']) { + case ExtraField::FIELD_TYPE_TEXT: + $form->addElement( + 'text', + 'extra_'.$field_details['field_variable'], + $field_details['field_display_text'], + array('class' => 'span4') + ); + $form->applyFilter('extra_'.$field_details['field_variable'], 'stripslashes'); + $form->applyFilter('extra_'.$field_details['field_variable'], 'trim'); + if (!$admin_permissions) { + if ($field_details['field_visible'] == 0) { + $form->freeze( + 'extra_'.$field_details['field_variable'] + ); + } + } + break; + case ExtraField::FIELD_TYPE_TEXTAREA: + $form->add_html_editor( + 'extra_'.$field_details['field_variable'], + $field_details['field_display_text'], + false, + false, + array('ToolbarSet' => 'Profile', 'Width' => '100%', 'Height' => '130') + ); + $form->applyFilter('extra_'.$field_details['field_variable'], 'stripslashes'); + $form->applyFilter('extra_'.$field_details['field_variable'], 'trim'); + if (!$admin_permissions) { + if ($field_details['field_visible'] == 0) { + $form->freeze( + 'extra_'.$field_details['field_variable'] + ); + } + } + break; + case ExtraField::FIELD_TYPE_RADIO: + $group = array(); + if (isset($field_details['options']) && !empty($field_details['options'])) { + foreach ($field_details['options'] as $option_details) { + $options[$option_details['option_value']] = $option_details['option_display_text']; + $group[] = $form->createElement( + 'radio', + 'extra_'.$field_details['field_variable'], + $option_details['option_value'], + $option_details['option_display_text'].'
', + $option_details['option_value'] + ); + } + } + $form->addGroup( + $group, + 'extra_'.$field_details['field_variable'], + $field_details['field_display_text'], + '' + ); + if (!$admin_permissions) { + if ($field_details['field_visible'] == 0) { + $form->freeze( + 'extra_'.$field_details['field_variable'] + ); + } + } + break; + case ExtraField::FIELD_TYPE_CHECKBOX: + $group = array(); + if (isset($field_details['options']) && !empty($field_details['options'])) { + foreach ($field_details['options'] as $option_details) { + $options[$option_details['option_value']] = $option_details['option_display_text']; + $group[] = $form->createElement( + 'checkbox', + 'extra_'.$field_details['field_variable'], + $option_details['option_value'], + $option_details['option_display_text'].'
', + $option_details['option_value'] + ); + } + } else { + // We assume that is a switch on/off with 1 and 0 as values + $group[] = $form->createElement( + 'checkbox', + 'extra_'.$field_details['field_variable'], + null, + //$field_details['field_display_text'].'
', + 'Yes
', + null + ); + } + $form->addGroup( + $group, + 'extra_'.$field_details['field_variable'], + $field_details['field_display_text'], + '' + ); + if (!$admin_permissions) { + if ($field_details['field_visible'] == 0) { + $form->freeze( + 'extra_'.$field_details['field_variable'] + ); + } + } + break; + case ExtraField::FIELD_TYPE_SELECT: + $get_lang_variables = false; + if (in_array( + $field_details['field_variable'], + array('mail_notify_message', 'mail_notify_invitation', 'mail_notify_group_message') + ) + ) { + $get_lang_variables = true; + } + + // Get extra field workflow + $userInfo = api_get_user_info(); + + $addOptions = array(); + + global $app; + $optionsExists = $app['orm.em']->getRepository('ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption')-> + findOneBy(array('fieldId' => $field_details['id'])); + + if ($optionsExists) { + if (isset($userInfo['status']) && !empty($userInfo['status'])) { + + $fieldWorkFlow = $app['orm.em']->getRepository('ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption') + ->findBy( + array( + 'fieldId' => $field_details['id'], + 'relatedFieldOptionId' => $defaultValueId, + 'roleId' => $userInfo['status'] + ) + ); + foreach ($fieldWorkFlow as $item) { + $addOptions[] = $item->getFieldOptionId(); + } + } + } + + $options = array(); + if (empty($defaultValueId)) { + $options[''] = get_lang('SelectAnOption'); + } + + $optionList = array(); + if (!empty($field_details['options'])) { + foreach ($field_details['options'] as $option_details) { + $optionList[$option_details['id']] = $option_details; + if ($get_lang_variables) { + $options[$option_details['option_value']] = get_lang($option_details['option_display_text']); + } else { + if ($optionsExists) { + // Adding always the default value + if ($option_details['id'] == $defaultValueId) { + $options[$option_details['option_value']] = $option_details['option_display_text']; + } else { + if (isset($addOptions) && !empty($addOptions)) { + // Parsing filters + if (in_array($option_details['id'], $addOptions)) { + $options[$option_details['option_value']] = $option_details['option_display_text']; + } + } + } + } else { + // Normal behaviour + $options[$option_details['option_value']] = $option_details['option_display_text']; + } + } + } + + if (isset($optionList[$defaultValueId])) { + + if (isset($optionList[$defaultValueId]['option_value']) && $optionList[$defaultValueId]['option_value'] == 'aprobada') { + if (api_is_question_manager() == false) { + $form->freeze(); + } + } + } + + // Setting priority message + if (isset($optionList[$defaultValueId]) && isset($optionList[$defaultValueId]['priority'])) { + + if (!empty($optionList[$defaultValueId]['priority'])) { + $priorityId = $optionList[$defaultValueId]['priority']; + $option = new ExtraFieldOption($this->type); + $messageType = $option->getPriorityMessageType($priorityId); + $form->addElement('label', null, Display::return_message($optionList[$defaultValueId]['priority_message'], $messageType)); + } + } + } + + if ($get_lang_variables) { + $field_details['field_display_text'] = get_lang($field_details['field_display_text']); + } + + // chzn-select doesn't work for sessions?? + $form->addElement( + 'select', + 'extra_'.$field_details['field_variable'], + $field_details['field_display_text'], + $options, + array('id' => 'extra_'.$field_details['field_variable']) + ); + + if ($optionsExists && $field_details['field_loggeable'] && !empty($defaultValueId)) { + + $form->addElement( + 'textarea', + 'extra_'.$field_details['field_variable'].'_comment', + $field_details['field_display_text'].' '.get_lang('Comment') + ); + + $extraFieldValue = new ExtraFieldValue($this->type); + $repo = $app['orm.em']->getRepository($extraFieldValue->entityName); + $repoLog = $app['orm.em']->getRepository('Gedmo\Loggable\Entity\LogEntry'); + $newEntity = $repo->findOneBy( + array( + $this->handlerEntityId => $itemId, + 'fieldId' => $field_details['id'] + ) + ); + // @todo move this in a function inside the class + if ($newEntity) { + $logs = $repoLog->getLogEntries($newEntity); + if (!empty($logs)) { + $html = ''.get_lang('LatestChanges').'

'; + + $table = new HTML_Table(array('class' => 'data_table')); + $table->setHeaderContents(0, 0, get_lang('Value')); + $table->setHeaderContents(0, 1, get_lang('Comment')); + $table->setHeaderContents(0, 2, get_lang('ModifyDate')); + $table->setHeaderContents(0, 3, get_lang('Username')); + $row = 1; + foreach ($logs as $log) { + $column = 0; + $data = $log->getData(); + $fieldValue = isset($data['fieldValue']) ? $data['fieldValue'] : null; + $comment = isset($data['comment']) ? $data['comment'] : null; + + $table->setCellContents($row, $column, $fieldValue); + $column++; + $table->setCellContents($row, $column, $comment); + $column++; + $table->setCellContents($row, $column, api_get_local_time($log->getLoggedAt()->format('Y-m-d H:i:s'))); + $column++; + $table->setCellContents($row, $column, $log->getUsername()); + $row++; + } + $form->addElement('label', null, $html.$table->toHtml()); + } + } + } + + if (!$admin_permissions) { + if ($field_details['field_visible'] == 0) { + $form->freeze('extra_'.$field_details['field_variable']); + } + } + break; + case ExtraField::FIELD_TYPE_SELECT_MULTIPLE: + $options = array(); + foreach ($field_details['options'] as $option_id => $option_details) { + $options[$option_details['option_value']] = $option_details['option_display_text']; + } + $form->addElement( + 'select', + 'extra_'.$field_details['field_variable'], + $field_details['field_display_text'], + $options, + array('multiple' => 'multiple') + ); + if (!$admin_permissions) { + if ($field_details['field_visible'] == 0) { + $form->freeze('extra_'.$field_details['field_variable']); + } + } + break; + case ExtraField::FIELD_TYPE_DATE: + $form->addElement( + 'datepickerdate', + 'extra_'.$field_details['field_variable'], + $field_details['field_display_text'], + array('form_name' => $form_name) + ); + $form->_elements[$form->_elementIndex['extra_'.$field_details['field_variable']]]->setLocalOption( + 'minYear', + 1900 + ); + $defaults['extra_'.$field_details['field_variable']] = date('Y-m-d 12:00:00'); + if (!isset($form->_defaultValues['extra_'.$field_details['field_variable']])) { + $form->setDefaults($defaults); + } + if (!$admin_permissions) { + if ($field_details['field_visible'] == 0) { + $form->freeze('extra_'.$field_details['field_variable']); + } + } + $form->applyFilter('theme', 'trim'); + break; + case ExtraField::FIELD_TYPE_DATETIME: + $form->addElement( + 'datepicker', + 'extra_'.$field_details['field_variable'], + $field_details['field_display_text'], + array('form_name' => $form_name) + ); + $form->_elements[$form->_elementIndex['extra_'.$field_details['field_variable']]]->setLocalOption( + 'minYear', + 1900 + ); + $defaults['extra_'.$field_details['field_variable']] = date('Y-m-d 12:00:00'); + if (!isset($form->_defaultValues['extra_'.$field_details['field_variable']])) { + $form->setDefaults($defaults); + } + if (!$admin_permissions) { + if ($field_details['field_visible'] == 0) { + $form->freeze('extra_'.$field_details['field_variable']); + } + } + $form->applyFilter('theme', 'trim'); + break; + case ExtraField::FIELD_TYPE_DOUBLE_SELECT: + $first_select_id = 'first_extra_'.$field_details['field_variable']; + $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php?1=1'; + + $jquery_ready_content .= ' + $("#'.$first_select_id.'").on("change", function() { + var id = $(this).val(); + if (id) { + $.ajax({ + url: "'.$url.'&a=get_second_select_options", + dataType: "json", + data: "type='.$type.'&field_id='.$field_details['id'].'&option_value_id="+id, + success: function(data) { + $("#second_extra_'.$field_details['field_variable'].'").empty(); + $.each(data, function(index, value) { + $("#second_extra_'.$field_details['field_variable'].'").append($("'; + } + } + $url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?'; + } else { + $extraFieldValue = new ExtraFieldValue($this->type); + $tags = array(); + if (!empty($itemId)) { + $tags = $extraFieldValue->getAllValuesByItemAndField($itemId, $field_id); + } + $tag_list = ''; + if (is_array($tags) && count($tags) > 0) { + $extraFieldOption = new ExtraFieldOption($this->type); + foreach ($tags as $tag) { + $option = $extraFieldOption->get($tag['field_value']); + $tag_list .= ''; + } + } + $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php'; + } + + $form->addElement('hidden', 'extra_'.$field_details['field_variable'].'__persist__', 1); + + $multiSelect = ''; + + $form->addElement('label', $field_details['field_display_text'], $multiSelect); + $complete_text = get_lang('StartToType'); + + //if cache is set to true the jquery will be called 1 time + + $jquery_ready_content .= <<type}", + cache: false, + filter_case: true, + filter_hide: true, + complete_text:"$complete_text", + firstselected: false, + filter_selected: true, + newel: true + }); +EOF; + break; + case ExtraField::FIELD_TYPE_TIMEZONE: + $form->addElement( + 'select', + 'extra_'.$field_details['field_variable'], + $field_details['field_display_text'], + api_get_timezones(), + '' + ); + if ($field_details['field_visible'] == 0) { + $form->freeze( + 'extra_'.$field_details['field_variable'] + ); + } + break; + case ExtraField::FIELD_TYPE_SOCIAL_PROFILE: + // get the social network's favicon + $icon_path = UserManager::get_favicon_from_url( + $extraData['extra_'.$field_details['field_variable']], + $field_details['field_default_value'] + ); + // special hack for hi5 + $leftpad = '1.7'; + $top = '0.4'; + $domain = parse_url($icon_path, PHP_URL_HOST); + if ($domain == 'www.hi5.com' or $domain == 'hi5.com') { + $leftpad = '3'; + $top = '0'; + } + // print the input field + $form->addElement( + 'text', + 'extra_'.$field_details['field_variable'], + $field_details['field_display_text'], + array( + 'size' => 60, + 'style' => 'background-image: url(\''.$icon_path.'\'); background-repeat: no-repeat; background-position: 0.4em '.$top.'em; padding-left: '.$leftpad.'em; ' + ) + ); + $form->applyFilter('extra_'.$field_details['field_variable'], 'stripslashes'); + $form->applyFilter('extra_'.$field_details['field_variable'], 'trim'); + if ($field_details['field_visible'] == 0) { + $form->freeze('extra_'.$field_details['field_variable']); + } + break; + } + } + } + $return = array(); + $return['jquery_ready_content'] = $jquery_ready_content; + + return $return; + } + + function setupBreadcrumb(&$breadcrumb, $action) + { + if ($action == 'add') { + $breadcrumb[] = array('url' => $this->pageUrl, 'name' => $this->pageName); + $breadcrumb[] = array('url' => '#', 'name' => get_lang('Add')); + } elseif ($action == 'edit') { + $breadcrumb[] = array('url' => $this->pageUrl, 'name' => $this->pageName); + $breadcrumb[] = array('url' => '#', 'name' => get_lang('Edit')); + } else { + $breadcrumb[] = array('url' => '#', 'name' => $this->pageName); + } + } + + + /** + * Displays the title + grid + */ + public function display() + { + // action links + echo ''; + echo Display::grid_html($this->type.'_fields'); + } + + public function getJqgridColumnNames() + { + return array( + get_lang('Name'), + get_lang('FieldLabel'), + get_lang('Type'), + get_lang('FieldChangeability'), + get_lang('Visibility'), + get_lang('Filter'), + get_lang('FieldOrder'), + get_lang('Actions') + ); + } + + public function getJqgridColumnModel() + { + return array( + array('name' => 'field_display_text', 'index' => 'field_display_text', 'width' => '180', 'align' => 'left'), + array( + 'name' => 'field_variable', + 'index' => 'field_variable', + 'width' => '', + 'align' => 'left', + 'sortable' => 'true' + ), + array( + 'name' => 'field_type', + 'index' => 'field_type', + 'width' => '', + 'align' => 'left', + 'sortable' => 'true' + ), + array( + 'name' => 'field_changeable', + 'index' => 'field_changeable', + 'width' => '50', + 'align' => 'left', + 'sortable' => 'true' + ), + array( + 'name' => 'field_visible', + 'index' => 'field_visible', + 'width' => '40', + 'align' => 'left', + 'sortable' => 'true' + ), + array( + 'name' => 'field_filter', + 'index' => 'field_filter', + 'width' => '30', + 'align' => 'left', + 'sortable' => 'true' + ), + array( + 'name' => 'field_order', + 'index' => 'field_order', + 'width' => '40', + 'align' => 'left', + 'sortable' => 'true' + ), + array( + 'name' => 'actions', + 'index' => 'actions', + 'width' => '100', + 'align' => 'left', + 'formatter' => 'action_formatter', + 'sortable' => 'false' + ) + ); + + } + + /** + * @param string $url + * @param string $action + * @return FormValidator + */ + public function return_form($url, $action) + { + $form = new FormValidator($this->type.'_field', 'post', $url); + + $form->addElement('hidden', 'type', $this->type); + $id = isset($_GET['id']) ? intval($_GET['id']) : null; + $form->addElement('hidden', 'id', $id); + + // Setting the form elements + $header = get_lang('Add'); + $defaults = array(); + + if ($action == 'edit') { + $header = get_lang('Modify'); + // Setting the defaults + $defaults = $this->get($id); + } + + $form->addElement('header', $header); + $form->addElement('text', 'field_display_text', get_lang('Name'), array('class' => 'span5')); + + // Field type + $types = self::get_field_types(); + + $form->addElement( + 'select', + 'field_type', + get_lang('FieldType'), + $types, + array('id' => 'field_type', 'class' => 'chzn-select', 'data-placeholder' => get_lang('Select')) + ); + $form->addElement('label', get_lang('Example'), '
-
'); + $form->addElement('text', 'field_variable', get_lang('FieldLabel'), array('class' => 'span5')); + $form->addElement( + 'text', + 'field_options', + get_lang('FieldPossibleValues'), + array('id' => 'field_options', 'class' => 'span6') + ); + + $fieldWithOptions = array( + ExtraField::FIELD_TYPE_SELECT, + ExtraField::FIELD_TYPE_TAG, + ExtraField::FIELD_TYPE_DOUBLE_SELECT, + ); + + if ($action == 'edit') { + if (in_array($defaults['field_type'], $fieldWithOptions)) { + $url = Display::url( + get_lang('EditExtraFieldOptions'), + 'extra_field_options.php?type='.$this->type.'&field_id='.$id + ); + $form->addElement('label', null, $url); + + if ($defaults['field_type'] == ExtraField::FIELD_TYPE_SELECT) { + $urlWorkFlow = Display::url( + get_lang('EditExtraFieldWorkFlow'), + 'extra_field_workflow.php?type='.$this->type.'&field_id='.$id + ); + $form->addElement('label', null, $urlWorkFlow); + } + + $form->freeze('field_options'); + } + } + $form->addElement( + 'text', + 'field_default_value', + get_lang('FieldDefaultValue'), + array('id' => 'field_default_value', 'class' => 'span5') + ); + + $group = array(); + $group[] = $form->createElement('radio', 'field_visible', null, get_lang('Yes'), 1); + $group[] = $form->createElement('radio', 'field_visible', null, get_lang('No'), 0); + $form->addGroup($group, '', get_lang('Visible'), '', false); + + $group = array(); + $group[] = $form->createElement('radio', 'field_changeable', null, get_lang('Yes'), 1); + $group[] = $form->createElement('radio', 'field_changeable', null, get_lang('No'), 0); + $form->addGroup($group, '', get_lang('FieldChangeability'), '', false); + + $group = array(); + $group[] = $form->createElement('radio', 'field_filter', null, get_lang('Yes'), 1); + $group[] = $form->createElement('radio', 'field_filter', null, get_lang('No'), 0); + $form->addGroup($group, '', get_lang('FieldFilter'), '', false); + + $group = array(); + $group[] = $form->createElement('radio', 'field_loggeable', null, get_lang('Yes'), 1); + $group[] = $form->createElement('radio', 'field_loggeable', null, get_lang('No'), 0); + $form->addGroup($group, '', get_lang('FieldLoggeable'), '', false); + + + $form->addElement('text', 'field_order', get_lang('FieldOrder'), array('class' => 'span1')); + + if ($action == 'edit') { + $option = new ExtraFieldOption($this->type); + if ($defaults['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) { + $form->freeze('field_options'); + } + $defaults['field_options'] = $option->get_field_options_by_field_to_string($id); + $form->addElement('button', 'submit', get_lang('Modify'), 'class="save"'); + } else { + $defaults['field_visible'] = 0; + $defaults['field_changeable'] = 0; + $defaults['field_filter'] = 0; + $form->addElement('button', 'submit', get_lang('Add'), 'class="save"'); + } + + /*if (!empty($defaults['created_at'])) { + $defaults['created_at'] = api_convert_and_format_date($defaults['created_at']); + } + if (!empty($defaults['updated_at'])) { + $defaults['updated_at'] = api_convert_and_format_date($defaults['updated_at']); + }*/ + $form->setDefaults($defaults); + + // Setting the rules + $form->addRule('field_display_text', get_lang('ThisFieldIsRequired'), 'required'); + //$form->addRule('field_variable', get_lang('ThisFieldIsRequired'), 'required'); + $form->addRule('field_type', get_lang('ThisFieldIsRequired'), 'required'); + + return $form; + } + + public function getJqgridActionLinks($token) + { + //With this function we can add actions to the jgrid (edit, delete, etc) + return 'function action_formatter(cellvalue, options, rowObject) { + return \''.Display::return_icon( + 'edit.png', + get_lang('Edit'), + '', + ICON_SIZE_SMALL + ).''. + ' '.Display::return_icon( + 'delete.png', + get_lang('Delete'), + '', + ICON_SIZE_SMALL + ).''. + '\'; + }'; + } + + /** + * @param array $columns + * @param array $column_model + * @param array $extraFields + * @return array + */ + public function getRules(&$columns, &$column_model, $extraFields = array(), $checkExtraFieldExistence = false) + { + $fields = $this->get_all( + array('field_visible = ? AND field_filter = ?' + => array(1, 1) + ), + 'option_display_text' + ); + $extraFieldOption = new ExtraFieldOption($this->type); + + $rules = array(); + if (!empty($fields)) { + foreach ($fields as $field) { + + $search_options = array(); + $type = 'text'; + if (in_array($field['field_type'], array(self::FIELD_TYPE_SELECT, self::FIELD_TYPE_DOUBLE_SELECT))) { + $type = 'select'; + $search_options['sopt'] = array('eq', 'ne'); //equal not equal + } else { + $search_options['sopt'] = array('cn', 'nc'); //contains not contains + } + + $search_options['searchhidden'] = 'true'; + $search_options['defaultValue'] = isset($search_options['field_default_value']) ? $search_options['field_default_value'] : null; + + if ($field['field_type'] == self::FIELD_TYPE_DOUBLE_SELECT) { + //Add 2 selects + $options = $extraFieldOption->get_field_options_by_field($field['id']); + $options = self::extra_field_double_select_convert_array_to_ordered_array($options); + $first_options = array(); + + if (!empty($options)) { + foreach ($options as $option) { + foreach ($option as $sub_option) { + if ($sub_option['option_value'] == 0) { + $first_options[] = $sub_option['field_id'].'#'.$sub_option['id'].':'.$sub_option['option_display_text']; + } + } + } + } + + $search_options['value'] = implode(';', $first_options); + $search_options['dataInit'] = 'fill_second_select'; + + //First + $column_model[] = array( + 'name' => 'extra_'.$field['field_variable'], + 'index' => 'extra_'.$field['field_variable'], + 'width' => '100', + 'hidden' => 'true', + 'search' => 'true', + 'stype' => 'select', + 'searchoptions' => $search_options + ); + $columns[] = $field['field_display_text'].' (1)'; + $rules[] = array('field' => 'extra_'.$field['field_variable'], 'op' => 'cn'); + + //Second + $search_options['value'] = $field['id'].':'; + $search_options['dataInit'] = 'register_second_select'; + + $column_model[] = array( + 'name' => 'extra_'.$field['field_variable'].'_second', + 'index' => 'extra_'.$field['field_variable'].'_second', + 'width' => '100', + 'hidden' => 'true', + 'search' => 'true', + 'stype' => 'select', + 'searchoptions' => $search_options + ); + $columns[] = $field['field_display_text'].' (2)'; + $rules[] = array('field' => 'extra_'.$field['field_variable'].'_second', 'op' => 'cn'); + continue; + } else { + $search_options['value'] = $extraFieldOption->get_field_options_to_string( + $field['id'], + false, + 'option_display_text' + ); + } + $column_model[] = array( + 'name' => 'extra_'.$field['field_variable'], + 'index' => 'extra_'.$field['field_variable'], + 'width' => '100', + 'hidden' => 'true', + 'search' => 'true', + 'stype' => $type, + 'searchoptions' => $search_options + ); + $columns[] = $field['field_display_text']; + $rules[] = array('field' => 'extra_'.$field['field_variable'], 'op' => 'cn'); + } + } + + return $rules; + } + + /** + * @param array $options + * @return array + */ + public function parseConditions($options) + { + $inject_extra_fields = null; + $extraFieldOption = new ExtraFieldOption($this->type); + $double_fields = array(); + + if (isset($options['extra'])) { + $extra_fields = $options['extra']; + if (!empty($extra_fields)) { + $counter = 1; + foreach ($extra_fields as &$extra) { + $extra_field_obj = new ExtraField($this->type); + $extra_field_info = $extra_field_obj->get($extra['id']); + $extra['extra_field_info'] = $extra_field_info; + + if (isset($extra_field_info['field_type']) && in_array( + $extra_field_info['field_type'], + array( + ExtraField::FIELD_TYPE_SELECT, + ExtraField::FIELD_TYPE_SELECT, + ExtraField::FIELD_TYPE_DOUBLE_SELECT + ) + ) + ) { + $inject_extra_fields .= " fvo$counter.option_display_text as {$extra['field']}, "; + } else { + $inject_extra_fields .= " fv$counter.field_value as {$extra['field']}, "; + } + + if (isset($extra_fields_info[$extra['id']])) { + $info = $extra_fields_info[$extra['id']]; + } else { + $info = $this->get($extra['id']); + $extra_fields_info[$extra['id']] = $info; + } + if (isset($info['field_type']) && $info['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) { + $double_fields[$info['id']] = $info; + } + $counter++; + } + } + } + $options_by_double = array(); + foreach ($double_fields as $double) { + $my_options = $extraFieldOption->get_field_options_by_field( + $double['id'], + true + ); + $options_by_double['extra_'.$double['field_variable']] = $my_options; + } + + $field_value_to_join = array(); + + //filter can be all/any = and/or + $inject_joins = null; + $inject_where = null; + $where = null; + + if (!empty($options['where'])) { + if (!empty($options['extra'])) { + // Removing double 1=1 + $options['where'] = str_replace(' 1 = 1 AND', '', $options['where']); + // Always OR + $counter = 1; + foreach ($extra_fields as $extra_info) { + $extra_field_info = $extra_info['extra_field_info']; + $inject_joins .= " INNER JOIN $this->table_field_values fv$counter ON (s.".$this->primaryKey." = fv$counter.".$this->handler_id.") "; + + //Add options + if (isset($extra_field_info['field_type']) && in_array( + $extra_field_info['field_type'], + array( + ExtraField::FIELD_TYPE_SELECT, + ExtraField::FIELD_TYPE_SELECT, + ExtraField::FIELD_TYPE_DOUBLE_SELECT + ) + ) + ) { + $options['where'] = str_replace( + $extra_info['field'], + 'fv'.$counter.'.field_id = '.$extra_info['id'].' AND fvo'.$counter.'.option_value', + $options['where'] + ); + $inject_joins .= " INNER JOIN $this->table_field_options fvo$counter ". + " ON (fv$counter.field_id = fvo$counter.field_id AND fv$counter.field_value = fvo$counter.option_value) "; + } else { + //text, textarea, etc + $options['where'] = str_replace( + $extra_info['field'], + 'fv'.$counter.'.field_id = '.$extra_info['id'].' AND fv'.$counter.'.field_value', + $options['where'] + ); + } + + $field_value_to_join[] = " fv$counter.$this->handler_id "; + $counter++; + } + if (!empty($field_value_to_join)) { + //$inject_where .= " AND s.id = ".implode(' = ', $field_value_to_join); + } + } + $where .= ' AND '.$options['where']; + } + + $order = null; + if (!empty($options['order'])) { + $order = " ORDER BY ".$options['order']; + } + $limit = null; + if (!empty($options['limit'])) { + $limit = " LIMIT ".$options['limit']; + } + + return array( + 'order' => $order, + 'limit' => $limit, + 'where' => $where, + 'inject_where' => $inject_where, + 'inject_joins' => $inject_joins, + 'field_value_to_join' => $field_value_to_join, + 'inject_extra_fields' => $inject_extra_fields, + ); + } + + + //@todo move this in the display_class or somewhere else + /** + * @param $col + * @param $oper + * @param $val + * @return string + */ + public function get_where_clause($col, $oper, $val) + { + + if (empty($col)) { + return ''; + } + if ($oper == 'bw' || $oper == 'bn') { + $val .= '%'; + } + if ($oper == 'ew' || $oper == 'en') { + $val = '%'.$val; + } + if ($oper == 'cn' || $oper == 'nc' || $oper == 'in' || $oper == 'ni') { + $val = '%'.$val.'%'; + } + $val = \Database::escape_string($val); + + return " $col {$this->ops[$oper]} '$val' "; + } + + public function getExtraFieldRules($filters, $stringToSearch = 'extra_') + { + $extra_fields = array(); + + // Getting double select if exists + $double_select = array(); + foreach ($filters->rules as $rule) { + if (strpos($rule->field, '_second') === false) { + + } else { + $my_field = str_replace('_second', '', $rule->field); + $double_select[$my_field] = $rule->data; + } + } + + $condition_array = array(); + + foreach ($filters->rules as $rule) { + + if (strpos($rule->field, $stringToSearch) === false) { + //normal fields + $field = $rule->field; + + if (isset($rule->data) && $rule->data != -1) { + $condition_array[] = $this->get_where_clause($field, $rule->op, $rule->data); + } + } else { + // Extra fields + + if (strpos($rule->field, '_second') === false) { + //No _second + $original_field = str_replace($stringToSearch, '', $rule->field); + $field_option = $this->get_handler_field_info_by_field_variable($original_field); + + if ($field_option['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) { + + if (isset($double_select[$rule->field])) { + $data = explode('#', $rule->data); + $rule->data = $data[1].'::'.$double_select[$rule->field]; + } else { + // only was sent 1 select + $data = explode('#', $rule->data); + $rule->data = $data[1]; + } + + if (!isset($rule->data)) { + $condition_array[] = ' ('.$this->get_where_clause($rule->field, $rule->op, $rule->data).') '; + $extra_fields[] = array('field' => $rule->field, 'id' => $field_option['id']); + } + } else { + if (isset($rule->data)) { + if ($rule->data == -1) { + continue; + } + $condition_array[] = ' ('.$this->get_where_clause($rule->field, $rule->op, $rule->data).') '; + $extra_fields[] = array( + 'field' => $rule->field, + 'id' => $field_option['id'], + 'data' => $rule->data + ); + } + } + } else { + $my_field = str_replace('_second', '', $rule->field); + $original_field = str_replace($stringToSearch, '', $my_field); + $field_option = $this->get_handler_field_info_by_field_variable($original_field); + $extra_fields[] = array( + 'field' => $rule->field, + 'id' => $field_option['id'] + ); + } + } + } + + return array( + 'extra_fields' => $extra_fields, + 'condition_array' => $condition_array + ); + } +} diff --git a/main/inc/lib/extra_field_option.lib.php b/main/inc/lib/extra_field_option.lib.php new file mode 100644 index 0000000000..b9f6dd0d7f --- /dev/null +++ b/main/inc/lib/extra_field_option.lib.php @@ -0,0 +1,659 @@ +type = $type; + switch ($this->type) { + case 'course': + $this->table = Database::get_main_table(TABLE_MAIN_COURSE_FIELD_OPTIONS); + break; + case 'user': + $this->table = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS); + break; + case 'session': + $this->table = Database::get_main_table(TABLE_MAIN_SESSION_FIELD_OPTIONS); + break; + case 'question': + $this->table = Database::get_main_table(TABLE_MAIN_QUESTION_FIELD_OPTIONS); + break; + case 'lp': + $this->table = Database::get_main_table(TABLE_MAIN_LP_FIELD_OPTIONS); + break; + } + } + + /** + * Gets the number of options already available in the table for this item type + * @return int Number of options available + * @assert () >= 0 + */ + public function get_count() + { + $row = Database::select('count(*) as count', $this->table, array(), 'first'); + + return $row['count']; + } + + /** + * Gets the number of options available for this field + * @param int Field ID + * @return int Number of options + * @assert ('') === false + * @assert (-1) == 0 + * @assert (0) == 0 + */ + public function get_count_by_field_id($field_id) + { + if (empty($field_id)) { + return false; + } + $row = Database::select( + 'count(*) as count', + $this->table, + array('where' => array('field_id = ?' => $field_id)), + 'first' + ); + + return $row['count']; + } + + /** + * Returns a list of options for a specific field, separated by ";" + * @param int Field ID + * @param bool Indicates whether we want the results to be given with their id + * @param string Order by clause (without the "order by") to be added to the SQL query + * @return string List of options separated by ; + * @assert (-1, false, null) == '' + */ + public function get_field_options_to_string($field_id, $add_id_in_array = false, $ordered_by = null) + { + $options = self::get_field_options_by_field($field_id, $add_id_in_array, $ordered_by); + $new_options = array(); + if (!empty($options)) { + foreach ($options as $option) { + $new_options[] = $option['option_value'].':'.$option['option_display_text']; + } + $string = implode(';', $new_options); + + return $string; + } + + return ''; + } + + /** + * Delete all the options of a specific field + * @param int Field ID + * @result void + * @assert (-1) === false + */ + public function delete_all_options_by_field_id($field_id) + { + $field_id = intval($field_id); + $sql = "DELETE FROM {$this->table} WHERE field_id = $field_id"; + $r = Database::query($sql); + + return $r; + } + + /** + * @param array $params + * + * @return int + */ + public function saveOptions($params, $show_query = false) + { + $optionInfo = self::get_field_option_by_field_and_option($params['field_id'], $params['option_value']); + + // Use URLify only for new items + //$optionValue = URLify::filter($params['option_value']); + $optionValue = replace_dangerous_char($params['option_value']); + $option = $params['option_value']; + + if ($optionInfo == false) { + $order = self::get_max_order($params['field_id']); + $new_params = array( + 'field_id' => $params['field_id'], + 'option_value' => trim($optionValue), + 'option_display_text' => trim($option), + 'option_order' => $order, + 'tms' => api_get_utc_datetime(), + ); + return parent::save($new_params, $show_query); + } + + return false; + } + + /** + * Saves an option into the corresponding *_field_options table + * @param array Parameters to be considered for the insertion + * @param bool Whether to show the query (sent to the parent save() method) + * @return bool True on success, false on error + * @assert (array('field_id'=>0), false) === false + * @assert (array('field_id'=>1), false) === true + */ + public function save($params, $show_query = false) + { + $field_id = intval($params['field_id']); + + if (empty($field_id)) { + return false; + } + + $time = api_get_utc_datetime(); + if (!empty($params['field_options']) && + in_array( + $params['field_type'], + array( + ExtraField::FIELD_TYPE_RADIO, + ExtraField::FIELD_TYPE_SELECT, + ExtraField::FIELD_TYPE_SELECT_MULTIPLE, + ExtraField::FIELD_TYPE_DOUBLE_SELECT + ) + ) + ) { + if ($params['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) { + //$params['field_options'] = France:Paris;Bretagne;Marseilles;Lyon|Belgique:Bruxelles;Namur;Liège;Bruges|Peru:Lima;Piura; + $options_parsed = ExtraField::extra_field_double_select_convert_string_to_array( + $params['field_options'] + ); + + if (!empty($options_parsed)) { + foreach ($options_parsed as $key => $option) { + $sub_options = $option['options']; + + $new_params = array( + 'field_id' => $field_id, + 'option_value' => 0, + 'option_display_text' => $option['label'], + 'option_order' => 0, + 'tms' => $time, + ); + + // Looking if option already exists: + $option_info = self::get_field_option_by_field_id_and_option_display_text( + $field_id, + $option['label'] + ); + + if (empty($option_info)) { + $sub_id = parent::save($new_params, $show_query); + } else { + $sub_id = $option_info['id']; + $new_params['id'] = $sub_id; + parent::update($new_params, $show_query); + } + + foreach ($sub_options as $sub_option) { + if (!empty($sub_option)) { + $new_params = array( + 'field_id' => $field_id, + 'option_value' => $sub_id, + 'option_display_text' => $sub_option, + 'option_order' => 0, + 'tms' => $time, + ); + $option_info = self::get_field_option_by_field_id_and_option_display_text_and_option_value( + $field_id, + $sub_option, + $sub_id + ); + if (empty($option_info)) { + parent::save($new_params, $show_query); + } else { + $new_params['id'] = $option_info['id']; + parent::update($new_params, $show_query); + } + } + + } + } + } + $list = array(); + } else { + $list = explode(';', $params['field_options']); + } + + if (!empty($list)) { + foreach ($list as $option) { + $option_info = self::get_field_option_by_field_and_option($field_id, $option); + // Use URLify only for new items + $optionValue = URLify::filter($option); + $option = trim($option); + + if ($option_info == false) { + $order = self::get_max_order($field_id); + + $new_params = array( + 'field_id' => $field_id, + 'option_value' => trim($optionValue), + 'option_display_text' => trim($option), + 'option_order' => $order, + 'tms' => $time, + ); + parent::save($new_params, $show_query); + } + } + } + } + + return true; + } + + /** + * Save one option item at a time + * @param array Parameters specific to the option + * @param bool Whether to show the query (sent to parent save() method) + * @param bool Whether to insert even if the option already exists + * @return bool True on success, false on failure + * @assert (array('field_id'=>0),false) === false + * @assert (array('field_id'=>0),false) === true + */ + public function save_one_item($params, $show_query = false, $insert_repeated = true) + { + $field_id = intval($params['field_id']); + if (empty($field_id)) { + return false; + } + + if (isset($params['option_value'])) { + $params['option_value'] = trim($params['option_value']); + } + + if (isset($params['option_display_text'])) { + $params['option_display_text'] = trim($params['option_display_text']); + } + + $params['tms'] = api_get_utc_datetime(); + if (empty($params['option_order'])) { + $order = self::get_max_order($field_id); + $params['option_order'] = $order; + } + if ($insert_repeated) { + parent::save($params, $show_query); + } else { + $check = self::get_field_option_by_field_and_option($field_id, $params['option_value']); + if ($check == false) { + parent::save($params, $show_query); + } + } + + return true; + } + + /** + * Get the complete row of a specific option of a specific field + * @param int Field ID + * @param string Value of the option + * @return mixed The row on success or false on failure + * @assert (0,'') === false + */ + public function get_field_option_by_field_and_option($field_id, $option_value) + { + $field_id = intval($field_id); + $option_value = Database::escape_string($option_value); + + $sql = "SELECT * FROM {$this->table} + WHERE field_id = $field_id AND option_value = '".$option_value."'"; + $result = Database::query($sql); + if (Database::num_rows($result) > 0) { + return Database::store_result($result, 'ASSOC'); + } + + return false; + } + + /** + * Get the complete row of a specific option's display text of a specific field + * @param int Field ID + * @param string Display value of the option + * @return mixed The row on success or false on failure + * @assert (0, '') === false + */ + public function get_field_option_by_field_id_and_option_display_text($field_id, $option_display_text) + { + $field_id = intval($field_id); + $option_display_text = Database::escape_string($option_display_text); + + $sql = "SELECT * FROM {$this->table} + WHERE field_id = $field_id AND option_display_text = '".$option_display_text."'"; + $result = Database::query($sql); + if (Database::num_rows($result) > 0) { + return Database::fetch_array($result, 'ASSOC'); + } + + return false; + } + + /** + * Get the complete row of a specific option's display text of a specific field + * @param int Field ID + * @param string Display value of the option + * @param string Value of the option + * @return mixed The row on success or false on failure + * @assert (0, '', '') === false + */ + public function get_field_option_by_field_id_and_option_display_text_and_option_value( + $field_id, + $option_display_text, + $option_value + ) { + $field_id = intval($field_id); + $option_display_text = Database::escape_string($option_display_text); + $option_value = Database::escape_string($option_value); + + $sql = "SELECT * FROM {$this->table} + WHERE + field_id = $field_id AND + option_display_text = '".$option_display_text."' AND + option_value = '$option_value'"; + $result = Database::query($sql); + if (Database::num_rows($result) > 0) { + return Database::fetch_array($result, 'ASSOC'); + } + + return false; + } + + /** + * Gets an array of options for a specific field + * @param int The field ID + * @param bool Whether to add the row ID in the result + * @param string Extra ordering query bit + * @result mixed Row on success, false on failure + * @assert (0, '') === false + */ + public function get_field_options_by_field($field_id, $add_id_in_array = false, $ordered_by = null) + { + $field_id = intval($field_id); + + $sql = "SELECT * FROM {$this->table} WHERE field_id = $field_id "; + + if (!empty($ordered_by)) { + $sql .= " ORDER BY $ordered_by "; + } + $result = Database::query($sql); + if (Database::num_rows($result) > 0) { + if ($add_id_in_array) { + $options = array(); + while ($row = Database::fetch_array($result, 'ASSOC')) { + $options[$row['id']] = $row; + } + + return $options; + } else { + return Database::store_result($result, 'ASSOC'); + } + } + + return false; + } + + /** + * Get options for a specific field as array or in JSON format suited for the double-select format + * @param int Field ID + * @param int Option value ID + * @param bool Return format (whether it should be formatted to JSON or not) + * @return mixed Row/JSON on success + */ + public function get_second_select_field_options_by_field($field_id, $option_value_id, $to_json = false) + { + $field_id = intval($field_id); + $option_value_id = intval($option_value_id); + $options = array(); + $sql = "SELECT * FROM {$this->table} + WHERE field_id = $field_id AND option_value = $option_value_id + ORDER BY option_display_text"; + $result = Database::query($sql); + if (Database::num_rows($result) > 0) { + $options = Database::store_result($result, 'ASSOC'); + } + + if ($to_json) { + $string = null; + if (!empty($options)) { + $array = array(); + foreach ($options as $option) { + $array[$option['id']] = $option['option_display_text']; + } + $string = json_encode($array); + } + + return $string; + } + + return $options; + } + + /** + * Get options for a specific field as string split by ; + * @param int Field ID + * @param string Extra query bit for reordering + * @return string HTML string of options + * @assert (0, '') === null + */ + public function get_field_options_by_field_to_string($field_id, $ordered_by = null) + { + $field = new ExtraField($this->type); + $field_info = $field->get($field_id); + $options = self::get_field_options_by_field($field_id, false, $ordered_by); + $elements = array(); + if (!empty($options)) { + switch ($field_info['field_type']) { + case ExtraField::FIELD_TYPE_DOUBLE_SELECT: + $html = ExtraField::extra_field_double_select_convert_array_to_string($options); + break; + default: + foreach ($options as $option) { + $elements[] = $option['option_value']; + } + $html = implode(';', $elements); + break; + } + + return $html; + } + + return null; + + } + + /** + * Get the maximum order value for a specific field + * @param int Field ID + * @return int Current max ID + 1 (we start from 0) + * @assert (0, '') === 1 + */ + public function get_max_order($field_id) + { + $field_id = intval($field_id); + $sql = "SELECT MAX(option_order) FROM {$this->table} WHERE field_id = $field_id"; + $res = Database::query($sql); + $max = 1; + if (Database::num_rows($res) > 0) { + $row = Database::fetch_array($res); + $max = $row[0] + 1; + } + + return $max; + } + + /** + * Update the option using the given params + * @param array $params data to be saved + */ + public function update($params) + { + parent::update($params); + } + + /** + * Display a form with the options for the field_id given in REQUEST + * @return void Prints output + */ + function display() + { + // action links + echo ''; + echo Display::grid_html('extra_field_options'); + } + + public function getPriorityOptions() + { + return array( + '' => get_lang('SelectAnOption'), + 1 => get_lang('Success'), + 2 => get_lang('Info'), + 3 => get_lang('Warning'), + 4 => get_lang('Error'), + ); + } + + public function getPriorityMessageType($priority) + { + switch ($priority) { + case 1: + return 'success'; + case 2: + return 'info'; + case 3: + return 'warning'; + case 4: + return 'error'; + } + return null; + + } + + /** + * Returns an HTML form for the current field + * @param string URL to send the form to (action=...) + * @param string Type of action to offer through the form (edit, usually) + * @return string HTML form + */ + public function return_form($url, $action) + { + $form_name = $this->type.'_field'; + $form = new FormValidator($form_name, 'post', $url); + // Settting the form elements + $header = get_lang('Add'); + if ($action == 'edit') { + $header = get_lang('Modify'); + } + + $form->addElement('header', $header); + $id = isset($_GET['id']) ? intval($_GET['id']) : ''; + + $form->addElement('hidden', 'id', $id); + $form->addElement('hidden', 'type', $this->type); + $form->addElement('hidden', 'field_id', $this->field_id); + + $form->addElement('text', 'option_display_text', get_lang('Name'), array('class' => 'span5')); + $form->addElement('text', 'option_value', get_lang('Value'), array('class' => 'span5')); + $form->addElement('text', 'option_order', get_lang('Order'), array('class' => 'span2')); + $form->addElement('select', 'priority', get_lang('Priority'), $this->getPriorityOptions()); + $form->addElement('textarea', 'priority_message', get_lang('PriorityMessage')); + + $defaults = array(); + + if ($action == 'edit') { + // Setting the defaults + $defaults = $this->get($id); + $form->freeze('option_value'); + $form->addElement('button', 'submit', get_lang('Modify'), 'class="save"'); + } else { + $form->addElement('button', 'submit', get_lang('Add'), 'class="save"'); + } + + $form->setDefaults($defaults); + + // Setting the rules + $form->addRule('option_display_text', get_lang('ThisFieldIsRequired'), 'required'); + //$form->addRule('field_variable', get_lang('ThisFieldIsRequired'), 'required'); + $form->addRule('option_value', get_lang('ThisFieldIsRequired'), 'required'); + + return $form; + } + + /** + * @param string $tag + * @param int $field_id + * @param int $limit + * @return array + */ + public function searchByField($tag, $field_id, $limit = 10) + { + $field_id = intval($field_id); + $limit = intval($limit); + $tag = Database::escape_string($tag); + $sql = "SELECT DISTINCT id, option_display_text + FROM {$this->table} + WHERE + field_id = '".$field_id."' AND + option_value LIKE '%$tag%' + ORDER BY option_value + LIMIT 0, $limit + "; + $result = Database::query($sql); + $values = array(); + if (Database::num_rows($result)) { + $values = Database::store_result($result, 'ASSOC'); + } + return $values; + } + + + /** + * @param string $tag + * @param int $field_id + * @param int $limit + * + * @return string + */ + public function getSearchOptionsByField($tag, $field_id, $limit = 10) + { + $result = $this->searchByField($tag, $field_id, $limit = 10); + $values = array(); + $json = null; + if (!empty($result)) { + foreach ($result as $item) { + $values[] = array( + 'value' => $item['id'], + 'caption' => $item['option_display_text'], + ); + } + $json = json_encode($values); + } + + return $json; + } + + +} diff --git a/main/inc/lib/extra_field_value.lib.php b/main/inc/lib/extra_field_value.lib.php new file mode 100644 index 0000000000..ae46fc4460 --- /dev/null +++ b/main/inc/lib/extra_field_value.lib.php @@ -0,0 +1,654 @@ +type = $type; + $extra_field = new ExtraField($this->type); + $this->handler_id = $extra_field->handler_id; + + switch ($this->type) { + case 'course': + $this->table = Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES); + $this->table_handler_field = Database::get_main_table(TABLE_MAIN_COURSE_FIELD); + $this->author_id = 'user_id'; + $this->entityName = 'ChamiloLMS\Entity\CourseFieldValues'; + break; + case 'user': + $this->table = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES); + $this->table_handler_field = Database::get_main_table(TABLE_MAIN_USER_FIELD); + $this->author_id = 'author_id'; + $this->entityName = 'ChamiloLMS\Entity\UserFieldValues'; + break; + case 'session': + $this->table = Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES); + $this->table_handler_field = Database::get_main_table(TABLE_MAIN_SESSION_FIELD); + $this->author_id = 'user_id'; + $this->entityName = 'ChamiloLMS\Entity\SessionFieldValues'; + break; + case 'question': + $this->table = Database::get_main_table(TABLE_MAIN_QUESTION_FIELD_VALUES); + $this->table_handler_field = Database::get_main_table(TABLE_MAIN_QUESTION_FIELD); + $this->author_id = 'user_id'; + $this->entityName = 'ChamiloLMS\Entity\QuestionFieldValues'; + break; + case 'lp': + $this->table = Database::get_main_table(TABLE_MAIN_LP_FIELD_VALUES); + $this->table_handler_field = Database::get_main_table(TABLE_MAIN_LP_FIELD); + $this->author_id = 'lp_id'; + //$this->entityName = 'ChamiloLMS\Entity\QuestionFieldValues'; + break; + default: + //unmanaged datatype, return false to let the caller know it + // didn't work + return false; + } + $this->columns[] = $this->handler_id; + $this->columns[] = $this->author_id; + } + + /** + * Gets the number of values stored in the table (all fields together) + * for this type of resource + * @return integer Number of rows in the table + * @assert () !== false + */ + public function get_count() + { + $row = Database::select('count(*) as count', $this->table, array(), 'first'); + return $row['count']; + } + + /** + * Saves a series of records given as parameter into the coresponding table + * @param array Structured parameter for the insertion into the *_field_values table + * @return mixed false on empty params, void otherwise + * @assert (array()) === false + */ + public function save_field_values($params) + { + $extra_field = new ExtraField($this->type); + + if (empty($params[$this->handler_id])) { + return false; + } + + foreach ($params as $key => $value) { + $found = strpos($key, '__persist__'); + if ($found) { + $tempKey = str_replace('__persist__', '', $key); + if (!isset($params[$tempKey])) { + $params[$tempKey] = array(); + } + break; + } + } + + // Parse params. + foreach ($params as $key => $value) { + if (substr($key, 0, 6) == 'extra_') { + // An extra field. + $field_variable = substr($key, 6); + $extra_field_info = $extra_field->get_handler_field_info_by_field_variable($field_variable); + + if ($extra_field_info) { + $commentVariable = 'extra_'.$field_variable.'_comment'; + $comment = isset($params[$commentVariable]) ? $params[$commentVariable] : null; + + switch ($extra_field_info['field_type']) { + case ExtraField::FIELD_TYPE_TAG : + + $old = self::getAllValuesByItemAndField( + $extra_field_info['id'], + $params[$this->handler_id] + ); + + $deleteItems = array(); + if (!empty($old)) { + $oldIds = array(); + foreach ($old as $oldItem) { + $oldIds[] = $oldItem['field_value']; + } + $deleteItems = array_diff($oldIds, $value); + } + + foreach ($value as $optionId) { + $new_params = array( + $this->handler_id => $params[$this->handler_id], + 'field_id' => $extra_field_info['id'], + 'field_value' => $optionId, + 'comment' => $comment + ); + self::save($new_params); + } + + if (!empty($deleteItems)) { + foreach ($deleteItems as $deleteFieldValue) { + self::deleteValuesByHandlerAndFieldAndValue( + $extra_field_info['id'], + $params[$this->handler_id], + $deleteFieldValue + ); + } + } + break; + default; + $new_params = array( + $this->handler_id => $params[$this->handler_id], + 'field_id' => $extra_field_info['id'], + 'field_value' => $value, + 'comment' => $comment + ); + self::save($new_params); + } + } + } + } + } + + /** + * Save values in the *_field_values table + * @param array Structured array with the values to save + * @param boolean Whether to show the insert query (passed to the parent save() method) + * @result mixed The result sent from the parent method + * @assert (array()) === false + */ + public function save($params, $show_query = false) + { + $extra_field = new ExtraField($this->type); + + // Setting value to insert. + $value = $params['field_value']; + $value_to_insert = null; + + if (is_array($value)) { + $value_to_insert = implode(';', $value); + } else { + $value_to_insert = Database::escape_string($value); + } + + $params['field_value'] = $value_to_insert; + + //If field id exists + $extra_field_info = $extra_field->get($params['field_id']); + + if ($extra_field_info) { + switch ($extra_field_info['field_type']) { + case ExtraField::FIELD_TYPE_RADIO: + case ExtraField::FIELD_TYPE_SELECT: + case ExtraField::FIELD_TYPE_SELECT_MULTIPLE: + //$field_options = $session_field_option->get_field_options_by_field($params['field_id']); + //$params['field_value'] = split(';', $value_to_insert); + /* + if ($field_options) { + $check = false; + foreach ($field_options as $option) { + if (in_array($option['option_value'], $values)) { + $check = true; + break; + } + } + if (!$check) { + return false; //option value not found + } + } else { + return false; //enumerated type but no option found + }*/ + break; + case ExtraField::FIELD_TYPE_TEXT: + case ExtraField::FIELD_TYPE_TEXTAREA: + break; + case ExtraField::FIELD_TYPE_DOUBLE_SELECT: + if (is_array($value)) { + if (isset($value['extra_'.$extra_field_info['field_variable']]) && + isset($value['extra_'.$extra_field_info['field_variable'].'_second']) + ) { + $value_to_insert = $value['extra_'.$extra_field_info['field_variable']].'::'.$value['extra_'.$extra_field_info['field_variable'].'_second']; + } else { + $value_to_insert = null; + } + } + break; + default: + break; + } + + if ($extra_field_info['field_type'] == ExtraField::FIELD_TYPE_TAG) { + $field_values = self::getAllValuesByItemAndFieldAndValue( + $params[$this->handler_id], + $params['field_id'], + $value + ); + } else { + $field_values = self::get_values_by_handler_and_field_id( + $params[$this->handler_id], + $params['field_id'] + ); + } + + $params['field_value'] = $value_to_insert; + $params['tms'] = api_get_utc_datetime(); + $params[$this->author_id] = api_get_user_id(); + + // Insert + if (empty($field_values)) { + if ($extra_field_info['field_loggeable'] == 1) { + global $app; + switch($this->type) { + case 'question': + $extraFieldValue = new ChamiloLMS\Entity\QuestionFieldValues(); + $extraFieldValue->setUserId(api_get_user_id()); + $extraFieldValue->setQuestionId($params[$this->handler_id]); + break; + case 'course': + $extraFieldValue = new ChamiloLMS\Entity\CourseFieldValues(); + $extraFieldValue->setUserId(api_get_user_id()); + $extraFieldValue->setQuestionId($params[$this->handler_id]); + break; + case 'user': + $extraFieldValue = new ChamiloLMS\Entity\UserFieldValues(); + $extraFieldValue->setUserId($params[$this->handler_id]); + $extraFieldValue->setAuthorId(api_get_user_id()); + break; + case 'session': + $extraFieldValue = new ChamiloLMS\Entity\SessionFieldValues(); + $extraFieldValue->setUserId(api_get_user_id()); + $extraFieldValue->setSessionId($params[$this->handler_id]); + break; + } + if (isset($extraFieldValue)) { + if (!empty($params['field_value'])) { + $extraFieldValue->setComment($params['comment']); + $extraFieldValue->setFieldValue($params['field_value']); + $extraFieldValue->setFieldId($params['field_id']); + $extraFieldValue->setTms(api_get_utc_datetime(null, false, true)); + $app['orm.ems']['db_write']->persist($extraFieldValue); + $app['orm.ems']['db_write']->flush(); + } + } + } else { + if ($extra_field_info['field_type'] == ExtraField::FIELD_TYPE_TAG) { + + $option = new ExtraFieldOption($this->type); + $optionExists = $option->get($params['field_value']); + if (empty($optionExists)) { + $optionParams = array( + 'field_id' => $params['field_id'], + 'option_value' => $params['field_value'] + ); + $optionId = $option->saveOptions($optionParams); + } else { + $optionId = $optionExists['id']; + } + + $params['field_value'] = $optionId; + if ($optionId) { + return parent::save($params, $show_query); + } + } else { + return parent::save($params, $show_query); + } + } + } else { + // Update + if ($extra_field_info['field_loggeable'] == 1) { + global $app; + switch($this->type) { + case 'question': + $extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\QuestionFieldValues')->find($field_values['id']); + $extraFieldValue->setUserId(api_get_user_id()); + $extraFieldValue->setQuestionId($params[$this->handler_id]); + break; + case 'course': + $extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\CourseFieldValues')->find($field_values['id']); + $extraFieldValue->setUserId(api_get_user_id()); + $extraFieldValue->setCourseCode($params[$this->handler_id]); + break; + case 'user': + $extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\UserFieldValues')->find($field_values['id']); + $extraFieldValue->setUserId(api_get_user_id()); + $extraFieldValue->setAuthorId(api_get_user_id()); + break; + case 'session': + $extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\SessionFieldValues')->find($field_values['id']); + $extraFieldValue->setUserId(api_get_user_id()); + $extraFieldValue->setSessionId($params[$this->handler_id]); + break; + } + + if (isset($extraFieldValue)) { + if (!empty($params['field_value'])) { + + /* + * If the field value is similar to the previous value then the comment will be the same + in order to no save in the log an empty record + */ + if ($extraFieldValue->getFieldValue() == $params['field_value']) { + if (empty($params['comment'])) { + $params['comment'] = $extraFieldValue->getComment(); + } + } + + $extraFieldValue->setComment($params['comment']); + $extraFieldValue->setFieldValue($params['field_value']); + $extraFieldValue->setFieldId($params['field_id']); + $extraFieldValue->setTms(api_get_utc_datetime(null, false, true)); + $app['orm.ems']['db_write']->persist($extraFieldValue); + $app['orm.ems']['db_write']->flush(); + } + } + } else { + $params['id'] = $field_values['id']; + return parent::update($params, $show_query); + } + } + } + } + + /** + * Returns the value of the given extra field on the given resource + * @param int Item ID (It could be a session_id, course_id or user_id) + * @param int Field ID (the ID from the *_field table) + * @param bool Whether to transform the result to a human readable strings + * @return mixed A structured array with the field_id and field_value, or false on error + * @assert (-1,-1) === false + */ + public function get_values_by_handler_and_field_id($item_id, $field_id, $transform = false) + { + $field_id = intval($field_id); + $item_id = Database::escape_string($item_id); + + $sql = "SELECT s.*, field_type FROM {$this->table} s + INNER JOIN {$this->table_handler_field} sf ON (s.field_id = sf.id) + WHERE {$this->handler_id} = '$item_id' AND + field_id = '".$field_id."' + ORDER BY id"; + $result = Database::query($sql); + if (Database::num_rows($result)) { + $result = Database::fetch_array($result, 'ASSOC'); + if ($transform) { + if (!empty($result['field_value'])) { + switch ($result['field_type']) { + case ExtraField::FIELD_TYPE_DOUBLE_SELECT: + $field_option = new ExtraFieldOption($this->type); + $options = explode('::', $result['field_value']); + // only available for PHP 5.4 :( $result['field_value'] = $field_option->get($options[0])['id'].' -> '; + $result = $field_option->get($options[0]); + $result_second = $field_option->get($options[1]); + if (!empty($result)) { + $result['field_value'] = $result['option_display_text'].' -> '; + $result['field_value'] .= $result_second['option_display_text']; + } + break; + case ExtraField::FIELD_TYPE_SELECT: + $field_option = new ExtraFieldOption($this->type); + $extra_field_option_result = $field_option->get_field_option_by_field_and_option( + $result['field_id'], + $result['field_value'] + ); + if (isset($extra_field_option_result[0])) { + $result['field_value'] = $extra_field_option_result[0]['option_display_text']; + } + break; + } + } + } + return $result; + } else { + return false; + } + } + + /** + * @param string $tag + * @param int $field_id + * @param int $limit + * @return array + */ + public function searchValuesByField($tag, $field_id, $limit = 10) + { + $field_id = intval($field_id); + $limit = intval($limit); + $tag = Database::escape_string($tag); + $sql = "SELECT DISTINCT s.field_value, s.field_id + FROM {$this->table} s + INNER JOIN {$this->table_handler_field} sf ON (s.field_id = sf.id) + WHERE + field_id = '".$field_id."' AND + field_value LIKE '%$tag%' + ORDER BY field_value + LIMIT 0, $limit + "; + $result = Database::query($sql); + $values = array(); + if (Database::num_rows($result)) { + $values = Database::store_result($result, 'ASSOC'); + } + return $values; + } + + /** + * Gets a structured array of the original item and its extra values, using + * a specific original item and a field name (like "branch", or "birthdate") + * @param int Item ID from the original table + * @param string The name of the field we are looking for + * @return mixed Array of results, or false on error or not found + * @assert (-1,'') === false + */ + public function get_values_by_handler_and_field_variable($item_id, $field_variable, $transform = false) + { + $item_id = Database::escape_string($item_id); + $field_variable = Database::escape_string($field_variable); + + $sql = "SELECT s.*, field_type FROM {$this->table} s + INNER JOIN {$this->table_handler_field} sf + ON (s.field_id = sf.id) + WHERE + {$this->handler_id} = '$item_id' AND + field_variable = '".$field_variable."' + ORDER BY id"; + $result = Database::query($sql); + if (Database::num_rows($result)) { + $result = Database::fetch_array($result, 'ASSOC'); + if ($transform) { + if ($result['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) { + if (!empty($result['field_value'])) { + $field_option = new ExtraFieldOption($this->type); + $options = explode('::', $result['field_value']); + // only available for PHP 5.4 :( $result['field_value'] = $field_option->get($options[0])['id'].' -> '; + $result = $field_option->get($options[0]); + $result_second = $field_option->get($options[1]); + if (!empty($result)) { + $result['field_value'] = $result['option_display_text'].' -> '; + $result['field_value'] .= $result_second['option_display_text']; + } + } + } + } + return $result; + } else { + return false; + } + } + + /** + * Gets the ID from the item (course, session, etc) for which + * the given field is defined with the given value + * @param string Field (type of data) we want to check + * @param string Data we are looking for in the given field + * @return mixed Give the ID if found, or false on failure or not found + * @assert (-1,-1) === false + */ + public function get_item_id_from_field_variable_and_field_value($field_variable, $field_value, $transform = false) + { + $field_value = Database::escape_string($field_value); + $field_variable = Database::escape_string($field_variable); + + $sql = "SELECT {$this->handler_id} FROM {$this->table} s + INNER JOIN {$this->table_handler_field} sf + ON (s.field_id = sf.id) + WHERE + field_value = '$field_value' AND + field_variable = '".$field_variable."' + "; + + $result = Database::query($sql); + if ($result !== false && Database::num_rows($result)) { + $result = Database::fetch_array($result, 'ASSOC'); + return $result; + } else { + return false; + } + } + + /** + * Get all values for a specific field id + * @param int Field ID + * @return mixed Array of values on success, false on failure or not found + * @assert (-1) === false + */ + public function get_values_by_field_id($field_id) + { + $field_id = intval($field_id); + $sql = "SELECT s.*, field_type FROM {$this->table} s + INNER JOIN {$this->table_handler_field} sf + ON (s.field_id = sf.id) + WHERE field_id = '".$field_id."' ORDER BY id"; + $result = Database::query($sql); + if (Database::num_rows($result)) { + return Database::store_result($result, 'ASSOC'); + } + return false; + } + + /** + * @param int $itemId + * @param int $fieldId + * @return array + */ + public function getAllValuesByItemAndField($itemId, $fieldId) + { + $fieldId = intval($fieldId); + $itemId = intval($itemId); + $sql = "SELECT s.* FROM {$this->table} s + INNER JOIN {$this->table_handler_field} sf + ON (s.field_id = sf.id) + WHERE + field_id = '".$fieldId."' AND + {$this->handler_id} = '$itemId' + ORDER BY field_value"; + $result = Database::query($sql); + if (Database::num_rows($result)) { + return Database::store_result($result, 'ASSOC'); + } + return false; + } + + /** + * @param int $itemId + * @param int $fieldId + * @param string $fieldValue + * @return array|bool + */ + public function getAllValuesByItemAndFieldAndValue($itemId, $fieldId, $fieldValue) + { + $fieldId = intval($fieldId); + $itemId = intval($itemId); + $fieldValue = Database::escape_string($fieldValue); + $sql = "SELECT s.* FROM {$this->table} s + INNER JOIN {$this->table_handler_field} sf + ON (s.field_id = sf.id) + WHERE + field_id = '".$fieldId."' AND + {$this->handler_id} = '$itemId' AND + field_value = $fieldValue + ORDER BY field_value"; + + $result = Database::query($sql); + if (Database::num_rows($result)) { + return Database::store_result($result, 'ASSOC'); + } + return false; + } + + /** + * Deletes all the values related to a specific field ID + * @param int Field ID + * @return void + * @assert ('a') == null + */ + public function delete_all_values_by_field_id($field_id) + { + $field_id = intval($field_id); + $sql = "DELETE FROM {$this->table} WHERE field_id = $field_id"; + Database::query($sql); + } + + /** + * Deletes values of a specific field for a specific item + * @param int Item ID (session id, course id, etc) + * @param int Field ID + * @return void + * @assert (-1,-1) == null + */ + public function delete_values_by_handler_and_field_id($item_id, $field_id) + { + $field_id = intval($field_id); + $item_id = Database::escape_string($item_id); + $sql = "DELETE FROM {$this->table} WHERE {$this->handler_id} = '$item_id' AND field_id = '".$field_id."' "; + Database::query($sql); + } + + /** + * @param int $itemId + * @param int $fieldId + * @param int $fieldValue + */ + public function deleteValuesByHandlerAndFieldAndValue($itemId, $fieldId, $fieldValue) + { + $itemId = intval($itemId); + $fieldId = intval($fieldId); + $fieldValue = Database::escape_string($fieldValue); + + $sql = "DELETE FROM {$this->table} + WHERE + {$this->handler_id} = '$itemId' AND + field_id = '".$fieldId."' AND + field_value = '$fieldValue'"; + Database::query($sql); + } + + /** + * Not yet implemented - Compares the field values of two items + * @param int Item 1 + * @param int Item 2 + * @return mixed Differential array generated from the comparison + */ + public function compare_item_values($item_id, $item_to_compare) + { + } +} diff --git a/main/inc/lib/fckeditor/editor/plugins/ImageManager/config.inc.php b/main/inc/lib/fckeditor/editor/plugins/ImageManager/config.inc.php index a8ba2cd702..c3ba266520 100755 --- a/main/inc/lib/fckeditor/editor/plugins/ImageManager/config.inc.php +++ b/main/inc/lib/fckeditor/editor/plugins/ImageManager/config.inc.php @@ -29,6 +29,7 @@ $language_file = array('document'); require_once '../../../../../../inc/global.inc.php'; +api_block_anonymous_users(); // Disabling access for anonymous users. api_block_anonymous_users(); diff --git a/main/inc/lib/fileUpload.lib.php b/main/inc/lib/fileUpload.lib.php index 575c070fe9..69b10a1102 100644 --- a/main/inc/lib/fileUpload.lib.php +++ b/main/inc/lib/fileUpload.lib.php @@ -249,12 +249,14 @@ function handle_uploaded_document( $where_to_save = $base_work_dir.$upload_path; // At least if the directory doesn't exist, tell so - if (!is_dir($where_to_save)) { - if ($output){ - Display::display_error_message(get_lang('DestDirectoryDoesntExist').' ('.$upload_path.')'); - } - return false; - } + if (!is_dir($where_to_save)) { + if (!mkdir($where_to_save, api_get_permissions_for_new_directories())) { + if ($output) { + Display::display_error_message(get_lang('DestDirectoryDoesntExist').' ('.$upload_path.')'); + } + return false; + } + } // Full path of the destination $store_path = $where_to_save.$clean_name; @@ -441,14 +443,20 @@ function moveUploadedFile($file, $storePath) * * @see - enough_size() uses dir_total_space() function */ -function enough_size($file_size, $dir, $max_dir_space) { - if ($max_dir_space) { - $already_filled_space = dir_total_space($dir); - if (($file_size + $already_filled_space) > $max_dir_space) { - return false; - } - } - return true; +function enough_size($file_size, $dir, $max_dir_space) +{ + // If the directory is the archive directory, safely ignore the size limit + if (api_get_path(SYS_ARCHIVE_PATH) == $dir) { + return true; + } + + if ($max_dir_space) { + $already_filled_space = dir_total_space($dir); + if (($file_size + $already_filled_space) > $max_dir_space) { + return false; + } + } + return true; } diff --git a/main/inc/lib/formvalidator/Element/select_ajax.php b/main/inc/lib/formvalidator/Element/select_ajax.php index 8ce93ba312..fb77ce8a2e 100644 --- a/main/inc/lib/formvalidator/Element/select_ajax.php +++ b/main/inc/lib/formvalidator/Element/select_ajax.php @@ -53,14 +53,30 @@ class HTML_QuickForm_Select_Ajax extends HTML_QuickForm_select $dataCondition = '$("#'.$this->getAttribute('name').'").select2("data", '.$result.')'; $tags = ', tags : function() { return '.$result.'} '; } + $width = 'element'; + $givenWidth = $this->getAttribute('width'); + if (!empty($givenWidth)) { + $width = $givenWidth; + } + + //Get the minimumInputLength for select2 + $minimumInputLength = ($this->getAttribute('minimumInputLength') > 3)? + $this->getAttribute('minimumInputLength') : + 3 + ; + $plHolder = $this->getAttribute('placeholder'); + if (empty($plHolder)) { + $plHolder = get_lang('SelectAnOption'); + } + $html .= ''; + $return .= Display::grid_html($tableId); + return $return; + } + /** * Display a sortable table that contains an overview off all the progress of the user in a session * @author César Perales , Beeznest Team */ - function display_survey_overview($sessionId = 0, $courseId = 0, $surveyId = 0, $answer = 2) { + function display_survey_overview($sessionId = 0, $courseId = 0, $surveyId = 0, $date_from, $date_to) { $course = api_get_course_info_by_id($courseId); /** @@ -451,7 +571,7 @@ class MySpace { $action_links = ''; // jqgrid will use this URL to do the selects - $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_survey_overview&session_id=' . intval($sessionId) . '&course_id=' . intval($courseId) . '&survey_id=' . intval($surveyId); + $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_survey_overview&session_id=' . $sessionId . '&course_id=' . $courseId . '&survey_id=' . $surveyId . '&date_to=' . $date_to . '&date_from=' . $date_from; //Table Id $tableId = 'lpProgress'; @@ -481,7 +601,7 @@ class MySpace { * Display a sortable table that contains an overview off all the progress of the user in a session * @author César Perales , Beeznest Team */ - function display_tracking_progress_overview($sessionId = 0, $courseId = 0) { + static function display_tracking_progress_overview($sessionId = 0, $courseId = 0, $date_from, $date_to) { //The order is important you need to check the the $column variable in the model.ajax.php file $columns = array( @@ -490,15 +610,13 @@ class MySpace { get_lang('Username'), #get_lang('Profile'), get_lang('Total'), - get_lang('CourseDescription'), + get_lang('Courses'), get_lang('LearningPaths'), get_lang('Exercises'), get_lang('Forums'), get_lang('Assignments'), get_lang('ToolWiki'), get_lang('ToolSurvey'), - //course description - get_lang('CourseDescriptionProgress'), //Learning paths get_lang('LearnpathsTotal'), get_lang('LearnpathsDone'), @@ -534,56 +652,54 @@ class MySpace { //Column config $column_model = array( - array('name'=>'lastname', 'index'=>'lastname', 'align'=>'left', 'search' => 'true'), - array('name'=>'firstname', 'index'=>'firstname', 'align'=>'left', 'search' => 'true'), - array('name'=>'username', 'index'=>'username', 'align'=>'left', 'search' => 'true'), - #array('name'=>'profile', 'index'=>'username', 'align'=>'left', 'search' => 'true'), - array('name'=>'total', 'index'=>'total', 'align'=>'left', 'search' => 'true'), - array('name'=>'courses', 'index'=>'courses', 'align'=>'left', 'search' => 'true'), - array('name'=>'lessons', 'index'=>'lessons', 'align'=>'left', 'search' => 'true'), - array('name'=>'exercises', 'index'=>'exercises', 'align'=>'left', 'search' => 'true'), - array('name'=>'forums', 'index'=>'forums', 'align'=>'left', 'search' => 'true'), - array('name'=>'homeworks', 'index'=>'homeworks', 'align'=>'left', 'search' => 'true'), - array('name'=>'wikis', 'index'=>'wikis', 'align'=>'left', 'search' => 'true'), - array('name'=>'surveys', 'index'=>'surveys', 'align'=>'left', 'search' => 'true'), - //Course description - array('name'=>'course_description_progress', 'index'=>'course_description_progress', 'align'=>'left', 'search' => 'true'), + array('name'=>'lastname', 'index'=>'lastname', 'align'=>'left'), + array('name'=>'firstname', 'index'=>'firstname', 'align'=>'left'), + array('name'=>'username', 'index'=>'username', 'align'=>'left'), + #array('name'=>'profile', 'index'=>'username', 'align'=>'left'), + array('name'=>'total', 'index'=>'total', 'align'=>'left'), + array('name'=>'courses', 'index'=>'courses', 'align'=>'left', 'sortable' => 'false'), + array('name'=>'lessons', 'index'=>'lessons', 'align'=>'left', 'sortable' => 'false'), + array('name'=>'exercises', 'index'=>'exercises', 'align'=>'left', 'sortable' => 'false'), + array('name'=>'forums', 'index'=>'forums', 'align'=>'left', 'sortable' => 'false'), + array('name'=>'homeworks', 'index'=>'homeworks', 'align'=>'left', 'sortable' => 'false'), + array('name'=>'wikis', 'index'=>'wikis', 'align'=>'left', 'sortable' => 'false'), + array('name'=>'surveys', 'index'=>'surveys', 'align'=>'left', 'sortable' => 'false'), //Lessons - array('name'=>'lessons_total', 'index'=>'lessons_total', 'align'=>'left', 'search' => 'true'), - array('name'=>'lessons_done', 'index'=>'lessons_done', 'align'=>'left', 'search' => 'true'), - array('name'=>'lessons_left', 'index'=>'lessons_left', 'align'=>'left', 'search' => 'true'), - array('name'=>'lessons_progress', 'index'=>'lessons_progress', 'align'=>'left', 'search' => 'true'), + array('name'=>'lessons_total', 'index'=>'lessons_total', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'lessons_done', 'index'=>'lessons_done', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'lessons_left', 'index'=>'lessons_left', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'lessons_progress', 'index'=>'lessons_progress', 'align'=>'center', 'sortable' => 'false'), //Exercises - array('name'=>'exercises_total', 'index'=>'exercises_total', 'align'=>'left', 'search' => 'true'), - array('name'=>'exercises_done', 'index'=>'exercises_done', 'align'=>'left', 'search' => 'true'), - array('name'=>'exercises_left', 'index'=>'exercises_left', 'align'=>'left', 'search' => 'true'), - array('name'=>'exercises_progress', 'index'=>'exercises_progress', 'align'=>'left', 'search' => 'true'), + array('name'=>'exercises_total', 'index'=>'exercises_total', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'exercises_done', 'index'=>'exercises_done', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'exercises_left', 'index'=>'exercises_left', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'exercises_progress', 'index'=>'exercises_progress', 'align'=>'center', 'sortable' => 'false'), //Assignments - array('name'=>'forums_total', 'index'=>'forums_total', 'align'=>'left', 'search' => 'true'), - array('name'=>'forums_done', 'index'=>'forums_done', 'align'=>'left', 'search' => 'true'), - array('name'=>'forums_left', 'index'=>'forums_left', 'align'=>'left', 'search' => 'true'), - array('name'=>'forums_progress', 'index'=>'forums_progress', 'align'=>'left', 'search' => 'true'), + array('name'=>'forums_total', 'index'=>'forums_total', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'forums_done', 'index'=>'forums_done', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'forums_left', 'index'=>'forums_left', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'forums_progress', 'index'=>'forums_progress', 'align'=>'center', 'sortable' => 'false'), //Assignments - array('name'=>'assigments_total', 'index'=>'assigments_total', 'align'=>'left', 'search' => 'true'), - array('name'=>'assigments_done', 'index'=>'assigments_done', 'align'=>'left', 'search' => 'true'), - array('name'=>'assigments_left', 'index'=>'assigments_left', 'align'=>'left', 'search' => 'true'), - array('name'=>'assigments_progress', 'index'=>'assigments_progress', 'align'=>'left', 'search' => 'true'), + array('name'=>'assigments_total', 'index'=>'assigments_total', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'assigments_done', 'index'=>'assigments_done', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'assigments_left', 'index'=>'assigments_left', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'assigments_progress', 'index'=>'assigments_progress', 'align'=>'center', 'sortable' => 'false'), //Assignments - array('name'=>'wiki_total', 'index'=>'wiki_total', 'align'=>'left', 'search' => 'true'), - array('name'=>'wiki_revisions', 'index'=>'wiki_revisions', 'align'=>'left', 'search' => 'true'), - array('name'=>'wiki_read', 'index'=>'wiki_read', 'align'=>'left', 'search' => 'true'), - array('name'=>'wiki_unread', 'index'=>'wiki_unread', 'align'=>'left', 'search' => 'true'), - array('name'=>'wiki_progress', 'index'=>'wiki_progress', 'align'=>'left', 'search' => 'true'), + array('name'=>'wiki_total', 'index'=>'wiki_total', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'wiki_revisions', 'index'=>'wiki_revisions', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'wiki_read', 'index'=>'wiki_read', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'wiki_unread', 'index'=>'wiki_unread', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'wiki_progress', 'index'=>'wiki_progress', 'align'=>'center', 'sortable' => 'false'), //Surveys - array('name'=>'surveys_total', 'index'=>'surveys_total', 'align'=>'left', 'search' => 'true'), - array('name'=>'surveys_done', 'index'=>'surveys_done', 'align'=>'left', 'search' => 'true'), - array('name'=>'surveys_left', 'index'=>'surveys_left', 'align'=>'left', 'search' => 'true'), - array('name'=>'surveys_progress', 'index'=>'surveys_progress', 'align'=>'left', 'search' => 'true'), + array('name'=>'surveys_total', 'index'=>'surveys_total', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'surveys_done', 'index'=>'surveys_done', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'surveys_left', 'index'=>'surveys_left', 'align'=>'center', 'sortable' => 'false'), + array('name'=>'surveys_progress', 'index'=>'surveys_progress', 'align'=>'center', 'sortable' => 'false'), ); $action_links = ''; // jqgrid will use this URL to do the selects - $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_progress&session_id=' . intval($sessionId) . '&course_id=' . intval($courseId); + $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_progress&session_id=' . $sessionId . '&course_id=' . $courseId . '&date_to=' . $date_to . '&date_from=' . $date_from; //Table Id $tableId = 'progressOverview'; @@ -591,6 +707,47 @@ class MySpace { //Autowidth $extra_params['autowidth'] = 'true'; + $extra_params['shrinkToFit'] = 'true'; + + $extra_params['headertitles'] = 'true'; + + $extra_params['groupHeaders'] = array( + 'courses_detail' => array( + "startColumnName" => 'courses', + "numberOfColumns" => 7, + "titleText" => get_lang('Global'), + ), + 'lessons' => array( + "startColumnName" => 'lessons_total', + "numberOfColumns" => 4, + "titleText" => get_lang('LearningPaths'), + ), + 'exercises' => array( + "startColumnName" => 'exercises_total', + "numberOfColumns" => 4, + "titleText" => get_lang('Exercises'), + ), + 'forums' => array( + "startColumnName" => 'forums_total', + "numberOfColumns" => 4, + "titleText" => get_lang('Forums'), + ), + 'assignments' => array( + "startColumnName" => 'assigments_total', + "numberOfColumns" => 4, + "titleText" => get_lang('Assignments'), + ), + 'wikis' => array( + "startColumnName" => 'wiki_total', + "numberOfColumns" => 5, + "titleText" => get_lang('Wiki'), + ), + 'surveys' => array( + "startColumnName" => 'surveys_total', + "numberOfColumns" => 4, + "titleText" => get_lang('Survey'), + ), + ); //height auto $extra_params['height'] = 'auto'; @@ -614,16 +771,17 @@ class MySpace { * @author César Perales , Beeznest Team * @version Chamilo 1.9.6 */ - function display_tracking_access_overview($sessionId = 0, $courseId = 0, $studentId = '', $profile = '', $date_to, $date_from) { + static function display_tracking_access_overview($sessionId = 0, $courseId = 0, $studentId = '', $profile = '', $date_from, $date_to) { //The order is important you need to check the the $column variable in the model.ajax.php file $columns = array( get_lang('LoginDate'), - get_lang('Username'), - get_lang('Firstname'), - get_lang('Lastname'), + get_lang('UserName'), + get_lang('LastName'), + get_lang('FirstName'), get_lang('Clicks'), get_lang('IP'), get_lang('TimeLoggedIn'), + get_lang('Section'), ); $column_model = array( @@ -634,6 +792,7 @@ class MySpace { array('name'=>'clicks', 'index'=>'clicks', 'align'=>'left', 'search' => 'true'), array('name'=>'ip', 'index'=>'ip', 'align'=>'left', 'search' => 'true'), array('name'=>'timeloggedin', 'index'=>'timeLoggedIn', 'align'=>'left', 'search' => 'true'), + array('name'=>'session', 'index'=>'session', 'align'=>'left') ); $action_links = ''; diff --git a/main/newscorm/learnpathList.class.php b/main/newscorm/learnpathList.class.php index e53fafd592..0e1c5023ed 100644 --- a/main/newscorm/learnpathList.class.php +++ b/main/newscorm/learnpathList.class.php @@ -170,7 +170,7 @@ class learnpathList { * @param int Id of session * @return array List of lessons with lessons id as keys */ - function get_course_lessons($course_code, $session_id) { + static function get_course_lessons($course_code, $session_id) { $tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN); $course = api_get_course_info($course_code); diff --git a/main/newscorm/lp_ajax_save_item.php b/main/newscorm/lp_ajax_save_item.php index 4c6947a0b1..d86d760e8d 100644 --- a/main/newscorm/lp_ajax_save_item.php +++ b/main/newscorm/lp_ajax_save_item.php @@ -44,7 +44,7 @@ require_once 'aiccItem.class.php'; * @param array Interactions array * @param string Core exit SCORM string */ -function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1, $min = -1, $status = '', $time = 0, $suspend = '', $location = '', $interactions = array(), $core_exit = 'none') +function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1, $min = -1, $status = '', $time = 0, $suspend = '', $location = '', $interactions = array(), $core_exit = 'none', $sessionId = null, $courseId = null) { global $debug; $return = null; @@ -58,6 +58,9 @@ function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1, $mylp = null; $lpobject = Session::read('lpobject'); + if (!is_object($lpobject) && isset($sessionId) && isset($courseId)) { + $lpobject = new learnpathItem($lp_id, $user_id, $courseId); + } if (isset($lpobject)) { $oLP = unserialize($lpobject); if ($debug) error_log("lpobject was set"); @@ -305,5 +308,8 @@ echo save_item( (!empty($_REQUEST['suspend'])?$_REQUEST['suspend']:null), (!empty($_REQUEST['loc'])?$_REQUEST['loc']:null), $interactions, - (!empty($_REQUEST['core_exit'])?$_REQUEST['core_exit']:'') + (!empty($_REQUEST['core_exit'])?$_REQUEST['core_exit']:''), + '', + (!empty($_REQUEST['session_id'])?$_REQUEST['session_id']:''), + (!empty($_REQUEST['course_id'])?$_REQUEST['course_id']:'') ); diff --git a/main/newscorm/lp_controller.php b/main/newscorm/lp_controller.php index cf147003ae..2e67962e3f 100644 --- a/main/newscorm/lp_controller.php +++ b/main/newscorm/lp_controller.php @@ -864,6 +864,12 @@ switch ($action) { $_SESSION['oLP']->delete_lp_image(); } + $extraFieldValue = new ExtraFieldValue('lp'); + $params = array( + 'lp_id' => $_SESSION['oLP']->id + ); + $extraFieldValue->save_field_values($_REQUEST); + if ($_FILES['lp_preview_image']['size'] > 0) $_SESSION['oLP']->upload_image($_FILES['lp_preview_image']); diff --git a/main/newscorm/lp_edit.php b/main/newscorm/lp_edit.php index fd7d8a2115..a3d8552d57 100644 --- a/main/newscorm/lp_edit.php +++ b/main/newscorm/lp_edit.php @@ -23,9 +23,9 @@ if (isset($_SESSION['gradebook'])) { if (!empty($gradebook) && $gradebook == 'view') { $interbreadcrumb[] = array ( - 'url' => '../gradebook/'.$_SESSION['gradebook_dest'], - 'name' => get_lang('ToolGradebook') - ); + 'url' => '../gradebook/'.$_SESSION['gradebook_dest'], + 'name' => get_lang('ToolGradebook') + ); } $interbreadcrumb[] = array('url' => 'lp_controller.php?action=list', 'name' => get_lang('LearningPaths')); $interbreadcrumb[] = array('url' => api_get_self()."?action=build&lp_id=".$_SESSION['oLP']->get_id(), 'name' => $_SESSION['oLP']->get_name()); @@ -50,11 +50,6 @@ function activate_end_date() { '; - -Display::display_header(get_lang('CourseSettings'), 'Path'); - -echo $_SESSION['oLP']->build_action_menu(); - $gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : null; $defaults=array(); @@ -198,6 +193,9 @@ if (api_is_platform_admin()) { $defaults['use_max_score'] = $_SESSION['oLP']->use_max_score; } +$extraField = new ExtraField('lp'); +$extra = $extraField->addElements($form, $_SESSION['oLP']->get_id()); + //Submit button $form->addElement('style_submit_button', 'Submit',get_lang('SaveLPSettings'),'class="save"'); @@ -205,12 +203,24 @@ $form->addElement('style_submit_button', 'Submit',get_lang('SaveLPSettings'),'cl $form->addElement('hidden', 'action', 'update_lp'); $form->addElement('hidden', 'lp_id', $_SESSION['oLP']->get_id()); +$htmlHeadXtra[] = ''; +$htmlHeadXtra[] = ''; +$htmlHeadXtra[] =''; + $defaults['publicated_on'] = ($publicated_on!='0000-00-00 00:00:00' && !empty($publicated_on))? api_get_local_time($publicated_on) : date('Y-m-d 12:00:00'); $defaults['expired_on'] = ($expired_on !='0000-00-00 00:00:00' && !empty($expired_on) )? api_get_local_time($expired_on): date('Y-m-d 12:00:00',time()+84600); $form->setDefaults($defaults); +Display::display_header(get_lang('CourseSettings'), 'Path'); + +echo $_SESSION['oLP']->build_action_menu(); + echo '
'; if ($_SESSION['oLP']->get_hide_toc_frame() == 1) { diff --git a/main/newscorm/lp_stats.php b/main/newscorm/lp_stats.php index 9c89bac5c3..c5823e4418 100644 --- a/main/newscorm/lp_stats.php +++ b/main/newscorm/lp_stats.php @@ -48,7 +48,7 @@ $course_id = $course_info['real_id']; if (isset($_GET['student_id'])) { $student_id = intval($_GET['student_id']); } -$session_id = api_get_session_id(); +$session_id = ($_GET['id_session'])? intval($_GET['id_session']) : api_get_session_id(); $session_condition = api_get_session_condition($session_id); //When origin is not set that means that the lp_stats are viewed from the "man running" icon @@ -859,10 +859,10 @@ if (!empty($a_my_id)) { //var_dump($my_studen_id, $my_course_id,$a_my_id); if (isset($_GET['extend_attempt'])) { //"Right green cross" extended - $total_score = Tracking::get_avg_student_score($my_studen_id, $my_course_id, $a_my_id, api_get_session_id(), false, false); + $total_score = Tracking::get_avg_student_score($my_studen_id, $my_course_id, $a_my_id, $session_id, false, false); } else { //"Left green cross" extended - $total_score = Tracking::get_avg_student_score($my_studen_id, $my_course_id, $a_my_id, api_get_session_id(), false, true); + $total_score = Tracking::get_avg_student_score($my_studen_id, $my_course_id, $a_my_id, $session_id, false, true); } } else { // Extend all "left green cross" @@ -870,12 +870,12 @@ if (!empty($a_my_id)) { $my_course_id = Database::escape_string($_GET['course']); // var_dump($student_id, $my_course_id ); if (!empty($student_id) && !empty($my_course_id)) { - $total_score = Tracking::get_avg_student_score($student_id, $my_course_id, array(intval($_GET['lp_id'])), api_get_session_id(), false, false); + $total_score = Tracking::get_avg_student_score($student_id, $my_course_id, array(intval($_GET['lp_id'])), $session_id, false, false); } else { $total_score = 0; } } else { - $total_score = Tracking::get_avg_student_score(api_get_user_id(), api_get_course_id(), array(intval($_GET['lp_id'])), api_get_session_id(), false, false); + $total_score = Tracking::get_avg_student_score(api_get_user_id(), api_get_course_id(), array(intval($_GET['lp_id'])), $session_id, false, false); } } diff --git a/main/newscorm/scorm_api.php b/main/newscorm/scorm_api.php index de39555b2b..3c86785096 100644 --- a/main/newscorm/scorm_api.php +++ b/main/newscorm/scorm_api.php @@ -183,8 +183,8 @@ olms.lms_item_lesson_mode = 'get_lesson_mode();?>'; olms.lms_item_launch_data = 'get_launch_data());?>'; olms.lms_item_core_exit = 'get_core_exit();?>'; olms.lms_course_id = 'get_course_int_id(); ?>'; +olms.lms_session_id = ''; olms.lms_course_code = 'getCourseCode(); ?>'; - get_items_details_as_js('olms.lms_item_types');?> olms.asset_timer = 0; @@ -1498,13 +1498,31 @@ function switch_item(current_item, next_item){ * @return void * @uses lp_ajax_save_item.php through an AJAX call */ -function xajax_save_item(lms_lp_id, lms_user_id, lms_view_id, lms_item_id, score, max, min, lesson_status, session_time, suspend_data, lesson_location, interactions, lms_item_core_exit, item_type) { +function xajax_save_item( + lms_lp_id, + lms_user_id, + lms_view_id, + lms_item_id, + score, + max, + min, + lesson_status, + session_time, + suspend_data, + lesson_location, + interactions, + lms_item_core_exit, + item_type, + session_id, + course_id) { var params = ''; params += 'lid='+lms_lp_id+'&uid='+lms_user_id+'&vid='+lms_view_id; params += '&iid='+lms_item_id+'&s='+score+'&max='+max+'&min='+min; params += '&status='+lesson_status+'&t='+session_time; params += '&suspend='+suspend_data+'&loc='+lesson_location; params += '&core_exit='+lms_item_core_exit; + params += '&session_id='+session_id; + params += '&course_id='+course_id; //console.info(session_time); if (olms.lms_lp_type == 1 || item_type == 'document') { logit_lms('xajax_save_item with params:' + params,3); diff --git a/main/session/index.php b/main/session/index.php index f6cac273c1..8cbf5d45fb 100644 --- a/main/session/index.php +++ b/main/session/index.php @@ -119,7 +119,16 @@ if (!empty($course_list)) { true ); $lp_list = $list->get_flat_list(); - $lp_count = count($lp_list); + + $lp_count = 0; + + if(!empty($lp_list)) { + foreach ($lp_list as $valLp) { + if($valLp['lp_visibility']) { + $lp_count++; + } + } + } $course_info = api_get_course_info($course_data['code']); $exercise_count = count(get_all_exercises($course_info, $session_id, true));