PageRenderTime 69ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/ojs/ojs-2.0.2-1/classes/oai/ojs/OAIDAO.inc.php

https://github.com/mcrider/pkpUpgradeTestSuite
PHP | 487 lines | 307 code | 65 blank | 115 comment | 39 complexity | ba2f2bd38ca4206e7d4112530aa1473f MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * OAIDAO.inc.php
  4. *
  5. * Copyright (c) 2003-2005 The Public Knowledge Project
  6. * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
  7. *
  8. * @package oai.ojs
  9. *
  10. * DAO operations for the OJS OAI interface.
  11. *
  12. * $Id: OAIDAO.inc.php,v 1.20 2005/09/06 01:55:29 kevin Exp $
  13. */
  14. import('oai.OAI');
  15. import('issue.Issue');
  16. class OAIDAO extends DAO {
  17. /** @var $oai JournalOAI parent OAI object */
  18. var $oai;
  19. /** Helper DAOs */
  20. var $journalDao;
  21. var $sectionDao;
  22. var $authorDao;
  23. var $suppFileDao;
  24. var $journalSettingsDao;
  25. /**
  26. * Constructor.
  27. */
  28. function OAIDAO() {
  29. parent::DAO();
  30. $this->journalDao = &DAORegistry::getDAO('JournalDAO');
  31. $this->sectionDao = &DAORegistry::getDAO('SectionDAO');
  32. $this->authorDao = &DAORegistry::getDAO('AuthorDAO');
  33. $this->suppFileDao = &DAORegistry::getDAO('SuppFileDAO');
  34. $this->journalSettingsDao = &DAORegistry::getDAO('JournalSettingsDAO');
  35. }
  36. /**
  37. * Set parent OAI object.
  38. * @param JournalOAI
  39. */
  40. function setOAI(&$oai) {
  41. $this->oai = $oai;
  42. }
  43. //
  44. // Records
  45. //
  46. /**
  47. * Return the *nix timestamp of the earliest published article.
  48. * @param $journalId int optional
  49. * @return int
  50. */
  51. function getEarliestDatestamp($journalId = null) {
  52. $result = &$this->retrieve(
  53. 'SELECT MIN(pa.date_published)
  54. FROM published_articles pa, issues i
  55. WHERE pa.issue_id = i.issue_id AND i.published = 1'
  56. . (isset($journalId) ? ' AND i.journal_id = ?' : ''),
  57. isset($journalId) ? $journalId : false
  58. );
  59. if (isset($result->fields[0])) {
  60. $timestamp = strtotime($this->datetimeFromDB($result->fields[0]));
  61. }
  62. if (!isset($timestamp) || $timestamp == -1) {
  63. $timestamp = 0;
  64. }
  65. return $timestamp;
  66. }
  67. /**
  68. * Check if an article ID specifies a published article.
  69. * @param $articleId int
  70. * @param $journalId int optional
  71. * @return boolean
  72. */
  73. function recordExists($articleId, $journalId = null) {
  74. $result = &$this->retrieve(
  75. 'SELECT COUNT(*)
  76. FROM published_articles pa, issues i
  77. WHERE pa.issue_id = i.issue_id AND i.published = 1 AND pa.article_id = ?'
  78. . (isset($journalId) ? ' AND i.journal_id = ?' : ''),
  79. isset($journalId) ? array($articleId, $journalId) : $articleId
  80. );
  81. return $result->fields[0] == 1;
  82. }
  83. /**
  84. * Return OAI record for specified article.
  85. * @param $articleId int
  86. * @param $journalId int optional
  87. * @return OAIRecord
  88. */
  89. function &getRecord($articleId, $journalId = null) {
  90. $result = &$this->retrieve(
  91. 'SELECT pa.*, a.*,
  92. j.path AS journal_path,
  93. j.title as journal_title,
  94. s.abbrev as section_abbrev,
  95. s.identify_type as section_item_type,
  96. i.date_published AS issue_published,
  97. i.title AS issue_title,
  98. i.volume AS issue_volume,
  99. i.number AS issue_number,
  100. i.year AS issue_year,
  101. i.label_format AS issue_label_format
  102. FROM published_articles pa, issues i, journals j, articles a
  103. LEFT JOIN sections s ON s.section_id = a.section_id
  104. WHERE pa.article_id = a.article_id AND j.journal_id = a.journal_id
  105. AND pa.issue_id = i.issue_id AND i.published = 1
  106. AND pa.article_id = ?'
  107. . (isset($journalId) ? ' AND a.journal_id = ?' : ''),
  108. isset($journalId) ? array($articleId, $journalId) : $articleId
  109. );
  110. $returner = null;
  111. if ($result->RecordCount() != 0) {
  112. $row = &$result->GetRowAssoc(false);
  113. $returner = &$this->_returnRecordFromRow($row);
  114. }
  115. $result->Close();
  116. return $returner;
  117. }
  118. /**
  119. * Return set of OAI records matching specified parameters.
  120. * @param $journalId int
  121. * @param $sectionId int
  122. * @parma $from int timestamp
  123. * @parma $until int timestamp
  124. * @param $offset int
  125. * @param $limit int
  126. * @param $total int
  127. * @return array OAIRecord
  128. */
  129. function &getRecords($journalId, $sectionId, $from, $until, $offset, $limit, &$total) {
  130. $records = array();
  131. $params = array();
  132. if (isset($journalId)) {
  133. array_push($params, $journalId);
  134. }
  135. if (isset($sectionId)) {
  136. array_push($params, $sectionId);
  137. }
  138. $result = &$this->retrieve(
  139. 'SELECT pa.*, a.*,
  140. j.path AS journal_path,
  141. j.title as journal_title,
  142. s.abbrev as section_abbrev,
  143. s.identify_type as section_item_type,
  144. i.date_published AS issue_published,
  145. i.title AS issue_title,
  146. i.volume AS issue_volume,
  147. i.number AS issue_number,
  148. i.year AS issue_year,
  149. i.label_format AS issue_label_format
  150. FROM published_articles pa, issues i, journals j, articles a
  151. LEFT JOIN sections s ON s.section_id = a.section_id
  152. WHERE pa.article_id = a.article_id AND j.journal_id = a.journal_id
  153. AND pa.issue_id = i.issue_id AND i.published = 1'
  154. . (isset($journalId) ? ' AND a.journal_id = ?' : '')
  155. . (isset($sectionId) ? ' AND a.section_id = ?' : '')
  156. . (isset($from) ? ' AND pa.date_published >= ' . $this->datetimeToDB($from) : '')
  157. . (isset($until) ? ' AND pa.date_published <= ' . $this->datetimeToDB($until) : ''),
  158. $params
  159. );
  160. $total = $result->RecordCount();
  161. $result->Move($offset);
  162. for ($count = 0; $count < $limit && !$result->EOF; $count++) {
  163. $row = &$result->GetRowAssoc(false);
  164. $records[] = &$this->_returnRecordFromRow($row);
  165. $result->moveNext();
  166. }
  167. $result->Close();
  168. return $records;
  169. }
  170. /**
  171. * Return set of OAI identifiers matching specified parameters.
  172. * @param $journalId int
  173. * @param $sectionId int
  174. * @parma $from int timestamp
  175. * @parma $until int timestamp
  176. * @param $offset int
  177. * @param $limit int
  178. * @param $total int
  179. * @return array OAIIdentifier
  180. */
  181. function &getIdentifiers($journalId, $sectionId, $from, $until, $offset, $limit, &$total) {
  182. $records = array();
  183. $params = array();
  184. if (isset($journalId)) {
  185. array_push($params, $journalId);
  186. }
  187. if (isset($sectionId)) {
  188. array_push($params, $sectionId);
  189. }
  190. $result = &$this->retrieve(
  191. 'SELECT pa.article_id, pa.date_published,
  192. j.title AS journal_title, j.path AS journal_path,
  193. s.abbrev as section_abbrev
  194. FROM published_articles pa, issues i, journals j, articles a
  195. LEFT JOIN sections s ON s.section_id = a.section_id
  196. WHERE pa.article_id = a.article_id AND j.journal_id = a.journal_id
  197. AND pa.issue_id = i.issue_id AND i.published = 1'
  198. . (isset($journalId) ? ' AND a.journal_id = ?' : '')
  199. . (isset($sectionId) ? ' AND a.section_id = ?' : '')
  200. . (isset($from) ? ' AND pa.date_published >= ' . $this->datetimeToDB($from) : '')
  201. . (isset($until) ? ' AND pa.date_published <= ' . $this->datetimeToDB($until) : ''),
  202. $params
  203. );
  204. $total = $result->RecordCount();
  205. $result->Move($offset);
  206. for ($count = 0; $count < $limit && !$result->EOF; $count++) {
  207. $row = &$result->GetRowAssoc(false);
  208. $records[] = &$this->_returnIdentifierFromRow($row);
  209. $result->moveNext();
  210. }
  211. $result->Close();
  212. return $records;
  213. }
  214. /**
  215. * Return OAIRecord object from database row.
  216. * @param $row array
  217. * @return OAIRecord
  218. */
  219. function &_returnRecordFromRow(&$row) {
  220. $record = &new OAIRecord();
  221. $articleId = $row['article_id'];
  222. if ($this->journalSettingsDao->getSetting($row['journal_id'], 'enablePublicArticleId')) {
  223. if (!empty($row['public_article_id'])) {
  224. $articleId = $row['public_article_id'];
  225. }
  226. }
  227. // FIXME Use public ID in OAI identifier?
  228. // FIXME Use "last-modified" field for datestamp?
  229. $record->identifier = $this->oai->articleIdToIdentifier($row['article_id']);
  230. $record->datestamp = $this->oai->UTCDate(strtotime($this->datetimeFromDB($row['date_published'])));
  231. $record->sets = array($row['journal_path'] . ':' . $row['section_abbrev']);
  232. $record->url = Request::getIndexUrl() . '/' . $row['journal_path'] . '/article/view/' . $articleId;
  233. $record->title = $row['title']; // FIXME include localized titles as well?
  234. $record->creator = array();
  235. $record->subject = array($row['discipline'], $row['subject'], $row['subject_class']);
  236. $record->description = $row['abstract'];
  237. $record->publisher = $row['journal_title'];
  238. $record->contributor = array($row['sponsor']);
  239. $record->date = date('Y-m-d', strtotime($this->datetimeFromDB($row['issue_published'])));
  240. $record->type = array(empty($row['section_item_type']) ? Locale::translate('rt.metadata.pkp.peerReviewed') : $row['section_item_type'], $row['type']);
  241. $record->format = array();
  242. $record->source = $row['journal_title'] . '; ' . $this->_formatIssueId($row);
  243. $record->language = $row['language'];
  244. $record->relation = array();
  245. $record->coverage = array($row['coverage_geo'], $row['coverage_chron'], $row['coverage_sample']);
  246. $record->rights = $this->journalSettingsDao->getSetting($row['journal_id'], 'copyrightNotice');
  247. // Get publisher
  248. $publisher = $this->journalSettingsDao->getSetting($row['journal_id'], 'publisher');
  249. if (isset($publisher['institution']) && !empty($publisher['institution'])) {
  250. $record->publisher = $publisher['institution'];
  251. }
  252. // Get author names
  253. $authors = $this->authorDao->getAuthorsByArticle($row['article_id']);
  254. for ($i = 0, $num = count($authors); $i < $num; $i++) {
  255. $authorName = $authors[$i]->getFullName();
  256. $affiliation = $authors[$i]->getAffiliation();
  257. if (!empty($affiliation)) {
  258. $authorName .= '; ' . $affiliation;
  259. }
  260. $record->creator[] = $authorName;
  261. }
  262. // Get galley formats
  263. $result = &$this->retrieve(
  264. 'SELECT DISTINCT(f.file_type) FROM article_galleys g, article_files f WHERE g.file_id = f.file_id AND g.article_id = ?',
  265. $row['article_id']
  266. );
  267. while (!$result->EOF) {
  268. $record->format[] = $result->fields[0];
  269. $result->MoveNext();
  270. }
  271. $result->Close();
  272. // Get supplementary files
  273. $suppFiles = $this->suppFileDao->getSuppFilesByArticle($row['article_id']);
  274. for ($i = 0, $num = count($suppFiles); $i < $num; $i++) {
  275. // FIXME replace with correct URL
  276. $record->relation[] = Request::getIndexUrl() . '/' . $row['journal_path'] . '/article/download/' . $articleId . '/' . $suppFiles[$i]->getFileId();
  277. }
  278. return $record;
  279. }
  280. /**
  281. * Return OAIIdentifier object from database row.
  282. * @param $row array
  283. * @return OAIIdentifier
  284. */
  285. function &_returnIdentifierFromRow(&$row) {
  286. $record = &new OAIRecord();
  287. $record->identifier = $this->oai->articleIdToIdentifier($row['article_id']);
  288. $record->datestamp = $this->oai->UTCDate(strtotime($this->datetimeFromDB($row['date_published'])));
  289. $record->sets = array($row['journal_path'] . ':' . $row['section_abbrev']);
  290. return $record;
  291. }
  292. // FIXME Common code with issue.Issue
  293. function _formatIssueId(&$row) {
  294. switch ($row['issue_label_format']) {
  295. case ISSUE_LABEL_VOL_YEAR:
  296. $vol = $row['issue_volume'];
  297. $year = $row['issue_year'];
  298. $volLabel = Locale::translate('issue.vol');
  299. return "$volLabel $vol ($year)";
  300. case ISSUE_LABEL_YEAR:
  301. return $row['issue_year'];
  302. case ISSUE_LABEL_TITLE:
  303. return $row['issue_title'];
  304. case ISSUE_LABEL_NUM_VOL_YEAR:
  305. default:
  306. $num = $row['issue_number'];
  307. $vol = $row['issue_volume'];
  308. $year = $row['issue_year'];
  309. $volLabel = Locale::translate('issue.vol');
  310. $numLabel = Locale::translate('issue.no');
  311. return "$volLabel $vol, $numLabel $num ($year)";
  312. }
  313. }
  314. //
  315. // Resumption tokens
  316. //
  317. /**
  318. * Clear stale resumption tokens.
  319. */
  320. function clearTokens() {
  321. $this->update(
  322. 'DELETE FROM oai_resumption_tokens WHERE expire < ?', time()
  323. );
  324. }
  325. /**
  326. * Retrieve a resumption token.
  327. * @return OAIResumptionToken
  328. */
  329. function &getToken($tokenId) {
  330. $result = &$this->retrieve(
  331. 'SELECT * FROM oai_resumption_tokens WHERE token = ?', $tokenId
  332. );
  333. if ($result->RecordCount() == 0) {
  334. $token = null;
  335. } else {
  336. $row = &$result->getRowAssoc(false);
  337. $token = new OAIResumptionToken($row['token'], $row['record_offset'], unserialize($row['params']), $row['expire']);
  338. }
  339. return $token;
  340. }
  341. /**
  342. * Insert an OAI resumption token, generating a new ID.
  343. * @param $token OAIResumptionToken
  344. * @return OAIResumptionToken
  345. */
  346. function &insertToken(&$token) {
  347. do {
  348. // Generate unique token ID
  349. $token->id = md5(uniqid(mt_rand(), true));
  350. $result = &$this->retrieve(
  351. 'SELECT COUNT(*) FROM oai_resumption_tokens WHERE token = ?',
  352. $token->id
  353. );
  354. } while($result->fields[0] != 0);
  355. $this->update(
  356. 'INSERT INTO oai_resumption_tokens (token, record_offset, params, expire)
  357. VALUES
  358. (?, ?, ?, ?)',
  359. array($token->id, $token->offset, serialize($token->params), $token->expire)
  360. );
  361. return $token;
  362. }
  363. //
  364. // Sets
  365. //
  366. /**
  367. * Return hierarchy of OAI sets (journals plus journal sections).
  368. * @param $journalId int
  369. * @param $offset int
  370. * @param $total int
  371. * @return array OAISet
  372. */
  373. function &getJournalSets($journalId, $offset, &$total) {
  374. if (isset($journalId)) {
  375. $journals = array($this->journalDao->getJournal($journalId));
  376. } else {
  377. $journals = &$this->journalDao->getJournals();
  378. $journals = &$journals->toArray();
  379. }
  380. // FIXME Set descriptions
  381. $sets = array();
  382. foreach ($journals as $journal) {
  383. $title = $journal->getTitle();
  384. $abbrev = $journal->getPath();
  385. array_push($sets, new OAISet($abbrev, $title, ''));
  386. $sections = &$this->sectionDao->getJournalSections($journal->getJournalId());
  387. foreach ($sections->toArray() as $section) {
  388. array_push($sets, new OAISet($abbrev . ':' . $section->getAbbrev(), $section->getTitle(), ''));
  389. }
  390. }
  391. if ($offset != 0) {
  392. $sets = array_slice($sets, $offset);
  393. }
  394. return $sets;
  395. }
  396. /**
  397. * Return the journal ID and section ID corresponding to a journal/section pairing.
  398. * @param $journalSpec string
  399. * @param $sectionSpec string
  400. * @param $restrictJournalId int
  401. * @return array (int, int)
  402. */
  403. function getSetJournalSectionId($journalSpec, $sectionSpec, $restrictJournalId = null) {
  404. $journalId = null;
  405. $journal = &$this->journalDao->getJournalByPath($journalSpec);
  406. if (!isset($journal) || (isset($restrictJournalId) && $journal->getJournalId() != $restrictJournalId)) {
  407. return array(0, 0);
  408. }
  409. $journalId = $journal->getJournalId();
  410. $sectionId = null;
  411. if (isset($sectionSpec)) {
  412. $section = &$this->sectionDao->getSectionByAbbrev($sectionSpec, $journal->getJournalId());
  413. if (isset($section)) {
  414. $sectionId = $section->getSectionId();
  415. } else {
  416. $sectionId = 0;
  417. }
  418. }
  419. return array($journalId, $sectionId);
  420. }
  421. }
  422. ?>