import_csv.php 129 KB

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