From b4bd2505c91d0e720dd9262f973161a85e4a4594 Mon Sep 17 00:00:00 2001 From: Julio Montoya Date: Thu, 17 Apr 2014 15:50:18 +0200 Subject: [PATCH] Adding lp extra fields BT#7975 --- main/admin/extra_field_options.php | 167 +++ main/admin/extra_field_workflow.php | 212 +++ main/admin/extra_fields.php | 216 +++ main/admin/specific_fields_add.php | 2 +- main/inc/ajax/extra_field.ajax.php | 30 + main/inc/ajax/model.ajax.php | 34 +- main/inc/lib/autoload.class.php | 5 + main/inc/lib/database.constants.inc.php | 4 + main/inc/lib/extra_field.lib.php | 1646 +++++++++++++++++++++++ main/inc/lib/extra_field_option.lib.php | 659 +++++++++ main/inc/lib/extra_field_value.lib.php | 654 +++++++++ main/inc/lib/model.lib.php | 1 + main/newscorm/lp_controller.php | 6 + main/newscorm/lp_edit.php | 26 +- 14 files changed, 3636 insertions(+), 26 deletions(-) create mode 100644 main/admin/extra_field_options.php create mode 100644 main/admin/extra_field_workflow.php create mode 100644 main/admin/extra_fields.php create mode 100644 main/inc/ajax/extra_field.ajax.php create mode 100644 main/inc/lib/extra_field.lib.php create mode 100644 main/inc/lib/extra_field_option.lib.php create mode 100644 main/inc/lib/extra_field_value.lib.php 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..3002f91a2a --- /dev/null +++ b/main/admin/extra_fields.php @@ -0,0 +1,216 @@ + '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', + 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/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 03c31e559c..c1a61dbff5 100644 --- a/main/inc/ajax/model.ajax.php +++ b/main/inc/ajax/model.ajax.php @@ -292,7 +292,7 @@ switch ($action) { $count = count($users); break; - /*case 'get_extra_fields': + case 'get_extra_fields': $type = $_REQUEST['type']; $obj = new ExtraField($type); $count = $obj->get_count(); @@ -302,7 +302,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(); @@ -618,10 +618,10 @@ switch ($action) { $columns = array( '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' => $where_condition, @@ -636,7 +636,7 @@ switch ($action) { $exerciseId = intval($_GET['exercise_id']); $date_from = $_GET['date_from']; $date_to = $_GET['date_to']; - + $columns = array( 'session', 'exercise_id', @@ -785,7 +785,7 @@ switch ($action) { $date_from = $_GET['date_from']; $date_to = $_GET['date_to']; } - $result = SessionManager::get_session_progress($sessionId, $courseId, $date_from, $date_to, + $result = SessionManager::get_session_progress($sessionId, $courseId, $date_from, $date_to, array( 'where' => $where_condition, 'order' => "$sidx $sord", @@ -1010,27 +1010,27 @@ switch ($action) { 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) { @@ -1048,13 +1048,13 @@ switch ($action) { $result[$i]['exer' . $j] = $grade; $j++; } - + if ($finalScore > 20) { $finalScore = 20; } - + $result[$i]['finalScore'] = number_format($finalScore, 2); - + $i++; } break; @@ -1128,8 +1128,8 @@ $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', @@ -1177,7 +1177,7 @@ if (in_array($action, $allowed_actions)) { case 'csv': default: //TODO add date if exists - $file_name = (!empty($action)) ? $action : 'company_report'; + $file_name = (!empty($action)) ? $action : 'company_report'; Export::export_table_csv($array, $file_name); break; } diff --git a/main/inc/lib/autoload.class.php b/main/inc/lib/autoload.class.php index 156937947b..f693c2ec71 100644 --- a/main/inc/lib/autoload.class.php +++ b/main/inc/lib/autoload.class.php @@ -917,6 +917,11 @@ class Autoload $result['UserForm'] = '/main/gradebook/lib/fe/userform.class.php'; $result['UserGroup'] = '/main/inc/lib/usergroup.lib.php'; $result['UserManager'] = '/main/inc/lib/usermanager.lib.php'; + + $result['ExtraField'] = '/main/inc/lib/extra_field.lib.php'; + $result['ExtraFieldOption'] = '/main/inc/lib/extra_field_option.lib.php'; + $result['ExtraFieldValue'] = '/main/inc/lib/extra_field_value.lib.php'; + $result['UserTable'] = '/main/gradebook/lib/fe/usertable.class.php'; $result['Utf8'] = '/main/inc/lib/system/text/utf8.class.php'; $result['Utf8Decoder'] = '/main/inc/lib/system/text/utf8_decoder.class.php'; 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/extra_field.lib.php b/main/inc/lib/extra_field.lib.php new file mode 100644 index 0000000000..d4d71e8f29 --- /dev/null +++ b/main/inc/lib/extra_field.lib.php @@ -0,0 +1,1646 @@ + '=', //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') + ); + + if ($action == 'edit') { + if (in_array( + $defaults['field_type'], + array(ExtraField::FIELD_TYPE_SELECT, ExtraField::FIELD_TYPE_DOUBLE_SELECT) + ) + ) { + $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/model.lib.php b/main/inc/lib/model.lib.php index 1d92b31374..7a59f628b4 100644 --- a/main/inc/lib/model.lib.php +++ b/main/inc/lib/model.lib.php @@ -164,6 +164,7 @@ class Model $params['created_at'] = api_get_utc_datetime(); } + if (!empty($params)) { $id = Database::insert($this->table, $params, $show_query); if (is_numeric($id)) { diff --git a/main/newscorm/lp_controller.php b/main/newscorm/lp_controller.php index baeedff8ee..4686924dac 100644 --- a/main/newscorm/lp_controller.php +++ b/main/newscorm/lp_controller.php @@ -859,6 +859,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) {