import_csv.php 91 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337
  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. ini_set('memory_limit', -1);
  11. ini_set('max_execution_time', 0);
  12. /**
  13. * Class ImportCsv
  14. */
  15. class ImportCsv
  16. {
  17. private $logger;
  18. private $dumpValues;
  19. public $test;
  20. public $defaultLanguage = 'dutch';
  21. public $extraFieldIdNameList = array(
  22. 'session' => 'external_session_id',
  23. 'course' => 'external_course_id',
  24. 'user' => 'external_user_id',
  25. 'calendar_event' => 'external_calendar_event_id',
  26. );
  27. public $defaultAdminId = 1;
  28. public $defaultSessionVisibility = 1;
  29. /**
  30. * When creating a user the expiration date is set to registration date + this value
  31. * @var int number of years
  32. */
  33. public $expirationDateInUserCreation = 1;
  34. public $batchSize = 20;
  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 Monolog\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 boolean
  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 (isset($fileInfo['extension']) && $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. 'unsubscribe-static'
  152. );
  153. foreach ($sections as $section) {
  154. $this->logger->addInfo("-- Import $section --");
  155. if (isset($fileToProcess[$section]) && !empty($fileToProcess[$section])) {
  156. $files = $fileToProcess[$section];
  157. foreach ($files as $fileInfo) {
  158. $method = $fileInfo['method'];
  159. $file = $fileInfo['file'];
  160. echo 'File: '.$file.PHP_EOL;
  161. $this->logger->addInfo("Reading file: $file");
  162. if ($method == 'importSessions') {
  163. $this->$method(
  164. $file,
  165. true,
  166. $teacherBackup,
  167. $groupBackup
  168. );
  169. } else {
  170. $this->$method($file, true);
  171. }
  172. $this->logger->addInfo("--Finish reading file--");
  173. }
  174. }
  175. }
  176. $sections = array(
  177. 'students-static',
  178. 'teachers-static',
  179. 'courses-static',
  180. 'sessions-static',
  181. 'calendar-static',
  182. 'sessionsextid-static',
  183. 'unsubscribe-static',
  184. 'unsubsessionsextid-static',
  185. 'subsessionsextid-static'
  186. );
  187. foreach ($sections as $section) {
  188. $this->logger->addInfo("-- Import static files $section --");
  189. if (isset($fileToProcessStatic[$section]) &&
  190. !empty($fileToProcessStatic[$section])
  191. ) {
  192. $files = $fileToProcessStatic[$section];
  193. foreach ($files as $fileInfo) {
  194. $method = $fileInfo['method'];
  195. $file = $fileInfo['file'];
  196. echo 'Static file: '.$file.PHP_EOL;
  197. $this->logger->addInfo("Reading static file: $file");
  198. $this->$method(
  199. $file,
  200. true,
  201. $teacherBackup,
  202. $groupBackup
  203. );
  204. $this->logger->addInfo("--Finish reading file--");
  205. }
  206. }
  207. }
  208. $this->logger->addInfo("teacher backup");
  209. $this->logger->addInfo(print_r($teacherBackup, 1));
  210. }
  211. }
  212. /**
  213. * Prepares extra fields before the import
  214. */
  215. private function prepareImport()
  216. {
  217. // Create user extra field: extra_external_user_id
  218. UserManager::create_extra_field(
  219. $this->extraFieldIdNameList['user'],
  220. 1,
  221. 'External user id',
  222. null
  223. );
  224. // Create course extra field: extra_external_course_id
  225. CourseManager::create_course_extra_field(
  226. $this->extraFieldIdNameList['course'],
  227. 1,
  228. 'External course id',
  229. ''
  230. );
  231. // Create session extra field extra_external_session_id
  232. SessionManager::create_session_extra_field(
  233. $this->extraFieldIdNameList['session'],
  234. 1,
  235. 'External session id'
  236. );
  237. // Create calendar_event extra field extra_external_session_id
  238. $extraField = new ExtraField('calendar_event');
  239. $extraField->save(
  240. array(
  241. 'field_type' => ExtraField::FIELD_TYPE_TEXT,
  242. 'variable' => $this->extraFieldIdNameList['calendar_event'],
  243. 'display_text' => 'External calendar event id',
  244. )
  245. );
  246. }
  247. /**
  248. * @param string $file
  249. */
  250. private function moveFile($file)
  251. {
  252. $moved = str_replace('incoming', 'treated', $file);
  253. if ($this->test) {
  254. $result = 1;
  255. } else {
  256. $result = rename($file, $moved);
  257. }
  258. if ($result) {
  259. $this->logger->addInfo("Moving file to the treated folder: $file");
  260. } else {
  261. $this->logger->addError(
  262. "Error - Cant move file to the treated folder: $file"
  263. );
  264. }
  265. }
  266. /**
  267. * @param array $row
  268. *
  269. * @return array
  270. */
  271. private function cleanUserRow($row)
  272. {
  273. $row['lastname'] = $row['LastName'];
  274. $row['firstname'] = $row['FirstName'];
  275. $row['email'] = $row['Email'];
  276. $row['username'] = $row['UserName'];
  277. $row['password'] = $row['Password'];
  278. $row['auth_source'] = isset($row['AuthSource']) ? $row['AuthSource'] : PLATFORM_AUTH_SOURCE;
  279. $row['official_code'] = $row['OfficialCode'];
  280. $row['phone'] = isset($row['PhoneNumber']) ? $row['PhoneNumber'] : '';
  281. if (isset($row['StudentID'])) {
  282. $row['extra_'.$this->extraFieldIdNameList['user']] = $row['StudentID'];
  283. }
  284. if (isset($row['TeacherID'])) {
  285. $row['extra_'.$this->extraFieldIdNameList['user']] = $row['TeacherID'];
  286. }
  287. return $row;
  288. }
  289. /**
  290. * @param array $row
  291. *
  292. * @return array
  293. */
  294. private function cleanCourseRow($row)
  295. {
  296. $row['title'] = $row['Title'];
  297. $row['course_code'] = $row['Code'];
  298. $row['course_category'] = $row['CourseCategory'];
  299. $row['email'] = $row['Teacher'];
  300. $row['language'] = $row['Language'];
  301. $row['teachers'] = array();
  302. if (isset($row['Teacher']) && !empty($row['Teacher'])) {
  303. $this->logger->addInfo("Teacher list found: ".$row['Teacher']);
  304. $teachers = explode(',', $row['Teacher']);
  305. if (!empty($teachers)) {
  306. foreach ($teachers as $teacherUserName) {
  307. $teacherUserName = trim($teacherUserName);
  308. $userInfo = api_get_user_info_from_username($teacherUserName);
  309. if (!empty($userInfo)) {
  310. $this->logger->addInfo("Username found: $teacherUserName");
  311. $row['teachers'][] = $userInfo['user_id'];
  312. }
  313. }
  314. }
  315. }
  316. if (isset($row['CourseID'])) {
  317. $row['extra_'.$this->extraFieldIdNameList['course']] = $row['CourseID'];
  318. }
  319. return $row;
  320. }
  321. /**
  322. * File to import
  323. * @param string $file
  324. */
  325. private function importTeachersStatic($file)
  326. {
  327. $this->importTeachers($file, true);
  328. }
  329. /**
  330. * File to import
  331. * @param string $file
  332. * @param bool $moveFile
  333. */
  334. private function importTeachers($file, $moveFile = true)
  335. {
  336. $this->fixCSVFile($file);
  337. $data = Import::csvToArray($file);
  338. /* Unique identifier: official-code username.
  339. Email address and password should never get updated. *ok
  340. The only fields that I can think of that should update if the data changes in the csv file are FirstName and LastName. *ok
  341. A slight edit of these fields should be taken into account. ???
  342. Adding teachers is no problem, but deleting them shouldn’t be automated, but we should get a log of “to delete teachers”.
  343. We’ll handle that manually if applicable.
  344. No delete!
  345. */
  346. $language = $this->defaultLanguage;
  347. if (!empty($data)) {
  348. $this->logger->addInfo(count($data)." records found.");
  349. $expirationDateOnCreation = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserCreation)."years"));
  350. $expirationDateOnUpdate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserUpdate)."years"));
  351. $batchSize = $this->batchSize;
  352. $em = Database::getManager();
  353. $counter = 1;
  354. foreach ($data as $row) {
  355. $row = $this->cleanUserRow($row);
  356. $user_id = UserManager::get_user_id_from_original_id(
  357. $row['extra_'.$this->extraFieldIdNameList['user']],
  358. $this->extraFieldIdNameList['user']
  359. );
  360. $userInfo = array();
  361. $userInfoByOfficialCode = null;
  362. if (!empty($user_id)) {
  363. $userInfo = api_get_user_info($user_id);
  364. $userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
  365. }
  366. if (empty($userInfo) && empty($userInfoByOfficialCode)) {
  367. // Create user
  368. $userId = UserManager::create_user(
  369. $row['firstname'],
  370. $row['lastname'],
  371. COURSEMANAGER,
  372. $row['email'],
  373. $row['username'],
  374. $row['password'],
  375. $row['official_code'],
  376. $language, //$row['language'],
  377. $row['phone'],
  378. null, //$row['picture'], //picture
  379. $row['auth_source'], // ?
  380. $expirationDateOnCreation, //'0000-00-00 00:00:00', //$row['expiration_date'], //$expiration_date = '0000-00-00 00:00:00',
  381. 1, //active
  382. 0,
  383. null, // extra
  384. null, //$encrypt_method = '',
  385. false //$send_mail = false
  386. );
  387. if ($userId) {
  388. foreach ($row as $key => $value) {
  389. if (substr($key, 0, 6) == 'extra_') {
  390. //an extra field
  391. UserManager::update_extra_field_value(
  392. $userId,
  393. substr($key, 6),
  394. $value
  395. );
  396. }
  397. }
  398. $this->logger->addInfo("Teachers - User created: ".$row['username']);
  399. } else {
  400. $this->logger->addError("Teachers - User NOT created: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
  401. $this->logger->addError(strip_tags(Display::getFlashToString()));
  402. Display::cleanFlashMessages();
  403. }
  404. } else {
  405. if (empty($userInfo)) {
  406. $this->logger->addError("Teachers - Can't update user :".$row['username']);
  407. continue;
  408. }
  409. // Update user
  410. $result = UserManager::update_user(
  411. $userInfo['user_id'],
  412. $row['firstname'], // <<-- changed
  413. $row['lastname'], // <<-- changed
  414. $userInfo['username'],
  415. null, //$password = null,
  416. $row['auth_source'],
  417. $userInfo['email'],
  418. COURSEMANAGER,
  419. $userInfo['official_code'],
  420. $userInfo['phone'],
  421. $userInfo['picture_uri'],
  422. $expirationDateOnUpdate,
  423. $userInfo['active'],
  424. null, //$creator_id = null,
  425. 0, //$hr_dept_id = 0,
  426. null, // $extra = null,
  427. null, //$language = 'english',
  428. null, //$encrypt_method = '',
  429. false, //$send_email = false,
  430. 0 //$reset_password = 0
  431. );
  432. if ($result) {
  433. foreach ($row as $key => $value) {
  434. if (substr($key, 0, 6) == 'extra_') {
  435. //an extra field
  436. UserManager::update_extra_field_value(
  437. $userInfo['user_id'],
  438. substr($key, 6),
  439. $value
  440. );
  441. }
  442. }
  443. $this->logger->addInfo("Teachers - User updated: ".$row['username']);
  444. } else {
  445. $this->logger->addError("Teachers - User not updated: ".$row['username']);
  446. }
  447. }
  448. if (($counter % $batchSize) === 0) {
  449. $em->flush();
  450. $em->clear(); // Detaches all objects from Doctrine!
  451. }
  452. $counter++;
  453. }
  454. $em->clear(); // Detaches all objects from Doctrine!
  455. }
  456. if ($moveFile) {
  457. $this->moveFile($file);
  458. }
  459. }
  460. /**
  461. * @param string $file
  462. */
  463. private function importStudentsStatic($file)
  464. {
  465. $this->importStudents($file, true);
  466. }
  467. /**
  468. * @param string $file
  469. * @param bool $moveFile
  470. */
  471. private function importStudents($file, $moveFile = true)
  472. {
  473. $this->fixCSVFile($file);
  474. $data = Import::csvToArray($file);
  475. /*
  476. * Another users import.
  477. Unique identifier: official code and username . ok
  478. Password should never get updated. ok
  479. If an update should need to occur (because it changed in the .csv),
  480. we’ll want that logged. We will handle this manually in that case.
  481. All other fields should be updateable, though passwords should of course not get updated. ok
  482. If a user gets deleted (not there anymore),
  483. He should be set inactive one year after the current date.
  484. So I presume you’ll just update the expiration date.
  485. We want to grant access to courses up to a year after deletion.
  486. */
  487. $timeStart = microtime(true);
  488. $batchSize = $this->batchSize;
  489. $em = Database::getManager();
  490. if (!empty($data)) {
  491. $language = $this->defaultLanguage;
  492. $this->logger->addInfo(count($data)." records found.");
  493. $expirationDateOnCreate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserCreation)."years"));
  494. $expirationDateOnUpdate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserUpdate)."years"));
  495. $counter = 1;
  496. foreach ($data as $row) {
  497. $row = $this->cleanUserRow($row);
  498. $user_id = UserManager::get_user_id_from_original_id(
  499. $row['extra_'.$this->extraFieldIdNameList['user']],
  500. $this->extraFieldIdNameList['user']
  501. );
  502. $userInfo = array();
  503. $userInfoByOfficialCode = null;
  504. if (!empty($user_id)) {
  505. $userInfo = api_get_user_info($user_id, false, true);
  506. $userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
  507. }
  508. if (empty($userInfo) && empty($userInfoByOfficialCode)) {
  509. // Create user
  510. $result = UserManager::create_user(
  511. $row['firstname'],
  512. $row['lastname'],
  513. STUDENT,
  514. $row['email'],
  515. $row['username'],
  516. $row['password'],
  517. $row['official_code'],
  518. $language, //$row['language'],
  519. $row['phone'],
  520. null, //$row['picture'], //picture
  521. $row['auth_source'], // ?
  522. $expirationDateOnCreate, //'0000-00-00 00:00:00', //$row['expiration_date'], //$expiration_date = '0000-00-00 00:00:00',
  523. 1, //active
  524. 0,
  525. null, // extra
  526. null, //$encrypt_method = '',
  527. false //$send_mail = false
  528. );
  529. if ($result) {
  530. foreach ($row as $key => $value) {
  531. if (substr($key, 0, 6) === 'extra_') {
  532. //an extra field
  533. UserManager::update_extra_field_value(
  534. $result,
  535. substr($key, 6),
  536. $value
  537. );
  538. }
  539. }
  540. $this->logger->addInfo("Students - User created: ".$row['username']);
  541. } else {
  542. $this->logger->addError("Students - User NOT created: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
  543. $this->logger->addError(strip_tags(Display::getFlashToString()));
  544. Display::cleanFlashMessages();
  545. }
  546. } else {
  547. if (empty($userInfo)) {
  548. $this->logger->addError("Students - Can't update user :".$row['username']);
  549. continue;
  550. }
  551. if (isset($row['action']) && $row['action'] === 'delete') {
  552. // Inactive one year later
  553. $userInfo['expiration_date'] = api_get_utc_datetime(api_strtotime(time() + 365*24*60*60));
  554. }
  555. $password = $row['password']; // change password
  556. $email = $row['email']; // change email
  557. $resetPassword = 2; // allow password change
  558. // Conditions that disables the update of password and email:
  559. if (isset($this->conditions['importStudents'])) {
  560. if (isset($this->conditions['importStudents']['update']) &&
  561. isset($this->conditions['importStudents']['update']['avoid'])
  562. ) {
  563. // Blocking email update -
  564. // 1. Condition
  565. $avoidUsersWithEmail = $this->conditions['importStudents']['update']['avoid']['email'];
  566. if ($userInfo['email'] != $row['email'] && in_array($row['email'], $avoidUsersWithEmail)) {
  567. $this->logger->addInfo("Students - User email is not updated : ".$row['username']." because the avoid conditions (email).");
  568. // Do not change email keep the old email.
  569. $email = $userInfo['email'];
  570. }
  571. // 2. Condition
  572. if (!in_array($userInfo['email'], $avoidUsersWithEmail) && !in_array($row['email'], $avoidUsersWithEmail)) {
  573. $email = $userInfo['email'];
  574. }
  575. // 3. Condition
  576. if (in_array($userInfo['email'], $avoidUsersWithEmail) && !in_array($row['email'], $avoidUsersWithEmail)) {
  577. $email = $row['email'];
  578. }
  579. // Blocking password update
  580. //$avoidUsersWithPassword = $this->conditions['importStudents']['update']['avoid']['password'];
  581. /*if (isset($row['password'])) {
  582. $user = api_get_user_entity($userInfo['id']);
  583. $encoded = UserManager::encryptPassword(
  584. $row['password'],
  585. $user
  586. );
  587. if ($userInfo['password'] != $encoded &&
  588. in_array($row['password'], $avoidUsersWithPassword)
  589. ) {
  590. $this->logger->addInfo(
  591. "Students - User password is not updated: ".$row['username']." because the avoid conditions (password)."
  592. );
  593. $password = null;
  594. $resetPassword = 0; // disallow password change
  595. }
  596. }*/
  597. }
  598. }
  599. // Always disallow password change during update
  600. $password = null;
  601. $resetPassword = 0; // disallow password change
  602. // Update user
  603. $result = UserManager::update_user(
  604. $userInfo['user_id'],
  605. $row['firstname'], // <<-- changed
  606. $row['lastname'], // <<-- changed
  607. $row['username'], // <<-- changed
  608. $password, //$password = null,
  609. $row['auth_source'],
  610. $email,
  611. STUDENT,
  612. $userInfo['official_code'],
  613. $userInfo['phone'],
  614. $userInfo['picture_uri'],
  615. $expirationDateOnUpdate,
  616. $userInfo['active'],
  617. null, //$creator_id = null,
  618. 0, //$hr_dept_id = 0,
  619. null, // $extra = null,
  620. null, //$language = 'english',
  621. null, //$encrypt_method = '',
  622. false, //$send_email = false,
  623. $resetPassword //$reset_password = 0
  624. );
  625. if ($result) {
  626. if ($row['username'] != $userInfo['username']) {
  627. $this->logger->addInfo("Students - Username was changes from '".$userInfo['username']."' to '".$row['username']."' ");
  628. }
  629. foreach ($row as $key => $value) {
  630. if (substr($key, 0, 6) === 'extra_') {
  631. //an extra field
  632. UserManager::update_extra_field_value(
  633. $userInfo['user_id'],
  634. substr($key, 6),
  635. $value
  636. );
  637. }
  638. }
  639. $this->logger->addInfo("Students - User updated: ".$row['username']);
  640. } else {
  641. $this->logger->addError("Students - User NOT updated: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
  642. }
  643. }
  644. if (($counter % $batchSize) === 0) {
  645. $em->flush();
  646. $em->clear(); // Detaches all objects from Doctrine!
  647. $this->logger->addInfo("Detaches all objects");
  648. }
  649. $counter++;
  650. }
  651. $em->clear(); // Detaches all objects from Doctrine!
  652. }
  653. $timeEnd = microtime(true);
  654. $executionTime = round(($timeEnd - $timeStart)/60, 2);
  655. $this->logger->addInfo("Execution Time for process students: $executionTime Min");
  656. if ($moveFile) {
  657. $this->moveFile($file);
  658. }
  659. }
  660. /**
  661. * @param string $file
  662. */
  663. private function importCoursesStatic($file, $moveFile, &$teacherBackup = array(), &$groupBackup = array())
  664. {
  665. $this->importCourses($file, true, $teacherBackup, $groupBackup);
  666. }
  667. /**
  668. * @param string $file
  669. * @param bool $moveFile
  670. *
  671. * @return int
  672. */
  673. private function importCalendarStatic($file, $moveFile = true)
  674. {
  675. $this->fixCSVFile($file);
  676. $data = Import::csvToArray($file);
  677. if (!empty($data)) {
  678. $this->logger->addInfo(count($data)." records found.");
  679. $eventsToCreate = array();
  680. $errorFound = false;
  681. foreach ($data as $row) {
  682. $sessionId = null;
  683. $externalSessionId = null;
  684. if (isset($row['external_sessionID'])) {
  685. $externalSessionId = $row['external_sessionID'];
  686. $sessionId = SessionManager::getSessionIdFromOriginalId(
  687. $externalSessionId,
  688. $this->extraFieldIdNameList['session']
  689. );
  690. }
  691. $courseCode = null;
  692. if (isset($row['coursecode'])) {
  693. $courseCode = $row['coursecode'];
  694. }
  695. $courseInfo = api_get_course_info($courseCode);
  696. if (empty($courseInfo)) {
  697. $this->logger->addInfo("Course '$courseCode' does not exists");
  698. }
  699. if (empty($sessionId)) {
  700. $this->logger->addInfo("external_sessionID: ".$externalSessionId." does not exists.");
  701. }
  702. $teacherId = null;
  703. if (!empty($sessionId) && !empty($courseInfo)) {
  704. $courseIncluded = SessionManager::relation_session_course_exist(
  705. $sessionId,
  706. $courseInfo['real_id']
  707. );
  708. if ($courseIncluded == false) {
  709. $this->logger->addInfo(
  710. "Course '$courseCode' is not included in session: $sessionId"
  711. );
  712. $errorFound = true;
  713. } else {
  714. $teachers = CourseManager::get_coach_list_from_course_code(
  715. $courseInfo['code'],
  716. $sessionId
  717. );
  718. // Getting first teacher.
  719. if (!empty($teachers)) {
  720. $teacher = current($teachers);
  721. $teacherId = $teacher['user_id'];
  722. } else {
  723. $sessionInfo = api_get_session_info($sessionId);
  724. $teacherId = $sessionInfo['id_coach'];
  725. }
  726. }
  727. } else {
  728. $errorFound = true;
  729. }
  730. if (empty($teacherId)) {
  731. $errorFound = true;
  732. $this->logger->addInfo(
  733. "No teacher found in course code : '$courseCode' and session: '$sessionId'"
  734. );
  735. }
  736. $date = $row['date'];
  737. $startTime = $row['time_start'];
  738. $endTime = $row['time_end'];
  739. $title = $row['title'];
  740. $comment = $row['comment'];
  741. $color = isset($row['color']) ? $row['color'] : '';
  742. $startDateYear = substr($date, 0, 4);
  743. $startDateMonth = substr($date, 4, 2);
  744. $startDateDay = substr($date, 6, 8);
  745. $startDate = $startDateYear.'-'.$startDateMonth.'-'.$startDateDay.' '.$startTime.":00";
  746. $endDate = $startDateYear.'-'.$startDateMonth.'-'.$startDateDay.' '.$endTime.":00";
  747. if (!api_is_valid_date($startDate) || !api_is_valid_date($endDate)) {
  748. $this->logger->addInfo(
  749. "Verify your dates: '$startDate' : '$endDate' "
  750. );
  751. $errorFound = true;
  752. }
  753. if ($errorFound == false) {
  754. $eventsToCreate[] = array(
  755. 'start' => $startDate,
  756. 'end' => $endDate,
  757. 'title' => $title,
  758. 'sender_id' => $teacherId,
  759. 'course_id' => $courseInfo['real_id'],
  760. 'session_id' => $sessionId,
  761. 'comment' => $comment,
  762. 'color' => $color,
  763. $this->extraFieldIdNameList['calendar_event'] => $row['external_calendar_itemID'],
  764. );
  765. }
  766. $errorFound = false;
  767. }
  768. if (empty($eventsToCreate)) {
  769. $this->logger->addInfo(
  770. "No events to add"
  771. );
  772. return 0;
  773. }
  774. $extraFieldValue = new ExtraFieldValue('calendar_event');
  775. $extraFieldName = $this->extraFieldIdNameList['calendar_event'];
  776. $externalEventId = null;
  777. $extraField = new ExtraField('calendar_event');
  778. $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
  779. $extraFieldName
  780. );
  781. if (empty($extraFieldInfo)) {
  782. $this->logger->addInfo(
  783. "No calendar event extra field created: $extraFieldName"
  784. );
  785. return 0;
  786. }
  787. $this->logger->addInfo(
  788. "Ready to insert events"
  789. );
  790. $batchSize = $this->batchSize;
  791. $counter = 1;
  792. $em = Database::getManager();
  793. $eventStartDateList = [];
  794. $eventEndDateList = [];
  795. $report = [
  796. 'mail_sent' => 0,
  797. 'mail_not_sent_announcement_exists' => 0,
  798. 'mail_not_sent_because_date' => 0,
  799. ];
  800. $eventsToCreateFinal = [];
  801. foreach ($eventsToCreate as $event) {
  802. $update = false;
  803. $item = null;
  804. if (!isset($event[$extraFieldName])) {
  805. $this->logger->addInfo(
  806. "No external_calendar_itemID found. Skipping ..."
  807. );
  808. continue;
  809. } else {
  810. $externalEventId = $event[$extraFieldName];
  811. if (empty($externalEventId)) {
  812. $this->logger->addInfo(
  813. "external_calendar_itemID was set but empty. Skipping ..."
  814. );
  815. continue;
  816. }
  817. $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
  818. $extraFieldName,
  819. $externalEventId,
  820. false,
  821. false,
  822. false
  823. );
  824. if (!empty($item)) {
  825. $update = true;
  826. }
  827. }
  828. $courseInfo = api_get_course_info_by_id($event['course_id']);
  829. $event['course_info'] = $courseInfo;
  830. $event['update'] = $update;
  831. $event['item'] = $item;
  832. $event['external_event_id'] = $externalEventId;
  833. if (isset($eventStartDateList[$courseInfo['real_id']]) &&
  834. isset($eventStartDateList[$courseInfo['real_id']][$event['session_id']])
  835. ) {
  836. $currentItemDate = api_strtotime($event['start']);
  837. $firstDate = $eventStartDateList[$courseInfo['real_id']][$event['session_id']];
  838. if ($currentItemDate < api_strtotime($firstDate)) {
  839. $eventStartDateList[$courseInfo['real_id']][$event['session_id']] = $event['start'];
  840. $eventEndDateList[$courseInfo['real_id']][$event['session_id']] = $event['end'];
  841. }
  842. } else {
  843. // First time
  844. $eventStartDateList[$courseInfo['real_id']][$event['session_id']] = $event['start'];
  845. $eventEndDateList[$courseInfo['real_id']][$event['session_id']] = $event['end'];
  846. }
  847. $eventsToCreateFinal[] = $event;
  848. }
  849. $eventAlreadySent = [];
  850. foreach ($eventsToCreateFinal as $event) {
  851. $courseInfo = $event['course_info'];
  852. $item = $event['item'];
  853. $update = $event['update'];
  854. $externalEventId = $event['external_event_id'];
  855. $info = 'Course: '.$courseInfo['real_id'].' ('.$courseInfo['code'].') - Session: '.$event['session_id'];
  856. $agenda = new Agenda(
  857. 'course',
  858. $event['sender_id'],
  859. $courseInfo['real_id'],
  860. $event['session_id']
  861. );
  862. $agenda->set_course($courseInfo);
  863. $agenda->setSessionId($event['session_id']);
  864. $agenda->setSenderId($event['sender_id']);
  865. $agenda->setIsAllowedToEdit(true);
  866. $eventComment = $event['comment'];
  867. $color = $event['color'];
  868. // To use the event comment you need
  869. // ALTER TABLE c_calendar_event ADD COLUMN comment TEXT;
  870. // add in configuration.php allow_agenda_event_comment = true
  871. if (empty($courseInfo)) {
  872. $this->logger->addInfo(
  873. "No course found for event #$externalEventId Course #".$event['course_id']." Skipping ..."
  874. );
  875. continue;
  876. }
  877. if (empty($event['sender_id'])) {
  878. $this->logger->addInfo(
  879. "No sender found for event #$externalEventId Send #".$event['sender_id']." Skipping ..."
  880. );
  881. continue;
  882. }
  883. // Taking first element of course-session event
  884. $alreadyAdded = false;
  885. $firstDate = $eventStartDateList[$courseInfo['real_id']][$event['session_id']];
  886. $firstEndDate = $eventEndDateList[$courseInfo['real_id']][$event['session_id']];
  887. if (isset($eventAlreadySent[$courseInfo['real_id']]) &&
  888. isset($eventAlreadySent[$courseInfo['real_id']][$event['session_id']])
  889. ) {
  890. $alreadyAdded = true;
  891. } else {
  892. $eventAlreadySent[$courseInfo['real_id']][$event['session_id']] = true;
  893. }
  894. // Working days (Mon-Fri)see BT#12156#note-16
  895. $days = 5;
  896. $startDatePlusDays = api_strtotime("$days weekdays");
  897. $this->logger->addInfo(
  898. "startDatePlusDays: ".api_get_utc_datetime($startDatePlusDays).' - First date: '.$firstDate
  899. );
  900. // Send
  901. if ($startDatePlusDays > api_strtotime($firstDate)) {
  902. $sendMail = true;
  903. } else {
  904. $sendMail = false;
  905. }
  906. // Send announcement to users
  907. if ($sendMail && $alreadyAdded == false) {
  908. $start = $firstDate;
  909. $end = $firstEndDate;
  910. if (!empty($end) &&
  911. api_format_date($start, DATE_FORMAT_LONG) == api_format_date($end, DATE_FORMAT_LONG)
  912. ) {
  913. $date = api_format_date($start, DATE_FORMAT_LONG).' ('.
  914. api_format_date($start, TIME_NO_SEC_FORMAT).' '.
  915. api_format_date($end, TIME_NO_SEC_FORMAT).')';
  916. } else {
  917. $date = api_format_date($start,DATE_TIME_FORMAT_LONG_24H).' - '.
  918. api_format_date($end, DATE_TIME_FORMAT_LONG_24H);
  919. }
  920. $sessionName = '';
  921. if (!empty($event['session_id'])) {
  922. $sessionName = ' ('.api_get_session_name($event['session_id']).')';
  923. }
  924. $courseTitle = $courseInfo['title'].$sessionName;
  925. $emailBody = get_lang('Dear').' ((user_firstname)) <br />'.
  926. sprintf(
  927. get_lang('YouHaveBeenSubscribedToCourseXTheStartDateXAndCommentX'),
  928. $courseTitle,
  929. $date,
  930. $event['comment']
  931. );
  932. $subject = sprintf(
  933. get_lang('AgendaAvailableInCourseX'),
  934. $courseInfo['title']
  935. );
  936. $coaches = SessionManager::getCoachesByCourseSession(
  937. $courseInfo['real_id'],
  938. $event['session_id']
  939. );
  940. // Search if an announcement exists:
  941. $announcementsWithTitleList = AnnouncementManager::getAnnouncementsByTitle(
  942. $subject,
  943. $courseInfo['real_id'],
  944. $event['session_id'],
  945. 1
  946. );
  947. if (count($announcementsWithTitleList) == 0) {
  948. $this->logger->addInfo(
  949. "Mail to be sent because start date: ".$event['start']." and no announcement found."
  950. );
  951. $announcementId = AnnouncementManager::add_announcement(
  952. $courseInfo,
  953. $event['session_id'],
  954. $subject,
  955. $emailBody,
  956. [
  957. 'everyone',
  958. 'users' => $coaches
  959. ],
  960. [],
  961. null,
  962. null,
  963. false,
  964. $this->defaultAdminId
  965. );
  966. if ($announcementId) {
  967. $this->logger->addInfo(
  968. "Announcement added: ".(int)($announcementId)." in $info"
  969. );
  970. $this->logger->addInfo(
  971. "<<--SENDING MAIL-->>"
  972. );
  973. $report['mail_sent']++;
  974. AnnouncementManager::sendEmail(
  975. $courseInfo,
  976. $event['session_id'],
  977. $announcementId,
  978. false
  979. );
  980. }
  981. } else {
  982. $report['mail_not_sent_announcement_exists']++;
  983. $this->logger->addInfo(
  984. "Mail NOT sent. An announcement seems to be already saved in $info"
  985. );
  986. }
  987. } else {
  988. if ($sendMail == false) {
  989. $report['mail_not_sent_because_date']++;
  990. }
  991. }
  992. $content = '';
  993. if ($update && isset($item['item_id'])) {
  994. //the event already exists, just update
  995. $eventResult = $agenda->editEvent(
  996. $item['item_id'],
  997. $event['start'],
  998. $event['end'],
  999. false,
  1000. $event['title'],
  1001. $content,
  1002. array('everyone'), // $usersToSend
  1003. array(), //$attachmentArray = array(),
  1004. [], //$attachmentCommentList
  1005. $eventComment,
  1006. $color,
  1007. false,
  1008. false
  1009. );
  1010. if ($eventResult !== false) {
  1011. $this->logger->addInfo(
  1012. "Event updated #".$item['item_id']." External cal Id: (".$externalEventId.") $info"
  1013. );
  1014. } else {
  1015. $this->logger->addInfo(
  1016. "Error while updating event with external id: $externalEventId"
  1017. );
  1018. }
  1019. } else {
  1020. // New event. Create it.
  1021. $eventId = $agenda->addEvent(
  1022. $event['start'],
  1023. $event['end'],
  1024. false,
  1025. $event['title'],
  1026. $content,
  1027. array('everyone'), // $usersToSend
  1028. false, //$addAsAnnouncement = false
  1029. null, // $parentEventId
  1030. array(), //$attachmentArray = array(),
  1031. [], //$attachmentCommentList
  1032. $eventComment,
  1033. $color
  1034. );
  1035. if (!empty($eventId)) {
  1036. //$extraFieldValue->is_course_model = true;
  1037. $extraFieldValue->save(
  1038. array(
  1039. 'value' => $externalEventId,
  1040. 'field_id' => $extraFieldInfo['id'],
  1041. 'item_id' => $eventId
  1042. )
  1043. );
  1044. $this->logger->addInfo(
  1045. "Event added: #$eventId External cal id: (".$externalEventId.") $info"
  1046. );
  1047. } else {
  1048. $this->logger->addInfo(
  1049. "Error while creating event external id: $externalEventId"
  1050. );
  1051. }
  1052. }
  1053. if (($counter % $batchSize) === 0) {
  1054. $em->flush();
  1055. $em->clear(); // Detaches all objects from Doctrine!
  1056. }
  1057. $counter++;
  1058. }
  1059. $em->clear(); // Detaches all objects from Doctrine!
  1060. $this->logger->addInfo('------Summary------');
  1061. foreach ($report as $title => $count) {
  1062. $this->logger->addInfo("$title: $count");
  1063. }
  1064. $this->logger->addInfo('------End Summary------');
  1065. }
  1066. if ($moveFile) {
  1067. $this->moveFile($file);
  1068. }
  1069. }
  1070. /**
  1071. * @param string $file
  1072. * @param bool $moveFile
  1073. * @param array $teacherBackup
  1074. * @param array $groupBackup
  1075. */
  1076. private function importCourses(
  1077. $file,
  1078. $moveFile = true,
  1079. &$teacherBackup = array(),
  1080. &$groupBackup = array()
  1081. ) {
  1082. $this->fixCSVFile($file);
  1083. $data = Import::csvToArray($file);
  1084. if (!empty($data)) {
  1085. $this->logger->addInfo(count($data)." records found.");
  1086. foreach ($data as $row) {
  1087. $row = $this->cleanCourseRow($row);
  1088. $courseId = CourseManager::get_course_id_from_original_id(
  1089. $row['extra_'.$this->extraFieldIdNameList['course']],
  1090. $this->extraFieldIdNameList['course']
  1091. );
  1092. $courseInfo = api_get_course_info_by_id($courseId);
  1093. if (empty($courseInfo)) {
  1094. // Create
  1095. $params = array();
  1096. $params['title'] = $row['title'];
  1097. $params['exemplary_content'] = false;
  1098. $params['wanted_code'] = $row['course_code'];
  1099. $params['course_category'] = $row['course_category'];
  1100. $params['course_language'] = $row['language'];
  1101. $params['teachers'] = $row['teachers'];
  1102. $courseInfo = CourseManager::create_course(
  1103. $params,
  1104. $this->defaultAdminId
  1105. );
  1106. if (!empty($courseInfo)) {
  1107. CourseManager::update_course_extra_field_value(
  1108. $courseInfo['code'],
  1109. 'external_course_id',
  1110. $row['extra_'.$this->extraFieldIdNameList['course']]
  1111. );
  1112. $this->logger->addInfo("Courses - Course created ".$courseInfo['code']);
  1113. } else {
  1114. $this->logger->addError("Courses - Can't create course:".$row['title']);
  1115. }
  1116. } else {
  1117. // Update
  1118. $params = array(
  1119. 'title' => $row['title'],
  1120. 'category_code' => $row['course_category']
  1121. );
  1122. $result = CourseManager::update_attributes(
  1123. $courseInfo['real_id'],
  1124. $params
  1125. );
  1126. $addTeacherToSession = isset($courseInfo['add_teachers_to_sessions_courses']) && !empty($courseInfo['add_teachers_to_sessions_courses']) ? true : false;
  1127. $teachers = $row['teachers'];
  1128. if (!is_array($teachers)) {
  1129. $teachers = array($teachers);
  1130. }
  1131. if ($addTeacherToSession) {
  1132. CourseManager::updateTeachers(
  1133. $courseInfo,
  1134. $row['teachers'],
  1135. false,
  1136. true,
  1137. false,
  1138. $teacherBackup,
  1139. $this->logger
  1140. );
  1141. } else {
  1142. CourseManager::updateTeachers(
  1143. $courseInfo,
  1144. $row['teachers'],
  1145. false,
  1146. false,
  1147. false,
  1148. $teacherBackup,
  1149. $this->logger
  1150. );
  1151. }
  1152. foreach ($teachers as $teacherId) {
  1153. if (isset($groupBackup['tutor'][$teacherId]) &&
  1154. isset($groupBackup['tutor'][$teacherId][$courseInfo['code']])
  1155. ) {
  1156. foreach ($groupBackup['tutor'][$teacherId][$courseInfo['code']] as $data) {
  1157. GroupManager::subscribe_tutors(
  1158. array($teacherId),
  1159. $data['group_id'],
  1160. $data['c_id']
  1161. );
  1162. }
  1163. }
  1164. if (isset($groupBackup['user'][$teacherId]) &&
  1165. isset($groupBackup['user'][$teacherId][$courseInfo['code']]) &&
  1166. !empty($groupBackup['user'][$teacherId][$courseInfo['code']])
  1167. ) {
  1168. foreach ($groupBackup['user'][$teacherId][$courseInfo['code']] as $data) {
  1169. GroupManager::subscribe_users(
  1170. array($teacherId),
  1171. $data['group_id'],
  1172. $data['c_id']
  1173. );
  1174. }
  1175. }
  1176. }
  1177. if ($result) {
  1178. $this->logger->addInfo("Courses - Course updated ".$courseInfo['code']);
  1179. } else {
  1180. $this->logger->addError("Courses - Course NOT updated ".$courseInfo['code']);
  1181. }
  1182. }
  1183. }
  1184. }
  1185. if ($moveFile) {
  1186. $this->moveFile($file);
  1187. }
  1188. }
  1189. /**
  1190. * Parse filename: encora_subsessionsextid-static_31082016.csv
  1191. * @param string $file
  1192. */
  1193. private function importSubscribeUserToCourseSessionExtStatic($file, $moveFile = true)
  1194. {
  1195. $data = Import::csv_reader($file);
  1196. if (!empty($data)) {
  1197. $this->logger->addInfo(count($data)." records found.");
  1198. $userIdList = [];
  1199. foreach ($data as $row) {
  1200. $chamiloUserName = $row['UserName'];
  1201. $chamiloCourseCode = $row['CourseCode'];
  1202. $externalSessionId = $row['ExtSessionID'];
  1203. $status = $row['Status'];
  1204. $chamiloSessionId = null;
  1205. if (!empty($externalSessionId)) {
  1206. $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
  1207. $externalSessionId,
  1208. $this->extraFieldIdNameList['session']
  1209. );
  1210. }
  1211. $sessionInfo = api_get_session_info($chamiloSessionId);
  1212. if (empty($sessionInfo)) {
  1213. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1214. continue;
  1215. }
  1216. $courseInfo = api_get_course_info($chamiloCourseCode);
  1217. if (empty($courseInfo)) {
  1218. $this->logger->addError('Course does not exists: '.$courseInfo);
  1219. continue;
  1220. }
  1221. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  1222. if (empty($userId)) {
  1223. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1224. continue;
  1225. }
  1226. switch ($status) {
  1227. case 'student':
  1228. SessionManager::subscribe_users_to_session_course(
  1229. array($userId),
  1230. $chamiloSessionId,
  1231. $courseInfo['code']
  1232. );
  1233. break;
  1234. case 'teacher':
  1235. SessionManager::set_coach_to_course_session(
  1236. $userId,
  1237. $chamiloSessionId,
  1238. $courseInfo['code']
  1239. );
  1240. break;
  1241. case 'drh':
  1242. $removeAllSessionsFromUser = true;
  1243. if (in_array($userId, $userIdList)) {
  1244. $removeAllSessionsFromUser = false;
  1245. } else {
  1246. $userIdList[] = $userId;
  1247. }
  1248. $userInfo = api_get_user_info($userId);
  1249. SessionManager::subscribeSessionsToDrh(
  1250. $userInfo,
  1251. [$chamiloSessionId],
  1252. false,
  1253. $removeAllSessionsFromUser
  1254. );
  1255. break;
  1256. }
  1257. $this->logger->addError(
  1258. "User '$chamiloUserName' was added as '$status' to Session: #$chamiloSessionId - Course: ".$courseInfo['code']
  1259. );
  1260. }
  1261. }
  1262. if ($moveFile) {
  1263. $this->moveFile($file);
  1264. }
  1265. }
  1266. /**
  1267. * @param $file
  1268. * @param bool $moveFile
  1269. */
  1270. private function importUnsubSessionsExtIdStatic($file, $moveFile = true)
  1271. {
  1272. $data = Import::csv_reader($file);
  1273. if (!empty($data)) {
  1274. $this->logger->addInfo(count($data)." records found.");
  1275. foreach ($data as $row) {
  1276. $chamiloUserName = $row['UserName'];
  1277. $chamiloCourseCode = $row['CourseCode'];
  1278. $externalSessionId = $row['ExtSessionID'];
  1279. $dateStop = $row['DateStop'];
  1280. $chamiloSessionId = null;
  1281. if (!empty($externalSessionId)) {
  1282. $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
  1283. $externalSessionId,
  1284. $this->extraFieldIdNameList['session']
  1285. );
  1286. }
  1287. $sessionInfo = api_get_session_info($chamiloSessionId);
  1288. if (empty($sessionInfo)) {
  1289. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1290. continue;
  1291. }
  1292. $courseInfo = api_get_course_info($chamiloCourseCode);
  1293. if (empty($courseInfo)) {
  1294. $this->logger->addError('Course does not exists: '.$courseInfo);
  1295. continue;
  1296. }
  1297. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  1298. if (empty($userId)) {
  1299. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1300. continue;
  1301. }
  1302. SessionManager::removeUsersFromCourseSession(
  1303. array($userId),
  1304. $chamiloSessionId,
  1305. $courseInfo
  1306. );
  1307. $this->logger->addError(
  1308. "User '$chamiloUserName' was remove from Session: #$chamiloSessionId - Course: " . $courseInfo['code']
  1309. );
  1310. }
  1311. }
  1312. if ($moveFile) {
  1313. $this->moveFile($file);
  1314. }
  1315. }
  1316. /**
  1317. *
  1318. * @param string $file
  1319. */
  1320. private function importSessionsExtIdStatic($file, $moveFile = true)
  1321. {
  1322. $data = Import::csv_reader($file);
  1323. if (!empty($data)) {
  1324. $this->logger->addInfo(count($data)." records found.");
  1325. foreach ($data as $row) {
  1326. $chamiloUserName = $row['UserName'];
  1327. $chamiloCourseCode = $row['CourseCode'];
  1328. $externalSessionId = $row['ExtSessionID'];
  1329. $type = $row['Type'];
  1330. $chamiloSessionId = null;
  1331. if (!empty($externalSessionId)) {
  1332. $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
  1333. $externalSessionId,
  1334. $this->extraFieldIdNameList['session']
  1335. );
  1336. }
  1337. $sessionInfo = api_get_session_info($chamiloSessionId);
  1338. if (empty($sessionInfo)) {
  1339. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1340. continue;
  1341. }
  1342. $courseInfo = api_get_course_info($chamiloCourseCode);
  1343. if (empty($courseInfo)) {
  1344. $this->logger->addError('Course does not exists: '.$courseInfo);
  1345. continue;
  1346. }
  1347. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  1348. if (empty($userId)) {
  1349. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1350. continue;
  1351. }
  1352. switch ($type) {
  1353. case 'student':
  1354. SessionManager::subscribe_users_to_session_course(
  1355. array($userId),
  1356. $chamiloSessionId,
  1357. $courseInfo['code'],
  1358. null,
  1359. false
  1360. );
  1361. break;
  1362. case 'teacher':
  1363. SessionManager::set_coach_to_course_session(
  1364. $userId,
  1365. $chamiloSessionId,
  1366. $courseInfo['code']
  1367. );
  1368. break;
  1369. }
  1370. $this->logger->addError(
  1371. "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: " . $courseInfo['code']
  1372. );
  1373. }
  1374. }
  1375. if ($moveFile) {
  1376. $this->moveFile($file);
  1377. }
  1378. }
  1379. /**
  1380. * Updates the session synchronize with the csv file.
  1381. * @param bool $moveFile
  1382. * @param string $file
  1383. */
  1384. private function importSessionsStatic($file, $moveFile = true)
  1385. {
  1386. $content = file($file);
  1387. $sessions = array();
  1388. $tag_names = array();
  1389. foreach ($content as $key => $enreg) {
  1390. $enreg = explode(';', trim($enreg));
  1391. if ($key) {
  1392. foreach ($tag_names as $tag_key => $tag_name) {
  1393. if (isset($enreg[$tag_key])) {
  1394. $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
  1395. }
  1396. }
  1397. } else {
  1398. foreach ($enreg as $tag_name) {
  1399. $tag_names[] = api_preg_replace(
  1400. '/[^a-zA-Z0-9_\-]/',
  1401. '',
  1402. $tag_name
  1403. );
  1404. }
  1405. if (!in_array('SessionName', $tag_names) ||
  1406. !in_array('DateStart',$tag_names) || !in_array('DateEnd', $tag_names)
  1407. ) {
  1408. $error_message = get_lang('NoNeededData');
  1409. break;
  1410. }
  1411. }
  1412. }
  1413. if (!empty($sessions)) {
  1414. // Looping the sessions.
  1415. foreach ($sessions as $session) {
  1416. if (!empty($session['SessionID'])) {
  1417. $sessionId = SessionManager::getSessionIdFromOriginalId(
  1418. $session['SessionID'],
  1419. $this->extraFieldIdNameList['session']
  1420. );
  1421. $coachUserName = isset($session['Coach']) ? $session['Coach'] : null;
  1422. $categoryId = isset($session['category_id']) ? $session['category_id'] : null;
  1423. // 2014-06-30
  1424. $dateStart = explode('/', $session['DateStart']);
  1425. $dateEnd = explode('/', $session['DateEnd']);
  1426. $visibility = $this->defaultSessionVisibility;
  1427. $coachId = null;
  1428. if (!empty($coachUserName)) {
  1429. $coachInfo = api_get_user_info_from_username($coachUserName);
  1430. $coachId = $coachInfo['user_id'];
  1431. }
  1432. $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
  1433. $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
  1434. $date = new \DateTime($dateStart);
  1435. $interval = new DateInterval('P'.$this->daysCoachAccessBeforeBeginning.'D');
  1436. $date->sub($interval);
  1437. $coachBefore = $date->format('Y-m-d h:i');
  1438. $date = new \DateTime($dateEnd);
  1439. $interval = new DateInterval('P'.$this->daysCoachAccessAfterBeginning.'D');
  1440. $date->add($interval);
  1441. $coachAfter = $date->format('Y-m-d h:i');
  1442. /*$dateStart = api_get_utc_datetime($dateStart);
  1443. $dateEnd = api_get_utc_datetime($dateEnd);
  1444. $coachBefore = api_get_utc_datetime($coachBefore);
  1445. $coachAfter = api_get_utc_datetime($coachAfter);*/
  1446. if (empty($sessionId)) {
  1447. $result = SessionManager::create_session(
  1448. $session['SessionName'],
  1449. $dateStart,
  1450. $dateEnd,
  1451. $dateStart,
  1452. $dateEnd,
  1453. $coachBefore,
  1454. $coachAfter,
  1455. $coachId,
  1456. $categoryId,
  1457. $visibility
  1458. );
  1459. if (is_numeric($result)) {
  1460. $sessionId = $result;
  1461. $this->logger->addInfo("Session #$sessionId created: ".$session['SessionName']);
  1462. SessionManager::update_session_extra_field_value(
  1463. $sessionId,
  1464. $this->extraFieldIdNameList['session'],
  1465. $session['SessionID']
  1466. );
  1467. } else {
  1468. $this->logger->addInfo("Failed creating session: ".$session['SessionName']);
  1469. }
  1470. } else {
  1471. $sessionInfo = api_get_session_info($sessionId);
  1472. $accessBefore = null;
  1473. $accessAfter = null;
  1474. if (empty($sessionInfo['nb_days_access_before_beginning']) ||
  1475. (!empty($sessionInfo['nb_days_access_before_beginning']) &&
  1476. $sessionInfo['nb_days_access_before_beginning'] < $this->daysCoachAccessBeforeBeginning)
  1477. ) {
  1478. $accessBefore = $coachBefore;
  1479. }
  1480. $accessAfter = null;
  1481. if (empty($sessionInfo['nb_days_access_after_end']) ||
  1482. (!empty($sessionInfo['nb_days_access_after_end']) &&
  1483. $sessionInfo['nb_days_access_after_end'] < $this->daysCoachAccessAfterBeginning)
  1484. ) {
  1485. $accessAfter = $coachAfter;
  1486. }
  1487. $showDescription = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : 1;
  1488. $result = SessionManager::edit_session(
  1489. $sessionId,
  1490. $session['SessionName'],
  1491. $dateStart,
  1492. $dateEnd,
  1493. $dateStart,
  1494. $dateEnd,
  1495. $accessBefore,
  1496. $accessAfter,
  1497. $coachId,
  1498. $categoryId,
  1499. $visibility,
  1500. null, //$description = null,
  1501. $showDescription
  1502. );
  1503. if (is_numeric($result)) {
  1504. $this->logger->addInfo("Session #$sessionId updated: ".$session['SessionName']);
  1505. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1506. $params = array(
  1507. 'description' => $session['SessionDescription']
  1508. );
  1509. Database::update(
  1510. $tbl_session,
  1511. $params,
  1512. array('id = ?' => $sessionId)
  1513. );
  1514. }
  1515. }
  1516. if (!empty($sessionId)) {
  1517. // Courses
  1518. $courses = explode('|', $session['Courses']);
  1519. $courseList = [];
  1520. $courseListWithCoach = [];
  1521. foreach ($courses as $course) {
  1522. $courseArray = bracketsToArray($course);
  1523. $courseCode = $courseArray[0];
  1524. if (CourseManager::course_exists($courseCode)) {
  1525. $courseInfo = api_get_course_info($courseCode);
  1526. $courseList[] = $courseInfo['real_id'];
  1527. // Extracting course coaches
  1528. $courseCoaches = isset($courseArray[1]) ? $courseArray[1] : null;
  1529. $courseCoaches = explode(',', $courseCoaches);
  1530. // Extracting students
  1531. $courseUsers = isset($courseArray[2]) ? $courseArray[2] : null;
  1532. $courseUsers = explode(',', $courseUsers);
  1533. $courseListWithCoach[] = [
  1534. 'course_info' => $courseInfo,
  1535. 'coaches' => $courseCoaches,
  1536. 'course_users' => $courseUsers
  1537. ];
  1538. }
  1539. }
  1540. SessionManager::add_courses_to_session(
  1541. $sessionId,
  1542. $courseList,
  1543. true
  1544. );
  1545. $this->logger->addInfo("Session #$sessionId: Courses added: '".implode(', ', $courseList)."'");
  1546. if (empty($courseListWithCoach)) {
  1547. $this->logger->addInfo("No users/coaches to update");
  1548. continue;
  1549. }
  1550. foreach ($courseListWithCoach as $courseData) {
  1551. $courseInfo = $courseData['course_info'];
  1552. $courseCode = $courseInfo['code'];
  1553. $courseId = $courseInfo['real_id'];
  1554. $courseCoaches = $courseData['coaches'];
  1555. $courseUsers = $courseData['course_users'];
  1556. // Coaches
  1557. if (!empty($courseCoaches)) {
  1558. $coachList = array();
  1559. foreach ($courseCoaches as $courseCoach) {
  1560. $courseCoachId = UserManager::get_user_id_from_username(
  1561. $courseCoach
  1562. );
  1563. if ($courseCoachId !== false) {
  1564. // Just insert new coaches
  1565. $coachList[] = $courseCoachId;
  1566. }
  1567. }
  1568. $this->logger->addInfo("Session #$sessionId: course '$courseCode' coaches added: '".implode(', ', $coachList)."'");
  1569. SessionManager::updateCoaches(
  1570. $sessionId,
  1571. $courseId,
  1572. $coachList,
  1573. true
  1574. );
  1575. } else {
  1576. $this->logger->addInfo("No coaches added");
  1577. }
  1578. // Students
  1579. if (!empty($courseUsers)) {
  1580. $userList = array();
  1581. foreach ($courseUsers as $username) {
  1582. $userInfo = api_get_user_info_from_username(trim($username));
  1583. if (!empty($userInfo)) {
  1584. $userList[] = $userInfo['user_id'];
  1585. }
  1586. }
  1587. $this->logger->addInfo("Session #$sessionId: course '$courseCode': Students added '".implode(', ', $userList)."'");
  1588. SessionManager::subscribe_users_to_session_course(
  1589. $userList,
  1590. $sessionId,
  1591. $courseCode,
  1592. SESSION_VISIBLE_READ_ONLY,
  1593. true
  1594. );
  1595. } else {
  1596. $this->logger->addInfo("No users to register.");
  1597. }
  1598. }
  1599. } else {
  1600. $this->logger->addInfo(
  1601. 'SessionID not found in system.'
  1602. );
  1603. }
  1604. } else {
  1605. $this->logger->addInfo('SessionID does not exists');
  1606. }
  1607. }
  1608. } else {
  1609. $this->logger->addInfo($error_message);
  1610. }
  1611. if ($moveFile) {
  1612. $this->moveFile($file);
  1613. }
  1614. }
  1615. /**
  1616. * @param string $file
  1617. * @param bool $moveFile
  1618. * @param array $teacherBackup
  1619. * @param array $groupBackup
  1620. */
  1621. private function importSessions(
  1622. $file,
  1623. $moveFile = true,
  1624. &$teacherBackup = array(),
  1625. &$groupBackup = array()
  1626. ) {
  1627. $avoid = null;
  1628. if (isset($this->conditions['importSessions']) &&
  1629. isset($this->conditions['importSessions']['update'])
  1630. ) {
  1631. $avoid = $this->conditions['importSessions']['update'];
  1632. }
  1633. $result = SessionManager::importCSV(
  1634. $file,
  1635. true,
  1636. $this->defaultAdminId,
  1637. $this->logger,
  1638. array('SessionID' => 'extra_'.$this->extraFieldIdNameList['session']),
  1639. $this->extraFieldIdNameList['session'],
  1640. $this->daysCoachAccessBeforeBeginning,
  1641. $this->daysCoachAccessAfterBeginning,
  1642. $this->defaultSessionVisibility,
  1643. $avoid,
  1644. false, // deleteUsersNotInList
  1645. false, // updateCourseCoaches
  1646. true, // sessionWithCoursesModifier
  1647. true, //$addOriginalCourseTeachersAsCourseSessionCoaches
  1648. false, //$removeAllTeachersFromCourse
  1649. 1, // $showDescription,
  1650. $teacherBackup,
  1651. $groupBackup
  1652. );
  1653. if (!empty($result['error_message'])) {
  1654. $this->logger->addError($result['error_message']);
  1655. }
  1656. $this->logger->addInfo("Sessions - Sessions parsed: ".$result['session_counter']);
  1657. if ($moveFile) {
  1658. $this->moveFile($file);
  1659. }
  1660. }
  1661. /**
  1662. * @param string $file
  1663. * @param bool $moveFile
  1664. */
  1665. private function importSubscribeStatic($file, $moveFile = true)
  1666. {
  1667. $data = Import::csv_reader($file);
  1668. if (!empty($data)) {
  1669. $this->logger->addInfo(count($data) . " records found.");
  1670. foreach ($data as $row) {
  1671. $chamiloUserName = $row['UserName'];
  1672. $chamiloCourseCode = $row['CourseCode'];
  1673. $chamiloSessionId = $row['SessionID'];
  1674. $type = $row['Type'];
  1675. $sessionInfo = api_get_session_info($chamiloSessionId);
  1676. if (empty($sessionInfo)) {
  1677. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1678. continue;
  1679. }
  1680. $courseInfo = api_get_course_info($chamiloCourseCode);
  1681. if (empty($courseInfo)) {
  1682. $this->logger->addError('Course does not exists: '.$courseInfo);
  1683. continue;
  1684. }
  1685. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  1686. if (empty($userId)) {
  1687. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1688. continue;
  1689. }
  1690. switch ($type) {
  1691. case 'student':
  1692. SessionManager::subscribe_users_to_session_course(
  1693. array($userId),
  1694. $chamiloSessionId,
  1695. $courseInfo['code'],
  1696. null,
  1697. false
  1698. );
  1699. break;
  1700. case 'teacher':
  1701. SessionManager::set_coach_to_course_session(
  1702. $userId,
  1703. $chamiloSessionId,
  1704. $courseInfo['real_id']
  1705. );
  1706. break;
  1707. }
  1708. $this->logger->addError(
  1709. "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: " . $courseInfo['code']
  1710. );
  1711. }
  1712. }
  1713. if ($moveFile) {
  1714. $this->moveFile($file);
  1715. }
  1716. }
  1717. /**
  1718. * @param $file
  1719. * @param bool $moveFile
  1720. */
  1721. private function importSubscribeUserToCourse($file, $moveFile = false, &$teacherBackup = [])
  1722. {
  1723. $data = Import::csv_reader($file);
  1724. if (!empty($data)) {
  1725. $this->logger->addInfo(count($data) . " records found.");
  1726. foreach ($data as $row) {
  1727. $chamiloUserName = $row['UserName'];
  1728. $chamiloCourseCode = $row['CourseCode'];
  1729. $status = $row['Status'];
  1730. $courseInfo = api_get_course_info($chamiloCourseCode);
  1731. if (empty($courseInfo)) {
  1732. $this->logger->addError(
  1733. 'Course does not exists: '.$chamiloCourseCode
  1734. );
  1735. continue;
  1736. }
  1737. $userId = UserManager::get_user_id_from_username(
  1738. $chamiloUserName
  1739. );
  1740. if (empty($userId)) {
  1741. $this->logger->addError(
  1742. 'User does not exists: '.$chamiloUserName
  1743. );
  1744. continue;
  1745. }
  1746. $userCourseCategory = '';
  1747. if (isset($teacherBackup[$userId]) &&
  1748. isset($teacherBackup[$userId][$courseInfo['code']])
  1749. ) {
  1750. $courseUserData = $teacherBackup[$userId][$courseInfo['code']];
  1751. $userCourseCategory = $courseUserData['user_course_cat'];
  1752. }
  1753. CourseManager::subscribe_user(
  1754. $userId,
  1755. $courseInfo['code'],
  1756. $status,
  1757. 0,
  1758. $userCourseCategory
  1759. );
  1760. $this->logger->addInfo(
  1761. "User $userId added to course ".$courseInfo['code']." with status '$status' with course category: '$userCourseCategory'"
  1762. );
  1763. }
  1764. }
  1765. if ($moveFile) {
  1766. $this->moveFile($file);
  1767. }
  1768. }
  1769. /**
  1770. * @param string $file
  1771. * @param bool $moveFile
  1772. * @param array $teacherBackup
  1773. * @param array $groupBackup
  1774. */
  1775. private function importUnsubscribeStatic(
  1776. $file,
  1777. $moveFile = false,
  1778. &$teacherBackup = array(),
  1779. &$groupBackup = array()
  1780. ) {
  1781. $data = Import::csv_reader($file);
  1782. if (!empty($data)) {
  1783. $this->logger->addInfo(count($data)." records found.");
  1784. foreach ($data as $row) {
  1785. $chamiloUserName = $row['UserName'];
  1786. $chamiloCourseCode = $row['CourseCode'];
  1787. $chamiloSessionId = $row['SessionID'];
  1788. $sessionInfo = api_get_session_info($chamiloSessionId);
  1789. if (empty($sessionInfo)) {
  1790. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1791. continue;
  1792. }
  1793. $courseInfo = api_get_course_info($chamiloCourseCode);
  1794. if (empty($courseInfo)) {
  1795. $this->logger->addError('Course does not exists: '.$courseInfo);
  1796. continue;
  1797. }
  1798. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  1799. if (empty($userId)) {
  1800. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1801. continue;
  1802. }
  1803. $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
  1804. WHERE
  1805. user_id = ".$userId." AND
  1806. c_id = '".$courseInfo['real_id']."'
  1807. ";
  1808. $result = Database::query($sql);
  1809. $rows = Database::num_rows($result);
  1810. if ($rows > 0) {
  1811. $userCourseData = Database::fetch_array($result, 'ASSOC');
  1812. if (!empty($userCourseData)) {
  1813. $teacherBackup[$userId][$courseInfo['code']] = $userCourseData;
  1814. }
  1815. }
  1816. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
  1817. WHERE
  1818. user_id = ".$userId." AND
  1819. c_id = '".$courseInfo['real_id']."'
  1820. ";
  1821. $result = Database::query($sql);
  1822. while ($groupData = Database::fetch_array($result, 'ASSOC')) {
  1823. $groupBackup['user'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
  1824. }
  1825. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
  1826. WHERE
  1827. user_id = ".$userId." AND
  1828. c_id = '".$courseInfo['real_id']."'
  1829. ";
  1830. $result = Database::query($sql);
  1831. while ($groupData = Database::fetch_array($result, 'ASSOC')) {
  1832. $groupBackup['tutor'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
  1833. }
  1834. CourseManager::unsubscribe_user(
  1835. $userId,
  1836. $courseInfo['code'],
  1837. $chamiloSessionId
  1838. );
  1839. $this->logger->addError(
  1840. "User '$chamiloUserName' was removed from session: #$chamiloSessionId, Course: ".$courseInfo['code']
  1841. );
  1842. }
  1843. }
  1844. if ($moveFile) {
  1845. $this->moveFile($file);
  1846. }
  1847. }
  1848. /**
  1849. * Dump database tables
  1850. */
  1851. private function dumpDatabaseTables()
  1852. {
  1853. echo 'Dumping tables'.PHP_EOL;
  1854. // User
  1855. $table = Database::get_main_table(TABLE_MAIN_USER);
  1856. $tableAdmin = Database::get_main_table(TABLE_MAIN_ADMIN);
  1857. $sql = "DELETE FROM $table
  1858. WHERE user_id not in (select user_id from $tableAdmin) and status <> ".ANONYMOUS;
  1859. Database::query($sql);
  1860. echo $sql.PHP_EOL;
  1861. // Truncate tables
  1862. $truncateTables = array(
  1863. Database::get_main_table(TABLE_MAIN_COURSE),
  1864. Database::get_main_table(TABLE_MAIN_COURSE_USER),
  1865. Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE),
  1866. Database::get_main_table(TABLE_MAIN_CATEGORY),
  1867. Database::get_main_table(TABLE_MAIN_COURSE_MODULE),
  1868. Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER),
  1869. Database::get_main_table(TABLE_MAIN_SESSION),
  1870. Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY),
  1871. Database::get_main_table(TABLE_MAIN_SESSION_COURSE),
  1872. Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER),
  1873. Database::get_main_table(TABLE_MAIN_SESSION_USER),
  1874. Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION),
  1875. Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
  1876. Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
  1877. Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES),
  1878. Database::get_main_table(TABLE_MAIN_USER_FIELD),
  1879. Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS),
  1880. Database::get_main_table(TABLE_MAIN_COURSE_FIELD),
  1881. Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
  1882. Database::get_main_table(TABLE_MAIN_SESSION_FIELD),
  1883. Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
  1884. Database::get_course_table(TABLE_AGENDA),
  1885. Database::get_course_table(TABLE_AGENDA_ATTACHMENT),
  1886. Database::get_course_table(TABLE_AGENDA_REPEAT),
  1887. Database::get_course_table(TABLE_AGENDA_REPEAT_NOT),
  1888. Database::get_main_table(TABLE_PERSONAL_AGENDA),
  1889. Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT_NOT),
  1890. Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT),
  1891. Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_VALUES),
  1892. Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS),
  1893. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS),
  1894. Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN),
  1895. Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS),
  1896. Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES),
  1897. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT),
  1898. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING),
  1899. Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT),
  1900. Database::get_main_table(TABLE_STATISTIC_TRACK_E_UPLOADS),
  1901. Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT),
  1902. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY),
  1903. Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY),
  1904. Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION),
  1905. Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG),
  1906. Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT),
  1907. Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_LOG),
  1908. Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK),
  1909. Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY),
  1910. Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE),
  1911. Database::get_course_table(TABLE_STUDENT_PUBLICATION),
  1912. Database::get_course_table(TABLE_QUIZ_QUESTION),
  1913. Database::get_course_table(TABLE_QUIZ_TEST),
  1914. Database::get_course_table(TABLE_QUIZ_ORDER),
  1915. Database::get_course_table(TABLE_QUIZ_ANSWER),
  1916. Database::get_course_table(TABLE_QUIZ_TEST_QUESTION),
  1917. Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION),
  1918. Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY),
  1919. Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY),
  1920. Database::get_course_table(TABLE_LP_MAIN),
  1921. Database::get_course_table(TABLE_LP_ITEM),
  1922. Database::get_course_table(TABLE_LP_VIEW),
  1923. Database::get_course_table(TABLE_LP_ITEM_VIEW),
  1924. Database::get_course_table(TABLE_DOCUMENT),
  1925. Database::get_course_table(TABLE_ITEM_PROPERTY),
  1926. Database::get_course_table(TABLE_TOOL_LIST),
  1927. Database::get_course_table(TABLE_TOOL_INTRO),
  1928. Database::get_course_table(TABLE_COURSE_SETTING),
  1929. Database::get_course_table(TABLE_SURVEY),
  1930. Database::get_course_table(TABLE_SURVEY_QUESTION),
  1931. Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION),
  1932. Database::get_course_table(TABLE_SURVEY_INVITATION),
  1933. Database::get_course_table(TABLE_SURVEY_ANSWER),
  1934. Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP),
  1935. Database::get_course_table(TABLE_SURVEY_REPORT),
  1936. Database::get_course_table(TABLE_GLOSSARY),
  1937. Database::get_course_table(TABLE_LINK),
  1938. Database::get_course_table(TABLE_LINK_CATEGORY),
  1939. Database::get_course_table(TABLE_GROUP),
  1940. Database::get_course_table(TABLE_GROUP_USER),
  1941. Database::get_course_table(TABLE_GROUP_TUTOR),
  1942. Database::get_course_table(TABLE_GROUP_CATEGORY),
  1943. Database::get_course_table(TABLE_DROPBOX_CATEGORY),
  1944. Database::get_course_table(TABLE_DROPBOX_FEEDBACK),
  1945. Database::get_course_table(TABLE_DROPBOX_POST),
  1946. Database::get_course_table(TABLE_DROPBOX_FILE),
  1947. Database::get_course_table(TABLE_DROPBOX_PERSON)
  1948. );
  1949. foreach ($truncateTables as $table) {
  1950. $sql = "TRUNCATE $table";
  1951. Database::query($sql);
  1952. echo $sql.PHP_EOL;
  1953. }
  1954. $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
  1955. $sql = "DELETE FROM $table WHERE tool = 'calendar_event'";
  1956. Database::query($sql);
  1957. echo $sql.PHP_EOL;
  1958. }
  1959. /**
  1960. * If csv file ends with '"' character then a '";' is added
  1961. * @param string $file
  1962. */
  1963. private function fixCSVFile($file)
  1964. {
  1965. /*$f = fopen($file, 'r+');
  1966. $cursor = -1;
  1967. fseek($f, $cursor, SEEK_END);
  1968. $char = fgetc($f);
  1969. while ($char === "\n" || $char === "\r") {
  1970. fseek($f, $cursor--, SEEK_END);
  1971. $char = fgetc($f);
  1972. }
  1973. if ($char === "\"") {
  1974. fseek($f, -1, SEEK_CUR);
  1975. fwrite($f, '";');
  1976. }*/
  1977. }
  1978. }
  1979. use Monolog\Logger;
  1980. use Monolog\Handler\StreamHandler;
  1981. use Monolog\Handler\NativeMailerHandler;
  1982. use Monolog\Handler\RotatingFileHandler;
  1983. use Monolog\Handler\BufferHandler;
  1984. $logger = new Logger('cron');
  1985. $emails = isset($_configuration['cron_notification_mails']) ? $_configuration['cron_notification_mails'] : null;
  1986. $minLevel = Logger::DEBUG;
  1987. if (!is_array($emails)) {
  1988. $emails = array($emails);
  1989. }
  1990. $subject = "Cron main/cron/import_csv.php ".date('Y-m-d h:i:s');
  1991. $from = api_get_setting('emailAdministrator');
  1992. /*
  1993. if (!empty($emails)) {
  1994. foreach ($emails as $email) {
  1995. $stream = new NativeMailerHandler($email, $subject, $from, $minLevel);
  1996. $logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
  1997. }
  1998. }*/
  1999. $stream = new StreamHandler(
  2000. api_get_path(SYS_ARCHIVE_PATH).'import_csv.log',
  2001. $minLevel
  2002. );
  2003. $logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
  2004. $logger->pushHandler(new RotatingFileHandler('import_csv', 5, $minLevel));
  2005. $cronImportCSVConditions = isset($_configuration['cron_import_csv_conditions']) ? $_configuration['cron_import_csv_conditions'] : null;
  2006. echo 'See the error log here: '.api_get_path(SYS_ARCHIVE_PATH).'import_csv.log'."\n";
  2007. $import = new ImportCsv($logger, $cronImportCSVConditions);
  2008. if (isset($_configuration['default_admin_user_id_for_cron'])) {
  2009. $import->defaultAdminId = $_configuration['default_admin_user_id_for_cron'];
  2010. }
  2011. // @todo in production disable the dump option
  2012. $dump = false;
  2013. if (isset($argv[1]) && $argv[1] = '--dump') {
  2014. $dump = true;
  2015. }
  2016. if (isset($_configuration['import_csv_disable_dump']) &&
  2017. $_configuration['import_csv_disable_dump'] == true
  2018. ) {
  2019. $import->setDumpValues(false);
  2020. } else {
  2021. $import->setDumpValues($dump);
  2022. }
  2023. // Do not moves the files to treated
  2024. if (isset($_configuration['import_csv_test'])) {
  2025. $import->test = $_configuration['import_csv_test'];
  2026. } else {
  2027. $import->test = true;
  2028. }
  2029. $timeStart = microtime(true);
  2030. $import->run();
  2031. $timeEnd = microtime(true);
  2032. $executionTime = round(($timeEnd - $timeStart) / 60, 2);
  2033. $logger->addInfo("Total execution Time $executionTime Min");
  2034. if (isset($_configuration['import_csv_fix_permissions']) &&
  2035. $_configuration['import_csv_fix_permissions'] == true
  2036. ) {
  2037. $command = "sudo find ".api_get_path(SYS_COURSE_PATH)." -type d -exec chmod 777 {} \; ";
  2038. echo "Executing: ".$command.PHP_EOL;
  2039. system($command);
  2040. $command = "sudo find ".api_get_path(SYS_CODE_PATH)."upload/users -type d -exec chmod 777 {} \;";
  2041. echo "Executing: ".$command.PHP_EOL;
  2042. system($command);
  2043. }