import_csv.php 110 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CourseBundle\Entity\CCalendarEvent;
  4. use Chamilo\CourseBundle\Entity\CItemProperty;
  5. use Chamilo\PluginBundle\Entity\StudentFollowUp\CarePost;
  6. use Fhaculty\Graph\Graph;
  7. use Graphp\GraphViz\GraphViz;
  8. use Monolog\Logger;
  9. use Monolog\Handler\StreamHandler;
  10. use Monolog\Handler\NativeMailerHandler;
  11. use Monolog\Handler\RotatingFileHandler;
  12. use Monolog\Handler\BufferHandler;
  13. if (PHP_SAPI != 'cli') {
  14. die('Run this script through the command line or comment this line in the code');
  15. }
  16. if (file_exists('multiple_url_fix.php')) {
  17. require 'multiple_url_fix.php';
  18. }
  19. require_once __DIR__.'/../inc/global.inc.php';
  20. ini_set('memory_limit', -1);
  21. ini_set('max_execution_time', 0);
  22. ini_set('log_errors', '1');
  23. /**
  24. * Class ImportCsv
  25. */
  26. class ImportCsv
  27. {
  28. private $logger;
  29. private $dumpValues;
  30. public $test;
  31. public $defaultLanguage = 'dutch';
  32. public $extraFieldIdNameList = array(
  33. 'session' => 'external_session_id',
  34. 'session_career' => 'external_career_id',
  35. 'course' => 'external_course_id',
  36. 'user' => 'external_user_id',
  37. 'calendar_event' => 'external_calendar_event_id',
  38. 'career' => 'external_career_id',
  39. 'career_diagram' => 'career_diagram',
  40. );
  41. public $defaultAdminId = 1;
  42. public $defaultSessionVisibility = 1;
  43. /**
  44. * When creating a user the expiration date is set to registration date + this value
  45. * @var int number of years
  46. */
  47. public $expirationDateInUserCreation = 1;
  48. public $batchSize = 20;
  49. /**
  50. * When updating a user the expiration date is set to update date + this value
  51. * @var int number of years
  52. */
  53. public $expirationDateInUserUpdate = 1;
  54. public $daysCoachAccessBeforeBeginning = 14;
  55. public $daysCoachAccessAfterBeginning = 14;
  56. public $conditions;
  57. private $updateEmailToDummy;
  58. /**
  59. * @param Monolog\Logger $logger
  60. * @param array
  61. */
  62. public function __construct($logger, $conditions)
  63. {
  64. $this->logger = $logger;
  65. $this->conditions = $conditions;
  66. $this->updateEmailToDummy = false;
  67. }
  68. /**
  69. * @param bool $dump
  70. */
  71. public function setDumpValues($dump)
  72. {
  73. $this->dumpValues = $dump;
  74. }
  75. /**
  76. * @return boolean
  77. */
  78. public function getDumpValues()
  79. {
  80. return $this->dumpValues;
  81. }
  82. /**
  83. * Runs the import process
  84. */
  85. public function run()
  86. {
  87. global $_configuration;
  88. $value = api_get_configuration_value('import_csv_custom_url_id');
  89. if (!empty($value)) {
  90. $_configuration['access_url'] = $value;
  91. }
  92. $path = api_get_path(SYS_CODE_PATH).'cron/incoming/';
  93. if (!is_dir($path)) {
  94. echo "The folder! $path does not exits";
  95. return 0;
  96. }
  97. if ($this->getDumpValues()) {
  98. $this->dumpDatabaseTables();
  99. }
  100. echo "Reading files: ".PHP_EOL.PHP_EOL;
  101. $files = scandir($path);
  102. $fileToProcess = array();
  103. $fileToProcessStatic = array();
  104. $teacherBackup = array();
  105. $groupBackup = array();
  106. if (!empty($files)) {
  107. foreach ($files as $file) {
  108. $fileInfo = pathinfo($file);
  109. if (isset($fileInfo['extension']) && $fileInfo['extension'] === 'csv') {
  110. // Checking teachers_yyyymmdd.csv, courses_yyyymmdd.csv, students_yyyymmdd.csv and sessions_yyyymmdd.csv
  111. $parts = explode('_', $fileInfo['filename']);
  112. $preMethod = ucwords($parts[1]);
  113. $preMethod = str_replace('-static', 'Static', $preMethod);
  114. $method = 'import'.$preMethod;
  115. $isStatic = strpos($method, 'Static');
  116. if ($method == 'importSessionsextidStatic') {
  117. $method = 'importSessionsExtIdStatic';
  118. }
  119. if ($method == 'importCourseinsertStatic') {
  120. $method = 'importSubscribeUserToCourse';
  121. }
  122. if ($method == 'importUnsubsessionsextidStatic') {
  123. $method = 'importUnsubsessionsExtidStatic';
  124. }
  125. if ($method == 'importCareersdiagram') {
  126. $method = 'importCareersDiagram';
  127. }
  128. if ($method == 'importSubsessionsextidStatic') {
  129. $method = 'importSubscribeUserToCourseSessionExtStatic';
  130. }
  131. if (method_exists($this, $method)) {
  132. if ((
  133. $method == 'importSubscribeStatic' ||
  134. $method == 'importSubscribeUserToCourse'
  135. ) ||
  136. empty($isStatic)
  137. ) {
  138. $fileToProcess[$parts[1]][] = array(
  139. 'method' => $method,
  140. 'file' => $path.$fileInfo['basename']
  141. );
  142. } else {
  143. $fileToProcessStatic[$parts[1]][] = array(
  144. 'method' => $method,
  145. 'file' => $path.$fileInfo['basename']
  146. );
  147. }
  148. } else {
  149. echo "Error - This file '$file' can't be processed.".PHP_EOL;
  150. echo "Trying to call $method".PHP_EOL;
  151. echo "The file have to has this format:".PHP_EOL;
  152. echo "prefix_students_ddmmyyyy.csv, prefix_teachers_ddmmyyyy.csv, prefix_courses_ddmmyyyy.csv, prefix_sessions_ddmmyyyy.csv ".PHP_EOL;
  153. exit;
  154. }
  155. }
  156. }
  157. if (empty($fileToProcess) && empty($fileToProcessStatic)) {
  158. echo 'Error - no files to process.';
  159. return 0;
  160. }
  161. $this->prepareImport();
  162. $sections = array(
  163. 'students',
  164. 'teachers',
  165. 'courses',
  166. 'sessions',
  167. 'subscribe-static',
  168. 'courseinsert-static',
  169. 'unsubscribe-static',
  170. 'care',
  171. 'careers',
  172. 'careersdiagram'
  173. );
  174. foreach ($sections as $section) {
  175. $this->logger->addInfo("-- Import $section --");
  176. if (isset($fileToProcess[$section]) && !empty($fileToProcess[$section])) {
  177. $files = $fileToProcess[$section];
  178. foreach ($files as $fileInfo) {
  179. $method = $fileInfo['method'];
  180. $file = $fileInfo['file'];
  181. echo 'File: '.$file.PHP_EOL;
  182. echo 'Method : '.$method.PHP_EOL;
  183. echo PHP_EOL;
  184. $this->logger->addInfo("Reading file: $file");
  185. $this->logger->addInfo("Loading method $method ");
  186. if ($method == 'importSessions') {
  187. $this->$method(
  188. $file,
  189. true,
  190. $teacherBackup,
  191. $groupBackup
  192. );
  193. } else {
  194. $this->$method($file, true);
  195. }
  196. $this->logger->addInfo("--Finish reading file--");
  197. }
  198. }
  199. }
  200. $sections = array(
  201. 'students-static',
  202. 'teachers-static',
  203. 'courses-static',
  204. 'sessions-static',
  205. 'calendar-static',
  206. 'sessionsextid-static',
  207. 'unsubscribe-static',
  208. 'unsubsessionsextid-static',
  209. 'subsessionsextid-static'
  210. );
  211. foreach ($sections as $section) {
  212. $this->logger->addInfo("-- Import static files $section --");
  213. if (isset($fileToProcessStatic[$section]) &&
  214. !empty($fileToProcessStatic[$section])
  215. ) {
  216. $files = $fileToProcessStatic[$section];
  217. foreach ($files as $fileInfo) {
  218. $method = $fileInfo['method'];
  219. $file = $fileInfo['file'];
  220. echo 'Static file: '.$file.PHP_EOL;
  221. echo 'Method : '.$method.PHP_EOL;
  222. echo PHP_EOL;
  223. $this->logger->addInfo("Reading static file: $file");
  224. $this->logger->addInfo("Loading method $method ");
  225. $this->$method(
  226. $file,
  227. true,
  228. $teacherBackup,
  229. $groupBackup
  230. );
  231. $this->logger->addInfo("--Finish reading file--");
  232. }
  233. }
  234. }
  235. $this->logger->addInfo("teacher backup");
  236. $this->logger->addInfo(print_r($teacherBackup, 1));
  237. }
  238. }
  239. /**
  240. * Prepares extra fields before the import
  241. */
  242. private function prepareImport()
  243. {
  244. // Create user extra field: extra_external_user_id
  245. UserManager::create_extra_field(
  246. $this->extraFieldIdNameList['user'],
  247. 1,
  248. 'External user id',
  249. null
  250. );
  251. // Create course extra field: extra_external_course_id
  252. CourseManager::create_course_extra_field(
  253. $this->extraFieldIdNameList['course'],
  254. 1,
  255. 'External course id',
  256. ''
  257. );
  258. // Create session extra field extra_external_session_id
  259. SessionManager::create_session_extra_field(
  260. $this->extraFieldIdNameList['session'],
  261. 1,
  262. 'External session id'
  263. );
  264. SessionManager::create_session_extra_field(
  265. $this->extraFieldIdNameList['session_career'],
  266. 1,
  267. 'Career id'
  268. );
  269. // Create calendar_event extra field extra_external_session_id
  270. $extraField = new ExtraField('calendar_event');
  271. $extraField->save(
  272. array(
  273. 'field_type' => ExtraField::FIELD_TYPE_TEXT,
  274. 'variable' => $this->extraFieldIdNameList['calendar_event'],
  275. 'display_text' => 'External calendar event id',
  276. )
  277. );
  278. $extraField = new ExtraField('career');
  279. $extraField->save(
  280. array(
  281. 'visible_to_self' => 1,
  282. 'field_type' => ExtraField::FIELD_TYPE_TEXT,
  283. 'variable' => $this->extraFieldIdNameList['career'],
  284. 'display_text' => 'External career id',
  285. )
  286. );
  287. $extraField->save(
  288. array(
  289. 'visible_to_self' => 1,
  290. 'field_type' => ExtraField::FIELD_TYPE_TEXTAREA,
  291. 'variable' => $this->extraFieldIdNameList['career_diagram'],
  292. 'display_text' => 'Career diagram',
  293. )
  294. );
  295. }
  296. /**
  297. * @param string $file
  298. */
  299. private function moveFile($file)
  300. {
  301. $moved = str_replace('incoming', 'treated', $file);
  302. if ($this->test) {
  303. $result = 1;
  304. } else {
  305. $result = rename($file, $moved);
  306. }
  307. if ($result) {
  308. $this->logger->addInfo("Moving file to the treated folder: $file");
  309. } else {
  310. $this->logger->addError(
  311. "Error - Cant move file to the treated folder: $file"
  312. );
  313. }
  314. }
  315. /**
  316. * @param array $row
  317. *
  318. * @return array
  319. */
  320. private function cleanUserRow($row)
  321. {
  322. $row['lastname'] = $row['LastName'];
  323. $row['firstname'] = $row['FirstName'];
  324. $row['email'] = $row['Email'];
  325. $row['username'] = $row['UserName'];
  326. $row['password'] = $row['Password'];
  327. $row['auth_source'] = isset($row['AuthSource']) ? $row['AuthSource'] : PLATFORM_AUTH_SOURCE;
  328. $row['official_code'] = $row['OfficialCode'];
  329. $row['phone'] = isset($row['PhoneNumber']) ? $row['PhoneNumber'] : '';
  330. if (isset($row['StudentID'])) {
  331. $row['extra_'.$this->extraFieldIdNameList['user']] = $row['StudentID'];
  332. }
  333. if (isset($row['TeacherID'])) {
  334. $row['extra_'.$this->extraFieldIdNameList['user']] = $row['TeacherID'];
  335. }
  336. return $row;
  337. }
  338. /**
  339. * @param array $row
  340. *
  341. * @return array
  342. */
  343. private function cleanCourseRow($row)
  344. {
  345. $row['title'] = $row['Title'];
  346. $row['course_code'] = $row['Code'];
  347. $row['course_category'] = $row['CourseCategory'];
  348. $row['email'] = $row['Teacher'];
  349. $row['language'] = $row['Language'];
  350. $row['visibility'] = isset($row['Visibility']) ? $row['Visibility'] : COURSE_VISIBILITY_REGISTERED;
  351. $row['teachers'] = array();
  352. if (isset($row['Teacher']) && !empty($row['Teacher'])) {
  353. $this->logger->addInfo("Teacher list found: ".$row['Teacher']);
  354. $teachers = explode(',', $row['Teacher']);
  355. if (!empty($teachers)) {
  356. foreach ($teachers as $teacherUserName) {
  357. $teacherUserName = trim($teacherUserName);
  358. $userInfo = api_get_user_info_from_username($teacherUserName);
  359. if (!empty($userInfo)) {
  360. $this->logger->addInfo("Username found: $teacherUserName");
  361. $row['teachers'][] = $userInfo['user_id'];
  362. }
  363. }
  364. }
  365. }
  366. if (isset($row['CourseID'])) {
  367. $row['extra_'.$this->extraFieldIdNameList['course']] = $row['CourseID'];
  368. }
  369. return $row;
  370. }
  371. /**
  372. * File to import
  373. * @param string $file
  374. */
  375. private function importTeachersStatic($file)
  376. {
  377. $this->importTeachers($file, true);
  378. }
  379. /**
  380. * File to import
  381. * @param string $file
  382. * @param bool $moveFile
  383. */
  384. private function importTeachers($file, $moveFile = true)
  385. {
  386. $this->fixCSVFile($file);
  387. $data = Import::csvToArray($file);
  388. /* Unique identifier: official-code username.
  389. Email address and password should never get updated. *ok
  390. The only fields that I can think of that should update if the data changes in the csv file are FirstName and LastName. *ok
  391. A slight edit of these fields should be taken into account. ???
  392. Adding teachers is no problem, but deleting them shouldn’t be automated, but we should get a log of “to delete teachers”.
  393. We’ll handle that manually if applicable.
  394. No delete!
  395. */
  396. $language = $this->defaultLanguage;
  397. if (!empty($data)) {
  398. $this->logger->addInfo(count($data)." records found.");
  399. $expirationDateOnCreation = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserCreation)."years"));
  400. $expirationDateOnUpdate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserUpdate)."years"));
  401. $batchSize = $this->batchSize;
  402. $em = Database::getManager();
  403. $counter = 1;
  404. foreach ($data as $row) {
  405. $row = $this->cleanUserRow($row);
  406. $user_id = UserManager::get_user_id_from_original_id(
  407. $row['extra_'.$this->extraFieldIdNameList['user']],
  408. $this->extraFieldIdNameList['user']
  409. );
  410. $userInfo = array();
  411. $userInfoByOfficialCode = null;
  412. if (!empty($user_id)) {
  413. $userInfo = api_get_user_info($user_id);
  414. $userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
  415. }
  416. if (empty($userInfo) && empty($userInfoByOfficialCode)) {
  417. // Create user
  418. $userId = UserManager::create_user(
  419. $row['firstname'],
  420. $row['lastname'],
  421. COURSEMANAGER,
  422. $row['email'],
  423. $row['username'],
  424. $row['password'],
  425. $row['official_code'],
  426. $language, //$row['language'],
  427. $row['phone'],
  428. null, //$row['picture'], //picture
  429. $row['auth_source'], // ?
  430. $expirationDateOnCreation, //'0000-00-00 00:00:00', //$row['expiration_date'], //$expiration_date = '0000-00-00 00:00:00',
  431. 1, //active
  432. 0,
  433. null, // extra
  434. null, //$encrypt_method = '',
  435. false //$send_mail = false
  436. );
  437. if ($userId) {
  438. foreach ($row as $key => $value) {
  439. if (substr($key, 0, 6) == 'extra_') {
  440. //an extra field
  441. UserManager::update_extra_field_value(
  442. $userId,
  443. substr($key, 6),
  444. $value
  445. );
  446. }
  447. }
  448. $this->logger->addInfo("Teachers - User created: ".$row['username']);
  449. } else {
  450. $this->logger->addError("Teachers - User NOT created: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
  451. $this->logger->addError(strip_tags(Display::getFlashToString()));
  452. Display::cleanFlashMessages();
  453. }
  454. } else {
  455. if (empty($userInfo)) {
  456. $this->logger->addError("Teachers - Can't update user :".$row['username']);
  457. continue;
  458. }
  459. // Update user
  460. $result = UserManager::update_user(
  461. $userInfo['user_id'],
  462. $row['firstname'], // <<-- changed
  463. $row['lastname'], // <<-- changed
  464. $userInfo['username'],
  465. null, //$password = null,
  466. $row['auth_source'],
  467. $userInfo['email'],
  468. COURSEMANAGER,
  469. $userInfo['official_code'],
  470. $userInfo['phone'],
  471. $userInfo['picture_uri'],
  472. $expirationDateOnUpdate,
  473. $userInfo['active'],
  474. null, //$creator_id = null,
  475. 0, //$hr_dept_id = 0,
  476. null, // $extra = null,
  477. null, //$language = 'english',
  478. null, //$encrypt_method = '',
  479. false, //$send_email = false,
  480. 0 //$reset_password = 0
  481. );
  482. if ($result) {
  483. foreach ($row as $key => $value) {
  484. if (substr($key, 0, 6) == 'extra_') {
  485. //an extra field
  486. UserManager::update_extra_field_value(
  487. $userInfo['user_id'],
  488. substr($key, 6),
  489. $value
  490. );
  491. }
  492. }
  493. $this->logger->addInfo("Teachers - User updated: ".$row['username']);
  494. } else {
  495. $this->logger->addError("Teachers - User not updated: ".$row['username']);
  496. }
  497. }
  498. if (($counter % $batchSize) === 0) {
  499. $em->flush();
  500. $em->clear(); // Detaches all objects from Doctrine!
  501. }
  502. $counter++;
  503. }
  504. $em->clear(); // Detaches all objects from Doctrine!
  505. }
  506. if ($moveFile) {
  507. $this->moveFile($file);
  508. }
  509. $this->updateUsersEmails();
  510. }
  511. /**
  512. * @param string $file
  513. */
  514. private function importStudentsStatic($file)
  515. {
  516. $this->importStudents($file, true);
  517. }
  518. /**
  519. * @param string $file
  520. * @param bool $moveFile
  521. */
  522. private function importStudents($file, $moveFile = true)
  523. {
  524. $this->fixCSVFile($file);
  525. $data = Import::csvToArray($file);
  526. /*
  527. * Another users import.
  528. Unique identifier: official code and username . ok
  529. Password should never get updated. ok
  530. If an update should need to occur (because it changed in the .csv),
  531. we’ll want that logged. We will handle this manually in that case.
  532. All other fields should be updateable, though passwords should of course not get updated. ok
  533. If a user gets deleted (not there anymore),
  534. He should be set inactive one year after the current date.
  535. So I presume you’ll just update the expiration date.
  536. We want to grant access to courses up to a year after deletion.
  537. */
  538. $timeStart = microtime(true);
  539. $batchSize = $this->batchSize;
  540. $em = Database::getManager();
  541. if (!empty($data)) {
  542. $language = $this->defaultLanguage;
  543. $this->logger->addInfo(count($data)." records found.");
  544. $expirationDateOnCreate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserCreation)."years"));
  545. $expirationDateOnUpdate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserUpdate)."years"));
  546. $counter = 1;
  547. $secondsInYear = 365 * 24 * 60 * 60;
  548. foreach ($data as $row) {
  549. $row = $this->cleanUserRow($row);
  550. $user_id = UserManager::get_user_id_from_original_id(
  551. $row['extra_'.$this->extraFieldIdNameList['user']],
  552. $this->extraFieldIdNameList['user']
  553. );
  554. $userInfo = array();
  555. $userInfoByOfficialCode = null;
  556. if (!empty($user_id)) {
  557. $userInfo = api_get_user_info($user_id, false, true);
  558. $userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
  559. }
  560. if (empty($userInfo) && empty($userInfoByOfficialCode)) {
  561. // Create user
  562. $result = UserManager::create_user(
  563. $row['firstname'],
  564. $row['lastname'],
  565. STUDENT,
  566. $row['email'],
  567. $row['username'],
  568. $row['password'],
  569. $row['official_code'],
  570. $language, //$row['language'],
  571. $row['phone'],
  572. null, //$row['picture'], //picture
  573. $row['auth_source'], // ?
  574. $expirationDateOnCreate, //'0000-00-00 00:00:00', //$row['expiration_date'], //$expiration_date = '0000-00-00 00:00:00',
  575. 1, //active
  576. 0,
  577. null, // extra
  578. null, //$encrypt_method = '',
  579. false //$send_mail = false
  580. );
  581. if ($result) {
  582. foreach ($row as $key => $value) {
  583. if (substr($key, 0, 6) === 'extra_') {
  584. //an extra field
  585. UserManager::update_extra_field_value(
  586. $result,
  587. substr($key, 6),
  588. $value
  589. );
  590. }
  591. }
  592. $this->logger->addInfo("Students - User created: ".$row['username']);
  593. } else {
  594. $this->logger->addError("Students - User NOT created: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
  595. $this->logger->addError(strip_tags(Display::getFlashToString()));
  596. Display::cleanFlashMessages();
  597. }
  598. } else {
  599. if (empty($userInfo)) {
  600. $this->logger->addError("Students - Can't update user :".$row['username']);
  601. continue;
  602. }
  603. if (isset($row['action']) && $row['action'] === 'delete') {
  604. // Inactive one year later
  605. $userInfo['expiration_date'] = api_get_utc_datetime(api_strtotime(time() + $secondsInYear));
  606. }
  607. $password = $row['password']; // change password
  608. $email = $row['email']; // change email
  609. $resetPassword = 2; // allow password change
  610. // Conditions that disables the update of password and email:
  611. if (isset($this->conditions['importStudents'])) {
  612. if (isset($this->conditions['importStudents']['update']) &&
  613. isset($this->conditions['importStudents']['update']['avoid'])
  614. ) {
  615. // Blocking email update -
  616. // 1. Condition
  617. $avoidUsersWithEmail = $this->conditions['importStudents']['update']['avoid']['email'];
  618. if ($userInfo['email'] != $row['email'] && in_array($row['email'], $avoidUsersWithEmail)) {
  619. $this->logger->addInfo("Students - User email is not updated : ".$row['username']." because the avoid conditions (email).");
  620. // Do not change email keep the old email.
  621. $email = $userInfo['email'];
  622. }
  623. // 2. Condition
  624. if (!in_array($userInfo['email'], $avoidUsersWithEmail) && !in_array($row['email'], $avoidUsersWithEmail)) {
  625. $email = $userInfo['email'];
  626. }
  627. // 3. Condition
  628. if (in_array($userInfo['email'], $avoidUsersWithEmail) && !in_array($row['email'], $avoidUsersWithEmail)) {
  629. $email = $row['email'];
  630. }
  631. // Blocking password update
  632. //$avoidUsersWithPassword = $this->conditions['importStudents']['update']['avoid']['password'];
  633. /*if (isset($row['password'])) {
  634. $user = api_get_user_entity($userInfo['id']);
  635. $encoded = UserManager::encryptPassword(
  636. $row['password'],
  637. $user
  638. );
  639. if ($userInfo['password'] != $encoded &&
  640. in_array($row['password'], $avoidUsersWithPassword)
  641. ) {
  642. $this->logger->addInfo(
  643. "Students - User password is not updated: ".$row['username']." because the avoid conditions (password)."
  644. );
  645. $password = null;
  646. $resetPassword = 0; // disallow password change
  647. }
  648. }*/
  649. }
  650. }
  651. // Always disallow password change during update
  652. $password = null;
  653. $resetPassword = 0; // disallow password change
  654. // Update user
  655. $result = UserManager::update_user(
  656. $userInfo['user_id'],
  657. $row['firstname'], // <<-- changed
  658. $row['lastname'], // <<-- changed
  659. $row['username'], // <<-- changed
  660. $password, //$password = null,
  661. $row['auth_source'],
  662. $email,
  663. STUDENT,
  664. $userInfo['official_code'],
  665. $userInfo['phone'],
  666. $userInfo['picture_uri'],
  667. $expirationDateOnUpdate,
  668. $userInfo['active'],
  669. null, //$creator_id = null,
  670. 0, //$hr_dept_id = 0,
  671. null, // $extra = null,
  672. null, //$language = 'english',
  673. null, //$encrypt_method = '',
  674. false, //$send_email = false,
  675. $resetPassword //$reset_password = 0
  676. );
  677. if ($result) {
  678. if ($row['username'] != $userInfo['username']) {
  679. $this->logger->addInfo("Students - Username was changes from '".$userInfo['username']."' to '".$row['username']."' ");
  680. }
  681. foreach ($row as $key => $value) {
  682. if (substr($key, 0, 6) === 'extra_') {
  683. //an extra field
  684. UserManager::update_extra_field_value(
  685. $userInfo['user_id'],
  686. substr($key, 6),
  687. $value
  688. );
  689. }
  690. }
  691. $this->logger->addInfo("Students - User updated: ".$row['username']);
  692. } else {
  693. $this->logger->addError("Students - User NOT updated: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
  694. }
  695. }
  696. if (($counter % $batchSize) === 0) {
  697. $em->flush();
  698. $em->clear(); // Detaches all objects from Doctrine!
  699. $this->logger->addInfo("Detaches all objects");
  700. }
  701. $counter++;
  702. }
  703. $em->clear(); // Detaches all objects from Doctrine!
  704. }
  705. $timeEnd = microtime(true);
  706. $executionTime = round(($timeEnd - $timeStart) / 60, 2);
  707. $this->logger->addInfo("Execution Time for process students: $executionTime Min");
  708. if ($moveFile) {
  709. $this->moveFile($file);
  710. }
  711. $this->updateUsersEmails();
  712. }
  713. /**
  714. * @param string $file
  715. */
  716. private function importCoursesStatic($file, $moveFile, &$teacherBackup = array(), &$groupBackup = array())
  717. {
  718. $this->importCourses($file, true, $teacherBackup, $groupBackup);
  719. }
  720. /**
  721. * @param string $file
  722. * @param bool $moveFile
  723. *
  724. * @return int
  725. */
  726. private function importCalendarStatic($file, $moveFile = true)
  727. {
  728. $this->fixCSVFile($file);
  729. $this->updateUsersEmails();
  730. $data = Import::csvToArray($file);
  731. if (!empty($data)) {
  732. $this->logger->addInfo(count($data)." records found.");
  733. $eventsToCreate = array();
  734. $errorFound = false;
  735. foreach ($data as $row) {
  736. $sessionId = null;
  737. $externalSessionId = null;
  738. if (isset($row['external_sessionID'])) {
  739. $externalSessionId = $row['external_sessionID'];
  740. $sessionId = SessionManager::getSessionIdFromOriginalId(
  741. $externalSessionId,
  742. $this->extraFieldIdNameList['session']
  743. );
  744. }
  745. $courseCode = null;
  746. if (isset($row['coursecode'])) {
  747. $courseCode = $row['coursecode'];
  748. }
  749. $courseInfo = api_get_course_info($courseCode);
  750. if (empty($courseInfo)) {
  751. $this->logger->addInfo("Course '$courseCode' does not exists");
  752. }
  753. if (empty($sessionId)) {
  754. $this->logger->addInfo("external_sessionID: ".$externalSessionId." does not exists.");
  755. }
  756. $teacherId = null;
  757. if (!empty($sessionId) && !empty($courseInfo)) {
  758. $courseIncluded = SessionManager::relation_session_course_exist(
  759. $sessionId,
  760. $courseInfo['real_id']
  761. );
  762. if ($courseIncluded == false) {
  763. $this->logger->addInfo(
  764. "Course '$courseCode' is not included in session: $sessionId"
  765. );
  766. $errorFound = true;
  767. } else {
  768. $teachers = CourseManager::get_coach_list_from_course_code(
  769. $courseInfo['code'],
  770. $sessionId
  771. );
  772. // Getting first teacher.
  773. if (!empty($teachers)) {
  774. $teacher = current($teachers);
  775. $teacherId = $teacher['user_id'];
  776. } else {
  777. $sessionInfo = api_get_session_info($sessionId);
  778. $teacherId = $sessionInfo['id_coach'];
  779. }
  780. }
  781. } else {
  782. $errorFound = true;
  783. }
  784. if (empty($teacherId)) {
  785. $errorFound = true;
  786. $this->logger->addInfo(
  787. "No teacher found in course code : '$courseCode' and session: '$sessionId'"
  788. );
  789. }
  790. $date = $row['date'];
  791. $startTime = $row['time_start'];
  792. $endTime = $row['time_end'];
  793. $title = $row['title'];
  794. $comment = $row['comment'];
  795. $color = isset($row['color']) ? $row['color'] : '';
  796. $startDateYear = substr($date, 0, 4);
  797. $startDateMonth = substr($date, 4, 2);
  798. $startDateDay = substr($date, 6, 8);
  799. $startDate = $startDateYear.'-'.$startDateMonth.'-'.$startDateDay.' '.$startTime.":00";
  800. $endDate = $startDateYear.'-'.$startDateMonth.'-'.$startDateDay.' '.$endTime.":00";
  801. if (!api_is_valid_date($startDate) || !api_is_valid_date($endDate)) {
  802. $this->logger->addInfo(
  803. "Verify your dates: '$startDate' : '$endDate' "
  804. );
  805. $errorFound = true;
  806. }
  807. if ($errorFound == false) {
  808. $eventsToCreate[] = array(
  809. 'start' => $startDate,
  810. 'end' => $endDate,
  811. 'title' => $title,
  812. 'sender_id' => $teacherId,
  813. 'course_id' => $courseInfo['real_id'],
  814. 'session_id' => $sessionId,
  815. 'comment' => $comment,
  816. 'color' => $color,
  817. $this->extraFieldIdNameList['calendar_event'] => $row['external_calendar_itemID'],
  818. );
  819. }
  820. $errorFound = false;
  821. }
  822. if (empty($eventsToCreate)) {
  823. $this->logger->addInfo(
  824. "No events to add"
  825. );
  826. return 0;
  827. }
  828. $extraFieldValue = new ExtraFieldValue('calendar_event');
  829. $extraFieldName = $this->extraFieldIdNameList['calendar_event'];
  830. $externalEventId = null;
  831. $extraField = new ExtraField('calendar_event');
  832. $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
  833. $extraFieldName
  834. );
  835. if (empty($extraFieldInfo)) {
  836. $this->logger->addInfo(
  837. "No calendar event extra field created: $extraFieldName"
  838. );
  839. return 0;
  840. }
  841. $this->logger->addInfo('Ready to insert # '.count($eventsToCreate).' events');
  842. $batchSize = $this->batchSize;
  843. $counter = 1;
  844. $em = Database::getManager();
  845. $eventStartDateList = [];
  846. $eventEndDateList = [];
  847. $report = [
  848. 'mail_sent' => 0,
  849. 'mail_not_sent_announcement_exists' => 0,
  850. 'mail_not_sent_because_date' => 0
  851. ];
  852. $eventsToCreateFinal = [];
  853. foreach ($eventsToCreate as $event) {
  854. $update = false;
  855. $item = null;
  856. if (!isset($event[$extraFieldName])) {
  857. $this->logger->addInfo(
  858. "No external_calendar_itemID found. Skipping ..."
  859. );
  860. continue;
  861. } else {
  862. $externalEventId = $event[$extraFieldName];
  863. if (empty($externalEventId)) {
  864. $this->logger->addInfo(
  865. "external_calendar_itemID was set but empty. Skipping ..."
  866. );
  867. continue;
  868. }
  869. $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
  870. $extraFieldName,
  871. $externalEventId,
  872. false,
  873. false,
  874. false
  875. );
  876. if (!empty($item)) {
  877. $update = true;
  878. }
  879. }
  880. $courseInfo = api_get_course_info_by_id($event['course_id']);
  881. $event['course_info'] = $courseInfo;
  882. $event['update'] = $update;
  883. $event['item'] = $item;
  884. $calendarEvent = null;
  885. /* Check if event changed of course code */
  886. if (!empty($item) && isset($item['item_id']) && !empty($item['item_id'])) {
  887. /** @var CCalendarEvent $calendarEvent */
  888. $calendarEvent = $em->getRepository('ChamiloCourseBundle:CCalendarEvent')->find($item['item_id']);
  889. }
  890. if ($calendarEvent) {
  891. $this->logger->addInfo('Calendar event found '.$item['item_id']);
  892. if ($calendarEvent->getCId() != $courseInfo['real_id']) {
  893. $this->logger->addInfo('Move from course #'.$calendarEvent->getCId().' to #'.$courseInfo['real_id']);
  894. // Seems that the course id changed in the csv
  895. $calendarEvent->setCId($courseInfo['real_id']);
  896. $em->persist($calendarEvent);
  897. $em->flush();
  898. $criteria = [
  899. 'tool' => 'calendar_event',
  900. 'ref' => $item['item_id']
  901. ];
  902. /** @var CItemProperty $itemProperty */
  903. $itemProperty = $em->getRepository('ChamiloCourseBundle:CItemProperty')->findOneBy($criteria);
  904. $courseEntity = $em->getRepository('ChamiloCoreBundle:Course')->find($courseInfo['real_id']);
  905. if ($itemProperty && $courseEntity) {
  906. $itemProperty->setCourse($courseEntity);
  907. $em->persist($itemProperty);
  908. $em->flush();
  909. }
  910. }
  911. } else {
  912. $this->logger->addInfo('Calendar event not found '.$item['item_id']);
  913. }
  914. $event['external_event_id'] = $externalEventId;
  915. if (isset($eventStartDateList[$courseInfo['real_id']]) &&
  916. isset($eventStartDateList[$courseInfo['real_id']][$event['session_id']])
  917. ) {
  918. $currentItemDate = api_strtotime($event['start']);
  919. $firstDate = $eventStartDateList[$courseInfo['real_id']][$event['session_id']];
  920. if ($currentItemDate < api_strtotime($firstDate)) {
  921. $eventStartDateList[$courseInfo['real_id']][$event['session_id']] = $event['start'];
  922. $eventEndDateList[$courseInfo['real_id']][$event['session_id']] = $event['end'];
  923. }
  924. } else {
  925. // First time
  926. $eventStartDateList[$courseInfo['real_id']][$event['session_id']] = $event['start'];
  927. $eventEndDateList[$courseInfo['real_id']][$event['session_id']] = $event['end'];
  928. }
  929. $eventsToCreateFinal[] = $event;
  930. }
  931. $eventAlreadySent = [];
  932. foreach ($eventsToCreateFinal as $event) {
  933. $courseInfo = $event['course_info'];
  934. $item = $event['item'];
  935. $update = $event['update'];
  936. $externalEventId = $event['external_event_id'];
  937. $info = 'Course: '.$courseInfo['real_id'].' ('.$courseInfo['code'].') - Session: '.$event['session_id'];
  938. $agenda = new Agenda(
  939. 'course',
  940. $event['sender_id'],
  941. $courseInfo['real_id'],
  942. $event['session_id']
  943. );
  944. $agenda->set_course($courseInfo);
  945. $agenda->setSessionId($event['session_id']);
  946. $agenda->setSenderId($event['sender_id']);
  947. $agenda->setIsAllowedToEdit(true);
  948. $eventComment = $event['comment'];
  949. $color = $event['color'];
  950. // To use the event comment you need
  951. // ALTER TABLE c_calendar_event ADD COLUMN comment TEXT;
  952. // add in configuration.php allow_agenda_event_comment = true
  953. if (empty($courseInfo)) {
  954. $this->logger->addInfo(
  955. "No course found for event #$externalEventId Course #".$event['course_id']." Skipping ..."
  956. );
  957. continue;
  958. }
  959. if (empty($event['sender_id'])) {
  960. $this->logger->addInfo(
  961. "No sender found for event #$externalEventId Send #".$event['sender_id']." Skipping ..."
  962. );
  963. continue;
  964. }
  965. // Taking first element of course-session event
  966. $alreadyAdded = false;
  967. $firstDate = $eventStartDateList[$courseInfo['real_id']][$event['session_id']];
  968. $firstEndDate = $eventEndDateList[$courseInfo['real_id']][$event['session_id']];
  969. if (isset($eventAlreadySent[$courseInfo['real_id']]) &&
  970. isset($eventAlreadySent[$courseInfo['real_id']][$event['session_id']])
  971. ) {
  972. $alreadyAdded = true;
  973. } else {
  974. $eventAlreadySent[$courseInfo['real_id']][$event['session_id']] = true;
  975. }
  976. // Working days (Mon-Fri)see BT#12156#note-16
  977. $days = 5;
  978. $startDatePlusDays = api_strtotime("$days weekdays");
  979. $this->logger->addInfo(
  980. "startDatePlusDays: ".api_get_utc_datetime($startDatePlusDays).' - First date: '.$firstDate
  981. );
  982. // Send
  983. if ($startDatePlusDays > api_strtotime($firstDate)) {
  984. $sendMail = true;
  985. } else {
  986. $sendMail = false;
  987. }
  988. // Send announcement to users
  989. if ($sendMail && $alreadyAdded == false) {
  990. $start = $firstDate;
  991. $end = $firstEndDate;
  992. if (!empty($end) &&
  993. api_format_date($start, DATE_FORMAT_LONG) == api_format_date($end, DATE_FORMAT_LONG)
  994. ) {
  995. $date = api_format_date($start, DATE_FORMAT_LONG).' ('.
  996. api_format_date($start, TIME_NO_SEC_FORMAT).' '.
  997. api_format_date($end, TIME_NO_SEC_FORMAT).')';
  998. } else {
  999. $date = api_format_date($start, DATE_TIME_FORMAT_LONG_24H).' - '.
  1000. api_format_date($end, DATE_TIME_FORMAT_LONG_24H);
  1001. }
  1002. $sessionName = '';
  1003. if (!empty($event['session_id'])) {
  1004. $sessionName = ' ('.api_get_session_name($event['session_id']).')';
  1005. }
  1006. $courseTitle = $courseInfo['title'].$sessionName;
  1007. $emailBody = get_lang('Dear').' ((user_firstname)) <br />'.
  1008. sprintf(
  1009. get_lang('YouHaveBeenSubscribedToCourseXTheStartDateXAndCommentX'),
  1010. $courseTitle,
  1011. $date,
  1012. $event['comment']
  1013. );
  1014. $subject = sprintf(
  1015. get_lang('AgendaAvailableInCourseX'),
  1016. $courseInfo['title']
  1017. );
  1018. $coaches = SessionManager::getCoachesByCourseSession(
  1019. $courseInfo['real_id'],
  1020. $event['session_id']
  1021. );
  1022. // Search if an announcement exists:
  1023. $announcementsWithTitleList = AnnouncementManager::getAnnouncementsByTitle(
  1024. $subject,
  1025. $courseInfo['real_id'],
  1026. $event['session_id'],
  1027. 1
  1028. );
  1029. if (count($announcementsWithTitleList) === 0) {
  1030. $this->logger->addInfo(
  1031. "Mail to be sent because start date: ".$event['start']." and no announcement found."
  1032. );
  1033. $announcementId = AnnouncementManager::add_announcement(
  1034. $courseInfo,
  1035. $event['session_id'],
  1036. $subject,
  1037. $emailBody,
  1038. [
  1039. 'everyone',
  1040. 'users' => $coaches
  1041. ],
  1042. [],
  1043. null,
  1044. null,
  1045. false,
  1046. $this->defaultAdminId
  1047. );
  1048. if ($announcementId) {
  1049. $this->logger->addInfo(
  1050. "Announcement added: ".(int) ($announcementId)." in $info"
  1051. );
  1052. $this->logger->addInfo(
  1053. "<<--SENDING MAIL-->>"
  1054. );
  1055. $report['mail_sent']++;
  1056. AnnouncementManager::sendEmail(
  1057. $courseInfo,
  1058. $event['session_id'],
  1059. $announcementId,
  1060. false
  1061. );
  1062. }
  1063. } else {
  1064. $report['mail_not_sent_announcement_exists']++;
  1065. $this->logger->addInfo(
  1066. "Mail NOT sent. An announcement seems to be already saved in '$info'"
  1067. );
  1068. }
  1069. } else {
  1070. if ($sendMail == false) {
  1071. $report['mail_not_sent_because_date']++;
  1072. }
  1073. }
  1074. $content = '';
  1075. if ($update && isset($item['item_id'])) {
  1076. //the event already exists, just update
  1077. $eventResult = $agenda->editEvent(
  1078. $item['item_id'],
  1079. $event['start'],
  1080. $event['end'],
  1081. false,
  1082. $event['title'],
  1083. $content,
  1084. array('everyone'), // $usersToSend
  1085. array(), //$attachmentArray = array(),
  1086. [], //$attachmentCommentList
  1087. $eventComment,
  1088. $color,
  1089. false,
  1090. false,
  1091. $this->defaultAdminId
  1092. );
  1093. if ($eventResult !== false) {
  1094. $this->logger->addInfo(
  1095. "Event updated #".$item['item_id']." External cal Id: (".$externalEventId.") $info"
  1096. );
  1097. } else {
  1098. $this->logger->addInfo(
  1099. "Error while updating event with external id: $externalEventId"
  1100. );
  1101. }
  1102. } else {
  1103. // New event. Create it.
  1104. $eventId = $agenda->addEvent(
  1105. $event['start'],
  1106. $event['end'],
  1107. false,
  1108. $event['title'],
  1109. $content,
  1110. array('everyone'), // $usersToSend
  1111. false, //$addAsAnnouncement = false
  1112. null, // $parentEventId
  1113. array(), //$attachmentArray = array(),
  1114. [], //$attachmentCommentList
  1115. $eventComment,
  1116. $color
  1117. );
  1118. if (!empty($eventId)) {
  1119. $extraFieldValue->save(
  1120. array(
  1121. 'value' => $externalEventId,
  1122. 'field_id' => $extraFieldInfo['id'],
  1123. 'item_id' => $eventId
  1124. )
  1125. );
  1126. $this->logger->addInfo(
  1127. "Event added: #$eventId External cal id: (".$externalEventId.") $info"
  1128. );
  1129. } else {
  1130. $this->logger->addInfo(
  1131. "Error while creating event external id: $externalEventId"
  1132. );
  1133. }
  1134. }
  1135. if (($counter % $batchSize) === 0) {
  1136. $em->flush();
  1137. $em->clear(); // Detaches all objects from Doctrine!
  1138. }
  1139. $counter++;
  1140. }
  1141. $em->clear(); // Detaches all objects from Doctrine!
  1142. $this->logger->addInfo('------Summary------');
  1143. foreach ($report as $title => $count) {
  1144. $this->logger->addInfo("$title: $count");
  1145. }
  1146. $this->logger->addInfo('------End Summary------');
  1147. }
  1148. if ($moveFile) {
  1149. $this->moveFile($file);
  1150. }
  1151. }
  1152. /**
  1153. * @param string $file
  1154. * @param bool $moveFile
  1155. * @param array $teacherBackup
  1156. * @param array $groupBackup
  1157. */
  1158. private function importCourses(
  1159. $file,
  1160. $moveFile = true,
  1161. &$teacherBackup = array(),
  1162. &$groupBackup = array()
  1163. ) {
  1164. $this->fixCSVFile($file);
  1165. $data = Import::csvToArray($file);
  1166. if (!empty($data)) {
  1167. $this->logger->addInfo(count($data)." records found.");
  1168. foreach ($data as $row) {
  1169. $row = $this->cleanCourseRow($row);
  1170. $courseId = CourseManager::get_course_id_from_original_id(
  1171. $row['extra_'.$this->extraFieldIdNameList['course']],
  1172. $this->extraFieldIdNameList['course']
  1173. );
  1174. $courseInfo = api_get_course_info_by_id($courseId);
  1175. if (empty($courseInfo)) {
  1176. // Create
  1177. $params = array();
  1178. $params['title'] = $row['title'];
  1179. $params['exemplary_content'] = false;
  1180. $params['wanted_code'] = $row['course_code'];
  1181. $params['course_category'] = $row['course_category'];
  1182. $params['course_language'] = $row['language'];
  1183. $params['teachers'] = $row['teachers'];
  1184. $params['visibility'] = $row['visibility'];
  1185. $courseInfo = CourseManager::create_course(
  1186. $params,
  1187. $this->defaultAdminId
  1188. );
  1189. if (!empty($courseInfo)) {
  1190. CourseManager::update_course_extra_field_value(
  1191. $courseInfo['code'],
  1192. 'external_course_id',
  1193. $row['extra_'.$this->extraFieldIdNameList['course']]
  1194. );
  1195. $this->logger->addInfo("Courses - Course created ".$courseInfo['code']);
  1196. } else {
  1197. $this->logger->addError("Courses - Can't create course:".$row['title']);
  1198. }
  1199. } else {
  1200. // Update
  1201. $params = array(
  1202. 'title' => $row['title'],
  1203. 'category_code' => $row['course_category'],
  1204. 'visibility' => $row['visibility']
  1205. );
  1206. $result = CourseManager::update_attributes(
  1207. $courseInfo['real_id'],
  1208. $params
  1209. );
  1210. $addTeacherToSession = isset($courseInfo['add_teachers_to_sessions_courses']) && !empty($courseInfo['add_teachers_to_sessions_courses']) ? true : false;
  1211. $teachers = $row['teachers'];
  1212. if (!is_array($teachers)) {
  1213. $teachers = array($teachers);
  1214. }
  1215. if ($addTeacherToSession) {
  1216. $this->logger->addInfo("Add teacher to all course sessions");
  1217. CourseManager::updateTeachers(
  1218. $courseInfo,
  1219. $row['teachers'],
  1220. false,
  1221. true,
  1222. false,
  1223. $teacherBackup,
  1224. $this->logger
  1225. );
  1226. } else {
  1227. CourseManager::updateTeachers(
  1228. $courseInfo,
  1229. $row['teachers'],
  1230. true,
  1231. false,
  1232. false,
  1233. $teacherBackup,
  1234. $this->logger
  1235. );
  1236. }
  1237. foreach ($teachers as $teacherId) {
  1238. if (isset($groupBackup['tutor'][$teacherId]) &&
  1239. isset($groupBackup['tutor'][$teacherId][$courseInfo['code']])
  1240. ) {
  1241. foreach ($groupBackup['tutor'][$teacherId][$courseInfo['code']] as $data) {
  1242. $groupInfo = GroupManager::get_group_properties($data['group_id']);
  1243. GroupManager::subscribe_tutors(
  1244. array($teacherId),
  1245. $groupInfo,
  1246. $data['c_id']
  1247. );
  1248. }
  1249. }
  1250. if (isset($groupBackup['user'][$teacherId]) &&
  1251. isset($groupBackup['user'][$teacherId][$courseInfo['code']]) &&
  1252. !empty($groupBackup['user'][$teacherId][$courseInfo['code']])
  1253. ) {
  1254. foreach ($groupBackup['user'][$teacherId][$courseInfo['code']] as $data) {
  1255. $groupInfo = GroupManager::get_group_properties($data['group_id']);
  1256. GroupManager::subscribe_users(
  1257. array($teacherId),
  1258. $groupInfo,
  1259. $data['c_id']
  1260. );
  1261. }
  1262. }
  1263. }
  1264. if ($result) {
  1265. $this->logger->addInfo("Courses - Course updated ".$courseInfo['code']);
  1266. } else {
  1267. $this->logger->addError("Courses - Course NOT updated ".$courseInfo['code']);
  1268. }
  1269. }
  1270. }
  1271. }
  1272. if ($moveFile) {
  1273. $this->moveFile($file);
  1274. }
  1275. }
  1276. /**
  1277. * Parse filename: encora_subsessionsextid-static_31082016.csv
  1278. * @param string $file
  1279. */
  1280. private function importSubscribeUserToCourseSessionExtStatic($file, $moveFile = true)
  1281. {
  1282. $data = Import::csv_reader($file);
  1283. if (!empty($data)) {
  1284. $this->logger->addInfo(count($data)." records found.");
  1285. $userIdList = [];
  1286. foreach ($data as $row) {
  1287. $chamiloUserName = $row['UserName'];
  1288. $chamiloCourseCode = $row['CourseCode'];
  1289. $externalSessionId = $row['ExtSessionID'];
  1290. $status = $row['Status'];
  1291. $chamiloSessionId = null;
  1292. if (!empty($externalSessionId)) {
  1293. $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
  1294. $externalSessionId,
  1295. $this->extraFieldIdNameList['session']
  1296. );
  1297. }
  1298. $sessionInfo = api_get_session_info($chamiloSessionId);
  1299. if (empty($sessionInfo)) {
  1300. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1301. continue;
  1302. }
  1303. $courseInfo = api_get_course_info($chamiloCourseCode);
  1304. if (empty($courseInfo)) {
  1305. $this->logger->addError('Course does not exists: '.$courseInfo);
  1306. continue;
  1307. }
  1308. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  1309. if (empty($userId)) {
  1310. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1311. continue;
  1312. }
  1313. switch ($status) {
  1314. case 'student':
  1315. SessionManager::subscribe_users_to_session_course(
  1316. array($userId),
  1317. $chamiloSessionId,
  1318. $courseInfo['code']
  1319. );
  1320. break;
  1321. case 'teacher':
  1322. SessionManager::set_coach_to_course_session(
  1323. $userId,
  1324. $chamiloSessionId,
  1325. $courseInfo['code']
  1326. );
  1327. break;
  1328. case 'drh':
  1329. $removeAllSessionsFromUser = true;
  1330. if (in_array($userId, $userIdList)) {
  1331. $removeAllSessionsFromUser = false;
  1332. } else {
  1333. $userIdList[] = $userId;
  1334. }
  1335. $userInfo = api_get_user_info($userId);
  1336. SessionManager::subscribeSessionsToDrh(
  1337. $userInfo,
  1338. [$chamiloSessionId],
  1339. false,
  1340. $removeAllSessionsFromUser
  1341. );
  1342. break;
  1343. }
  1344. $this->logger->addError(
  1345. "User '$chamiloUserName' was added as '$status' to Session: #$chamiloSessionId - Course: ".$courseInfo['code']
  1346. );
  1347. }
  1348. }
  1349. if ($moveFile) {
  1350. $this->moveFile($file);
  1351. }
  1352. }
  1353. /**
  1354. * @param $file
  1355. * @param bool $moveFile
  1356. */
  1357. private function importUnsubSessionsExtIdStatic($file, $moveFile = true)
  1358. {
  1359. $data = Import::csv_reader($file);
  1360. if (!empty($data)) {
  1361. $this->logger->addInfo(count($data)." records found.");
  1362. foreach ($data as $row) {
  1363. $chamiloUserName = $row['UserName'];
  1364. $chamiloCourseCode = $row['CourseCode'];
  1365. $externalSessionId = $row['ExtSessionID'];
  1366. $dateStop = $row['DateStop'];
  1367. $chamiloSessionId = null;
  1368. if (!empty($externalSessionId)) {
  1369. $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
  1370. $externalSessionId,
  1371. $this->extraFieldIdNameList['session']
  1372. );
  1373. }
  1374. $sessionInfo = api_get_session_info($chamiloSessionId);
  1375. if (empty($sessionInfo)) {
  1376. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1377. continue;
  1378. }
  1379. $courseInfo = api_get_course_info($chamiloCourseCode);
  1380. if (empty($courseInfo)) {
  1381. $this->logger->addError('Course does not exists: '.$courseInfo);
  1382. continue;
  1383. }
  1384. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  1385. if (empty($userId)) {
  1386. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1387. continue;
  1388. }
  1389. SessionManager::removeUsersFromCourseSession(
  1390. array($userId),
  1391. $chamiloSessionId,
  1392. $courseInfo
  1393. );
  1394. $this->logger->addError(
  1395. "User '$chamiloUserName' was remove from Session: #$chamiloSessionId - Course: ".$courseInfo['code']
  1396. );
  1397. }
  1398. }
  1399. if ($moveFile) {
  1400. $this->moveFile($file);
  1401. }
  1402. }
  1403. /**
  1404. *
  1405. * @param string $file
  1406. */
  1407. private function importSessionsExtIdStatic($file, $moveFile = true)
  1408. {
  1409. $data = Import::csv_reader($file);
  1410. if (!empty($data)) {
  1411. $this->logger->addInfo(count($data)." records found.");
  1412. foreach ($data as $row) {
  1413. $chamiloUserName = $row['UserName'];
  1414. $chamiloCourseCode = $row['CourseCode'];
  1415. $externalSessionId = $row['ExtSessionID'];
  1416. $type = $row['Type'];
  1417. $chamiloSessionId = null;
  1418. if (!empty($externalSessionId)) {
  1419. $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
  1420. $externalSessionId,
  1421. $this->extraFieldIdNameList['session']
  1422. );
  1423. }
  1424. $sessionInfo = api_get_session_info($chamiloSessionId);
  1425. if (empty($sessionInfo)) {
  1426. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1427. continue;
  1428. }
  1429. $courseInfo = api_get_course_info($chamiloCourseCode);
  1430. if (empty($courseInfo)) {
  1431. $this->logger->addError('Course does not exists: '.$courseInfo);
  1432. continue;
  1433. }
  1434. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  1435. if (empty($userId)) {
  1436. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1437. continue;
  1438. }
  1439. switch ($type) {
  1440. case 'student':
  1441. SessionManager::subscribe_users_to_session_course(
  1442. array($userId),
  1443. $chamiloSessionId,
  1444. $courseInfo['code'],
  1445. null,
  1446. false
  1447. );
  1448. break;
  1449. case 'teacher':
  1450. SessionManager::set_coach_to_course_session(
  1451. $userId,
  1452. $chamiloSessionId,
  1453. $courseInfo['code']
  1454. );
  1455. break;
  1456. }
  1457. $this->logger->addError(
  1458. "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: ".$courseInfo['code']
  1459. );
  1460. }
  1461. }
  1462. if ($moveFile) {
  1463. $this->moveFile($file);
  1464. }
  1465. }
  1466. /**
  1467. * Updates the session synchronize with the csv file.
  1468. * @param bool $moveFile
  1469. * @param string $file
  1470. */
  1471. private function importSessionsStatic($file, $moveFile = true)
  1472. {
  1473. $content = file($file);
  1474. $sessions = array();
  1475. $tag_names = array();
  1476. foreach ($content as $key => $enreg) {
  1477. $enreg = explode(';', trim($enreg));
  1478. if ($key) {
  1479. foreach ($tag_names as $tag_key => $tag_name) {
  1480. if (isset($enreg[$tag_key])) {
  1481. $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
  1482. }
  1483. }
  1484. } else {
  1485. foreach ($enreg as $tag_name) {
  1486. $tag_names[] = api_preg_replace(
  1487. '/[^a-zA-Z0-9_\-]/',
  1488. '',
  1489. $tag_name
  1490. );
  1491. }
  1492. if (!in_array('SessionName', $tag_names) ||
  1493. !in_array('DateStart', $tag_names) || !in_array('DateEnd', $tag_names)
  1494. ) {
  1495. $error_message = get_lang('NoNeededData');
  1496. break;
  1497. }
  1498. }
  1499. }
  1500. if (!empty($sessions)) {
  1501. // Looping the sessions.
  1502. foreach ($sessions as $session) {
  1503. if (!empty($session['SessionID'])) {
  1504. $sessionId = SessionManager::getSessionIdFromOriginalId(
  1505. $session['SessionID'],
  1506. $this->extraFieldIdNameList['session']
  1507. );
  1508. $coachUserName = isset($session['Coach']) ? $session['Coach'] : null;
  1509. $categoryId = isset($session['category_id']) ? $session['category_id'] : null;
  1510. // 2014-06-30
  1511. $dateStart = explode('/', $session['DateStart']);
  1512. $dateEnd = explode('/', $session['DateEnd']);
  1513. $visibility = $this->defaultSessionVisibility;
  1514. $coachId = null;
  1515. if (!empty($coachUserName)) {
  1516. $coachInfo = api_get_user_info_from_username($coachUserName);
  1517. $coachId = $coachInfo['user_id'];
  1518. }
  1519. $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
  1520. $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
  1521. $date = new \DateTime($dateStart);
  1522. $interval = new DateInterval('P'.$this->daysCoachAccessBeforeBeginning.'D');
  1523. $date->sub($interval);
  1524. $coachBefore = $date->format('Y-m-d h:i');
  1525. $date = new \DateTime($dateEnd);
  1526. $interval = new DateInterval('P'.$this->daysCoachAccessAfterBeginning.'D');
  1527. $date->add($interval);
  1528. $coachAfter = $date->format('Y-m-d h:i');
  1529. /*$dateStart = api_get_utc_datetime($dateStart);
  1530. $dateEnd = api_get_utc_datetime($dateEnd);
  1531. $coachBefore = api_get_utc_datetime($coachBefore);
  1532. $coachAfter = api_get_utc_datetime($coachAfter);*/
  1533. if (empty($sessionId)) {
  1534. $result = SessionManager::create_session(
  1535. $session['SessionName'],
  1536. $dateStart,
  1537. $dateEnd,
  1538. $dateStart,
  1539. $dateEnd,
  1540. $coachBefore,
  1541. $coachAfter,
  1542. $coachId,
  1543. $categoryId,
  1544. $visibility
  1545. );
  1546. if (is_numeric($result)) {
  1547. $sessionId = $result;
  1548. $this->logger->addInfo("Session #$sessionId created: ".$session['SessionName']);
  1549. SessionManager::update_session_extra_field_value(
  1550. $sessionId,
  1551. $this->extraFieldIdNameList['session'],
  1552. $session['SessionID']
  1553. );
  1554. } else {
  1555. $this->logger->addInfo("Failed creating session: ".$session['SessionName']);
  1556. }
  1557. } else {
  1558. $sessionInfo = api_get_session_info($sessionId);
  1559. $accessBefore = null;
  1560. $accessAfter = null;
  1561. if (empty($sessionInfo['nb_days_access_before_beginning']) ||
  1562. (!empty($sessionInfo['nb_days_access_before_beginning']) &&
  1563. $sessionInfo['nb_days_access_before_beginning'] < $this->daysCoachAccessBeforeBeginning)
  1564. ) {
  1565. $accessBefore = $coachBefore;
  1566. }
  1567. $accessAfter = null;
  1568. if (empty($sessionInfo['nb_days_access_after_end']) ||
  1569. (!empty($sessionInfo['nb_days_access_after_end']) &&
  1570. $sessionInfo['nb_days_access_after_end'] < $this->daysCoachAccessAfterBeginning)
  1571. ) {
  1572. $accessAfter = $coachAfter;
  1573. }
  1574. $showDescription = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : 1;
  1575. $result = SessionManager::edit_session(
  1576. $sessionId,
  1577. $session['SessionName'],
  1578. $dateStart,
  1579. $dateEnd,
  1580. $dateStart,
  1581. $dateEnd,
  1582. $accessBefore,
  1583. $accessAfter,
  1584. $coachId,
  1585. $categoryId,
  1586. $visibility,
  1587. null, //$description = null,
  1588. $showDescription
  1589. );
  1590. if (is_numeric($result)) {
  1591. $this->logger->addInfo("Session #$sessionId updated: ".$session['SessionName']);
  1592. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1593. $params = array(
  1594. 'description' => $session['SessionDescription']
  1595. );
  1596. Database::update(
  1597. $tbl_session,
  1598. $params,
  1599. array('id = ?' => $sessionId)
  1600. );
  1601. }
  1602. }
  1603. if (!empty($sessionId)) {
  1604. // Courses
  1605. $courses = explode('|', $session['Courses']);
  1606. $courseList = [];
  1607. $courseListWithCoach = [];
  1608. foreach ($courses as $course) {
  1609. $courseArray = bracketsToArray($course);
  1610. $courseCode = $courseArray[0];
  1611. if (CourseManager::course_exists($courseCode)) {
  1612. $courseInfo = api_get_course_info($courseCode);
  1613. $courseList[] = $courseInfo['real_id'];
  1614. // Extracting course coaches
  1615. $courseCoaches = isset($courseArray[1]) ? $courseArray[1] : null;
  1616. $courseCoaches = explode(',', $courseCoaches);
  1617. // Extracting students
  1618. $courseUsers = isset($courseArray[2]) ? $courseArray[2] : null;
  1619. $courseUsers = explode(',', $courseUsers);
  1620. $courseListWithCoach[] = [
  1621. 'course_info' => $courseInfo,
  1622. 'coaches' => $courseCoaches,
  1623. 'course_users' => $courseUsers
  1624. ];
  1625. }
  1626. }
  1627. SessionManager::add_courses_to_session(
  1628. $sessionId,
  1629. $courseList,
  1630. true
  1631. );
  1632. $this->logger->addInfo("Session #$sessionId: Courses added: '".implode(', ', $courseList)."'");
  1633. if (empty($courseListWithCoach)) {
  1634. $this->logger->addInfo("No users/coaches to update");
  1635. continue;
  1636. }
  1637. foreach ($courseListWithCoach as $courseData) {
  1638. $courseInfo = $courseData['course_info'];
  1639. $courseCode = $courseInfo['code'];
  1640. $courseId = $courseInfo['real_id'];
  1641. $courseCoaches = $courseData['coaches'];
  1642. $courseUsers = $courseData['course_users'];
  1643. // Coaches
  1644. if (!empty($courseCoaches)) {
  1645. $coachList = array();
  1646. foreach ($courseCoaches as $courseCoach) {
  1647. $courseCoachId = UserManager::get_user_id_from_username(
  1648. $courseCoach
  1649. );
  1650. if ($courseCoachId !== false) {
  1651. // Just insert new coaches
  1652. $coachList[] = $courseCoachId;
  1653. }
  1654. }
  1655. $this->logger->addInfo("Session #$sessionId: course '$courseCode' coaches added: '".implode(', ', $coachList)."'");
  1656. SessionManager::updateCoaches(
  1657. $sessionId,
  1658. $courseId,
  1659. $coachList,
  1660. true
  1661. );
  1662. } else {
  1663. $this->logger->addInfo("No coaches added");
  1664. }
  1665. // Students
  1666. if (!empty($courseUsers)) {
  1667. $userList = array();
  1668. foreach ($courseUsers as $username) {
  1669. $userInfo = api_get_user_info_from_username(trim($username));
  1670. if (!empty($userInfo)) {
  1671. $userList[] = $userInfo['user_id'];
  1672. }
  1673. }
  1674. $this->logger->addInfo("Session #$sessionId: course '$courseCode': Students added '".implode(', ', $userList)."'");
  1675. SessionManager::subscribe_users_to_session_course(
  1676. $userList,
  1677. $sessionId,
  1678. $courseCode,
  1679. SESSION_VISIBLE_READ_ONLY,
  1680. true
  1681. );
  1682. } else {
  1683. $this->logger->addInfo("No users to register.");
  1684. }
  1685. }
  1686. } else {
  1687. $this->logger->addInfo(
  1688. 'SessionID not found in system.'
  1689. );
  1690. }
  1691. } else {
  1692. $this->logger->addInfo('SessionID does not exists');
  1693. }
  1694. }
  1695. } else {
  1696. $this->logger->addInfo($error_message);
  1697. }
  1698. if ($moveFile) {
  1699. $this->moveFile($file);
  1700. }
  1701. }
  1702. /**
  1703. * @param string $file
  1704. * @param bool $moveFile
  1705. * @param array $teacherBackup
  1706. * @param array $groupBackup
  1707. */
  1708. private function importSessions(
  1709. $file,
  1710. $moveFile = true,
  1711. &$teacherBackup = array(),
  1712. &$groupBackup = array()
  1713. ) {
  1714. $avoid = null;
  1715. if (isset($this->conditions['importSessions']) &&
  1716. isset($this->conditions['importSessions']['update'])
  1717. ) {
  1718. $avoid = $this->conditions['importSessions']['update'];
  1719. }
  1720. $result = SessionManager::importCSV(
  1721. $file,
  1722. true,
  1723. $this->defaultAdminId,
  1724. $this->logger,
  1725. array(
  1726. 'SessionID' => 'extra_'.$this->extraFieldIdNameList['session'],
  1727. 'CareerId' => 'extra_'.$this->extraFieldIdNameList['session_career']
  1728. ),
  1729. $this->extraFieldIdNameList['session'],
  1730. $this->daysCoachAccessBeforeBeginning,
  1731. $this->daysCoachAccessAfterBeginning,
  1732. $this->defaultSessionVisibility,
  1733. $avoid,
  1734. false, // deleteUsersNotInList
  1735. false, // updateCourseCoaches
  1736. true, // sessionWithCoursesModifier
  1737. true, //$addOriginalCourseTeachersAsCourseSessionCoaches
  1738. false, //$removeAllTeachersFromCourse
  1739. 1, // $showDescription,
  1740. $teacherBackup,
  1741. $groupBackup
  1742. );
  1743. if (!empty($result['error_message'])) {
  1744. $this->logger->addError($result['error_message']);
  1745. }
  1746. $this->logger->addInfo("Sessions - Sessions parsed: ".$result['session_counter']);
  1747. if ($moveFile) {
  1748. $this->moveFile($file);
  1749. }
  1750. }
  1751. /**
  1752. * @param string $file
  1753. * @param bool $moveFile
  1754. */
  1755. private function importSubscribeStatic($file, $moveFile = true)
  1756. {
  1757. $data = Import::csv_reader($file);
  1758. if (!empty($data)) {
  1759. $this->logger->addInfo(count($data)." records found.");
  1760. foreach ($data as $row) {
  1761. $chamiloUserName = $row['UserName'];
  1762. $chamiloCourseCode = $row['CourseCode'];
  1763. $chamiloSessionId = $row['SessionID'];
  1764. $type = $row['Type'];
  1765. $sessionInfo = api_get_session_info($chamiloSessionId);
  1766. if (empty($sessionInfo)) {
  1767. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  1768. continue;
  1769. }
  1770. $courseInfo = api_get_course_info($chamiloCourseCode);
  1771. if (empty($courseInfo)) {
  1772. $this->logger->addError('Course does not exists: '.$courseInfo);
  1773. continue;
  1774. }
  1775. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  1776. if (empty($userId)) {
  1777. $this->logger->addError('User does not exists: '.$chamiloUserName);
  1778. continue;
  1779. }
  1780. switch ($type) {
  1781. case 'student':
  1782. SessionManager::subscribe_users_to_session_course(
  1783. array($userId),
  1784. $chamiloSessionId,
  1785. $courseInfo['code'],
  1786. null,
  1787. false
  1788. );
  1789. break;
  1790. case 'teacher':
  1791. SessionManager::set_coach_to_course_session(
  1792. $userId,
  1793. $chamiloSessionId,
  1794. $courseInfo['real_id']
  1795. );
  1796. break;
  1797. }
  1798. $this->logger->addError(
  1799. "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: ".$courseInfo['code']
  1800. );
  1801. }
  1802. }
  1803. if ($moveFile) {
  1804. $this->moveFile($file);
  1805. }
  1806. }
  1807. /**
  1808. * @param $file
  1809. * @param bool $moveFile
  1810. */
  1811. private function importSubscribeUserToCourse($file, $moveFile = false, &$teacherBackup = [])
  1812. {
  1813. $data = Import::csv_reader($file);
  1814. if (!empty($data)) {
  1815. $this->logger->addInfo(count($data)." records found.");
  1816. foreach ($data as $row) {
  1817. $chamiloUserName = $row['UserName'];
  1818. $chamiloCourseCode = $row['CourseCode'];
  1819. $status = $row['Status'];
  1820. $courseInfo = api_get_course_info($chamiloCourseCode);
  1821. if (empty($courseInfo)) {
  1822. $this->logger->addError(
  1823. 'Course does not exists: '.$chamiloCourseCode
  1824. );
  1825. continue;
  1826. }
  1827. $userId = UserManager::get_user_id_from_username(
  1828. $chamiloUserName
  1829. );
  1830. if (empty($userId)) {
  1831. $this->logger->addError(
  1832. 'User does not exists: '.$chamiloUserName
  1833. );
  1834. continue;
  1835. }
  1836. $userCourseCategory = '';
  1837. if (isset($teacherBackup[$userId]) &&
  1838. isset($teacherBackup[$userId][$courseInfo['code']])
  1839. ) {
  1840. $courseUserData = $teacherBackup[$userId][$courseInfo['code']];
  1841. $userCourseCategory = $courseUserData['user_course_cat'];
  1842. }
  1843. CourseManager::subscribe_user(
  1844. $userId,
  1845. $courseInfo['code'],
  1846. $status,
  1847. 0,
  1848. $userCourseCategory
  1849. );
  1850. $this->logger->addInfo(
  1851. "User $userId added to course ".$courseInfo['code']." with status '$status' with course category: '$userCourseCategory'"
  1852. );
  1853. }
  1854. }
  1855. if ($moveFile) {
  1856. $this->moveFile($file);
  1857. }
  1858. }
  1859. /**
  1860. * @param $file
  1861. * @param bool $moveFile
  1862. */
  1863. public function importCare($file, $moveFile = false)
  1864. {
  1865. $data = Import::csv_reader($file);
  1866. $counter = 1;
  1867. $batchSize = $this->batchSize;
  1868. $em = Database::getManager();
  1869. if (!empty($data)) {
  1870. $this->logger->addInfo(count($data)." records found.");
  1871. $items = [];
  1872. foreach ($data as $list) {
  1873. $post = [];
  1874. foreach ($list as $key => $value) {
  1875. $key = (string) trim($key);
  1876. // Remove utf8 bom
  1877. $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
  1878. $post[$key] = $value;
  1879. }
  1880. if (empty($post)) {
  1881. continue;
  1882. }
  1883. $externalId = $post['External_care_id'];
  1884. $items[$externalId] = $post;
  1885. }
  1886. ksort($items);
  1887. foreach ($items as $row) {
  1888. // Insert user
  1889. $insertUserInfo = api_get_user_info_from_username($row['Added_by']);
  1890. if (empty($insertUserInfo)) {
  1891. $this->logger->addInfo("User does '".$row['Added_by']."' not exists skip this entry.");
  1892. continue;
  1893. }
  1894. $insertUserInfo = api_get_user_entity($insertUserInfo['user_id']);
  1895. // User about the post
  1896. $userId = UserManager::get_user_id_from_original_id(
  1897. $row['External_user_id'],
  1898. $this->extraFieldIdNameList['user']
  1899. );
  1900. if (empty($userId)) {
  1901. if (empty($userInfo)) {
  1902. $this->logger->addInfo("User does '".$row['External_user_id']."' not exists skip this entry.");
  1903. continue;
  1904. }
  1905. }
  1906. $userInfo = api_get_user_entity($userId);
  1907. // Dates
  1908. $createdAt = $this->createDateTime($row['Added_On']);
  1909. $updatedAt = $this->createDateTime($row['Edited_on']);
  1910. // Parent
  1911. $parent = null;
  1912. if (!empty($row['Parent_id'])) {
  1913. $parentId = $items[$row['Parent_id']];
  1914. $criteria = [
  1915. 'externalCareId' => $parentId
  1916. ];
  1917. $parent = $em->getRepository('ChamiloPluginBundle:StudentFollowUp\CarePost')->findOneBy($criteria);
  1918. }
  1919. // Tags
  1920. $tags = explode(',', $row['Tags']);
  1921. // Check if post already was added:
  1922. $criteria = [
  1923. 'externalCareId' => $row['External_care_id']
  1924. ];
  1925. $post = $em->getRepository('ChamiloPluginBundle:StudentFollowUp\CarePost')->findOneBy($criteria);
  1926. if (empty($post)) {
  1927. $post = new CarePost();
  1928. }
  1929. $post
  1930. ->setTitle($row['Title'])
  1931. ->setContent($row['Article'])
  1932. ->setExternalCareId($row['External_care_id'])
  1933. ->setCreatedAt($createdAt)
  1934. ->setUpdatedAt($updatedAt)
  1935. ->setPrivate((int) $row['Private'])
  1936. ->setInsertUser($insertUserInfo)
  1937. ->setExternalSource((int) $row['Source_is_external'])
  1938. ->setParent($parent)
  1939. ->setTags($tags)
  1940. ->setUser($userInfo)
  1941. ;
  1942. $em->persist($post);
  1943. $em->flush();
  1944. if (($counter % $batchSize) === 0) {
  1945. $em->flush();
  1946. $em->clear(); // Detaches all objects from Doctrine!
  1947. }
  1948. $counter++;
  1949. }
  1950. $em->clear(); // Detaches all objects from Doctrine!
  1951. }
  1952. }
  1953. /**
  1954. * 23/4/2017 to datetime
  1955. * @param $string
  1956. * @return mixed
  1957. */
  1958. private function createDateTime($string)
  1959. {
  1960. if (empty($string)) {
  1961. return null;
  1962. }
  1963. $date = DateTime::createFromFormat('j/m/Y', $string);
  1964. return $date;
  1965. }
  1966. /**
  1967. * @param $file
  1968. * @param bool $moveFile
  1969. * @param array $teacherBackup
  1970. * @param array $groupBackup
  1971. * @return bool
  1972. */
  1973. private function importCareers(
  1974. $file,
  1975. $moveFile = false,
  1976. &$teacherBackup = array(),
  1977. &$groupBackup = array()
  1978. ) {
  1979. $data = Import::csv_reader($file);
  1980. if (!empty($data)) {
  1981. $this->logger->addInfo(count($data)." records found.");
  1982. $extraFieldValue = new ExtraFieldValue('career');
  1983. $extraFieldName = $this->extraFieldIdNameList['career'];
  1984. $externalEventId = null;
  1985. $extraField = new ExtraField('career');
  1986. $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
  1987. $extraFieldName
  1988. );
  1989. if (empty($extraFieldInfo)) {
  1990. return false;
  1991. }
  1992. foreach ($data as $row) {
  1993. foreach ($row as $key => $value) {
  1994. $key = (string)trim($key);
  1995. // Remove utf8 bom
  1996. $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
  1997. $row[$key] = $value;
  1998. }
  1999. $itemId = $row['CareerId'];
  2000. $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
  2001. $extraFieldName,
  2002. $itemId,
  2003. false,
  2004. false,
  2005. false
  2006. );
  2007. $career = new Career();
  2008. if (empty($item)) {
  2009. $params = [
  2010. 'status' => 1,
  2011. 'name' => $row['CareerName']
  2012. ];
  2013. $careerId = $career->save($params);
  2014. if ($careerId) {
  2015. $params = [
  2016. 'item_id' => $careerId,
  2017. 'extra_'.$extraFieldName => $itemId,
  2018. ];
  2019. $extraFieldValue->saveFieldValues($params);
  2020. }
  2021. } else {
  2022. if (isset($item['item_id'])) {
  2023. $params = [
  2024. 'id' => $item['item_id'],
  2025. 'name' => $row['CareerName']
  2026. ];
  2027. $career->update($params);
  2028. }
  2029. }
  2030. }
  2031. }
  2032. }
  2033. /**
  2034. * @param $file
  2035. * @param bool $moveFile
  2036. * @param array $teacherBackup
  2037. * @param array $groupBackup
  2038. */
  2039. private function importCareersDiagram(
  2040. $file,
  2041. $moveFile = false,
  2042. &$teacherBackup = array(),
  2043. &$groupBackup = array()
  2044. ) {
  2045. $data = Import::csv_reader($file);
  2046. $extraFieldValue = new ExtraFieldValue('career');
  2047. $extraFieldName = $this->extraFieldIdNameList['career'];
  2048. $externalEventId = null;
  2049. $extraField = new ExtraField('career');
  2050. $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
  2051. $extraFieldName
  2052. );
  2053. $careerDiagramExtraFieldName = $this->extraFieldIdNameList['career_diagram'];
  2054. $extraFieldDiagramInfo = $extraField->get_handler_field_info_by_field_variable(
  2055. $careerDiagramExtraFieldName
  2056. );
  2057. if (empty($extraFieldInfo) || empty($extraFieldDiagramInfo)) {
  2058. return false;
  2059. }
  2060. if (!empty($data)) {
  2061. $this->logger->addInfo(count($data)." records found.");
  2062. $values = [];
  2063. foreach ($data as $row) {
  2064. foreach ($row as $key => $value) {
  2065. $key = (string) trim($key);
  2066. // Remove utf8 bom
  2067. $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
  2068. $row[$key] = $value;
  2069. }
  2070. $values[$row['Column']][] = $row;
  2071. }
  2072. $careerList = [];
  2073. $careerNameList = [];
  2074. ksort($values);
  2075. $careerChamiloIdList = [];
  2076. // 1. First create all items
  2077. foreach ($values as $column => $rowList) {
  2078. foreach ($rowList as $row) {
  2079. $careerId = $row['CareerId'];
  2080. $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
  2081. $extraFieldName,
  2082. $careerId,
  2083. false,
  2084. false,
  2085. false
  2086. );
  2087. $chamiloCareerName = '';
  2088. if (empty($item)) {
  2089. $this->logger->addInfo("Career not found: $careerId");
  2090. continue;
  2091. } else {
  2092. if (isset($item['item_id'])) {
  2093. $careerChamiloId = $item['item_id'];
  2094. $career = new Career();
  2095. $career = $career->find($careerChamiloId);
  2096. $chamiloCareerName = $career['name'];
  2097. $careerNameList[$careerId] = $chamiloCareerName;
  2098. $careerChamiloIdList[$careerId] = $careerChamiloId;
  2099. } else {
  2100. continue;
  2101. }
  2102. }
  2103. if (empty($chamiloCareerName)) {
  2104. $this->logger->addInfo("Career not found: $careerId");
  2105. continue;
  2106. }
  2107. if (isset($careerList[$careerId])) {
  2108. $graph = $careerList[$careerId];
  2109. } else {
  2110. $graph = new Graph($careerId);
  2111. $graph->setAttribute('graphviz.graph.rankdir', 'LR');
  2112. $careerList[$careerId] = $graph;
  2113. }
  2114. $currentCourseId = (int) $row['CourseId'];
  2115. $name = $row['CourseName'];
  2116. $color = $row['DefinedColor'];
  2117. $notes = $row['Notes'];
  2118. $groupValue = $row['Group'];
  2119. $rowValue = $row['Row'];
  2120. $arrow = $row['DrawArrowFrom'];
  2121. $subGroup = $row['SubGroup'];
  2122. $connections = $row['Connections'];
  2123. if ($graph->hasVertex($currentCourseId)) {
  2124. // Avoid double insertion
  2125. continue;
  2126. } else {
  2127. $current = $graph->createVertex($currentCourseId);
  2128. $current->setAttribute('graphviz.label', $name);
  2129. $current->setAttribute('DefinedColor', $color);
  2130. $current->setAttribute('Notes', $notes);
  2131. $current->setAttribute('Row', $rowValue);
  2132. $current->setAttribute('Group', $groupValue);
  2133. $current->setAttribute('DrawArrowFrom', $arrow);
  2134. $current->setAttribute('SubGroup', $subGroup);
  2135. $current->setAttribute('Connections', $connections);
  2136. //$current->setAttribute('graphviz.color', 'blue');
  2137. $current->setAttribute('graphviz.shape', 'box');
  2138. $current->setGroup($column);
  2139. }
  2140. }
  2141. }
  2142. // 2. Create connections
  2143. // $column start with 1 (depending in Column row)
  2144. foreach ($values as $column => $rowList) {
  2145. foreach ($rowList as $row) {
  2146. $careerId = $row['CareerId'];
  2147. if (isset($careerList[$careerId])) {
  2148. $graph = $careerList[$careerId];
  2149. } else {
  2150. continue;
  2151. }
  2152. $currentCourseId = (int) $row['CourseId'];
  2153. if ($graph->hasVertex($currentCourseId)) {
  2154. $current = $graph->getVertex($currentCourseId);
  2155. } else {
  2156. continue;
  2157. }
  2158. if (isset($row['DependedOn']) && !empty($row['DependedOn'])) {
  2159. $parentList = explode(',', $row['DependedOn']);
  2160. foreach ($parentList as $parentId) {
  2161. $parentId = (int) $parentId;
  2162. echo $parentId.PHP_EOL;
  2163. if ($graph->hasVertex($parentId)) {
  2164. /** @var Vertex $parent */
  2165. $parent = $graph->getVertex($parentId);
  2166. /*$parent->setAttribute('graphviz.color', 'red');
  2167. $parent->setAttribute('graphviz.label', $name);
  2168. $parent->setAttribute('graphviz.shape', 'square');*/
  2169. $parent->createEdgeTo($current);
  2170. }
  2171. }
  2172. }
  2173. }
  2174. }
  2175. /** @var Graph $graph */
  2176. foreach ($careerList as $id => $graph) {
  2177. if (isset($careerChamiloIdList[$id])) {
  2178. $params = [
  2179. 'item_id' => $careerChamiloIdList[$id],
  2180. 'extra_'.$careerDiagramExtraFieldName => serialize($graph),
  2181. 'extra_'.$extraFieldName => $id,
  2182. ];
  2183. $extraFieldValue->saveFieldValues($params);
  2184. }
  2185. }
  2186. }
  2187. }
  2188. /**
  2189. * @param string $file
  2190. * @param bool $moveFile
  2191. * @param array $teacherBackup
  2192. * @param array $groupBackup
  2193. */
  2194. private function importUnsubscribeStatic(
  2195. $file,
  2196. $moveFile = false,
  2197. &$teacherBackup = array(),
  2198. &$groupBackup = array()
  2199. ) {
  2200. $data = Import::csv_reader($file);
  2201. if (!empty($data)) {
  2202. $this->logger->addInfo(count($data)." records found.");
  2203. foreach ($data as $row) {
  2204. $chamiloUserName = $row['UserName'];
  2205. $chamiloCourseCode = $row['CourseCode'];
  2206. $chamiloSessionId = $row['SessionID'];
  2207. $sessionInfo = api_get_session_info($chamiloSessionId);
  2208. if (empty($sessionInfo)) {
  2209. $this->logger->addError('Session does not exists: '.$chamiloSessionId);
  2210. continue;
  2211. }
  2212. $courseInfo = api_get_course_info($chamiloCourseCode);
  2213. if (empty($courseInfo)) {
  2214. $this->logger->addError('Course does not exists: '.$courseInfo);
  2215. continue;
  2216. }
  2217. $userId = UserManager::get_user_id_from_username($chamiloUserName);
  2218. if (empty($userId)) {
  2219. $this->logger->addError('User does not exists: '.$chamiloUserName);
  2220. continue;
  2221. }
  2222. $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
  2223. WHERE
  2224. user_id = ".$userId." AND
  2225. c_id = '".$courseInfo['real_id']."'
  2226. ";
  2227. $result = Database::query($sql);
  2228. $rows = Database::num_rows($result);
  2229. if ($rows > 0) {
  2230. $userCourseData = Database::fetch_array($result, 'ASSOC');
  2231. if (!empty($userCourseData)) {
  2232. $teacherBackup[$userId][$courseInfo['code']] = $userCourseData;
  2233. }
  2234. }
  2235. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
  2236. WHERE
  2237. user_id = ".$userId." AND
  2238. c_id = '".$courseInfo['real_id']."'
  2239. ";
  2240. $result = Database::query($sql);
  2241. while ($groupData = Database::fetch_array($result, 'ASSOC')) {
  2242. $groupBackup['user'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
  2243. }
  2244. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
  2245. WHERE
  2246. user_id = ".$userId." AND
  2247. c_id = '".$courseInfo['real_id']."'
  2248. ";
  2249. $result = Database::query($sql);
  2250. while ($groupData = Database::fetch_array($result, 'ASSOC')) {
  2251. $groupBackup['tutor'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
  2252. }
  2253. CourseManager::unsubscribe_user(
  2254. $userId,
  2255. $courseInfo['code'],
  2256. $chamiloSessionId
  2257. );
  2258. $this->logger->addError(
  2259. "User '$chamiloUserName' was removed from session: #$chamiloSessionId, Course: ".$courseInfo['code']
  2260. );
  2261. }
  2262. }
  2263. if ($moveFile) {
  2264. $this->moveFile($file);
  2265. }
  2266. }
  2267. /**
  2268. * Dump database tables
  2269. */
  2270. private function dumpDatabaseTables()
  2271. {
  2272. echo 'Dumping tables'.PHP_EOL;
  2273. // User
  2274. $table = Database::get_main_table(TABLE_MAIN_USER);
  2275. $tableAdmin = Database::get_main_table(TABLE_MAIN_ADMIN);
  2276. $sql = "DELETE FROM $table
  2277. WHERE user_id not in (select user_id from $tableAdmin) and status <> ".ANONYMOUS;
  2278. Database::query($sql);
  2279. echo $sql.PHP_EOL;
  2280. // Truncate tables
  2281. $truncateTables = array(
  2282. Database::get_main_table(TABLE_MAIN_COURSE),
  2283. Database::get_main_table(TABLE_MAIN_COURSE_USER),
  2284. Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE),
  2285. Database::get_main_table(TABLE_MAIN_CATEGORY),
  2286. Database::get_main_table(TABLE_MAIN_COURSE_MODULE),
  2287. Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER),
  2288. Database::get_main_table(TABLE_MAIN_SESSION),
  2289. Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY),
  2290. Database::get_main_table(TABLE_MAIN_SESSION_COURSE),
  2291. Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER),
  2292. Database::get_main_table(TABLE_MAIN_SESSION_USER),
  2293. Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION),
  2294. Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
  2295. Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
  2296. Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES),
  2297. Database::get_main_table(TABLE_MAIN_USER_FIELD),
  2298. Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS),
  2299. Database::get_main_table(TABLE_MAIN_COURSE_FIELD),
  2300. Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
  2301. Database::get_main_table(TABLE_MAIN_SESSION_FIELD),
  2302. Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
  2303. Database::get_course_table(TABLE_AGENDA),
  2304. Database::get_course_table(TABLE_AGENDA_ATTACHMENT),
  2305. Database::get_course_table(TABLE_AGENDA_REPEAT),
  2306. Database::get_course_table(TABLE_AGENDA_REPEAT_NOT),
  2307. Database::get_main_table(TABLE_PERSONAL_AGENDA),
  2308. Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT_NOT),
  2309. Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT),
  2310. Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_VALUES),
  2311. Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS),
  2312. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS),
  2313. Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN),
  2314. Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS),
  2315. Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES),
  2316. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT),
  2317. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING),
  2318. Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT),
  2319. Database::get_main_table(TABLE_STATISTIC_TRACK_E_UPLOADS),
  2320. Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT),
  2321. Database::get_main_table(TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY),
  2322. Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY),
  2323. Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION),
  2324. Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG),
  2325. Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT),
  2326. Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_LOG),
  2327. Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK),
  2328. Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY),
  2329. Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE),
  2330. Database::get_course_table(TABLE_STUDENT_PUBLICATION),
  2331. Database::get_course_table(TABLE_QUIZ_QUESTION),
  2332. Database::get_course_table(TABLE_QUIZ_TEST),
  2333. Database::get_course_table(TABLE_QUIZ_ORDER),
  2334. Database::get_course_table(TABLE_QUIZ_ANSWER),
  2335. Database::get_course_table(TABLE_QUIZ_TEST_QUESTION),
  2336. Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION),
  2337. Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY),
  2338. Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY),
  2339. Database::get_course_table(TABLE_LP_MAIN),
  2340. Database::get_course_table(TABLE_LP_ITEM),
  2341. Database::get_course_table(TABLE_LP_VIEW),
  2342. Database::get_course_table(TABLE_LP_ITEM_VIEW),
  2343. Database::get_course_table(TABLE_DOCUMENT),
  2344. Database::get_course_table(TABLE_ITEM_PROPERTY),
  2345. Database::get_course_table(TABLE_TOOL_LIST),
  2346. Database::get_course_table(TABLE_TOOL_INTRO),
  2347. Database::get_course_table(TABLE_COURSE_SETTING),
  2348. Database::get_course_table(TABLE_SURVEY),
  2349. Database::get_course_table(TABLE_SURVEY_QUESTION),
  2350. Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION),
  2351. Database::get_course_table(TABLE_SURVEY_INVITATION),
  2352. Database::get_course_table(TABLE_SURVEY_ANSWER),
  2353. Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP),
  2354. Database::get_course_table(TABLE_SURVEY_REPORT),
  2355. Database::get_course_table(TABLE_GLOSSARY),
  2356. Database::get_course_table(TABLE_LINK),
  2357. Database::get_course_table(TABLE_LINK_CATEGORY),
  2358. Database::get_course_table(TABLE_GROUP),
  2359. Database::get_course_table(TABLE_GROUP_USER),
  2360. Database::get_course_table(TABLE_GROUP_TUTOR),
  2361. Database::get_course_table(TABLE_GROUP_CATEGORY),
  2362. Database::get_course_table(TABLE_DROPBOX_CATEGORY),
  2363. Database::get_course_table(TABLE_DROPBOX_FEEDBACK),
  2364. Database::get_course_table(TABLE_DROPBOX_POST),
  2365. Database::get_course_table(TABLE_DROPBOX_FILE),
  2366. Database::get_course_table(TABLE_DROPBOX_PERSON)
  2367. );
  2368. foreach ($truncateTables as $table) {
  2369. $sql = "TRUNCATE $table";
  2370. Database::query($sql);
  2371. echo $sql.PHP_EOL;
  2372. }
  2373. $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
  2374. $sql = "DELETE FROM $table WHERE tool = 'calendar_event'";
  2375. Database::query($sql);
  2376. echo $sql.PHP_EOL;
  2377. }
  2378. /**
  2379. * If csv file ends with '"' character then a '";' is added
  2380. * @param string $file
  2381. */
  2382. private function fixCSVFile($file)
  2383. {
  2384. /*$f = fopen($file, 'r+');
  2385. $cursor = -1;
  2386. fseek($f, $cursor, SEEK_END);
  2387. $char = fgetc($f);
  2388. while ($char === "\n" || $char === "\r") {
  2389. fseek($f, $cursor--, SEEK_END);
  2390. $char = fgetc($f);
  2391. }
  2392. if ($char === "\"") {
  2393. fseek($f, -1, SEEK_CUR);
  2394. fwrite($f, '";');
  2395. }*/
  2396. }
  2397. /**
  2398. * @return mixed
  2399. */
  2400. public function getUpdateEmailToDummy()
  2401. {
  2402. return $this->updateEmailToDummy;
  2403. }
  2404. /**
  2405. * @param mixed $updateEmailToDummy
  2406. */
  2407. public function setUpdateEmailToDummy($updateEmailToDummy)
  2408. {
  2409. $this->updateEmailToDummy = $updateEmailToDummy;
  2410. }
  2411. /**
  2412. * Change emails of all users except admins
  2413. *
  2414. */
  2415. public function updateUsersEmails()
  2416. {
  2417. if ($this->getUpdateEmailToDummy() === true) {
  2418. $sql = "UPDATE user SET email = CONCAT(username,'@example.com') WHERE id NOT IN (SELECT user_id FROM admin)";
  2419. Database::query($sql);
  2420. }
  2421. }
  2422. }
  2423. $logger = new Logger('cron');
  2424. $emails = isset($_configuration['cron_notification_mails']) ? $_configuration['cron_notification_mails'] : null;
  2425. $minLevel = Logger::DEBUG;
  2426. if (!is_array($emails)) {
  2427. $emails = array($emails);
  2428. }
  2429. $subject = "Cron main/cron/import_csv.php ".date('Y-m-d h:i:s');
  2430. $from = api_get_setting('emailAdministrator');
  2431. /*
  2432. if (!empty($emails)) {
  2433. foreach ($emails as $email) {
  2434. $stream = new NativeMailerHandler($email, $subject, $from, $minLevel);
  2435. $logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
  2436. }
  2437. }*/
  2438. $stream = new StreamHandler(
  2439. api_get_path(SYS_ARCHIVE_PATH).'import_csv.log',
  2440. $minLevel
  2441. );
  2442. $logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
  2443. $logger->pushHandler(new RotatingFileHandler('import_csv', 5, $minLevel));
  2444. $cronImportCSVConditions = isset($_configuration['cron_import_csv_conditions']) ? $_configuration['cron_import_csv_conditions'] : null;
  2445. echo 'See the error log here: '.api_get_path(SYS_ARCHIVE_PATH).'import_csv.log'."\n";
  2446. $import = new ImportCsv($logger, $cronImportCSVConditions);
  2447. if (isset($_configuration['default_admin_user_id_for_cron'])) {
  2448. $import->defaultAdminId = $_configuration['default_admin_user_id_for_cron'];
  2449. }
  2450. // @todo in production disable the dump option
  2451. $dump = false;
  2452. if (isset($argv[1]) && $argv[1] = '--dump') {
  2453. $dump = true;
  2454. }
  2455. if (isset($_configuration['import_csv_disable_dump']) &&
  2456. $_configuration['import_csv_disable_dump'] == true
  2457. ) {
  2458. $import->setDumpValues(false);
  2459. } else {
  2460. $import->setDumpValues($dump);
  2461. }
  2462. $import->setUpdateEmailToDummy(api_get_configuration_value('update_users_email_to_dummy_except_admins'));
  2463. // Do not moves the files to treated
  2464. if (isset($_configuration['import_csv_test'])) {
  2465. $import->test = $_configuration['import_csv_test'];
  2466. } else {
  2467. $import->test = true;
  2468. }
  2469. $timeStart = microtime(true);
  2470. $import->run();
  2471. $timeEnd = microtime(true);
  2472. $executionTime = round(($timeEnd - $timeStart) / 60, 2);
  2473. $logger->addInfo("Total execution Time $executionTime Min");
  2474. if (isset($_configuration['import_csv_fix_permissions']) &&
  2475. $_configuration['import_csv_fix_permissions'] == true
  2476. ) {
  2477. $command = "sudo find ".api_get_path(SYS_COURSE_PATH)." -type d -exec chmod 777 {} \; ";
  2478. echo "Executing: ".$command.PHP_EOL;
  2479. system($command);
  2480. $command = "sudo find ".api_get_path(SYS_CODE_PATH)."upload/users -type d -exec chmod 777 {} \;";
  2481. echo "Executing: ".$command.PHP_EOL;
  2482. system($command);
  2483. }