evalform.class.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Script
  5. * @package chamilo.gradebook
  6. */
  7. /**
  8. * Init
  9. */
  10. require_once dirname(__FILE__).'/../../../inc/global.inc.php';
  11. require_once dirname(__FILE__).'/../be.inc.php';
  12. require_once dirname(__FILE__).'/../gradebook_functions.inc.php';
  13. /**
  14. * Extends formvalidator with add&edit forms for evaluations
  15. * @author Stijn Konings
  16. * @package chamilo.gradebook
  17. */
  18. $htmlHeadXtra[] = '<script>
  19. function setFocus(){
  20. $("#evaluation_title").focus();
  21. }
  22. $(document).ready(function () {
  23. setFocus();
  24. });
  25. </script>';
  26. class EvalForm extends FormValidator
  27. {
  28. const TYPE_ADD= 1;
  29. const TYPE_EDIT= 2;
  30. const TYPE_MOVE= 3;
  31. const TYPE_RESULT_ADD= 4;
  32. const TYPE_RESULT_EDIT= 5;
  33. const TYPE_ALL_RESULTS_EDIT= 6;
  34. const TYPE_ADD_USERS_TO_EVAL= 7;
  35. private $evaluation_object;
  36. private $result_object;
  37. private $extra;
  38. /**
  39. * Builds a form containing form items based on a given parameter
  40. * @param int form_type 1=add, 2=edit,3=move,4=result_add
  41. * @param obj cat_obj the category object
  42. * @param obj res_obj the result object
  43. * @param string form name
  44. * @param method
  45. * @param action
  46. */
  47. public function __construct($form_type, $evaluation_object, $result_object, $form_name, $method= 'post', $action= null, $extra1 = null, $extra2 = null) {
  48. parent::__construct($form_name, $method, $action);
  49. if (isset ($evaluation_object)) {
  50. $this->evaluation_object= $evaluation_object;
  51. }
  52. if (isset ($result_object)) {
  53. $this->result_object= $result_object;
  54. }
  55. if (isset ($extra1)) {
  56. $this->extra = $extra1;
  57. }
  58. switch ($form_type) {
  59. case self :: TYPE_EDIT:
  60. $this->build_editing_form();
  61. break;
  62. case self :: TYPE_ADD:
  63. $this->build_add_form();
  64. break;
  65. case self :: TYPE_MOVE:
  66. $this->build_editing_form();
  67. break;
  68. case self :: TYPE_RESULT_ADD:
  69. $this->build_result_add_form();
  70. break;
  71. case self :: TYPE_RESULT_EDIT:
  72. $this->build_result_edit_form();
  73. break;
  74. case self :: TYPE_ALL_RESULTS_EDIT:
  75. $this->build_all_results_edit_form();
  76. break;
  77. case self :: TYPE_ADD_USERS_TO_EVAL:
  78. $this->build_add_user_to_eval();
  79. break;
  80. }
  81. $this->setDefaults();
  82. }
  83. /**
  84. * This form will build a form to add users to an evaluation
  85. */
  86. protected function build_add_user_to_eval()
  87. {
  88. $this->addElement('header', get_lang('ChooseUser'));
  89. $select= $this->addElement('select', 'firstLetterUser', get_lang('FirstLetter'), null, array(
  90. 'onchange'=> 'document.add_users_to_evaluation.submit()'
  91. ));
  92. $select->addOption('','');
  93. for ($i = 65; $i <= 90; $i ++) {
  94. $letter = chr($i);
  95. if (isset($this->extra) && $this->extra == $letter) {
  96. $select->addOption($letter,$letter,'selected');
  97. } else {
  98. $select->addOption($letter,$letter);
  99. }
  100. }
  101. $select= $this->addElement('select', 'add_users', null, null, array (
  102. 'multiple' => 'multiple',
  103. 'size' => '15',
  104. 'style' => 'width:250px'
  105. ));
  106. foreach ($this->evaluation_object->get_not_subscribed_students() as $user) {
  107. if ( (!isset($this->extra)) || empty($this->extra) || api_strtoupper(api_substr($user[1],0,1)) == $this->extra ) {
  108. $select->addoption($user[1] . ' ' . $user[2] . ' (' . $user[3] . ')', $user[0]);
  109. }
  110. }
  111. $this->addElement('submit', 'submit_button', get_lang('AddUserToEval'));
  112. }
  113. /**
  114. * This function builds a form to edit all results in an evaluation
  115. */
  116. protected function build_all_results_edit_form()
  117. {
  118. //extra field for check on maxvalue
  119. $this->addElement('hidden', 'maxvalue', $this->evaluation_object->get_max());
  120. $this->addElement('hidden', 'minvalue', 0);
  121. $this->addElement('header', get_lang('EditResult'));
  122. $renderer =& $this->defaultRenderer();
  123. // set new form template
  124. $form_template = '<form{attributes}>
  125. <table class="data_table" border="0" cellpadding="5" cellspacing="5">{content}
  126. </table>
  127. </form>';
  128. $renderer->setFormTemplate($form_template);
  129. if (api_is_western_name_order()){
  130. $renderer->setHeaderTemplate(
  131. '<tr>
  132. <th>'.get_lang('OfficialCode').'</th>
  133. <th>'.get_lang('UserName').'</th>
  134. <th>'.get_lang('FirstName').'</th>
  135. <th>'.get_lang('LastName').'</th>
  136. <th>'.get_lang('Qualify').'</th>
  137. </tr>'
  138. );
  139. } else {
  140. $renderer->setHeaderTemplate(
  141. '<tr>
  142. <th>'.get_lang('OfficialCode').'</th>
  143. <th>'.get_lang('UserName').'</th>
  144. <th>'.get_lang('LastName').'</th>
  145. <th>'.get_lang('FirstName').'</th>
  146. <th>'.get_lang('Qualify').'</th>
  147. </tr>'
  148. );
  149. }
  150. $template_submit = '<tr>
  151. <td colspan="4" ></td>
  152. <td >
  153. {element}
  154. <!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
  155. </td>
  156. </tr>';
  157. $results_and_users = array();
  158. foreach ($this->result_object as $result) {
  159. $user = api_get_user_info($result->get_user_id());
  160. $results_and_users[] = array ('result' => $result, 'user' => $user);
  161. }
  162. usort($results_and_users, array ('EvalForm', 'sort_by_user'));
  163. $defaults = array();
  164. foreach ($results_and_users as $result_and_user) {
  165. $user = $result_and_user['user'];
  166. $result = $result_and_user['result'];
  167. $renderer = &$this->defaultRenderer();
  168. $this->add_textfield('score[' . $result->get_id() . ']', $this->build_stud_label($user['user_id'], $user['username'], $user['lastname'], $user['firstname']), false, array('class' => "span2",
  169. 'maxlength' => 5));
  170. $this->addRule('score[' . $result->get_id() . ']', get_lang('OnlyNumbers'), 'numeric');
  171. $this->addRule(array (
  172. 'score[' . $result->get_id() . ']', 'maxvalue'), get_lang('OverMax'), 'compare', '<=');
  173. $this->addRule(array (
  174. 'score[' . $result->get_id() . ']', 'minvalue'), get_lang('UnderMin'), 'compare', '>=');
  175. $defaults['score[' . $result->get_id() . ']'] = $result->get_score();
  176. if (api_is_western_name_order() ) {
  177. $user_info = '<td align="left" >'.$user['firstname'].'</td>';
  178. $user_info .= '<td align="left" >'.$user['lastname'].'</td>';
  179. } else {
  180. $user_info = '<td align="left" >'.$user['lastname'].'</td>';
  181. $user_info .= '<td align="left" >'.$user['firstname'].'</td>';
  182. }
  183. $template = '<tr>
  184. <td align="left" >'.$user['official_code'].'</td>
  185. <td align="left" >'.$user['username'].'</td>
  186. '.$user_info.'
  187. <td align="left">{element} / '.$this->evaluation_object->get_max().'
  188. <!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
  189. </td>
  190. </tr>';
  191. $renderer->setElementTemplate($template,'score[' . $result->get_id() . ']');
  192. }
  193. $this->setDefaults($defaults);
  194. $this->addElement('style_submit_button', 'submit',get_lang('EditResult'),'class="save"');
  195. $renderer->setElementTemplate($template_submit,'submit');
  196. }
  197. /**
  198. * This function builds a form to move an item to another category
  199. *
  200. */
  201. protected function build_move_form()
  202. {
  203. $renderer = & $this->defaultRenderer();
  204. $renderer->setElementTemplate('<span>{element}</span> ');
  205. $this->addElement('static', null, null, '"'.$this->evaluation_object->get_name().'" ');
  206. $this->addElement('static', null, null, get_lang('MoveTo').' : ');
  207. $select= $this->addElement('select', 'move_cat', null, null);
  208. foreach ($this->evaluation_object->get_target_categories() as $cat) {
  209. for ($i= 0; $i < $cat[2]; $i++) {
  210. $line .= '&mdash;';
  211. }
  212. $select->addoption($line . ' ' . $cat[1], $cat[0]);
  213. $line= '';
  214. }
  215. $this->addElement('style_submit_button' , 'submit', get_lang('Ok'),'class="save"');
  216. }
  217. /**
  218. * Builds a result form containing inputs for all students with a given course_code
  219. */
  220. protected function build_result_add_form()
  221. {
  222. $renderer =& $this->defaultRenderer();
  223. $renderer->setFormTemplate(
  224. '<form{attributes}>
  225. <table class="data_table">
  226. {content}
  227. </table>
  228. </form>'
  229. );
  230. $courseInfo = api_get_course_info($this->evaluation_object->get_course_code());
  231. $tblusers = get_users_in_course($courseInfo['real_id']);
  232. $nr_users = 0;
  233. //extra field for check on maxvalue
  234. $this->addElement('hidden', 'maxvalue', $this->evaluation_object->get_max());
  235. $this->addElement('hidden', 'minvalue', 0);
  236. $this->addElement('header', get_lang('AddResult'));
  237. if (api_is_western_name_order()){
  238. $renderer->setHeaderTemplate(
  239. '<tr>
  240. <th>'.get_lang('OfficialCode').'</th>
  241. <th>'.get_lang('UserName').'</th>
  242. <th>'.get_lang('FirstName').'</th>
  243. <th>'.get_lang('LastName').'</th>
  244. <th>'.get_lang('Qualify').'</th>
  245. </tr>'
  246. );
  247. } else {
  248. $renderer->setHeaderTemplate(
  249. '<tr>
  250. <th>'.get_lang('OfficialCode').'</th>
  251. <th>'.get_lang('UserName').'</th>
  252. <th>'.get_lang('LastName').'</th>
  253. <th>'.get_lang('FirstName').'</th>
  254. <th>'.get_lang('Qualify').'</th>
  255. </tr>'
  256. );
  257. }
  258. foreach ($tblusers as $user) {
  259. $element_name = 'score['.$user[0].']';
  260. //user_id, user.username, lastname, firstname
  261. $this->add_textfield($element_name,
  262. $this->build_stud_label($user[0], $user[1], $user[2], $user[3]),
  263. false,
  264. array ('class' => 'span1','maxlength' => 5));
  265. $this->addRule($element_name, get_lang('OnlyNumbers'), 'numeric');
  266. $this->addRule(array($element_name,'maxvalue'), get_lang('OverMax'), 'compare', '<=');
  267. $this->addRule(array($element_name,'minvalue'), get_lang('UnderMin'), 'compare', '>=');
  268. if (api_is_western_name_order() ) {
  269. $user_info = '<td align="left" >'.$user[3].'</td>';
  270. $user_info .= '<td align="left" >'.$user[2].'</td>';
  271. } else {
  272. $user_info = '<td align="left" >'.$user[2].'</td>';
  273. $user_info .= '<td align="left" >'.$user[3].'</td>';
  274. }
  275. $nr_users++;
  276. $template = '<tr>
  277. <td align="left" >'.$user[4].'</td>
  278. <td align="left" >'.$user[1].'</td>
  279. '.$user_info.'
  280. <td align="left">{element} / '.$this->evaluation_object->get_max().'
  281. <!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
  282. </td>
  283. </tr>';
  284. $renderer->setElementTemplate($template, $element_name);
  285. }
  286. $this->addElement('hidden', 'nr_users', $nr_users);
  287. $this->addElement('hidden', 'evaluation_id', $this->result_object->get_evaluation_id());
  288. $this->addElement('style_submit_button', 'submit', get_lang('AddResult'),'class="save"');
  289. $template_submit = '<tr>
  290. <td colspan="4" ></td>
  291. <td >
  292. {element}
  293. <!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
  294. </td>
  295. </tr>';
  296. $renderer->setElementTemplate($template_submit, 'submit');
  297. }
  298. /**
  299. * Builds a form to edit a result
  300. */
  301. protected function build_result_edit_form()
  302. {
  303. $this->setDefaults(array (
  304. 'score' => $this->result_object->get_score(),
  305. 'maximum' => $this->evaluation_object->get_max()
  306. ));
  307. $userinfo= api_get_user_info($this->result_object->get_user_id());
  308. $renderer =& $this->defaultRenderer();
  309. $renderer->setElementTemplate('<span>{element}</span> ');
  310. $this->addElement('label', get_lang('User'), $userinfo['complete_name']);
  311. $this->add_textfield('score', array(get_lang('Score'), null, '/ '.$this->evaluation_object->get_max()), false, array (
  312. 'size' => '4',
  313. 'class' => 'span1',
  314. 'maxlength' => '5'
  315. ));
  316. /* $this->add_textfield('maximum', null, false, array (
  317. 'size' => '4',
  318. 'maxlength' => '5',
  319. 'disabled' => 'disabled'
  320. ));*/
  321. $this->addElement('style_submit_button', 'submit', get_lang('Edit'),'class="save"');
  322. $this->addElement('hidden', 'minvalue', 0);
  323. $this->addElement('hidden', 'hid_user_id', $this->result_object->get_user_id());
  324. $this->addElement('hidden', 'maxvalue', $this->evaluation_object->get_max());
  325. $this->addRule('score', get_lang('OnlyNumbers'), 'numeric',null,'client');
  326. $this->addRule(array (
  327. 'score',
  328. 'maxvalue'
  329. ), get_lang('OverMax'), 'compare', '<=','client');
  330. $this->addRule(array (
  331. 'score',
  332. 'minvalue'
  333. ), get_lang('UnderMin'), 'compare', '>=','client');
  334. }
  335. /**
  336. * Builds a form to add an evaluation
  337. */
  338. protected function build_add_form()
  339. {
  340. $this->setDefaults(array ( 'hid_user_id' => $this->evaluation_object->get_user_id(),
  341. 'hid_category_id' => $this->evaluation_object->get_category_id(),
  342. 'hid_course_code' => $this->evaluation_object->get_course_code(), 'created_at' => api_get_utc_datetime()));
  343. $this->build_basic_form(0);
  344. if ($this->evaluation_object->get_course_code() == null) {
  345. $this->addElement('checkbox', 'adduser', null, get_lang('AddUserToEval'));
  346. } else {
  347. $this->addElement('checkbox', 'addresult', null, get_lang('AddResult'));
  348. }
  349. $this->addElement('style_submit_button', 'submit', get_lang('AddAssessment'),'class="add"');
  350. }
  351. /**
  352. * Builds a form to edit an evaluation
  353. */
  354. protected function build_editing_form()
  355. {
  356. $parent_cat = Category :: load($this->evaluation_object->get_category_id());
  357. if ($parent_cat[0]->get_parent_id() == 0) {
  358. $weight_mask = $this->evaluation_object->get_weight();
  359. } else {
  360. $cat = Category :: load($parent_cat[0]->get_parent_id());
  361. $global_weight = $cat[0]->get_weight();
  362. $weight_mask = $global_weight*$this->evaluation_object->get_weight()/$parent_cat[0]->get_weight() ;
  363. }
  364. $weight_mask = $this->evaluation_object->get_weight();
  365. $this->setDefaults(array ( 'hid_id' => $this->evaluation_object->get_id(),
  366. 'name' => $this->evaluation_object->get_name(),
  367. 'description' => $this->evaluation_object->get_description(),
  368. 'hid_user_id' => $this->evaluation_object->get_user_id(),
  369. 'hid_course_code' => $this->evaluation_object->get_course_code(),
  370. 'hid_category_id' => $this->evaluation_object->get_category_id(),
  371. 'created_at' => api_get_utc_datetime($this->evaluation_object->get_date()),
  372. 'weight' => $weight,
  373. 'weight_mask' => $weight_mask,
  374. 'max' => $this->evaluation_object->get_max(),
  375. 'visible' => $this->evaluation_object->is_visible()));
  376. $id_current=isset($this->id)?$this->id :null;
  377. $this->addElement('hidden', 'hid_id', $id_current);
  378. $this->build_basic_form(1);
  379. $this->addElement('style_submit_button', 'submit', get_lang('ModifyEvaluation'),'class="save"');
  380. }
  381. /**
  382. * Builds a basic form that is used in add and edit
  383. */
  384. private function build_basic_form($edit = 0)
  385. {
  386. $form_title = get_lang('NewEvaluation');
  387. if (!empty($_GET['editeval']) && $_GET['editeval'] == 1) {
  388. $form_title = get_lang('EditEvaluation');
  389. }
  390. $this->addElement('header', $form_title);
  391. $this->addElement('hidden', 'zero', 0);
  392. $this->addElement('hidden', 'hid_user_id');
  393. $this->addElement('hidden', 'hid_course_code');
  394. $this->add_textfield('name', get_lang('EvaluationName'), true, array (
  395. 'class' => 'span3',
  396. 'maxlength' => '50',
  397. 'id' => 'evaluation_title'
  398. ));
  399. $cat_id = $this->evaluation_object->get_category_id();
  400. $session_id = api_get_session_id();
  401. $course_code = api_get_course_id();
  402. $all_categories = Category :: load(null, null, $course_code, null, null, $session_id, false);
  403. if (count($all_categories) == 1) {
  404. $this->addElement('hidden', 'hid_category_id', $cat_id);
  405. } else {
  406. $select_gradebook = $this->addElement('select', 'hid_category_id', get_lang('SelectGradebook'), array(), array('id' => 'hid_category_id'));
  407. $this->addRule('hid_category_id', get_lang('ThisFieldIsRequired'), 'nonzero');
  408. $default_weight = 0;
  409. if (!empty($all_categories)) {
  410. foreach ($all_categories as $my_cat) {
  411. if ($my_cat->get_course_code() == api_get_course_id()) {
  412. $grade_model_id = $my_cat->get_grade_model_id();
  413. if (empty($grade_model_id)) {
  414. if ($my_cat->get_parent_id() == 0) {
  415. $default_weight = $my_cat->get_weight();
  416. $select_gradebook->addoption(get_lang('Default'), $my_cat->get_id());
  417. $cats_added[] = $my_cat->get_id();
  418. } else {
  419. $select_gradebook->addoption($my_cat->get_name(), $my_cat->get_id());
  420. $cats_added[] = $my_cat->get_id();
  421. }
  422. } else {
  423. $select_gradebook->addoption(get_lang('Select'), 0);
  424. }
  425. if ($this->evaluation_object->get_category_id() == $my_cat->get_id()) {
  426. $default_weight = $my_cat->get_weight();
  427. }
  428. }
  429. }
  430. }
  431. }
  432. $this->add_textfield('weight_mask', array(get_lang('Weight'), null, ' [0 .. <span id="max_weight">' . $all_categories[0]->get_weight() . '</span>] '), true, array(
  433. 'size' => '4',
  434. 'maxlength' => '5',
  435. 'class' => 'span1'
  436. ));
  437. /*$this->add_textfield('weight', array(null, null, '/ <span id="max_weight">'.$default_weight.'</span>'), true, array (
  438. 'size' => '4',
  439. 'maxlength' => '5',
  440. 'class' => 'span1'
  441. ));*/
  442. if ($edit) {
  443. if (!$this->evaluation_object->has_results()) {
  444. $this->add_textfield('max', get_lang('QualificationNumeric'), true, array (
  445. 'class' => 'span1',
  446. 'maxlength' => '5'
  447. ));
  448. } else {
  449. $this->add_textfield('max', array(get_lang('QualificationNumeric'), get_lang('CannotChangeTheMaxNote')), false, array (
  450. 'class' => 'span1',
  451. 'maxlength' => '5',
  452. 'disabled' => 'disabled'
  453. ));
  454. }
  455. } else {
  456. $this->add_textfield('max', get_lang('QualificationNumeric'), true, array (
  457. 'class' => 'span1',
  458. 'maxlength' => '5'
  459. ));
  460. $default_max = api_get_setting('gradebook_default_weight');
  461. $defaults['max'] = isset($default_max) ? $default_max : 100;
  462. $this->setDefaults($defaults);
  463. }
  464. $this->addElement('textarea', 'description', get_lang('Description'), array (
  465. 'rows' => '3',
  466. 'class' => 'span3',
  467. ));
  468. $this->addRule('hid_category_id', get_lang('ThisFieldIsRequired'), 'required');
  469. $this->addElement('checkbox', 'visible', null, get_lang('Visible'));
  470. $this->addRule('weight_mask', get_lang('OnlyNumbers'), 'numeric');
  471. $this->addRule(array('weight_mask', 'zero'), get_lang('NegativeValue'), 'compare', '>=');
  472. $this->addRule('max', get_lang('OnlyNumbers'), 'numeric');
  473. $this->addRule(array('max', 'zero'), get_lang('NegativeValue'), 'compare', '>=');
  474. $setting = api_get_setting('tool_visible_by_default_at_creation');
  475. $visibility_default = 1;
  476. if (isset($setting['gradebook']) && $setting['gradebook'] == 'false') {
  477. $visibility_default = 0;
  478. }
  479. $this->setDefaults(array('visible' => $visibility_default));
  480. }
  481. function display()
  482. {
  483. parent :: display();
  484. }
  485. function setDefaults($defaults = array(), $filter = null)
  486. {
  487. parent :: setDefaults($defaults, $filter);
  488. }
  489. private function build_stud_label($id, $username, $lastname, $firstname)
  490. {
  491. $opendocurl_start = '';
  492. $opendocurl_end = '';
  493. // evaluation's origin is a link
  494. if ($this->evaluation_object->get_category_id() < 0) {
  495. $link = LinkFactory :: get_evaluation_link ($this->evaluation_object->get_id());
  496. $doc_url = $link->get_view_url($id);
  497. if ($doc_url != null) {
  498. $opendocurl_start .= '<a href="'. $doc_url . '" target="_blank">';
  499. $opendocurl_end = '</a>';
  500. }
  501. }
  502. return $opendocurl_start . api_get_person_name($firstname, $lastname) .' ('.$username.')'. $opendocurl_end;
  503. }
  504. function sort_by_user($item1, $item2)
  505. {
  506. $user1 = $item1['user'];
  507. $user2 = $item2['user'];
  508. if (api_sort_by_first_name()) {
  509. $result = api_strcmp($user1['firstname'], $user2['firstname']);
  510. if ($result == 0) {
  511. return api_strcmp($user1['lastname'], $user2['lastname']);
  512. }
  513. } else {
  514. $result = api_strcmp($user1['lastname'], $user2['lastname']);
  515. if ($result == 0) {
  516. return api_strcmp($user1['firstname'], $user2['firstname']);
  517. }
  518. }
  519. return $result;
  520. }
  521. }