AdvancedSubscriptionPlugin.php 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Class AdvancedSubscriptionPlugin
  5. * This class is used to add an advanced subscription allowing the admin to
  6. * create user queues requesting a subscribe to a session.
  7. *
  8. * @package chamilo.plugin.advanced_subscription
  9. */
  10. class AdvancedSubscriptionPlugin extends Plugin implements HookPluginInterface
  11. {
  12. protected $strings;
  13. private $errorMessages;
  14. /**
  15. * Constructor.
  16. */
  17. public function __construct()
  18. {
  19. $parameters = [
  20. 'yearly_cost_limit' => 'text',
  21. 'yearly_hours_limit' => 'text',
  22. 'yearly_cost_unit_converter' => 'text',
  23. 'courses_count_limit' => 'text',
  24. 'course_session_credit_year_start_date' => 'text',
  25. 'ws_url' => 'text',
  26. 'min_profile_percentage' => 'text',
  27. 'check_induction' => 'boolean',
  28. 'secret_key' => 'text',
  29. 'terms_and_conditions' => 'wysiwyg',
  30. ];
  31. parent::__construct('1.0', 'Imanol Losada, Daniel Barreto', $parameters);
  32. $this->errorMessages = [];
  33. }
  34. /**
  35. * Instance the plugin.
  36. *
  37. * @staticvar null $result
  38. *
  39. * @return AdvancedSubscriptionPlugin
  40. */
  41. public static function create()
  42. {
  43. static $result = null;
  44. return $result ? $result : $result = new self();
  45. }
  46. /**
  47. * Install the plugin.
  48. */
  49. public function install()
  50. {
  51. $this->installDatabase();
  52. $this->addAreaField();
  53. $this->installHook();
  54. }
  55. /**
  56. * Uninstall the plugin.
  57. */
  58. public function uninstall()
  59. {
  60. $setting = api_get_setting('advanced_subscription');
  61. if (!empty($setting)) {
  62. $this->uninstallHook();
  63. // Note: Keeping area field data is intended so it will not be removed
  64. $this->uninstallDatabase();
  65. }
  66. }
  67. /**
  68. * Get the error messages list.
  69. *
  70. * @return array The message list
  71. */
  72. public function getErrorMessages()
  73. {
  74. return $this->errorMessages;
  75. }
  76. /**
  77. * Check if is allowed subscribe to open session.
  78. *
  79. * @param array $params WS params
  80. *
  81. * @return bool
  82. */
  83. public function isAllowedSubscribeToOpenSession($params)
  84. {
  85. $self = self::create();
  86. $wsUrl = $self->get('ws_url');
  87. $profileCompleted = 0;
  88. if (!empty($wsUrl)) {
  89. $client = new SoapClient(
  90. null,
  91. ['location' => $wsUrl, 'uri' => $wsUrl]
  92. );
  93. $userInfo = api_get_user_info(
  94. $params['user_id'],
  95. false,
  96. false,
  97. true
  98. );
  99. try {
  100. $profileCompleted = $client->__soapCall(
  101. 'getProfileCompletionPercentage',
  102. $userInfo['extra']['drupal_user_id']
  103. );
  104. } catch (\Exception $e) {
  105. $profileCompleted = 0;
  106. }
  107. } elseif (isset($params['profile_completed'])) {
  108. $profileCompleted = (float) $params['profile_completed'];
  109. }
  110. $profileCompletedMin = (float) $self->get('min_profile_percentage');
  111. if ($profileCompleted < $profileCompletedMin) {
  112. $this->errorMessages[] = sprintf(
  113. $this->get_lang('AdvancedSubscriptionProfileIncomplete'),
  114. $profileCompletedMin,
  115. $profileCompleted
  116. );
  117. }
  118. $vacancy = $self->getVacancy($params['session_id']);
  119. $sessionInfo = api_get_session_info($params['session_id']);
  120. if ($sessionInfo['nbr_users'] >= $vacancy) {
  121. $this->errorMessages[] = sprintf(
  122. $this->get_lang('SessionXWithoutVacancies'),
  123. $sessionInfo['name']
  124. );
  125. }
  126. return empty($this->errorMessages);
  127. }
  128. /**
  129. * Return true if user is allowed to be added to queue for session subscription.
  130. *
  131. * @param int $userId
  132. * @param array $params MUST have keys:
  133. * "is_connected" Indicate if the user is online on external web
  134. * "profile_completed" Percentage of completed profile, given by WS
  135. * @param bool $collectErrors Optional. Default is false. Whether collect all errors or throw exeptions
  136. *
  137. * @throws Exception
  138. *
  139. * @return bool
  140. */
  141. public function isAllowedToDoRequest($userId, $params = [], $collectErrors = false)
  142. {
  143. $plugin = self::create();
  144. $wsUrl = $plugin->get('ws_url');
  145. // Student always is connected
  146. $isConnected = true;
  147. if (!$isConnected) {
  148. $this->errorMessages[] = $this->get_lang('AdvancedSubscriptionNotConnected');
  149. if (!$collectErrors) {
  150. throw new \Exception($this->get_lang('AdvancedSubscriptionNotConnected'));
  151. }
  152. }
  153. $profileCompletedMin = (float) $plugin->get('min_profile_percentage');
  154. $profileCompleted = 0;
  155. if (is_string($wsUrl) && !empty($wsUrl)) {
  156. $options = [
  157. 'location' => $wsUrl,
  158. 'uri' => $wsUrl,
  159. ];
  160. $client = new SoapClient(null, $options);
  161. $userInfo = api_get_user_info($userId);
  162. try {
  163. $profileCompleted = $client->__soapCall('getProfileCompletionPercentage', $userInfo['extra']['drupal_user_id']);
  164. } catch (\Exception $e) {
  165. $profileCompleted = 0;
  166. }
  167. } elseif (isset($params['profile_completed'])) {
  168. $profileCompleted = (float) $params['profile_completed'];
  169. }
  170. if ($profileCompleted < $profileCompletedMin) {
  171. $errorMessage = sprintf(
  172. $this->get_lang('AdvancedSubscriptionProfileIncomplete'),
  173. $profileCompletedMin,
  174. $profileCompleted
  175. );
  176. $this->errorMessages[] = $errorMessage;
  177. if (!$collectErrors) {
  178. throw new \Exception($errorMessage);
  179. }
  180. }
  181. $yearlyCostLimit = $plugin->get('yearly_cost_limit');
  182. $maxCost = $plugin->get('yearly_cost_unit_converter');
  183. $maxCost *= $yearlyCostLimit;
  184. $userCost = 0;
  185. $now = new DateTime(api_get_utc_datetime());
  186. $newYearDate = $plugin->get('course_session_credit_year_start_date');
  187. $newYearDate = !empty($newYearDate) ?
  188. new \DateTime($newYearDate.$now->format('/Y')) : $now;
  189. $extra = new ExtraFieldValue('session');
  190. $joinSessionTable = Database::get_main_table(TABLE_MAIN_SESSION_USER).' su INNER JOIN '.
  191. Database::get_main_table(TABLE_MAIN_SESSION).' s ON s.id = su.session_id';
  192. $whereSessionParams = 'su.relation_type = ? AND s.access_start_date >= ? AND su.user_id = ?';
  193. $whereSessionParamsValues = [
  194. 0,
  195. $newYearDate->format('Y-m-d'),
  196. $userId,
  197. ];
  198. $whereSession = [
  199. 'where' => [
  200. $whereSessionParams => $whereSessionParamsValues,
  201. ],
  202. ];
  203. $selectSession = 's.id AS id';
  204. $sessions = Database::select(
  205. $selectSession,
  206. $joinSessionTable,
  207. $whereSession
  208. );
  209. $expendedTimeMax = $plugin->get('yearly_hours_limit');
  210. $expendedTime = 0;
  211. if (is_array($sessions) && count($sessions) > 0) {
  212. foreach ($sessions as $session) {
  213. $costField = $extra->get_values_by_handler_and_field_variable($session['id'], 'cost');
  214. $userCost += $costField['value'];
  215. $teachingHoursField = $extra->get_values_by_handler_and_field_variable($session['id'], 'teaching_hours');
  216. $expendedTime += $teachingHoursField['value'];
  217. }
  218. }
  219. if (isset($params['sessionId'])) {
  220. $costField = $extra->get_values_by_handler_and_field_variable($params['sessionId'], 'cost');
  221. $userCost += $costField['value'];
  222. $teachingHoursField = $extra->get_values_by_handler_and_field_variable($params['sessionId'], 'teaching_hours');
  223. $expendedTime += $teachingHoursField['value'];
  224. }
  225. if ($maxCost <= $userCost) {
  226. $errorMessage = sprintf(
  227. $this->get_lang('AdvancedSubscriptionCostXLimitReached'),
  228. $yearlyCostLimit
  229. );
  230. $this->errorMessages[] = $errorMessage;
  231. if (!$collectErrors) {
  232. throw new \Exception($errorMessage);
  233. }
  234. }
  235. if ($expendedTimeMax <= $expendedTime) {
  236. $errorMessage = sprintf(
  237. $this->get_lang('AdvancedSubscriptionTimeXLimitReached'),
  238. $expendedTimeMax
  239. );
  240. $this->errorMessages[] = $errorMessage;
  241. if (!$collectErrors) {
  242. throw new \Exception($errorMessage);
  243. }
  244. }
  245. $expendedNumMax = $plugin->get('courses_count_limit');
  246. $expendedNum = count($sessions);
  247. if ($expendedNumMax <= $expendedNum) {
  248. $errorMessage = sprintf(
  249. $this->get_lang('AdvancedSubscriptionCourseXLimitReached'),
  250. $expendedNumMax
  251. );
  252. $this->errorMessages[] = $errorMessage;
  253. if (!$collectErrors) {
  254. throw new \Exception($errorMessage);
  255. }
  256. }
  257. $checkInduction = $plugin->get('check_induction');
  258. $numberOfApprovedInductionSessions = $this->getApprovedInductionSessions($userId);
  259. $completedInduction = $numberOfApprovedInductionSessions > 0;
  260. if ($checkInduction == 'true' && !$completedInduction) {
  261. $this->errorMessages[] = $this->get_lang('AdvancedSubscriptionIncompleteInduction');
  262. if (!$collectErrors) {
  263. throw new \Exception($this->get_lang('AdvancedSubscriptionIncompleteInduction'));
  264. }
  265. }
  266. return empty($this->errorMessages);
  267. }
  268. /**
  269. * Register a user into a queue for a session.
  270. *
  271. * @param $userId
  272. * @param $sessionId
  273. *
  274. * @return bool|int
  275. */
  276. public function addToQueue($userId, $sessionId)
  277. {
  278. // Filter input variables
  279. $userId = intval($userId);
  280. $sessionId = intval($sessionId);
  281. $now = api_get_utc_datetime();
  282. $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
  283. $attributes = [
  284. 'session_id' => $sessionId,
  285. 'user_id' => $userId,
  286. 'status' => 0,
  287. 'created_at' => $now,
  288. 'updated_at' => null,
  289. ];
  290. $id = Database::insert($advancedSubscriptionQueueTable, $attributes);
  291. return $id;
  292. }
  293. /**
  294. * Register message with type and status.
  295. *
  296. * @param $mailId
  297. * @param $userId
  298. * @param $sessionId
  299. *
  300. * @return bool|int
  301. */
  302. public function saveLastMessage($mailId, $userId, $sessionId)
  303. {
  304. // Filter variables
  305. $mailId = intval($mailId);
  306. $userId = intval($userId);
  307. $sessionId = intval($sessionId);
  308. $queueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
  309. $attributes = [
  310. 'last_message_id' => $mailId,
  311. 'updated_at' => api_get_utc_datetime(),
  312. ];
  313. $num = Database::update(
  314. $queueTable,
  315. $attributes,
  316. ['user_id = ? AND session_id = ?' => [$userId, $sessionId]]
  317. );
  318. return $num;
  319. }
  320. /**
  321. * Check for requirements and register user into queue.
  322. *
  323. * @param $userId
  324. * @param $sessionId
  325. * @param $params
  326. *
  327. * @return bool|string
  328. */
  329. public function startSubscription($userId, $sessionId, $params)
  330. {
  331. $result = 'Params not found';
  332. if (!empty($sessionId) && !empty($userId)) {
  333. $plugin = self::create();
  334. try {
  335. if ($plugin->isAllowedToDoRequest($userId, $params)) {
  336. $result = (bool) $plugin->addToQueue($userId, $sessionId);
  337. } else {
  338. throw new \Exception($this->get_lang('AdvancedSubscriptionNotMoreAble'));
  339. }
  340. } catch (Exception $e) {
  341. $result = $e->getMessage();
  342. }
  343. }
  344. return $result;
  345. }
  346. /**
  347. * Send message for the student subscription approval to a specific session.
  348. *
  349. * @param int|array $studentId
  350. * @param int $receiverId
  351. * @param string $subject
  352. * @param string $content
  353. * @param int $sessionId
  354. * @param bool $save
  355. * @param array $fileAttachments
  356. *
  357. * @return bool|int
  358. */
  359. public function sendMailMessage(
  360. $studentId,
  361. $receiverId,
  362. $subject,
  363. $content,
  364. $sessionId,
  365. $save = false,
  366. $fileAttachments = []
  367. ) {
  368. if (!empty($fileAttachments) &&
  369. is_array($fileAttachments) &&
  370. isset($fileAttachments['files']) &&
  371. isset($fileAttachments['comments'])
  372. ) {
  373. $mailId = MessageManager::send_message(
  374. $receiverId,
  375. $subject,
  376. $content,
  377. $fileAttachments['files'],
  378. $fileAttachments['comments']
  379. );
  380. } else {
  381. $mailId = MessageManager::send_message(
  382. $receiverId,
  383. $subject,
  384. $content
  385. );
  386. }
  387. if ($save && !empty($mailId)) {
  388. // Save as sent message
  389. if (is_array($studentId) && !empty($studentId)) {
  390. foreach ($studentId as $student) {
  391. $this->saveLastMessage($mailId, $student['user_id'], $sessionId);
  392. }
  393. } else {
  394. $studentId = intval($studentId);
  395. $this->saveLastMessage($mailId, $studentId, $sessionId);
  396. }
  397. } elseif (!empty($mailId)) {
  398. // Update queue row, updated_at
  399. Database::update(
  400. Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE),
  401. [
  402. 'updated_at' => api_get_utc_datetime(),
  403. ],
  404. [
  405. 'user_id = ? AND session_id = ?' => [$studentId, $sessionId],
  406. ]
  407. );
  408. }
  409. return $mailId;
  410. }
  411. /**
  412. * Check if session is open for subscription.
  413. *
  414. * @param $sessionId
  415. * @param string $fieldVariable
  416. *
  417. * @return bool
  418. */
  419. public function isSessionOpen($sessionId, $fieldVariable = 'is_open_session')
  420. {
  421. $extraFieldValue = new ExtraFieldValue('session');
  422. $result = $extraFieldValue->get_values_by_handler_and_field_variable(
  423. $sessionId,
  424. $fieldVariable
  425. );
  426. $isOpen = false;
  427. if (!empty($result)) {
  428. $isOpen = (bool) $result['value'];
  429. }
  430. return $isOpen;
  431. }
  432. /**
  433. * Check if user is in the session's target group based on its area.
  434. *
  435. * @param $userId
  436. * @param $sessionId
  437. * @param string $userFieldVariable
  438. * @param string $sessionFieldVariable
  439. *
  440. * @return bool
  441. */
  442. public function isUserInTargetGroup(
  443. $userId,
  444. $sessionId,
  445. $userFieldVariable = 'area',
  446. $sessionFieldVariable = 'target'
  447. ) {
  448. $extraSessionFieldValue = new ExtraFieldValue('session');
  449. $sessionTarget = $extraSessionFieldValue->get_values_by_handler_and_field_variable(
  450. $sessionId,
  451. $sessionFieldVariable
  452. );
  453. $extraUserFieldValue = new ExtraFieldValue('user');
  454. $userArea = $extraUserFieldValue->get_values_by_handler_and_field_variable(
  455. $userId,
  456. $userFieldVariable
  457. );
  458. $isInTargetGroup = false;
  459. if (isset($sessionTarget) && (!empty($sessionTarget)) && $sessionTarget['value'] == 'minedu') {
  460. if (substr($userArea['value'], 0, 6) == 'MINEDU') {
  461. $isInTargetGroup = true;
  462. }
  463. }
  464. if (isset($sessionTarget) && (!empty($sessionTarget)) && $sessionTarget['value'] == 'regiones') {
  465. if ((substr($userArea['value'], 0, 4) == 'UGEL') || (substr($userArea['value'], 0, 3) == 'DRE')) {
  466. $isInTargetGroup = true;
  467. }
  468. }
  469. return $isInTargetGroup;
  470. }
  471. /**
  472. * Update the queue status for subscription approval rejected or accepted.
  473. *
  474. * @param $params
  475. * @param $newStatus
  476. *
  477. * @return bool
  478. */
  479. public function updateQueueStatus($params, $newStatus)
  480. {
  481. $newStatus = intval($newStatus);
  482. $res = false;
  483. if (isset($params['queue']['id'])) {
  484. $where = [
  485. 'id = ?' => intval($params['queue']['id']),
  486. ];
  487. } elseif (isset($params['studentUserId']) && isset($params['sessionId'])) {
  488. $where = [
  489. 'user_id = ? AND session_id = ? AND status <> ? AND status <> ?' => [
  490. intval($params['studentUserId']),
  491. intval($params['sessionId']),
  492. $newStatus,
  493. ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED,
  494. ],
  495. ];
  496. }
  497. if (isset($where)) {
  498. $res = (bool) Database::update(
  499. Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE),
  500. [
  501. 'status' => $newStatus,
  502. 'updated_at' => api_get_utc_datetime(),
  503. ],
  504. $where
  505. );
  506. }
  507. return $res;
  508. }
  509. /**
  510. * Render and send mail by defined advanced subscription action.
  511. *
  512. * @param $data
  513. * @param $actionType
  514. *
  515. * @return array
  516. */
  517. public function sendMail($data, $actionType)
  518. {
  519. $template = new Template($this->get_lang('plugin_title'));
  520. $template->assign('data', $data);
  521. $templateParams = [
  522. 'user',
  523. 'student',
  524. 'students',
  525. 'superior',
  526. 'admins',
  527. 'session',
  528. 'signature',
  529. 'admin_view_url',
  530. 'acceptUrl',
  531. 'rejectUrl',
  532. ];
  533. foreach ($templateParams as $templateParam) {
  534. $template->assign($templateParam, $data[$templateParam]);
  535. }
  536. $mailIds = [];
  537. switch ($actionType) {
  538. case ADVANCED_SUBSCRIPTION_ACTION_STUDENT_REQUEST:
  539. // Mail to student
  540. $mailIds['render'] = $this->sendMailMessage(
  541. $data['studentUserId'],
  542. $data['student']['user_id'],
  543. $this->get_lang('MailStudentRequest'),
  544. $template->fetch('/advanced_subscription/views/student_notice_student.tpl'),
  545. $data['sessionId'],
  546. true
  547. );
  548. // Mail to superior
  549. $mailIds[] = $this->sendMailMessage(
  550. $data['studentUserId'],
  551. $data['superior']['user_id'],
  552. $this->get_lang('MailStudentRequest'),
  553. $template->fetch('/advanced_subscription/views/student_notice_superior.tpl'),
  554. $data['sessionId']
  555. );
  556. break;
  557. case ADVANCED_SUBSCRIPTION_ACTION_SUPERIOR_APPROVE:
  558. // Mail to student
  559. $mailIds[] = $this->sendMailMessage(
  560. $data['studentUserId'],
  561. $data['student']['user_id'],
  562. $this->get_lang('MailBossAccept'),
  563. $template->fetch('/advanced_subscription/views/superior_accepted_notice_student.tpl'),
  564. $data['sessionId'],
  565. true
  566. );
  567. // Mail to superior
  568. $mailIds['render'] = $this->sendMailMessage(
  569. $data['studentUserId'],
  570. $data['superior']['user_id'],
  571. $this->get_lang('MailBossAccept'),
  572. $template->fetch('/advanced_subscription/views/superior_accepted_notice_superior.tpl'),
  573. $data['sessionId']
  574. );
  575. // Mail to admin
  576. foreach ($data['admins'] as $adminId => $admin) {
  577. $template->assign('admin', $admin);
  578. $mailIds[] = $this->sendMailMessage(
  579. $data['studentUserId'],
  580. $adminId,
  581. $this->get_lang('MailBossAccept'),
  582. $template->fetch('/advanced_subscription/views/superior_accepted_notice_admin.tpl'),
  583. $data['sessionId']
  584. );
  585. }
  586. break;
  587. case ADVANCED_SUBSCRIPTION_ACTION_SUPERIOR_DISAPPROVE:
  588. // Mail to student
  589. $mailIds[] = $this->sendMailMessage(
  590. $data['studentUserId'],
  591. $data['student']['user_id'],
  592. $this->get_lang('MailBossReject'),
  593. $template->fetch('/advanced_subscription/views/superior_rejected_notice_student.tpl'),
  594. $data['sessionId'],
  595. true
  596. );
  597. // Mail to superior
  598. $mailIds['render'] = $this->sendMailMessage(
  599. $data['studentUserId'],
  600. $data['superior']['user_id'],
  601. $this->get_lang('MailBossReject'),
  602. $template->fetch('/advanced_subscription/views/superior_rejected_notice_superior.tpl'),
  603. $data['sessionId']
  604. );
  605. break;
  606. case ADVANCED_SUBSCRIPTION_ACTION_SUPERIOR_SELECT:
  607. // Mail to student
  608. $mailIds[] = $this->sendMailMessage(
  609. $data['studentUserId'],
  610. $data['student']['user_id'],
  611. $this->get_lang('MailStudentRequestSelect'),
  612. $template->fetch('/advanced_subscription/views/student_notice_student.tpl'),
  613. $data['sessionId'],
  614. true
  615. );
  616. // Mail to superior
  617. $mailIds['render'] = $this->sendMailMessage(
  618. $data['studentUserId'],
  619. $data['superior']['user_id'],
  620. $this->get_lang('MailStudentRequestSelect'),
  621. $template->fetch('/advanced_subscription/views/student_notice_superior.tpl'),
  622. $data['sessionId']
  623. );
  624. break;
  625. case ADVANCED_SUBSCRIPTION_ACTION_ADMIN_APPROVE:
  626. $fileAttachments = [];
  627. if (api_get_plugin_setting('courselegal', 'tool_enable')) {
  628. $courseLegal = CourseLegalPlugin::create();
  629. $courses = SessionManager::get_course_list_by_session_id($data['sessionId']);
  630. $course = current($courses);
  631. $data['courseId'] = $course['id'];
  632. $data['course'] = api_get_course_info_by_id($data['courseId']);
  633. $termsAndConditions = $courseLegal->getData($data['courseId'], $data['sessionId']);
  634. $termsAndConditions = $termsAndConditions['content'];
  635. $termsAndConditions = $this->renderTemplateString($termsAndConditions, $data);
  636. $tpl = new Template(get_lang('TermsAndConditions'));
  637. $tpl->assign('session', $data['session']);
  638. $tpl->assign('student', $data['student']);
  639. $tpl->assign('sessionId', $data['sessionId']);
  640. $tpl->assign('termsContent', $termsAndConditions);
  641. $termsAndConditions = $tpl->fetch('/advanced_subscription/views/terms_and_conditions_to_pdf.tpl');
  642. $pdf = new PDF();
  643. $filename = 'terms'.sha1(rand(0, 99999));
  644. $pdf->content_to_pdf($termsAndConditions, null, $filename, null, 'F');
  645. $fileAttachments['file'][] = [
  646. 'name' => $filename.'.pdf',
  647. 'application/pdf' => $filename.'.pdf',
  648. 'tmp_name' => api_get_path(SYS_ARCHIVE_PATH).$filename.'.pdf',
  649. 'error' => UPLOAD_ERR_OK,
  650. 'size' => filesize(api_get_path(SYS_ARCHIVE_PATH).$filename.'.pdf'),
  651. ];
  652. $fileAttachments['comments'][] = get_lang('TermsAndConditions');
  653. }
  654. // Mail to student
  655. $mailIds[] = $this->sendMailMessage(
  656. $data['studentUserId'],
  657. $data['student']['user_id'],
  658. $this->get_lang('MailAdminAccept'),
  659. $template->fetch('/advanced_subscription/views/admin_accepted_notice_student.tpl'),
  660. $data['sessionId'],
  661. true,
  662. $fileAttachments
  663. );
  664. // Mail to superior
  665. $mailIds[] = $this->sendMailMessage(
  666. $data['studentUserId'],
  667. $data['superior']['user_id'],
  668. $this->get_lang('MailAdminAccept'),
  669. $template->fetch('/advanced_subscription/views/admin_accepted_notice_superior.tpl'),
  670. $data['sessionId']
  671. );
  672. // Mail to admin
  673. $adminId = $data['currentUserId'];
  674. $template->assign('admin', $data['admins'][$adminId]);
  675. $mailIds['render'] = $this->sendMailMessage(
  676. $data['studentUserId'],
  677. $adminId,
  678. $this->get_lang('MailAdminAccept'),
  679. $template->fetch('/advanced_subscription/views/admin_accepted_notice_admin.tpl'),
  680. $data['sessionId']
  681. );
  682. break;
  683. case ADVANCED_SUBSCRIPTION_ACTION_ADMIN_DISAPPROVE:
  684. // Mail to student
  685. $mailIds[] = $this->sendMailMessage(
  686. $data['studentUserId'],
  687. $data['student']['user_id'],
  688. $this->get_lang('MailAdminReject'),
  689. $template->fetch('/advanced_subscription/views/admin_rejected_notice_student.tpl'),
  690. $data['sessionId'],
  691. true
  692. );
  693. // Mail to superior
  694. $mailIds[] = $this->sendMailMessage(
  695. $data['studentUserId'],
  696. $data['superior']['user_id'],
  697. $this->get_lang('MailAdminReject'),
  698. $template->fetch('/advanced_subscription/views/admin_rejected_notice_superior.tpl'),
  699. $data['sessionId']
  700. );
  701. // Mail to admin
  702. $adminId = $data['currentUserId'];
  703. $template->assign('admin', $data['admins'][$adminId]);
  704. $mailIds['render'] = $this->sendMailMessage(
  705. $data['studentUserId'],
  706. $adminId,
  707. $this->get_lang('MailAdminReject'),
  708. $template->fetch('/advanced_subscription/views/admin_rejected_notice_admin.tpl'),
  709. $data['sessionId']
  710. );
  711. break;
  712. case ADVANCED_SUBSCRIPTION_ACTION_STUDENT_REQUEST_NO_BOSS:
  713. // Mail to student
  714. $mailIds['render'] = $this->sendMailMessage(
  715. $data['studentUserId'],
  716. $data['student']['user_id'],
  717. $this->get_lang('MailStudentRequestNoBoss'),
  718. $template->fetch('/advanced_subscription/views/student_no_superior_notice_student.tpl'),
  719. $data['sessionId'],
  720. true
  721. );
  722. // Mail to admin
  723. foreach ($data['admins'] as $adminId => $admin) {
  724. $template->assign('admin', $admin);
  725. $mailIds[] = $this->sendMailMessage(
  726. $data['studentUserId'],
  727. $adminId,
  728. $this->get_lang('MailStudentRequestNoBoss'),
  729. $template->fetch('/advanced_subscription/views/student_no_superior_notice_admin.tpl'),
  730. $data['sessionId']
  731. );
  732. }
  733. break;
  734. case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_STUDENT:
  735. $mailIds['render'] = $this->sendMailMessage(
  736. $data['student']['user_id'],
  737. $data['student']['user_id'],
  738. $this->get_lang('MailRemindStudent'),
  739. $template->fetch('/advanced_subscription/views/reminder_notice_student.tpl'),
  740. $data['sessionId'],
  741. true
  742. );
  743. break;
  744. case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_SUPERIOR:
  745. $mailIds['render'] = $this->sendMailMessage(
  746. $data['students'],
  747. $data['superior']['user_id'],
  748. $this->get_lang('MailRemindSuperior'),
  749. $template->fetch('/advanced_subscription/views/reminder_notice_superior.tpl'),
  750. $data['sessionId']
  751. );
  752. break;
  753. case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_SUPERIOR_MAX:
  754. $mailIds['render'] = $this->sendMailMessage(
  755. $data['students'],
  756. $data['superior']['user_id'],
  757. $this->get_lang('MailRemindSuperior'),
  758. $template->fetch('/advanced_subscription/views/reminder_notice_superior_max.tpl'),
  759. $data['sessionId']
  760. );
  761. break;
  762. case ADVANCED_SUBSCRIPTION_ACTION_REMINDER_ADMIN:
  763. // Mail to admin
  764. foreach ($data['admins'] as $adminId => $admin) {
  765. $template->assign('admin', $admin);
  766. $mailIds[] = $this->sendMailMessage(
  767. $data['students'],
  768. $adminId,
  769. $this->get_lang('MailRemindAdmin'),
  770. $template->fetch('/advanced_subscription/views/reminder_notice_admin.tpl'),
  771. $data['sessionId']
  772. );
  773. }
  774. break;
  775. default:
  776. break;
  777. }
  778. return $mailIds;
  779. }
  780. /**
  781. * Count the users in queue filtered by params (sessions, status).
  782. *
  783. * @param array $params Input array containing the set of
  784. * session and status to count from queue
  785. * e.g:
  786. * array('sessions' => array(215, 218, 345, 502),
  787. * 'status' => array(0, 1, 2))
  788. *
  789. * @return int
  790. */
  791. public function countQueueByParams($params)
  792. {
  793. $count = 0;
  794. if (!empty($params) && is_array($params)) {
  795. $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
  796. $where['1 = ? '] = 1;
  797. if (isset($params['sessions']) && is_array($params['sessions'])) {
  798. foreach ($params['sessions'] as &$sessionId) {
  799. $sessionId = intval($sessionId);
  800. }
  801. $where['AND session_id IN ( ? ) '] = implode($params['sessions']);
  802. }
  803. if (isset($params['status']) && is_array($params['status'])) {
  804. foreach ($params['status'] as &$status) {
  805. $status = intval($status);
  806. }
  807. $where['AND status IN ( ? ) '] = implode($params['status']);
  808. }
  809. $where['where'] = $where;
  810. $count = Database::select('COUNT(*)', $advancedSubscriptionQueueTable, $where);
  811. $count = $count[0]['COUNT(*)'];
  812. }
  813. return $count;
  814. }
  815. /**
  816. * This method will call the Hook management insertHook to add Hook observer from this plugin.
  817. */
  818. public function installHook()
  819. {
  820. $hookObserver = HookAdvancedSubscription::create();
  821. HookAdminBlock::create()->attach($hookObserver);
  822. HookWSRegistration::create()->attach($hookObserver);
  823. HookNotificationContent::create()->attach($hookObserver);
  824. HookNotificationTitle::create()->attach($hookObserver);
  825. }
  826. /**
  827. * This method will call the Hook management deleteHook to disable Hook observer from this plugin.
  828. */
  829. public function uninstallHook()
  830. {
  831. $hookObserver = HookAdvancedSubscription::create();
  832. HookAdminBlock::create()->detach($hookObserver);
  833. HookWSRegistration::create()->detach($hookObserver);
  834. HookNotificationContent::create()->detach($hookObserver);
  835. HookNotificationTitle::create()->detach($hookObserver);
  836. }
  837. /**
  838. * Return the status from user in queue to session subscription.
  839. *
  840. * @param int $userId
  841. * @param int $sessionId
  842. *
  843. * @return bool|int
  844. */
  845. public function getQueueStatus($userId, $sessionId)
  846. {
  847. $userId = intval($userId);
  848. $sessionId = intval($sessionId);
  849. if (!empty($userId) && !empty($sessionId)) {
  850. $queueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
  851. $row = Database::select(
  852. 'status',
  853. $queueTable,
  854. [
  855. 'where' => [
  856. 'user_id = ? AND session_id = ?' => [$userId, $sessionId],
  857. ],
  858. ]
  859. );
  860. if (count($row) == 1) {
  861. return $row[0]['status'];
  862. } else {
  863. return ADVANCED_SUBSCRIPTION_QUEUE_STATUS_NO_QUEUE;
  864. }
  865. }
  866. return false;
  867. }
  868. /**
  869. * Return the remaining vacancy.
  870. *
  871. * @param $sessionId
  872. *
  873. * @return bool|int
  874. */
  875. public function getVacancy($sessionId)
  876. {
  877. if (!empty($sessionId)) {
  878. $extra = new ExtraFieldValue('session');
  879. $var = $extra->get_values_by_handler_and_field_variable(
  880. $sessionId,
  881. 'vacancies'
  882. );
  883. $vacancy = intval($var['value']);
  884. if (!empty($vacancy)) {
  885. $vacancy -= $this->countQueueByParams(
  886. [
  887. 'sessions' => [$sessionId],
  888. 'status' => [ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED],
  889. ]
  890. );
  891. if ($vacancy >= 0) {
  892. return $vacancy;
  893. } else {
  894. return 0;
  895. }
  896. }
  897. }
  898. return false;
  899. }
  900. /**
  901. * Return the session details data from a session ID (including the extra
  902. * fields used for the advanced subscription mechanism).
  903. *
  904. * @param $sessionId
  905. *
  906. * @return bool|mixed
  907. */
  908. public function getSessionDetails($sessionId)
  909. {
  910. if (!empty($sessionId)) {
  911. // Assign variables
  912. $fieldsArray = [
  913. 'code',
  914. 'cost',
  915. 'place',
  916. 'allow_visitors',
  917. 'teaching_hours',
  918. 'brochure',
  919. 'banner',
  920. ];
  921. $extraField = new ExtraField('session');
  922. // Get session fields
  923. $fieldList = $extraField->get_all([
  924. 'variable IN ( ?, ?, ?, ?, ?, ?, ? )' => $fieldsArray,
  925. ]);
  926. // Index session fields
  927. $fields = [];
  928. foreach ($fieldList as $field) {
  929. $fields[$field['id']] = $field['variable'];
  930. }
  931. $mergedArray = array_merge([$sessionId], array_keys($fields));
  932. $sql = "SELECT * FROM ".Database::get_main_table(TABLE_EXTRA_FIELD_VALUES)."
  933. WHERE item_id = %d AND field_id IN (%d, %d, %d, %d, %d, %d, %d)";
  934. $sql = vsprintf($sql, $mergedArray);
  935. $sessionFieldValueList = Database::query($sql);
  936. while ($sessionFieldValue = Database::fetch_assoc($sessionFieldValueList)) {
  937. // Check if session field value is set in session field list
  938. if (isset($fields[$sessionFieldValue['field_id']])) {
  939. $var = $fields[$sessionFieldValue['field_id']];
  940. $val = $sessionFieldValue['value'];
  941. // Assign session field value to session
  942. $sessionArray[$var] = $val;
  943. }
  944. }
  945. $sessionArray['description'] = SessionManager::getDescriptionFromSessionId($sessionId);
  946. if (isset($sessionArray['brochure'])) {
  947. $sessionArray['brochure'] = api_get_path(WEB_UPLOAD_PATH).$sessionArray['brochure'];
  948. }
  949. if (isset($sessionArray['banner'])) {
  950. $sessionArray['banner'] = api_get_path(WEB_UPLOAD_PATH).$sessionArray['banner'];
  951. }
  952. return $sessionArray;
  953. }
  954. return false;
  955. }
  956. /**
  957. * Get status message.
  958. *
  959. * @param int $status
  960. * @param bool $isAble
  961. *
  962. * @return string
  963. */
  964. public function getStatusMessage($status, $isAble = true)
  965. {
  966. switch ($status) {
  967. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_NO_QUEUE:
  968. $message = $this->get_lang('AdvancedSubscriptionNoQueue');
  969. if ($isAble) {
  970. $message = $this->get_lang('AdvancedSubscriptionNoQueueIsAble');
  971. }
  972. break;
  973. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_START:
  974. $message = $this->get_lang('AdvancedSubscriptionQueueStart');
  975. break;
  976. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_DISAPPROVED:
  977. $message = $this->get_lang('AdvancedSubscriptionQueueBossDisapproved');
  978. break;
  979. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_APPROVED:
  980. $message = $this->get_lang('AdvancedSubscriptionQueueBossApproved');
  981. break;
  982. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_DISAPPROVED:
  983. $message = $this->get_lang('AdvancedSubscriptionQueueAdminDisapproved');
  984. break;
  985. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED:
  986. $message = $this->get_lang('AdvancedSubscriptionQueueAdminApproved');
  987. break;
  988. default:
  989. $message = sprintf($this->get_lang('AdvancedSubscriptionQueueDefault'), $status);
  990. }
  991. return $message;
  992. }
  993. /**
  994. * Return the url to go to session.
  995. *
  996. * @param $sessionId
  997. *
  998. * @return string
  999. */
  1000. public function getSessionUrl($sessionId)
  1001. {
  1002. $url = api_get_path(WEB_CODE_PATH).'session/?session_id='.intval($sessionId);
  1003. return $url;
  1004. }
  1005. /**
  1006. * Get a url for subscribe a user in session.
  1007. *
  1008. * @param int $userId The user ID
  1009. * @param array $params Params from WS
  1010. *
  1011. * @return string
  1012. */
  1013. public function getOpenSessionUrl($userId, $params)
  1014. {
  1015. $userIsSubscribed = SessionManager::isUserSubscribedAsStudent(
  1016. $params['session_id'],
  1017. $userId
  1018. );
  1019. if ($userIsSubscribed) {
  1020. return api_get_path(WEB_CODE_PATH)
  1021. .'session/index.php?session_id='
  1022. .intval($params['session_id']);
  1023. }
  1024. $params['secret_key'] = null;
  1025. $params['user_id'] = null;
  1026. $params['user_field'] = null;
  1027. $params['is_connected'] = null;
  1028. $urlParams = array_merge($params, ['user_id' => $userId]);
  1029. $url = api_get_path(WEB_PLUGIN_PATH);
  1030. $url .= 'advanced_subscription/src/open_session.php?';
  1031. $url .= http_build_query($urlParams);
  1032. return 'javascript:void(window.open(\''
  1033. .$url
  1034. .'\',\'AdvancedSubscriptionTerms\', \'toolbar=no,location=no,'
  1035. .'status=no,menubar=no,scrollbars=yes,resizable=yes,width=700px,'
  1036. .'height=600px\', \'100\' ))';
  1037. }
  1038. /**
  1039. * Return the url to enter to subscription queue to session.
  1040. *
  1041. * @param $params
  1042. *
  1043. * @return string
  1044. */
  1045. public function getQueueUrl($params)
  1046. {
  1047. $url = api_get_path(WEB_PLUGIN_PATH).'advanced_subscription/ajax/advanced_subscription.ajax.php?'.
  1048. 'a='.Security::remove_XSS($params['action']).'&'.
  1049. 's='.intval($params['sessionId']).'&'.
  1050. 'current_user_id='.intval($params['currentUserId']).'&'.
  1051. 'e='.intval($params['newStatus']).'&'.
  1052. 'u='.intval($params['studentUserId']).'&'.
  1053. 'q='.intval($params['queueId']).'&'.
  1054. 'is_connected=1&'.
  1055. 'profile_completed='.intval($params['profile_completed']).'&'.
  1056. 'v='.$this->generateHash($params);
  1057. return $url;
  1058. }
  1059. /**
  1060. * Return the list of student, in queue used by admin view.
  1061. *
  1062. * @param int $sessionId
  1063. *
  1064. * @return array
  1065. */
  1066. public function listAllStudentsInQueueBySession($sessionId)
  1067. {
  1068. // Filter input variable
  1069. $sessionId = intval($sessionId);
  1070. // Assign variables
  1071. $fieldsArray = [
  1072. 'target',
  1073. 'publication_end_date',
  1074. 'mode',
  1075. 'recommended_number_of_participants',
  1076. 'vacancies',
  1077. ];
  1078. $sessionArray = api_get_session_info($sessionId);
  1079. $extraSession = new ExtraFieldValue('session');
  1080. $extraField = new ExtraField('session');
  1081. // Get session fields
  1082. $fieldList = $extraField->get_all([
  1083. 'variable IN ( ?, ?, ?, ?, ?)' => $fieldsArray,
  1084. ]);
  1085. // Index session fields
  1086. $fields = [];
  1087. foreach ($fieldList as $field) {
  1088. $fields[$field['id']] = $field['variable'];
  1089. }
  1090. $mergedArray = array_merge([$sessionId], array_keys($fields));
  1091. $sessionFieldValueList = $extraSession->get_all(
  1092. [
  1093. 'item_id = ? field_id IN ( ?, ?, ?, ?, ?, ?, ? )' => $mergedArray,
  1094. ]
  1095. );
  1096. foreach ($sessionFieldValueList as $sessionFieldValue) {
  1097. // Check if session field value is set in session field list
  1098. if (isset($fields[$sessionFieldValue['field_id']])) {
  1099. $var = $fields[$sessionFieldValue['field_id']];
  1100. $val = $sessionFieldValue['value'];
  1101. // Assign session field value to session
  1102. $sessionArray[$var] = $val;
  1103. }
  1104. }
  1105. $queueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
  1106. $userTable = Database::get_main_table(TABLE_MAIN_USER);
  1107. $userJoinTable = $queueTable.' q INNER JOIN '.$userTable.' u ON q.user_id = u.user_id';
  1108. $where = [
  1109. 'where' => [
  1110. 'q.session_id = ?' => [
  1111. $sessionId,
  1112. ],
  1113. ],
  1114. 'order' => 'q.status DESC, u.lastname ASC',
  1115. ];
  1116. $select = 'u.user_id, u.firstname, u.lastname, q.created_at, q.updated_at, q.status, q.id as queue_id';
  1117. $students = Database::select($select, $userJoinTable, $where);
  1118. foreach ($students as &$student) {
  1119. $status = intval($student['status']);
  1120. switch ($status) {
  1121. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_NO_QUEUE:
  1122. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_START:
  1123. $student['validation'] = '';
  1124. break;
  1125. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_DISAPPROVED:
  1126. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_DISAPPROVED:
  1127. $student['validation'] = 'No';
  1128. break;
  1129. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_BOSS_APPROVED:
  1130. case ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED:
  1131. $student['validation'] = 'Yes';
  1132. break;
  1133. default:
  1134. error_log(__FILE__.' '.__FUNCTION__.' Student status no detected');
  1135. }
  1136. }
  1137. $return = [
  1138. 'session' => $sessionArray,
  1139. 'students' => $students,
  1140. ];
  1141. return $return;
  1142. }
  1143. /**
  1144. * List all session (id, name) for select input.
  1145. *
  1146. * @param int $limit
  1147. *
  1148. * @return array
  1149. */
  1150. public function listAllSessions($limit = 100)
  1151. {
  1152. $limit = intval($limit);
  1153. $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
  1154. $columns = 'id, name';
  1155. $conditions = [];
  1156. if ($limit > 0) {
  1157. $conditions = [
  1158. 'order' => 'name',
  1159. 'limit' => $limit,
  1160. ];
  1161. }
  1162. return Database::select($columns, $sessionTable, $conditions);
  1163. }
  1164. /**
  1165. * Generate security hash to check data send by url params.
  1166. *
  1167. * @param string $data
  1168. *
  1169. * @return string
  1170. */
  1171. public function generateHash($data)
  1172. {
  1173. $key = sha1($this->get('secret_key'));
  1174. // Prepare array to have specific type variables
  1175. $dataPrepared['action'] = strval($data['action']);
  1176. $dataPrepared['sessionId'] = intval($data['sessionId']);
  1177. $dataPrepared['currentUserId'] = intval($data['currentUserId']);
  1178. $dataPrepared['studentUserId'] = intval($data['studentUserId']);
  1179. $dataPrepared['queueId'] = intval($data['queueId']);
  1180. $dataPrepared['newStatus'] = intval($data['newStatus']);
  1181. $dataPrepared = serialize($dataPrepared);
  1182. return sha1($dataPrepared.$key);
  1183. }
  1184. /**
  1185. * Verify hash from data.
  1186. *
  1187. * @param string $data
  1188. * @param string $hash
  1189. *
  1190. * @return bool
  1191. */
  1192. public function checkHash($data, $hash)
  1193. {
  1194. return $this->generateHash($data) == $hash;
  1195. }
  1196. /**
  1197. * Copied and fixed from plugin.class.php
  1198. * Returns the "system" name of the plugin in lowercase letters.
  1199. *
  1200. * @return string
  1201. */
  1202. public function get_name()
  1203. {
  1204. return 'advanced_subscription';
  1205. }
  1206. /**
  1207. * Return the url to show subscription terms.
  1208. *
  1209. * @param array $params
  1210. * @param int $mode
  1211. *
  1212. * @return string
  1213. */
  1214. public function getTermsUrl($params, $mode = ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP)
  1215. {
  1216. $urlParams = [
  1217. 'a' => Security::remove_XSS($params['action']),
  1218. 's' => intval($params['sessionId']),
  1219. 'current_user_id' => intval($params['currentUserId']),
  1220. 'e' => intval($params['newStatus']),
  1221. 'u' => intval($params['studentUserId']),
  1222. 'q' => intval($params['queueId']),
  1223. 'is_connected' => 1,
  1224. 'profile_completed' => intval($params['profile_completed']),
  1225. 'v' => $this->generateHash($params),
  1226. ];
  1227. switch ($mode) {
  1228. case ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP:
  1229. case ADVANCED_SUBSCRIPTION_TERMS_MODE_FINAL:
  1230. $urlParams['r'] = 0;
  1231. break;
  1232. case ADVANCED_SUBSCRIPTION_TERMS_MODE_REJECT:
  1233. $urlParams['r'] = 1;
  1234. break;
  1235. }
  1236. $url = api_get_path(WEB_PLUGIN_PATH)."advanced_subscription/src/terms_and_conditions.php?";
  1237. $url .= http_build_query($urlParams);
  1238. // Launch popup
  1239. if ($mode == ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP) {
  1240. $url = 'javascript:void(window.open(\''.$url.'\',\'AdvancedSubscriptionTerms\', \'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=700px,height=600px\', \'100\' ))';
  1241. }
  1242. return $url;
  1243. }
  1244. /**
  1245. * Return the url to get mail rendered.
  1246. *
  1247. * @param array $params
  1248. *
  1249. * @return string
  1250. */
  1251. public function getRenderMailUrl($params)
  1252. {
  1253. $url = api_get_path(WEB_PLUGIN_PATH).'advanced_subscription/src/render_mail.php?'.
  1254. 'q='.$params['queueId'].'&'.
  1255. 'v='.$this->generateHash($params);
  1256. return $url;
  1257. }
  1258. /**
  1259. * Return the last message id from queue row.
  1260. *
  1261. * @param int $studentUserId
  1262. * @param int $sessionId
  1263. *
  1264. * @return int|bool
  1265. */
  1266. public function getLastMessageId($studentUserId, $sessionId)
  1267. {
  1268. $studentUserId = intval($studentUserId);
  1269. $sessionId = intval($sessionId);
  1270. if (!empty($sessionId) && !empty($studentUserId)) {
  1271. $row = Database::select(
  1272. 'last_message_id',
  1273. Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE),
  1274. [
  1275. 'where' => [
  1276. 'user_id = ? AND session_id = ?' => [$studentUserId, $sessionId],
  1277. ],
  1278. ]
  1279. );
  1280. if (count($row) > 0) {
  1281. return $row[0]['last_message_id'];
  1282. }
  1283. }
  1284. return false;
  1285. }
  1286. /**
  1287. * Return string replacing tags "{{}}"with variables assigned in $data.
  1288. *
  1289. * @param string $templateContent
  1290. * @param array $data
  1291. *
  1292. * @return string
  1293. */
  1294. public function renderTemplateString($templateContent, $data = [])
  1295. {
  1296. $twigString = new \Twig_Environment(new \Twig_Loader_String());
  1297. $templateContent = $twigString->render(
  1298. $templateContent,
  1299. $data
  1300. );
  1301. return $templateContent;
  1302. }
  1303. /**
  1304. * addAreaField() (adds an area field if it is not already created).
  1305. */
  1306. private function addAreaField()
  1307. {
  1308. $extraField = new ExtraField('user');
  1309. $extraFieldHandler = $extraField->get_handler_field_info_by_field_variable('area');
  1310. $areaExists = $extraFieldHandler !== false;
  1311. if (!$areaExists) {
  1312. $extraField = new ExtraField('user');
  1313. $extraField->save([
  1314. 'field_type' => 1,
  1315. 'variable' => 'area',
  1316. 'display_text' => get_plugin_lang('Area', 'AdvancedSubscriptionPlugin'),
  1317. 'default_value' => null,
  1318. 'field_order' => null,
  1319. 'visible_to_self' => 1,
  1320. 'changeable' => 1,
  1321. 'filter' => null,
  1322. ]);
  1323. }
  1324. }
  1325. /**
  1326. * Create the database tables for the plugin.
  1327. */
  1328. private function installDatabase()
  1329. {
  1330. $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
  1331. $sql = "CREATE TABLE IF NOT EXISTS $advancedSubscriptionQueueTable (".
  1332. "id int UNSIGNED NOT NULL AUTO_INCREMENT, ".
  1333. "session_id int UNSIGNED NOT NULL, ".
  1334. "user_id int UNSIGNED NOT NULL, ".
  1335. "status int UNSIGNED NOT NULL, ".
  1336. "last_message_id int UNSIGNED NOT NULL, ".
  1337. "created_at datetime NOT NULL, ".
  1338. "updated_at datetime NULL, ".
  1339. "PRIMARY KEY PK_advanced_subscription_queue (id), ".
  1340. "UNIQUE KEY UK_advanced_subscription_queue (user_id, session_id)); ";
  1341. Database::query($sql);
  1342. }
  1343. /**
  1344. * Drop the database tables for the plugin.
  1345. */
  1346. private function uninstallDatabase()
  1347. {
  1348. /* Drop plugin tables */
  1349. $advancedSubscriptionQueueTable = Database::get_main_table(TABLE_ADVANCED_SUBSCRIPTION_QUEUE);
  1350. $sql = "DROP TABLE IF EXISTS $advancedSubscriptionQueueTable; ";
  1351. Database::query($sql);
  1352. /* Delete settings */
  1353. $settingsTable = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
  1354. Database::query("DELETE FROM $settingsTable WHERE subkey = 'advanced_subscription'");
  1355. }
  1356. /**
  1357. * Get the count of approved induction sessions by a user.
  1358. *
  1359. * @param int $userId The user id
  1360. *
  1361. * @return int The count of approved sessions
  1362. */
  1363. private function getApprovedInductionSessions($userId)
  1364. {
  1365. $tSession = Database::get_main_table(TABLE_MAIN_SESSION);
  1366. $tSessionField = Database::get_main_table(TABLE_EXTRA_FIELD);
  1367. $tSessionFieldValues = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
  1368. $tSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  1369. $extraFieldType = \Chamilo\CoreBundle\Entity\ExtraField::SESSION_FIELD_TYPE;
  1370. $sql = "SELECT s.id FROM $tSession AS s
  1371. INNER JOIN $tSessionFieldValues AS sfv ON s.id = sfv.item_id
  1372. INNER JOIN $tSessionField AS sf ON sfv.field_id = sf.id
  1373. INNER JOIN $tSessionUser AS su ON s.id = su.session_id
  1374. WHERE
  1375. sf.extra_field_type = $extraFieldType AND
  1376. sf.variable = 'is_induction_session' AND
  1377. su.relation_type = 0 AND
  1378. su.user_id = ".intval($userId);
  1379. $result = Database::query($sql);
  1380. if ($result === false) {
  1381. return 0;
  1382. }
  1383. $numberOfApproved = 0;
  1384. while ($session = Database::fetch_assoc($result)) {
  1385. $numberOfApprovedCourses = 0;
  1386. $courses = SessionManager::get_course_list_by_session_id($session['id']);
  1387. foreach ($courses as $course) {
  1388. $courseCategories = Category::load(
  1389. null,
  1390. null,
  1391. $course['code'],
  1392. null,
  1393. null,
  1394. $session['id'],
  1395. false
  1396. );
  1397. if (count($courseCategories) > 0 &&
  1398. Category::userFinishedCourse($userId, $courseCategories[0])
  1399. ) {
  1400. $numberOfApprovedCourses++;
  1401. }
  1402. }
  1403. if ($numberOfApprovedCourses === count($courses)) {
  1404. $numberOfApproved++;
  1405. }
  1406. }
  1407. return $numberOfApproved;
  1408. }
  1409. }