PageRenderTime 61ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/site/ImportOCS1.inc.php

https://github.com/lib-uoguelph-ca/ocs
PHP | 963 lines | 693 code | 158 blank | 112 comment | 78 complexity | 63c57ff5d896a6b91caf549ece8bf63d MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * @file ImportOCS1.inc.php
  4. *
  5. * Copyright (c) 2000-2012 John Willinsky
  6. * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
  7. *
  8. * @class ImportOCS1
  9. * @ingroup site
  10. *
  11. * @brief Class to import data from an OCS 1.x installation.
  12. *
  13. */
  14. // $Id$
  15. import('user.User');
  16. import('conference.Conference');
  17. import('conference.Track');
  18. import('security.Role');
  19. import('registration.Registration');
  20. import('registration.RegistrationType');
  21. import('currency.Currency');
  22. import('paper.Paper');
  23. import('paper.PaperComment');
  24. import('paper.PaperFile');
  25. import('paper.PaperGalley');
  26. import('paper.PaperHTMLGalley');
  27. import('paper.PaperNote');
  28. import('paper.Author');
  29. import('paper.PublishedPaper');
  30. import('paper.SuppFile');
  31. import('submission.common/Action');
  32. import('submission.author.AuthorSubmission');
  33. import('submission.reviewer.ReviewerSubmission');
  34. import('submission.editAssignment.EditAssignment');
  35. import('submission.reviewAssignment.ReviewAssignment');
  36. import('comment.Comment');
  37. import('file.PaperFileManager');
  38. import('file.PublicFileManager');
  39. import('search.PaperSearchIndex');
  40. class ImportOCS1 {
  41. //
  42. // Private variables
  43. //
  44. var $importPath;
  45. var $conferencePath;
  46. var $conference;
  47. var $conferenceId = 0;
  48. var $conferenceIsNew;
  49. var $dbtable = array();
  50. var $schedConfMap = array();
  51. var $trackMap = array();
  52. var $paperMap = array();
  53. var $reviewerMap = array();
  54. var $importDBConn;
  55. var $importDao;
  56. var $indexUrl;
  57. var $globalConfigInfo;
  58. var $conferenceInfo = array();
  59. var $userCount = 0;
  60. var $paperCount = 0;
  61. var $options;
  62. var $error;
  63. /** @var $conflicts array List of conflicting user accounts */
  64. var $conflicts;
  65. /** @var $errors array List of errors */
  66. var $errors;
  67. /**
  68. * Constructor.
  69. */
  70. function ImportOCS1() {
  71. // Note: generally Request's auto-detection won't work correctly
  72. // when run via CLI so use config setting if available
  73. $this->indexUrl = Config::getVar('general', 'base_url');
  74. if ($this->indexUrl)
  75. $this->indexUrl .= '/' . INDEX_SCRIPTNAME;
  76. else
  77. $this->indexUrl = Request::getIndexUrl();
  78. $this->conflicts = array();
  79. $this->errors = array();
  80. }
  81. /**
  82. * Record error message.
  83. * @return string;
  84. */
  85. function error($message = null) {
  86. if (isset($message)) {
  87. $this->error = $message;
  88. }
  89. return $this->error;
  90. }
  91. /**
  92. * Check if an option is enabled.
  93. * @param $option string
  94. * @return boolean
  95. */
  96. function hasOption($option) {
  97. return in_array($option, $this->options);
  98. }
  99. /**
  100. * Execute import of an OCS 1 conference.
  101. * If an existing conference path is specified, only content is imported;
  102. * otherwise, a new conference is created and all conference settings are also imported.
  103. * @param $conferencePath string conference URL path
  104. * @param $importPath string local filesystem path to the base OCS 1 directory
  105. * @param $options array supported: 'importRegistrations'
  106. * @return boolean/int false or conference ID
  107. */
  108. function import($conferencePath, $importPath, $options = array()) {
  109. @set_time_limit(0);
  110. $this->conferencePath = $conferencePath;
  111. $this->importPath = $importPath;
  112. $this->options = $options;
  113. // Force a new database connection
  114. $dbconn =& DBConnection::getInstance();
  115. $dbconn->reconnect(true);
  116. // Create a connection to the old database
  117. if (!@include($this->importPath . '/include/db.inc.php')) { // Suppress E_NOTICE messages
  118. $this->error('Failed to load ' . $this->importPath . '/include/db.php');
  119. return false;
  120. }
  121. // Assumes no character set (not supported by OCS 1.x)
  122. // Forces open a new connection
  123. $this->importDBConn = new DBConnection($db_type, $db_host, $db_login, $db_password, $db_name, false, false, true, false, true);
  124. $dbconn =& $this->importDBConn->getDBConn();
  125. if (!$this->importDBConn->isConnected()) {
  126. $this->error('Database connection error: ' . $dbconn->errorMsg());
  127. return false;
  128. }
  129. $this->dbtable = $dbtable;
  130. $this->importDao = new DAO($dbconn);
  131. if (!$this->loadGlobalConfig()) {
  132. $this->error('Unsupported or unrecognized OCS version');
  133. return false;
  134. }
  135. $this->importConference();
  136. $this->importSchedConfs();
  137. $this->importTracks();
  138. $this->importPapers();
  139. $this->importReviewers();
  140. $this->importReviews();
  141. if ($this->hasOption('importRegistrations')) {
  142. $this->importRegistrations();
  143. }
  144. // Rebuild search index
  145. $this->rebuildSearchIndex();
  146. return $this->conferenceId;
  147. }
  148. /**
  149. * Load OCS 1 configuration and settings data.
  150. * @return boolean
  151. */
  152. function loadGlobalConfig() {
  153. $dbtable = $this->dbtable;
  154. // Load global config
  155. $result =& $this->importDao->retrieve("SELECT * FROM $dbtable[conference_global]");
  156. $this->globalConfigInfo =& $result->fields;
  157. $result->Close();
  158. if (!isset($this->globalConfigInfo['admin_login'])) {
  159. return false;
  160. }
  161. return true;
  162. }
  163. //
  164. // Conference
  165. //
  166. function importConference() {
  167. // If necessary, create the conference.
  168. $conferenceDao =& DAORegistry::getDAO('ConferenceDAO');
  169. if (!$conference =& $conferenceDao->getConferenceByPath($this->conferencePath)) {
  170. if ($this->hasOption('verbose')) {
  171. printf("Creating conference\n");
  172. }
  173. unset($conference);
  174. $conference = new Conference();
  175. $conference->setPath($this->conferencePath);
  176. $conference->setPrimaryLocale(AppLocale::getLocale());
  177. $conference->setEnabled(true);
  178. $this->conferenceId = $conferenceDao->insertConference($conference);
  179. $conferenceDao->resequenceConferences();
  180. $conference->updateSetting('title', array(AppLocale::getLocale() => $this->globalConfigInfo['name']), null, true);
  181. $this->conferenceIsNew = true;
  182. } else {
  183. if ($this->hasOption('verbose')) {
  184. printf("Using existing conference\n");
  185. }
  186. $conference->updateSetting('title', array(AppLocale::getLocale() => $this->globalConfigInfo['name']), null, true);
  187. $this->conferenceId = $conference->getId();
  188. $this->conferenceIsNew = false;
  189. }
  190. $this->conference =& $conference;
  191. $roleDao =& DAORegistry::getDAO('RoleDAO');
  192. if ($this->conferenceIsNew) {
  193. // All site admins should get a manager role by default
  194. $admins = $roleDao->getUsersByRoleId(ROLE_ID_SITE_ADMIN);
  195. foreach ($admins->toArray() as $admin) {
  196. $role = new Role();
  197. $role->setConferenceId($this->conferenceId);
  198. $role->setUserId($admin->getId());
  199. $role->setRoleId(ROLE_ID_CONFERENCE_MANAGER);
  200. $roleDao->insertRole($role);
  201. }
  202. // Install the default RT versions.
  203. import('rt.ocs.ConferenceRTAdmin');
  204. $conferenceRtAdmin = new ConferenceRTAdmin($this->conferenceId);
  205. $conferenceRtAdmin->restoreVersions(false);
  206. $confSettings = array(
  207. 'itemsPerPage' => array('int', 25),
  208. 'numPageLinks' => array('int', 10),
  209. );
  210. foreach ($confSettings as $settingName => $settingInfo) {
  211. list($settingType, $settingValue) = $settingInfo;
  212. $this->conference->updateSetting($settingName, $settingValue, $settingType);
  213. }
  214. }
  215. }
  216. //
  217. // Scheduled Conference
  218. //
  219. function importSchedConfs() {
  220. if ($this->hasOption('verbose')) {
  221. printf("Importing scheduled conferences\n");
  222. }
  223. $dbtable = $this->dbtable;
  224. $result =& $this->importDao->retrieve("SELECT id FROM $dbtable[conference] ORDER BY id");
  225. $conferenceIds = array();
  226. while (!$result->EOF) {
  227. $conferenceIds[] =& $result->fields[0];
  228. $result->MoveNext();
  229. }
  230. $result->Close();
  231. foreach ($conferenceIds as $id) {
  232. $this->importSchedConf($id);
  233. }
  234. }
  235. /**
  236. * Import scheduled conference and related settings.
  237. * @param $id int
  238. */
  239. function importSchedConf($id) {
  240. $schedConfDao =& DAORegistry::getDAO('SchedConfDAO');
  241. $userDao =& DAORegistry::getDAO('UserDAO');
  242. if ($this->hasOption('verbose')) {
  243. printf("Importing OCS 1.x conference ID $id\n");
  244. }
  245. $dbtable = $this->dbtable;
  246. // Load sched conf config
  247. $result =& $this->importDao->retrieve("SELECT * FROM $dbtable[conference] WHERE id = ?", array($id));
  248. $this->conferenceInfo[$id] =& $result->fields;
  249. $result->Close();
  250. $conferenceInfo =& $this->conferenceInfo[$id];
  251. // Create/fetch scheduled conference
  252. if (!$schedConf =& $schedConfDao->getSchedConfByPath($id, $this->conferenceId)) {
  253. unset($schedConf);
  254. $schedConf = new SchedConf();
  255. $schedConf->setConferenceId($this->conferenceId);
  256. $schedConf->setPath($id);
  257. $schedConfDao->insertSchedConf($schedConf);
  258. $schedConfDao->resequenceSchedConfs($this->conferenceId);
  259. $schedConf->updateSetting('title', array(AppLocale::getLocale() => $conferenceInfo['name']), null, true);
  260. } else {
  261. $schedConf->updateSetting('title', array(AppLocale::getLocale() => $conferenceInfo['name']), null, true);
  262. }
  263. $this->schedConfMap[$id] =& $schedConf;
  264. $schedConfSettings = array(
  265. 'contactEmail' => array('string', Core::cleanVar($this->conferenceInfo[$id]['contact_email'])),
  266. 'contactName' => array('string', Core::cleanVar($this->conferenceInfo[$id]['contact_name']))
  267. );
  268. foreach ($schedConfSettings as $settingName => $settingInfo) {
  269. list($settingType, $settingValue) = $settingInfo;
  270. $schedConf->updateSetting($settingName, $settingValue, $settingType);
  271. }
  272. }
  273. /**
  274. * Import registrations and registration types.
  275. */
  276. function importRegistrations() {
  277. if ($this->hasOption('verbose')) {
  278. printf("Importing registrations\n");
  279. }
  280. $registrationTypeDao =& DAORegistry::getDAO('RegistrationTypeDAO');
  281. $registrationDao =& DAORegistry::getDAO('RegistrationDAO');
  282. $userDao =& DAORegistry::getDAO('UserDAO');
  283. $registrationTypes = array();
  284. foreach ($this->conferenceInfo as $conferenceId => $conferenceInfo) {
  285. $levels = array_map('trim', split("\n", Core::cleanVar($conferenceInfo['reg_levels'])));
  286. $fees = array_map('trim', split("\n", Core::cleanVar($conferenceInfo['reg_fees'])));
  287. $levelsLate = array_map('trim', split("\n", Core::cleanVar($conferenceInfo['reg_levels_late'])));
  288. $feesLate = array_map('trim', split("\n", Core::cleanVar($conferenceInfo['reg_fees_late'])));
  289. $lateDate = Core::cleanVar($conferenceInfo['reg_late_date']);
  290. $schedConf =& $this->schedConfMap[$conferenceId];
  291. foreach ($levels as $key => $level) {
  292. $fee = $fees[$key];
  293. $registrationType = new RegistrationType();
  294. $registrationType->setSchedConfId($schedConf->getId());
  295. $registrationType->setName($level, AppLocale::getLocale());
  296. $registrationType->setCost($fee);
  297. $registrationType->setCurrencyCodeAlpha('USD'); // FIXME?
  298. $registrationType->setOpeningDate(Core::cleanVar($conferenceInfo['accept_deadline']));
  299. $registrationType->setClosingDate($lateDate);
  300. $registrationType->setAccess(REGISTRATION_TYPE_ACCESS_ONLINE);
  301. $registrationType->setPublic(0);
  302. $registrationType->setInstitutional(0);
  303. $registrationType->setMembership(0);
  304. $registrationType->setSequence($key);
  305. $registrationTypeDao->insertRegistrationType($registrationType);
  306. $registrationTypes[substr($level, 0, 60)] =& $registrationType; // Truncated in 1.x DB
  307. unset($registrationType);
  308. }
  309. foreach ($levelsLate as $key => $level) {
  310. $fee = $feesLate[$key];
  311. $registrationType = new RegistrationType();
  312. $registrationType->setSchedConfId($schedConf->getId());
  313. $registrationType->setName($level . ' (Late)', AppLocale::getLocale());
  314. $registrationType->setCost($fee);
  315. $registrationType->setCurrencyCodeAlpha('USD'); // FIXME?
  316. $registrationType->setOpeningDate($lateDate);
  317. $registrationType->setClosingDate(Core::cleanVar($conferenceInfo['start_date']));
  318. $registrationType->setAccess(REGISTRATION_TYPE_ACCESS_ONLINE);
  319. $registrationType->setPublic(0);
  320. $registrationType->setInstitutional(0);
  321. $registrationType->setMembership(0);
  322. $registrationType->setSequence($key);
  323. $registrationTypeDao->insertRegistrationType($registrationType);
  324. $registrationTypes[substr($level, 0, 60) . ' (Late)'] =& $registrationType; // Truncated in 1.x DB
  325. unset($registrationType);
  326. }
  327. }
  328. $result =& $this->importDao->retrieve('SELECT * FROM registrants ORDER BY cf, id');
  329. while (!$result->EOF) {
  330. $row =& $result->fields;
  331. $schedConf =& $this->schedConfMap[$row['cf']];
  332. $email = Core::cleanVar($row['email']);
  333. if (!$user =& $userDao->getUserByEmail($email)) {
  334. // The user doesn't exist by email; create one.
  335. $name = Core::cleanVar($row['name']);
  336. $nameParts = split(' ', $name);
  337. $lastName = array_pop($nameParts);
  338. $firstName = join(' ', $nameParts);
  339. $user = new User();
  340. $user->setEmail($email);
  341. $user->setFirstName($firstName);
  342. $user->setLastName($lastName);
  343. $user->setPhone(Core::cleanVar($row['phone']));
  344. $user->setFax(Core::cleanVar($row['fax']));
  345. $user->setMailingAddress(Core::cleanVar($row['address']));
  346. $i = "";
  347. while ($userDao->userExistsByUsername($lastName . $i)) $i++;
  348. $user->setUsername($lastName . $i);
  349. $user->setDateRegistered($row['date_registered']);
  350. $user->setDateLastLogin(null);
  351. $user->setMustChangePassword(1);
  352. $password = Validation::generatePassword();
  353. $user->setPassword(Validation::encryptCredentials($user->getUsername(), $password));
  354. $userDao->insertUser($user);
  355. if ($this->hasOption('emailUsers')) {
  356. import('mail.MailTemplate');
  357. $mail = new MailTemplate('USER_REGISTER');
  358. $mail->setFrom($schedConf->getSetting('contactEmail'), $schedConf->getSetting('contactName'));
  359. $mail->assignParams(array('username' => $user->getUsername(), 'password' => $password, 'conferenceName' => $schedConf->getFullTitle()));
  360. $mail->addRecipient($user->getEmail(), $user->getFullName());
  361. $mail->send();
  362. }
  363. }
  364. $regLevel = trim(Core::cleanVar($row['reg_level']));
  365. $regFee = Core::cleanVar($row['reg_fee']);
  366. $conferenceInfo =& $this->conferenceInfo[$row['cf']];
  367. $seekingRegLevel = $regLevel . (strtotime($row['date_registered']) > strtotime($conferenceInfo['reg_late_date']) ? ' (Late)':'');
  368. $registrationType =& $registrationTypes[$seekingRegLevel];
  369. if (!$registrationType || $registrationType->getCost() != $regFee) {
  370. if (!$registrationType) $this->errors[] = "Registration data inconsistency: Registration type \"$seekingRegLevel\" not found for user with email $email.";
  371. else {
  372. $this->errors[] = "Registration data inconsistency: Paid registration fee $regFee does not match registration type cost for \"$seekingRegLevel\" (" . $registrationType->getCost() . ") for user with email $email.";
  373. unset($registrationType);
  374. }
  375. unset($user);
  376. unset($schedConf);
  377. $result->MoveNext();
  378. continue;
  379. }
  380. if ($registrationDao->registrationExistsByUser($user->getId(), $schedConf->getId())) {
  381. $this->errors[] = "A duplicate registration (level \"$seekingRegLevel\") was skipped for user with email $email.";
  382. } else {
  383. $registration = new Registration();
  384. $registration->setSchedConfId($schedConf->getId());
  385. $registration->setUserId($user->getId());
  386. $registration->setTypeId($registrationType->getTypeId());
  387. if ($row['has_paid'] == 'paid') $registration->setDatePaid(Core::cleanVar($row['date_paid']));
  388. $registration->setSpecialRequests(Core::cleanVar($row['special_requests']));
  389. $registration->setDateRegistered($row['date_registered']);
  390. $registrationDao->insertRegistration($registration);
  391. unset($registration);
  392. }
  393. unset($user);
  394. unset($registrationType);
  395. unset($conferenceInfo);
  396. unset($schedConf);
  397. $result->MoveNext();
  398. }
  399. $result->Close();
  400. }
  401. /**
  402. * Import tracks.
  403. */
  404. function importTracks() {
  405. if ($this->hasOption('verbose')) {
  406. printf("Importing tracks\n");
  407. }
  408. $trackDao =& DAORegistry::getDAO('TrackDAO');
  409. $result =& $this->importDao->retrieve('SELECT * FROM tracks ORDER BY cf, track_order');
  410. $oldConferenceId = null;
  411. while (!$result->EOF) {
  412. $row =& $result->fields;
  413. if ($oldConferenceId != $row['cf']) {
  414. $sequence = 0;
  415. $oldConferenceId = $row['cf'];
  416. }
  417. $track = new Track();
  418. $schedConf =& $this->schedConfMap[$row['cf']];
  419. $track->setSchedConfId($schedConf->getId());
  420. $track->setTitle(Core::cleanVar($row['track']), AppLocale::getLocale());
  421. $track->setSequence(++$sequence);
  422. $track->setDirectorRestricted(0);
  423. $track->setMetaReviewed(1);
  424. $trackId = $trackDao->insertTrack($track);
  425. $this->trackMap[$row['id']] = $trackId;
  426. $result->MoveNext();
  427. unset($track);
  428. unset($schedConf);
  429. }
  430. $result->Close();
  431. }
  432. /**
  433. * Import reviewers
  434. */
  435. function importReviewers() {
  436. if ($this->hasOption('verbose')) {
  437. printf("Importing reviewers\n");
  438. }
  439. import('file.PaperFileManager');
  440. import('search.PaperSearchIndex');
  441. $userDao =& DAORegistry::getDAO('UserDAO');
  442. $roleDao =& DAORegistry::getDAO('RoleDAO');
  443. $editAssignmentDao =& DAORegistry::getDAO('EditAssignmentDAO');
  444. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  445. $result =& $this->importDao->retrieve('SELECT * FROM reviewers');
  446. while (!$result->EOF) {
  447. $row =& $result->fields;
  448. $schedConf =& $this->schedConfMap[$row['cf']];
  449. $schedConfId = $schedConf->getId();
  450. $user = $userDao->getUserByUsername(Core::cleanVar($row['login']));
  451. if (!$user) {
  452. unset($user);
  453. $user = new User();
  454. $user->setUsername(Core::cleanVar($row['login']));
  455. $nameParts = split(' ', Core::cleanVar($row['name']));
  456. $firstName = array_shift($nameParts);
  457. $lastName = join(' ', $nameParts);
  458. $user->setFirstName(empty($firstName)?'(NONE)':$firstName);
  459. $user->setLastName(empty($lastName)?'(NONE)':$lastName);
  460. $user->setEmail(Core::cleanVar($row['email']));
  461. $user->setDateRegistered(Core::getCurrentDate());
  462. $user->setDateLastLogin(null);
  463. $user->setMustChangePassword(1);
  464. $password = Validation::generatePassword();
  465. $user->setPassword(Validation::encryptCredentials($user->getUsername(), $password));
  466. if ($this->hasOption('emailUsers')) {
  467. import('mail.MailTemplate');
  468. $mail = new MailTemplate('USER_REGISTER');
  469. $mail->setFrom($schedConf->getSetting('contactEmail'), $schedConf->getSetting('contactName'));
  470. $mail->assignParams(array('username' => $user->getUsername(), 'password' => $password, 'conferenceName' => $schedConf->getFullTitle()));
  471. $mail->addRecipient($user->getEmail(), $user->getFullName());
  472. $mail->send();
  473. }
  474. $user->setDisabled(0);
  475. $otherUser =& $userDao->getUserByEmail(Core::cleanVar($row['email']));
  476. if ($otherUser !== null) {
  477. // User exists with this email -- munge it to make unique
  478. $user->setEmail('ocs-' . Core::cleanVar($row['login']) . '+' . Core::cleanVar($row['email']));
  479. $this->conflicts[] = array(&$otherUser, &$user);
  480. }
  481. unset($otherUser);
  482. $userDao->insertUser($user);
  483. // Make this user a author
  484. $role = new Role();
  485. $role->setSchedConfId($schedConf->getId());
  486. $role->setConferenceId($schedConf->getConferenceId());
  487. $role->setUserId($user->getId());
  488. $role->setRoleId(ROLE_ID_REVIEWER);
  489. $roleDao->insertRole($role);
  490. unset($role);
  491. }
  492. $this->reviewerMap[$row['login']] =& $user;
  493. unset($schedConf);
  494. unset($user);
  495. $result->MoveNext();
  496. }
  497. $result->Close();
  498. }
  499. /**
  500. * Import papers (including metadata and files).
  501. */
  502. function importPapers() {
  503. if ($this->hasOption('verbose')) {
  504. printf("Importing papers\n");
  505. }
  506. import('file.PaperFileManager');
  507. import('search.PaperSearchIndex');
  508. $userDao =& DAORegistry::getDAO('UserDAO');
  509. $roleDao =& DAORegistry::getDAO('RoleDAO');
  510. $trackDao =& DAORegistry::getDAO('TrackDAO');
  511. $paperDao =& DAORegistry::getDAO('PaperDAO');
  512. $publishedPaperDao =& DAORegistry::getDAO('PublishedPaperDAO');
  513. $galleyDao =& DAORegistry::getDAO('PaperGalleyDAO');
  514. $unassignedTrackId = null;
  515. $result =& $this->importDao->retrieve('SELECT * FROM papers ORDER by id');
  516. while (!$result->EOF) {
  517. $row =& $result->fields;
  518. $schedConf =& $this->schedConfMap[$row['cf']];
  519. $schedConfId = $schedConf->getId();
  520. // Bring in the primary user for this paper.
  521. $user = $userDao->getUserByUsername(Core::cleanVar($row['login']));
  522. if (!$user) {
  523. unset($user);
  524. $user = new User();
  525. $user->setUsername(Core::cleanVar($row['login']));
  526. $user->setFirstName(Core::cleanVar($row['first_name']));
  527. $user->setLastName(Core::cleanVar($row['surname']));
  528. $user->setAffiliation(Core::cleanVar($row['affiliation']));
  529. $user->setEmail(Core::cleanVar($row['email']));
  530. $user->setUrl(Core::cleanVar($row['url']));
  531. $user->setBiography(Core::cleanVar($row['bio']), AppLocale::getLocale());
  532. $user->setLocales(array());
  533. $user->setDateRegistered($row['created']);
  534. $user->setDateLastLogin($row['created']);
  535. $user->setMustChangePassword(1);
  536. $password = Validation::generatePassword();
  537. $user->setPassword(Validation::encryptCredentials($user->getUsername(), $password));
  538. if ($this->hasOption('emailUsers')) {
  539. import('mail.MailTemplate');
  540. $mail = new MailTemplate('USER_REGISTER');
  541. $mail->setFrom($schedConf->getSetting('contactEmail'), $schedConf->getSetting('contactName'));
  542. $mail->assignParams(array('username' => $user->getUsername(), 'password' => $password, 'conferenceName' => $schedConf->getFullTitle()));
  543. $mail->addRecipient($user->getEmail(), $user->getFullName());
  544. $mail->send();
  545. }
  546. $user->setDisabled(0);
  547. $otherUser =& $userDao->getUserByEmail(Core::cleanVar($row['email']));
  548. if ($otherUser !== null) {
  549. // User exists with this email -- munge it to make unique
  550. $user->setEmail('ocs-' . Core::cleanVar($row['login']) . '+' . Core::cleanVar($row['email']));
  551. $this->conflicts[] = array(&$otherUser, &$user);
  552. }
  553. unset($otherUser);
  554. $userDao->insertUser($user);
  555. // Make this user a author
  556. $role = new Role();
  557. $role->setSchedConfId($schedConf->getId());
  558. $role->setConferenceId($schedConf->getConferenceId());
  559. $role->setUserId($user->getId());
  560. $role->setRoleId(ROLE_ID_AUTHOR);
  561. $roleDao->insertRole($role);
  562. unset($role);
  563. }
  564. $userId = $user->getId();
  565. // Bring in the basic entry for the paper
  566. $paper = new Paper();
  567. $paper->setUserId($userId);
  568. $paper->setSchedConfId($schedConfId);
  569. $oldTrackId = $row['primary_track_id'];
  570. if (!$oldTrackId || !isset($this->trackMap[$oldTrackId])) {
  571. $oldTrackId = $row['secondary_track_id'];
  572. }
  573. if (!$oldTrackId || !isset($this->trackMap[$oldTrackId])) {
  574. if (!$unassignedTrackId) {
  575. // Create an "Unassigned" track to use for submissions
  576. // that didn't have a track in OCS 1.x.
  577. $track = new Track();
  578. $track->setSchedConfId($schedConf->getId());
  579. $track->setTitle('UNASSIGNED', AppLocale::getLocale());
  580. $track->setSequence(REALLY_BIG_NUMBER);
  581. $track->setDirectorRestricted(1);
  582. $track->setMetaReviewed(1);
  583. $unassignedTrackId = $trackDao->insertTrack($track);
  584. }
  585. $newTrackId = $unassignedTrackId;
  586. } else {
  587. $newTrackId = $this->trackMap[$oldTrackId];
  588. }
  589. $paper->setTrackId($newTrackId);
  590. $paper->setTitle(Core::cleanVar($row['title']), AppLocale::getLocale());
  591. $paper->setAbstract(Core::cleanVar($row['abstract']), AppLocale::getLocale());
  592. $paper->setDiscipline(Core::cleanVar($row['discipline']), AppLocale::getLocale());
  593. $paper->setSponsor(Core::cleanVar($row['sponsor']), AppLocale::getLocale());
  594. $paper->setSubject(Core::cleanVar($row['topic']), AppLocale::getLocale());
  595. $paper->setLanguage(Core::cleanVar($row['language']));
  596. $paper->setDateSubmitted($row['created']);
  597. $paper->setDateStatusModified($row['timestamp']);
  598. // $paper->setTypeConst($row['present_format'] == 'multiple' ? SUBMISSION_TYPE_PANEL : SUBMISSION_TYPE_SINGLE); FIXME
  599. $paper->setCurrentStage(REVIEW_STAGE_ABSTRACT);
  600. $paper->setSubmissionProgress(0);
  601. $paper->setPages('');
  602. // Bring in authors
  603. $firstNames = split("\n", Core::cleanVar($row['first_name'] . "\n" . $row['add_first_names']));
  604. $lastNames = split("\n", Core::cleanVar($row['surname'] . "\n" . $row['add_surnames']));
  605. $emails = split("\n", Core::cleanVar($row['email'] . "\n" . $row['add_emails']));
  606. $affiliations = split("\n", Core::cleanVar($row['affiliation'] . "\n" . $row['add_affiliations']));
  607. $urls = split("\n", Core::cleanVar($row['url'] . "\n" . $row['add_urls']));
  608. foreach ($emails as $key => $email) {
  609. if (empty($email)) continue;
  610. $author = new Author();
  611. $author->setEmail($email);
  612. $author->setFirstName($firstNames[$key]);
  613. $author->setLastName($lastNames[$key]);
  614. $author->setAffiliation($affiliations[$key]);
  615. @$author->setUrl($urls[$key]); // Suppress warnings from inconsistent OCS 1.x data
  616. $author->setPrimaryContact($key == 0 ? 1 : 0);
  617. $paper->addAuthor($author);
  618. unset($author);
  619. }
  620. switch ($row['accepted']) {
  621. case 'true':
  622. $paper->setStatus(STATUS_PUBLISHED);
  623. $paperId = $paperDao->insertPaper($paper);
  624. $publishedPaper = new PublishedPaper();
  625. $publishedPaper->setPaperId($paperId);
  626. $publishedPaper->setSchedConfId($schedConfId);
  627. $publishedPaper->setDatePublished(Core::getCurrentDate());
  628. $publishedPaper->setSeq(REALLY_BIG_NUMBER);
  629. $publishedPaper->setViews(0);
  630. $publishedPaperDao->insertPublishedPaper($publishedPaper);
  631. $publishedPaperDao->resequencePublishedPapers($paper->getTrackId(), $schedConfId);
  632. break;
  633. case 'reject':
  634. $paper->setStatus(STATUS_DECLINED);
  635. $paperId = $paperDao->insertPaper($paper);
  636. break;
  637. default:
  638. $paper->setStatus(STATUS_QUEUED);
  639. $paperId = $paperDao->insertPaper($paper);
  640. }
  641. $this->paperMap[$row['id']] =& $paper;
  642. $paperFileManager = new PaperFileManager($paperId);
  643. if (!empty($row['paper']) && $row['paper'] != 'PDF') {
  644. $format = 'text/html';
  645. $extension = $paperFileManager->getDocumentExtension($format);
  646. $fileId = $paperFileManager->writeSubmissionFile('migratedFile' . $extension, $row['paper'], $format);
  647. $paper->setSubmissionFileId($fileId);
  648. $paperDao->updatePaper($paper);
  649. $fileId = $paperFileManager->writePublicFile('migratedGalley' . $extension, $row['paper'], $format);
  650. PaperSearchIndex::updateFileIndex($paperId, PAPER_SEARCH_GALLEY_FILE, $fileId);
  651. if (strstr($format, 'html')) {
  652. $galley = new PaperHTMLGalley();
  653. $galley->setLabel('HTML');
  654. } else {
  655. $galley = new PaperGalley();
  656. switch ($format) {
  657. case 'application/pdf': $galley->setLabel('PDF'); break;
  658. case 'application/postscript': $galley->setLabel('PostScript'); break;
  659. case 'application/msword': $galley->setLabel('Word'); break;
  660. case 'text/xml': $galley->setLabel('XML'); break;
  661. case 'application/powerpoint': $galley->setLabel('Slideshow'); break;
  662. default: $galley->setLabel('Untitled'); break;
  663. }
  664. }
  665. $galley->setLocale(AppLocale::getLocale());
  666. $galley->setPaperId($paperId);
  667. $galley->setFileId($fileId);
  668. $galleyDao->insertGalley($galley);
  669. unset($galley);
  670. } elseif ($row['paper'] == 'PDF') {
  671. $fileId = $paperFileManager->copySubmissionFile($this->importPath . '/papers/' . $row['pdf'], 'application/pdf');
  672. $paper->setSubmissionFileId($fileId);
  673. $paperDao->updatePaper($paper);
  674. $fileId = $paperFileManager->copyPublicFile($this->importPath . '/papers/' . $row['pdf'], 'application/pdf');
  675. PaperSearchIndex::updateFileIndex($paperId, PAPER_SEARCH_GALLEY_FILE, $fileId);
  676. $galley = new PaperGalley();
  677. $galley->setLabel('PDF');
  678. $galley->setLocale(AppLocale::getLocale());
  679. $galley->setPaperId($paperId);
  680. $galley->setFileId($fileId);
  681. $galleyDao->insertGalley($galley);
  682. unset($galley);
  683. }
  684. // FIXME: The following fields from OCS 1.x are UNUSED:
  685. // program_insert approach coverage format relation appendix_names appendix_dates
  686. // appendix appendix_pdf secondary_track_id multiple_* restrict_access paper_email
  687. // delete_paper comment_email
  688. unset($user);
  689. unset($paper);
  690. unset($schedConf);
  691. unset($paperFileManager);
  692. $result->MoveNext();
  693. }
  694. $result->Close();
  695. }
  696. /**
  697. * Import reviews.
  698. */
  699. function importReviews() {
  700. if ($this->hasOption('verbose')) {
  701. printf("Importing reviews\n");
  702. }
  703. $userDao =& DAORegistry::getDAO('UserDAO');
  704. $roleDao =& DAORegistry::getDAO('RoleDAO');
  705. $editAssignmentDao =& DAORegistry::getDAO('EditAssignmentDAO');
  706. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  707. $paperCommentDao =& DAORegistry::getDAO('PaperCommentDAO');
  708. $unassignedTrackId = null;
  709. $result =& $this->importDao->retrieve('SELECT * FROM reviews ORDER by timestamp');
  710. while (!$result->EOF) {
  711. $row =& $result->fields;
  712. $schedConf =& $this->schedConfMap[$row['cf']];
  713. $paper =& $this->paperMap[$row['paper']];
  714. $reviewer =& $this->reviewerMap[$row['reviewer']];
  715. if (!$schedConf || !$paper || !$reviewer) {
  716. // Database inconsistency! Skip this entry.
  717. if (!$schedConf) $errors[] = "Unknown conference referenced in reviews: $row[cf]";
  718. else unset($schedConf);
  719. if (!$paper) $errors[] = "Unknown paper referenced in reviews: $row[paper]";
  720. else unset($paper);
  721. if (!$reviewer) $errors[] = "Unknown reviewer referenced in reviews: $row[reviewer]";
  722. else unset($reviewer);
  723. $result->MoveNext();
  724. continue;
  725. }
  726. $schedConfId = $schedConf->getId();
  727. $paperId = $paper->getId();
  728. $reviewerId = $reviewer->getId();
  729. $reviewAssignment = new ReviewAssignment();
  730. $reviewAssignment->setReviewerId($reviewerId);
  731. $reviewAssignment->setPaperId($paperId);
  732. $reviewAssignment->setStage(REVIEW_STAGE_ABSTRACT); // Won't always be accurate
  733. $reviewAssignment->setDateAssigned($row['timestamp']);
  734. $reviewAssignment->setDateNotified($row['timestamp']);
  735. $reviewAssignment->setDateConfirmed($row['timestamp']);
  736. $reviewAssignment->setDeclined(0);
  737. switch (trim(strtolower(array_shift(split("[\n\.:]", $row['recommendation']))))) {
  738. case 'accept':
  739. $reviewAssignment->setRecommendation(SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT);
  740. $reviewAssignment->setDateCompleted($row['timestamp']);
  741. break;
  742. case 'revise':
  743. case 'pending revisions':
  744. case 'accept with revisions':
  745. $reviewAssignment->setRecommendation(SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS);
  746. $reviewAssignment->setDateCompleted($row['timestamp']);
  747. break;
  748. case 'decline':
  749. case 'reject':
  750. $reviewAssignment->setRecommendation(SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE);
  751. $reviewAssignment->setDateCompleted($row['timestamp']);
  752. break;
  753. default:
  754. // WARNING: We're not setting a recommendation here at all!
  755. break;
  756. }
  757. $reviewId = $reviewAssignmentDao->insertReviewAssignment($reviewAssignment);
  758. $paperComment = new PaperComment();
  759. $paperComment->setCommentType(COMMENT_TYPE_PEER_REVIEW);
  760. $paperComment->setRoleId(ROLE_ID_REVIEWER);
  761. $paperComment->setPaperId($paperId);
  762. $paperComment->setAssocId($reviewId);
  763. $paperComment->setAuthorId($reviewerId);
  764. $paperComment->setCommentTitle('');
  765. $paperComment->setComments(Core::cleanVar($row['comments'] . "\n" . $row['recommendation']));
  766. $paperComment->setDatePosted($row['timestamp']);
  767. $paperComment->setViewable(0);
  768. $paperCommentDao->insertPaperComment($paperComment);
  769. unset($schedConf);
  770. unset($paper);
  771. unset($reviewer);
  772. unset($reviewAssignment);
  773. unset($paperComment);
  774. $result->MoveNext();
  775. }
  776. $result->Close();
  777. }
  778. //
  779. // Helper functions
  780. //
  781. /**
  782. * Rebuild the paper search index.
  783. * Note: Rebuilds index for _all_ conferences (non-optimal, but shouldn't be a problem)
  784. * Based on code from tools/rebuildSearchIndex.php
  785. */
  786. function rebuildSearchIndex() {
  787. if ($this->hasOption('verbose')) {
  788. printf("Rebuilding search index\n");
  789. }
  790. PaperSearchIndex::rebuildIndex();
  791. }
  792. /**
  793. * Get the list of conflicting user accounts.
  794. */
  795. function getConflicts() {
  796. return $this->conflicts;
  797. }
  798. /**
  799. * Get the list of errors.
  800. */
  801. function getErrors() {
  802. return $this->errors;
  803. }
  804. }
  805. ?>