Search : Add search diagnosis from preprodparkur - task beeznest#18899

pull/3939/head
Christian 4 years ago
parent e6cbb89c10
commit 740ea07709
  1. 20
      assets/vue/components/layout/DashboardLayout.vue
  2. 6
      assets/vue/store/security.js
  3. 11
      public/main/inc/ajax/extra_field.ajax.php
  4. 56
      public/main/inc/ajax/model.ajax.php
  5. 71
      public/main/inc/lib/extra_field.lib.php
  6. 4
      public/main/inc/lib/extra_field_value.lib.php
  7. 6
      public/main/inc/lib/pear/HTML/QuickForm/element.php
  8. 121
      public/main/inc/lib/sessionmanager.lib.php
  9. 6
      public/main/search/bootstrap/bootstrap.min.css
  10. 6
      public/main/search/bootstrap/bootstrap.min.js
  11. 9
      public/main/search/cropper/cropper.min.css
  12. 10
      public/main/search/cropper/cropper.min.js
  13. 1231
      public/main/search/load_search.php
  14. 881
      public/main/search/search.php
  15. 1
      public/main/search/select2/select2.min.css
  16. 2
      public/main/search/select2/select2.min.js
  17. 14
      public/main/template/default/search/search_extra_field.html.twig
  18. 4
      src/CoreBundle/Entity/ExtraFieldSavedSearch.php
  19. 2
      src/CoreBundle/Settings/SessionSettingsSchema.php

@ -284,6 +284,24 @@ export default {
['Courses category', 'mdi-book', 'CourseCategoryList'], ['Courses category', 'mdi-book', 'CourseCategoryList'],
], ],
}), }),
updated() {
if (this.isAuthenticated) {
console.log(this.linksUser);
if (this.isBoss) {
if(!this.linksUser.some(data => data.id === 'load_search')) {
this.linksUser.push({icon: 'mdi-format-list-checks', url: '/main/search/load_search.php', text: 'Diagnosis Management', id: 'load_search'});
}
if(!this.linksUser.some(data => data.id === 'search')) {
this.linksUser.push({icon: 'mdi-account-search', url: '/main/search/search.php', text: 'Diagnostic Form', id: 'search'});
}
}
if (this.isStudent) {
if(!this.linksUser.some(data => data.id === 'search')) {
this.linksUser.push({icon: 'mdi-account-search', url: '/main/search/search.php', text: 'Diagnostic Form', id: 'search'});
}
}
}
},
created() { created() {
//console.log('dashboard created'); //console.log('dashboard created');
this.legacyContent = ''; this.legacyContent = '';
@ -314,6 +332,8 @@ export default {
...mapGetters({ ...mapGetters({
'isAuthenticated': 'security/isAuthenticated', 'isAuthenticated': 'security/isAuthenticated',
'isAdmin': 'security/isAdmin', 'isAdmin': 'security/isAdmin',
'isBoss': 'security/isBoss',
'isStudent': 'security/isStudent',
'currentUser': 'security/getUser', 'currentUser': 'security/getUser',
}), }),
}, },

@ -41,6 +41,12 @@ export default {
return getters.hasRole('ROLE_CURRENT_COURSE_TEACHER'); return getters.hasRole('ROLE_CURRENT_COURSE_TEACHER');
}, },
isBoss(state, getters) {
return getters.hasRole('ROLE_STUDENT_BOSS');
},
isStudent(state, getters) {
return getters.hasRole('ROLE_STUDENT');
},
getUser(state) { getUser(state) {
return state.user; return state.user;
}, },

@ -49,13 +49,10 @@ switch ($action) {
$tags = Database::getManager() $tags = Database::getManager()
->getRepository(Tag::class) ->getRepository(Tag::class)
->createQueryBuilder('t') ->findBy([
->where("t.tag LIKE :tag") 'tag' => $tag,
->andWhere('t.fieldId = :field') 'field' => $fieldId,
->setParameter('field', $fieldId) ]);
->setParameter('tag', "$tag%")
->getQuery()
->getResult();
/** @var Tag $tag */ /** @var Tag $tag */
foreach ($tags as $tag) { foreach ($tags as $tag) {

@ -800,6 +800,21 @@ switch ($action) {
break; break;
case 'get_sessions': case 'get_sessions':
$listType = isset($_REQUEST['list_type']) ? $_REQUEST['list_type'] : SessionManager::getDefaultSessionTab(); $listType = isset($_REQUEST['list_type']) ? $_REQUEST['list_type'] : SessionManager::getDefaultSessionTab();
$language = isset($_REQUEST['lang']) ? $_REQUEST['lang'] : '';
$sessionColumns = SessionManager::getGridColumns($listType);
$columns = $sessionColumns['simple_column_name'];
$loadExtraFields = isset($_REQUEST['load_extra_field']) ? $_REQUEST['load_extra_field'] : '';
$extraFieldsToLoad = [];
if (!empty($loadExtraFields)) {
$loadExtraFields = explode(',', $loadExtraFields);
foreach ($loadExtraFields as $fieldId) {
$extraField = new ExtraField('session');
$fieldData = $extraField->get($fieldId);
$extraFieldsToLoad[] = $fieldData;
}
}
if ('custom' === $listType && api_get_configuration_value('allow_session_status')) { if ('custom' === $listType && api_get_configuration_value('allow_session_status')) {
$whereCondition .= ' AND (s.status IN ("'.SessionManager::STATUS_PLANNED.'", "'.SessionManager::STATUS_PROGRESS.'") ) '; $whereCondition .= ' AND (s.status IN ("'.SessionManager::STATUS_PLANNED.'", "'.SessionManager::STATUS_PROGRESS.'") ) ';
@ -812,6 +827,15 @@ switch ($action) {
); );
break; break;
case 'custom': case 'custom':
case 'simple':
$count = SessionManager::getSessionsForAdmin(
['where' => $whereCondition, 'extra' => $extra_fields],
true,
[],
$extraFieldsToLoad,
$language
);
break;
case 'active': case 'active':
case 'close': case 'close':
case 'all': case 'all':
@ -1906,9 +1930,25 @@ switch ($action) {
} }
break; break;
case 'get_sessions': case 'get_sessions':
$listType = isset($_REQUEST['list_type']) ? $_REQUEST['list_type'] : 'simple';
$language = isset($_REQUEST['lang']) ? $_REQUEST['lang'] : '';
$order = isset($_REQUEST['order']) ? $_REQUEST['order'] : '';
$sessionColumns = SessionManager::getGridColumns($listType); $sessionColumns = SessionManager::getGridColumns($listType);
$columns = $sessionColumns['simple_column_name']; $columns = $sessionColumns['simple_column_name'];
$loadExtraFields = isset($_REQUEST['load_extra_field']) ? $_REQUEST['load_extra_field'] : '';
$extraFieldsToLoad = [];
if (!empty($loadExtraFields)) {
$loadExtraFields = explode(',', $loadExtraFields);
foreach ($loadExtraFields as $fieldId) {
$extraField = new ExtraField('session');
$fieldData = $extraField->get($fieldId);
$extraFieldsToLoad[] = $fieldData;
}
}
$sidx = in_array($sidx, $columns) ? $sidx : 'name'; $sidx = in_array($sidx, $columns) ? $sidx : 'name';
switch ($listType) { switch ($listType) {
case 'complete': case 'complete':
@ -1921,9 +1961,23 @@ switch ($action) {
] ]
); );
break; break;
case 'custom':
case 'simple':
$result = SessionManager::getSessionsForAdmin(
[
'where' => $whereCondition,
'order' => "$sidx $sord, s.name",
'extra' => $extra_fields,
'limit' => "$start , $limit",
],
false,
$sessionColumns,
$extraFieldsToLoad,
$language,
);
break;
case 'active': case 'active':
case 'close': case 'close':
case 'custom':
case 'all': case 'all':
$result = SessionManager::formatSessionsAdminForGrid( $result = SessionManager::formatSessionsAdminForGrid(
[ [

@ -1198,7 +1198,74 @@ class ExtraField extends Model
$options[$optionDetails['option_value']] = $optionDetails['display_text']; $options[$optionDetails['option_value']] = $optionDetails['display_text'];
} }
} }
if ($orderDependingDefaults) {
if (isset($extraData['extra_'.$variable])) {
$defaultOptions = $extraData['extra_'.$variable];
$firstList = [];
if ($addEmptyOptionSelects) {
$firstList[] = '';
}
foreach ($defaultOptions as $key) {
if (isset($options[$key])) {
$firstList[$key] = $options[$key];
}
}
if (!empty($firstList)) {
$options = array_merge($firstList, $options);
}
} else {
$firstList = [];
if ($addEmptyOptionSelects) {
$firstList[] = ' ';
$options = array_merge($firstList, $options);
}
}
}
// OFAJ
$separateValue = 0;
if (isset($separateExtraMultipleSelect[$variable])) {
$separateValue = $separateExtraMultipleSelect[$variable];
}
if ($separateValue > 0) {
for ($i = 0; $i < $separateValue; $i++) {
$form->addSelect(
'extra_'.$variable.'['.$i.']',
$customLabelsExtraMultipleSelect[$variable][$i],
$options,
['id' => 'extra_'.$variable.'_'.$i]
);
}
} else {
// Ofaj
$attributes = ['multiple' => 'multiple', 'id' => 'extra_'.$variable];
$chosenSelect = [
'ecouter',
'lire',
'participer_a_une_conversation',
's_exprimer_oralement_en_continu',
'ecrire',
];
if (in_array($variable, $chosenSelect)) {
$attributes['select_chosen'] = true;
}
// default behaviour
$form->addSelect( $form->addSelect(
'extra_'.$variable,
$field_details['display_text'],
$options,
$attributes,
);
}
if ($freezeElement) {
$form->freeze('extra_'.$variable);
}
/*$form->addSelect(
'extra_'.$variable, 'extra_'.$variable,
$field_details['display_text'], $field_details['display_text'],
$options, $options,
@ -1209,7 +1276,7 @@ class ExtraField extends Model
); );
if ($freezeElement) { if ($freezeElement) {
$form->freeze('extra_'.$variable); $form->freeze('extra_'.$variable);
} }*/
break; break;
case self::FIELD_TYPE_DATE: case self::FIELD_TYPE_DATE:
$form->addDatePicker('extra_'.$variable, $field_details['display_text']); $form->addDatePicker('extra_'.$variable, $field_details['display_text']);
@ -1275,7 +1342,7 @@ class ExtraField extends Model
$tagsSelect = $form->addSelect( $tagsSelect = $form->addSelect(
'extra_'.$variable.'['.$i.']', 'extra_'.$variable.'['.$i.']',
$customLabelsExtraMultipleSelect[$variable][$i], //$field_details['display_text'], $customLabelsExtraMultipleSelect[$variable][$i], //$field_details['display_text'],
null, [],
['id' => 'extra_'.$variable.'_'.$i] ['id' => 'extra_'.$variable.'_'.$i]
); );

@ -234,16 +234,18 @@ class ExtraFieldValue extends Model
} }
} }
if (!empty($tags)) {
foreach ($tags as $tag) { foreach ($tags as $tag) {
$tagUses = $em $tagUses = $em
->getRepository(ExtraFieldRelTag::class) ->getRepository(ExtraFieldRelTag::class)
->findBy([ ->findBy([
'tagId' => $tag->getId(), 'tag' => $tag->getId(),
]); ]);
$tag->setCount(count($tagUses) + 1); $tag->setCount(count($tagUses) + 1);
$em->persist($tag); $em->persist($tag);
} }
}
$em->flush(); $em->flush();

@ -386,10 +386,9 @@ class HTML_QuickForm_element extends HTML_Common
$elementName $elementName
); );
$myVar = "['$replacedName']"; $myVar = "['$replacedName']";
return eval("return (isset(\$values$myVar)) ? \$values$myVar : null;");
return isset($values[$myVar]) ? $values[$myVar] : null; //return isset($values[$myVar]) ? $values[$myVar] : null;
} }
return null; return null;
} }
@ -416,7 +415,6 @@ class HTML_QuickForm_element extends HTML_Common
// constant values override both default and submitted ones // constant values override both default and submitted ones
// default values are overridden by submitted. // default values are overridden by submitted.
$value = $this->_findValue($caller->_constantValues); $value = $this->_findValue($caller->_constantValues);
if (null === $value) { if (null === $value) {
$value = $this->_findValue($caller->_submitValues); $value = $this->_findValue($caller->_submitValues);
if (null === $value) { if (null === $value) {

@ -419,7 +419,7 @@ class SessionManager
SELECT DISTINCT SELECT DISTINCT
IF ( IF (
(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR (s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
(s.access_start_date IS NULL AND s.access_end_date = IS NULL ) OR (s.access_start_date IS NULL AND s.access_end_date IS NULL ) OR
(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR (s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
('$today' <= s.access_end_date AND s.access_start_date IS NULL) ('$today' <= s.access_end_date AND s.access_start_date IS NULL)
, 1, 0) as session_active, , 1, 0) as session_active,
@ -7557,6 +7557,16 @@ class SessionManager
} }
foreach ($sessionFieldValueList as $sessionFieldValue) { foreach ($sessionFieldValueList as $sessionFieldValue) {
// Match session field values to session
if ($sessionFieldValue['item_id'] != $sessionId) {
continue;
}
// Check if session field value is set in session field list
if (!isset($fields[$sessionFieldValue['field_id']])) {
continue;
}
$extrafieldVariable = $fields[$sessionFieldValue['field_id']]; $extrafieldVariable = $fields[$sessionFieldValue['field_id']];
$extrafieldValue = $sessionFieldValue['value']; $extrafieldValue = $sessionFieldValue['value'];
@ -8260,6 +8270,109 @@ class SessionManager
]; ];
} }
break; break;
case 'simple':
$columns = [
'#',
get_lang('Name'),
get_lang('Category'),
get_lang('Session Display Start Date'),
get_lang('Session Display End Date'),
get_lang('Visibility'),
];
$columnModel = [
[
'name' => 'id',
'index' => 's.id',
'width' => '160',
'hidden' => 'true',
],
[
'name' => 'name',
'index' => 's.name',
'width' => '160',
'align' => 'left',
'search' => 'true',
'searchoptions' => ['sopt' => $operators],
],
[
'name' => 'category_name',
'index' => 'category_name',
'width' => '40',
'align' => 'left',
'search' => 'true',
'searchoptions' => ['sopt' => $operators],
],
[
'name' => 'display_start_date',
'index' => 'display_start_date',
'width' => '50',
'align' => 'left',
'search' => 'true',
'searchoptions' => [
'dataInit' => 'date_pick_today',
'sopt' => $date_operators,
],
],
[
'name' => 'display_end_date',
'index' => 'display_end_date',
'width' => '50',
'align' => 'left',
'search' => 'true',
'searchoptions' => [
'dataInit' => 'date_pick_one_month',
'sopt' => $date_operators,
],
],
[
'name' => 'visibility',
'index' => 'visibility',
'width' => '40',
'align' => 'left',
'search' => 'false',
],
];
if ($showCount) {
$columns[] = get_lang('Users');
$columnModel[] = [
'name' => 'users',
'index' => 'users',
'width' => '20',
'align' => 'left',
'search' => 'false',
];
// ofaj
$columns[] = get_lang('Teachers');
$columnModel[] = [
'name' => 'teachers',
'index' => 'teachers',
'width' => '20',
'align' => 'left',
'search' => 'false',
];
}
if (api_get_configuration_value('allow_session_status')) {
$columns[] = get_lang('SessionStatus');
$list = self::getStatusList();
$listToString = '';
foreach ($list as $statusId => $status) {
$listToString .= $statusId.':'.$status.';';
}
$columnModel[] = ['name' => 'status', 'index' => 'status', 'width' => '25', 'align' => 'left', 'search' => 'true', 'stype' => 'select',
// for the bottom bar
'searchoptions' => [
'defaultValue' => '1',
'value' => $listToString,
],
];
}
break;
case 'complete': case 'complete':
$columns = [ $columns = [
get_lang('Name'), get_lang('Name'),
@ -8346,8 +8459,8 @@ class SessionManager
'#', '#',
get_lang('Name'), get_lang('Name'),
get_lang('Category'), get_lang('Category'),
get_lang('SessionDisplayStartDate'), get_lang('Start date to display'),
get_lang('SessionDisplayEndDate'), get_lang('End date to display'),
get_lang('Visibility'), get_lang('Visibility'),
]; ];
$columnModel = [ $columnModel = [
@ -8481,7 +8594,7 @@ class SessionManager
'sortable' => 'false', 'sortable' => 'false',
'search' => 'false', 'search' => 'false',
]; ];
$columns[] = get_lang('Detail'); $columns[] = get_lang('Actions');
} }
$columnName = []; $columnName = [];

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,9 @@
/*!
* Cropper v1.0.0
* https://github.com/fengyuanchen/cropper
*
* Copyright (c) 2014-2015 Fengyuan Chen and contributors
* Released under the MIT license
*
* Date: 2015-10-10T02:10:06.999Z
*/.cropper-container{position:relative;overflow:hidden;font-size:0;line-height:0;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;direction:ltr!important;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.cropper-container img{display:block;width:100%;min-width:0!important;max-width:none!important;height:100%;min-height:0!important;max-height:none!important;image-orientation:0deg!important}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal{position:absolute;top:0;right:0;bottom:0;left:0}.cropper-drag-box{background-color:#fff;filter:alpha(opacity=0);opacity:0}.cropper-dashed,.cropper-modal{filter:alpha(opacity=50);opacity:.5}.cropper-modal{background-color:#000}.cropper-view-box{display:block;width:100%;height:100%;overflow:hidden;outline:#39f solid 1px;outline-color:rgba(51,153,255,.75)}.cropper-dashed{position:absolute;display:block;border:0 dashed #eee}.cropper-dashed.dashed-h{top:33.33333%;left:0;width:100%;height:33.33333%;border-top-width:1px;border-bottom-width:1px}.cropper-dashed.dashed-v{top:0;left:33.33333%;width:33.33333%;height:100%;border-right-width:1px;border-left-width:1px}.cropper-center{position:absolute;top:50%;left:50%;display:block;width:0;height:0;filter:alpha(opacity=75);opacity:.75}.cropper-center:after,.cropper-center:before{position:absolute;display:block;content:" ";background-color:#eee}.cropper-center:before{top:0;left:-3px;width:7px;height:1px}.cropper-center:after{top:-3px;left:0;width:1px;height:7px}.cropper-face,.cropper-line,.cropper-point{position:absolute;display:block;width:100%;height:100%;filter:alpha(opacity=10);opacity:.1}.cropper-face{top:0;left:0;background-color:#fff}.cropper-line,.cropper-point{background-color:#39f}.cropper-line.line-e{top:0;right:-3px;width:5px;cursor:e-resize}.cropper-line.line-n{top:-3px;left:0;height:5px;cursor:n-resize}.cropper-line.line-w{top:0;left:-3px;width:5px;cursor:w-resize}.cropper-line.line-s{bottom:-3px;left:0;height:5px;cursor:s-resize}.cropper-point{width:5px;height:5px;filter:alpha(opacity=75);opacity:.75}.cropper-point.point-e{top:50%;right:-3px;margin-top:-3px;cursor:e-resize}.cropper-point.point-n{top:-3px;left:50%;margin-left:-3px;cursor:n-resize}.cropper-point.point-w{top:50%;left:-3px;margin-top:-3px;cursor:w-resize}.cropper-point.point-s{bottom:-3px;left:50%;margin-left:-3px;cursor:s-resize}.cropper-point.point-ne{top:-3px;right:-3px;cursor:ne-resize}.cropper-point.point-nw{top:-3px;left:-3px;cursor:nw-resize}.cropper-point.point-sw{bottom:-3px;left:-3px;cursor:sw-resize}.cropper-point.point-se{right:-3px;bottom:-3px;width:20px;height:20px;cursor:se-resize;filter:alpha(opacity=100);opacity:1}.cropper-point.point-se:before{position:absolute;right:-50%;bottom:-50%;display:block;width:200%;height:200%;content:" ";background-color:#39f;filter:alpha(opacity=0);opacity:0}@media (min-width:768px){.cropper-point.point-se{width:15px;height:15px}}@media (min-width:992px){.cropper-point.point-se{width:10px;height:10px}}@media (min-width:1200px){.cropper-point.point-se{width:5px;height:5px;filter:alpha(opacity=75);opacity:.75}}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-invisible{filter:alpha(opacity=0);opacity:0}.cropper-hide{position:absolute;display:block;width:0;height:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -0,0 +1,881 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\ExtraFieldSavedSearch;
use Chamilo\CoreBundle\Entity\User;
//use Chamilo\CoreBundle\Entity\ExtraField;
use ChamiloSession as Session;
$cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
if ('false' === api_get_setting('session.allow_search_diagnostic')) {
api_not_allowed();
}
api_block_anonymous_users();
$userId = api_get_user_id();
$userInfo = api_get_user_info();
$em = Database::getManager();
$adminPermissions = true;
/** @var ExtraFieldSavedSearch $saved */
$search = [
'user' => $userId,
];
$extraFieldSavedSearchRepo = $em->getRepository(ExtraFieldSavedSearch::class);
$items = $extraFieldSavedSearchRepo->findBy($search);
$extraFieldSession = new ExtraField('session');
$extraFieldValueSession = new ExtraFieldValue('session');
$filter = false;
$extraFieldValue = new ExtraFieldValue('user');
$wantStage = $extraFieldValue->get_values_by_handler_and_field_variable(api_get_user_id(), 'filiere_want_stage');
$diagnosisComplete = $extraFieldValue->get_values_by_handler_and_field_variable(
api_get_user_id(),
'diagnosis_completed'
);
$diagnosisComplete = false;
if ($diagnosisComplete && isset($diagnosisComplete['value']) && $diagnosisComplete['value'] == 1) {
if (!isset($_GET['result'])) {
header('Location:'.api_get_self().'?result=1');
exit;
}
}
$hide = true;
if ($wantStage !== false) {
$hide = $wantStage['value'] === 'yes';
}
$defaultValueStatus = 'extraFiliere.hide()';
if ($hide === false) {
$defaultValueStatus = '';
}
$url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php?a=order&user_id='.$userId;
// Use current user language
$langInfo = api_get_language_from_iso($userInfo['language']);
$targetLanguage = $langInfo->getEnglishName();
$theme = 'theme_fr';
switch ($targetLanguage) {
case 'italian':
$theme = 'theme_it';
break;
case 'polish':
$theme = 'theme_pl';
break;
case 'spanish':
$theme = 'theme_es';
break;
case 'french2':
case 'french':
$theme = 'theme_fr';
break;
case 'german2':
case 'german':
$theme = 'theme_de';
break;
}
$htmlHeadXtra[] = '
<style>
input[type="checkbox"], input[type="radio"] {
appearance: auto !important;
font-size: 14px;
margin-left: 0px !important;
height: auto !important;
width: auto !important;
}
form label, input {
font-size: 15px !important;
font-weight: normal !important;
}
.btn {
padding: 0px 12px !important;
}
</style>
<link href="bootstrap/bootstrap.min.css" rel="stylesheet" media="screen" type="text/css" />
<script src="bootstrap/bootstrap.min.js"></script>
<link href="select2/select2.min.css" rel="stylesheet" media="screen" type="text/css" />
<script src="select2/select2.min.js"></script>
';
$htmlHeadXtra[] = '<script>
$(function() {
var themeDefault = "extra_'.$theme.'";
var extraFiliere = $("input[name=\'extra_filiere[extra_filiere]\']").parent().parent().parent();
'.$defaultValueStatus.'
$("input[name=\'extra_filiere_want_stage[extra_filiere_want_stage]\']").change(function() {
if ($(this).val() == "no") {
extraFiliere.show();
} else {
extraFiliere.hide();
}
});
$("#extra_theme").parent().append(
$("<a>", {
"class": "btn ajax btn-default",
"href": "'.$url.'&field_variable=extra_theme",
"text": "'.get_lang('Order').'"
})
);
$("#extra_theme_fr").parent().append(
$("<a>", {
"class": "btn ajax btn-default",
"href": "'.$url.'&field_variable=extra_theme_fr",
"text": "'.get_lang('Order').'"
})
);
$("#extra_theme_de").parent().append(
$("<a>", {
"class": "btn ajax btn-default",
"href": "'.$url.'&field_variable=extra_theme_de",
"text": "'.get_lang('Order').'"
})
);
$("#extra_theme_it").parent().append(
$("<a>", {
"class": "btn ajax btn-default",
"href": "'.$url.'&field_variable=extra_theme_it",
"text": "'.get_lang('Order').'"
})
);
$("#extra_theme_es").parent().append(
$("<a>", {
"class": "btn ajax btn-default",
"href": "'.$url.'&field_variable=extra_theme_es",
"text": "'.get_lang('Order').'"
})
);
$("#extra_theme_pl").parent().append(
$("<a>", {
"class": "btn ajax btn-default",
"href": "'.$url.'&field_variable=extra_theme_pl",
"text": "'.get_lang('Order').'"
})
);
$("#extra_domaine_0, #extra_domaine_1, #extra_domaine_2").on("change", function() {
var domainList = [];
$("#extra_domaine_0 option:selected").each(function() {
domainList.push($(this).val());
});
$("#extra_domaine_1 option:selected").each(function() {
domainList.push($(this).val());
});
$("#extra_domaine_2 option:selected").each(function() {
domainList.push($(this).val());
});
var domainListToString = JSON.stringify(domainList);
$.ajax({
contentType: "application/x-www-form-urlencoded",
type: "GET",
url: "'.api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php?a=search_options_from_tags&type=session&from=extra_domaine&search="+themeDefault+"&options="+domainListToString,
success: function(data) {
var selectToString = "";
selectToString += "<option></option>";
jQuery.each(JSON.parse(data), function(i, item) {
selectToString += "<optgroup label=\'"+item.text+"\'>";
// Add empty value
jQuery.each(item.children, function(j, data) {
if (data.text != "") {
selectToString += "<option value=\'"+data.text+"\'> " +data.text+"</option>"
}
});
selectToString += "</optgroup>";
});
for (i = 0; i <= 5; i++) {
var themeId = "#"+themeDefault+"_"+i;
var beforeValue = $(themeId).find(":selected").val();
$(themeId).find("option").remove().end();
$(themeId).empty();
$(themeId).html(selectToString);
$(themeId).val(beforeValue);
$(themeId).selectpicker("refresh");
}
}
});
});
});
</script>';
$result = SessionManager::getGridColumns('simple');
$columns = $result['columns'];
$column_model = $result['column_model'];
$defaults = [];
$tagsData = [];
if (!empty($items)) {
/** @var ExtraFieldSavedSearch $item */
foreach ($items as $item) {
$variable = 'extra_'.$item->getField()->getVariable();
if ($item->getField()->getFieldType() == Extrafield::FIELD_TYPE_TAG) {
$tagsData[$variable] = $item->getValue();
}
$defaults[$variable] = $item->getValue();
}
}
$extraField = new ExtraField('user');
$userForm = new FormValidator('user_form');
$jqueryExtra = '';
$htmlHeadXtra[] = '<script>
$(function() {
$("#user_form select").select2();
var blocks = [
"#collapseOne",
"#collapseTwo",
"#collapseThree",
"#collapseFour",
"#collapseFive",
"#collapseSix",
"#collapseSeven",
"#collapseEight"
];
$.each(blocks, function( index, value ) {
if (window.location.hash == value) {
return true;
}
$(value).collapse("hide");
});
$("#filiere").on("click", function() {
$("#filiere_panel").toggle();
return false;
});
$("#dispo").on("click", function() {
$("#dispo_panel").toggle();
return false;
});
$("#dispo_pendant").on("click", function() {
$("#dispo_pendant_panel").toggle();
return false;
});
$("#niveau").on("click", function() {
$("#niveau_panel").toggle();
return false;
});
$("#methode").on("click", function() {
$("#methode_panel").toggle();
return false;
});
$("#enviroment").on("click", function() {
$("#enviroment_panel").toggle();
return false;
});
$("#themes").on("click", function() {
$("#themes_panel").toggle();
return false;
});
$("#objectifs").on("click", function() {
$("#objectifs_panel").toggle();
return false;
});
});
</script>';
$userForm->addHtml('<div class="panel-group" id="search_extrafield" role="tablist" aria-multiselectable="true">');
$userForm->addHtml('<div class="panel panel-default">');
$userForm->addHtml('<div class="panel-heading"><a role="button" data-toggle="collapse" data-parent="#search_extrafield" href="#collapseZero" aria-expanded="true" aria-controls="collapseZero">'.
get_lang('Diagnostic Form').'</a></div>');
$userForm->addHtml('<div id="collapseZero" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingZero">');
$userForm->addHtml('<div class="panel-body"><p class="text-info">');
$userForm->addHtml(get_lang('Diagnostic Introduction'));
$userForm->addHtml('</p></div></div></div></div>');
$userForm->addHtml('<div class="panel-group" id="search_extrafield" role="tablist" aria-multiselectable="true">');
$userForm->addHtml('<div class="panel panel-default">');
$userForm->addHtml('<div class="panel-heading"><a role="button" data-toggle="collapse" data-parent="#search_extrafield" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">'.get_lang('Filiere').'</a></div>');
$userForm->addHtml('<div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">');
$userForm->addHtml('<div class="panel-body"><p class="text-info">'.get_lang('Filiere Explanation').'</p>');
$fieldsToShow = [
'statusocial',
'filiere_user',
'filiereprecision',
'filiere_want_stage',
];
$extra = $extraField->addElements(
$userForm,
api_get_user_id(),
[],
$filter,
true,
$fieldsToShow,
$fieldsToShow,
[],
false,
$adminPermissions
);
$jqueryExtra .= $extra['jquery_ready_content'];
$fieldsToShow = [
'filiere',
];
$extra = $extraFieldSession->addElements(
$userForm,
api_get_user_id(),
[],
$filter,
true,
$fieldsToShow,
$fieldsToShow,
[],
false,
$adminPermissions
);
$jqueryExtra .= $extra['jquery_ready_content'];
$userForm->addButtonSave(get_lang('Save'), 'submit_partial[collapseOne]');
$userForm->addHtml('</div></div></div>');
$userForm->addHtml('<div class="panel panel-default">');
$userForm->addHtml(
'<div class="panel-heading"><a role="button" data-toggle="collapse" data-parent="#search_extrafield" href="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">'.
get_lang('Disponibilite Avant').'</a></div>'
);
$userForm->addHtml('<div id="collapseTwo" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingTwo">');
$userForm->addHtml('<div class="panel-body"><p class="text-info">'.get_lang('Disponibilite Avant Explanation').'</p>');
$extra = $extraFieldSession->addElements(
$userForm,
'',
[],
$filter,
true,
['access_start_date', 'access_end_date'],
[],
[],
false,
$adminPermissions
);
$userForm->addRule(
['extra_access_start_date', 'extra_access_end_date'],
get_lang('StartDateMustBeBeforeTheEndDate'),
'compare_datetime_text',
'< allow_empty'
);
$jqueryExtra .= $extra['jquery_ready_content'];
$elements = $userForm->getElements();
$variables = ['access_start_date', 'access_end_date'];
foreach ($elements as $element) {
$element->setAttribute('extra_label_class', 'red_underline');
}
$fieldsToShow = [
'heures_disponibilite_par_semaine',
'moment_de_disponibilite',
];
$extra = $extraField->addElements(
$userForm,
api_get_user_id(),
[],
$filter,
true,
$fieldsToShow,
$fieldsToShow,
[],
false,
$adminPermissions
);
$userForm->addButtonSave(get_lang('Save'), 'submit_partial[collapseTwo]');
$jqueryExtra .= $extra['jquery_ready_content'];
$userForm->addHtml('</div></div></div>');
$userForm->addHtml('<div class="panel panel-default">');
$userForm->addHtml('<div class="panel-heading"><a role="button" data-toggle="collapse" data-parent="#search_extrafield" href="#collapseThree" aria-expanded="true" aria-controls="collapseThree">'.get_lang('Disponibilite Pendant Mon Stage').'</a></div>');
$userForm->addHtml('<div id="collapseThree" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingThree">');
$userForm->addHtml('<div class="panel-body"><p class="text-info">'.get_lang('Disponibilite Pendant Mon Stage Explanation').'</p>');
$fieldsToShow = [
'datedebutstage',
'datefinstage',
'je_ne_connais_pas_encore_mes_dates_de_stage',
'deja_sur_place',
'poursuiteapprentissagestage',
'heures_disponibilite_par_semaine_stage',
];
$extra = $extraField->addElements(
$userForm,
api_get_user_id(),
[],
$filter,
true,
$fieldsToShow,
$fieldsToShow,
[],
false,
$adminPermissions
);
$userForm->addRule(
['extra_datedebutstage', 'extra_datefinstage'],
get_lang('StartDateMustBeBeforeTheEndDate'),
'compare_datetime_text',
'< allow_empty'
);
$jqueryExtra .= $extra['jquery_ready_content'];
$userForm->addButtonSave(get_lang('Save'), 'submit_partial[collapseThree]');
$userForm->addHtml('</div></div></div>');
$userForm->addHtml('<div class="panel panel-default">');
$userForm->addHtml('<div class="panel-heading"><a role="button" data-toggle="collapse" data-parent="#search_extrafield" href="#collapseFour" aria-expanded="true" aria-controls="collapseFour">'.get_lang('Themes Objectifs').'</a></div>');
$userForm->addHtml('<div id="collapseFour" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingFour">');
$userForm->addHtml('<div class="panel-body"><p class="text-info">'.get_lang('Themes Objectifs Explanation').'</p>');
$introductionTextList = [
'domaine' => get_lang('Domaine Introduction'),
$theme => get_lang('Theme Field Introduction'),
];
$fieldsToShow = [
'domaine',
$theme,
];
$extra = $extraFieldSession->addElements(
$userForm,
api_get_user_id(),
[],
$filter,
false, //tag as select
$fieldsToShow,
$fieldsToShow,
$defaults,
true,
$adminPermissions,
['domaine' => 3, $theme => 5], // $separateExtraMultipleSelect
[
'domaine' => [
get_lang('Domaine').' 1',
get_lang('Domaine').' 2',
get_lang('Domaine').' 3',
],
$theme => [
get_lang('ThemeField').' 1',
get_lang('ThemeField').' 2',
get_lang('ThemeField').' 3',
get_lang('ThemeField').' 4',
get_lang('ThemeField').' 5',
],
],
true, //$addEmptyOptionSelects
$introductionTextList
);
$jqueryExtra .= $extra['jquery_ready_content'];
$userForm->addButtonSave(get_lang('Save'), 'submit_partial[collapseFour]');
$userForm->addHtml('</div></div></div>');
$userForm->addHtml('<div class="panel panel-default">');
$userForm->addHtml('<div class="panel-heading"><a role="button" data-toggle="collapse" data-parent="#search_extrafield" href="#collapseFive" aria-expanded="true" aria-controls="collapseFive">'.get_lang('Niveau Langue').'</a></div>');
$userForm->addHtml('<div id="collapseFive" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingFive">');
$userForm->addHtml('<div class="panel-body"><p class="text-info">'.get_lang('Niveau Langue Explanation').'</p>');
$fieldsToShow = [
//'competenceniveau'
'ecouter',
'lire',
'participer_a_une_conversation',
's_exprimer_oralement_en_continu',
'ecrire',
];
$extra = $extraFieldSession->addElements(
$userForm,
api_get_user_id(),
[],
$filter,
true,
$fieldsToShow,
$fieldsToShow,
$defaults,
false, //$orderDependingDefaults = false,
$adminPermissions
);
$jqueryExtra .= $extra['jquery_ready_content'];
$userForm->addButtonSave(get_lang('Save'), 'submit_partial[collapseFive]');
$userForm->addHtml('</div></div></div>');
$userForm->addHtml('<div class="panel panel-default">');
$userForm->addHtml('<div class="panel-heading"><a role="button" data-toggle="collapse" data-parent="#search_extrafield" href="#collapseSix" aria-expanded="true" aria-controls="collapseSix">'.get_lang('Objectifs Apprentissage').'</a></div>');
$userForm->addHtml('<div id="collapseSix" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingSix">');
$userForm->addHtml('<div class="panel-body"><p class="text-info">'.get_lang('Objectifs Apprentissage Explanation').'</p>');
$fieldsToShow = [
'objectif_apprentissage',
];
$extra = $extraField->addElements(
$userForm,
api_get_user_id(),
[],
$filter,
false,
$fieldsToShow,
$fieldsToShow,
[],
false,
$adminPermissions
);
$jqueryExtra .= $extra['jquery_ready_content'];
$userForm->addButtonSave(get_lang('Save'), 'submit_partial[collapseSix]');
$userForm->addHtml('</div></div></div>');
$userForm->addHtml('<div class="panel panel-default">');
$userForm->addHtml('<div class="panel-heading"><a role="button" data-toggle="collapse" data-parent="#search_extrafield" href="#collapseSeven" aria-expanded="true" aria-controls="collapseSeven">'.get_lang('Methode Travail').'</a></div>');
$userForm->addHtml('<div id="collapseSeven" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingSeven">');
$userForm->addHtml('<div class="panel-body"><p class="text-info">'.get_lang('Methode Travail Explanation').'</p>');
$fieldsToShow = [
'methode_de_travaille',
'accompagnement',
];
$extra = $extraField->addElements(
$userForm,
api_get_user_id(),
[],
$filter,
true,
$fieldsToShow,
$fieldsToShow,
[],
false,
$adminPermissions
);
$jqueryExtra .= $extra['jquery_ready_content'];
$userForm->addButtonSave(get_lang('Save'), 'submit_partial[collapseSeven]');
$userForm->addHtml('</div></div></div>');
// Enviroment
$userForm->addHtml('<div class="panel panel-default">');
$userForm->addHtml(
'<div class="panel-heading">
<a role="button" data-toggle="collapse" data-parent="#search_extrafield" href="#collapseEight" aria-expanded="true" aria-controls="collapseEight">'.
get_lang('Mon Environnement De Travail').'</a></div>');
$userForm->addHtml('<div id="collapseEight" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingEight">');
$userForm->addHtml('<div class="panel-body"><p class="text-info">'.get_lang('Mon Environnement De Travail').'</p>');
$fieldsToShow = [
'outil_de_travail_ordinateur',
'outil_de_travail_ordinateur_so',
'outil_de_travail_tablette',
'outil_de_travail_tablette_so',
'outil_de_travail_smartphone',
'outil_de_travail_smartphone_so',
];
$userForm->addLabel(null, get_lang('Mon Environnement De Travail Explanation Intro1'));
$extra = $extraField->addElements(
$userForm,
api_get_user_id(),
[],
$filter,
true,
$fieldsToShow,
$fieldsToShow,
[],
false,
$adminPermissions
);
$userForm->addLabel(null, get_lang('Mon Environnement De Travail Explanation Intro2'));
$jqueryExtra .= $extra['jquery_ready_content'];
$fieldsToShow = [
'browser_platforme',
'browser_platforme_autre',
'browser_platforme_version',
];
$extra = $extraField->addElements(
$userForm,
api_get_user_id(),
[],
$filter,
true,
$fieldsToShow,
$fieldsToShow,
[],
false,
$adminPermissions
);
$jqueryExtra .= $extra['jquery_ready_content'];
$userForm->addHtml('<p class="text-info">'.get_lang('Mon Environnement De Travail Renvoi FAQ').'</p>');
$userForm->addButtonSave(get_lang('Save'), 'submit_partial[collapseEight]');
$userForm->addHtml('</div></div></div>');
$userForm->addHtml('</div>');
//$userForm->addHtml('</div>');
$htmlHeadXtra[] = '<script>
$(function () {
'.$jqueryExtra.'
});
</script>';
$userForm->addButtonSave(get_lang('Send'));
$userForm->setDefaults($defaults);
$domaine1 = $userForm->getElementByName('extra_domaine[0]');
$domaine2 = $userForm->getElementByName('extra_domaine[1]');
$domaine3 = $userForm->getElementByName('extra_domaine[2]');
$domainList = array_merge(
is_object($domaine1) ? $domaine1->getValue() : [],
is_object($domaine3) ? $domaine3->getValue() : [],
is_object($domaine2) ? $domaine2->getValue() : []
);
$themeList = [];
$resultOptions = $extraFieldSession->searchOptionsFromTags(
'extra_domaine',
'extra_'.$theme,
$domainList
);
if ($resultOptions) {
$resultOptions = array_column($resultOptions, 'tag', 'id');
$resultOptions = array_filter($resultOptions);
for ($i = 0; $i < 5; $i++) {
$themeElement = $userForm->getElementByName('extra_'.$theme.'['.$i.']');
foreach ($resultOptions as $key => $value) {
$themeElement->addOption($value, $value);
}
}
}
if ($userForm->validate()) {
// Saving to user extra fields
$extraFieldValue = new ExtraFieldValue('user');
$userData = $userForm->getSubmitValues();
$isPartial = false;
$block = '';
if (isset($userData['submit_partial'])) {
$block = key($userData['submit_partial']);
$isPartial = true;
}
if ($isPartial === false) {
$userData['extra_diagnosis_completed'] = 1;
}
$extraFieldValue->saveFieldValues(
$userData,
true,
false,
[],
['legal_accept'],
true
);
// Saving to extra_field_saved_search
$user = $em->getRepository(User::class)->find($userId);
$sessionFields = [
'extra_access_start_date',
'extra_access_end_date',
'extra_filiere',
'extra_domaine',
'extra_domaine[0]',
'extra_domaine[1]',
'extra_domaine[3]',
'extra_temps_de_travail',
//'extra_competenceniveau',
'extra_'.$theme,
'extra_'.$theme.'[0]',
'extra_'.$theme.'[1]',
'extra_'.$theme.'[2]',
'extra_'.$theme.'[3]',
'extra_'.$theme.'[4]',
'extra_ecouter',
'extra_lire',
'extra_participer_a_une_conversation',
'extra_s_exprimer_oralement_en_continu',
'extra_ecrire',
];
foreach ($userData as $key => $value) {
$found = strpos($key, '__persist__');
if ($found === false) {
continue;
}
}
if (isset($userData['extra_filiere_want_stage']) &&
isset($userData['extra_filiere_want_stage']['extra_filiere_want_stage'])
) {
$wantStage = $userData['extra_filiere_want_stage']['extra_filiere_want_stage'];
if ($wantStage === 'yes') {
if (isset($userData['extra_filiere_user'])) {
$userData['extra_filiere'] = [];
$userData['extra_filiere']['extra_filiere'] = $userData['extra_filiere_user']['extra_filiere_user'];
}
}
}
// save in ExtraFieldSavedSearch.
$extraFieldRepo = $em->getRepository(\Chamilo\CoreBundle\Entity\ExtraField::class);
foreach ($userData as $key => $value) {
if (substr($key, 0, 6) != 'extra_' && substr($key, 0, 7) != '_extra_') {
continue;
}
if (!in_array($key, $sessionFields)) {
continue;
}
$field_variable = substr($key, 6);
$extraFieldInfo = $extraFieldValueSession
->getExtraField()
->get_handler_field_info_by_field_variable($field_variable)
;
if (!$extraFieldInfo) {
continue;
}
$extraFieldObj = $extraFieldRepo->find($extraFieldInfo['id']);
$search = [
'field' => $extraFieldObj,
'user' => $user,
];
/** @var ExtraFieldSavedSearch $saved */
$saved = $extraFieldSavedSearchRepo->findOneBy($search);
if ($saved) {
$saved
->setField($extraFieldObj)
->setUser($user)
->setValue($value)
;
$em->merge($saved);
} else {
$saved = new ExtraFieldSavedSearch();
$saved
->setField($extraFieldObj)
->setUser($user)
->setValue($value);
$em->persist($saved);
}
$em->flush();
}
$superiorUserList = UserManager::getStudentBossList($userInfo['user_id']);
if ($superiorUserList && $isPartial == false) {
$url = api_get_path(WEB_PATH).'load_search.php?user_id='.$userInfo['user_id'];
$urlContact = api_get_path(WEB_CODE_PATH).'messages/inbox.php?f=social';
$subject = sprintf(get_lang('Diagnosis From User %s'), $userInfo['complete_name']);
$message = sprintf(get_lang('Diagnosis From User %s lang %s with link %s Contact at %s'), $userInfo['complete_name'], $userInfo['language'], $url, $urlContact);
foreach ($superiorUserList as $bossData) {
$bossId = $bossData['boss_id'];
MessageManager::send_message_simple(
$bossId,
$subject,
$message
);
}
}
if ($isPartial) {
header('Location:'.api_get_self().'#'.$block);
} else {
header('Location:'.api_get_self().'?result=1');
}
exit;
}
$userFormToString = $userForm->returnForm();
$result = isset($_GET['result']) ? true : false;
$tpl = new Template(get_lang('Diagnosis'));
$tpl->assign('grid', '');
$tpl->assign('grid_js', '');
$tpl->assign('form_search', '');
$tpl->assign('form', '');
if ($result === false) {
$tpl->assign('form', $userFormToString);
} else {
Display::addFlash(Display::return_message(get_lang('Your session search diagnosis is saved')));
}
$content = $tpl->fetch($tpl->get_template('search/search_extra_field.tpl'));
$tpl->assign('content', $content);
$tpl->display_one_col_template();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,14 @@
{% autoescape false %}
{{ form_search }}
{{ form }}
<script>
$(function() {
{{ grid_js }}
});
</script>
{{ grid }}
{% endautoescape %}

@ -43,7 +43,7 @@ class ExtraFieldSavedSearch
/** /**
* @ORM\Column(name="value", type="array", nullable=true, unique=false) * @ORM\Column(name="value", type="array", nullable=true, unique=false)
*/ */
protected ?array $value = []; protected $value = '';
/** /**
* Get id. * Get id.
@ -75,7 +75,7 @@ class ExtraFieldSavedSearch
return $this->value; return $this->value;
} }
public function setValue(array $value): self public function setValue($value): self
{ {
$this->value = $value; $this->value = $value;

@ -44,6 +44,7 @@ class SessionSettingsSchema extends AbstractSettingsSchema
'hide_tab_list' => '', 'hide_tab_list' => '',
'session_admins_edit_courses_content' => 'false', 'session_admins_edit_courses_content' => 'false',
'allow_session_admin_login_as_teacher' => 'false', 'allow_session_admin_login_as_teacher' => 'false',
'allow_search_diagnostic' => 'false'
] ]
) )
; ;
@ -97,6 +98,7 @@ class SessionSettingsSchema extends AbstractSettingsSchema
->add('hide_tab_list') ->add('hide_tab_list')
->add('session_admins_edit_courses_content', YesNoType::class) ->add('session_admins_edit_courses_content', YesNoType::class)
->add('allow_session_admin_login_as_teacher', YesNoType::class) ->add('allow_session_admin_login_as_teacher', YesNoType::class)
->add('allow_search_diagnostic', YesNoType::class)
; ;
} }
} }

Loading…
Cancel
Save