Open Monograph Press  3.3.0
Upgrade.inc.php
1 <?php
2 
17 import('lib.pkp.classes.install.Installer');
18 
19 class Upgrade extends Installer {
20 
25  function __construct($params, $installFile = 'upgrade.xml', $isPlugin = false) {
26  parent::__construct($installFile, $params, $isPlugin);
27  }
28 
29 
34  function isUpgrade() {
35  return true;
36  }
37 
38 
39  //
40  // Specific upgrade actions
41  //
42 
50  function fixFilenames($upgrade, $params, $dryrun = false) {
51  $pressDao = DAORegistry::getDAO('PressDAO'); /* @var $pressDao PressDAO */
52  $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */
53  $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */
54  DAORegistry::getDAO('GenreDAO'); // Load constants
55  $siteDao = DAORegistry::getDAO('SiteDAO'); /* @var $siteDao SiteDAO */
56  $site = $siteDao->getSite();
57  $adminEmail = $site->getLocalizedContactEmail();
58 
59  import('lib.pkp.classes.file.SubmissionFileManager');
60 
61  $contexts = $pressDao->getAll();
62  while ($context = $contexts->next()) {
63  $submissions = $submissionDao->getByContextId($context->getId());
64  while ($submission = $submissions->next()) {
65  $submissionFileManager = new SubmissionFileManager($context->getId(), $submission->getId());
66  $submissionFiles = $submissionFileDao->getBySubmissionId($submission->getId());
67  foreach ($submissionFiles as $submissionFile) {
68  $generatedFilename = $submissionFile->getServerFileName();
69  $basePath = $submissionFileManager->getBasePath() . $submissionFile->_fileStageToPath($submissionFile->getFileStage()) . '/';
70  $globPattern = $submissionFile->getSubmissionId() . '-' .
71  '*' . '-' . // Genre name and designation globbed (together)
72  $submissionFile->getFileId() . '-' .
73  $submissionFile->getRevision() . '-' .
74  $submissionFile->getFileStage() . '-' .
75  date('Ymd', strtotime($submissionFile->getDateUploaded())) .
76  '.' . strtolower_codesafe($submissionFile->getExtension());
77 
78  $matchedResults = glob($basePath . $globPattern);
79  if (count($matchedResults)>1) {
80  error_log("Duplicate potential files for \"$globPattern\"!", 1, $adminEmail);
81  continue;
82  }
83  if (count($matchedResults) == 1) {
84  // 1 result matched.
85  $discoveredFilename = array_shift($matchedResults);
86  if ($dryrun) {
87  echo "Need to rename \"$discoveredFilename\" to \"$generatedFilename\".\n";
88  } else {
89  rename($discoveredFilename, $basePath . $generatedFilename);
90  }
91  } else {
92  // 0 results matched.
93  error_log("Unable to find a match for \"$globPattern\".\n", 1, $adminEmail);
94  continue;
95  }
96  }
97  }
98  }
99  return true;
100  }
101 
106  function enableDefaultTheme() {
107  $pressDao = DAORegistry::getDAO('PressDAO'); /* @var $pressDao PressDAO */
108  $contexts = $pressDao->getAll();
109  $pluginSettingsDao = DAORegistry::getDAO('PluginSettingsDAO'); /* @var $pluginSettingsDao PluginSettingsDAO */
110 
111  // Site-wide
112  $pluginSettingsDao->updateSetting(0, 'defaultthemeplugin', 'enabled', '1', 'int');
113 
114  // For each press
115  while ($context = $contexts->next()) {
116  $pluginSettingsDao->updateSetting($context->getId(), 'defaultthemeplugin', 'enabled', '1', 'int');
117  }
118  return true;
119  }
120 
125  function syncSeriesAssocType() {
126  // Can be any DAO.
127  $dao =& DAORegistry::getDAO('UserDAO'); /* @var $dao DAO */
128  $tablesToUpdate = array(
129  'features',
130  'data_object_tombstone_oai_set_objects',
131  'new_releases',
132  'spotlights',
133  'notifications',
134  'email_templates',
135  'email_templates_data',
136  'controlled_vocabs',
137  'event_log',
138  'email_log',
139  'metadata_descriptions',
140  'notes',
141  'item_views');
142 
143  foreach ($tablesToUpdate as $tableName) {
144  $dao->update('UPDATE ' . $tableName . ' SET assoc_type = ' . ASSOC_TYPE_SERIES . ' WHERE assoc_type = 526');
145  }
146 
147  return true;
148  }
149 
154  function fixAuthorSettings() {
155  $authorDao = DAORegistry::getDAO('AuthorDAO'); /* @var $authorDao AuthorDAO */
156 
157  // Get all authors with broken data
158  $result = $authorDao->retrieve(
159  'SELECT DISTINCT author_id
160  FROM author_settings
161  WHERE (setting_name = ? OR setting_name = ?)
162  AND setting_type = ?',
163  array('affiliation', 'biography', 'object')
164  );
165 
166  while (!$result->EOF) {
167  $row = $result->getRowAssoc(false);
168  $authorId = $row['author_id'];
169  $result->MoveNext();
170 
171  $author = $authorDao->getById($authorId);
172  if (!$author) continue; // Bonehead check (DB integrity)
173 
174  foreach ((array) $author->getAffiliation(null) as $locale => $affiliation) {
175  if (is_array($affiliation)) foreach($affiliation as $locale => $s) {
176  $author->setAffiliation($s, $locale);
177  }
178  }
179 
180  foreach ((array) $author->getBiography(null) as $locale => $biography) {
181  if (is_array($biography)) foreach($biography as $locale => $s) {
182  $author->setBiography($s, $locale);
183  }
184  }
185  $authorDao->updateObject($author);
186  }
187 
188  $result->Close();
189  return true;
190  }
191 
197  $emailTemplateDao = DAORegistry::getDAO('EmailTemplateDAO'); /* @var $emailTemplateDao EmailTemplateDAO */
198 
199  // Convert the email templates in email_templates_data to localized
200  $result = $emailTemplateDao->retrieve('SELECT * FROM email_templates_data');
201  while (!$result->EOF) {
202  $row = $result->getRowAssoc(false);
203  $emailTemplateDao->update(
204  'UPDATE email_templates_data
205  SET body = ?
206  WHERE email_key = ? AND
207  locale = ? AND
208  assoc_type = ? AND
209  assoc_id = ?',
210  array(
211  preg_replace('/{\$[a-zA-Z]+Url}/', '<a href="\0">\0</a>', nl2br($row['body'])),
212  $row['email_key'],
213  $row['locale'],
214  $row['assoc_type'],
215  $row['assoc_id']
216  )
217  );
218  $result->MoveNext();
219  }
220  $result->Close();
221 
222  // Convert the email templates in email_templates_default_data to localized
223  $result = $emailTemplateDao->retrieve('SELECT * FROM email_templates_default_data');
224  while (!$result->EOF) {
225  $row = $result->getRowAssoc(false);
226  $emailTemplateDao->update(
227  'UPDATE email_templates_default_data
228  SET body = ?
229  WHERE email_key = ? AND
230  locale = ?',
231  array(
232  preg_replace('/{\$[a-zA-Z]+Url}/', '<a href="\0">\0</a>', nl2br($row['body'])),
233  $row['email_key'],
234  $row['locale'],
235  )
236  );
237  $result->MoveNext();
238  }
239  $result->Close();
240 
241  // Localize the email header and footer fields.
242  $contextDao = DAORegistry::getDAO('PressDAO'); /* @var $contextDao PressDAO */
243  $settingsDao = DAORegistry::getDAO('PressSettingsDAO'); /* @var $settingsDao PressSettingsDAO */
244  $contexts = $contextDao->getAll();
245  while ($context = $contexts->next()) {
246  foreach (array('emailFooter', 'emailSignature') as $settingName) {
247  $settingsDao->updateSetting(
248  $context->getId(),
249  $settingName,
250  $context->getData('emailHeader'),
251  'string'
252  );
253  }
254  }
255 
256  return true;
257  }
258 
263  function convertQueries() {
264  $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */
265  import('lib.pkp.classes.submission.SubmissionFile');
266 
267  $filesResult = $submissionFileDao->retrieve(
268  'SELECT DISTINCT sf.file_id, sf.assoc_type, sf.assoc_id, s.symbolic, s.date_notified, s.date_completed, s.user_id, s.signoff_id FROM submission_files sf, signoffs s WHERE s.assoc_type=? AND s.assoc_id=sf.file_id AND s.symbolic IN (?, ?)',
269  array(ASSOC_TYPE_SUBMISSION_FILE, 'SIGNOFF_COPYEDITING', 'SIGNOFF_PROOFING')
270  );
271 
272  $queryDao = DAORegistry::getDAO('QueryDAO'); /* @var $queryDao QueryDAO */
273  $noteDao = DAORegistry::getDAO('NoteDAO'); /* @var $noteDao NoteDAO */
274  $userDao = DAORegistry::getDAO('UserDAO'); /* @var $userDao UserDAO */
275  $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /* @var $stageAssignmentDao StageAssignmentDAO */
276 
277  //
278  // 1. Go through all signoff/file pairs and migrate them into queries.
279  // Queries should be created per file and users should be consolidated
280  // from potentially multiple audit assignments into fewer queries.
281  //
282 
283  while (!$filesResult->EOF) {
284  $row = $filesResult->getRowAssoc(false);
285  $fileId = $row['file_id'];
286  $symbolic = $row['symbolic'];
287  $dateNotified = $row['date_notified']?strtotime($row['date_notified']):null;
288  $dateCompleted = $row['date_completed']?strtotime($row['date_completed']):null;
289  $userId = $row['user_id'];
290  $signoffId = $row['signoff_id'];
291  $fileAssocType = $row['assoc_type'];
292  $fileAssocId = $row['assoc_id'];
293  $filesResult->MoveNext();
294 
295  $submissionFiles = $submissionFileDao->getAllRevisions($fileId);
296  assert(count($submissionFiles)>0);
297  $anyFile = end($submissionFiles);
298 
299  $assocType = $assocId = $query = null; // Prevent PHP scrutinizer warnings
300  switch ($symbolic) {
301  case 'SIGNOFF_COPYEDITING':
302  $query = $queryDao->newDataObject();
303  $query->setAssocType($assocType = ASSOC_TYPE_SUBMISSION);
304  $query->setAssocId($assocId = $anyFile->getSubmissionId());
305  $query->setStageId(WORKFLOW_STAGE_ID_EDITING);
306  break;
307  case 'SIGNOFF_PROOFING':
308  // We've already migrated a signoff for this file; add this user to it too.
309  if ($anyFile->getAssocType() == ASSOC_TYPE_NOTE) {
310  $note = $noteDao->getById($anyFile->getAssocId());
311  assert($note && $note->getAssocType() == ASSOC_TYPE_QUERY);
312  if (count($queryDao->getParticipantIds($note->getAssocId(), $userId))==0) $queryDao->insertParticipant($anyFile->getAssocId(), $userId);
313  $this->_transferSignoffData($signoffId, $note->getAssocId());
314  continue 2;
315  }
316  $query = $queryDao->newDataObject();
317  assert($anyFile->getAssocType()==ASSOC_TYPE_REPRESENTATION);
318  $query->setAssocType($assocType = ASSOC_TYPE_SUBMISSION);
319  $query->setAssocId($assocId = $anyFile->getSubmissionId());
320  $query->setStageId(WORKFLOW_STAGE_ID_PRODUCTION);
321  break;
322  default: assert(false);
323  }
324  $query->setSequence(REALLY_BIG_NUMBER);
325  $query->setIsClosed($dateCompleted?true:false);
326  $queryDao->insertObject($query);
327  $queryDao->resequence($assocType, $assocId);
328 
329  // Build a list of all users who should be involved in the query
330  $user = $userDao->getById($userId);
331  $assignedUserIds = array($userId);
332  foreach (array(ROLE_ID_MANAGER, ROLE_ID_SUB_EDITOR, ROLE_ID_ASSISTANT) as $roleId) {
333  $stageAssignments = $stageAssignmentDao->getBySubmissionAndRoleId($anyFile->getSubmissionId(), $roleId, $query->getStageId());
334  while ($stageAssignment = $stageAssignments->next()) {
335  $assignedUserIds[] = $stageAssignment->getUserId();
336  }
337  }
338  // Add the assigned auditor as a query participant
339  foreach (array_unique($assignedUserIds) as $assignedUserId) {
340  $queryDao->insertParticipant($query->getId(), $assignedUserId);
341  }
342 
343  // Create a head note
344  $headNote = $noteDao->newDataObject();
345  $headNote->setAssocType(ASSOC_TYPE_QUERY);
346  $headNote->setAssocId($query->getId());
347  switch($symbolic) {
348  case 'SIGNOFF_COPYEDITING':
349  $headNote->setTitle('Copyediting for "' . $anyFile->getFileLabel() . '"');
350  $headNote->setContents('Auditing assignment for the file "' . htmlspecialchars($anyFile->getFileLabel()) . '" (Signoff ID: ' . $signoffId . ')');
351  break;
352  case 'SIGNOFF_PROOFING':
353  $headNote->setTitle('Proofreading for ' . $anyFile->getFileLabel());
354  $headNote->setContents('Proofing assignment for the file "' . htmlspecialchars($anyFile->getFileLabel()) . '" (Signoff ID: ' . $signoffId . ')');
355  break;
356  default: assert(false);
357  }
358  $noteDao->insertObject($headNote);
359 
360  // Correct the creation date (automatically assigned) with the signoff value
361  $headNote->setDateCreated($dateNotified);
362  $noteDao->updateObject($headNote);
363 
364  // Add completion as a note
365  if ($dateCompleted) {
366  $completionNote = $noteDao->newDataObject();
367  $completionNote->setAssocType(ASSOC_TYPE_QUERY);
368  $completionNote->setAssocId($query->getId());
369  $completionNote->setContents('The assignment is complete.');
370  $completionNote->setUserId($userId);
371  $noteDao->insertObject($completionNote);
372  $completionNote->setDateCreated($dateCompleted);
373  $noteDao->updateObject($completionNote);
374  }
375 
376  $this->_transferSignoffData($signoffId, $query->getId());
377  }
378  $filesResult->Close();
379  return true;
380  }
381 
390  function fixQueriesAssocTypes() {
391  // Get queries by submission ids, in order to resequence them correctly after the assoc_type change
392  $queryDao = DAORegistry::getDAO('QueryDAO'); /* @var $queryDao QueryDAO */
393  $allQueriesResult = $queryDao->retrieve(
394  'SELECT DISTINCT q.*,
395  COALESCE(pf.submission_id, qs.assoc_id) AS submission_id
396  FROM queries q
397  LEFT JOIN publication_formats pf ON (q.assoc_type = ? AND q.assoc_id = pf.publication_format_id AND q.stage_id = ?)
398  LEFT JOIN queries qs ON (qs.assoc_type = ?)
399  WHERE q.assoc_type = ? OR q.assoc_type = ?
400  ORDER BY query_id',
401  array((int) ASSOC_TYPE_REPRESENTATION, (int) WORKFLOW_STAGE_ID_PRODUCTION, (int) ASSOC_TYPE_SUBMISSION, (int) ASSOC_TYPE_SUBMISSION, (int) ASSOC_TYPE_REPRESENTATION)
402  );
403  $allQueries = array();
404  while (!$allQueriesResult->EOF) {
405  $row = $allQueriesResult->getRowAssoc(false);
406  $allQueries[$row['submission_id']]['queries'][] = $query = $queryDao->_fromRow($row);
407  // mark if this submission queries should be fixed
408  $fix = array_key_exists('fix', $allQueries[$row['submission_id']]) ? $allQueries[$row['submission_id']]['fix'] : false;
409  $allQueries[$row['submission_id']]['fix'] = ($query->getAssocType() == ASSOC_TYPE_REPRESENTATION) || $fix;
410  $allQueriesResult->MoveNext();
411  }
412  $allQueriesResult->Close();
413  foreach ($allQueries as $submissionId => $queriesBySubmission) {
414  // Touch i.e. fix and resequence only the submission queries that contained assoc_type = ASSOC_TYPE_REPRESENTATION
415  if ($allQueries[$submissionId]['fix']) {
416  $i = 1;
417  foreach($queriesBySubmission['queries'] as $query) {
418  if ($query->getAssocType() == ASSOC_TYPE_REPRESENTATION) {
419  $query->setAssocType(ASSOC_TYPE_SUBMISSION);
420  $query->setAssocId($submissionId);
421  }
422  $query->setSequence($i);
423  $queryDao->updateObject($query);
424  $i++;
425  }
426  }
427  }
428  return true;
429  }
430 
436  $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */
437  $stageAssignmetDao = DAORegistry::getDAO('StageAssignmentDAO'); /* @var $stageAssignmetDao StageAssignmentDAO */
438  $queryDao = DAORegistry::getDAO('QueryDAO'); /* @var $queryDao QueryDAO */
439  $noteDao = DAORegistry::getDAO('NoteDAO'); /* @var $noteDao NoteDAO */
440  $userGroupDao = DAORegistry::getDAO('UserGroupDAO'); /* @var $userGroupDao UserGroupDAO */
441 
442  import('lib.pkp.classes.security.Role'); // ROLE_ID_...
443 
444  $commentsResult = $submissionDao->retrieve(
445  'SELECT s.submission_id, s.context_id, s.comments_to_ed, s.date_submitted
446  FROM submissions_tmp s
447  WHERE s.comments_to_ed IS NOT NULL AND s.comments_to_ed != \'\''
448  );
449  while (!$commentsResult->EOF) {
450  $row = $commentsResult->getRowAssoc(false);
451  $comments_to_ed = PKPString::stripUnsafeHtml($row['comments_to_ed']);
452  if ($comments_to_ed != ""){
453  $userId = null;
454  $authorAssignmentsResult = $stageAssignmetDao->getBySubmissionAndRoleId($row['submission_id'], ROLE_ID_AUTHOR);
455  if ($authorAssignmentsResult->getCount() != 0) {
456  // We assume the results are ordered by stage_assignment_id i.e. first author assignemnt is first
457  $userId = $authorAssignmentsResult->next()->getUserId();
458  } else {
459  $managerUserGroup = $userGroupDao->getDefaultByRoleId($row['context_id'], ROLE_ID_MANAGER);
460  $managerUsers = $userGroupDao->getUsersById($managerUserGroup->getId(), $row['context_id']);
461  $userId = $managerUsers->next()->getId();
462  }
463  assert($userId);
464 
465  $query = $queryDao->newDataObject();
466  $query->setAssocType(ASSOC_TYPE_SUBMISSION);
467  $query->setAssocId($row['submission_id']);
468  $query->setStageId(WORKFLOW_STAGE_ID_SUBMISSION);
469  $query->setSequence(REALLY_BIG_NUMBER);
470 
471  $queryDao->insertObject($query);
472  $queryDao->resequence(ASSOC_TYPE_SUBMISSION, $row['submission_id']);
473  $queryDao->insertParticipant($query->getId(), $userId);
474 
475  $queryId = $query->getId();
476 
477  $note = $noteDao->newDataObject();
478  $note->setUserId($userId);
479  $note->setAssocType(ASSOC_TYPE_QUERY);
480  $note->setTitle('Cover Note to Editor');
481  $note->setContents($comments_to_ed);
482  $note->setDateCreated(strtotime($row['date_submitted']));
483  $note->setDateModified(strtotime($row['date_submitted']));
484  $note->setAssocId($queryId);
485  $noteDao->insertObject($note);
486  }
487  $commentsResult->MoveNext();
488  }
489  $commentsResult->Close();
490 
491  // remove temporary table
492  $submissionDao->update('DROP TABLE submissions_tmp');
493 
494  return true;
495  }
496 
502  private function _transferSignoffData($signoffId, $queryId) {
503  $noteDao = DAORegistry::getDAO('NoteDAO'); /* @var $noteDao NoteDAO */
504  $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */
505  $userDao = DAORegistry::getDAO('UserDAO'); /* @var $userDao UserDAO */
506 
507  $notes = $noteDao->getByAssoc(1048582 /* ASSOC_TYPE_SIGNOFF */, $signoffId);
508  while ($note = $notes->next()) {
509  $note->setAssocType(ASSOC_TYPE_QUERY);
510  $note->setAssocId($queryId);
511  $noteDao->updateObject($note);
512 
513  // Convert any attached files
514  $submissionFiles = $submissionFileDao->getAllRevisionsByAssocId(ASSOC_TYPE_NOTE, $note->getId());
515  foreach ($submissionFiles as $submissionFile) {
516  $submissionFile->setAssocType(ASSOC_TYPE_NOTE);
517  $submissionFile->setAssocId($note->getId());
518  $submissionFile->setFileStage(SUBMISSION_FILE_QUERY);
519  $submissionFileDao->updateObject($submissionFile);
520  }
521  }
522 
523  // Transfer signoff signoffs into notes
524  $signoffsResult = $submissionFileDao->retrieve(
525  'SELECT * FROM signoffs WHERE symbolic = ? AND assoc_type = ? AND assoc_id = ?',
526  array('SIGNOFF_SIGNOFF', 1048582 /* ASSOC_TYPE_SIGNOFF */, $signoffId)
527  );
528  while (!$signoffsResult->EOF) {
529  $row = $signoffsResult->getRowAssoc(false);
530  $metaSignoffId = $row['signoff_id'];
531  $userId = $row['user_id'];
532  $dateCompleted = $row['date_completed']?strtotime($row['date_completed']):null;
533  $signoffsResult->MoveNext();
534 
535  if ($dateCompleted) {
536  $user = $userDao->getById($userId);
537  $note = $noteDao->newDataObject();
538  $note->setAssocType(ASSOC_TYPE_QUERY);
539  $note->setAssocId($queryId);
540  $note->setUserId($userId);
541  $note->setContents('The completed task has been reviewed by ' . htmlspecialchars($user->getFullName()) . ' (' . $user->getEmail() . ').');
542  $noteDao->insertObject($note);
543  $note->setDateCreated(Core::getCurrentDate());
544  $noteDao->updateObject($note);
545  }
546  $submissionFileDao->update('DELETE FROM signoffs WHERE signoff_id=?', array($metaSignoffId));
547  }
548  $signoffsResult->Close();
549 
550  $submissionFileDao->update('DELETE FROM signoffs WHERE signoff_id=?', array($signoffId));
551  }
552 
558  if ($this->tableExists('static_pages')) {
559  $contextDao = Application::getContextDAO();
560  $navigationMenuItemDao = DAORegistry::getDAO('NavigationMenuItemDAO'); /* @var $navigationMenuItemDao NavigationMenuItemDAO */
561 
562  import('plugins.generic.staticPages.classes.StaticPagesDAO');
563 
564  $staticPagesDao = new StaticPagesDAO();
565 
566  $contexts = $contextDao->getAll();
567  while ($context = $contexts->next()) {
568  $contextStaticPages = $staticPagesDao->getByContextId($context->getId())->toAssociativeArray();
569  foreach($contextStaticPages as $staticPage) {
570  $retNMIId = $navigationMenuItemDao->portStaticPage($staticPage);
571  if ($retNMIId) {
572  $staticPagesDao->deleteById($staticPage->getId());
573  } else {
574  error_log('WARNING: The StaticPage "' . $staticPage->getLocalizedTitle() . '" uses a path (' . $staticPage->getPath() . ') that conflicts with an existing Custom Navigation Menu Item path. Skipping this StaticPage.');
575  }
576  }
577  }
578  }
579 
580  return true;
581  }
582 
588  $userDao = DAORegistry::getDAO('UserDAO'); /* @var $userDao UserDAO */
589  import('lib.pkp.classes.identity.Identity'); // IDENTITY_SETTING_...
590  // the user names will be saved in the site's primary locale
591  $userDao->update("INSERT INTO user_settings (user_id, locale, setting_name, setting_value, setting_type) SELECT DISTINCT u.user_id, s.primary_locale, ?, u.first_name, 'string' FROM users_tmp u, site s", array(IDENTITY_SETTING_GIVENNAME));
592  $userDao->update("INSERT INTO user_settings (user_id, locale, setting_name, setting_value, setting_type) SELECT DISTINCT u.user_id, s.primary_locale, ?, u.last_name, 'string' FROM users_tmp u, site s", array(IDENTITY_SETTING_FAMILYNAME));
593  // the author names will be saved in the submission's primary locale
594  $userDao->update("INSERT INTO author_settings (author_id, locale, setting_name, setting_value, setting_type) SELECT DISTINCT a.author_id, s.locale, ?, a.first_name, 'string' FROM authors_tmp a, submissions s WHERE s.submission_id = a.submission_id", array(IDENTITY_SETTING_GIVENNAME));
595  $userDao->update("INSERT INTO author_settings (author_id, locale, setting_name, setting_value, setting_type) SELECT DISTINCT a.author_id, s.locale, ?, a.last_name, 'string' FROM authors_tmp a, submissions s WHERE s.submission_id = a.submission_id", array(IDENTITY_SETTING_FAMILYNAME));
596 
597  // middle name will be migrated to the given name
598  // note that given names are already migrated to the settings table
599  $driver = $userDao->getDriver();
600  switch ($driver) {
601  case 'mysql':
602  case 'mysqli':
603  // the alias for _settings table cannot be used for some reason -- syntax error
604  $userDao->update("UPDATE user_settings, users_tmp u SET user_settings.setting_value = CONCAT(user_settings.setting_value, ' ', u.middle_name) WHERE user_settings.setting_name = ? AND u.user_id = user_settings.user_id AND u.middle_name IS NOT NULL AND u.middle_name <> ''", array(IDENTITY_SETTING_GIVENNAME));
605  $userDao->update("UPDATE author_settings, authors_tmp a SET author_settings.setting_value = CONCAT(author_settings.setting_value, ' ', a.middle_name) WHERE author_settings.setting_name = ? AND a.author_id = author_settings.author_id AND a.middle_name IS NOT NULL AND a.middle_name <> ''", array(IDENTITY_SETTING_GIVENNAME));
606  break;
607  case 'postgres':
608  case 'postgres64':
609  case 'postgres7':
610  case 'postgres8':
611  case 'postgres9':
612  $userDao->update("UPDATE user_settings SET setting_value = CONCAT(setting_value, ' ', u.middle_name) FROM users_tmp u WHERE user_settings.setting_name = ? AND u.user_id = user_settings.user_id AND u.middle_name IS NOT NULL AND u.middle_name <> ''", array(IDENTITY_SETTING_GIVENNAME));
613  $userDao->update("UPDATE author_settings SET setting_value = CONCAT(setting_value, ' ', a.middle_name) FROM authors_tmp a WHERE author_settings.setting_name = ? AND a.author_id = author_settings.author_id AND a.middle_name IS NOT NULL AND a.middle_name <> ''", array(IDENTITY_SETTING_GIVENNAME));
614  break;
615  default: fatalError('Unknown database type!');
616  }
617 
618  // salutation and suffix will be migrated to the preferred public name
619  // user preferred public names will be inserted for each supported site locales
620  $siteDao = DAORegistry::getDAO('SiteDAO'); /* @var $siteDao SiteDAO */
621  $site = $siteDao->getSite();
622  $supportedLocales = $site->getSupportedLocales();
623  $userResult = $userDao->retrieve("
624  SELECT user_id, first_name, last_name, middle_name, salutation, suffix FROM users_tmp
625  WHERE (salutation IS NOT NULL AND salutation <> '') OR
626  (suffix IS NOT NULL AND suffix <> '')
627  ");
628  while (!$userResult->EOF) {
629  $row = $userResult->GetRowAssoc(false);
630  $userId = $row['user_id'];
631  $firstName = $row['first_name'];
632  $lastName = $row['last_name'];
633  $middleName = $row['middle_name'];
634  $salutation = $row['salutation'];
635  $suffix = $row['suffix'];
636  foreach ($supportedLocales as $siteLocale) {
637  $preferredPublicName = ($salutation != '' ? "$salutation " : '') . "$firstName " . ($middleName != '' ? "$middleName " : '') . $lastName . ($suffix != '' ? ", $suffix" : '');
638  if (AppLocale::isLocaleWithFamilyFirst($siteLocale)) {
639  $preferredPublicName = "$lastName, " . ($salutation != '' ? "$salutation " : '') . $firstName . ($middleName != '' ? " $middleName" : '');
640  }
641  $params = array((int) $userId, $siteLocale, $preferredPublicName);
642  $userDao->update("INSERT INTO user_settings (user_id, locale, setting_name, setting_value, setting_type) VALUES (?, ?, 'preferredPublicName', ?, 'string')", $params);
643  }
644  $userResult->MoveNext();
645  }
646  $userResult->Close();
647 
648  // author suffix will be migrated to the author preferred public name
649  // author preferred public names will be inserted for each press supported locale
650  // get supported locales for the press (there shold actually be only one press)
651  $pressDao = DAORegistry::getDAO('PressDAO'); /* @var $pressDao PressDAO */
652  $presses = $pressDao->getAll();
653  $pressessSupportedLocales = array();
654  while ($press = $presses->next()) {
655  $pressessSupportedLocales[$press->getId()] = $press->getSupportedLocales();
656  }
657  // get all authors with a suffix
658  $authorResult = $userDao->retrieve("
659  SELECT a.author_id, a.first_name, a.last_name, a.middle_name, a.suffix, p.press_id FROM authors_tmp a
660  LEFT JOIN submissions s ON (s.submission_id = a.submission_id)
661  LEFT JOIN presses p ON (p.press_id = s.context_id)
662  WHERE suffix IS NOT NULL AND suffix <> ''
663  ");
664  while (!$authorResult->EOF) {
665  $row = $authorResult->GetRowAssoc(false);
666  $authorId = $row['author_id'];
667  $firstName = $row['first_name'];
668  $lastName = $row['last_name'];
669  $middleName = $row['middle_name'];
670  $suffix = $row['suffix'];
671  $pressId = $row['press_id'];
672  $supportedLocales = $pressessSupportedLocales[$pressId];
673  foreach ($supportedLocales as $locale) {
674  $preferredPublicName = "$firstName " . ($middleName != '' ? "$middleName " : '') . $lastName . ($suffix != '' ? ", $suffix" : '');
676  $preferredPublicName = "$lastName, " . $firstName . ($middleName != '' ? " $middleName" : '');
677  }
678  $params = array((int) $authorId, $locale, $preferredPublicName);
679  $userDao->update("INSERT INTO author_settings (author_id, locale, setting_name, setting_value, setting_type) VALUES (?, ?, 'preferredPublicName', ?, 'string')", $params);
680  }
681  $authorResult->MoveNext();
682  }
683  $authorResult->Close();
684 
685  // remove temporary table
686  $siteDao->update('DROP TABLE users_tmp');
687  $siteDao->update('DROP TABLE authors_tmp');
688  return true;
689  }
690 
697  $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO');
698  $userGroupDao = DAORegistry::getDAO('UserGroupDAO');
701  $roleString = '(' . implode(",", $roles) . ')';
702 
703  $userGroupDao->update('UPDATE user_groups SET permit_metadata_edit = 1 WHERE role_id IN ' . $roleString);
704  switch ($userGroupDao->getDriver()) {
705  case 'mysql':
706  case 'mysqli':
707  $stageAssignmentDao->update('UPDATE stage_assignments sa JOIN user_groups ug on sa.user_group_id = ug.user_group_id SET sa.can_change_metadata = 1 WHERE ug.role_id IN ' . $roleString);
708  break;
709  case 'postgres':
710  case 'postgres64':
711  case 'postgres7':
712  case 'postgres8':
713  case 'postgres9':
714  $stageAssignmentDao->update('UPDATE stage_assignments SET can_change_metadata=1 FROM stage_assignments sa JOIN user_groups ug ON (sa.user_group_id = ug.user_group_id) WHERE ug.role_id IN ' . $roleString);
715  break;
716  default: fatalError("Unknown database type!");
717  }
718 
719  return true;
720  }
721 
733  import('lib.pkp.classes.file.BaseSubmissionFileManager');
734  import('lib.pkp.classes.file.FileManager');
735  import('classes.file.PublicFileManager');
736 
737  $fileManager = new \FileManager();
738  $publicFileManager = new \PublicFileManager();
739  $contexts = [];
740 
741  $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */
742  $result = $submissionDao->retrieve(
743  'SELECT ps.submission_id as submission_id,
744  ps.cover_image as cover_image,
745  s.context_id as context_id
746  FROM published_submissions ps
747  LEFT JOIN submissions s ON (s.submission_id = ps.submission_id)'
748  );
749  while (!$result->EOF) {
750  $row = $result->getRowAssoc(false);
751  if (empty($row['cover_image'])) {
752  $result->MoveNext();
753  continue;
754  }
755  $coverImage = unserialize($row['cover_image']);
756  if (empty($coverImage)) {
757  $result->MoveNext();
758  continue;
759  }
760  $context = $contexts[$row['context_id']];
761  if (empty($context)) {
762  $context = Services::get('context')->get($row['context_id']);
763  }
764 
765  // Get existing image paths
766  $baseSubmissionFileManager = new BaseSubmissionFileManager($row['context_id'], $row['submission_id']);
767  $coverPath = $baseSubmissionFileManager->getBasePath() . 'simple/' . $coverImage['name'];
768  $coverPathInfo = pathinfo($coverPath);
769  $thumbPath = $baseSubmissionFileManager->getBasePath() . 'simple/' . $coverImage['thumbnailName'];
770  $thumbPathInfo = pathinfo($thumbPath);
771 
772  // Copy the files to the public directory
773  $newCoverPath = join('_', [
774  'submission',
775  $row['submission_id'],
776  $row['submission_id'],
777  'coverImage',
778  ]) . '.' . $coverPathInfo['extension'];
779  $publicFileManager->copyContextFile(
780  $row['context_id'],
781  $coverPath,
782  $newCoverPath
783  );
784  $newThumbPath = join('_', [
785  'submission',
786  $row['submission_id'],
787  $row['submission_id'],
788  'coverImage',
789  't'
790  ]) . '.' . $thumbPathInfo['extension'];
791  $publicFileManager->copyContextFile(
792  $row['context_id'],
793  $thumbPath,
794  $newThumbPath
795  );
796 
797  // Create a submission_settings entry for each locale
798  if(isset($context)) {
799  foreach ($context->getSupportedFormLocales() as $localeKey) {
800  $newCoverPathInfo = pathinfo($newCoverPath);
801  $submissionDao = DAORegistry::getDAO('SubmissionDAO');
802  /* @var $submissionDao SubmissionDAO */
803  $submissionDao->update(
804  'INSERT INTO submission_settings (submission_id, setting_name, setting_value, setting_type, locale)
805  VALUES (?, ?, ?, ?, ?)',
806  [
807  $row['submission_id'],
808  'coverImage',
809  serialize([
810  'uploadName' => $newCoverPathInfo['basename'],
811  'dateUploaded' => $coverImage['dateUploaded'],
812  'altText' => '',
813  ]),
814  'object',
815  $localeKey,
816  ]
817  );
818  }
819  }
820 
821  // Delete the old images
822  $fileManager->deleteByPath($coverPath);
823  $fileManager->deleteByPath($thumbPath);
824 
825  $result->MoveNext();
826  }
827  $result->Close();
828 
829 
830  return true;
831  }
832 }
833 
834 
Upgrade\fixFilenames
fixFilenames($upgrade, $params, $dryrun=false)
Definition: Upgrade.inc.php:50
Application\getContextDAO
static getContextDAO()
Definition: Application.inc.php:145
SubmissionFileManager
Helper class for database-backed submission file management tasks.
Definition: SubmissionFileManager.inc.php:30
Upgrade\fixQueriesAssocTypes
fixQueriesAssocTypes()
Definition: Upgrade.inc.php:390
Installer\$params
$params
Definition: Installer.inc.php:52
StaticPagesDAO
Definition: StaticPagesDAO.inc.php:18
PKPString\stripUnsafeHtml
static stripUnsafeHtml($input)
Definition: PKPString.inc.php:377
DAORegistry\getDAO
static & getDAO($name, $dbconn=null)
Definition: DAORegistry.inc.php:57
Upgrade
Perform system upgrade.
Definition: Upgrade.inc.php:19
Upgrade\fixAuthorSettings
fixAuthorSettings()
Definition: Upgrade.inc.php:154
Installer\tableExists
tableExists($tableName)
Definition: Installer.inc.php:775
Upgrade\htmlifyEmailTemplates
htmlifyEmailTemplates()
Definition: Upgrade.inc.php:196
Upgrade\syncSeriesAssocType
syncSeriesAssocType()
Definition: Upgrade.inc.php:125
Installer\$notes
$notes
Definition: Installer.inc.php:106
Upgrade\convertCommentsToEditor
convertCommentsToEditor()
Definition: Upgrade.inc.php:435
Upgrade\migrateSubmissionCoverImages
migrateSubmissionCoverImages()
Definition: Upgrade.inc.php:732
BaseSubmissionFileManager
Base helper class for submission file management tasks.
Definition: BaseSubmissionFileManager.inc.php:30
Upgrade\migrateUserAndAuthorNames
migrateUserAndAuthorNames()
Definition: Upgrade.inc.php:587
Upgrade\migrateStaticPagesToNavigationMenuItems
migrateStaticPagesToNavigationMenuItems()
Definition: Upgrade.inc.php:557
Installer\$isPlugin
$isPlugin
Definition: Installer.inc.php:46
UserGroupDAO\getNotChangeMetadataEditPermissionRoles
static getNotChangeMetadataEditPermissionRoles()
Definition: UserGroupDAO.inc.php:1046
PKPLocale\isLocaleWithFamilyFirst
static isLocaleWithFamilyFirst($locale)
Definition: PKPLocale.inc.php:492
Upgrade\enableDefaultTheme
enableDefaultTheme()
Definition: Upgrade.inc.php:106
strtolower_codesafe
strtolower_codesafe($str)
Definition: functions.inc.php:280
Core\getCurrentDate
static getCurrentDate($ts=null)
Definition: Core.inc.php:63
Upgrade\isUpgrade
isUpgrade()
Definition: Upgrade.inc.php:34
Upgrade\__construct
__construct($params, $installFile='upgrade.xml', $isPlugin=false)
Definition: Upgrade.inc.php:25
Upgrade\changeUserRolesAndStageAssignmentsForStagePermitSubmissionEdit
changeUserRolesAndStageAssignmentsForStagePermitSubmissionEdit()
Definition: Upgrade.inc.php:696
Upgrade\convertQueries
convertQueries()
Definition: Upgrade.inc.php:263
Installer
Base class for install and upgrade scripts.
Definition: Installer.inc.php:34
fatalError
if(!function_exists('import')) fatalError($reason)
Definition: functions.inc.php:32
Installer\$locale
$locale
Definition: Installer.inc.php:76
PKPServices\get
static get($service)
Definition: PKPServices.inc.php:49