00001 <?php
00002
00015
00016
00017
00018 import('classes.plugins.ImportExportPlugin');
00019
00020 import('xml.XMLCustomWriter');
00021
00022 define('NATIVE_DTD_URL', 'http://pkp.sfu.ca/ojs/dtds/native.dtd');
00023 define('NATIVE_DTD_ID', '-//PKP//OJS Articles and Issues XML//EN');
00024
00025 class NativeImportExportPlugin extends ImportExportPlugin {
00032 function register($category, $path) {
00033 $success = parent::register($category, $path);
00034 $this->addLocaleData();
00035 return $success;
00036 }
00037
00043 function getName() {
00044 return 'NativeImportExportPlugin';
00045 }
00046
00047 function getDisplayName() {
00048 return Locale::translate('plugins.importexport.native.displayName');
00049 }
00050
00051 function getDescription() {
00052 return Locale::translate('plugins.importexport.native.description');
00053 }
00054
00055 function display(&$args) {
00056 $templateMgr = &TemplateManager::getManager();
00057 parent::display($args);
00058
00059 $issueDao = &DAORegistry::getDAO('IssueDAO');
00060
00061 $journal = &Request::getJournal();
00062 switch (array_shift($args)) {
00063 case 'exportIssues':
00064 $issueIds = Request::getUserVar('issueId');
00065 if (!isset($issueIds)) $issueIds = array();
00066 $issues = array();
00067 foreach ($issueIds as $issueId) {
00068 $issue = &$issueDao->getIssueById($issueId);
00069 if (!$issue) Request::redirect();
00070 $issues[] = &$issue;
00071 }
00072 $this->exportIssues($journal, $issues);
00073 break;
00074 case 'exportIssue':
00075 $issueId = array_shift($args);
00076 $issue = &$issueDao->getIssueById($issueId);
00077 if (!$issue) Request::redirect();
00078 $this->exportIssue($journal, $issue);
00079 break;
00080 case 'exportArticle':
00081 $articleIds = array(array_shift($args));
00082 $result = array_shift(ArticleSearch::formatResults($articleIds));
00083 $this->exportArticle($journal, $result['issue'], $result['section'], $result['publishedArticle']);
00084 break;
00085 case 'exportArticles':
00086 $articleIds = Request::getUserVar('articleId');
00087 if (!isset($articleIds)) $articleIds = array();
00088 $results = &ArticleSearch::formatResults($articleIds);
00089 $this->exportArticles($results);
00090 break;
00091 case 'issues':
00092
00093 $this->setBreadcrumbs(array(), true);
00094 $issueDao = &DAORegistry::getDAO('IssueDAO');
00095 $issues = &$issueDao->getIssues($journal->getJournalId(), Handler::getRangeInfo('issues'));
00096
00097 $templateMgr->assign_by_ref('issues', $issues);
00098 $templateMgr->display($this->getTemplatePath() . 'issues.tpl');
00099 break;
00100 case 'articles':
00101
00102 $this->setBreadcrumbs(array(), true);
00103 $publishedArticleDao = &DAORegistry::getDAO('PublishedArticleDAO');
00104 $rangeInfo = Handler::getRangeInfo('articles');
00105 $articleIds = $publishedArticleDao->getPublishedArticleIdsAlphabetizedByJournal($journal->getJournalId(), false);
00106 $totalArticles = count($articleIds);
00107 if ($rangeInfo->isValid()) $articleIds = array_slice($articleIds, $rangeInfo->getCount() * ($rangeInfo->getPage()-1), $rangeInfo->getCount());
00108 $iterator = &new VirtualArrayIterator(ArticleSearch::formatResults($articleIds), $totalArticles, $rangeInfo->getPage(), $rangeInfo->getCount());
00109 $templateMgr->assign_by_ref('articles', $iterator);
00110 $templateMgr->display($this->getTemplatePath() . 'articles.tpl');
00111 break;
00112 case 'import':
00113 import('file.TemporaryFileManager');
00114 $issueDao = &DAORegistry::getDAO('IssueDAO');
00115 $sectionDao = &DAORegistry::getDAO('SectionDAO');
00116 $user = &Request::getUser();
00117 $temporaryFileManager = &new TemporaryFileManager();
00118
00119 if (($existingFileId = Request::getUserVar('temporaryFileId'))) {
00120
00121 $temporaryFile = TemporaryFileManager::getFile($existingFileId, $user->getUserId());
00122 } else {
00123 $temporaryFile = $temporaryFileManager->handleUpload('importFile', $user->getUserId());
00124 }
00125
00126 $context = array(
00127 'journal' => $journal,
00128 'user' => $user
00129 );
00130
00131 if (($sectionId = Request::getUserVar('sectionId'))) {
00132 $context['section'] = $sectionDao->getSection($sectionId);
00133 }
00134
00135 if (($issueId = Request::getUserVar('issueId'))) {
00136 $context['issue'] = $issueDao->getIssueById($issueId, $journal->getJournalId());
00137 }
00138
00139 if (!$temporaryFile) {
00140 $templateMgr->assign('error', 'plugins.importexport.native.error.uploadFailed');
00141 return $templateMgr->display($this->getTemplatePath() . 'importError.tpl');
00142 }
00143
00144 $doc = &$this->getDocument($temporaryFile->getFilePath());
00145
00146 if (substr($this->getRootNodeName($doc), 0, 7) === 'article') {
00147
00148
00149
00150 if (!isset($context['issue']) || !isset($context['section'])) {
00151 $issues = &$issueDao->getIssues($journal->getJournalId(), Handler::getRangeInfo('issues'));
00152 $templateMgr->assign_by_ref('issues', $issues);
00153 $templateMgr->assign('sectionOptions', array('0' => Locale::translate('author.submit.selectSection')) + $sectionDao->getSectionTitles($journal->getJournalId(), false));
00154 $templateMgr->assign('temporaryFileId', $temporaryFile->getFileId());
00155 return $templateMgr->display($this->getTemplatePath() . 'articleContext.tpl');
00156 }
00157 }
00158
00159 @set_time_limit(0);
00160
00161 if ($this->handleImport($context, $doc, $errors, $issues, $articles, false)) {
00162 $templateMgr->assign_by_ref('issues', $issues);
00163 $templateMgr->assign_by_ref('articles', $articles);
00164 return $templateMgr->display($this->getTemplatePath() . 'importSuccess.tpl');
00165 } else {
00166 $templateMgr->assign_by_ref('errors', $errors);
00167 return $templateMgr->display($this->getTemplatePath() . 'importError.tpl');
00168 }
00169 break;
00170 default:
00171 $this->setBreadcrumbs();
00172 $templateMgr->display($this->getTemplatePath() . 'index.tpl');
00173 }
00174 }
00175
00176 function exportIssue(&$journal, &$issue, $outputFile = null) {
00177 $this->import('NativeExportDom');
00178 $doc = &XMLCustomWriter::createDocument('issue', NATIVE_DTD_ID, NATIVE_DTD_URL);
00179 $issueNode = &NativeExportDom::generateIssueDom($doc, $journal, $issue);
00180 XMLCustomWriter::appendChild($doc, $issueNode);
00181
00182 if (!empty($outputFile)) {
00183 if (($h = fopen($outputFile, 'wb'))===false) return false;
00184 fwrite($h, XMLCustomWriter::getXML($doc));
00185 fclose($h);
00186 } else {
00187 header("Content-Type: application/xml");
00188 header("Cache-Control: private");
00189 header("Content-Disposition: attachment; filename=\"issue-" . $issue->getIssueId() . ".xml\"");
00190 XMLCustomWriter::printXML($doc);
00191 }
00192 return true;
00193 }
00194
00195 function exportArticle(&$journal, &$issue, &$section, &$article, $outputFile = null) {
00196 $this->import('NativeExportDom');
00197 $doc = &XMLCustomWriter::createDocument('article', NATIVE_DTD_ID, NATIVE_DTD_URL);
00198 $articleNode = &NativeExportDom::generateArticleDom($doc, $journal, $issue, $section, $article);
00199 XMLCustomWriter::appendChild($doc, $articleNode);
00200
00201 if (!empty($outputFile)) {
00202 if (($h = fopen($outputFile, 'w'))===false) return false;
00203 fwrite($h, XMLCustomWriter::getXML($doc));
00204 fclose($h);
00205 } else {
00206 header("Content-Type: application/xml");
00207 header("Cache-Control: private");
00208 header("Content-Disposition: attachment; filename=\"article-" . $article->getArticleId() . ".xml\"");
00209 XMLCustomWriter::printXML($doc);
00210 }
00211 return true;
00212 }
00213
00214 function exportIssues(&$journal, &$issues, $outputFile = null) {
00215 $this->import('NativeExportDom');
00216 $doc = &XMLCustomWriter::createDocument('issues', NATIVE_DTD_ID, NATIVE_DTD_URL);
00217 $issuesNode = &XMLCustomWriter::createElement($doc, 'issues');
00218 XMLCustomWriter::appendChild($doc, $issuesNode);
00219
00220 foreach ($issues as $issue) {
00221 $issueNode = &NativeExportDom::generateIssueDom($doc, $journal, $issue);
00222 XMLCustomWriter::appendChild($issuesNode, $issueNode);
00223 }
00224
00225 if (!empty($outputFile)) {
00226 if (($h = fopen($outputFile, 'w'))===false) return false;
00227 fwrite($h, XMLCustomWriter::getXML($doc));
00228 fclose($h);
00229 } else {
00230 header("Content-Type: application/xml");
00231 header("Cache-Control: private");
00232 header("Content-Disposition: attachment; filename=\"issues.xml\"");
00233 XMLCustomWriter::printXML($doc);
00234 }
00235 return true;
00236 }
00237
00238 function exportArticles(&$results, $outputFile = null) {
00239 $this->import('NativeExportDom');
00240 $doc = &XMLCustomWriter::createDocument('articles', NATIVE_DTD_ID, NATIVE_DTD_URL);
00241 $articlesNode = &XMLCustomWriter::createElement($doc, 'articles');
00242 XMLCustomWriter::appendChild($doc, $articlesNode);
00243
00244 foreach ($results as $result) {
00245 $article = &$result['publishedArticle'];
00246 $section = &$result['section'];
00247 $issue = &$result['issue'];
00248 $journal = &$result['journal'];
00249 $articleNode = &NativeExportDom::generateArticleDom($doc, $journal, $issue, $section, $article);
00250 XMLCustomWriter::appendChild($articlesNode, $articleNode);
00251 }
00252
00253 if (!empty($outputFile)) {
00254 if (($h = fopen($outputFile, 'w'))===false) return false;
00255 fwrite($h, XMLCustomWriter::getXML($doc));
00256 fclose($h);
00257 } else {
00258 header("Content-Type: application/xml");
00259 header("Cache-Control: private");
00260 header("Content-Disposition: attachment; filename=\"articles.xml\"");
00261 XMLCustomWriter::printXML($doc);
00262 }
00263 return true;
00264 }
00265
00266 function &getDocument($fileName) {
00267 $parser = &new XMLParser();
00268 $returner =& $parser->parse($fileName);
00269 return $returner;
00270 }
00271
00272 function getRootNodeName(&$doc) {
00273 return $doc->name;
00274 }
00275
00276 function handleImport(&$context, &$doc, &$errors, &$issues, &$articles, $isCommandLine) {
00277 $errors = array();
00278 $issues = array();
00279 $articles = array();
00280
00281 $user = &$context['user'];
00282 $journal = &$context['journal'];
00283
00284 $rootNodeName = $this->getRootNodeName($doc);
00285
00286 $this->import('NativeImportDom');
00287
00288 switch ($rootNodeName) {
00289 case 'issues':
00290 return NativeImportDom::importIssues($journal, $doc->children, $issues, $errors, $user, $isCommandLine);
00291 break;
00292 case 'issue':
00293 $dependentItems = array();
00294 $result = NativeImportDom::importIssue($journal, $doc, $issue, $errors, $user, $isCommandLine, $dependentItems);
00295 if ($result) $issues = array($issue);
00296 return $result;
00297 break;
00298 case 'articles':
00299 $section = &$context['section'];
00300 $issue = &$context['issue'];
00301 return NativeImportDom::importArticles($journal, $doc->children, $issue, $section, $articles, $errors, $user, $isCommandLine);
00302 break;
00303 case 'article':
00304 $section = &$context['section'];
00305 $issue = &$context['issue'];
00306 $result = NativeImportDom::importArticle($journal, $doc, $issue, $section, $article, $errors, $user, $isCommandLine);
00307 if ($result) $articles = array($article);
00308 return $result;
00309 break;
00310 default:
00311 $errors[] = array('plugins.importexport.native.import.error.unsupportedRoot', array('rootName' => $rootNodeName));
00312 return false;
00313 break;
00314 }
00315 }
00316
00321 function executeCLI($scriptName, &$args) {
00322 $command = array_shift($args);
00323 $xmlFile = array_shift($args);
00324 $journalPath = array_shift($args);
00325
00326 $journalDao = &DAORegistry::getDAO('JournalDAO');
00327 $issueDao = &DAORegistry::getDAO('IssueDAO');
00328 $sectionDao = &DAORegistry::getDAO('SectionDAO');
00329 $userDao = &DAORegistry::getDAO('UserDAO');
00330 $publishedArticleDao = &DAORegistry::getDAO('PublishedArticleDAO');
00331
00332 $journal = &$journalDao->getJournalByPath($journalPath);
00333
00334 if (!$journal) {
00335 if ($journalPath != '') {
00336 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00337 echo Locale::translate('plugins.importexport.native.error.unknownJournal', array('journalPath' => $journalPath)) . "\n\n";
00338 }
00339 $this->usage($scriptName);
00340 return;
00341 }
00342
00343 $this->import('NativeImportDom');
00344 if ($xmlFile && NativeImportDom::isRelativePath($xmlFile)) {
00345 $xmlFile = PWD . '/' . $xmlFile;
00346 }
00347
00348 switch ($command) {
00349 case 'import':
00350 $userName = array_shift($args);
00351 $user = &$userDao->getUserByUsername($userName);
00352
00353 if (!$user) {
00354 if ($userName != '') {
00355 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00356 echo Locale::translate('plugins.importexport.native.error.unknownUser', array('userName' => $userName)) . "\n\n";
00357 }
00358 $this->usage($scriptName);
00359 return;
00360 }
00361
00362 $doc = &$this->getDocument($xmlFile);
00363
00364 $context = array(
00365 'user' => $user,
00366 'journal' => $journal
00367 );
00368
00369 switch ($this->getRootNodeName($doc)) {
00370 case 'article':
00371 case 'articles':
00372
00373
00374 if (array_shift($args) !== 'issue_id') return $this->usage($scriptName);
00375 $issue = &$issueDao->getIssueByBestIssueId(($issueId = array_shift($args)), $journal->getJournalId());
00376 if (!$issue) {
00377 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00378 echo Locale::translate('plugins.importexport.native.export.error.issueNotFound', array('issueId' => $issueId)) . "\n\n";
00379 return;
00380 }
00381
00382 $context['issue'] = &$issue;
00383
00384 switch (array_shift($args)) {
00385 case 'section_id':
00386 $section = &$sectionDao->getSection(($sectionIdentifier = array_shift($args)));
00387 break;
00388 case 'section_name':
00389 $section = &$sectionDao->getSectionByTitle(($sectionIdentifier = array_shift($args)), $journal->getJournalId());
00390 break;
00391 case 'section_abbrev':
00392 $section = &$sectionDao->getSectionByAbbrev(($sectionIdentifier = array_shift($args)));
00393 break;
00394 default:
00395 return $this->usage($scriptName);
00396 }
00397
00398 if (!$section) {
00399 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00400 echo Locale::translate('plugins.importexport.native.export.error.sectionNotFound', array('sectionIdentifier' => $sectionIdentifier)) . "\n\n";
00401 return;
00402 }
00403 $context['section'] = &$section;
00404 }
00405
00406 $result = $this->handleImport($context, $doc, $errors, $issues, $articles, true);
00407 if ($result) {
00408 echo Locale::translate('plugins.importexport.native.import.success.description') . "\n\n";
00409 if (!empty($issues)) echo Locale::translate('issue.issues') . ":\n";
00410 foreach ($issues as $issue) {
00411 echo "\t" . $issue->getIssueIdentification() . "\n";
00412 }
00413
00414 if (!empty($articles)) echo Locale::translate('article.articles') . ":\n";
00415 foreach ($articles as $article) {
00416 echo "\t" . $article->getArticleTitle() . "\n";
00417 }
00418 } else {
00419 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00420 foreach ($errors as $error) {
00421 echo "\t" . Locale::translate($error[0], $error[1]) . "\n";
00422 }
00423 }
00424 return;
00425 break;
00426 case 'export':
00427 if ($xmlFile != '') switch (array_shift($args)) {
00428 case 'article':
00429 $articleId = array_shift($args);
00430 $publishedArticle = &$publishedArticleDao->getPublishedArticleByBestArticleId($journal->getJournalId(), $articleId);
00431 if ($publishedArticle == null) {
00432 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00433 echo Locale::translate('plugins.importexport.native.export.error.articleNotFound', array('articleId' => $articleId)) . "\n\n";
00434 return;
00435 }
00436 $issue = &$issueDao->getIssueById($publishedArticle->getIssueId());
00437
00438 $sectionDao = &DAORegistry::getDAO('SectionDAO');
00439 $section = &$sectionDao->getSection($publishedArticle->getSectionId());
00440
00441 if (!$this->exportArticle($journal, $issue, $section, $publishedArticle, $xmlFile)) {
00442 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00443 echo Locale::translate('plugins.importexport.native.export.error.couldNotWrite', array('fileName' => $xmlFile)) . "\n\n";
00444 }
00445 return;
00446 case 'articles':
00447 $results = &ArticleSearch::formatResults($args);
00448 if (!$this->exportArticles($results, $xmlFile)) {
00449 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00450 echo Locale::translate('plugins.importexport.native.export.error.couldNotWrite', array('fileName' => $xmlFile)) . "\n\n";
00451 }
00452 return;
00453 case 'issue':
00454 $issueId = array_shift($args);
00455 $issue = &$issueDao->getIssueByBestIssueId($issueId, $journal->getJournalId());
00456 if ($issue == null) {
00457 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00458 echo Locale::translate('plugins.importexport.native.export.error.issueNotFound', array('issueId' => $issueId)) . "\n\n";
00459 return;
00460 }
00461 if (!$this->exportIssue($journal, $issue, $xmlFile)) {
00462 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00463 echo Locale::translate('plugins.importexport.native.export.error.couldNotWrite', array('fileName' => $xmlFile)) . "\n\n";
00464 }
00465 return;
00466 case 'issues':
00467 $issues = array();
00468 while (($issueId = array_shift($args))!==null) {
00469 $issue = &$issueDao->getIssueByBestIssueId($issueId, $journal->getJournalId());
00470 if ($issue == null) {
00471 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00472 echo Locale::translate('plugins.importexport.native.export.error.issueNotFound', array('issueId' => $issueId)) . "\n\n";
00473 return;
00474 }
00475 $issues[] = &$issue;
00476 }
00477 if (!$this->exportIssues($journal, $issues, $xmlFile)) {
00478 echo Locale::translate('plugins.importexport.native.cliError') . "\n";
00479 echo Locale::translate('plugins.importexport.native.export.error.couldNotWrite', array('fileName' => $xmlFile)) . "\n\n";
00480 }
00481 return;
00482 }
00483 break;
00484 }
00485 $this->usage($scriptName);
00486 }
00487
00491 function usage($scriptName) {
00492 echo Locale::translate('plugins.importexport.native.cliUsage', array(
00493 'scriptName' => $scriptName,
00494 'pluginName' => $this->getName()
00495 )) . "\n";
00496 }
00497 }
00498
00499 ?>