import_csv.php 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. if (PHP_SAPI !='cli') {
  4. die('Run this script through the command line or comment this line in the code');
  5. }
  6. if (file_exists('multiple_url_fix.php')) {
  7. require 'multiple_url_fix.php';
  8. }
  9. require_once __DIR__.'/../inc/global.inc.php';
  10. require_once api_get_path(LIBRARY_PATH).'log.class.php';
  11. ini_set('memory_limit', -1);
  12. ini_set('max_execution_time', 0);
  13. /**
  14. * Class ImportCsv
  15. */
  16. class ImportCsv
  17. {
  18. private $logger;
  19. private $dumpValues;
  20. public $test;
  21. public $defaultLanguage = 'dutch';
  22. public $extraFieldIdNameList = array(
  23. 'session' => 'external_session_id',
  24. 'course' => 'external_course_id',
  25. 'user' => 'external_user_id',
  26. 'calendar_event' => 'external_calendar_event_id'
  27. );
  28. public $defaultAdminId = 1;
  29. public $defaultSessionVisibility = 1;
  30. /**
  31. * When creating a user the expiration date is set to registration date + this value
  32. * @var int number of years
  33. */
  34. public $expirationDateInUserCreation = 1;
  35. /**
  36. * When updating a user the expiration date is set to update date + this value
  37. * @var int number of years
  38. */
  39. public $expirationDateInUserUpdate = 1;
  40. public $daysCoachAccessBeforeBeginning = 14;
  41. public $daysCoachAccessAfterBeginning = 14;
  42. public $conditions;
  43. /**
  44. * @param Logger $logger
  45. * @param array
  46. */
  47. public function __construct($logger, $conditions)
  48. {
  49. $this->logger = $logger;
  50. $this->conditions = $conditions;
  51. }
  52. /**
  53. * @param bool $dump
  54. */
  55. public function setDumpValues($dump)
  56. {
  57. $this->dumpValues = $dump;
  58. }
  59. /**
  60. * @return mixed
  61. */
  62. public function getDumpValues()
  63. {
  64. return $this->dumpValues;
  65. }
  66. /**
  67. * Runs the import process
  68. */
  69. public function run()
  70. {
  71. global $_configuration;
  72. $value = api_get_configuration_value('import_csv_custom_url_id');
  73. if (!empty($value)) {
  74. $_configuration['access_url'] = $value;
  75. }
  76. $path = api_get_path(SYS_CODE_PATH).'cron/incoming/';
  77. if (!is_dir($path)) {
  78. echo "The folder! $path does not exits";
  79. return 0;
  80. }
  81. if ($this->getDumpValues()) {
  82. $this->dumpDatabaseTables();
  83. }
  84. echo "Reading files: ".PHP_EOL.PHP_EOL;
  85. $files = scandir($path);
  86. $fileToProcess = array();
  87. $fileToProcessStatic = array();
  88. $teacherBackup = array();
  89. $groupBackup = array();
  90. if (!empty($files)) {
  91. foreach ($files as $file) {
  92. $fileInfo = pathinfo($file);
  93. if ($fileInfo['extension'] == 'csv') {
  94. // Checking teachers_yyyymmdd.csv, courses_yyyymmdd.csv, students_yyyymmdd.csv and sessions_yyyymmdd.csv
  95. $parts = explode('_', $fileInfo['filename']);
  96. $preMethod = ucwords($parts[1]);
  97. $preMethod = str_replace('-static', 'Static', $preMethod);
  98. $method = 'import'.$preMethod;
  99. $isStatic = strpos($method, 'Static');
  100. if ($method == 'importSessionsextidStatic') {
  101. $method = 'importSessionsExtIdStatic';
  102. }
  103. if ($method == 'importCourseinsertStatic') {
  104. $method = 'importSubscribeUserToCourse';
  105. }
  106. if ($method == 'importUnsubsessionsextidStatic') {
  107. $method = 'importUnsubsessionsExtidStatic';
  108. }
  109. if ($method == 'importSubsessionsextidStatic') {
  110. $method = 'importSubscribeUserToCourseSessionExtStatic';
  111. }
  112. if (method_exists($this, $method)) {
  113. if (
  114. (
  115. $method == 'importSubscribeStatic' ||
  116. $method == 'importSubscribeUserToCourse'
  117. ) ||
  118. empty($isStatic)
  119. ) {
  120. $fileToProcess[$parts[1]][] = array(
  121. 'method' => $method,
  122. 'file' => $path.$fileInfo['basename']
  123. );
  124. } else {
  125. $fileToProcessStatic[$parts[1]][] = array(
  126. 'method' => $method,
  127. 'file' => $path.$fileInfo['basename']
  128. );
  129. }
  130. } else {
  131. echo "Error - This file '$file' can't be processed.".PHP_EOL;
  132. echo "Trying to call $method".PHP_EOL;
  133. echo "The file have to has this format:".PHP_EOL;
  134. echo "prefix_students_ddmmyyyy.csv, prefix_teachers_ddmmyyyy.csv, prefix_courses_ddmmyyyy.csv, prefix_sessions_ddmmyyyy.csv ".PHP_EOL;
  135. exit;
  136. }
  137. }
  138. }
  139. if (empty($fileToProcess) && empty($fileToProcessStatic)) {
  140. echo 'Error - no files to process.';
  141. return 0;
  142. }
  143. $this->prepareImport();
  144. $sections = array(
  145. 'students',
  146. 'teachers',
  147. 'courses',
  148. 'sessions',
  149. 'subscribe-static',
  150. 'courseinsert-static'
  151. );
  152. foreach ($sections as $section) {
  153. $this->logger->addInfo("-- Import $section --");
  154. if (isset($fileToProcess[$section]) && !empty($fileToProcess[$section])) {
  155. $files = $fileToProcess[$section];
  156. foreach ($files as $fileInfo) {
  157. $method = $fileInfo['method'];
  158. $file = $fileInfo['file'];
  159. echo 'File: '.$file.PHP_EOL;
  160. $this->logger->addInfo("Reading file: $file");
  161. if ($method == 'importSessions') {
  162. $this->$method($file, true, $teacherBackup, $groupBackup);
  163. } else {
  164. $this->$method($file, true);
  165. }
  166. }
  167. }
  168. }
  169. $sections = array(
  170. 'students-static',
  171. 'teachers-static',
  172. 'courses-static',
  173. 'sessions-static',
  174. 'calendar-static',
  175. 'sessionsextid-static',
  176. 'unsubscribe-static',
  177. 'unsubsessionsextid-static',
  178. 'subsessionsextid-static'
  179. );
  180. foreach ($sections as $section) {
  181. $this->logger->addInfo("-- Import static files $section --");
  182. if (isset($fileToProcessStatic[$section]) &&
  183. !empty($fileToProcessStatic[$section])
  184. ) {
  185. $files = $fileToProcessStatic[$section];
  186. foreach ($files as $fileInfo) {
  187. $method = $fileInfo['method'];
  188. $file = $fileInfo['file'];
  189. echo 'Static file: '.$file.PHP_EOL;
  190. $this->logger->addInfo("Reading static file: $file");
  191. $this->$method($file, true, $teacherBackup, $groupBackup);
  192. }
  193. }
  194. }
  195. }
  196. }
  197. /**
  198. * Prepares extra fields before the import
  199. */
  200. private function prepareImport()
  201. {
  202. // Create user extra field: extra_external_user_id
  203. UserManager::create_extra_field(
  204. $this->extraFieldIdNameList['user'],
  205. 1,
  206. 'External user id',
  207. null
  208. );
  209. // Create course extra field: extra_external_course_id
  210. CourseManager::create_course_extra_field(
  211. $this->extraFieldIdNameList['course'],
  212. 1,
  213. 'External course id'
  214. );
  215. // Create session extra field extra_external_session_id
  216. SessionManager::create_session_extra_field(
  217. $this->extraFieldIdNameList['session'],
  218. 1,
  219. 'External session id'
  220. );
  221. // Create calendar_event extra field extra_external_session_id
  222. $extraField = new ExtraField('calendar_event');
  223. $extraField->save(array(
  224. 'field_type' => ExtraField::FIELD_TYPE_TEXT,
  225. 'field_variable' => $this->extraFieldIdNameList['calendar_event'],
  226. 'field_display_text' => 'External calendar event id'
  227. ));
  228. }
  229. /**
  230. * @param string $file
  231. */
  232. private function moveFile($file)
  233. {
  234. $moved = str_replace('incoming', 'treated', $file);
  235. if ($this->test) {
  236. $result = 1;
  237. } else {
  238. $result = rename($file, $moved);
  239. }
  240. if ($result) {
  241. $this->logger->addInfo("Moving file to the treated folder: $file");
  242. } else {
  243. $this->logger->addError("Error - Cant move file to the treated folder: $file");
  244. }
  245. }
  246. /**
  247. * @param array $row
  248. *
  249. * @return array
  250. */
  251. private function cleanUserRow($row)
  252. {
  253. $row['lastname'] = $row['LastName'];
  254. $row['firstname'] = $row['FirstName'];
  255. $row['email'] = $row['Email'];
  256. $row['username'] = $row['UserName'];
  257. $row['password'] = $row['Password'];
  258. $row['auth_source'] = isset($row['AuthSource']) ? $row['AuthSource'] : PLATFORM_AUTH_SOURCE;
  259. $row['official_code'] = $row['OfficialCode'];
  260. $row['phone'] = $row['PhoneNumber'];
  261. if (isset($row['StudentID'])) {
  262. $row['extra_'.$this->extraFieldIdNameList['user']] = $row['StudentID'];
  263. }
  264. if (isset($row['TeacherID'])) {
  265. $row['extra_'.$this->extraFieldIdNameList['user']] = $row['TeacherID'];
  266. }
  267. return $row;
  268. }
  269. /**
  270. * @param array $row
  271. *
  272. * @return array
  273. */
  274. private function cleanCourseRow($row)
  275. {
  276. $row['title'] = $row['Title'];
  277. $row['course_code'] = $row['Code'];
  278. $row['course_category'] = $row['CourseCategory'];
  279. $row['email'] = $row['Teacher'];
  280. $row['language'] = $row['Language'];
  281. $row['teachers'] = array();
  282. if (isset($row['Teacher']) && !empty($row['Teacher'])) {
  283. $teachers = explode(',', $row['Teacher']);
  284. if (!empty($teachers)) {
  285. foreach ($teachers as $teacherUserName) {
  286. $teacherUserName = trim($teacherUserName);
  287. $userInfo = api_get_user_info_from_username($teacherUserName);
  288. if (!empty($userInfo)) {
  289. $row['teachers'][] = $userInfo['user_id'];
  290. }
  291. }
  292. }
  293. }
  294. if (isset($row['CourseID'])) {
  295. $row['extra_'.$this->extraFieldIdNameList['course']] = $row['CourseID'];
  296. }
  297. return $row;
  298. }
  299. /**
  300. * File to import
  301. * @param string $file
  302. */
  303. private function importTeachersStatic($file)
  304. {
  305. $this->importTeachers($file, false);
  306. }
  307. /**
  308. * File to import
  309. * @param string $file
  310. * @param bool $moveFile
  311. */
  312. private function importTeachers($file, $moveFile = true)
  313. {
  314. $data = Import::csv_to_array($file);
  315. /* Unique identifier: official-code username.
  316. Email address and password should never get updated. *ok
  317. The only fields that I can think of that should update if the data changes in the csv file are FirstName and LastName. *ok
  318. A slight edit of these fields should be taken into account. ???
  319. Adding teachers is no problem, but deleting them shouldn’t be automated, but we should get a log of “to delete teachers”.
  320. We’ll handle that manually if applicable.
  321. No delete!
  322. */
  323. $language = $this->defaultLanguage;
  324. if (!empty($data)) {
  325. $this->logger->addInfo(count($data)." records found.");
  326. foreach ($data as $row) {
  327. $row = $this->cleanUserRow($row);
  328. $user_id = UserManager::get_user_id_from_original_id(
  329. $row['extra_' . $this->extraFieldIdNameList['user']],
  330. $this->extraFieldIdNameList['user']
  331. );
  332. $userInfo = array();
  333. $userInfoByOfficialCode = null;
  334. if (!empty($user_id)) {
  335. $userInfo = api_get_user_info($user_id);
  336. $userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
  337. }
  338. $expirationDate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserCreation)."years"));
  339. if (empty($userInfo) && empty($userInfoByOfficialCode)) {
  340. // Create user
  341. $userId = UserManager::create_user(
  342. $row['firstname'],
  343. $row['lastname'],
  344. COURSEMANAGER,
  345. $row['email'],
  346. $row['username'],
  347. $row['password'],
  348. $row['official_code'],
  349. $language, //$row['language'],
  350. $row['phone'],
  351. null, //$row['picture'], //picture
  352. $row['auth_source'], // ?
  353. $expirationDate, //'0000-00-00 00:00:00', //$row['expiration_date'], //$expiration_date = '0000-00-00 00:00:00',
  354. 1, //active
  355. 0,
  356. null, // extra
  357. null, //$encrypt_method = '',
  358. false //$send_mail = false
  359. );
  360. if ($userId) {
  361. foreach ($row as $key => $value) {
  362. if (substr($key, 0, 6) == 'extra_') {
  363. //an extra field
  364. UserManager::update_extra_field_value($userId, substr($key, 6), $value);
  365. }
  366. }
  367. $this->logger->addInfo("Teachers - User created: ".$row['username']);
  368. } else {
  369. $this->logger->addError("Teachers - User NOT created: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
  370. }
  371. } else {
  372. if (empty($userInfo)) {
  373. $this->logger->addError("Teachers - Can't update user :".$row['username']);
  374. continue;
  375. }
  376. $expirationDate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserUpdate)."years"));
  377. // Update user
  378. $result = UserManager::update_user(
  379. $userInfo['user_id'],
  380. $row['firstname'], // <<-- changed
  381. $row['lastname'], // <<-- changed
  382. $userInfo['username'],
  383. null, //$password = null,
  384. $row['auth_source'],
  385. $userInfo['email'],
  386. COURSEMANAGER,
  387. $userInfo['official_code'],
  388. $userInfo['phone'],
  389. $userInfo['picture_uri'],
  390. $expirationDate,
  391. $userInfo['active'],
  392. null, //$creator_id = null,
  393. 0, //$hr_dept_id = 0,
  394. null, // $extra = null,
  395. null, //$language = 'english',
  396. null, //$encrypt_method = '',
  397. false, //$send_email = false,
  398. 0 //$reset_password = 0
  399. );
  400. if ($result) {
  401. foreach ($row as $key => $value) {
  402. if (substr($key, 0, 6) == 'extra_') {
  403. //an extra field
  404. UserManager::update_extra_field_value(
  405. $userInfo['user_id'],
  406. substr($key, 6),
  407. $value
  408. );
  409. }
  410. }
  411. $this->logger->addInfo("Teachers - User updated: ".$row['username']);
  412. } else {
  413. $this->logger->addError("Teachers - User not updated: ".$row['username']);
  414. }
  415. }
  416. }
  417. }
  418. if ($moveFile) {
  419. $this->moveFile($file);
  420. }
  421. }
  422. /**
  423. * @param string $file
  424. */
  425. private function importStudentsStatic($file)
  426. {
  427. $this->importStudents($file, false);
  428. }
  429. /**
  430. * @param string $file
  431. * @param bool $moveFile
  432. */
  433. private function importStudents($file, $moveFile = true)
  434. {
  435. $data = Import::csv_to_array($file);
  436. /*
  437. * Another users import.
  438. Unique identifier: official code and username . ok
  439. Password should never get updated. ok
  440. If an update should need to occur (because it changed in the .csv),
  441. we’ll want that logged. We will handle this manually in that case.
  442. All other fields should be updateable, though passwords should of course not get updated. ok
  443. If a user gets deleted (not there anymore),
  444. He should be set inactive one year after the current date.
  445. So I presume you’ll just update the expiration date.
  446. We want to grant access to courses up to a year after deletion.
  447. */
  448. if (!empty($data)) {
  449. $language = $this->defaultLanguage;
  450. $this->logger->addInfo(count($data)." records found.");
  451. foreach ($data as $row) {
  452. $row = $this->cleanUserRow($row);
  453. $user_id = UserManager::get_user_id_from_original_id(
  454. $row['extra_'.$this->extraFieldIdNameList['user']],
  455. $this->extraFieldIdNameList['user']
  456. );
  457. $userInfo = array();
  458. $userInfoByOfficialCode = null;
  459. if (!empty($user_id)) {
  460. $userInfo = api_get_user_info($user_id);
  461. $userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
  462. }
  463. $expirationDate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserCreation)."years"));
  464. if (empty($userInfo) && empty($userInfoByOfficialCode)) {
  465. // Create user
  466. $result = UserManager::create_user(
  467. $row['firstname'],
  468. $row['lastname'],
  469. STUDENT,
  470. $row['email'],
  471. $row['username'],
  472. $row['password'],
  473. $row['official_code'],
  474. $language, //$row['language'],
  475. $row['phone'],
  476. null, //$row['picture'], //picture
  477. $row['auth_source'], // ?
  478. $expirationDate, //'0000-00-00 00:00:00', //$row['expiration_date'], //$expiration_date = '0000-00-00 00:00:00',
  479. 1, //active
  480. 0,
  481. null, // extra
  482. null, //$encrypt_method = '',
  483. false //$send_mail = false
  484. );
  485. if ($result) {
  486. foreach ($row as $key => $value) {
  487. if (substr($key, 0, 6) == 'extra_') {
  488. //an extra field
  489. UserManager::update_extra_field_value($result, substr($key, 6), $value);
  490. }
  491. }
  492. $this->logger->addInfo("Students - User created: ".$row['username']);
  493. } else {
  494. $this->logger->addError("Students - User NOT created: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
  495. }
  496. } else {
  497. if (empty($userInfo)) {
  498. $this->logger->addError("Students - Can't update user :".$row['username']);
  499. continue;
  500. }
  501. if ($row['action'] == 'delete') {
  502. // Inactive one year later
  503. $userInfo['expiration_date'] = api_get_utc_datetime(api_strtotime(time() + 365*24*60*60));
  504. }
  505. $password = $row['password']; // change password
  506. $email = $row['email']; // change email
  507. $resetPassword = 2; // allow password change
  508. // Conditions that disables the update of password and email:
  509. if (isset($this->conditions['importStudents'])) {
  510. if (isset($this->conditions['importStudents']['update']) &&
  511. isset($this->conditions['importStudents']['update']['avoid'])
  512. ) {
  513. // Blocking email update -
  514. // 1. Condition
  515. $avoidUsersWithEmail = $this->conditions['importStudents']['update']['avoid']['email'];
  516. if ($userInfo['email'] != $row['email'] && in_array($row['email'], $avoidUsersWithEmail)) {
  517. $this->logger->addInfo("Students - User email is not updated : ".$row['username']." because the avoid conditions (email).");
  518. // Do not change email keep the old email.
  519. $email = $userInfo['email'];
  520. }
  521. // 2. Condition
  522. if (!in_array($userInfo['email'], $avoidUsersWithEmail) && !in_array($row['email'], $avoidUsersWithEmail)) {
  523. $email = $userInfo['email'];
  524. }
  525. // 3. Condition
  526. if (in_array($userInfo['email'], $avoidUsersWithEmail) && !in_array($row['email'], $avoidUsersWithEmail)) {
  527. $email = $row['email'];
  528. }
  529. // Blocking password update
  530. $avoidUsersWithPassword = $this->conditions['importStudents']['update']['avoid']['password'];
  531. if ($userInfo['password'] != api_get_encrypted_password($row['password']) && in_array($row['password'], $avoidUsersWithPassword)) {
  532. $this->logger->addInfo("Students - User password is not updated: ".$row['username']." because the avoid conditions (password).");
  533. $password = null;
  534. $resetPassword = 0; // disallow password change
  535. }
  536. }
  537. }
  538. $expirationDate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserUpdate)."years"));
  539. // Update user
  540. $result = UserManager::update_user(
  541. $userInfo['user_id'],
  542. $row['firstname'], // <<-- changed
  543. $row['lastname'], // <<-- changed
  544. $row['username'], // <<-- changed
  545. $password, //$password = null,
  546. $row['auth_source'],
  547. $email,
  548. STUDENT,
  549. $userInfo['official_code'],
  550. $userInfo['phone'],
  551. $userInfo['picture_uri'],
  552. $expirationDate,
  553. $userInfo['active'],
  554. null, //$creator_id = null,
  555. 0, //$hr_dept_id = 0,
  556. null, // $extra = null,
  557. null, //$language = 'english',
  558. null, //$encrypt_method = '',
  559. false, //$send_email = false,
  560. $resetPassword //$reset_password = 0
  561. );
  562. if ($result) {
  563. if ($row['username'] != $userInfo['username']) {
  564. $this->logger->addInfo("Students - Username was changes from '".$userInfo['username']."' to '".$row['username']."' ");
  565. }
  566. foreach ($row as $key => $value) {
  567. if (substr($key, 0, 6) == 'extra_') {
  568. //an extra field
  569. UserManager::update_extra_field_value(
  570. $userInfo['user_id'],
  571. substr($key, 6),
  572. $value
  573. );
  574. }
  575. }
  576. $this->logger->addInfo("Students - User updated: ".$row['username']);
  577. } else {
  578. $this->logger->addError("Students - User NOT updated: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
  579. }
  580. }
  581. }
  582. }
  583. if ($moveFile) {
  584. $this->moveFile($file);
  585. }
  586. }
  587. /**
  588. * @param string $file
  589. */
  590. private function importCoursesStatic($file, $moveFile, &$teacherBackup = array(), &$groupBackup = array())
  591. {
  592. $this->importCourses($file, false, $teacherBackup, $groupBackup);
  593. }
  594. /**
  595. * @param string $file
  596. * @param bool $moveFile
  597. *
  598. * @return int
  599. */
  600. private function importCalendarStatic($file, $moveFile = true)
  601. {
  602. $data = Import::csv_to_array($file);
  603. if (!empty($data)) {
  604. $this->logger->addInfo(count($data) . " records found.");
  605. $eventsToCreate = array();
  606. $errorFound = false;
  607. foreach ($data as $row) {
  608. $sessionId = null;
  609. $externalSessionId = null;
  610. if (isset($row['external_sessionID'])) {
  611. $externalSessionId = $row['external_sessionID'];
  612. $sessionId = SessionManager::get_session_id_from_original_id(
  613. $externalSessionId,
  614. $this->extraFieldIdNameList['session']
  615. );
  616. }
  617. $courseCode = null;
  618. if (isset($row['coursecode'])) {
  619. $courseCode = $row['coursecode'];
  620. }
  621. $courseInfo = api_get_course_info($courseCode);
  622. if (empty($courseInfo)) {
  623. $this->logger->addInfo("Course '$courseCode' does not exists");
  624. }
  625. if (empty($sessionId)) {
  626. $this->logger->addInfo("external_sessionID: ".$externalSessionId." does not exists.");
  627. }
  628. $teacherId = null;
  629. if (!empty($sessionId) && !empty($courseInfo)) {
  630. $courseIncluded = SessionManager::relation_session_course_exist(
  631. $sessionId,
  632. $courseInfo['code']
  633. );
  634. if ($courseIncluded == false) {
  635. $this->logger->addInfo(
  636. "Course '$courseCode' is not included in session: $sessionId"
  637. );
  638. $errorFound = true;
  639. } else {
  640. $teachers = CourseManager::get_coach_list_from_course_code(
  641. $courseInfo['code'],
  642. $sessionId
  643. );
  644. // Getting first teacher.
  645. if (!empty($teachers)) {
  646. $teacher = current($teachers);
  647. $teacherId = $teacher['user_id'];
  648. } else {
  649. $sessionInfo = api_get_session_info($sessionId);
  650. $teacherId = $sessionInfo['id_coach'];
  651. }
  652. }
  653. } else {
  654. $errorFound = true;
  655. }
  656. if (empty($teacherId)) {
  657. $errorFound = true;
  658. $this->logger->addInfo(
  659. "No teacher found in course code : '$courseCode' and session: '$sessionId'"
  660. );
  661. }
  662. $date = $row['date'];
  663. $startTime = $row['time_start'];
  664. $endTime = $row['time_end'];
  665. $title = $row['title'];
  666. $comment = $row['comment'];
  667. $color = isset($row['color']) ? $row['color'] : '';
  668. $startDateYear = substr($date, 0, 4);
  669. $startDateMonth = substr($date, 4, 2);
  670. $startDateDay = substr($date, 6, 8);
  671. $startDate = $startDateYear.'-'.$startDateMonth.'-'.$startDateDay.' '.$startTime.":00";
  672. $endDate = $startDateYear.'-'.$startDateMonth.'-'.$startDateDay.' '.$endTime.":00";
  673. if (!api_is_valid_date($startDate) || !api_is_valid_date($endDate)) {
  674. $this->logger->addInfo(
  675. "Verify your dates: '$startDate' : '$endDate' "
  676. );
  677. $errorFound = true;
  678. }
  679. // If old events do nothing.
  680. /*if (api_strtotime($startDate) < time()) {
  681. continue;
  682. }*/
  683. if ($errorFound == false) {
  684. $eventsToCreate[] = array(
  685. 'start' => $startDate,
  686. 'end' => $endDate,
  687. 'title' => $title,
  688. 'sender_id' => $teacherId,
  689. 'course_id' => $courseInfo['real_id'],
  690. 'session_id' => $sessionId,
  691. 'comment' => $comment,
  692. 'color' => $color,
  693. $this->extraFieldIdNameList['calendar_event'] => $row['external_calendar_itemID']
  694. );
  695. }
  696. $errorFound = false;
  697. }
  698. if (empty($eventsToCreate)) {
  699. $this->logger->addInfo(
  700. "No events to add"
  701. );
  702. return 0;
  703. }
  704. $this->logger->addInfo(
  705. "Ready to insert events"
  706. );
  707. $agenda = new Agenda();
  708. $extraFieldValue = new ExtraFieldValue('calendar_event');
  709. $extraFieldName = $this->extraFieldIdNameList['calendar_event'];
  710. $externalEventId = null;
  711. $extraField = new ExtraField('calendar_event');
  712. $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable($extraFieldName);
  713. if (empty($extraFieldInfo)) {
  714. $this->logger->addInfo(
  715. "No calendar event extra field created: $extraFieldName"
  716. );
  717. return 0;
  718. }
  719. foreach ($eventsToCreate as $event) {
  720. $update = false;
  721. $item = null;
  722. if (!isset($event[$extraFieldName])) {
  723. $this->logger->addInfo(
  724. "No external_calendar_itemID found. Skipping ..."
  725. );
  726. continue;
  727. } else {
  728. $externalEventId = $event[$extraFieldName];
  729. if (empty($externalEventId)) {
  730. $this->logger->addInfo(
  731. "external_calendar_itemID was set but empty. Skipping ..."
  732. );
  733. continue;
  734. }
  735. $items = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
  736. $extraFieldName,
  737. $externalEventId,
  738. false,
  739. false,
  740. true
  741. );
  742. $item = null;
  743. foreach ($items as $tempItem) {
  744. if ($tempItem['c_id'] == $event['course_id']) {
  745. $item = $tempItem;
  746. }
  747. }
  748. if (!empty($item)) {
  749. $this->logger->addInfo(
  750. "Event #$externalEventId was already added. Updating ..."
  751. );
  752. $update = true;
  753. //continue;
  754. }
  755. }
  756. $courseInfo = api_get_course_info_by_id($event['course_id']);
  757. $agenda->set_course($courseInfo);
  758. $agenda->setType('course');
  759. $agenda->setSessionId($event['session_id']);
  760. $agenda->setSenderId($event['sender_id']);
  761. $agenda->setIsAllowedToEdit(true);
  762. $eventComment = $event['comment'];
  763. $color = $event['color'];
  764. // To use the event comment you need
  765. // ALTER TABLE c_calendar_event ADD COLUMN comment TEXT;
  766. // add in configuration.php allow_agenda_event_comment = true
  767. if (empty($courseInfo)) {
  768. $this->logger->addInfo(
  769. "No course found for added: #".$event['course_id']." Skipping ..."
  770. );
  771. continue;
  772. }
  773. if (empty($event['sender_id'])) {
  774. $this->logger->addInfo(
  775. "No sender found: #".$event['sender_id']." Skipping ..."
  776. );
  777. continue;
  778. }
  779. $content = '';
  780. if ($update && isset($item['calendar_event_id'])) {
  781. //the event already exists, just update
  782. $eventId = $agenda->edit_event(
  783. $item['calendar_event_id'],
  784. $event['start'],
  785. $event['end'],
  786. false,
  787. $event['title'],
  788. $content,
  789. array('everyone'), // send to
  790. array(), //$attachmentArray = array(),
  791. null, //$attachmentComment = null,
  792. $eventComment,
  793. $color
  794. );
  795. if ($eventId !== false) {
  796. $this->logger->addInfo(
  797. "Event updated: #$eventId"
  798. );
  799. } else {
  800. $this->logger->addInfo(
  801. "Error while updating event."
  802. );
  803. }
  804. } else {
  805. // New event. Create it.
  806. $eventId = $agenda->add_event(
  807. $event['start'],
  808. $event['end'],
  809. false,
  810. $event['title'],
  811. $content,
  812. array('everyone'), // send to
  813. false, //$addAsAnnouncement = false
  814. null, // $parentEventId
  815. array(), //$attachmentArray = array(),
  816. null, //$attachmentComment = null,
  817. $eventComment,
  818. $color
  819. );
  820. if (!empty($eventId)) {
  821. $extraFieldValue->is_course_model = true;
  822. $extraFieldValue->save(
  823. array(
  824. 'field_value' => $externalEventId,
  825. 'field_id' => $extraFieldInfo['id'],
  826. 'calendar_event_id' => $eventId,
  827. 'c_id' => $event['course_id']
  828. )
  829. );
  830. $this->logger->addInfo(
  831. "Event added: #$eventId"
  832. );
  833. } else {
  834. $this->logger->addInfo(
  835. "Error while creating event."
  836. );
  837. }
  838. }
  839. }
  840. }
  841. if ($moveFile) {
  842. $this->moveFile($file);
  843. }
  844. }
  845. /**
  846. * @param string $file
  847. * @param bool $moveFile
  848. * @param array $teacherBackup
  849. * @param array $groupBackup
  850. */
  851. private function importCourses($file, $moveFile = true, &$teacherBackup = array(), &$groupBackup = array())
  852. {
  853. $data = Import::csv_to_array($file);
  854. if (!empty($data)) {
  855. $this->logger->addInfo(count($data)." records found.");
  856. foreach ($data as $row) {
  857. $row = $this->cleanCourseRow($row);
  858. $courseCode = CourseManager::get_course_id_from_original_id(
  859. $row['extra_' . $this->extraFieldIdNameList['course']],
  860. $this->extraFieldIdNameList['course']
  861. );
  862. $courseInfo = api_get_course_info($courseCode);
  863. if (empty($courseInfo)) {
  864. // Create
  865. $params = array();
  866. $params['title'] = $row['title'];
  867. $params['exemplary_content'] = false;
  868. $params['wanted_code'] = $row['course_code'];
  869. $params['course_category'] = $row['course_category'];
  870. $params['course_language'] = $row['language'];
  871. $params['teachers'] = $row['teachers'];
  872. $courseInfo = CourseManager::create_course($params);
  873. if (!empty($courseInfo)) {
  874. CourseManager::update_course_extra_field_value(
  875. $courseInfo['code'],
  876. 'external_course_id',
  877. $row['extra_'.$this->extraFieldIdNameList['course']]
  878. );
  879. $this->logger->addInfo("Courses - Course created ".$courseInfo['code']);
  880. } else {
  881. $this->logger->addError("Courses - Can't create course:".$row['title']);
  882. }
  883. } else {
  884. // Update
  885. $params = array(
  886. 'title' => $row['title'],
  887. 'category_code' => $row['course_category']
  888. );
  889. $result = CourseManager::update_attributes(
  890. $courseInfo['real_id'],
  891. $params
  892. );
  893. $addTeacherToSession = isset($courseInfo['add_teachers_to_sessions_courses']) && !empty($courseInfo['add_teachers_to_sessions_courses']) ? true : false;
  894. $teachers = $row['teachers'];
  895. if (!is_array($teachers)) {
  896. $teachers = array($teachers);
  897. }
  898. if ($addTeacherToSession) {
  899. CourseManager::updateTeachers(
  900. $courseInfo['code'],
  901. $row['teachers'],
  902. false,
  903. true,
  904. false,
  905. $teacherBackup
  906. );
  907. } else {
  908. CourseManager::updateTeachers(
  909. $courseInfo['code'],
  910. $row['teachers'],
  911. true,
  912. false,
  913. false,
  914. $teacherBackup
  915. );
  916. }
  917. foreach ($teachers as $teacherId) {
  918. if (isset($groupBackup['tutor'][$teacherId]) &&
  919. isset($groupBackup['tutor'][$teacherId][$courseInfo['code']])
  920. ) {
  921. foreach ($groupBackup['tutor'][$teacherId][$courseInfo['code']] as $data) {
  922. GroupManager::subscribe_tutors(
  923. array($teacherId),
  924. $data['group_id'],
  925. $data['c_id']
  926. );
  927. }
  928. }
  929. if (isset($groupBackup['user'][$teacherId]) &&
  930. isset($groupBackup['user'][$teacherId][$courseInfo['code']]) &&
  931. !empty($groupBackup['user'][$teacherId][$courseInfo['code']])
  932. ) {
  933. foreach ($groupBackup['user'][$teacherId][$courseInfo['code']] as $data) {
  934. GroupManager::subscribe_users(
  935. array($teacherId),
  936. $data['group_id'],
  937. $data['c_id']
  938. );
  939. }
  940. }
  941. }
  942. if ($result) {
  943. $this->logger->addInfo("Courses - Course updated ".$courseInfo['code']);
  944. } else {
  945. $this->logger->addError("Courses - Course NOT updated ".$courseInfo['code']);
  946. }
  947. }
  948. }
  949. }
  950. if ($moveFile) {
  951. $this->moveFile($file);
  952. }
  953. }
  954. /**
  955. * Parse filename: encora_subsessionsextid-static_31082016.csv
  956. * @param string $file
  957. */
  958. private function importSubscribeUserToCourseSessionExtStatic($file)
  959. {
  960. $data = Import::csv_reader($file);
  961. if (!empty($data)) {
  962. $this->logger->addInfo(count($data) . " records found.");
  963. foreach ($data as $row) {
  964. $chamiloUserName = $row['UserName'];
  965. $chamiloCourseCode = $row['CourseCode'];
  966. $externalSessionId = $row['ExtSessionID'];
  967. $status = $row['Status'];
  968. $chamiloSessionId = null;
  969. if (!empty($externalSessionId)) {
  970. $chamiloSessionId = SessionManager::get_session_id_from_original_id(
  971. $externalSessionId,
  972. $this->extraFieldIdNameList['session']
  973. );
  974. }
  975. $sessionInfo = api_get_session_info($chamiloSessionId);
  976. if (empty($sessionInfo)) {
  977. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  978. continue;
  979. }
  980. $courseInfo = api_get_course_info($chamiloCourseCode);
  981. if (empty($courseInfo)) {
  982. $this->logger->addError('Course does not exists: '.$courseInfo);
  983. continue;
  984. }
  985. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  986. if (empty($userId)) {
  987. $this->logger->addError('User does not exists: '.$chamiloUserName);
  988. continue;
  989. }
  990. switch ($status) {
  991. case 'student':
  992. SessionManager::subscribe_users_to_session_course(
  993. array($userId),
  994. $chamiloSessionId,
  995. $courseInfo['code']
  996. );
  997. break;
  998. case 'teacher':
  999. SessionManager::set_coach_to_course_session(
  1000. $userId,
  1001. $chamiloSessionId,
  1002. $courseInfo['code']
  1003. );
  1004. break;
  1005. case 'drh':
  1006. $userInfo = api_get_user_info($userId);
  1007. SessionManager::suscribe_sessions_to_hr_manager(
  1008. $userInfo,
  1009. [$chamiloSessionId],
  1010. false,
  1011. false
  1012. );
  1013. break;
  1014. }
  1015. $this->logger->addError(
  1016. "User '$chamiloUserName' was added as '$status' to Session: #$chamiloSessionId - Course: " . $courseInfo['code']
  1017. );
  1018. }
  1019. }
  1020. }
  1021. /**
  1022. * @param string $file
  1023. */
  1024. private function importUnsubSessionsExtIdStatic($file)
  1025. {
  1026. $data = Import::csv_reader($file);
  1027. if (!empty($data)) {
  1028. $this->logger->addInfo(count($data) . " records found.");
  1029. foreach ($data as $row) {
  1030. $chamiloUserName = $row['UserName'];
  1031. $chamiloCourseCode = $row['CourseCode'];
  1032. $externalSessionId = $row['ExtSessionID'];
  1033. $dateStop = $row['DateStop'];
  1034. $chamiloSessionId = null;
  1035. if (!empty($externalSessionId)) {
  1036. $chamiloSessionId = SessionManager::get_session_id_from_original_id(
  1037. $externalSessionId,
  1038. $this->extraFieldIdNameList['session']
  1039. );
  1040. }
  1041. $sessionInfo = api_get_session_info($chamiloSessionId);
  1042. if (empty($sessionInfo)) {
  1043. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1044. continue;
  1045. }
  1046. $courseInfo = api_get_course_info($chamiloCourseCode);
  1047. if (empty($courseInfo)) {
  1048. $this->logger->addError('Course does not exists: '.$courseInfo);
  1049. continue;
  1050. }
  1051. $userId = Usermanager::get_user_id_from_username($chamiloUserName);
  1052. if (empty($userId)) {
  1053. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1054. continue;
  1055. }
  1056. SessionManager::removeUsersFromCourseSession(
  1057. array($userId),
  1058. $chamiloSessionId,
  1059. $courseInfo
  1060. );
  1061. $this->logger->addError(
  1062. "User '$chamiloUserName' was remove from Session: #$chamiloSessionId - Course: " . $courseInfo['code']
  1063. );
  1064. }
  1065. }
  1066. }
  1067. /**
  1068. *
  1069. * @param string $file
  1070. */
  1071. private function importSessionsExtIdStatic($file)
  1072. {
  1073. $data = Import::csv_reader($file);
  1074. if (!empty($data)) {
  1075. $this->logger->addInfo(count($data) . " records found.");
  1076. foreach ($data as $row) {
  1077. $chamiloUserName = $row['UserName'];
  1078. $chamiloCourseCode = $row['CourseCode'];
  1079. $externalSessionId = $row['ExtSessionID'];
  1080. $type = $row['Type'];
  1081. $chamiloSessionId = null;
  1082. if (!empty($externalSessionId)) {
  1083. $chamiloSessionId = SessionManager::get_session_id_from_original_id(
  1084. $externalSessionId,
  1085. $this->extraFieldIdNameList['session']
  1086. );
  1087. }
  1088. $sessionInfo = api_get_session_info($chamiloSessionId);
  1089. if (empty($sessionInfo)) {
  1090. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1091. continue;
  1092. }
  1093. $courseInfo = api_get_course_info($chamiloCourseCode);
  1094. if (empty($courseInfo)) {
  1095. $this->logger->addError('Course does not exists: '.$courseInfo);
  1096. continue;
  1097. }
  1098. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  1099. if (empty($userId)) {
  1100. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1101. continue;
  1102. }
  1103. $status = null;
  1104. switch ($type) {
  1105. case 'student':
  1106. SessionManager::subscribe_users_to_session_course(
  1107. array($userId),
  1108. $chamiloSessionId,
  1109. $courseInfo['code'],
  1110. null,
  1111. false
  1112. );
  1113. break;
  1114. case 'teacher':
  1115. SessionManager::set_coach_to_course_session(
  1116. $userId,
  1117. $chamiloSessionId,
  1118. $courseInfo['code']
  1119. );
  1120. break;
  1121. }
  1122. $this->logger->addError(
  1123. "User '$chamiloUserName' was added as $type to session: #$chamiloSessionId - Course: " . $courseInfo['code']
  1124. );
  1125. }
  1126. }
  1127. }
  1128. /**
  1129. * Updates the session synchronize with the csv file.
  1130. * @param string $file
  1131. */
  1132. private function importSessionsStatic($file)
  1133. {
  1134. $content = file($file);
  1135. $sessions = array();
  1136. if (!api_strstr($content[0], ';')) {
  1137. $error_message = get_lang('NotCSV');
  1138. } else {
  1139. $tag_names = array();
  1140. foreach ($content as $key => $enreg) {
  1141. $enreg = explode(';', trim($enreg));
  1142. if ($key) {
  1143. foreach ($tag_names as $tag_key => $tag_name) {
  1144. $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
  1145. }
  1146. } else {
  1147. foreach ($enreg as $tag_name) {
  1148. $tag_names[] = api_preg_replace(
  1149. '/[^a-zA-Z0-9_\-]/',
  1150. '',
  1151. $tag_name
  1152. );
  1153. }
  1154. if (!in_array('SessionName', $tag_names) || !in_array(
  1155. 'DateStart',
  1156. $tag_names
  1157. ) || !in_array('DateEnd', $tag_names)
  1158. ) {
  1159. $error_message = get_lang('NoNeededData');
  1160. break;
  1161. }
  1162. }
  1163. }
  1164. }
  1165. if (!empty($sessions)) {
  1166. // Looping the sessions.
  1167. foreach ($sessions as $session) {
  1168. if (!empty($session['SessionID'])) {
  1169. $sessionId = SessionManager::get_session_id_from_original_id(
  1170. $session['SessionID'],
  1171. $this->extraFieldIdNameList['session']
  1172. );
  1173. $coachUserName = isset($session['Coach']) ? $session['Coach'] : null;
  1174. $categoryId = isset($session['category_id']) ? $session['category_id'] : null;
  1175. // 2014-06-30
  1176. $dateStart = explode('/', $session['DateStart']);
  1177. $dateEnd = explode('/', $session['DateEnd']);
  1178. $visibility = $this->defaultSessionVisibility;
  1179. $coachId = null;
  1180. if (!empty($coachUserName)) {
  1181. $coachInfo = api_get_user_info_from_username($coachUserName);
  1182. $coachId = $coachInfo['user_id'];
  1183. }
  1184. if (empty($sessionId)) {
  1185. $result = SessionManager::create_session(
  1186. $session['SessionName'],
  1187. $dateStart[0],
  1188. $dateStart[1],
  1189. $dateStart[2],
  1190. $dateEnd[0],
  1191. $dateEnd[1],
  1192. $dateEnd[2],
  1193. $this->daysCoachAccessBeforeBeginning,
  1194. $this->daysCoachAccessAfterBeginning,
  1195. null,
  1196. $coachUserName,
  1197. $categoryId,
  1198. $visibility,
  1199. 1
  1200. );
  1201. if (is_numeric($result)) {
  1202. $sessionId = $result;
  1203. SessionManager::update_session_extra_field_value(
  1204. $sessionId,
  1205. $this->extraFieldIdNameList['session'],
  1206. $session['SessionID']
  1207. );
  1208. }
  1209. } else {
  1210. $sessionInfo = api_get_session_info($sessionId);
  1211. $accessBefore = null;
  1212. $accessAfter = null;
  1213. if (empty($sessionInfo['nb_days_access_before_beginning']) ||
  1214. (!empty($sessionInfo['nb_days_access_before_beginning']) &&
  1215. $sessionInfo['nb_days_access_before_beginning'] < $this->daysCoachAccessBeforeBeginning)
  1216. ) {
  1217. $accessBefore = intval($this->daysCoachAccessBeforeBeginning);
  1218. }
  1219. $accessAfter = null;
  1220. if (empty($sessionInfo['nb_days_access_after_end']) ||
  1221. (!empty($sessionInfo['nb_days_access_after_end']) &&
  1222. $sessionInfo['nb_days_access_after_end'] < $this->daysCoachAccessAfterBeginning)
  1223. ) {
  1224. $accessAfter = intval($this->daysCoachAccessAfterBeginning);
  1225. }
  1226. $showDescription = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : 1;
  1227. $result = SessionManager::edit_session(
  1228. $sessionId,
  1229. $session['SessionName'],
  1230. $dateStart[0],
  1231. $dateStart[1],
  1232. $dateStart[2],
  1233. $dateEnd[0],
  1234. $dateEnd[1],
  1235. $dateEnd[2],
  1236. $accessBefore,
  1237. $accessAfter,
  1238. null,
  1239. $coachId,
  1240. $categoryId,
  1241. $visibility,
  1242. true, //$start_limit =
  1243. true, //$end_limit =
  1244. null, //$description
  1245. $showDescription // $showDescription = null,
  1246. );
  1247. if (is_numeric($result)) {
  1248. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1249. $params = array(
  1250. 'description' => $session['SessionDescription'],
  1251. );
  1252. Database::update(
  1253. $tbl_session,
  1254. $params,
  1255. array('id = ?' => $sessionId)
  1256. );
  1257. }
  1258. }
  1259. // Courses
  1260. $courses = explode('|', $session['Courses']);
  1261. $courseList = array();
  1262. foreach ($courses as $course) {
  1263. $courseArray = bracketsToArray($course);
  1264. $courseCode = $courseArray[0];
  1265. if (CourseManager::course_exists($courseCode)) {
  1266. $courseList[] = $courseCode;
  1267. }
  1268. }
  1269. SessionManager::add_courses_to_session(
  1270. $sessionId,
  1271. $courseList,
  1272. true
  1273. );
  1274. if (!empty($sessionId)) {
  1275. $courses = explode('|', $session['Courses']);
  1276. foreach ($courses as $course) {
  1277. $courseArray = bracketsToArray($course);
  1278. $courseCode = $courseArray[0];
  1279. if (CourseManager::course_exists($courseCode)) {
  1280. // Coaches
  1281. $courseCoaches = isset($courseArray[1]) ? $courseArray[1] : null;
  1282. $courseCoaches = explode(',', $courseCoaches);
  1283. if (!empty($courseCoaches)) {
  1284. $coachList = array();
  1285. foreach ($courseCoaches as $courseCoach) {
  1286. $courseCoachId = UserManager::get_user_id_from_username($courseCoach);
  1287. if ($courseCoachId !== false) {
  1288. // Just insert new coaches
  1289. $coachList[] = $courseCoachId;
  1290. }
  1291. }
  1292. SessionManager::updateCoaches(
  1293. $sessionId,
  1294. $courseCode,
  1295. $coachList,
  1296. true
  1297. );
  1298. }
  1299. // Students
  1300. $courseUsers = isset($courseArray[2]) ? $courseArray[2] : null;
  1301. $courseUsers = explode(',', $courseUsers);
  1302. if (!empty($courseUsers)) {
  1303. $userList = array();
  1304. foreach ($courseUsers as $username) {
  1305. $userInfo = api_get_user_info_from_username(trim($username));
  1306. if (!empty($userInfo)) {
  1307. $userList[] = $userInfo['user_id'];
  1308. }
  1309. }
  1310. SessionManager::subscribe_users_to_session_course(
  1311. $userList,
  1312. $sessionId,
  1313. $courseCode,
  1314. SESSION_VISIBLE_READ_ONLY,
  1315. true
  1316. );
  1317. } else {
  1318. $this->logger->addInfo("No users to register.");
  1319. }
  1320. } else {
  1321. $this->logger->addInfo("Course does not exists $courseCode");
  1322. }
  1323. }
  1324. } else {
  1325. $this->logger->addInfo('SessionID not found in system.');
  1326. }
  1327. } else {
  1328. $this->logger->addInfo('SessionID does not exists');
  1329. }
  1330. }
  1331. } else {
  1332. $this->logger->addInfo($error_message);
  1333. }
  1334. }
  1335. /**
  1336. * @param string $file
  1337. * @param bool $moveFile
  1338. * @param array $teacherBackup
  1339. * @param array $groupBackup
  1340. */
  1341. private function importSessions($file, $moveFile = true, &$teacherBackup = array(), &$groupBackup = array())
  1342. {
  1343. $avoid = null;
  1344. if (isset($this->conditions['importSessions']) &&
  1345. isset($this->conditions['importSessions']['update'])
  1346. ) {
  1347. $avoid = $this->conditions['importSessions']['update'];
  1348. }
  1349. $result = SessionManager::importCSV(
  1350. $file,
  1351. true,
  1352. $this->defaultAdminId,
  1353. $this->logger,
  1354. array('SessionID' => 'extra_'.$this->extraFieldIdNameList['session']),
  1355. $this->extraFieldIdNameList['session'],
  1356. $this->daysCoachAccessBeforeBeginning,
  1357. $this->daysCoachAccessAfterBeginning,
  1358. $this->defaultSessionVisibility,
  1359. $avoid,
  1360. false, // deleteUsersNotInList
  1361. false, // updateCourseCoaches
  1362. true, // sessionWithCoursesModifier
  1363. true, //$addOriginalCourseTeachersAsCourseSessionCoaches
  1364. true, //$removeAllTeachersFromCourse
  1365. 1, // $showDescription,
  1366. $teacherBackup,
  1367. $groupBackup
  1368. );
  1369. if (!empty($result['error_message'])) {
  1370. $this->logger->addError($result['error_message']);
  1371. }
  1372. $this->logger->addInfo("Sessions - Sessions parsed: ".$result['session_counter']);
  1373. if ($moveFile) {
  1374. $this->moveFile($file);
  1375. }
  1376. }
  1377. /**
  1378. * @param string $file
  1379. */
  1380. private function importSubscribeStatic($file)
  1381. {
  1382. $data = Import::csv_reader($file);
  1383. if (!empty($data)) {
  1384. $this->logger->addInfo(count($data) . " records found.");
  1385. foreach ($data as $row) {
  1386. $chamiloUserName = $row['UserName'];
  1387. $chamiloCourseCode = $row['CourseCode'];
  1388. $chamiloSessionId = $row['SessionID'];
  1389. $type = $row['Type'];
  1390. $sessionInfo = api_get_session_info($chamiloSessionId);
  1391. if (empty($sessionInfo)) {
  1392. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1393. continue;
  1394. }
  1395. $courseInfo = api_get_course_info($chamiloCourseCode);
  1396. if (empty($courseInfo)) {
  1397. $this->logger->addError('Course does not exists: '.$courseInfo);
  1398. continue;
  1399. }
  1400. $userId = Usermanager::get_user_id_from_username($chamiloUserName);
  1401. if (empty($userId)) {
  1402. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1403. continue;
  1404. }
  1405. $status = null;
  1406. switch ($type) {
  1407. case 'student':
  1408. SessionManager::subscribe_users_to_session_course(
  1409. array($userId),
  1410. $chamiloSessionId,
  1411. $courseInfo['code'],
  1412. null,
  1413. false
  1414. );
  1415. break;
  1416. case 'teacher':
  1417. SessionManager::set_coach_to_course_session(
  1418. $userId,
  1419. $chamiloSessionId,
  1420. $courseInfo['code']
  1421. );
  1422. break;
  1423. }
  1424. $this->logger->addError(
  1425. "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: " . $courseInfo['code']
  1426. );
  1427. }
  1428. }
  1429. }
  1430. /**
  1431. * @param $file
  1432. * @param bool $moveFile
  1433. */
  1434. private function importSubscribeUserToCourse($file, $moveFile = false)
  1435. {
  1436. $data = Import::csv_reader($file);
  1437. if (!empty($data)) {
  1438. $this->logger->addInfo(count($data) . " records found.");
  1439. foreach ($data as $row) {
  1440. $chamiloUserName = $row['UserName'];
  1441. $chamiloCourseCode = $row['CourseCode'];
  1442. $status = $row['Status'];
  1443. $courseInfo = api_get_course_info($chamiloCourseCode);
  1444. if (empty($courseInfo)) {
  1445. $this->logger->addError('Course does not exists: '.$chamiloCourseCode);
  1446. continue;
  1447. }
  1448. $userId = Usermanager::get_user_id_from_username($chamiloUserName);
  1449. if (empty($userId)) {
  1450. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1451. continue;
  1452. }
  1453. CourseManager::subscribe_user($userId, $courseInfo['code'], $status);
  1454. $this->logger->addInfo("User $userId added to course $chamiloCourseCode as $status");
  1455. }
  1456. }
  1457. }
  1458. /**
  1459. * @param string $file
  1460. */
  1461. private function importUnsubscribeStatic($file, $moveFile = false, &$teacherBackup = array(), &$groupBackup = array())
  1462. {
  1463. $data = Import::csv_reader($file);
  1464. if (!empty($data)) {
  1465. $this->logger->addInfo(count($data)." records found.");
  1466. foreach ($data as $row) {
  1467. $chamiloUserName = $row['UserName'];
  1468. $chamiloCourseCode = $row['CourseCode'];
  1469. $chamiloSessionId = $row['SessionID'];
  1470. $sessionInfo = api_get_session_info($chamiloSessionId);
  1471. if (empty($sessionInfo)) {
  1472. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1473. continue;
  1474. }
  1475. $courseInfo = api_get_course_info($chamiloCourseCode);
  1476. if (empty($courseInfo)) {
  1477. $this->logger->addError('Course does not exists: '.$courseInfo);
  1478. continue;
  1479. }
  1480. $userId = Usermanager::get_user_id_from_username($chamiloUserName);
  1481. if (empty($userId)) {
  1482. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1483. continue;
  1484. }
  1485. $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
  1486. WHERE
  1487. user_id = ".$userId." AND
  1488. course_code = '".$courseInfo['code']."'
  1489. ";
  1490. $result = Database::query($sql);
  1491. $userCourseData = Database::fetch_array($result, 'ASSOC');
  1492. $teacherBackup[$userId][$courseInfo['code']] = $userCourseData;
  1493. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
  1494. WHERE
  1495. user_id = ".$userId." AND
  1496. c_id = '".$courseInfo['real_id']."'
  1497. ";
  1498. $result = Database::query($sql);
  1499. while ($groupData = Database::fetch_array($result, 'ASSOC')) {
  1500. $groupBackup['user'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
  1501. }
  1502. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
  1503. WHERE
  1504. user_id = ".$userId." AND
  1505. c_id = '".$courseInfo['real_id']."'
  1506. ";
  1507. $result = Database::query($sql);
  1508. while ($groupData = Database::fetch_array($result, 'ASSOC')) {
  1509. $groupBackup['tutor'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
  1510. }
  1511. CourseManager::unsubscribe_user(
  1512. $userId,
  1513. $courseInfo['code'],
  1514. $chamiloSessionId
  1515. );
  1516. $this->logger->addError(
  1517. "User '$chamiloUserName' was removed from session: #$chamiloSessionId, Course: ".$courseInfo['code']
  1518. );
  1519. }
  1520. }
  1521. }
  1522. /**
  1523. * Dump database tables
  1524. */
  1525. private function dumpDatabaseTables()
  1526. {
  1527. echo 'Dumping tables'.PHP_EOL;
  1528. // User
  1529. $table = Database::get_main_table(TABLE_MAIN_USER);
  1530. $tableAdmin = Database::get_main_table(TABLE_MAIN_ADMIN);
  1531. $sql = "DELETE FROM $table
  1532. WHERE user_id not in (select user_id from $tableAdmin) and status <> ".ANONYMOUS;
  1533. Database::query($sql);
  1534. echo $sql.PHP_EOL;
  1535. // Truncate tables
  1536. $truncateTables = array(
  1537. Database::get_main_table(TABLE_MAIN_COURSE),
  1538. Database::get_main_table(TABLE_MAIN_COURSE_USER),
  1539. Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE),
  1540. Database::get_main_table(TABLE_MAIN_CATEGORY),
  1541. Database::get_main_table(TABLE_MAIN_COURSE_MODULE),
  1542. Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER),
  1543. Database::get_main_table(TABLE_MAIN_SESSION),
  1544. Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY),
  1545. Database::get_main_table(TABLE_MAIN_SESSION_COURSE),
  1546. Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER),
  1547. Database::get_main_table(TABLE_MAIN_SESSION_USER),
  1548. Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION),
  1549. Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
  1550. Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
  1551. Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES),
  1552. Database::get_main_table(TABLE_MAIN_USER_FIELD),
  1553. Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS),
  1554. Database::get_main_table(TABLE_MAIN_COURSE_FIELD),
  1555. Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
  1556. Database::get_main_table(TABLE_MAIN_SESSION_FIELD),
  1557. Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
  1558. Database::get_course_table(TABLE_AGENDA),
  1559. Database::get_course_table(TABLE_AGENDA_ATTACHMENT),
  1560. Database::get_course_table(TABLE_AGENDA_REPEAT),
  1561. Database::get_course_table(TABLE_AGENDA_REPEAT_NOT),
  1562. Database::get_main_table(TABLE_PERSONAL_AGENDA),
  1563. Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT_NOT),
  1564. Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT),
  1565. Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_VALUES),
  1566. Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS),
  1567. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS),
  1568. Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN),
  1569. Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS),
  1570. Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES),
  1571. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT),
  1572. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING),
  1573. Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT),
  1574. Database::get_main_table(TABLE_STATISTIC_TRACK_E_UPLOADS),
  1575. Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT),
  1576. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY),
  1577. Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY),
  1578. Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION),
  1579. Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG),
  1580. Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT),
  1581. Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_LOG),
  1582. Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK),
  1583. Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY),
  1584. Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE),
  1585. Database::get_course_table(TABLE_STUDENT_PUBLICATION),
  1586. Database::get_course_table(TABLE_QUIZ_QUESTION),
  1587. Database::get_course_table(TABLE_QUIZ_TEST),
  1588. Database::get_course_table(TABLE_QUIZ_ORDER),
  1589. Database::get_course_table(TABLE_QUIZ_ANSWER),
  1590. Database::get_course_table(TABLE_QUIZ_TEST_QUESTION),
  1591. Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION),
  1592. Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY),
  1593. Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY),
  1594. Database::get_course_table(TABLE_LP_MAIN),
  1595. Database::get_course_table(TABLE_LP_ITEM),
  1596. Database::get_course_table(TABLE_LP_VIEW),
  1597. Database::get_course_table(TABLE_LP_ITEM_VIEW),
  1598. Database::get_course_table(TABLE_DOCUMENT),
  1599. Database::get_course_table(TABLE_ITEM_PROPERTY),
  1600. Database::get_course_table(TABLE_TOOL_LIST),
  1601. Database::get_course_table(TABLE_TOOL_INTRO),
  1602. Database::get_course_table(TABLE_COURSE_SETTING),
  1603. Database::get_course_table(TABLE_SURVEY),
  1604. Database::get_course_table(TABLE_SURVEY_QUESTION),
  1605. Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION),
  1606. Database::get_course_table(TABLE_SURVEY_INVITATION),
  1607. Database::get_course_table(TABLE_SURVEY_ANSWER),
  1608. Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP),
  1609. Database::get_course_table(TABLE_SURVEY_REPORT),
  1610. Database::get_course_table(TABLE_GLOSSARY),
  1611. Database::get_course_table(TABLE_LINK),
  1612. Database::get_course_table(TABLE_LINK_CATEGORY),
  1613. Database::get_course_table(TABLE_GROUP),
  1614. Database::get_course_table(TABLE_GROUP_USER),
  1615. Database::get_course_table(TABLE_GROUP_TUTOR),
  1616. Database::get_course_table(TABLE_GROUP_CATEGORY),
  1617. Database::get_course_table(TABLE_DROPBOX_CATEGORY),
  1618. Database::get_course_table(TABLE_DROPBOX_FEEDBACK),
  1619. Database::get_course_table(TABLE_DROPBOX_POST),
  1620. Database::get_course_table(TABLE_DROPBOX_FILE),
  1621. Database::get_course_table(TABLE_DROPBOX_PERSON)
  1622. );
  1623. foreach ($truncateTables as $table) {
  1624. $sql = "TRUNCATE $table";
  1625. Database::query($sql);
  1626. echo $sql.PHP_EOL;
  1627. }
  1628. }
  1629. }
  1630. use Monolog\Logger;
  1631. use Monolog\Handler\StreamHandler;
  1632. use Monolog\Handler\NativeMailerHandler;
  1633. use Monolog\Handler\RotatingFileHandler;
  1634. use Monolog\Handler\BufferHandler;
  1635. $logger = new Logger('cron');
  1636. $emails = isset($_configuration['cron_notification_mails']) ? $_configuration['cron_notification_mails'] : null;
  1637. $minLevel = Logger::DEBUG;
  1638. if (!is_array($emails)) {
  1639. $emails = array($emails);
  1640. }
  1641. $subject = "Cron main/cron/import_csv.php ".date('Y-m-d h:i:s');
  1642. $from = api_get_setting('emailAdministrator');
  1643. /*
  1644. if (!empty($emails)) {
  1645. foreach ($emails as $email) {
  1646. $stream = new NativeMailerHandler($email, $subject, $from, $minLevel);
  1647. $logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
  1648. }
  1649. }*/
  1650. $stream = new StreamHandler(api_get_path(SYS_ARCHIVE_PATH).'import_csv.log', $minLevel);
  1651. $logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
  1652. $logger->pushHandler(new RotatingFileHandler('import_csv', 5, $minLevel));
  1653. $cronImportCSVConditions = isset($_configuration['cron_import_csv_conditions']) ? $_configuration['cron_import_csv_conditions'] : null;
  1654. echo 'See the error log here: '.api_get_path(SYS_ARCHIVE_PATH).'import_csv.log'."\n";
  1655. $import = new ImportCsv($logger, $cronImportCSVConditions);
  1656. if (isset($_configuration['default_admin_user_id_for_cron'])) {
  1657. $import->defaultAdminId = $_configuration['default_admin_user_id_for_cron'];
  1658. }
  1659. // @todo in production disable the dump option
  1660. $dump = false;
  1661. if (isset($argv[1]) && $argv[1] = '--dump') {
  1662. $dump = true;
  1663. }
  1664. if (isset($_configuration['import_csv_disable_dump']) &&
  1665. $_configuration['import_csv_disable_dump'] == true
  1666. ) {
  1667. $import->setDumpValues(false);
  1668. } else {
  1669. $import->setDumpValues($dump);
  1670. }
  1671. // Do not moves the files to treated
  1672. if (isset($_configuration['import_csv_test'])) {
  1673. $import->test = $_configuration['import_csv_test'];
  1674. } else {
  1675. $import->test = true;
  1676. }
  1677. $import->run();
  1678. if (isset($_configuration['import_csv_fix_permissions']) &&
  1679. $_configuration['import_csv_fix_permissions'] == true
  1680. ) {
  1681. $command = "sudo find ".api_get_path(SYS_COURSE_PATH)." -type d -exec chmod 777 {} \; ";
  1682. echo "Executing: ".$command.PHP_EOL;
  1683. system($command);
  1684. $command = "sudo find ".api_get_path(SYS_CODE_PATH)."upload/users -type d -exec chmod 777 {} \;";
  1685. echo "Executing: ".$command.PHP_EOL;
  1686. system($command);
  1687. }